1
2
3
4
5
6
7
8
9
10
11 package org.mule.module.cxf.builder;
12
13 import org.mule.api.AnnotatedObject;
14 import org.mule.api.DefaultMuleException;
15 import org.mule.api.MuleContext;
16 import org.mule.api.MuleException;
17 import org.mule.api.context.MuleContextAware;
18 import org.mule.api.lifecycle.Callable;
19 import org.mule.api.lifecycle.Disposable;
20 import org.mule.api.lifecycle.Initialisable;
21 import org.mule.api.processor.MessageProcessorBuilder;
22 import org.mule.api.service.ServiceAware;
23 import org.mule.module.cxf.CxfConfiguration;
24 import org.mule.module.cxf.CxfConstants;
25 import org.mule.module.cxf.CxfInboundMessageProcessor;
26 import org.mule.module.cxf.MuleInvoker;
27 import org.mule.module.cxf.support.CxfUtils;
28 import org.mule.module.cxf.support.MuleHeadersInInterceptor;
29 import org.mule.module.cxf.support.MuleHeadersOutInterceptor;
30 import org.mule.module.cxf.support.MuleServiceConfiguration;
31 import org.mule.util.ClassUtils;
32
33 import java.util.Collections;
34 import java.util.HashMap;
35 import java.util.List;
36 import java.util.Map;
37 import java.util.concurrent.ConcurrentHashMap;
38 import java.util.concurrent.CopyOnWriteArrayList;
39
40 import javax.xml.namespace.QName;
41
42 import org.apache.cxf.Bus;
43 import org.apache.cxf.configuration.Configurer;
44 import org.apache.cxf.endpoint.Server;
45 import org.apache.cxf.feature.AbstractFeature;
46 import org.apache.cxf.frontend.ServerFactoryBean;
47 import org.apache.cxf.interceptor.AttachmentOutInterceptor;
48 import org.apache.cxf.interceptor.Interceptor;
49 import org.apache.cxf.interceptor.OneWayProcessorInterceptor;
50 import org.apache.cxf.message.Message;
51 import org.apache.cxf.service.factory.AbstractServiceConfiguration;
52 import org.apache.cxf.service.factory.ReflectionServiceFactoryBean;
53 import org.apache.cxf.service.invoker.Invoker;
54
55
56
57
58
59
60
61 public abstract class AbstractInboundMessageProcessorBuilder implements MuleContextAware, MessageProcessorBuilder, AnnotatedObject
62 {
63 private CxfConfiguration configuration;
64 private Server server;
65 private boolean enableMuleSoapHeaders = true;
66 private String wsdlLocation;
67 private String bindingId;
68 private String mtomEnabled;
69 private String soapVersion;
70 private String service;
71 private String namespace;
72 private List<AbstractFeature> features;
73 private List<Interceptor<? extends Message>> inInterceptors = new CopyOnWriteArrayList<Interceptor<? extends Message>>();
74 private List<Interceptor<? extends Message>> inFaultInterceptors = new CopyOnWriteArrayList<Interceptor<? extends Message>>();
75 private List<Interceptor<? extends Message>> outInterceptors = new CopyOnWriteArrayList<Interceptor<? extends Message>>();
76 private List<Interceptor<? extends Message>> outFaultInterceptors = new CopyOnWriteArrayList<Interceptor<? extends Message>>();
77 protected MuleContext muleContext;
78 private String port;
79 private Map<String,Object> properties = new HashMap<String, Object>();
80 private boolean validationEnabled;
81 private List<String> schemaLocations;
82 private String onException = CxfConstants.CREATE_SOAP_FAULT;
83 private final Map<QName, Object> annotations = new ConcurrentHashMap<QName, Object>();
84
85 @Override
86 public CxfInboundMessageProcessor build() throws MuleException
87 {
88 if (muleContext == null)
89 {
90 throw new IllegalStateException("MuleContext must be supplied.");
91 }
92
93 if (configuration == null)
94 {
95 configuration = CxfConfiguration.getConfiguration(muleContext);
96 }
97
98 if (configuration == null)
99 {
100 throw new IllegalStateException("A CxfConfiguration object must be supplied.");
101 }
102
103 ServerFactoryBean sfb;
104 try
105 {
106 sfb = createServerFactory();
107 }
108 catch (Exception e)
109 {
110 throw new DefaultMuleException(e);
111 }
112
113
114 if (bindingId != null)
115 {
116 sfb.setBindingId(bindingId);
117 }
118
119 if (features != null)
120 {
121 sfb.getFeatures().addAll(features);
122 }
123
124 if (mtomEnabled != null)
125 {
126 properties.put("mtom-enabled", mtomEnabled);
127 properties.put(AttachmentOutInterceptor.WRITE_ATTACHMENTS, true);
128 }
129
130 if (inInterceptors != null)
131 {
132 sfb.getInInterceptors().addAll(inInterceptors);
133 }
134
135 if (inFaultInterceptors != null)
136 {
137 sfb.getInFaultInterceptors().addAll(inFaultInterceptors);
138 }
139
140 if (outInterceptors != null)
141 {
142 sfb.getOutInterceptors().addAll(outInterceptors);
143 }
144
145 if (outFaultInterceptors != null)
146 {
147 sfb.getOutFaultInterceptors().addAll(outFaultInterceptors);
148 }
149
150 if (enableMuleSoapHeaders && !configuration.isEnableMuleSoapHeaders())
151 {
152 sfb.getInInterceptors().add(new MuleHeadersInInterceptor());
153 sfb.getInFaultInterceptors().add(new MuleHeadersInInterceptor());
154 sfb.getOutInterceptors().add(new MuleHeadersOutInterceptor());
155 sfb.getOutFaultInterceptors().add(new MuleHeadersOutInterceptor());
156 }
157
158 String address = getAddress();
159 address = CxfUtils.mapUnsupportedSchemas(address);
160 sfb.setAddress(address);
161
162 if (wsdlLocation != null)
163 {
164 sfb.setWsdlURL(wsdlLocation);
165 }
166
167 sfb.setSchemaLocations(schemaLocations);
168
169 ReflectionServiceFactoryBean svcFac = sfb.getServiceFactory();
170 initServiceFactory(svcFac);
171
172 CxfInboundMessageProcessor processor = new CxfInboundMessageProcessor();
173 processor.setMuleContext(muleContext);
174 processor.setOnFaultInvokeStrategy(CxfConstants.INVOKE_EXCEPTION_STRATEGY.equals(onException));
175 configureMessageProcessor(sfb, processor);
176 sfb.setStart(false);
177
178 Bus bus = configuration.getCxfBus();
179 sfb.setBus(bus);
180 svcFac.setBus(bus);
181
182 Configurer configurer = bus.getExtension(Configurer.class);
183 if (null != configurer)
184 {
185 configurer.configureBean(svcFac.getEndpointName().toString(), sfb);
186 }
187
188 if (validationEnabled)
189 {
190 properties.put("schema-validation-enabled", "true");
191 }
192
193
194 if(soapVersion != null)
195 {
196 sfb.setBindingId(CxfUtils.getBindingIdForSoapVersion(soapVersion));
197 }
198
199 sfb.setProperties(properties);
200 sfb.setInvoker(createInvoker(processor));
201
202 server = sfb.create();
203
204 CxfUtils.removeInterceptor(server.getEndpoint().getService().getInInterceptors(), OneWayProcessorInterceptor.class.getName());
205 configureServer(server);
206
207 processor.setBus(sfb.getBus());
208 processor.setServer(server);
209 processor.setProxy(isProxy());
210 return processor;
211 }
212
213 protected Invoker createInvoker(CxfInboundMessageProcessor processor)
214 {
215 return new MuleInvoker(processor, getServiceClass());
216 }
217
218 protected void configureServer(Server server2)
219 {
220
221 }
222
223 protected abstract Class<?> getServiceClass();
224
225 protected void configureMessageProcessor(ServerFactoryBean sfb, CxfInboundMessageProcessor processor)
226 {
227
228 }
229
230 protected abstract ServerFactoryBean createServerFactory() throws Exception;
231
232 protected String getAddress()
233 {
234 return "http://internalMuleCxfRegistry/" + hashCode();
235 }
236
237
238
239
240 private void initServiceFactory(ReflectionServiceFactoryBean svcFac)
241 {
242 addIgnoredMethods(svcFac, Callable.class.getName());
243 addIgnoredMethods(svcFac, Initialisable.class.getName());
244 addIgnoredMethods(svcFac, Disposable.class.getName());
245 addIgnoredMethods(svcFac, ServiceAware.class.getName());
246
247 svcFac.getServiceConfigurations().add(0, new MuleServiceConfiguration(this));
248
249 svcFac.setServiceClass(getServiceClass());
250 for (AbstractServiceConfiguration c : svcFac.getServiceConfigurations())
251 {
252 c.setServiceFactory(svcFac);
253 }
254 }
255
256 public void addIgnoredMethods(ReflectionServiceFactoryBean svcFac, String className)
257 {
258 try
259 {
260 Class<?> c = ClassUtils.loadClass(className, getClass());
261 for (int i = 0; i < c.getMethods().length; i++)
262 {
263 svcFac.getIgnoredMethods().add(c.getMethods()[i]);
264 }
265 }
266 catch (ClassNotFoundException e)
267 {
268
269 }
270 }
271
272
273 public Server getServer()
274 {
275 return server;
276 }
277
278 public abstract boolean isProxy();
279
280 public CxfConfiguration getConfiguration()
281 {
282 return configuration;
283 }
284
285 public void setConfiguration(CxfConfiguration configuration)
286 {
287 this.configuration = configuration;
288 }
289
290 public boolean isEnableMuleSoapHeaders()
291 {
292 return enableMuleSoapHeaders;
293 }
294
295 public void setEnableMuleSoapHeaders(boolean enableMuleSoapHeaders)
296 {
297 this.enableMuleSoapHeaders = enableMuleSoapHeaders;
298 }
299
300 public String getWsdlLocation()
301 {
302 return wsdlLocation;
303 }
304
305 public void setWsdlLocation(String wsdlUrl)
306 {
307 this.wsdlLocation = wsdlUrl;
308 }
309
310 public String getBindingId()
311 {
312 return bindingId;
313 }
314
315 public void setBindingId(String bindingId)
316 {
317 this.bindingId = bindingId;
318 }
319
320 public void setSoapVersion(String soapVersion)
321 {
322 this.soapVersion = soapVersion;
323 }
324
325 public String getSoapVersion()
326 {
327 return soapVersion;
328 }
329
330 public String getMtomEnabled()
331 {
332 return mtomEnabled;
333 }
334
335 public void setMtomEnabled(String mtomEnabled)
336 {
337 this.mtomEnabled = mtomEnabled;
338 }
339
340 public String getService()
341 {
342 return service;
343 }
344
345 public void setService(String name)
346 {
347 this.service = name;
348 }
349
350 public String getNamespace()
351 {
352 return namespace;
353 }
354
355 public void setNamespace(String namespace)
356 {
357 this.namespace = namespace;
358 }
359
360 public List<AbstractFeature> getFeatures()
361 {
362 return features;
363 }
364
365 public void setFeatures(List<AbstractFeature> features)
366 {
367 this.features = features;
368 }
369
370 public List<Interceptor<? extends Message>> getInInterceptors()
371 {
372 return inInterceptors;
373 }
374
375 public void setInInterceptors(List<Interceptor<? extends Message>> inInterceptors)
376 {
377 this.inInterceptors = inInterceptors;
378 }
379
380 public List<Interceptor<? extends Message>> getInFaultInterceptors()
381 {
382 return inFaultInterceptors;
383 }
384
385 public void setInFaultInterceptors(List<Interceptor<? extends Message>> inFaultInterceptors)
386 {
387 this.inFaultInterceptors = inFaultInterceptors;
388 }
389
390 public List<Interceptor<? extends Message>> getOutInterceptors()
391 {
392 return outInterceptors;
393 }
394
395 public void setOutInterceptors(List<Interceptor<? extends Message>> outInterceptors)
396 {
397 this.outInterceptors = outInterceptors;
398 }
399
400 public List<Interceptor<? extends Message>> getOutFaultInterceptors()
401 {
402 return outFaultInterceptors;
403 }
404
405 public void setOutFaultInterceptors(List<Interceptor<? extends Message>> outFaultInterceptors)
406 {
407 this.outFaultInterceptors = outFaultInterceptors;
408 }
409
410 @Override
411 public void setMuleContext(MuleContext muleContext)
412 {
413 this.muleContext = muleContext;
414 }
415
416 public String getPort()
417 {
418 return port;
419 }
420
421 public void setPort(String endpoint)
422 {
423 this.port = endpoint;
424 }
425
426 public Map<String, Object> getProperties()
427 {
428 return properties;
429 }
430
431 public void setProperties(Map<String, Object> properties)
432 {
433 this.properties = properties;
434 }
435
436 public boolean isValidationEnabled()
437 {
438 return validationEnabled;
439 }
440
441 public void setValidationEnabled(boolean validationEnabled)
442 {
443 this.validationEnabled = validationEnabled;
444 }
445
446 public List<String> getSchemaLocations()
447 {
448 return schemaLocations;
449 }
450
451 public void setSchemaLocations(List<String> schemaLocations)
452 {
453 this.schemaLocations = schemaLocations;
454 }
455
456 public String getOnException()
457 {
458 return this.onException;
459 }
460
461 public void setOnException(String onException)
462 {
463 this.onException = onException;
464 }
465
466 public final Object getAnnotation(QName name)
467 {
468 return annotations.get(name);
469 }
470
471 public final Map<QName, Object> getAnnotations()
472 {
473 return Collections.unmodifiableMap(annotations);
474 }
475
476 public synchronized final void setAnnotations(Map<QName, Object> newAnnotations)
477 {
478 annotations.clear();
479 annotations.putAll(newAnnotations);
480 }
481 }