package de.dfki.util.xmlrpc.server;
import static de.dfki.util.xmlrpc.XmlRpc.getTypeConverter;
import java.lang.reflect.Method;
import java.util.logging.Logger;
import de.dfki.util.xmlrpc.common.MethodSignature;
import de.dfki.util.xmlrpc.conversion.TypeConversionException;
import org.apache.xmlrpc.XmlRpcException;
/**
* Default implementation for the {@link InvocationInterceptor} interface.
* <p>
* Method parameters are converted from XML-RPC representation into user-representation needed for
* the API call. The return value is converted back to XML-RPC representation.
* </p>
*
* Calls of methods of class java.lang.Object are not allowed.
*
* @author lauer
*/
public class DefaultInvocationInterceptor implements InvocationInterceptor
{
private static Logger mLog = Logger.getLogger( DefaultInvocationInterceptor.class.getName() );
public static Logger log()
{
return ( mLog );
}
/** needed in case the api defines parameter converter mappings. */
public Object invokeMethod( Object delegate, String methodName, Class<?>[] xmlRpcSignature, Object[] args )
throws Throwable
{
assert xmlRpcSignature != null;
log().fine( "Calling method '" + methodName + "'" );
Method method = lookupMethod( delegate, methodName, xmlRpcSignature );
if( method.getDeclaringClass() == Object.class )
{
throw new XmlRpcException( 0, "Can't call methods defined in java.lang.Object" );
}
MethodSignature methodSig = MethodSignature.createFromMethod( method );
Object[] adaptedParameters = adaptParameters( methodSig, args );
Object result = method.invoke( delegate, adaptedParameters );
//convert result back to a XML-RPC compliant representation
result = getTypeConverter().convertToXmlRpcRepresentation( methodSig.getReturnParameter(), result );
if (result == null && !methodSig.getReturnParameter().getApiRepresentationClass().equals( void.class ))
{
throw( new XmlRpcException( 0, "Method '" + method + "' must not return <null>" ) );
}
return( result );
}
protected Method lookupMethod( Object delegate, String methodName, Class<?>[] xmlRpcSignature )
throws NoSuchMethodException
{
assert delegate != null;
for( Method m: delegate.getClass().getMethods() )
{
if (!m.getName().equals( methodName ))
{
continue;
}
if( m.getParameterTypes().length != xmlRpcSignature.length)
{
continue;
}
return( m );
}
throw( new NoSuchMethodException( methodName ) );
}
protected Object[] adaptParameters( MethodSignature methodSig, Object[] xmlRpcParams )
throws TypeConversionException
{
for( int i = 0; i < xmlRpcParams.length; i++ )
{
Object elt = xmlRpcParams[i];
xmlRpcParams[i] = getTypeConverter().convertToUserRepresentation( methodSig.getParameterAt( i ), elt );
}
return( xmlRpcParams );
}
}