* 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-ffa450edef68master
@@ -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 | ||||
{ | { | ||||