Browse Source

Changes to DefaultConfigurer:

* Uses the DataType role when creating instances for interface properties,
  rather than using the interface itself as the role.

* Added ObjectConfigurer.getTypedProperty().  This replaces the implicit
  behaviour in DefaultObjectConfigurer.getProperty() where the typed
  property was returned for an unknown property name.

* Typed properties are set using attributes and references, with the
  property's interface role shorthand name.  Previously, the DefaultConfigurer
  would attempt to set the typed property for any unknown attribute or
  reference name.

* Can have a set() method for a typed property, rather than an add() method.
  Same semantics as setX() and addX() methods.

* Added a several more test cases.


git-svn-id: https://svn.apache.org/repos/asf/ant/core/trunk@271227 13f79535-47bb-0310-9956-ffa450edef68
master
adammurdoch 23 years ago
parent
commit
7a5c30f33c
14 changed files with 603 additions and 84 deletions
  1. +78
    -20
      proposal/myrmidon/src/java/org/apache/myrmidon/components/configurer/DefaultConfigurer.java
  2. +51
    -36
      proposal/myrmidon/src/java/org/apache/myrmidon/components/configurer/DefaultObjectConfigurer.java
  3. +10
    -0
      proposal/myrmidon/src/java/org/apache/myrmidon/components/configurer/ObjectConfigurer.java
  4. +4
    -4
      proposal/myrmidon/src/java/org/apache/myrmidon/components/configurer/Resources.properties
  5. +18
    -0
      proposal/myrmidon/src/test/org/apache/myrmidon/components/AbstractComponentTest.java
  6. +46
    -0
      proposal/myrmidon/src/test/org/apache/myrmidon/components/configurer/ConfigTest10.java
  7. +130
    -12
      proposal/myrmidon/src/test/org/apache/myrmidon/components/configurer/DefaultConfigurerTest.java
  8. +4
    -0
      proposal/myrmidon/src/test/org/apache/myrmidon/components/configurer/MyRole1.java
  9. +32
    -0
      proposal/myrmidon/src/test/org/apache/myrmidon/components/configurer/StringToMyRole1Converter.java
  10. +18
    -0
      proposal/myrmidon/src/testcases/org/apache/myrmidon/components/AbstractComponentTest.java
  11. +46
    -0
      proposal/myrmidon/src/testcases/org/apache/myrmidon/components/configurer/ConfigTest10.java
  12. +130
    -12
      proposal/myrmidon/src/testcases/org/apache/myrmidon/components/configurer/DefaultConfigurerTest.java
  13. +4
    -0
      proposal/myrmidon/src/testcases/org/apache/myrmidon/components/configurer/MyRole1.java
  14. +32
    -0
      proposal/myrmidon/src/testcases/org/apache/myrmidon/components/configurer/StringToMyRole1Converter.java

+ 78
- 20
proposal/myrmidon/src/java/org/apache/myrmidon/components/configurer/DefaultConfigurer.java View File

@@ -28,6 +28,8 @@ import org.apache.myrmidon.interfaces.converter.MasterConverter;
import org.apache.myrmidon.interfaces.type.TypeException;
import org.apache.myrmidon.interfaces.type.TypeFactory;
import org.apache.myrmidon.interfaces.type.TypeManager;
import org.apache.myrmidon.interfaces.role.RoleManager;
import org.apache.myrmidon.framework.DataType;

