* Completed property hooks, so that the underlying Ant1 project
is not used for setting, getting or resolving properties.
* Made PropertyResolver.resolveProperties()take a TaskContext,
instead of Avalon Context. (We can always split out a generic
interface later, if need be.) Ant1 compatibility layer user
ClassicPropertyResolver, which needs a better name.
* Added modified BuildException, which incudes a Myrmidon-friendly
getCause() method, to allow Ant1 exceptions to be properly cascaded.
* DefaultTaskContext:
- Allow "+" in property names.
- Implemented DefaultTaskContext.getProperties()
- No longer implements avalon Context (not needed)
git-svn-id: https://svn.apache.org/repos/asf/ant/core/trunk@271924 13f79535-47bb-0310-9956-ffa450edef68
master
| @@ -62,6 +62,7 @@ | |||||
| <patternset id="ant1.omit"> | <patternset id="ant1.omit"> | ||||
| <exclude name="${ant1.package}/ant/Main.class"/> | <exclude name="${ant1.package}/ant/Main.class"/> | ||||
| <exclude name="${ant1.package}/ant/Task.class"/> | <exclude name="${ant1.package}/ant/Task.class"/> | ||||
| <exclude name="${ant1.package}/ant/BuildException.class"/> | |||||
| <exclude name="${ant1.package}/ant/types/Path.class"/> | <exclude name="${ant1.package}/ant/types/Path.class"/> | ||||
| </patternset> | </patternset> | ||||
| @@ -18,7 +18,7 @@ it may can mimic the Ant1 configuration policy using the IntrospectionHelper. | |||||
| The idea is to provide hooks between the Ant1 project and the Myrmidon | The idea is to provide hooks between the Ant1 project and the Myrmidon | ||||
| project, eg | project, eg | ||||
| logging: done | logging: done | ||||
| properties: done but not quite working | |||||
| properties: done | |||||
| references: not done | references: not done | ||||
| Task definitions: done. | Task definitions: done. | ||||
| @@ -51,10 +51,8 @@ BUILD INSTRUCTIONS | |||||
| TODO | TODO | ||||
| ---- | ---- | ||||
| * Convert this to an Xdoc document | * Convert this to an Xdoc document | ||||
| * Try out automatic registration of tasks - remove everything | |||||
| from ant-descriptor.xml and just use Project.addTaskDefinition() | |||||
| to register tasks? (similar for DataTypes) | |||||
| * Get a version of <ant> and <antcall> working | * Get a version of <ant> and <antcall> working | ||||
| * Test heaps more tasks | * Test heaps more tasks | ||||
| * Check that "if" and "unless" conversions are working. | |||||
| * Provide hooks between Ant1 references and Myrmidon properties. Need to use | |||||
| converters for adapting Ant2 objects (like Ant2 <path> or <fileset>) as Ant1 types. | |||||
| @@ -7,13 +7,22 @@ | |||||
| */ | */ | ||||
| package org.apache.tools.ant; | package org.apache.tools.ant; | ||||
| import java.io.File; | |||||
| import java.io.IOException; | import java.io.IOException; | ||||
| import java.io.InputStream; | import java.io.InputStream; | ||||
| import java.util.Enumeration; | import java.util.Enumeration; | ||||
| import java.util.HashSet; | |||||
| import java.util.Hashtable; | |||||
| import java.util.Iterator; | |||||
| import java.util.Map; | |||||
| import java.util.Properties; | import java.util.Properties; | ||||
| import java.util.Set; | |||||
| import org.apache.myrmidon.api.TaskContext; | import org.apache.myrmidon.api.TaskContext; | ||||
| import org.apache.myrmidon.api.TaskException; | |||||
| import org.apache.myrmidon.interfaces.type.DefaultTypeFactory; | import org.apache.myrmidon.interfaces.type.DefaultTypeFactory; | ||||
| import org.apache.myrmidon.interfaces.type.TypeManager; | import org.apache.myrmidon.interfaces.type.TypeManager; | ||||
| import org.apache.myrmidon.interfaces.property.PropertyResolver; | |||||
| import org.apache.myrmidon.components.property.ClassicPropertyResolver; | |||||
| /** | /** | ||||
| * Ant1 Project proxy for Myrmidon. Provides hooks between Myrmidon TaskContext | * Ant1 Project proxy for Myrmidon. Provides hooks between Myrmidon TaskContext | ||||
| @@ -27,9 +36,14 @@ import org.apache.myrmidon.interfaces.type.TypeManager; | |||||
| */ | */ | ||||
| public class Ant1CompatProject extends Project | public class Ant1CompatProject extends Project | ||||
| { | { | ||||
| private TaskContext m_context; | |||||
| public static final String ANT1_TASK_PREFIX = "ant1."; | public static final String ANT1_TASK_PREFIX = "ant1."; | ||||
| private static final PropertyResolver c_ant1PropertyResolver = | |||||
| new ClassicPropertyResolver(); | |||||
| private Set m_userProperties = new HashSet(); | |||||
| private TaskContext m_context; | |||||
| public Ant1CompatProject( TaskContext context ) | public Ant1CompatProject( TaskContext context ) | ||||
| { | { | ||||
| super(); | super(); | ||||
| @@ -244,4 +258,242 @@ public class Ant1CompatProject extends Project | |||||
| typeManager.registerType( roleType, typeName, factory ); | typeManager.registerType( roleType, typeName, factory ); | ||||
| } | } | ||||
| /** | |||||
| * Sets a property. Any existing property of the same name | |||||
| * is overwritten, unless it is a user property. | |||||
| * @param name The name of property to set. | |||||
| * Must not be <code>null</code>. | |||||
| * @param value The new value of the property. | |||||
| * Must not be <code>null</code>. | |||||
| */ | |||||
| public void setProperty( String name, String value ) | |||||
| { | |||||
| if( m_userProperties.contains( name ) ) | |||||
| { | |||||
| log( "Override ignored for user property " + name, MSG_VERBOSE ); | |||||
| return; | |||||
| } | |||||
| if( null != m_context.getProperty( name ) ) | |||||
| { | |||||
| log( "Overriding previous definition of property " + name, | |||||
| MSG_VERBOSE ); | |||||
| } | |||||
| log( "Setting project property: " + name + " -> " + | |||||
| value, MSG_DEBUG ); | |||||
| doSetProperty( name, value ); | |||||
| } | |||||
| /** | |||||
| * Sets a property if no value currently exists. If the property | |||||
| * exists already, a message is logged and the method returns with | |||||
| * no other effect. | |||||
| * | |||||
| * @param name The name of property to set. | |||||
| * Must not be <code>null</code>. | |||||
| * @param value The new value of the property. | |||||
| * Must not be <code>null</code>. | |||||
| * @since 1.5 | |||||
| */ | |||||
| public void setNewProperty( String name, String value ) | |||||
| { | |||||
| if( null != m_context.getProperty( name ) ) | |||||
| { | |||||
| log( "Override ignored for property " + name, MSG_VERBOSE ); | |||||
| return; | |||||
| } | |||||
| log( "Setting project property: " + name + " -> " + | |||||
| value, MSG_DEBUG ); | |||||
| doSetProperty( name, value ); | |||||
| } | |||||
| /** | |||||
| * Sets a user property, which cannot be overwritten by | |||||
| * set/unset property calls. Any previous value is overwritten. | |||||
| * @param name The name of property to set. | |||||
| * Must not be <code>null</code>. | |||||
| * @param value The new value of the property. | |||||
| * Must not be <code>null</code>. | |||||
| * @see #setProperty(String,String) | |||||
| */ | |||||
| public void setUserProperty( String name, String value ) | |||||
| { | |||||
| log( "Setting ro project property: " + name + " -> " + | |||||
| value, MSG_DEBUG ); | |||||
| m_userProperties.add( name ); | |||||
| doSetProperty( name, value ); | |||||
| } | |||||
| /** | |||||
| * Sets a property value in the context, wrapping exceptions as | |||||
| * Ant1 BuildExceptions. | |||||
| * @param name property name | |||||
| * @param value property value | |||||
| */ | |||||
| private void doSetProperty( String name, String value ) | |||||
| { | |||||
| try | |||||
| { | |||||
| m_context.setProperty( name, value ); | |||||
| } | |||||
| catch( TaskException e ) | |||||
| { | |||||
| throw new BuildException( "Could not set property: " + name, e ); | |||||
| } | |||||
| } | |||||
| /** | |||||
| * Returns the value of a property, if it is set. | |||||
| * | |||||
| * @param name The name of the property. | |||||
| * May be <code>null</code>, in which case | |||||
| * the return value is also <code>null</code>. | |||||
| * @return the property value, or <code>null</code> for no match | |||||
| * or if a <code>null</code> name is provided. | |||||
| */ | |||||
| public String getProperty( String name ) | |||||
| { | |||||
| Object value = m_context.getProperty( name ); | |||||
| // In Ant1, all properties are strings. | |||||
| if( value instanceof String ) | |||||
| { | |||||
| return (String)value; | |||||
| } | |||||
| else | |||||
| { | |||||
| return null; | |||||
| } | |||||
| } | |||||
| /** | |||||
| * Returns the value of a user property, if it is set. | |||||
| * | |||||
| * @param name The name of the property. | |||||
| * May be <code>null</code>, in which case | |||||
| * the return value is also <code>null</code>. | |||||
| * @return the property value, or <code>null</code> for no match | |||||
| * or if a <code>null</code> name is provided. | |||||
| */ | |||||
| public String getUserProperty( String name ) | |||||
| { | |||||
| if( m_userProperties.contains( name ) ) | |||||
| { | |||||
| return getProperty( name ); | |||||
| } | |||||
| else | |||||
| { | |||||
| return null; | |||||
| } | |||||
| } | |||||
| /** | |||||
| * Returns a copy of the properties table. | |||||
| * @return a hashtable containing all properties | |||||
| * (including user properties). | |||||
| */ | |||||
| public Hashtable getProperties() | |||||
| { | |||||
| Hashtable propsCopy = new Hashtable(); | |||||
| Map contextProps = m_context.getProperties(); | |||||
| Iterator propNames = contextProps.keySet().iterator(); | |||||
| while( propNames.hasNext() ) | |||||
| { | |||||
| String name = (String)propNames.next(); | |||||
| // Use getProperty() to only return Strings. | |||||
| String value = getProperty( name ); | |||||
| if( value != null ) | |||||
| { | |||||
| propsCopy.put( name, value ); | |||||
| } | |||||
| } | |||||
| return propsCopy; | |||||
| } | |||||
| /** | |||||
| * Returns a copy of the user property hashtable | |||||
| * @return a hashtable containing just the user properties | |||||
| */ | |||||
| public Hashtable getUserProperties() | |||||
| { | |||||
| Hashtable propsCopy = new Hashtable(); | |||||
| Iterator userPropNames = m_userProperties.iterator(); | |||||
| while( userPropNames.hasNext() ) | |||||
| { | |||||
| String name = (String)userPropNames.next(); | |||||
| String value = getProperty( name ); | |||||
| propsCopy.put( name, value ); | |||||
| } | |||||
| return propsCopy; | |||||
| } | |||||
| /** | |||||
| * Replaces ${} 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. | |||||
| * May be <code>null</code>. | |||||
| * | |||||
| * @return the given string with embedded property names replaced | |||||
| * by values, or <code>null</code> if the given string is | |||||
| * <code>null</code>. | |||||
| * | |||||
| * @exception BuildException if the given value has an unclosed | |||||
| * property name, e.g. <code>${xxx</code> | |||||
| */ | |||||
| public String replaceProperties( String value ) | |||||
| throws BuildException | |||||
| { | |||||
| try | |||||
| { | |||||
| return (String)c_ant1PropertyResolver.resolveProperties( value, | |||||
| m_context ); | |||||
| } | |||||
| catch( TaskException e ) | |||||
| { | |||||
| throw new BuildException( "Error resolving value: '" + value + "'", e ); | |||||
| } | |||||
| } | |||||
| /** | |||||
| * Make the Ant1 project set the java version property, and then | |||||
| * copy it into the context properties. | |||||
| * | |||||
| * @exception BuildException if this Java version is not supported | |||||
| * | |||||
| * @see #getJavaVersion() | |||||
| */ | |||||
| public void setJavaVersionProperty() throws BuildException | |||||
| { | |||||
| String javaVersion = getJavaVersion(); | |||||
| doSetProperty( "ant.java.version", javaVersion ); | |||||
| log( "Detected Java version: " + javaVersion + " in: " | |||||
| + System.getProperty( "java.home" ), MSG_VERBOSE ); | |||||
| log( "Detected OS: " + System.getProperty( "os.name" ), MSG_VERBOSE ); | |||||
| } | |||||
| /** | |||||
| * Sets the base directory for the project, checking that | |||||
| * the given filename exists and is a directory. | |||||
| * | |||||
| * @param baseD The project base directory. | |||||
| * Must not be <code>null</code>. | |||||
| * | |||||
| * @exception BuildException if the directory if invalid | |||||
| */ | |||||
| public void setBaseDir( File baseD ) throws BuildException | |||||
| { | |||||
| super.setBaseDir( baseD ); | |||||
| doSetProperty( "basedir", super.getProperty( "basedir" ) ); | |||||
| } | |||||
| } | } | ||||
| @@ -0,0 +1,255 @@ | |||||
| /* | |||||
| * The Apache Software License, Version 1.1 | |||||
| * | |||||
| * Copyright (c) 2000-2002 The Apache Software Foundation. All rights | |||||
| * reserved. | |||||
| * | |||||
| * Redistribution and use in source and binary forms, with or without | |||||
| * modification, are permitted provided that the following conditions | |||||
| * are met: | |||||
| * | |||||
| * 1. Redistributions of source code must retain the above copyright | |||||
| * notice, this list of conditions and the following disclaimer. | |||||
| * | |||||
| * 2. Redistributions in binary form must reproduce the above copyright | |||||
| * notice, this list of conditions and the following disclaimer in | |||||
| * the documentation and/or other materials provided with the | |||||
| * distribution. | |||||
| * | |||||
| * 3. The end-user documentation included with the redistribution, if | |||||
| * any, must include the following acknowlegement: | |||||
| * "This product includes software developed by the | |||||
| * Apache Software Foundation (http://www.apache.org/)." | |||||
| * Alternately, this acknowlegement may appear in the software itself, | |||||
| * if and wherever such third-party acknowlegements normally appear. | |||||
| * | |||||
| * 4. The names "The Jakarta Project", "Ant", and "Apache Software | |||||
| * Foundation" must not be used to endorse or promote products derived | |||||
| * from this software without prior written permission. For written | |||||
| * permission, please contact apache@apache.org. | |||||
| * | |||||
| * 5. Products derived from this software may not be called "Apache" | |||||
| * nor may "Apache" appear in their names without prior written | |||||
| * permission of the Apache Group. | |||||
| * | |||||
| * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED | |||||
| * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES | |||||
| * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | |||||
| * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR | |||||
| * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | |||||
| * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | |||||
| * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF | |||||
| * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | |||||
| * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, | |||||
| * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT | |||||
| * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | |||||
| * SUCH DAMAGE. | |||||
| * ==================================================================== | |||||
| * | |||||
| * This software consists of voluntary contributions made by many | |||||
| * individuals on behalf of the Apache Software Foundation. For more | |||||
| * information on the Apache Software Foundation, please see | |||||
| * <http://www.apache.org/>. | |||||
| */ | |||||
| package org.apache.tools.ant; | |||||
| import java.io.PrintWriter; | |||||
| import java.io.PrintStream; | |||||
| import org.apache.tools.ant.Location; | |||||
| /** | |||||
| *----------------------------------------------------------------- | |||||
| * Ant1Compatability layer version of BuildException, modified slightly | |||||
| * from original Ant1 BuildException, to provide a Myrmidon-friendly | |||||
| * getCause(), so that cascading exceptions are followed. | |||||
| * ----------------------------------------------------------------- | |||||
| * | |||||
| * Signals an error condition during a build | |||||
| * | |||||
| * @author James Duncan Davidson | |||||
| */ | |||||
| public class BuildException extends RuntimeException { | |||||
| /** Exception that might have caused this one. */ | |||||
| private Throwable cause; | |||||
| /** Location in the build file where the exception occured */ | |||||
| private Location location = Location.UNKNOWN_LOCATION; | |||||
| /** | |||||
| * Constructs a build exception with no descriptive information. | |||||
| */ | |||||
| public BuildException() { | |||||
| super(); | |||||
| } | |||||
| /** | |||||
| * Constructs an exception with the given descriptive message. | |||||
| * | |||||
| * @param msg A description of or information about the exception. | |||||
| * Should not be <code>null</code>. | |||||
| */ | |||||
| public BuildException(String msg) { | |||||
| super(msg); | |||||
| } | |||||
| /** | |||||
| * Constructs an exception with the given message and exception as | |||||
| * a root cause. | |||||
| * | |||||
| * @param msg A description of or information about the exception. | |||||
| * Should not be <code>null</code> unless a cause is specified. | |||||
| * @param cause The exception that might have caused this one. | |||||
| * May be <code>null</code>. | |||||
| */ | |||||
| public BuildException(String msg, Throwable cause) { | |||||
| super(msg); | |||||
| this.cause = cause; | |||||
| } | |||||
| /** | |||||
| * Constructs an exception with the given message and exception as | |||||
| * a root cause and a location in a file. | |||||
| * | |||||
| * @param msg A description of or information about the exception. | |||||
| * Should not be <code>null</code> unless a cause is specified. | |||||
| * @param cause The exception that might have caused this one. | |||||
| * May be <code>null</code>. | |||||
| * @param location The location in the project file where the error | |||||
| * occurred. Must not be <code>null</code>. | |||||
| */ | |||||
| public BuildException(String msg, Throwable cause, Location location) { | |||||
| this(msg, cause); | |||||
| this.location = location; | |||||
| } | |||||
| /** | |||||
| * Constructs an exception with the given exception as a root cause. | |||||
| * | |||||
| * @param cause The exception that might have caused this one. | |||||
| * Should not be <code>null</code>. | |||||
| */ | |||||
| public BuildException(Throwable cause) { | |||||
| super(cause.toString()); | |||||
| this.cause = cause; | |||||
| } | |||||
| /** | |||||
| * Constructs an exception with the given descriptive message and a | |||||
| * location in a file. | |||||
| * | |||||
| * @param msg A description of or information about the exception. | |||||
| * Should not be <code>null</code>. | |||||
| * @param location The location in the project file where the error | |||||
| * occurred. Must not be <code>null</code>. | |||||
| */ | |||||
| public BuildException(String msg, Location location) { | |||||
| super(msg); | |||||
| this.location = location; | |||||
| } | |||||
| /** | |||||
| * Constructs an exception with the given exception as | |||||
| * a root cause and a location in a file. | |||||
| * | |||||
| * @param cause The exception that might have caused this one. | |||||
| * Should not be <code>null</code>. | |||||
| * @param location The location in the project file where the error | |||||
| * occurred. Must not be <code>null</code>. | |||||
| */ | |||||
| public BuildException(Throwable cause, Location location) { | |||||
| this(cause); | |||||
| this.location = location; | |||||
| } | |||||
| /** | |||||
| * Returns the nested exception, if any. | |||||
| * | |||||
| * @return the nested exception, or <code>null</code> if no | |||||
| * exception is associated with this one | |||||
| */ | |||||
| public Throwable getException() { | |||||
| return cause; | |||||
| } | |||||
| /** | |||||
| * Returns the location of the error and the error message. | |||||
| * | |||||
| * @return the location of the error and the error message | |||||
| */ | |||||
| public String toString() { | |||||
| return location.toString() + getMessage(); | |||||
| } | |||||
| /** | |||||
| * Sets the file location where the error occurred. | |||||
| * | |||||
| * @param location The file location where the error occurred. | |||||
| * Must not be <code>null</code>. | |||||
| */ | |||||
| public void setLocation(Location location) { | |||||
| this.location = location; | |||||
| } | |||||
| /** | |||||
| * Returns the file location where the error occurred. | |||||
| * | |||||
| * @return the file location where the error occurred. | |||||
| */ | |||||
| public Location getLocation() { | |||||
| return location; | |||||
| } | |||||
| /** | |||||
| * Prints the stack trace for this exception and any | |||||
| * nested exception to <code>System.err</code>. | |||||
| */ | |||||
| public void printStackTrace() { | |||||
| printStackTrace(System.err); | |||||
| } | |||||
| /** | |||||
| * Prints the stack trace of this exception and any nested | |||||
| * exception to the specified PrintStream. | |||||
| * | |||||
| * @param ps The PrintStream to print the stack trace to. | |||||
| * Must not be <code>null</code>. | |||||
| */ | |||||
| public void printStackTrace(PrintStream ps) { | |||||
| synchronized (ps) { | |||||
| super.printStackTrace(ps); | |||||
| if (cause != null) { | |||||
| ps.println("--- Nested Exception ---"); | |||||
| cause.printStackTrace(ps); | |||||
| } | |||||
| } | |||||
| } | |||||
| /** | |||||
| * Prints the stack trace of this exception and any nested | |||||
| * exception to the specified PrintWriter. | |||||
| * | |||||
| * @param pw The PrintWriter to print the stack trace to. | |||||
| * Must not be <code>null</code>. | |||||
| */ | |||||
| public void printStackTrace(PrintWriter pw) { | |||||
| synchronized (pw) { | |||||
| super.printStackTrace(pw); | |||||
| if (cause != null) { | |||||
| pw.println("--- Nested Exception ---"); | |||||
| cause.printStackTrace(pw); | |||||
| } | |||||
| } | |||||
| } | |||||
| //-------------------Modified from Ant1 --------------------- | |||||
| /** | |||||
| * Myrmidon-friendly cascading exception method. | |||||
| * @return the cascading cause of this exception. | |||||
| */ | |||||
| public Throwable getCause() | |||||
| { | |||||
| return cause; | |||||
| } | |||||
| //--------------------- End modified section --------------- | |||||
| } | |||||
| @@ -7,9 +7,8 @@ | |||||
| */ | */ | ||||
| package org.apache.myrmidon.components.property; | package org.apache.myrmidon.components.property; | ||||
| import org.apache.avalon.framework.context.Context; | |||||
| import org.apache.avalon.framework.context.ContextException; | |||||
| import org.apache.myrmidon.interfaces.property.PropertyResolver; | import org.apache.myrmidon.interfaces.property.PropertyResolver; | ||||
| import org.apache.myrmidon.api.TaskContext; | |||||
| /** | /** | ||||
| * A {@link PropertyResolver} implementation which resolves properties | * A {@link PropertyResolver} implementation which resolves properties | ||||
| @@ -30,15 +29,16 @@ public class ClassicPropertyResolver | |||||
| * @param context the set of known properties | * @param context the set of known properties | ||||
| */ | */ | ||||
| protected Object getPropertyValue( final String propertyName, | protected Object getPropertyValue( final String propertyName, | ||||
| final Context context ) | |||||
| final TaskContext context ) | |||||
| { | { | ||||
| try | |||||
| Object propertyValue = context.getProperty( propertyName ); | |||||
| if ( propertyValue == null ) | |||||
| { | { | ||||
| return context.get( propertyName ); | |||||
| return "${" + propertyName + "}"; | |||||
| } | } | ||||
| catch( ContextException e ) | |||||
| else | |||||
| { | { | ||||
| return "${" + propertyName + "}"; | |||||
| return propertyValue; | |||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| @@ -9,9 +9,8 @@ package org.apache.myrmidon.components.property; | |||||
| import org.apache.avalon.excalibur.i18n.ResourceManager; | import org.apache.avalon.excalibur.i18n.ResourceManager; | ||||
| import org.apache.avalon.excalibur.i18n.Resources; | import org.apache.avalon.excalibur.i18n.Resources; | ||||
| import org.apache.avalon.framework.context.Context; | |||||
| import org.apache.avalon.framework.context.ContextException; | |||||
| import org.apache.myrmidon.api.TaskException; | import org.apache.myrmidon.api.TaskException; | ||||
| import org.apache.myrmidon.api.TaskContext; | |||||
| import org.apache.myrmidon.interfaces.property.PropertyResolver; | import org.apache.myrmidon.interfaces.property.PropertyResolver; | ||||
| /** | /** | ||||
| @@ -43,7 +42,7 @@ public class DefaultPropertyResolver | |||||
| * @exception TaskException if an error occurs | * @exception TaskException if an error occurs | ||||
| */ | */ | ||||
| public Object resolveProperties( final String content, | public Object resolveProperties( final String content, | ||||
| final Context context ) | |||||
| final TaskContext context ) | |||||
| throws TaskException | throws TaskException | ||||
| { | { | ||||
| int start = findNextProperty( content, 0 ); | int start = findNextProperty( content, 0 ); | ||||
| @@ -100,7 +99,7 @@ public class DefaultPropertyResolver | |||||
| * @exception TaskException if an error occurs | * @exception TaskException if an error occurs | ||||
| */ | */ | ||||
| private Object recursiveResolveProperty( final String content, | private Object recursiveResolveProperty( final String content, | ||||
| final Context context ) | |||||
| final TaskContext context ) | |||||
| throws TaskException | throws TaskException | ||||
| { | { | ||||
| int start = findNextProperty( content, 0 ); | int start = findNextProperty( content, 0 ); | ||||
| @@ -238,18 +237,19 @@ public class DefaultPropertyResolver | |||||
| * @exception TaskException if the property is undefined | * @exception TaskException if the property is undefined | ||||
| */ | */ | ||||
| protected Object getPropertyValue( final String propertyName, | protected Object getPropertyValue( final String propertyName, | ||||
| final Context context ) | |||||
| final TaskContext context ) | |||||
| throws TaskException | throws TaskException | ||||
| { | { | ||||
| try | |||||
| { | |||||
| return context.get( propertyName ); | |||||
| } | |||||
| catch( ContextException e ) | |||||
| Object propertyValue = context.getProperty( propertyName ); | |||||
| if ( propertyValue == null ) | |||||
| { | { | ||||
| final String message = REZ.getString( "prop.missing-value.error", propertyName ); | final String message = REZ.getString( "prop.missing-value.error", propertyName ); | ||||
| throw new TaskException( message ); | throw new TaskException( message ); | ||||
| } | } | ||||
| else | |||||
| { | |||||
| return propertyValue; | |||||
| } | |||||
| } | } | ||||
| } | } | ||||
| @@ -10,11 +10,10 @@ package org.apache.myrmidon.components.workspace; | |||||
| import java.io.File; | import java.io.File; | ||||
| import java.util.Hashtable; | import java.util.Hashtable; | ||||
| import java.util.Map; | import java.util.Map; | ||||
| import java.util.HashMap; | |||||
| import org.apache.avalon.excalibur.i18n.ResourceManager; | import org.apache.avalon.excalibur.i18n.ResourceManager; | ||||
| import org.apache.avalon.excalibur.i18n.Resources; | import org.apache.avalon.excalibur.i18n.Resources; | ||||
| import org.apache.avalon.excalibur.io.FileUtil; | import org.apache.avalon.excalibur.io.FileUtil; | ||||
| import org.apache.avalon.framework.context.Context; | |||||
| import org.apache.avalon.framework.context.ContextException; | |||||
| import org.apache.avalon.framework.logger.Logger; | import org.apache.avalon.framework.logger.Logger; | ||||
| import org.apache.avalon.framework.service.ServiceException; | import org.apache.avalon.framework.service.ServiceException; | ||||
| import org.apache.avalon.framework.service.ServiceManager; | import org.apache.avalon.framework.service.ServiceManager; | ||||
| @@ -30,17 +29,19 @@ import org.apache.myrmidon.interfaces.property.PropertyResolver; | |||||
| * @version $Revision$ $Date$ | * @version $Revision$ $Date$ | ||||
| */ | */ | ||||
| public class DefaultTaskContext | public class DefaultTaskContext | ||||
| implements TaskContext, Context | |||||
| implements TaskContext | |||||
| { | { | ||||
| private final static Resources REZ = | private final static Resources REZ = | ||||
| ResourceManager.getPackageResources( DefaultTaskContext.class ); | ResourceManager.getPackageResources( DefaultTaskContext.class ); | ||||
| // Property name validator allows digits, but no internal whitespace. | // Property name validator allows digits, but no internal whitespace. | ||||
| private static DefaultNameValidator c_propertyNameValidator = new DefaultNameValidator(); | |||||
| private static DefaultNameValidator c_propertyNameValidator = | |||||
| new DefaultNameValidator(); | |||||
| static | static | ||||
| { | { | ||||
| c_propertyNameValidator.setAllowInternalWhitespace( false ); | c_propertyNameValidator.setAllowInternalWhitespace( false ); | ||||
| c_propertyNameValidator.setAdditionalInternalCharacters( "_-.+" ); | |||||
| } | } | ||||
| private final Map m_contextData = new Hashtable(); | private final Map m_contextData = new Hashtable(); | ||||
| @@ -193,7 +194,7 @@ public class DefaultTaskContext | |||||
| */ | */ | ||||
| public Map getProperties() | public Map getProperties() | ||||
| { | { | ||||
| return null; | |||||
| return new HashMap( m_contextData ); | |||||
| } | } | ||||
| /** | /** | ||||
| @@ -354,20 +355,6 @@ public class DefaultTaskContext | |||||
| return context; | return context; | ||||
| } | } | ||||
| /** | |||||
| * Returns a property. | |||||
| */ | |||||
| public Object get( final Object key ) throws ContextException | |||||
| { | |||||
| final Object value = getProperty( (String)key ); | |||||
| if( value == null ) | |||||
| { | |||||
| final String message = REZ.getString( "unknown-property.error", key ); | |||||
| throw new ContextException( message ); | |||||
| } | |||||
| return value; | |||||
| } | |||||
| /** | /** | ||||
| * Checks that the supplied property name is valid. | * Checks that the supplied property name is valid. | ||||
| */ | */ | ||||
| @@ -7,8 +7,8 @@ | |||||
| */ | */ | ||||
| package org.apache.myrmidon.interfaces.property; | package org.apache.myrmidon.interfaces.property; | ||||
| import org.apache.avalon.framework.context.Context; | |||||
| import org.apache.myrmidon.api.TaskException; | import org.apache.myrmidon.api.TaskException; | ||||
| import org.apache.myrmidon.api.TaskContext; | |||||
| /** | /** | ||||
| * | * | ||||
| @@ -33,6 +33,6 @@ public interface PropertyResolver | |||||
| * @exception TaskException if an error occurs | * @exception TaskException if an error occurs | ||||
| */ | */ | ||||
| Object resolveProperties( final String value, | Object resolveProperties( final String value, | ||||
| final Context context ) | |||||
| final TaskContext context ) | |||||
| throws TaskException; | throws TaskException; | ||||
| } | } | ||||
| @@ -10,9 +10,9 @@ package org.apache.myrmidon.components.property.test; | |||||
| import java.io.File; | import java.io.File; | ||||
| import java.util.Date; | import java.util.Date; | ||||
| import org.apache.avalon.excalibur.i18n.Resources; | import org.apache.avalon.excalibur.i18n.Resources; | ||||
| import org.apache.avalon.framework.context.Context; | |||||
| import org.apache.myrmidon.AbstractMyrmidonTest; | import org.apache.myrmidon.AbstractMyrmidonTest; | ||||
| import org.apache.myrmidon.api.TaskException; | import org.apache.myrmidon.api.TaskException; | ||||
| import org.apache.myrmidon.api.TaskContext; | |||||
| import org.apache.myrmidon.components.workspace.DefaultTaskContext; | import org.apache.myrmidon.components.workspace.DefaultTaskContext; | ||||
| import org.apache.myrmidon.interfaces.property.PropertyResolver; | import org.apache.myrmidon.interfaces.property.PropertyResolver; | ||||
| @@ -117,7 +117,7 @@ public abstract class AbstractPropertyResolverTestCase | |||||
| */ | */ | ||||
| protected void doTestResolution( final String value, | protected void doTestResolution( final String value, | ||||
| final Object expected, | final Object expected, | ||||
| final Context context ) | |||||
| final TaskContext context ) | |||||
| throws Exception | throws Exception | ||||
| { | { | ||||
| final Object resolved = m_resolver.resolveProperties( value, context ); | final Object resolved = m_resolver.resolveProperties( value, context ); | ||||
| @@ -131,7 +131,7 @@ public abstract class AbstractPropertyResolverTestCase | |||||
| */ | */ | ||||
| protected void doTestFailure( final String value, | protected void doTestFailure( final String value, | ||||
| final String expectedErrorMessage, | final String expectedErrorMessage, | ||||
| final Context context ) | |||||
| final TaskContext context ) | |||||
| { | { | ||||
| try | try | ||||
| { | { | ||||
| @@ -10,9 +10,9 @@ package org.apache.myrmidon.components.property.test; | |||||
| import java.io.File; | import java.io.File; | ||||
| import java.util.Date; | import java.util.Date; | ||||
| import org.apache.avalon.excalibur.i18n.Resources; | import org.apache.avalon.excalibur.i18n.Resources; | ||||
| import org.apache.avalon.framework.context.Context; | |||||
| import org.apache.myrmidon.AbstractMyrmidonTest; | import org.apache.myrmidon.AbstractMyrmidonTest; | ||||
| import org.apache.myrmidon.api.TaskException; | import org.apache.myrmidon.api.TaskException; | ||||
| import org.apache.myrmidon.api.TaskContext; | |||||
| import org.apache.myrmidon.components.workspace.DefaultTaskContext; | import org.apache.myrmidon.components.workspace.DefaultTaskContext; | ||||
| import org.apache.myrmidon.interfaces.property.PropertyResolver; | import org.apache.myrmidon.interfaces.property.PropertyResolver; | ||||
| @@ -117,7 +117,7 @@ public abstract class AbstractPropertyResolverTestCase | |||||
| */ | */ | ||||
| protected void doTestResolution( final String value, | protected void doTestResolution( final String value, | ||||
| final Object expected, | final Object expected, | ||||
| final Context context ) | |||||
| final TaskContext context ) | |||||
| throws Exception | throws Exception | ||||
| { | { | ||||
| final Object resolved = m_resolver.resolveProperties( value, context ); | final Object resolved = m_resolver.resolveProperties( value, context ); | ||||
| @@ -131,7 +131,7 @@ public abstract class AbstractPropertyResolverTestCase | |||||
| */ | */ | ||||
| protected void doTestFailure( final String value, | protected void doTestFailure( final String value, | ||||
| final String expectedErrorMessage, | final String expectedErrorMessage, | ||||
| final Context context ) | |||||
| final TaskContext context ) | |||||
| { | { | ||||
| try | try | ||||
| { | { | ||||