1 package org.codehaus.xfire.client; 2 3 import java.lang.reflect.InvocationHandler; 4 import java.lang.reflect.Method; 5 import java.lang.reflect.Proxy; 6 import java.util.Arrays; 7 8 import org.apache.commons.logging.Log; 9 import org.apache.commons.logging.LogFactory; 10 import org.codehaus.xfire.XFireException; 11 import org.codehaus.xfire.service.OperationInfo; 12 13 /*** 14 * Proxy implementation for XFire SOAP clients. Applications will generally use <code>XFireProxyFactory</code> to 15 * create proxy clients. 16 * 17 * @author <a href="mailto:poutsma@mac.com">Arjen Poutsma</a> 18 * @see XFireProxyFactory#create 19 */ 20 public class XFireProxy 21 implements InvocationHandler 22 { 23 private static final Log log = LogFactory.getLog(XFireProxy.class); 24 private Client client; 25 26 XFireProxy(Client client) 27 { 28 this.client = client; 29 } 30 31 /*** 32 * Handles the object invocation. 33 * 34 * @param proxy the proxy object to invoke 35 * @param method the method to call 36 * @param args the arguments to the proxy object 37 */ 38 public Object invoke(Object proxy, Method method, Object[] args) 39 throws Throwable 40 { 41 String methodName = method.getName(); 42 Class[] parameterTypes = method.getParameterTypes(); 43 if (log.isDebugEnabled()) 44 { 45 log.debug("Method [" + methodName + "] " + ((args == null) ? "" : Arrays.asList(args).toString())); 46 } 47 48 Object result = handleCanonicalMethods(methodName, parameterTypes, args); 49 50 if (result == null) 51 { 52 result = handleRequest(methodName, args); 53 } 54 if (log.isDebugEnabled()) 55 { 56 log.debug("Result [" + String.valueOf(result) + "]"); 57 } 58 return result; 59 } 60 61 private Object handleRequest(String methodName, Object[] args) 62 throws XFireException 63 { 64 OperationInfo op = client.getService().getServiceInfo().getOperation(methodName); 65 66 Object[] response = (Object[]) client.invoke(op, args); 67 68 if (response.length > 0) 69 return response[0]; 70 else 71 return null; 72 } 73 74 /*** 75 * Handles canonical method calls such as <code>equals</code>, <code>hashCode</code>, and <code>toString</code>. 76 * 77 * @param methodName the method name. 78 * @param params the parameter types. 79 * @param args the arguments 80 * @return the result, if <code>methodName</code> is a canonical method; or <code>null</code> if not. 81 */ 82 private Object handleCanonicalMethods(String methodName, Class[] params, Object[] args) 83 { 84 if (methodName.equals("equals") && 85 params.length == 1 86 && params[0].equals(Object.class)) 87 { 88 Object other = args[0]; 89 if (other == null || 90 !Proxy.isProxyClass(other.getClass()) || 91 !(Proxy.getInvocationHandler(other) instanceof XFireProxy)) 92 { 93 return Boolean.FALSE; 94 } 95 96 XFireProxy otherClient = (XFireProxy) Proxy.getInvocationHandler(other); 97 98 return new Boolean(otherClient == this); 99 } 100 else if (methodName.equals("hashCode") && params.length == 0) 101 { 102 return new Integer(hashCode()); 103 } 104 else if (methodName.equals("toString") && params.length == 0) 105 { 106 return "XFireProxy[" + client.getUrl() + "]"; 107 } 108 return null; 109 } 110 } 111