/**
* Class used to configure tasks.
@@ -48,6 +50,9 @@ public class DefaultConfigurer
//TypeManager to use to create types in typed adders
private TypeManager m_typeManager;

//RoleManager to use to map from type names -> role shorthand
private RoleManager m_roleManager;

///Cached object configurers. This is a map from Class to the
///ObjectConfigurer for that class.
private Map m_configurerCache = new HashMap();
@@ -57,6 +62,7 @@ public class DefaultConfigurer
{
m_converter = (MasterConverter)componentManager.lookup( MasterConverter.ROLE );
m_typeManager = (TypeManager)componentManager.lookup( TypeManager.ROLE );
m_roleManager = (RoleManager)componentManager.lookup( RoleManager.ROLE );
}

/**
@@ -122,7 +128,6 @@ public class DefaultConfigurer
}
catch( final ConfigurationException ce )
{
ce.fillInStackTrace();
throw ce;
}
catch( final CascadingException ce )
@@ -151,7 +156,6 @@ public class DefaultConfigurer
}
catch( final ConfigurationException ce )
{
ce.fillInStackTrace();
throw ce;
}
catch( final CascadingException ce )
@@ -180,13 +184,12 @@ public class DefaultConfigurer
}
catch( final ConfigurationException ce )
{
ce.fillInStackTrace();
throw ce;
}
catch( final CascadingException ce )
{
final String message =
REZ.getString( "bad-set-element.error", name );
REZ.getString( "bad-set-element.error", elemName, name );
throw new ConfigurationException( message, ce );
}
}
@@ -269,8 +272,8 @@ public class DefaultConfigurer
final String name = element.getName();

// Locate the configurer for the child element
final PropertyConfigurer childConfigurer =
state.getConfigurer().getProperty( name );
final PropertyConfigurer childConfigurer
= getConfigurerFromName( state.getConfigurer(), name, true );

// Create & configure the child element
final Object child =
@@ -288,9 +291,6 @@ public class DefaultConfigurer
final Context context )
throws CascadingException
{
// Adjust the name
final String elementName = element.getName();
final String name = elementName.substring( 0, elementName.length() - 4 );

// Extract the id
final String id = element.getAttribute( "id" );
@@ -302,6 +302,7 @@ public class DefaultConfigurer
}

// Set the property
final String name = element.getName();
setReference( state, name, id, context );
}

@@ -309,13 +310,17 @@ public class DefaultConfigurer
* Sets a property using a reference.
*/
private void setReference( final ConfigurationState state,
final String name,
final String refName,
final String unresolvedId,
final Context context )
throws CascadingException
{
// Locate the configurer for the child element
final PropertyConfigurer childConfigurer = state.getConfigurer().getProperty( name );
// Adjust the name
final String name = refName.substring( 0, refName.length() - 4 );

// Locate the configurer for the property
final PropertyConfigurer childConfigurer
= getConfigurerFromName( state.getConfigurer(), name, false );

// Resolve any props in the id
Object id = PropertyUtil.resolveProperty( unresolvedId, context, false );
@@ -356,14 +361,13 @@ public class DefaultConfigurer
if( name.toLowerCase().endsWith( "-ref" ) )
{
// A reference
final String refName = name.substring( 0, name.length() - 4 );
setReference( state, refName, value, context );
setReference( state, name, value, context );
}
else
{
// Set the value
final PropertyConfigurer propConfigurer =
state.getConfigurer().getProperty( name );
PropertyConfigurer propConfigurer
= getConfigurerFromName( state.getConfigurer(), name, false );
setValue( propConfigurer, state, value, context );
}
}
@@ -424,7 +428,7 @@ public class DefaultConfigurer
}
else if( null == child )
{
// Create an instance using the default constructor
// Create an instance
if( type.isInterface() )
{
child = createdTypedObject( name, type );
@@ -439,18 +443,62 @@ public class DefaultConfigurer
return child;
}

/**
* Determines the property configurer to use for a particular element
* or attribute. If the supplied name matches a property of the
* class being configured, that property configurer is returned. If
* the supplied name matches the role shorthand for the class' typed
* property, then the typed property configurer is used.
*
* @param configurer The configurer for the class being configured.
* @param name The attribute/element name.
*/
private PropertyConfigurer getConfigurerFromName( final ObjectConfigurer configurer,
final String name,
boolean ignoreRoleName )
throws NoSuchPropertyException
{
// Try a named property
final NoSuchPropertyException exc;
try
{
return configurer.getProperty( name );
}
catch( NoSuchPropertyException e )
{
// Keep for later
exc = e;
}

// Try a typed property
final PropertyConfigurer propertyConfigurer = configurer.getTypedProperty();
if( ! ignoreRoleName )
{
final String roleShorthand = m_roleManager.getNameForRole( propertyConfigurer.getType().getName() );
if( ! name.equalsIgnoreCase(roleShorthand) )
{
// Rethrow the original exception
throw exc;
}
}

return propertyConfigurer;
}

/**
* Utility method to create an instance of the
* specified type that satisfied supplied interface.
* specified type that satisfies supplied interface.
*/
private Object createdTypedObject( final String name,
final Class type )
throws ConfigurationException
{
final TypeFactory factory = getTypeFactory( type );
// Attempt to create the object
final Object obj;
try
{
return factory.create( name );
final TypeFactory factory = getTypeFactory( DataType.class );
obj = factory.create( name );
}
catch( final Exception e )
{
@@ -460,6 +508,16 @@ public class DefaultConfigurer
type.getName() );
throw new ConfigurationException( message, e );
}

// Check the types
if( ! type.isInstance( obj ) )
{
final String message =
REZ.getString( "mismatched-typed-object.error", name, type.getName() );
throw new ConfigurationException( message );
}

return obj;
}

/**


+ 51
- 36
proposal/myrmidon/src/java/org/apache/myrmidon/components/configurer/DefaultObjectConfigurer.java View File

@@ -46,6 +46,11 @@ class DefaultObjectConfigurer
*/
private final List m_allProps = new ArrayList();

/**
* The typed property configurer.
*/
private PropertyConfigurer m_typedPropConfigurer;

/**
* Content configurer.
*/
@@ -67,15 +72,15 @@ class DefaultObjectConfigurer
public void enableAll()
throws ConfigurationException
{
// TODO - get rid of creators, and either setter or adders
enableAdders();
// TODO - get rid of creators
enableProperties();
enableContent();
}

