View Javadoc

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