package de.dfki.util.xmlrpc.conversion;
import java.util.Collection;
import java.util.Date;
import java.util.Map;
import de.dfki.util.xmlrpc.XmlRpc;
import de.dfki.util.xmlrpc.XmlRpc.Type;
import de.dfki.util.xmlrpc.common.ApiParameter;
import org.apache.xmlrpc.Base64;
/**
* Type converter doing only the standard conversion work (actually, does only type checks
* and passes values through)
*
* @author lauer
*/
public class StandardXmlRpcTypeConverter implements TypeConverter
{
/**
* Maps a java class to an XML-RPC type.
*
* @param cls
* The class to map.
*
* @return The corresponding XML-RPC type. <code>null</code>, if the
* mapping failed.
*/
public static Type mapJavaTypeToXmlRpcType( Class<?> cls )
{
if (cls == null)
{
return( Type.NONE );
}
if (!(cls instanceof Class))
{
return( null );
}
for( Type type : Type.values() )
{
if( type.getCorrespondingBaseType().isAssignableFrom( cls ) )
{
return ( type );
}
if( type.getCorrespondingPrimitiveType() != null &&
type.getCorrespondingPrimitiveType().equals( cls ) )
{
return( type );
}
}
return ( null );
}
/**
* Checks, if an instance <code>o</code> is compliant with XML-RPC type <code>t</code>.
*/
public boolean areCompatible( final Type t, final Object o )
{
boolean isOk = false;
switch( t )
{
case BOOLEAN:
isOk = o instanceof Boolean;
break;
case INT:
isOk = o instanceof Integer;
break;
case STRING:
isOk = o instanceof String;
break;
case DOUBLE:
isOk = o instanceof Double;
break;
case FLOAT:
isOk = o instanceof Float;
break;
case DATE:
isOk = o instanceof Date;
break;
case STRUCT:
isOk = o instanceof Map;
break;
case ARRAY:
isOk = o instanceof Collection;
break;
case BASE64:
isOk = o instanceof byte[];
break;
case STRINGasBASE64:
isOk = o instanceof String;
break;
case NONE:
isOk = (o == null);
break;
}
return ( isOk );
}
public Object convertToUserRepresentation( ApiParameter apiParam, Object parameterValueInXmlRpcRep )
throws TypeConversionException
{
assert apiParam != null;
//TODO: add conversion specialties from MethodCall here
if (apiParam.getXmlRpcType() == Type.FLOAT)
{
parameterValueInXmlRpcRep = ((Double)parameterValueInXmlRpcRep).floatValue();
}
return( parameterValueInXmlRpcRep );
}
public Object convertToXmlRpcRepresentation( ApiParameter apiParam, Object parameterValueInUserRep )
throws TypeConversionException
{
assert apiParam != null;
if (parameterValueInUserRep == null)
return( null );
if (apiParam.getXmlRpcType() == null && Object.class.equals( apiParam.getApiRepresentationClass() ) )
return( parameterValueInUserRep );
if (!areCompatible( apiParam.getXmlRpcType(), parameterValueInUserRep ))
{
throw( new TypeConversionException( "Cannot convert " + parameterValueInUserRep + " into XML-RPC representation " + apiParam.getXmlRpcType() ) );
}
//convert a string into base64
if (parameterValueInUserRep.getClass().equals( String.class )
&& apiParam.getXmlRpcType() == XmlRpc.Type.BASE64 )
{
parameterValueInUserRep = new String( Base64.encode( ((String)parameterValueInUserRep).getBytes() ) );
}
if (apiParam.getXmlRpcType() == Type.FLOAT)
{
parameterValueInUserRep = ((Float)parameterValueInUserRep).doubleValue();
}
return( parameterValueInUserRep );
}
public Type convertToXmlRpcRepresentationClass( Class<?> userRepClass )
throws TypeConversionException
{
final Type t = mapJavaTypeToXmlRpcType( userRepClass );
if (t == null && !userRepClass.equals( void.class ))
throw( new TypeConversionException( "Cannot find a XML-RPC compliant type for class " + userRepClass ) );
return( t );
}
}