KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jboss > net > axis > AxisInvocationHandler


1 /*
2  * JBoss, the OpenSource J2EE webOS
3  *
4  * Distributable under LGPL license.
5  * See terms of license at gnu.org.
6  */

7
8 // $Id: AxisInvocationHandler.java,v 1.16.6.2 2005/04/03 07:19:23 starksm Exp $
9

10 package org.jboss.net.axis;
11
12 import org.jboss.axis.ConfigurationException;
13 import org.jboss.axis.EngineConfiguration;
14 import org.jboss.axis.EngineConfigurationFactory;
15 import org.jboss.axis.client.Call;
16 import org.jboss.axis.client.Service;
17 import org.jboss.axis.configuration.EngineConfigurationFactoryFinder;
18
19 import javax.management.MalformedObjectNameException JavaDoc;
20 import javax.management.ObjectName JavaDoc;
21 import java.io.IOException JavaDoc;
22 import java.io.ObjectInputStream JavaDoc;
23 import java.io.Serializable JavaDoc;
24 import java.lang.reflect.InvocationHandler JavaDoc;
25 import java.lang.reflect.Method JavaDoc;
26 import java.lang.reflect.Proxy JavaDoc;
27 import java.net.URL JavaDoc;
28 import java.util.HashMap JavaDoc;
29 import java.util.Map JavaDoc;
30
31 /**
32  * <p>
33  * An invocation handler that allows typed and persistent
34  * client access to remote SOAP/Axis services.
35  * Adds method/interface to name resolution
36  * to the axis client engine. Unfortunately the
37  * AxisClientProxy has a package-protected
38  * constructor, otherwise we could inherit from there.
39  * </p>
40  * @deprecated Due to the inherent deficiencies in
41  * using pure reflection meat-data to access web services, we recommend
42  * using the full-blown jaxrpc/wsdl approach.
43  * @created 1. Oktober 2001, 09:29
44  * @author <a HREF="mailto:Christoph.Jung@infor.de">Christoph G. Jung</a>
45  * @version $Revision: 1.16.6.2 $
46  */

