donaldp 02/03/22 20:56:24
Modified:
proposal/myrmidon/src/java/org/apache/myrmidon/components/converter
DefaultMasterConverter.java
Added: proposal/myrmidon/src/java/org/apache/aut/converter
AbstractMasterConverter.java
Removed:
proposal/myrmidon/src/java/org/apache/myrmidon/components/converter
AbstractMasterConverter.java
Log:
Move AbstractMasterConverter from
org.apache.myrmidon.components.converter
to
org.apache.aut.converter
Revision Changes Path
1.28 +2 -1
jakarta-ant/proposal/myrmidon/src/java/org/apache/myrmidon/components/converter/DefaultMasterConverter.java
Index: DefaultMasterConverter.java
===================================================================
RCS file:
/home/cvs/jakarta-ant/proposal/myrmidon/src/java/org/apache/myrmidon/components/converter/DefaultMasterConverter.java,v
retrieving revision 1.27
retrieving revision 1.28
diff -u -r1.27 -r1.28
--- DefaultMasterConverter.java 23 Mar 2002 04:54:21 -0000 1.27
+++ DefaultMasterConverter.java 23 Mar 2002 04:56:24 -0000 1.28
@@ -8,6 +8,7 @@
package org.apache.myrmidon.components.converter;
import org.apache.aut.converter.Converter;
+import org.apache.aut.converter.AbstractMasterConverter;
import org.apache.avalon.framework.service.ServiceException;
import org.apache.avalon.framework.service.ServiceManager;
import org.apache.avalon.framework.service.Serviceable;
@@ -19,7 +20,7 @@
* Converter engine to handle converting between types.
*
* @author <a href="mailto:[EMAIL PROTECTED]">Peter Donald</a>
- * @version $Revision: 1.27 $ $Date: 2002/03/23 04:54:21 $
+ * @version $Revision: 1.28 $ $Date: 2002/03/23 04:56:24 $
*/
public class DefaultMasterConverter
extends AbstractMasterConverter
1.1
jakarta-ant/proposal/myrmidon/src/java/org/apache/aut/converter/AbstractMasterConverter.java
Index: AbstractMasterConverter.java
===================================================================
/*
* 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.aut.converter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import org.apache.aut.converter.Converter;
import org.apache.aut.converter.ConverterException;
import org.apache.avalon.excalibur.i18n.ResourceManager;
import org.apache.avalon.excalibur.i18n.Resources;
import org.apache.myrmidon.components.converter.DefaultMasterConverter;
/**
* This is an abstract implementation of a <code>MasterConverter</code>.
* A MasterConverter is capable of converting between many different
* source and destination types. The <code>MasterConverter</code>
* delegates to other converters that do the actual work.
*
* <p>To use this class you must subclass it, overide the
* (@link #createConverter(String)) method and register some
* converters using the (@link #registerConverter(String,String,String))
* method.</p>
*
* <p>The reason this class deals with strings rather than Class objects
* is because dealing with strings allows us to implement alternative
* mechanisms for defining Converters in the future, only defining converter
* when it is first used.</p>
*
* @author <a href="mailto:[EMAIL PROTECTED]">Peter Donald</a>
* @version $Revision: 1.1 $ $Date: 2002/03/23 04:56:24 $
*/
public class AbstractMasterConverter
implements Converter
{
private final static Resources REZ =
ResourceManager.getPackageResources( DefaultMasterConverter.class );
/**
* Map from converter classname to instance of converter.
*/
private final Map m_converters = new HashMap();
/**
* This holds the mapping between source/destination
* and converter name.
*/
private final HashMap m_mapping = new HashMap();
/**
* Convert object to destination type.
*
* @param destination the destination type
* @param original the original object
* @param context the context in which to convert
* @return the converted object
* @exception org.apache.aut.converter.ConverterException if an error
occurs
*/
public Object convert( final Class destination,
final Object original,
final Object context )
throws ConverterException
{
final Class originalClass = original.getClass();
if( destination.isAssignableFrom( originalClass ) )
{
return original;
}
try
{
// Search inheritance hierarchy for converter
final String name = findConverter( originalClass, destination );
// Create the converter
Converter converter = (Converter)m_converters.get( name );
if( converter == null )
{
converter = createConverter( name );
m_converters.put( name, converter );
}
// Convert
final Object object = converter.convert( destination, original,
context );
if( destination.isInstance( object ) )
{
return object;
}
final String message =
REZ.getString( "bad-return-type.error",
object.getClass().getName(),
destination.getName() );
throw new ConverterException( message );
}
catch( final Exception e )
{
final String message = REZ.getString( "convert.error",
originalClass.getName(),
destination.getName() );
throw new ConverterException( message, e );
}
}
/**
* Register a converter
*
* @param classname the className of converter
* @param source the source classname
* @param destination the destination classname
*/
protected void registerConverter( final String classname,
final String source,
final String destination )
{
HashMap map = (HashMap)m_mapping.get( source );
if( null == map )
{
map = new HashMap();
m_mapping.put( source, map );
}
map.put( destination, classname );
//Remove instance of converter if it has already been created
m_converters.remove( classname );
}
/**
* Create an instance of converter with specified name.
*
* @param name the name of converter
* @return the created converter instance
* @throws java.lang.Exception if converter can not be created.
*/
protected abstract Converter createConverter( final String name )
throws Exception;
/**
* Determine the name of the converter to use to convert between
* original and destination classes.
*/
private String findConverter( final Class originalClass,
final Class destination )
throws ConverterException
{
//TODO: Maybe we should search the destination classes hierarchy as
well
// Recursively iterate over the super-types of the original class,
// looking for a converter from source type -> destination type.
// If more than one is found, choose the most specialised.
Class match = null;
String converterName = null;
ArrayList queue = new ArrayList();
queue.add( originalClass );
while( !queue.isEmpty() )
{
Class clazz = (Class)queue.remove( 0 );
// Add superclass and all interfaces
if( clazz.getSuperclass() != null )
{
queue.add( clazz.getSuperclass() );
}
final Class[] interfaces = clazz.getInterfaces();
for( int i = 0; i < interfaces.length; i++ )
{
queue.add( interfaces[ i ] );
}
// Check if we can convert from current class to destination
final String name = getConverterClassname( clazz.getName(),
destination.getName()
);
if( name == null )
{
continue;
}
// Choose the more specialised source class
if( match == null || match.isAssignableFrom( clazz ) )
{
match = clazz;
converterName = name;
}
else if( clazz.isAssignableFrom( clazz ) )
{
continue;
}
else
{
// Duplicate
final String message = REZ.getString(
"ambiguous-converter.error" );
throw new ConverterException( message );
}
}
// TODO - should cache the (src, dest) -> converter mapping
if( match != null )
{
return converterName;
}
// Could not find a converter
final String message = REZ.getString( "no-converter.error" );
throw new ConverterException( message );
}
/**
* Retrieve name of ConverterInfo that describes converter that converts
* from source to destination.
*
* @param source the source classname
* @param destination the destination classname
* @return the className of converter or null if none available
*/
private String getConverterClassname( final String source, final String
destination )
{
final HashMap map = (HashMap)m_mapping.get( source );
if( null == map )
{
return null;
}
return (String)map.get( destination );
}
}
--
To unsubscribe, e-mail: <mailto:[EMAIL PROTECTED]>
For additional commands, e-mail: <mailto:[EMAIL PROTECTED]>