git-svn-id: https://svn.apache.org/repos/asf/ant/core/trunk@270181 13f79535-47bb-0310-9956-ffa450edef68master
| @@ -1083,7 +1083,105 @@ public class Project | |||||
| public String replaceProperties( String value ) | public String replaceProperties( String value ) | ||||
| throws TaskException | throws TaskException | ||||
| { | { | ||||
| return ProjectHelper.replaceProperties( this, value ); | |||||
| return replaceProperties( this, value, getProperties() ); | |||||
| } | |||||
| /** | |||||
| * Replace ${} style constructions in the given value with the string value | |||||
| * of the corresponding data types. | |||||
| * | |||||
| * @param value the string to be scanned for property references. | |||||
| * @param project Description of Parameter | |||||
| * @param keys Description of Parameter | |||||
| * @return Description of the Returned Value | |||||
| * @exception TaskException Description of Exception | |||||
| */ | |||||
| private String replaceProperties( Project project, String value, Hashtable keys ) | |||||
| throws TaskException | |||||
| { | |||||
| if( value == null ) | |||||
| { | |||||
| return null; | |||||
| } | |||||
| Vector fragments = new Vector(); | |||||
| Vector propertyRefs = new Vector(); | |||||
| parsePropertyString( value, fragments, propertyRefs ); | |||||
| StringBuffer sb = new StringBuffer(); | |||||
| Enumeration i = fragments.elements(); | |||||
| Enumeration j = propertyRefs.elements(); | |||||
| while( i.hasMoreElements() ) | |||||
| { | |||||
| String fragment = (String)i.nextElement(); | |||||
| if( fragment == null ) | |||||
| { | |||||
| String propertyName = (String)j.nextElement(); | |||||
| if( !keys.containsKey( propertyName ) ) | |||||
| { | |||||
| project.log( "Property ${" + propertyName + "} has not been set", Project.MSG_VERBOSE ); | |||||
| } | |||||
| fragment = ( keys.containsKey( propertyName ) ) ? (String)keys.get( propertyName ) | |||||
| : "${" + propertyName + "}"; | |||||
| } | |||||
| sb.append( fragment ); | |||||
| } | |||||
| return sb.toString(); | |||||
| } | |||||
| /** | |||||
| * This method will parse a string containing ${value} style property values | |||||
| * into two lists. The first list is a collection of text fragments, while | |||||
| * the other is a set of string property names null entries in the first | |||||
| * list indicate a property reference from the second list. | |||||
| * | |||||
| * @param value Description of Parameter | |||||
| * @param fragments Description of Parameter | |||||
| * @param propertyRefs Description of Parameter | |||||
| * @exception TaskException Description of Exception | |||||
| */ | |||||
| private void parsePropertyString( String value, Vector fragments, Vector propertyRefs ) | |||||
| throws TaskException | |||||
| { | |||||
| int prev = 0; | |||||
| int pos; | |||||
| while( ( pos = value.indexOf( "$", prev ) ) >= 0 ) | |||||
| { | |||||
| if( pos > 0 ) | |||||
| { | |||||
| fragments.addElement( value.substring( prev, pos ) ); | |||||
| } | |||||
| if( pos == ( value.length() - 1 ) ) | |||||
| { | |||||
| fragments.addElement( "$" ); | |||||
| prev = pos + 1; | |||||
| } | |||||
| else if( value.charAt( pos + 1 ) != '{' ) | |||||
| { | |||||
| fragments.addElement( value.substring( pos + 1, pos + 2 ) ); | |||||
| prev = pos + 2; | |||||
| } | |||||
| else | |||||
| { | |||||
| int endName = value.indexOf( '}', pos ); | |||||
| if( endName < 0 ) | |||||
| { | |||||
| throw new TaskException( "Syntax error in property: " | |||||
| + value ); | |||||
| } | |||||
| String propertyName = value.substring( pos + 2, endName ); | |||||
| fragments.addElement( null ); | |||||
| propertyRefs.addElement( propertyName ); | |||||
| prev = endName + 1; | |||||
| } | |||||
| } | |||||
| if( prev < value.length() ) | |||||
| { | |||||
| fragments.addElement( value.substring( prev ) ); | |||||
| } | |||||
| } | } | ||||
| /** | /** | ||||
| @@ -1,158 +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; | |||||
| import java.util.Enumeration; | |||||
| import java.util.Locale; | |||||
| import java.util.Vector; | |||||
| import org.apache.myrmidon.api.TaskException; | |||||
| import org.xml.sax.AttributeList; | |||||
| import org.xml.sax.helpers.AttributeListImpl; | |||||
| /** | |||||
| * Wrapper class that holds the attributes of a Task (or elements nested below | |||||
| * that level) and takes care of configuring that element at runtime. | |||||
| * | |||||
| * @author <a href="mailto:stefan.bodewig@epost.de">Stefan Bodewig</a> | |||||
| */ | |||||
| public class RuntimeConfigurable | |||||
| { | |||||
| private String elementTag = null; | |||||
| private Vector children = new Vector(); | |||||
| private Object wrappedObject = null; | |||||
| private StringBuffer characters = new StringBuffer(); | |||||
| private AttributeList attributes; | |||||
| /** | |||||
| * @param proxy The element to wrap. | |||||
| * @param elementTag Description of Parameter | |||||
| */ | |||||
| public RuntimeConfigurable( Object proxy, String elementTag ) | |||||
| { | |||||
| wrappedObject = proxy; | |||||
| this.elementTag = elementTag; | |||||
| } | |||||
| /** | |||||
| * Set's the attributes for the wrapped element. | |||||
| * | |||||
| * @param attributes The new Attributes value | |||||
| */ | |||||
| public void setAttributes( AttributeList attributes ) | |||||
| { | |||||
| this.attributes = new AttributeListImpl( attributes ); | |||||
| } | |||||
| /** | |||||
| * Returns the AttributeList of the wrapped element. | |||||
| * | |||||
| * @return The Attributes value | |||||
| */ | |||||
| public AttributeList getAttributes() | |||||
| { | |||||
| return attributes; | |||||
| } | |||||
| public String getElementTag() | |||||
| { | |||||
| return elementTag; | |||||
| } | |||||
| /** | |||||
| * Adds child elements to the wrapped element. | |||||
| * | |||||
| * @param child The feature to be added to the Child attribute | |||||
| */ | |||||
| public void addChild( RuntimeConfigurable child ) | |||||
| { | |||||
| children.addElement( child ); | |||||
| } | |||||
| /** | |||||
| * Add characters from #PCDATA areas to the wrapped element. | |||||
| * | |||||
| * @param data The feature to be added to the Text attribute | |||||
| */ | |||||
| public void addText( String data ) | |||||
| { | |||||
| characters.append( data ); | |||||
| } | |||||
| /** | |||||
| * Add characters from #PCDATA areas to the wrapped element. | |||||
| * | |||||
| * @param buf The feature to be added to the Text attribute | |||||
| * @param start The feature to be added to the Text attribute | |||||
| * @param end The feature to be added to the Text attribute | |||||
| */ | |||||
| public void addText( char[] buf, int start, int end ) | |||||
| { | |||||
| addText( new String( buf, start, end ) ); | |||||
| } | |||||
| /** | |||||
| * Configure the wrapped element and all children. | |||||
| * | |||||
| * @param p Description of Parameter | |||||
| * @exception BuildException Description of Exception | |||||
| */ | |||||
| public void maybeConfigure( Project p ) | |||||
| throws TaskException | |||||
| { | |||||
| String id = null; | |||||
| if( attributes != null ) | |||||
| { | |||||
| ProjectHelper.configure( wrappedObject, attributes, p ); | |||||
| id = attributes.getValue( "id" ); | |||||
| attributes = null; | |||||
| } | |||||
| if( characters.length() != 0 ) | |||||
| { | |||||
| ProjectHelper.addText( p, wrappedObject, characters.toString() ); | |||||
| characters.setLength( 0 ); | |||||
| } | |||||
| Enumeration enum = children.elements(); | |||||
| while( enum.hasMoreElements() ) | |||||
| { | |||||
| RuntimeConfigurable child = (RuntimeConfigurable)enum.nextElement(); | |||||
| if( child.wrappedObject instanceof Task ) | |||||
| { | |||||
| Task childTask = (Task)child.wrappedObject; | |||||
| } | |||||
| else | |||||
| { | |||||
| child.maybeConfigure( p ); | |||||
| } | |||||
| ProjectHelper.storeChild( p, wrappedObject, child.wrappedObject, child.getElementTag().toLowerCase( Locale.US ) ); | |||||
| } | |||||
| if( id != null ) | |||||
| { | |||||
| p.addReference( id, wrappedObject ); | |||||
| } | |||||
| } | |||||
| void setProxy( Object proxy ) | |||||
| { | |||||
| wrappedObject = proxy; | |||||
| } | |||||
| /** | |||||
| * Returns the child with index <code>index</code>. | |||||
| * | |||||
| * @param index Description of Parameter | |||||
| * @return The Child value | |||||
| */ | |||||
| RuntimeConfigurable getChild( int index ) | |||||
| { | |||||
| return (RuntimeConfigurable)children.elementAt( index ); | |||||
| } | |||||
| } | |||||
| @@ -1,226 +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; | |||||
| import java.util.Vector; | |||||
| import org.apache.myrmidon.api.TaskException; | |||||
| /** | |||||
| * Wrapper class that holds all information necessary to create a task or data | |||||
| * type that did not exist when Ant started. | |||||
| * | |||||
| * @author <a href="mailto:stefan.bodewig@epost.de">Stefan Bodewig</a> | |||||
| */ | |||||
| public class UnknownElement extends Task | |||||
| { | |||||
| /** | |||||
| * Childelements, holds UnknownElement instances. | |||||
| */ | |||||
| private Vector children = new Vector(); | |||||
| /** | |||||
| * Holds the name of the task/type or nested child element of a task/type | |||||
| * that hasn't been defined at parser time. | |||||
| */ | |||||
| private String elementName; | |||||
| /** | |||||
| * The real object after it has been loaded. | |||||
| */ | |||||
| private Object realThing; | |||||
| public UnknownElement( String elementName ) | |||||
| { | |||||
| this.elementName = elementName; | |||||
| } | |||||
| /** | |||||
| * return the corresponding XML element name. | |||||
| * | |||||
| * @return The Tag value | |||||
| */ | |||||
| public String getTag() | |||||
| { | |||||
| return elementName; | |||||
| } | |||||
| /** | |||||
| * Return the task instance after it has been created (and if it is a task. | |||||
| * | |||||
| * @return The Task value | |||||
| */ | |||||
| public Task getTask() | |||||
| { | |||||
| if( realThing != null && realThing instanceof Task ) | |||||
| { | |||||
| return (Task)realThing; | |||||
| } | |||||
| return null; | |||||
| } | |||||
| /** | |||||
| * Adds a child element to this element. | |||||
| * | |||||
| * @param child The feature to be added to the Child attribute | |||||
| */ | |||||
| public void addChild( UnknownElement child ) | |||||
| { | |||||
| children.addElement( child ); | |||||
| } | |||||
| /** | |||||
| * Called when the real task has been configured for the first time. | |||||
| */ | |||||
| public void execute() | |||||
| throws TaskException | |||||
| { | |||||
| if( realThing == null ) | |||||
| { | |||||
| // plain impossible to get here, maybeConfigure should | |||||
| // have thrown an exception. | |||||
| throw new TaskException( "Could not create task of type: " | |||||
| + elementName ); | |||||
| } | |||||
| if( realThing instanceof Task ) | |||||
| { | |||||
| ( (Task)realThing ).perform(); | |||||
| } | |||||
| } | |||||
| /** | |||||
| * creates the real object instance, creates child elements, configures the | |||||
| * attributes of the real object. | |||||
| * | |||||
| * @exception BuildException Description of Exception | |||||
| */ | |||||
| public void maybeConfigure() | |||||
| throws TaskException | |||||
| { | |||||
| } | |||||
| protected BuildException getNotFoundException( String what, | |||||
| String elementName ) | |||||
| { | |||||
| String lSep = System.getProperty( "line.separator" ); | |||||
| String msg = "Could not create " + what + " of type: " + elementName | |||||
| + "." + lSep | |||||
| + "Ant could not find the task or a class this" + lSep | |||||
| + "task relies upon." + lSep | |||||
| + "Common solutions are to use taskdef to declare" + lSep | |||||
| + "your task, or, if this is an optional task," + lSep | |||||
| + "to put the optional.jar and all required libraries of" + lSep | |||||
| + "this task in the lib directory of" + lSep | |||||
| + "your ant installation (ANT_HOME)." + lSep | |||||
| + "There is also the possibility that your build file " + lSep | |||||
| + "is written to work with a more recent version of ant " + lSep | |||||
| + "than the one you are using, in which case you have to " + lSep | |||||
| + "upgrade."; | |||||
| return new BuildException( msg ); | |||||
| } | |||||
| /** | |||||
| * Creates child elements, creates children of the children, sets attributes | |||||
| * of the child elements. | |||||
| * | |||||
| * @param parent Description of Parameter | |||||
| * @param parentWrapper Description of Parameter | |||||
| * @exception BuildException Description of Exception | |||||
| */ | |||||
| protected void handleChildren( Object parent, | |||||
| RuntimeConfigurable parentWrapper ) | |||||
| throws TaskException | |||||
| { | |||||
| if( parent instanceof TaskAdapter ) | |||||
| { | |||||
| parent = ( (TaskAdapter)parent ).getProxy(); | |||||
| } | |||||
| Class parentClass = parent.getClass(); | |||||
| IntrospectionHelper ih = IntrospectionHelper.getHelper( parentClass ); | |||||
| for( int i = 0; i < children.size(); i++ ) | |||||
| { | |||||
| RuntimeConfigurable childWrapper = parentWrapper.getChild( i ); | |||||
| UnknownElement child = (UnknownElement)children.elementAt( i ); | |||||
| Object realChild = null; | |||||
| if( parent instanceof TaskContainer ) | |||||
| { | |||||
| realChild = makeTask( child, childWrapper, false ); | |||||
| ( (TaskContainer)parent ).addTask( (Task)realChild ); | |||||
| } | |||||
| else | |||||
| { | |||||
| realChild = ih.createElement( project, parent, child.getTag() ); | |||||
| } | |||||
| childWrapper.setProxy( realChild ); | |||||
| child.handleChildren( realChild, childWrapper ); | |||||
| if( parent instanceof TaskContainer ) | |||||
| { | |||||
| ( (Task)realChild ).maybeConfigure(); | |||||
| } | |||||
| } | |||||
| } | |||||
| /** | |||||
| * Creates a named task or data type - if it is a task, configure it up to | |||||
| * the init() stage. | |||||
| * | |||||
| * @param ue Description of Parameter | |||||
| * @param w Description of Parameter | |||||
| * @return Description of the Returned Value | |||||
| */ | |||||
| protected Object makeObject( UnknownElement ue, RuntimeConfigurable w ) | |||||
| throws TaskException | |||||
| { | |||||
| Object o = makeTask( ue, w, true ); | |||||
| if( o == null ) | |||||
| { | |||||
| o = project.createDataType( ue.getTag() ); | |||||
| } | |||||
| if( o == null ) | |||||
| { | |||||
| throw getNotFoundException( "task or type", ue.getTag() ); | |||||
| } | |||||
| return o; | |||||
| } | |||||
| /** | |||||
| * Create a named task and configure it up to the init() stage. | |||||
| * | |||||
| * @param ue Description of Parameter | |||||
| * @param w Description of Parameter | |||||
| * @param onTopLevel Description of Parameter | |||||
| * @return Description of the Returned Value | |||||
| */ | |||||
| protected Task makeTask( UnknownElement ue, RuntimeConfigurable w, | |||||
| boolean onTopLevel ) | |||||
| throws TaskException | |||||
| { | |||||
| Task task = project.createTask( ue.getTag() ); | |||||
| if( task == null && !onTopLevel ) | |||||
| { | |||||
| throw getNotFoundException( "task", ue.getTag() ); | |||||
| } | |||||
| if( task != null ) | |||||
| { | |||||
| // UnknownElement always has an associated target | |||||
| task.setOwningTarget( target ); | |||||
| task.init(); | |||||
| } | |||||
| return task; | |||||
| } | |||||
| }// UnknownElement | |||||
| @@ -1083,7 +1083,105 @@ public class Project | |||||
| public String replaceProperties( String value ) | public String replaceProperties( String value ) | ||||
| throws TaskException | throws TaskException | ||||
| { | { | ||||
| return ProjectHelper.replaceProperties( this, value ); | |||||
| return replaceProperties( this, value, getProperties() ); | |||||
| } | |||||
| /** | |||||
| * Replace ${} style constructions in the given value with the string value | |||||
| * of the corresponding data types. | |||||
| * | |||||
| * @param value the string to be scanned for property references. | |||||
| * @param project Description of Parameter | |||||
| * @param keys Description of Parameter | |||||
| * @return Description of the Returned Value | |||||
| * @exception TaskException Description of Exception | |||||
| */ | |||||
| private String replaceProperties( Project project, String value, Hashtable keys ) | |||||
| throws TaskException | |||||
| { | |||||
| if( value == null ) | |||||
| { | |||||
| return null; | |||||
| } | |||||
| Vector fragments = new Vector(); | |||||
| Vector propertyRefs = new Vector(); | |||||
| parsePropertyString( value, fragments, propertyRefs ); | |||||
| StringBuffer sb = new StringBuffer(); | |||||
| Enumeration i = fragments.elements(); | |||||
| Enumeration j = propertyRefs.elements(); | |||||
| while( i.hasMoreElements() ) | |||||
| { | |||||
| String fragment = (String)i.nextElement(); | |||||
| if( fragment == null ) | |||||
| { | |||||
| String propertyName = (String)j.nextElement(); | |||||
| if( !keys.containsKey( propertyName ) ) | |||||
| { | |||||
| project.log( "Property ${" + propertyName + "} has not been set", Project.MSG_VERBOSE ); | |||||
| } | |||||
| fragment = ( keys.containsKey( propertyName ) ) ? (String)keys.get( propertyName ) | |||||
| : "${" + propertyName + "}"; | |||||
| } | |||||
| sb.append( fragment ); | |||||
| } | |||||
| return sb.toString(); | |||||
| } | |||||
| /** | |||||
| * This method will parse a string containing ${value} style property values | |||||
| * into two lists. The first list is a collection of text fragments, while | |||||
| * the other is a set of string property names null entries in the first | |||||
| * list indicate a property reference from the second list. | |||||
| * | |||||
| * @param value Description of Parameter | |||||
| * @param fragments Description of Parameter | |||||
| * @param propertyRefs Description of Parameter | |||||
| * @exception TaskException Description of Exception | |||||
| */ | |||||
| private void parsePropertyString( String value, Vector fragments, Vector propertyRefs ) | |||||
| throws TaskException | |||||
| { | |||||
| int prev = 0; | |||||
| int pos; | |||||
| while( ( pos = value.indexOf( "$", prev ) ) >= 0 ) | |||||
| { | |||||
| if( pos > 0 ) | |||||
| { | |||||
| fragments.addElement( value.substring( prev, pos ) ); | |||||
| } | |||||
| if( pos == ( value.length() - 1 ) ) | |||||
| { | |||||
| fragments.addElement( "$" ); | |||||
| prev = pos + 1; | |||||
| } | |||||
| else if( value.charAt( pos + 1 ) != '{' ) | |||||
| { | |||||
| fragments.addElement( value.substring( pos + 1, pos + 2 ) ); | |||||
| prev = pos + 2; | |||||
| } | |||||
| else | |||||
| { | |||||
| int endName = value.indexOf( '}', pos ); | |||||
| if( endName < 0 ) | |||||
| { | |||||
| throw new TaskException( "Syntax error in property: " | |||||
| + value ); | |||||
| } | |||||
| String propertyName = value.substring( pos + 2, endName ); | |||||
| fragments.addElement( null ); | |||||
| propertyRefs.addElement( propertyName ); | |||||
| prev = endName + 1; | |||||
| } | |||||
| } | |||||
| if( prev < value.length() ) | |||||
| { | |||||
| fragments.addElement( value.substring( prev ) ); | |||||
| } | |||||
| } | } | ||||
| /** | /** | ||||
| @@ -1,158 +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; | |||||
| import java.util.Enumeration; | |||||
| import java.util.Locale; | |||||
| import java.util.Vector; | |||||
| import org.apache.myrmidon.api.TaskException; | |||||
| import org.xml.sax.AttributeList; | |||||
| import org.xml.sax.helpers.AttributeListImpl; | |||||
| /** | |||||
| * Wrapper class that holds the attributes of a Task (or elements nested below | |||||
| * that level) and takes care of configuring that element at runtime. | |||||
| * | |||||
| * @author <a href="mailto:stefan.bodewig@epost.de">Stefan Bodewig</a> | |||||
| */ | |||||
| public class RuntimeConfigurable | |||||
| { | |||||
| private String elementTag = null; | |||||
| private Vector children = new Vector(); | |||||
| private Object wrappedObject = null; | |||||
| private StringBuffer characters = new StringBuffer(); | |||||
| private AttributeList attributes; | |||||
| /** | |||||
| * @param proxy The element to wrap. | |||||
| * @param elementTag Description of Parameter | |||||
| */ | |||||
| public RuntimeConfigurable( Object proxy, String elementTag ) | |||||
| { | |||||
| wrappedObject = proxy; | |||||
| this.elementTag = elementTag; | |||||
| } | |||||
| /** | |||||
| * Set's the attributes for the wrapped element. | |||||
| * | |||||
| * @param attributes The new Attributes value | |||||
| */ | |||||
| public void setAttributes( AttributeList attributes ) | |||||
| { | |||||
| this.attributes = new AttributeListImpl( attributes ); | |||||
| } | |||||
| /** | |||||
| * Returns the AttributeList of the wrapped element. | |||||
| * | |||||
| * @return The Attributes value | |||||
| */ | |||||
| public AttributeList getAttributes() | |||||
| { | |||||
| return attributes; | |||||
| } | |||||
| public String getElementTag() | |||||
| { | |||||
| return elementTag; | |||||
| } | |||||
| /** | |||||
| * Adds child elements to the wrapped element. | |||||
| * | |||||
| * @param child The feature to be added to the Child attribute | |||||
| */ | |||||
| public void addChild( RuntimeConfigurable child ) | |||||
| { | |||||
| children.addElement( child ); | |||||
| } | |||||
| /** | |||||
| * Add characters from #PCDATA areas to the wrapped element. | |||||
| * | |||||
| * @param data The feature to be added to the Text attribute | |||||
| */ | |||||
| public void addText( String data ) | |||||
| { | |||||
| characters.append( data ); | |||||
| } | |||||
| /** | |||||
| * Add characters from #PCDATA areas to the wrapped element. | |||||
| * | |||||
| * @param buf The feature to be added to the Text attribute | |||||
| * @param start The feature to be added to the Text attribute | |||||
| * @param end The feature to be added to the Text attribute | |||||
| */ | |||||
| public void addText( char[] buf, int start, int end ) | |||||
| { | |||||
| addText( new String( buf, start, end ) ); | |||||
| } | |||||
| /** | |||||
| * Configure the wrapped element and all children. | |||||
| * | |||||
| * @param p Description of Parameter | |||||
| * @exception BuildException Description of Exception | |||||
| */ | |||||
| public void maybeConfigure( Project p ) | |||||
| throws TaskException | |||||
| { | |||||
| String id = null; | |||||
| if( attributes != null ) | |||||
| { | |||||
| ProjectHelper.configure( wrappedObject, attributes, p ); | |||||
| id = attributes.getValue( "id" ); | |||||
| attributes = null; | |||||
| } | |||||
| if( characters.length() != 0 ) | |||||
| { | |||||
| ProjectHelper.addText( p, wrappedObject, characters.toString() ); | |||||
| characters.setLength( 0 ); | |||||
| } | |||||
| Enumeration enum = children.elements(); | |||||
| while( enum.hasMoreElements() ) | |||||
| { | |||||
| RuntimeConfigurable child = (RuntimeConfigurable)enum.nextElement(); | |||||
| if( child.wrappedObject instanceof Task ) | |||||
| { | |||||
| Task childTask = (Task)child.wrappedObject; | |||||
| } | |||||
| else | |||||
| { | |||||
| child.maybeConfigure( p ); | |||||
| } | |||||
| ProjectHelper.storeChild( p, wrappedObject, child.wrappedObject, child.getElementTag().toLowerCase( Locale.US ) ); | |||||
| } | |||||
| if( id != null ) | |||||
| { | |||||
| p.addReference( id, wrappedObject ); | |||||
| } | |||||
| } | |||||
| void setProxy( Object proxy ) | |||||
| { | |||||
| wrappedObject = proxy; | |||||
| } | |||||
| /** | |||||
| * Returns the child with index <code>index</code>. | |||||
| * | |||||
| * @param index Description of Parameter | |||||
| * @return The Child value | |||||
| */ | |||||
| RuntimeConfigurable getChild( int index ) | |||||
| { | |||||
| return (RuntimeConfigurable)children.elementAt( index ); | |||||
| } | |||||
| } | |||||
| @@ -1,226 +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; | |||||
| import java.util.Vector; | |||||
| import org.apache.myrmidon.api.TaskException; | |||||
| /** | |||||
| * Wrapper class that holds all information necessary to create a task or data | |||||
| * type that did not exist when Ant started. | |||||
| * | |||||
| * @author <a href="mailto:stefan.bodewig@epost.de">Stefan Bodewig</a> | |||||
| */ | |||||
| public class UnknownElement extends Task | |||||
| { | |||||
| /** | |||||
| * Childelements, holds UnknownElement instances. | |||||
| */ | |||||
| private Vector children = new Vector(); | |||||
| /** | |||||
| * Holds the name of the task/type or nested child element of a task/type | |||||
| * that hasn't been defined at parser time. | |||||
| */ | |||||
| private String elementName; | |||||
| /** | |||||
| * The real object after it has been loaded. | |||||
| */ | |||||
| private Object realThing; | |||||
| public UnknownElement( String elementName ) | |||||
| { | |||||
| this.elementName = elementName; | |||||
| } | |||||
| /** | |||||
| * return the corresponding XML element name. | |||||
| * | |||||
| * @return The Tag value | |||||
| */ | |||||
| public String getTag() | |||||
| { | |||||
| return elementName; | |||||
| } | |||||
| /** | |||||
| * Return the task instance after it has been created (and if it is a task. | |||||
| * | |||||
| * @return The Task value | |||||
| */ | |||||
| public Task getTask() | |||||
| { | |||||
| if( realThing != null && realThing instanceof Task ) | |||||
| { | |||||
| return (Task)realThing; | |||||
| } | |||||
| return null; | |||||
| } | |||||
| /** | |||||
| * Adds a child element to this element. | |||||
| * | |||||
| * @param child The feature to be added to the Child attribute | |||||
| */ | |||||
| public void addChild( UnknownElement child ) | |||||
| { | |||||
| children.addElement( child ); | |||||
| } | |||||
| /** | |||||
| * Called when the real task has been configured for the first time. | |||||
| */ | |||||
| public void execute() | |||||
| throws TaskException | |||||
| { | |||||
| if( realThing == null ) | |||||
| { | |||||
| // plain impossible to get here, maybeConfigure should | |||||
| // have thrown an exception. | |||||
| throw new TaskException( "Could not create task of type: " | |||||
| + elementName ); | |||||
| } | |||||
| if( realThing instanceof Task ) | |||||
| { | |||||
| ( (Task)realThing ).perform(); | |||||
| } | |||||
| } | |||||
| /** | |||||
| * creates the real object instance, creates child elements, configures the | |||||
| * attributes of the real object. | |||||
| * | |||||
| * @exception BuildException Description of Exception | |||||
| */ | |||||
| public void maybeConfigure() | |||||
| throws TaskException | |||||
| { | |||||
| } | |||||
| protected BuildException getNotFoundException( String what, | |||||
| String elementName ) | |||||
| { | |||||
| String lSep = System.getProperty( "line.separator" ); | |||||
| String msg = "Could not create " + what + " of type: " + elementName | |||||
| + "." + lSep | |||||
| + "Ant could not find the task or a class this" + lSep | |||||
| + "task relies upon." + lSep | |||||
| + "Common solutions are to use taskdef to declare" + lSep | |||||
| + "your task, or, if this is an optional task," + lSep | |||||
| + "to put the optional.jar and all required libraries of" + lSep | |||||
| + "this task in the lib directory of" + lSep | |||||
| + "your ant installation (ANT_HOME)." + lSep | |||||
| + "There is also the possibility that your build file " + lSep | |||||
| + "is written to work with a more recent version of ant " + lSep | |||||
| + "than the one you are using, in which case you have to " + lSep | |||||
| + "upgrade."; | |||||
| return new BuildException( msg ); | |||||
| } | |||||
| /** | |||||
| * Creates child elements, creates children of the children, sets attributes | |||||
| * of the child elements. | |||||
| * | |||||
| * @param parent Description of Parameter | |||||
| * @param parentWrapper Description of Parameter | |||||
| * @exception BuildException Description of Exception | |||||
| */ | |||||
| protected void handleChildren( Object parent, | |||||
| RuntimeConfigurable parentWrapper ) | |||||
| throws TaskException | |||||
| { | |||||
| if( parent instanceof TaskAdapter ) | |||||
| { | |||||
| parent = ( (TaskAdapter)parent ).getProxy(); | |||||
| } | |||||
| Class parentClass = parent.getClass(); | |||||
| IntrospectionHelper ih = IntrospectionHelper.getHelper( parentClass ); | |||||
| for( int i = 0; i < children.size(); i++ ) | |||||
| { | |||||
| RuntimeConfigurable childWrapper = parentWrapper.getChild( i ); | |||||
| UnknownElement child = (UnknownElement)children.elementAt( i ); | |||||
| Object realChild = null; | |||||
| if( parent instanceof TaskContainer ) | |||||
| { | |||||
| realChild = makeTask( child, childWrapper, false ); | |||||
| ( (TaskContainer)parent ).addTask( (Task)realChild ); | |||||
| } | |||||
| else | |||||
| { | |||||
| realChild = ih.createElement( project, parent, child.getTag() ); | |||||
| } | |||||
| childWrapper.setProxy( realChild ); | |||||
| child.handleChildren( realChild, childWrapper ); | |||||
| if( parent instanceof TaskContainer ) | |||||
| { | |||||
| ( (Task)realChild ).maybeConfigure(); | |||||
| } | |||||
| } | |||||
| } | |||||
| /** | |||||
| * Creates a named task or data type - if it is a task, configure it up to | |||||
| * the init() stage. | |||||
| * | |||||
| * @param ue Description of Parameter | |||||
| * @param w Description of Parameter | |||||
| * @return Description of the Returned Value | |||||
| */ | |||||
| protected Object makeObject( UnknownElement ue, RuntimeConfigurable w ) | |||||
| throws TaskException | |||||
| { | |||||
| Object o = makeTask( ue, w, true ); | |||||
| if( o == null ) | |||||
| { | |||||
| o = project.createDataType( ue.getTag() ); | |||||
| } | |||||
| if( o == null ) | |||||
| { | |||||
| throw getNotFoundException( "task or type", ue.getTag() ); | |||||
| } | |||||
| return o; | |||||
| } | |||||
| /** | |||||
| * Create a named task and configure it up to the init() stage. | |||||
| * | |||||
| * @param ue Description of Parameter | |||||
| * @param w Description of Parameter | |||||
| * @param onTopLevel Description of Parameter | |||||
| * @return Description of the Returned Value | |||||
| */ | |||||
| protected Task makeTask( UnknownElement ue, RuntimeConfigurable w, | |||||
| boolean onTopLevel ) | |||||
| throws TaskException | |||||
| { | |||||
| Task task = project.createTask( ue.getTag() ); | |||||
| if( task == null && !onTopLevel ) | |||||
| { | |||||
| throw getNotFoundException( "task", ue.getTag() ); | |||||
| } | |||||
| if( task != null ) | |||||
| { | |||||
| // UnknownElement always has an associated target | |||||
| task.setOwningTarget( target ); | |||||
| task.init(); | |||||
| } | |||||
| return task; | |||||
| } | |||||
| }// UnknownElement | |||||