/*
* Created on Jun 8, 2005
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*
* Copyright @2005 the original author or authors.
*/
package org.springmodules.remoting.xmlrpc;
import java.lang.reflect.Method;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.remoting.support.RemoteInvocation;
import org.springframework.remoting.support.RemoteInvocationBasedExporter;
import org.springmodules.remoting.xmlrpc.support.XmlRpcElement;
import org.springmodules.remoting.xmlrpc.support.XmlRpcRequest;
import org.springmodules.util.Strings;
/**
* <p>
* Default implementation of <code>{@link RemoteInvocationBasedExporter}</code>.
* </p>
*
* @author Alex Ruiz
*
* @version $Revision$ $Date$
*/
public final class XmlRpcServiceExporterImpl extends
RemoteInvocationBasedExporter implements XmlRpcServiceExporter,
InitializingBean {
/**
* Exported service.
*/
private Object service;
public XmlRpcServiceExporterImpl() {
super();
}
/**
* @see InitializingBean#afterPropertiesSet()
*/
public void afterPropertiesSet() throws Exception {
service = getProxyForService();
}
/**
* @param xmlRpcRequest
* the XML-RPC request that specifies the method to execute.
* @return a <code>RemoteInvocation</code> containing the service method
* that matches the one specified in the given XML-RPC request.
* @throws XmlRpcMethodNotFoundException
* if the a matching service method cannot be found.
*/
protected RemoteInvocation findMatchingMethod(XmlRpcRequest xmlRpcRequest) {
String requestMethodName = xmlRpcRequest.getMethodName();
XmlRpcElement[] requestParameters = xmlRpcRequest.getParameters();
int requestParameterCount = requestParameters.length;
Method targetMethod = null;
Object[] arguments = null;
Method[] serviceMethods = getServiceInterface().getDeclaredMethods();
int serviceMethodCount = serviceMethods.length;
for (int i = 0; i < serviceMethodCount; i++) {
Method serviceMethod = serviceMethods[i];
if (serviceMethod.getName().equals(requestMethodName)) {
Class[] parameterTypes = serviceMethod.getParameterTypes();
int parameterTypeCount = parameterTypes.length;
if (parameterTypeCount != requestParameterCount) {
continue;
}
boolean matchingMethod = true;
arguments = new Object[parameterTypeCount];
for (int j = 0; j < parameterTypeCount; j++) {
XmlRpcElement requestParameter = requestParameters[j];
Class targetType = parameterTypes[j];
Object argument = requestParameter.getMatchingValue(targetType);
if (argument == XmlRpcElement.NOT_MATCHING) {
matchingMethod = false;
break;
}
arguments[j] = argument;
}
if (matchingMethod) {
targetMethod = serviceMethod;
break;
}
}
}
if (targetMethod == null) {
throw new XmlRpcMethodNotFoundException("Unable to find method "
+ Strings.quote(requestMethodName) + "");
}
RemoteInvocation invocation = new RemoteInvocation(targetMethod.getName(),
targetMethod.getParameterTypes(), arguments);
return invocation;
}
/**
* @see XmlRpcServiceExporter#invoke(XmlRpcRequest)
* @see #findMatchingMethod(XmlRpcRequest)
*/
public Object invoke(XmlRpcRequest xmlRpcRequest) throws Exception {
RemoteInvocation invocation = findMatchingMethod(xmlRpcRequest);
return invoke(invocation, service);
}
}