1 | |
|
2 | |
|
3 | |
|
4 | |
|
5 | |
|
6 | |
|
7 | |
|
8 | |
|
9 | |
|
10 | |
|
11 | |
package org.mule.transport.cxf; |
12 | |
|
13 | |
import org.mule.api.MuleException; |
14 | |
import org.mule.api.component.Component; |
15 | |
import org.mule.api.component.JavaComponent; |
16 | |
import org.mule.api.endpoint.InboundEndpoint; |
17 | |
import org.mule.api.lifecycle.Callable; |
18 | |
import org.mule.api.lifecycle.CreateException; |
19 | |
import org.mule.api.lifecycle.Disposable; |
20 | |
import org.mule.api.lifecycle.Initialisable; |
21 | |
import org.mule.api.lifecycle.InitialisationException; |
22 | |
import org.mule.api.service.Service; |
23 | |
import org.mule.api.service.ServiceAware; |
24 | |
import org.mule.api.transport.Connector; |
25 | |
import org.mule.transport.AbstractMessageReceiver; |
26 | |
import org.mule.transport.cxf.i18n.CxfMessages; |
27 | |
import org.mule.transport.cxf.support.MuleHeadersInInterceptor; |
28 | |
import org.mule.transport.cxf.support.MuleProtocolHeadersOutInterceptor; |
29 | |
import org.mule.transport.cxf.support.OutputPayloadInterceptor; |
30 | |
import org.mule.transport.cxf.support.ProxyService; |
31 | |
import org.mule.util.ClassUtils; |
32 | |
import org.mule.util.StringUtils; |
33 | |
|
34 | |
import java.util.ArrayList; |
35 | |
import java.util.HashMap; |
36 | |
import java.util.List; |
37 | |
import java.util.Map; |
38 | |
|
39 | |
import javax.xml.namespace.QName; |
40 | |
|
41 | |
import org.apache.commons.lang.BooleanUtils; |
42 | |
import org.apache.cxf.Bus; |
43 | |
import org.apache.cxf.aegis.databinding.AegisDatabinding; |
44 | |
import org.apache.cxf.configuration.Configurer; |
45 | |
import org.apache.cxf.databinding.DataBinding; |
46 | |
import org.apache.cxf.databinding.stax.StaxDataBinding; |
47 | |
import org.apache.cxf.databinding.stax.StaxDataBindingFeature; |
48 | |
import org.apache.cxf.endpoint.Server; |
49 | |
import org.apache.cxf.feature.AbstractFeature; |
50 | |
import org.apache.cxf.frontend.ServerFactoryBean; |
51 | |
import org.apache.cxf.interceptor.Interceptor; |
52 | |
import org.apache.cxf.jaxws.JaxWsServerFactoryBean; |
53 | |
import org.apache.cxf.service.factory.AbstractServiceConfiguration; |
54 | |
import org.apache.cxf.service.factory.ReflectionServiceFactoryBean; |
55 | |
|
56 | |
|
57 | |
|
58 | |
|
59 | |
|
60 | |
public class CxfMessageReceiver extends AbstractMessageReceiver |
61 | |
{ |
62 | |
|
63 | |
protected CxfConnector connector; |
64 | |
private Server server; |
65 | |
private boolean proxy; |
66 | |
private boolean applySecurityToProtocol; |
67 | |
private boolean applyTransformersToProtocol; |
68 | |
private boolean applyFiltersToProtocol; |
69 | |
|
70 | |
public CxfMessageReceiver(Connector connector, Service service, InboundEndpoint Endpoint) |
71 | |
throws CreateException |
72 | |
{ |
73 | 290 | super(connector, service, Endpoint); |
74 | 290 | this.connector = (CxfConnector) connector; |
75 | 290 | } |
76 | |
|
77 | |
@SuppressWarnings("unchecked") |
78 | |
@Override |
79 | |
protected void doInitialise() throws InitialisationException |
80 | |
{ |
81 | |
try |
82 | |
{ |
83 | 290 | Map endpointProps = getEndpoint().getProperties(); |
84 | 290 | String wsdlUrl = (String) endpointProps.get(CxfConstants.WSDL_LOCATION); |
85 | 290 | String bindingId = (String) endpointProps.get(CxfConstants.BINDING_ID); |
86 | 290 | String frontend = (String) endpointProps.get(CxfConstants.FRONTEND); |
87 | 290 | String serviceClassName = (String) endpointProps.get(CxfConstants.SERVICE_CLASS); |
88 | 290 | String mtomEnabled = (String) endpointProps.get(CxfConstants.MTOM_ENABLED); |
89 | 290 | List<DataBinding> databinding = (List<DataBinding>) endpointProps.get(CxfConstants.DATA_BINDING); |
90 | 290 | List<AbstractFeature> features = (List<AbstractFeature>) endpointProps.get(CxfConstants.FEATURES); |
91 | 290 | String proxyStr = (String) endpointProps.get(CxfConstants.PROXY); |
92 | |
|
93 | 290 | applyFiltersToProtocol = BooleanUtils.toBoolean((String) endpointProps.get(CxfConstants.APPLY_FILTERS_TO_PROTOCOL)); |
94 | 290 | applySecurityToProtocol = BooleanUtils.toBoolean((String) endpointProps.get(CxfConstants.APPLY_SECURITY_TO_PROTOCOL)); |
95 | 290 | applyTransformersToProtocol = BooleanUtils.toBoolean((String) endpointProps.get(CxfConstants.APPLY_TRANSFORMERS_TO_PROTOCOL)); |
96 | |
|
97 | 290 | Class<?> svcCls = null; |
98 | |
Class<?> targetCls; |
99 | |
|
100 | 290 | proxy = BooleanUtils.toBoolean(proxyStr); |
101 | |
|
102 | 290 | if (proxy) |
103 | |
{ |
104 | 40 | svcCls = ProxyService.class; |
105 | 40 | targetCls = svcCls; |
106 | 40 | frontend = "simple"; |
107 | |
} |
108 | |
else |
109 | |
{ |
110 | 250 | if (StringUtils.isEmpty(frontend)) |
111 | |
{ |
112 | 204 | frontend = connector.getDefaultFrontend(); |
113 | |
} |
114 | |
|
115 | 250 | if (!StringUtils.isEmpty(serviceClassName)) |
116 | |
{ |
117 | 10 | svcCls = ClassUtils.loadClass(serviceClassName, getClass()); |
118 | |
} |
119 | |
|
120 | 250 | targetCls = getTargetClass(svcCls); |
121 | |
|
122 | 250 | if (svcCls == null) |
123 | |
{ |
124 | 240 | svcCls = targetCls; |
125 | |
} |
126 | |
} |
127 | |
|
128 | 290 | ServerFactoryBean sfb = null; |
129 | 290 | if (CxfConstants.SIMPLE_FRONTEND.equals(frontend)) |
130 | |
{ |
131 | 256 | sfb = new ServerFactoryBean(); |
132 | 256 | sfb.setDataBinding(new AegisDatabinding()); |
133 | |
} |
134 | 34 | else if (CxfConstants.JAX_WS_FRONTEND.equals(frontend)) |
135 | |
{ |
136 | 34 | sfb = new JaxWsServerFactoryBean(); |
137 | |
} |
138 | |
else |
139 | |
{ |
140 | 0 | throw new CreateException(CxfMessages.invalidFrontend(frontend), this); |
141 | |
} |
142 | |
|
143 | 290 | if (!proxy) |
144 | |
{ |
145 | 250 | if (databinding != null && databinding.size() > 0) |
146 | |
{ |
147 | |
|
148 | 2 | sfb.setDataBinding(databinding.get(0)); |
149 | |
} |
150 | |
|
151 | 250 | if (service.getComponent() instanceof JavaComponent) |
152 | |
{ |
153 | 240 | sfb.setServiceBean(((JavaComponent) service.getComponent()).getObjectFactory().getInstance()); |
154 | |
} |
155 | |
} |
156 | |
else |
157 | |
{ |
158 | 40 | sfb.setDataBinding(new StaxDataBinding()); |
159 | 40 | sfb.getFeatures().add(new StaxDataBindingFeature()); |
160 | |
} |
161 | |
|
162 | |
|
163 | 290 | if (bindingId != null) |
164 | |
{ |
165 | 0 | sfb.setBindingId(bindingId); |
166 | |
} |
167 | |
|
168 | 290 | if (features != null) |
169 | |
{ |
170 | 26 | sfb.getFeatures().addAll(features); |
171 | |
} |
172 | |
|
173 | 290 | if (mtomEnabled != null) |
174 | |
{ |
175 | 2 | Map<String, Object> properties = sfb.getProperties(); |
176 | 2 | if (properties == null) |
177 | |
{ |
178 | 2 | properties = new HashMap<String, Object>(); |
179 | 2 | sfb.setProperties(properties); |
180 | |
} |
181 | 2 | properties.put("mtom-enabled", mtomEnabled); |
182 | |
} |
183 | |
|
184 | 290 | sfb.setInInterceptors((List<Interceptor>) endpointProps.get("inInterceptors")); |
185 | 290 | sfb.setInFaultInterceptors((List<Interceptor>) endpointProps.get("inFaultInterceptors")); |
186 | 290 | sfb.setOutInterceptors((List<Interceptor>) endpointProps.get("outInterceptors")); |
187 | 290 | sfb.setOutFaultInterceptors((List<Interceptor>) endpointProps.get("outFaultInterceptors")); |
188 | |
|
189 | 290 | if (sfb.getInInterceptors() == null) |
190 | |
{ |
191 | 288 | sfb.setInInterceptors(new ArrayList<Interceptor>()); |
192 | |
} |
193 | |
|
194 | 290 | sfb.getInInterceptors().add(new MuleHeadersInInterceptor()); |
195 | |
|
196 | 290 | if (sfb.getOutInterceptors() == null) |
197 | |
{ |
198 | 290 | sfb.setOutInterceptors(new ArrayList<Interceptor>()); |
199 | |
} |
200 | 290 | sfb.getOutInterceptors().add(new MuleProtocolHeadersOutInterceptor()); |
201 | |
|
202 | 290 | if (sfb.getOutFaultInterceptors() == null) |
203 | |
{ |
204 | 290 | sfb.setOutFaultInterceptors(new ArrayList<Interceptor>()); |
205 | |
} |
206 | 290 | sfb.getOutFaultInterceptors().add(new MuleProtocolHeadersOutInterceptor()); |
207 | |
|
208 | 290 | if (proxy) |
209 | |
{ |
210 | 40 | sfb.getOutInterceptors().add(new OutputPayloadInterceptor()); |
211 | |
} |
212 | |
|
213 | 290 | sfb.setServiceClass(svcCls); |
214 | 290 | sfb.setAddress(getAddressWithoutQuery()); |
215 | |
|
216 | 290 | if (wsdlUrl != null) |
217 | |
{ |
218 | 0 | sfb.setWsdlURL(wsdlUrl); |
219 | |
} |
220 | |
|
221 | 290 | ReflectionServiceFactoryBean svcFac = sfb.getServiceFactory(); |
222 | |
|
223 | 290 | addIgnoredMethods(svcFac, Callable.class.getName()); |
224 | 290 | addIgnoredMethods(svcFac, Initialisable.class.getName()); |
225 | 290 | addIgnoredMethods(svcFac, Disposable.class.getName()); |
226 | 290 | addIgnoredMethods(svcFac, ServiceAware.class.getName()); |
227 | |
|
228 | 290 | String name = (String) endpointProps.get(CxfConstants.NAME); |
229 | |
|
230 | 290 | String namespace = (String) endpointProps.get(CxfConstants.NAMESPACE); |
231 | |
|
232 | |
|
233 | 290 | initServiceName(svcCls, name, namespace, svcFac); |
234 | |
|
235 | 290 | boolean sync = endpoint.isSynchronous(); |
236 | |
|
237 | 290 | if (endpoint.getEndpointURI().getScheme().startsWith("http") |
238 | |
|| endpoint.getEndpointURI().getScheme().startsWith("servlet")) |
239 | |
{ |
240 | 204 | sync = true; |
241 | |
} |
242 | |
|
243 | 290 | sfb.setInvoker(new MuleInvoker(this, targetCls, sync)); |
244 | 290 | sfb.setStart(false); |
245 | |
|
246 | 290 | Bus bus = connector.getCxfBus(); |
247 | 290 | sfb.setBus(bus); |
248 | |
|
249 | 290 | initializeServerFactory(sfb); |
250 | |
|
251 | 290 | Configurer configurer = bus.getExtension(Configurer.class); |
252 | 290 | if (null != configurer) |
253 | |
{ |
254 | 290 | configurer.configureBean(sfb.getServiceFactory().getEndpointName().toString(), sfb); |
255 | |
} |
256 | |
|
257 | 290 | server = sfb.create(); |
258 | |
} |
259 | 0 | catch (MuleException e) |
260 | |
{ |
261 | 0 | throw new InitialisationException(e, this); |
262 | |
} |
263 | 0 | catch (ClassNotFoundException e) |
264 | |
{ |
265 | |
|
266 | |
|
267 | 0 | throw new InitialisationException(e, this); |
268 | |
} |
269 | 0 | catch (Exception e) |
270 | |
{ |
271 | 0 | throw new InitialisationException(e, this); |
272 | 290 | } |
273 | 290 | } |
274 | |
|
275 | |
|
276 | |
|
277 | |
|
278 | |
|
279 | |
|
280 | |
protected void initializeServerFactory(ServerFactoryBean sfb) |
281 | |
{ |
282 | 290 | } |
283 | |
|
284 | |
private String getAddressWithoutQuery() |
285 | |
{ |
286 | 290 | String a = getEndpointURI().getAddress(); |
287 | 290 | int idx = a.lastIndexOf('?'); |
288 | 290 | if (idx > -1) { |
289 | 0 | a = a.substring(0, idx); |
290 | |
} |
291 | 290 | return a; |
292 | |
} |
293 | |
|
294 | |
|
295 | |
|
296 | |
|
297 | |
|
298 | |
private void initServiceName(Class<?> exposedInterface, |
299 | |
String name, |
300 | |
String namespace, |
301 | |
ReflectionServiceFactoryBean svcFac) |
302 | |
{ |
303 | 290 | svcFac.setServiceClass(exposedInterface); |
304 | 290 | for (AbstractServiceConfiguration c : svcFac.getServiceConfigurations()) |
305 | |
{ |
306 | 324 | c.setServiceFactory(svcFac); |
307 | |
} |
308 | |
|
309 | 290 | if (name != null && namespace == null) |
310 | |
{ |
311 | 0 | namespace = svcFac.getServiceQName().getNamespaceURI(); |
312 | |
} |
313 | 290 | else if (name == null && namespace != null) |
314 | |
{ |
315 | 0 | name = svcFac.getServiceQName().getLocalPart(); |
316 | |
} |
317 | |
|
318 | 290 | if (name != null) |
319 | |
{ |
320 | 0 | svcFac.setServiceName(new QName(namespace, name)); |
321 | |
} |
322 | 290 | } |
323 | |
|
324 | |
public void addIgnoredMethods(ReflectionServiceFactoryBean svcFac, String className) |
325 | |
{ |
326 | |
try |
327 | |
{ |
328 | 1160 | Class<?> c = ClassUtils.loadClass(className, getClass()); |
329 | 2320 | for (int i = 0; i < c.getMethods().length; i++) |
330 | |
{ |
331 | 1160 | svcFac.getIgnoredMethods().add(c.getMethods()[i]); |
332 | |
} |
333 | |
} |
334 | 0 | catch (ClassNotFoundException e) |
335 | |
{ |
336 | |
|
337 | 1160 | } |
338 | 1160 | } |
339 | |
|
340 | |
private Class<?> getTargetClass(Class<?> svcCls) throws MuleException, ClassNotFoundException |
341 | |
{ |
342 | 250 | Component component = service.getComponent(); |
343 | 250 | if (!(component instanceof JavaComponent)) |
344 | |
{ |
345 | 10 | if (svcCls == null) |
346 | |
{ |
347 | 0 | throw new InitialisationException(CxfMessages.serviceClassRequiredWithPassThrough(), this); |
348 | |
} |
349 | |
else |
350 | |
{ |
351 | 10 | return svcCls; |
352 | |
} |
353 | |
} |
354 | |
|
355 | |
try |
356 | |
{ |
357 | 240 | return ((JavaComponent) component).getObjectType(); |
358 | |
} |
359 | 0 | catch (Exception e) |
360 | |
{ |
361 | 0 | throw new CreateException(e, this); |
362 | |
} |
363 | |
} |
364 | |
|
365 | |
protected void doDispose() |
366 | |
{ |
367 | |
|
368 | 580 | } |
369 | |
|
370 | |
public void doConnect() throws Exception |
371 | |
{ |
372 | |
|
373 | 288 | server.start(); |
374 | 288 | connector.registerReceiverWithMuleService(this, endpoint.getEndpointURI()); |
375 | 288 | } |
376 | |
|
377 | |
public void doDisconnect() throws Exception |
378 | |
{ |
379 | 288 | server.stop(); |
380 | 288 | } |
381 | |
|
382 | |
public void doStart() throws MuleException |
383 | |
{ |
384 | |
|
385 | 288 | } |
386 | |
|
387 | |
public void doStop() throws MuleException |
388 | |
{ |
389 | |
|
390 | 288 | } |
391 | |
|
392 | |
public Server getServer() |
393 | |
{ |
394 | 300 | return server; |
395 | |
} |
396 | |
|
397 | |
public boolean isProxy() |
398 | |
{ |
399 | 106 | return proxy; |
400 | |
} |
401 | |
|
402 | |
public boolean isApplySecurityToProtocol() |
403 | |
{ |
404 | 288 | return applySecurityToProtocol; |
405 | |
} |
406 | |
|
407 | |
public boolean isApplyTransformersToProtocol() |
408 | |
{ |
409 | 288 | return applyTransformersToProtocol; |
410 | |
} |
411 | |
|
412 | |
public boolean isApplyFiltersToProtocol() |
413 | |
{ |
414 | 288 | return applyFiltersToProtocol; |
415 | |
} |
416 | |
|
417 | |
} |