1 package org.codehaus.xfire.spring.remoting;
2
3 import java.lang.reflect.InvocationTargetException;
4 import java.lang.reflect.UndeclaredThrowableException;
5 import java.net.ConnectException;
6 import java.net.MalformedURLException;
7
8 import org.aopalliance.aop.AspectException;
9 import org.aopalliance.intercept.MethodInterceptor;
10 import org.aopalliance.intercept.MethodInvocation;
11 import org.codehaus.xfire.XFire;
12 import org.codehaus.xfire.client.XFireProxyFactory;
13 import org.codehaus.xfire.spring.ServiceBean;
14 import org.springframework.beans.factory.InitializingBean;
15 import org.springframework.remoting.RemoteAccessException;
16 import org.springframework.remoting.RemoteConnectFailureException;
17
18 /***
19 * Interceptor for accessing a XFire SOAP service.
20 *
21 * @author <a href="mailto:poutsma@mac.com">Arjen Poutsma</a>
22 * @see XFireExporter
23 * @see XFireProxyFactory
24 */
25 public class XFireClientInterceptor
26 implements MethodInterceptor, InitializingBean
27 {
28 private XFireProxyFactory proxyFactory;
29 private Object xFireProxy;
30
31 private String serviceUrl;
32 private ServiceBean service;
33 private XFire xfire;
34
35 public void afterPropertiesSet()
36 throws MalformedURLException
37 {
38 prepare();
39 }
40
41 /***
42 * Initialize the XFire proxy for this interceptor.
43 */
44 public void prepare()
45 throws MalformedURLException
46 {
47 if (getXfire() == null)
48 {
49 throw new IllegalArgumentException("xFire is required");
50 }
51 if (getServiceUrl() == null)
52 {
53 throw new IllegalArgumentException("serviceUrl is required");
54 }
55 if (this.proxyFactory == null)
56 {
57 this.proxyFactory = new XFireProxyFactory(getXfire());
58 }
59 this.xFireProxy = createXFireProxy(this.proxyFactory);
60 }
61
62 /***
63 * Create the XFire proxy that is wrapped by this interceptor.
64 *
65 * @param proxyFactory the proxy factory to use
66 * @return the Burlap proxy
67 * @throws MalformedURLException if thrown by the proxy factory
68 * @see XFireProxyFactory#create
69 */
70 protected Object createXFireProxy(XFireProxyFactory proxyFactory)
71 throws MalformedURLException
72 {
73 return proxyFactory.create(getService().getXFireService(), getServiceUrl());
74 }
75
76
77 public Object invoke(MethodInvocation invocation)
78 throws Throwable
79 {
80 if (this.xFireProxy == null)
81 {
82 throw new IllegalStateException("XFireClientInterceptor is not properly initialized - " +
83 "invoke 'prepare' before attempting any operations");
84 }
85
86 try
87 {
88 return invocation.getMethod().invoke(this.xFireProxy, invocation.getArguments());
89 }
90 catch (InvocationTargetException ex)
91 {
92 if (ex.getTargetException() instanceof UndeclaredThrowableException)
93 {
94 UndeclaredThrowableException utex = (UndeclaredThrowableException) ex.getTargetException();
95 throw convertBurlapAccessException(utex.getUndeclaredThrowable());
96 }
97 throw ex.getTargetException();
98 }
99 catch (Throwable ex)
100 {
101 throw new AspectException("Failed to invoke SOAP service [" + getServiceUrl() + "]", ex);
102 }
103 }
104
105 /***
106 * Convert the given Remote exception to an appropriate Spring RemoteAccessException.
107 *
108 * @param ex the exception to convert
109 * @return the RemoteAccessException to throw
110 */
111 protected RemoteAccessException convertBurlapAccessException(Throwable ex)
112 {
113 if (ex instanceof ConnectException)
114 {
115 throw new RemoteConnectFailureException("Cannot connect to SOAP service at [" + getServiceUrl() + "]", ex);
116 }
117 else
118 {
119 throw new RemoteAccessException("Cannot access SOAP service at [" + getServiceUrl() + "]", ex);
120 }
121 }
122
123 /***
124 * Set the <code>XFireProxyFactory</code> instance to use. If not specified, a default
125 * <code>XFireProxyFactory</code> will be created.
126 *
127 * @param proxyFactory the proxy factory
128 */
129 public void setProxyFactory(XFireProxyFactory proxyFactory)
130 {
131 this.proxyFactory = proxyFactory;
132 }
133
134 public String getServiceUrl()
135 {
136 return serviceUrl;
137 }
138
139 public void setServiceUrl(String serviceUrl)
140 {
141 this.serviceUrl = serviceUrl;
142 }
143
144 public ServiceBean getService()
145 {
146 return service;
147 }
148
149 public void setService(ServiceBean serviceBean)
150 {
151 this.service = serviceBean;
152 }
153
154 public XFire getXfire()
155 {
156 return xfire;
157 }
158
159 public void setXfire(XFire fire)
160 {
161 xfire = fire;
162 }
163 }
164