Axis2PortClientInterceptor.java
package org.andromda.cartridges.support.webservice.client;
import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.aop.support.AopUtils;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.support.RootBeanDefinition;
import org.springframework.remoting.rmi.RmiClientInterceptorUtils;
/**
* Interceptor for accessing a specific port of a web service.
* Change from RootBeanDefinition to GenericBeanDefinition when using Spring 2.5
*/
public class Axis2PortClientInterceptor
extends org.springframework.beans.factory.support.RootBeanDefinition
implements MethodInterceptor,
InitializingBean
{
private static final long serialVersionUID = 34L;
/**
* LogFactory.getLog(Axis2PortClientInterceptor.class)
*/
protected final Log logger = LogFactory.getLog(Axis2PortClientInterceptor.class);
private final Object preparationMonitor = new Object();
private String username;
/**
* Set the username to connect to the service.
* @param username
*/
public void setUsername(String username)
{
this.username = username;
}
/**
* Return the username to connect to the service.
* @return username
*/
public String getUsername()
{
return username;
}
private String password;
/**
* Set the password to connect to the service.
* @param password
*/
public void setPassword(String password)
{
this.password = password;
}
/**
* Return the password to connect to the service.
* @return password
*/
public String getPassword()
{
String password = this.password;
if (password != null && this.getBase64Password())
{
password = new String(Base64.decodeBase64(password.getBytes()));
}
return password;
}
private boolean base64Password;
/**
* Sets a flag indicating whether or not the password given is in Base64.
*
* @param base64Password true/false
*/
public void setBase64Password(boolean base64Password)
{
this.base64Password = base64Password;
}
/**
* Gets the flag indicating whether or not the password given is in Base64.
*
* @return true/false
*/
public boolean getBase64Password()
{
return this.base64Password;
}
private long timeout;
/**
* Sets the timeout of the client in seconds.
*
* @param timeout
*/
public void setTimeout(final long timeout)
{
this.timeout = timeout;
}
/**
* Gets the timeout of the client in seconds.
*
* @return the timeout.
*/
public long getTimeout()
{
return this.timeout;
}
private Class serviceInterface;
/**
* Set the interface of the service that this factory should create a proxy for.
* @param serviceInterface
*/
public void setServiceInterface(Class serviceInterface)
{
if (serviceInterface != null && !serviceInterface.isInterface())
{
throw new IllegalArgumentException("serviceInterface must be an interface");
}
this.serviceInterface = serviceInterface;
}
/**
* Return the interface of the service that this factory should create a proxy for.
* @return serviceInterface
*/
public Class getServiceInterface()
{
return serviceInterface;
}
private String wsdlUrl;
/**
* Returns the URL to the WSDL for the service.
*
* @return the wsdlUrl
*/
public String getWsdlUrl()
{
return wsdlUrl;
}
/**
* Sets the WSDL URL for the service.
*
* @param wsdlUrl the wsdlUrl to set
*/
public void setWsdlUrl(String wsdlUrl)
{
this.wsdlUrl = wsdlUrl;
}
private String portAddress;
/**
* Returns the port address (if not using a port address in the WSDL).
*
* @return the portAddress
*/
public String getPortAddress()
{
return portAddress;
}
/**
* Sets the port address (if to use one other than the one in the WSDL).
*
* @param portAddress the portAddress to set
*/
public void setPortAddress(String portAddress)
{
this.portAddress = portAddress;
}
private TypeMapper typeMapper = new DefaultTypeMapper();
/**
* Sets the {@link TypeMapper} to use. It only makes sense to set this
* if you want to change the default type mapping behavoir.
*
* @param typeMapper the typeMapper to set
* @throws IllegalAccessException
* @throws InstantiationException
*/
public void setTypeMapper(Class typeMapper)
throws InstantiationException, IllegalAccessException
{
if (typeMapper == null)
{
throw new IllegalArgumentException("'typeMapper' can not be null");
}
if (!TypeMapper.class.isAssignableFrom(typeMapper))
{
throw new IllegalArgumentException("'typeMapper' must be an instance of: " + TypeMapper.class.getName());
}
this.typeMapper = (TypeMapper)typeMapper.newInstance();
}
/**
* Prepares the JAX-RPC service and port if the "lazyInit"
* isn't false.
*/
public void afterPropertiesSet()
{
this.prepare();
}
private WebServiceClient client;
/**
* Create and initialize the service for the specified WSDL.
*/
public void prepare()
{
synchronized (this.preparationMonitor)
{
if (this.getServiceInterface() == null)
{
throw new IllegalArgumentException("'serviceInterface' must be specified!");
}
if (StringUtils.isBlank(this.getPortAddress()))
{
throw new IllegalArgumentException("'portAddress' must be specified!");
}
if (StringUtils.isBlank(this.getWsdlUrl()))
{
throw new IllegalArgumentException("'wsdlUrl' must be specified!");
}
if (this.client == null)
{
this.client =
new WebServiceClient(
this.getWsdlUrl(),
this.getPortAddress(),
this.getServiceInterface(),
this.getUsername(),
this.getPassword());
this.client.setTimeout(this.getTimeout());
this.client.setTypeMapper(this.typeMapper);
}
}
}
/**
* Translates the method invocation into a JAX-RPC service invocation.
* Uses traditional RMI stub invocation if a JAX-RPC port stub is available;
* falls back to JAX-RPC dynamic calls else.
* @param invocation
* @return invoked operation return
* @throws Throwable
* @see WebServiceClient#invokeBlocking(String, Object[])
* @see org.springframework.remoting.rmi.RmiClientInterceptorUtils
*/
public Object invoke(MethodInvocation invocation)
throws Throwable
{
if (AopUtils.isToStringMethod(invocation.getMethod()))
{
return "Axis2 proxy for port [" + this.getPortAddress() + "] of service [" +
this.getServiceInterface().getName() + ']';
}
if (logger.isDebugEnabled())
{
logger.debug(
"Invoking '" + invocation.getMethod().getName() + "' on port: '" +
this.getPortAddress() + "' through interface: '" + this.getServiceInterface().getName() + '\'');
}
try
{
try
{
return this.client.invokeBlocking(
invocation.getMethod().getName(),
invocation.getArguments());
}
finally
{
this.client.cleanup();
}
}
catch (WebServiceClientException exception)
{
throw RmiClientInterceptorUtils.convertRmiAccessException(
invocation.getMethod(),
exception,
this.getServiceInterface().getName());
}
}
/**
* @see org.springframework.beans.factory.support.RootBeanDefinition#cloneBeanDefinition()
*/
public RootBeanDefinition cloneBeanDefinition() {
return new RootBeanDefinition(this);
}
}