/**
* Enables all creators + adders.
*/
public void enableAdders()
private void enableProperties()
throws ConfigurationException
{
final Map creators = findCreators();
@@ -119,6 +124,16 @@ class DefaultObjectConfigurer
type = addMethod.getParameterTypes()[ 0 ];
}

final boolean isTypedProp = (propName.length() == 0);
if( isTypedProp && !type.isInterface() )
{
final String message =
REZ.getString( "typed-adder-non-interface.error",
m_class.getName(),
type.getName() );
throw new ConfigurationException( message );
}

// Determine the max count for the property
int maxCount = Integer.MAX_VALUE;
if( addMethod != null && addMethod.getName().startsWith( "set" ) )
@@ -132,8 +147,15 @@ class DefaultObjectConfigurer
createMethod,
addMethod,
maxCount );
m_props.put( propName, configurer );
m_allProps.add( configurer );
if( isTypedProp )
{
m_typedPropConfigurer = configurer;
}
else
{
m_props.put( propName, configurer );
}
}
}

@@ -160,19 +182,7 @@ class DefaultObjectConfigurer
continue;
}

final boolean isTypedAdder = methodName.equals( "add" );

final Class paramType = method.getParameterTypes()[ 0 ];
if( isTypedAdder && !paramType.isInterface() )
{
final String message =
REZ.getString( "typed-adder-non-interface.error",
m_class.getName(),
paramType.getName() );
throw new ConfigurationException( message );
}

// TODO - un-hard-code this
// Skip the text content method
if( methodName.equals( "addContent" ) )
{
continue;
@@ -180,8 +190,7 @@ class DefaultObjectConfigurer

// Extract property name
final String propName = extractName( 3, methodName );

final Class type = paramType;
final Class type = method.getParameterTypes()[0];

// Add to the adders map
if( adders.containsKey( propName ) )
@@ -190,15 +199,7 @@ class DefaultObjectConfigurer
final Class currentType = candidate.getParameterTypes()[ 0 ];

// Ditch the string version, if any
if( isTypedAdder )
{
// Both are string, or both are not string
final String message =
REZ.getString( "multiple-typed-adder-methods-for-element.error",
m_class.getName() );
throw new ConfigurationException( message );
}
else if( currentType != String.class && type == String.class )
if( currentType != String.class && type == String.class )
{
// New type is string, and current type is not. Ignore
// the new method
@@ -217,6 +218,7 @@ class DefaultObjectConfigurer
// Else, current type is string, and new type is not, so
// continue below, and overwrite the current method
}

adders.put( propName, method );
}
return adders;
@@ -253,7 +255,7 @@ class DefaultObjectConfigurer
final String message =
REZ.getString( "multiple-creator-methods-for-element.error",
m_class.getName(),
elemName );
methodName );
throw new ConfigurationException( message );
}
creators.put( elemName, method );
@@ -264,9 +266,13 @@ class DefaultObjectConfigurer
/**
* Enables content.
*/
public void enableContent()
private void enableContent()
throws ConfigurationException
{
// TODO - should be using 'setContent', rather than 'addContent',
// to better match the call-at-most-once semantics of the other
// setter methods

// Locate any 'addContent' methods, which return void, and take
// a single parameter.
final Method[] methods = m_class.getMethods();
@@ -355,16 +361,25 @@ class DefaultObjectConfigurer
return configurer;
}

//Maybe there is a typed adder??
configurer = (PropertyConfigurer)m_props.get( "" );
if( null != configurer )
// Unknown property
final String message = REZ.getString( "unknown-property.error", m_class.getName(), name );
throw new NoSuchPropertyException( message );
}

/**
* Returns a configurer for the typed property of this class.
*/
public PropertyConfigurer getTypedProperty()
throws NoSuchPropertyException
{
if( null != m_typedPropConfigurer )
{
return configurer;
return m_typedPropConfigurer;
}
else
{
// Unknown property
final String message = REZ.getString( "unknown-property.error", m_class.getName(), name );
// No typed property
final String message = REZ.getString( "no-typed-property.error", m_class.getName() );
throw new NoSuchPropertyException( message );
}
}


+ 10
- 0
proposal/myrmidon/src/java/org/apache/myrmidon/components/configurer/ObjectConfigurer.java View File

@@ -58,4 +58,14 @@ interface ObjectConfigurer
*/
PropertyConfigurer getContentConfigurer()
throws NoSuchPropertyException;

/**
* Returns a configurer for the typed property of this class.
*
* @return A configurer for the typed property.
* @throws NoSuchPropertyException If the class does not have a typed
* property.
*/
PropertyConfigurer getTypedProperty()
throws NoSuchPropertyException;
}

+ 4
- 4
proposal/myrmidon/src/java/org/apache/myrmidon/components/configurer/Resources.properties View File