47
48 public class AxisInvocationHandler implements InvocationHandler JavaDoc, Serializable JavaDoc
49 {
50    static final long serialVersionUID = -8250523938712824229L;
51
52    //
53
// Attributes
54
//
55

56    /** mapping of methods to interface names */
57    protected Map JavaDoc methodToInterface;
58    /** mapping of methods to method names */
59    protected Map JavaDoc methodToName;
60    /** the call object to which we delegate */
61    transient protected Call call;
62    /** if attached to a server-engine, we can reattach */
63    protected String JavaDoc rootContext;
64    /** the endpoint to which we are attached */
65    protected String JavaDoc endPoint;
66     
67    //
68
// Constructors
69
//
70

71    /**
72     * Creates a new AxisInvocationHandler and
73     * save some origin information to re-attach to the
74     * engine after being serialized.
75     * @param call the Axis call object
76     * @param methodMap a map of Java method to service method names
77     * @param interfaceMap a map of Java interface to service names
78     */

79    public AxisInvocationHandler(Call call, Map JavaDoc methodMap, Map JavaDoc interfaceMap)
80    {
81       this.call = call;
82       this.methodToInterface = interfaceMap;
83       this.methodToName = methodMap;
84       // we obtain the configuration of the service
85
EngineConfiguration myEngineConfig = call.getService().getEngine().getConfig();
86
87       try
88       {
89          rootContext = (String JavaDoc)myEngineConfig.getGlobalOptions().get(Constants.CONFIGURATION_CONTEXT);
90       }
91       catch (ConfigurationException e)
92       {
93 // access problem
94
}
95       catch (NullPointerException JavaDoc e)
96       {
97 // no global options
98
}
99       
100 // if the endpoint has already been specified,
101
// save it for re-attachement
102
if (call.getTargetEndpointAddress() != null)
103       {
104          endPoint = call.getTargetEndpointAddress().toString();
105       }
106    }
107
108    /**
109     * Creates a new AxisInvocationHandler
110     * @param endpoint target address of the service
111     * @param service an Axis service object
112     * @param methodMap a map of Java method to service method names
113     * @param interfaceMap a map of Java interface to service names
114     */

115    public AxisInvocationHandler(URL JavaDoc endpoint,
116                                 String JavaDoc soapAction,
117                                 Service service,
118                                 Map JavaDoc methodMap,
119                                 Map JavaDoc interfaceMap)
120    {
121       this(new Call(service), methodMap, interfaceMap);
122       call.setTargetEndpointAddress(endpoint);
123       call.setSOAPActionURI(soapAction);
124       setBasicAuthentication(endpoint);
125       endPoint = endpoint.toString();
126    }
127
128    /**
129     * Creates a new AxisInvocationHandler
130     * @param endPoint target url of the web service
131     * @param methodMap a map of Java method to service method names
132     * @param interfaceMap a map of Java interface to service names
133     * @param maintainSession a flag that indicates whether this handler
134     * should keep a persistent session with the service endpoint
135     */

136    public AxisInvocationHandler(URL JavaDoc endPoint,
137                                 String JavaDoc soapAction,
138                                 Map JavaDoc methodMap,
139                                 Map JavaDoc interfaceMap,
140                                 boolean maintainSession)
141    {
142       this(endPoint, soapAction, new Service(), methodMap, interfaceMap);
143       call.setMaintainSession(maintainSession);
144    }
145
146    /**
147     * Creates a new AxisInvocationHandler that keeps a persistent session with
148     * the service endpoint
149     * @param endPoint target url of the web service
150     * @param methodMap a map of Java method to service method names
151     * @param interfaceMap a map of Java interface to service names
152     */

153    public AxisInvocationHandler(URL JavaDoc endPoint, String JavaDoc soapAction, Map JavaDoc methodMap, Map JavaDoc interfaceMap)
154    {
155       this(endPoint, soapAction, methodMap, interfaceMap, true);
156    }
157
158    /**
159     * Creates a new AxisInvocationHandler that keeps a persistent session with
160     * the service endpoint. The unqualified name of the
161     * intercepted Java interface will be the used service name.
162     * @param endPoint target url of the web service
163     * @param methodMap a map of Java method to service method names
164     */

165    public AxisInvocationHandler(URL JavaDoc endPoint, String JavaDoc soapAction, Map JavaDoc methodMap)
166    {
167       this(endPoint, soapAction, methodMap, new DefaultInterfaceMap());
168    }
169
170    /**
171     * Creates a new AxisInvocationHandler that keeps a persistent session with
172     * the service endpoint. The unqualified name of the
173     * intercepted Java interface will be the used service name.
174     * Intercepted methods are mapped straightforwardly to web service names.
175     * @param endPoint target url of the web service
176     * @param methodMap a map of Java method to service method names
177     */

178    public AxisInvocationHandler(URL JavaDoc endPoint, String JavaDoc soapAction)
179    {
180       this(endPoint, soapAction, new DefaultMethodMap());
181    }
182
183    //
184
// Helpers
185
//
186

187    /** helper to transfer url authentication information into engine */
188    protected void setBasicAuthentication(URL JavaDoc target)
189    {
190       String JavaDoc userInfo = target.getUserInfo();
191       if (userInfo != null)
192       {
193          java.util.StringTokenizer JavaDoc tok = new java.util.StringTokenizer JavaDoc(userInfo, ":");
194          if (tok.hasMoreTokens())
195          {
196             call.setUsername(tok.nextToken());
197             if (tok.hasMoreTokens())
198             {
199                call.setPassword(tok.nextToken());
200             }
201          }
202       }
203    }
204
205    //
206
// Invocationhandling API
207
//
208

209    /** invoke given namespace+method+args */
210    public Object JavaDoc invoke(String JavaDoc serviceName, String JavaDoc methodName, Object JavaDoc[] args)
211            throws java.rmi.RemoteException JavaDoc
212    {
213       try
214       {
215          return call.invoke(serviceName, methodName, args);
216       }
217       finally
218       {
219          call.setReturnType(null);
220          call.removeAllParameters();
221       }
222    }
223
224    /** invoke with additional method parameter signature */
225    public Object JavaDoc invoke(String JavaDoc serviceName,
226                         String JavaDoc methodName,
227                         Object JavaDoc[] args,
228                         Class JavaDoc[] parameters)
229            throws java.rmi.RemoteException JavaDoc
230    {
231       // classes are normally ignored
232
return invoke(serviceName, methodName, args);
233    }
234
235    /** generic invocation method */
236    public java.lang.Object JavaDoc invoke(java.lang.Object JavaDoc target,
237                                   java.lang.reflect.Method JavaDoc method,
238                                   java.lang.Object JavaDoc[] args)
239            throws java.lang.Throwable JavaDoc
240    {
241       return invoke((String JavaDoc)methodToInterface.get(method),
242               (String JavaDoc)methodToName.get(method),
243               args,
244               method.getParameterTypes());
245    }
246
247
248    //
249
// Static API
250
//
251

252    /** default creation of service */
253    public static Object JavaDoc createAxisService(Class JavaDoc _interface, URL JavaDoc endpoint, String JavaDoc soapAction)
254    {
255       return createAxisService(_interface, new AxisInvocationHandler(endpoint, soapAction));
256    }
257
258    /** default creation of service */
259    public static Object JavaDoc createAxisService(Class JavaDoc _interface,
260                                           URL JavaDoc endpoint, String JavaDoc soapAction, Service service)
261    {
262       return createAxisService(_interface,
263               new AxisInvocationHandler(endpoint, soapAction, service, new DefaultMethodMap(), new DefaultInterfaceMap()));
264    }
265
266    /** default creation of service */
267    public static Object JavaDoc createAxisService(Class JavaDoc _interface,
268                                           Call call)
269    {
270       return createAxisService(_interface,
271               new AxisInvocationHandler(call, new DefaultMethodMap(), new DefaultInterfaceMap()));
272    }
273
274    /** default creation of service */
275    public static Object JavaDoc createAxisService(Class JavaDoc _interface,
276                                           AxisInvocationHandler handler)
277    {
278       return Proxy.newProxyInstance(_interface.getClassLoader(),
279               new Class JavaDoc[]{_interface},
280               handler);
281    }
282
283    /**
284     * a tiny helper that does some default mapping of methods to interface names
285     * we do not hash the actual reflection information because
286     * we could collide with proxy serialisation holding fucking
287     * old classes
288     */

289
290    public static class DefaultInterfaceMap extends HashMap JavaDoc
291    {
292
293       /** no entries is the default */
294       public DefaultInterfaceMap()
295       {
296          super(0);
297       }
298
299       /** returns default interface if no mapping of method/interface is defined */
300       public Object JavaDoc get(Object JavaDoc key)
301       {
302
303          // first try a direct lookup
304
Object JavaDoc result = super.get(((Method JavaDoc)key).getName());
305
306          if (result == null)
307          {
308             // if that is unsuccessful, we try to
309
// lookup the class/interface itself
310
result = super.get(((Method JavaDoc)key).getDeclaringClass().getName());
311
312             // if that is not specified, we simply extract the
313
// un-qualified classname
314
if (result == null)
315             {
316                String JavaDoc sresult = ((Method JavaDoc)key).getDeclaringClass().getName();
317                if (sresult.indexOf(".") != -1)
318                   sresult = sresult.substring(sresult.lastIndexOf(".") + 1);
319                result = sresult;
320             }
321          }
322
323          return result;
324       }
325
326       /** registers an interface name for a given class or method */
327       public Object JavaDoc put(Object JavaDoc key, Object JavaDoc value)
328       {
329          if (key instanceof Method JavaDoc)
330          {
331             return super.put(((Method JavaDoc)key).getName(), value);
332          }
333          else if (key instanceof Class JavaDoc)
334          {
335             return super.put(((Class JavaDoc)key).getName(), value);
336          }
337          else
338          {
339             return super.put(key, value);
340          }
341       }
342
343    }
344
345    /**
346     * a tiny helper that does some default mapping of methods to method names
347     * we do not hash the actual reflection information because
348     * we could collide with proxy serialisation holding fucking
349     * old classes
350     */

351
352    public static class DefaultMethodMap extends HashMap JavaDoc
353    {
354
355       /** no entries is the default */
356       public DefaultMethodMap()
357       {
358          super(0);
359       }
360
361       /** returns default interface if no mapping is defined */
362       public Object JavaDoc get(Object JavaDoc key)
363       {
364
365          Object JavaDoc result = super.get(((Method JavaDoc)key).getName());
366
367          if (result == null)
368          {
369             result = ((Method JavaDoc)key).getName();
370          }
371
372          return result;
373       }
374
375       /** registers a new method */
376       public Object JavaDoc put(Object JavaDoc key, Object JavaDoc value)
377       {
378          if (key instanceof Method JavaDoc)
379          {
380             return super.put(((Method JavaDoc)key).getName(), value);
381          }
382          else
383          {
384             return super.put(key, value);
385          }
386       }
387    }
388
389    /**
390     * serialization helper to reattach to engine, must be private
391     * to be called correctly
392     */

393    private void readObject(ObjectInputStream JavaDoc stream) throws IOException JavaDoc, ClassNotFoundException JavaDoc
394    {
395       stream.defaultReadObject();
396         
397       // try to find the engine that we were attached to
398
try
399       {
400          EngineConfigurationFactory factory = EngineConfigurationFactoryFinder.
401                  newFactory(new ObjectName JavaDoc(rootContext));
402
403          EngineConfiguration engine = null;
404
405          if (factory != null)
406          {
407             engine = factory.getClientEngineConfig();
408          }
409
410          if (engine != null)
411          {
412             call = new Call(new Service(engine));
413          }
414          else
415          {
416             // not there, try the default config
417
call = new Call(new Service());
418          }
419       }
420       catch (MalformedObjectNameException JavaDoc e)
421       {
422          throw new IOException JavaDoc("Could not contact jmx configuration factory." + e);
423       }
424
425       URL JavaDoc endpoint = new URL JavaDoc(endPoint);
426       call.setTargetEndpointAddress(endpoint);
427       setBasicAuthentication(endpoint);
428    }
429
430 }
431
Popular Tags