package org.jboss.webservice.client;
import org.jboss.axis.client.AxisClientProxy;
import org.jboss.logging.Logger;
import javax.xml.rpc.JAXRPCException;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.rmi.Remote;
import java.rmi.RemoteException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class PortProxy implements InvocationHandler
{
private static final Logger log = Logger.getLogger(PortProxy.class);
private Remote port;
private CallImpl call;
private List seiMethods = new ArrayList();
private List objectMethods = new ArrayList();
private List stubMethods = new ArrayList();
private Method getPropertyMethod;
private Method setPropertyMethod;
public PortProxy(Remote port, Class seiClass)
{
this.port = port;
AxisClientProxy axisClientProxy = (AxisClientProxy)Proxy.getInvocationHandler(port);
this.call = (CallImpl)axisClientProxy.getCall();
objectMethods.addAll(Arrays.asList(Object.class.getMethods()));
seiMethods.addAll(Arrays.asList(seiClass.getMethods()));
stubMethods.addAll(Arrays.asList(org.jboss.webservice.client.Stub.class.getMethods()));
try
{
getPropertyMethod = Stub.class.getMethod("_getProperty", new Class[]{String.class});
setPropertyMethod = Stub.class.getMethod("_setProperty", new Class[]{String.class, Object.class});
}
catch (NoSuchMethodException ignore)
{
}
}
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable
{
String methodName = method.getName();
try
{
Object retObj = null;
if (seiMethods.contains(method))
{
log.debug("Invoke on service endpoint interface: " + methodName);
retObj = method.invoke(port, args);
return retObj;
}
if (stubMethods.contains(method))
{
log.debug("Invoke on stub interface: " + methodName);
if ("getUsername".equals(methodName))
retObj = getPropertyMethod.invoke(port, new Object[]{Stub.USERNAME_PROPERTY});
else if ("setUsername".equals(methodName))
retObj = setPropertyMethod.invoke(port, new Object[]{Stub.USERNAME_PROPERTY, args[0]});
else if ("getPassword".equals(methodName))
retObj = getPropertyMethod.invoke(port, new Object[]{Stub.PASSWORD_PROPERTY});
else if ("setPassword".equals(methodName))
retObj = setPropertyMethod.invoke(port, new Object[]{Stub.PASSWORD_PROPERTY, args[0]});
else if ("getEndpointAddress".equals(methodName))
retObj = getPropertyMethod.invoke(port, new Object[]{Stub.ENDPOINT_ADDRESS_PROPERTY});
else if ("setEndpointAddress".equals(methodName))
retObj = setPropertyMethod.invoke(port, new Object[]{Stub.ENDPOINT_ADDRESS_PROPERTY, args[0]});
else if ("getSessionMaintain".equals(methodName))
retObj = getPropertyMethod.invoke(port, new Object[]{Stub.SESSION_MAINTAIN_PROPERTY});
else if ("setSessionMaintain".equals(methodName))
retObj = setPropertyMethod.invoke(port, new Object[]{Stub.SESSION_MAINTAIN_PROPERTY, args[0]});
else if ("getTimeout".equals(methodName))
retObj = call.getTimeout();
else if ("setTimeout".equals(methodName))
call.setTimeout((Integer)args[0]);
else if (getPropertyMethod.equals(method) && Stub.CLIENT_TIMEOUT_PROPERTY.equals(args[0]))
retObj = call.getTimeout();
else if (setPropertyMethod.equals(method) && Stub.CLIENT_TIMEOUT_PROPERTY.equals(args[0]))
call.setTimeout((Integer)args[1]);
else if ("addAttachment".equals(methodName))
call.addAttachment((String)args[0], args[1]);
else if ("removeAttachment".equals(methodName))
call.removeAttachment((String)args[0]);
else if ("getAttachments".equals(methodName))
retObj = call.getAttachmentIdentifiers();
else if ("getAttachment".equals(methodName))
retObj = call.getAttachment((String)args[0]);
else
retObj = method.invoke(port, args);
return retObj;
}
if (objectMethods.contains(method))
{
log.debug("Invoke on object: " + methodName);
retObj = method.invoke(port, args);
return retObj;
}
throw new JAXRPCException("Don't know how to invoke: " + method);
}
catch (Exception e)
{
Throwable th = processException(e);
if (seiMethods.contains(method))
{
if (th instanceof JAXRPCException || th instanceof RuntimeException)
{
RemoteException re = new RemoteException(th.getMessage(), th);
th = re;
}
}
throw th;
}
}
private Throwable processException(Exception ex)
{
Throwable th = ex;
if (ex instanceof InvocationTargetException)
th = ((InvocationTargetException)ex).getTargetException();
log.error("Port error", th);
return th;
}
}