@@ -3,9 +3,8 @@ extra-config-for-ref.error=A reference element can only include an "id" attribut
get-ref.error=Could not locate reference "{0}".
mismatch-ref-types.error=Mismatched type for reference "{0}". Was expecting an object of type {1}, instead found an object of type {2}.
incompatible-element-types.error=Incompatible creator and adder/setter methods found in class {0} for property "{1}".
multiple-adder-methods-for-element.error=Multiple adder/setter methods found in class {0} for property "{1}".
multiple-typed-adder-methods-for-element.error=Multiple typed add() methods found in class {0}.
multiple-creator-methods-for-element.error=Multiple creator methods found in class {0} for property "{1}".
multiple-adder-methods-for-element.error=Multiple add{1}() or set{1}() methods found in class {0}.
multiple-creator-methods-for-element.error=Multiple {1}() methods found in class {0}.
multiple-content-setter-methods.error=Multiple content setter methods found in class {0}.
pending-property-value.error=An object created using the creator method has not been set using the adder/setter method.
unknown-property.error=Class {0} does not have a "{1}" property.
@@ -22,4 +21,5 @@ no-content.error=Text content is not allowed for element <{0}>.
bad-set-content.error=Could not set text content for element <{0}>.
typed-adder-non-interface.error=The typed adder for class "{0}" must have a single parameter that is an interface rather than {1} which defines a class.
no-factory-for-role.error=Unable to locate type factory for role "{0}"
create-typed-object.error=Could not create an object of type "{0}" of class {1}.
create-typed-object.error=Could not create an object of type "{0}" of class {1}.
typed-property-not-supported.error=Class {0} does not have a typed property.

+ 18
- 0
proposal/myrmidon/src/test/org/apache/myrmidon/components/AbstractComponentTest.java View File

@@ -38,6 +38,9 @@ import org.apache.myrmidon.interfaces.deployer.Deployer;
import org.apache.myrmidon.interfaces.extensions.ExtensionManager;
import org.apache.myrmidon.interfaces.role.RoleManager;
import org.apache.myrmidon.interfaces.type.TypeManager;
import org.apache.myrmidon.interfaces.type.TypeException;
import org.apache.myrmidon.interfaces.type.DefaultTypeFactory;
import org.apache.myrmidon.converter.Converter;

/**
* A base class for tests for the default components.
@@ -145,6 +148,21 @@ public abstract class AbstractComponentTest
}
}

/**
* Utility method to register a Converter.
*/
protected void registerConverter( final Class converterClass,
final Class sourceClass,
final Class destClass )
throws ComponentException, TypeException
{
ConverterRegistry converterRegistry = (ConverterRegistry)getComponentManager().lookup( ConverterRegistry.ROLE );
converterRegistry.registerConverter( converterClass.getName(), sourceClass.getName(), destClass.getName() );
DefaultTypeFactory factory = new DefaultTypeFactory( getClass().getClassLoader() );
factory.addNameClassMapping( converterClass.getName(), converterClass.getName() );
getTypeManager().registerType( Converter.class, converterClass.getName(), factory );
}

/**
* Asserts that an exception contains the expected message.
*


+ 46
- 0
proposal/myrmidon/src/test/org/apache/myrmidon/components/configurer/ConfigTest10.java View File

@@ -0,0 +1,46 @@
/*
* 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.txt file.
*/
package org.apache.myrmidon.components.configurer;

import org.apache.myrmidon.components.AbstractComponentTest;

/**
* A class for testing conversion.
*
* @author <a href="mailto:adammurdoch@apache.org">Adam Murdoch</a>
*/
public class ConfigTest10
{
private int m_intProp;
private Integer m_integerProp;

public void setIntProp( int intProp )
{
m_intProp = intProp;
}

public void setIntegerProp( Integer integerProp )
{
m_integerProp = integerProp;
}

public boolean equals( Object obj )
{
ConfigTest10 test = (ConfigTest10)obj;
if( m_intProp != test.m_intProp )
{
return false;
}
if ( !AbstractComponentTest.equals( m_integerProp, test.m_integerProp ) )
{
return false;
}

return true;
}
}

+ 130
- 12
proposal/myrmidon/src/test/org/apache/myrmidon/components/configurer/DefaultConfigurerTest.java View File

@@ -8,7 +8,7 @@
package org.apache.myrmidon.components.configurer;

import java.io.File;
import junit.framework.AssertionFailedError;
import org.apache.antlib.core.StringToIntegerConverter;
import org.apache.avalon.excalibur.i18n.ResourceManager;
import org.apache.avalon.excalibur.i18n.Resources;
import org.apache.avalon.framework.configuration.ConfigurationException;
@@ -16,7 +16,9 @@ import org.apache.avalon.framework.configuration.DefaultConfiguration;
import org.apache.myrmidon.api.TaskContext;
import org.apache.myrmidon.components.AbstractComponentTest;
import org.apache.myrmidon.components.workspace.DefaultTaskContext;
import org.apache.myrmidon.framework.DataType;
import org.apache.myrmidon.interfaces.configurer.Configurer;
import org.apache.myrmidon.interfaces.role.RoleManager;
import org.apache.myrmidon.interfaces.type.DefaultTypeFactory;

