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 ) | |||
| 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 ) | |||
| 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 | |||