/**
@@ -80,6 +82,35 @@ public class DefaultConfigurerTest
assertEquals( expected, test );
}

/**
* Tests attribute conversion.
*/
public void testAttributeConvert()
throws Exception
{
// Setup test data
final DefaultConfiguration config = new DefaultConfiguration( "test", "test" );
config.setAttribute( "int-prop", "90" );
config.setAttribute( "integer-prop", "-401" );

// Register the converter
final Class converterClass = StringToIntegerConverter.class;
final Class sourceClass = String.class;
final Class destClass = Integer.class;
registerConverter( converterClass, sourceClass, destClass );

final ConfigTest10 test = new ConfigTest10();

// Configure the object
m_configurer.configure( test, config, m_context );

// Check result
final ConfigTest10 expected = new ConfigTest10();
expected.setIntProp( 90 );
expected.setIntegerProp( new Integer(-401) );
assertEquals( expected, test );
}

/**
* Tests setting an unknown attribute.
*/
@@ -96,7 +127,7 @@ public class DefaultConfigurerTest
try
{
m_configurer.configure( test, config, m_context );
throw new AssertionFailedError();
fail();
}
catch( final ConfigurationException ce )
{
@@ -155,7 +186,7 @@ public class DefaultConfigurerTest
try
{
m_configurer.configure( test, config, m_context );
throw new AssertionFailedError();
fail();
}
catch( final ConfigurationException ce )
{
@@ -202,7 +233,7 @@ public class DefaultConfigurerTest
try
{
m_configurer.configure( test, config, m_context );
throw new AssertionFailedError();
fail();
}
catch( final ConfigurationException ce )
{
@@ -280,6 +311,34 @@ public class DefaultConfigurerTest
assertEquals( expected, test );
}

/**
* Tests that extra content is not allowed in a reference element.
*/
public void testReferenceElementExtra()
throws Exception
{
// Setup test data
final DefaultConfiguration config = new DefaultConfiguration( "test", "test" );
final DefaultConfiguration elem = new DefaultConfiguration( "some-prop-ref", "test" );
elem.setAttribute( "id", "prop-a" );
elem.setAttribute( "extra-attr", "some value" );
config.addChild( elem );

final ConfigTest1 test = new ConfigTest1();

try
{
// Configure the object
m_configurer.configure( test, config, m_context );
fail();
}
catch( ConfigurationException e )
{
final String message = REZ.getString( "extra-config-for-ref.error" );
assertSameMessage( message, e );
}
}

/**
* Tests whether an object with a non-iterface typed adder causes an
* exception.
@@ -326,8 +385,9 @@ public class DefaultConfigurerTest
}
catch( final ConfigurationException ce )
{
final String message = REZ.getString( "multiple-typed-adder-methods-for-element.error",
ConfigTest5.class.getName() );
final String message = REZ.getString( "multiple-adder-methods-for-element.error",
ConfigTest5.class.getName(),
"");
assertSameMessage( message, ce );
}
}
@@ -349,8 +409,8 @@ public class DefaultConfigurerTest
final DefaultTypeFactory factory = new DefaultTypeFactory( loader );
factory.addNameClassMapping( "my-type1", MyType1.class.getName() );
factory.addNameClassMapping( "my-type2", MyType2.class.getName() );
getTypeManager().registerType( MyRole1.class, "my-type1", factory );
getTypeManager().registerType( MyRole1.class, "my-type2", factory );
getTypeManager().registerType( DataType.class, "my-type1", factory );
getTypeManager().registerType( DataType.class, "my-type2", factory );

final ConfigTest6 test = new ConfigTest6();

@@ -363,6 +423,32 @@ public class DefaultConfigurerTest
assertEquals( expected, test );
}

/**
* Tests to see if typed adder can be used via an attribute.
*/
public void testTypedAdderAttribute()
throws Exception
{
// Setup test data
final DefaultConfiguration config = new DefaultConfiguration( "test", "test" );
config.setAttribute( "my-role1", "some value" );

// Set up the converter and role
RoleManager roleMgr = (RoleManager)getComponentManager().lookup( RoleManager.ROLE );
roleMgr.addNameRoleMapping( "my-role1", MyRole1.ROLE );
registerConverter( StringToMyRole1Converter.class, String.class, MyRole1.class );

final ConfigTest6 test = new ConfigTest6();

// Configure the object
m_configurer.configure( test, config, m_context );

// Check result
final ConfigTest6 expected = new ConfigTest6();
expected.add( new MyType1() );
assertEquals( expected, test );
}

/**
* Tests to see if typed adder works, with Configuration type.
*/
@@ -388,7 +474,7 @@ public class DefaultConfigurerTest
}

/**
* Tests to see if typed adder works, with Configuration objects.
* Tests to see if adder works, with Configuration objects.
*/
public void testConfigAdder()
throws Exception
@@ -470,7 +556,7 @@ public class DefaultConfigurerTest
try
{
m_configurer.configure( test, config, m_context );
throw new AssertionFailedError();
fail();
}
catch( ConfigurationException e )
{
@@ -498,7 +584,7 @@ public class DefaultConfigurerTest
try
{
m_configurer.configure( test, config, m_context );
throw new AssertionFailedError();
fail();
}
catch( ConfigurationException e )
{
@@ -510,6 +596,38 @@ public class DefaultConfigurerTest
}
}

/**
* Tests using a reference with a typed adder. Tests using an attribute
* and a nested element.
*/
public void testTypedAdderReference()
throws Exception
{
// Setup test data
final DefaultConfiguration config = new DefaultConfiguration( "test", "test" );
config.setAttribute( "my-role1-ref", "id" );
final DefaultConfiguration child = new DefaultConfiguration( "my-role1-ref", "test" );
child.setAttribute( "id", "id2" );
config.addChild( child );

// Add role mapping, and add to reference to context
final RoleManager roleMgr = (RoleManager)getComponentManager().lookup( RoleManager.ROLE );
roleMgr.addNameRoleMapping( "my-role1", MyRole1.class.getName() );
m_context.setProperty( "id", new MyType1() );
m_context.setProperty( "id2", new MyType2() );

final ConfigTest6 test = new ConfigTest6();

// Configure the object
m_configurer.configure( test, config, m_context );

// Compare against expected value
final ConfigTest6 expected = new ConfigTest6();
expected.add( new MyType1() );
expected.add( new MyType2() );
assertEquals( expected, test );
}

/**
* Tests reporting of nested errors.
*/
@@ -527,7 +645,7 @@ public class DefaultConfigurerTest
{
// Configure the object
m_configurer.configure( test, config, m_context );
throw new AssertionFailedError();
fail();
}
catch( ConfigurationException e )
{


+ 4
- 0
proposal/myrmidon/src/test/org/apache/myrmidon/components/configurer/MyRole1.java View File

@@ -7,6 +7,8 @@
*/
package org.apache.myrmidon.components.configurer;

import org.apache.myrmidon.framework.DataType;

/**
* A basic interface to test configurer.
*
@@ -14,5 +16,7 @@ package org.apache.myrmidon.components.configurer;
* @version $Revision$ $Date$
*/
public interface MyRole1
extends DataType
{
String ROLE = MyRole1.class.getName();
}

+ 32
- 0
proposal/myrmidon/src/test/org/apache/myrmidon/components/configurer/StringToMyRole1Converter.java View File

@@ -0,0 +1,32 @@
/*
* 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.txt file.
*/
package org.apache.myrmidon.components.configurer;

import org.apache.myrmidon.converter.AbstractConverter;
import org.apache.myrmidon.converter.ConverterException;
import org.apache.avalon.framework.context.Context;

/**
* Converts from a string to a {@link MyRole1} implementation.
*
* @author <a href="mailto:adammurdoch@apache.org">Adam Murdoch</a>
*/
public class StringToMyRole1Converter
extends AbstractConverter
{
public StringToMyRole1Converter()
{
super( String.class, MyRole1.class );
}

protected Object convert( Object original, Context context )
throws ConverterException
{
return new MyType1();
}
}

+ 18
- 0
proposal/myrmidon/src/testcases/org/apache/myrmidon/components/AbstractComponentTest.java View File

@@ -38,6 +38,9 @@ import org.apache.myrmidon.interfaces.deployer.Deployer;
import org.apache.myrmidon.interfaces.extensions.ExtensionManager;
import org.apache.myrmidon.interfaces.role.RoleManager;
import org.apache.myrmidon.interfaces.type.TypeManager;
import org.apache.myrmidon.interfaces.type.TypeException;
import org.apache.myrmidon.interfaces.type.DefaultTypeFactory;
import org.apache.myrmidon.converter.Converter;

/**
* A base class for tests for the default components.
@@ -145,6 +148,21 @@ public abstract class AbstractComponentTest
}
}

/**
* Utility method to register a Converter.
*/
protected void registerConverter( final Class converterClass,
final Class sourceClass,
final Class destClass )
throws ComponentException, TypeException
{
ConverterRegistry converterRegistry = (ConverterRegistry)getComponentManager().lookup( ConverterRegistry.ROLE );
converterRegistry.registerConverter( converterClass.getName(), sourceClass.getName(), destClass.getName() );
DefaultTypeFactory factory = new DefaultTypeFactory( getClass().getClassLoader() );
factory.addNameClassMapping( converterClass.getName(), converterClass.getName() );
getTypeManager().registerType( Converter.class, converterClass.getName(), factory );
}

/**
* Asserts that an exception contains the expected message.
*


+ 46
- 0
proposal/myrmidon/src/testcases/org/apache/myrmidon/components/configurer/ConfigTest10.java View File

@@ -0,0 +1,46 @@
/*
* 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.txt file.
*/
package org.apache.myrmidon.components.configurer;

import org.apache.myrmidon.components.AbstractComponentTest;

/**
* A class for testing conversion.
*
* @author <a href="mailto:adammurdoch@apache.org">Adam Murdoch</a>
*/
public class ConfigTest10
{
private int m_intProp;
private Integer m_integerProp;

public void setIntProp( int intProp )
{
m_intProp = intProp;
}

public void setIntegerProp( Integer integerProp )
{
m_integerProp = integerProp;
}

public boolean equals( Object obj )
{
ConfigTest10 test = (ConfigTest10)obj;
if( m_intProp != test.m_intProp )
{
return false;
}
if ( !AbstractComponentTest.equals( m_integerProp, test.m_integerProp ) )
{
return false;
}

return true;
}
}

+ 130
- 12
proposal/myrmidon/src/testcases/org/apache/myrmidon/components/configurer/DefaultConfigurerTest.java View File

@@ -8,7 +8,7 @@
package org.apache.myrmidon.components.configurer;

import java.io.File;
import junit.framework.AssertionFailedError;
import org.apache.antlib.core.StringToIntegerConverter;
import org.apache.avalon.excalibur.i18n.ResourceManager;
import org.apache.avalon.excalibur.i18n.Resources;
import org.apache.avalon.framework.configuration.ConfigurationException;
@@ -16,7 +16,9 @@ import org.apache.avalon.framework.configuration.DefaultConfiguration;
import org.apache.myrmidon.api.TaskContext;
import org.apache.myrmidon.components.AbstractComponentTest;
import org.apache.myrmidon.components.workspace.DefaultTaskContext;
import org.apache.myrmidon.framework.DataType;
import org.apache.myrmidon.interfaces.configurer.Configurer;
import org.apache.myrmidon.interfaces.role.RoleManager;
import org.apache.myrmidon.interfaces.type.DefaultTypeFactory;

/**
@@ -80,6 +82,35 @@ public class DefaultConfigurerTest
assertEquals( expected, test );
}

/**
* Tests attribute conversion.
*/
public void testAttributeConvert()
throws Exception
{
// Setup test data
final DefaultConfiguration config = new DefaultConfiguration( "test", "test" );
config.setAttribute( "int-prop", "90" );
config.setAttribute( "integer-prop", "-401" );

// Register the converter
final Class converterClass = StringToIntegerConverter.class;
final Class sourceClass = String.class;
final Class destClass = Integer.class;
registerConverter( converterClass, sourceClass, destClass );

final ConfigTest10 test = new ConfigTest10();

// Configure the object
m_configurer.configure( test, config, m_context );

// Check result
final ConfigTest10 expected = new ConfigTest10();
expected.setIntProp( 90 );
expected.setIntegerProp( new Integer(-401) );
assertEquals( expected, test );
}

/**
* Tests setting an unknown attribute.
*/
@@ -96,7 +127,7 @@ public class DefaultConfigurerTest
try
{
m_configurer.configure( test, config, m_context );
throw new AssertionFailedError();
fail();
}
catch( final ConfigurationException ce )
{
@@ -155,7 +186,7 @@ public class DefaultConfigurerTest
try
{
m_configurer.configure( test, config, m_context );
throw new AssertionFailedError();
fail();
}
catch( final ConfigurationException ce )
{
@@ -202,7 +233,7 @@ public class DefaultConfigurerTest
try
{
m_configurer.configure( test, config, m_context );
throw new AssertionFailedError();
fail();
}
catch( final ConfigurationException ce )
{
@@ -280,6 +311,34 @@ public class DefaultConfigurerTest
assertEquals( expected, test );
}

/**
* Tests that extra content is not allowed in a reference element.
*/
public void testReferenceElementExtra()
throws Exception
{
// Setup test data
final DefaultConfiguration config = new DefaultConfiguration( "test", "test" );
final DefaultConfiguration elem = new DefaultConfiguration( "some-prop-ref", "test" );
elem.setAttribute( "id", "prop-a" );
elem.setAttribute( "extra-attr", "some value" );
config.addChild( elem );

final ConfigTest1 test = new ConfigTest1();

try
{
// Configure the object
m_configurer.configure( test, config, m_context );
fail();
}
catch( ConfigurationException e )
{
final String message = REZ.getString( "extra-config-for-ref.error" );
assertSameMessage( message, e );
}
}

/**
* Tests whether an object with a non-iterface typed adder causes an
* exception.
@@ -326,8 +385,9 @@ public class DefaultConfigurerTest
}
catch( final ConfigurationException ce )
{
final String message = REZ.getString( "multiple-typed-adder-methods-for-element.error",
ConfigTest5.class.getName() );
final String message = REZ.getString( "multiple-adder-methods-for-element.error",
ConfigTest5.class.getName(),
"");
assertSameMessage( message, ce );
}
}
@@ -349,8 +409,8 @@ public class DefaultConfigurerTest
final DefaultTypeFactory factory = new DefaultTypeFactory( loader );
factory.addNameClassMapping( "my-type1", MyType1.class.getName() );
factory.addNameClassMapping( "my-type2", MyType2.class.getName() );
getTypeManager().registerType( MyRole1.class, "my-type1", factory );
getTypeManager().registerType( MyRole1.class, "my-type2", factory );
getTypeManager().registerType( DataType.class, "my-type1", factory );
getTypeManager().registerType( DataType.class, "my-type2", factory );

final ConfigTest6 test = new ConfigTest6();

@@ -363,6 +423,32 @@ public class DefaultConfigurerTest
assertEquals( expected, test );
}

/**
* Tests to see if typed adder can be used via an attribute.
*/
public void testTypedAdderAttribute()
throws Exception
{
// Setup test data
final DefaultConfiguration config = new DefaultConfiguration( "test", "test" );
config.setAttribute( "my-role1", "some value" );

// Set up the converter and role
RoleManager roleMgr = (RoleManager)getComponentManager().lookup( RoleManager.ROLE );
roleMgr.addNameRoleMapping( "my-role1", MyRole1.ROLE );
registerConverter( StringToMyRole1Converter.class, String.class, MyRole1.class );

final ConfigTest6 test = new ConfigTest6();

// Configure the object
m_configurer.configure( test, config, m_context );

// Check result
final ConfigTest6 expected = new ConfigTest6();
expected.add( new MyType1() );
assertEquals( expected, test );
}

/**
* Tests to see if typed adder works, with Configuration type.
*/
@@ -388,7 +474,7 @@ public class DefaultConfigurerTest
}

/**
* Tests to see if typed adder works, with Configuration objects.
* Tests to see if adder works, with Configuration objects.
*/
public void testConfigAdder()
throws Exception
@@ -470,7 +556,7 @@ public class DefaultConfigurerTest
try
{
m_configurer.configure( test, config, m_context );
throw new AssertionFailedError();
fail();
}
catch( ConfigurationException e )
{
@@ -498,7 +584,7 @@ public class DefaultConfigurerTest
try
{
m_configurer.configure( test, config, m_context );
throw new AssertionFailedError();
fail();
}
catch( ConfigurationException e )
{
@@ -510,6 +596,38 @@ public class DefaultConfigurerTest
}
}

/**
* Tests using a reference with a typed adder. Tests using an attribute
* and a nested element.
*/
public void testTypedAdderReference()
throws Exception
{
// Setup test data
final DefaultConfiguration config = new DefaultConfiguration( "test", "test" );
config.setAttribute( "my-role1-ref", "id" );
final DefaultConfiguration child = new DefaultConfiguration( "my-role1-ref", "test" );
child.setAttribute( "id", "id2" );
config.addChild( child );

// Add role mapping, and add to reference to context
final RoleManager roleMgr = (RoleManager)getComponentManager().lookup( RoleManager.ROLE );
roleMgr.addNameRoleMapping( "my-role1", MyRole1.class.getName() );
m_context.setProperty( "id", new MyType1() );
m_context.setProperty( "id2", new MyType2() );

final ConfigTest6 test = new ConfigTest6();

// Configure the object
m_configurer.configure( test, config, m_context );

// Compare against expected value
final ConfigTest6 expected = new ConfigTest6();
expected.add( new MyType1() );
expected.add( new MyType2() );
assertEquals( expected, test );
}

/**
* Tests reporting of nested errors.
*/
@@ -527,7 +645,7 @@ public class DefaultConfigurerTest
{
// Configure the object
m_configurer.configure( test, config, m_context );
throw new AssertionFailedError();
fail();
}
catch( ConfigurationException e )
{


+ 4
- 0
proposal/myrmidon/src/testcases/org/apache/myrmidon/components/configurer/MyRole1.java View File

@@ -7,6 +7,8 @@
*/
package org.apache.myrmidon.components.configurer;

import org.apache.myrmidon.framework.DataType;

/**
* A basic interface to test configurer.
*
@@ -14,5 +16,7 @@ package org.apache.myrmidon.components.configurer;
* @version $Revision$ $Date$
*/
public interface MyRole1
extends DataType
{
String ROLE = MyRole1.class.getName();
}

+ 32
- 0
proposal/myrmidon/src/testcases/org/apache/myrmidon/components/configurer/StringToMyRole1Converter.java View File

@@ -0,0 +1,32 @@
/*
* 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.txt file.
*/
package org.apache.myrmidon.components.configurer;

import org.apache.myrmidon.converter.AbstractConverter;
import org.apache.myrmidon.converter.ConverterException;
import org.apache.avalon.framework.context.Context;

/**
* Converts from a string to a {@link MyRole1} implementation.
*
* @author <a href="mailto:adammurdoch@apache.org">Adam Murdoch</a>
*/
public class StringToMyRole1Converter
extends AbstractConverter
{
public StringToMyRole1Converter()
{
super( String.class, MyRole1.class );
}

protected Object convert( Object original, Context context )
throws ConverterException
{
return new MyType1();
}
}

Loading…
Cancel
Save