KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > objectweb > celtix > bus > jaxws > EndpointImpl


1 package org.objectweb.celtix.bus.jaxws;
2
3 import java.io.IOException JavaDoc;
4 import java.lang.reflect.Method JavaDoc;
5 import java.util.Iterator JavaDoc;
6 import java.util.List JavaDoc;
7 import java.util.Map JavaDoc;
8 import java.util.concurrent.ConcurrentHashMap JavaDoc;
9 import java.util.concurrent.Executor JavaDoc;
10 import java.util.logging.Level JavaDoc;
11 import java.util.logging.Logger JavaDoc;
12
13 import javax.jws.soap.SOAPBinding.Style;
14 import javax.wsdl.BindingInput;
15 import javax.wsdl.BindingOperation;
16 import javax.wsdl.Definition;
17 import javax.wsdl.Port;
18 import javax.wsdl.WSDLException;
19 import javax.wsdl.extensions.ExtensibilityElement;
20 import javax.wsdl.extensions.soap.SOAPBody;
21 import javax.xml.bind.JAXBContext;
22 import javax.xml.bind.JAXBException;
23 import javax.xml.namespace.QName JavaDoc;
24 import javax.xml.transform.Source JavaDoc;
25 import javax.xml.validation.Schema JavaDoc;
26 import javax.xml.ws.Binding;
27 import javax.xml.ws.BindingType;
28 import javax.xml.ws.Endpoint;
29 import javax.xml.ws.Provider;
30 import javax.xml.ws.ServiceMode;
31 import javax.xml.ws.WebServiceException;
32 import javax.xml.ws.WebServicePermission;
33 import javax.xml.ws.WebServiceProvider;
34 import javax.xml.ws.handler.Handler;
35 import javax.xml.ws.soap.SOAPBinding;
36
37 import org.objectweb.celtix.Bus;
38 import org.objectweb.celtix.BusException;
39 import org.objectweb.celtix.bindings.BindingFactory;
40 import org.objectweb.celtix.bindings.DataBindingCallback;
41 import org.objectweb.celtix.bindings.ServerBinding;
42 import org.objectweb.celtix.bindings.ServerBindingEndpointCallback;
43 import org.objectweb.celtix.bindings.ServerDataBindingCallback;
44 import org.objectweb.celtix.bus.handlers.AnnotationHandlerChainBuilder;
45 import org.objectweb.celtix.bus.jaxws.configuration.types.HandlerChainType;
46 import org.objectweb.celtix.common.i18n.Message;
47 import org.objectweb.celtix.common.injection.ResourceInjector;
48 import org.objectweb.celtix.common.logging.LogUtils;
49 import org.objectweb.celtix.configuration.Configuration;
50 import org.objectweb.celtix.configuration.ConfigurationBuilder;
51 import org.objectweb.celtix.configuration.ConfigurationBuilderFactory;
52 import org.objectweb.celtix.context.ObjectMessageContext;
53 import org.objectweb.celtix.endpoints.ContextInspector;
54 import org.objectweb.celtix.ws.addressing.EndpointReferenceType;
55 import org.objectweb.celtix.wsdl.EndpointReferenceUtils;
56
57 public class EndpointImpl extends javax.xml.ws.Endpoint
58     implements ServerBindingEndpointCallback {
59
60     public static final String JavaDoc ENDPOINT_CONFIGURATION_URI =
61         "http://celtix.objectweb.org/bus/jaxws/endpoint-config";
62     
63     private static final Logger JavaDoc LOG = LogUtils.getL7dLogger(EndpointImpl.class);
64
65     protected EndpointReferenceType reference;
66     
67     protected boolean published;
68     
69     protected final Bus bus;
70     protected final Object JavaDoc implementor;
71     protected Class JavaDoc<?> implementorClass;
72     protected final String JavaDoc bindingURI;
73     
74     protected Configuration configuration;
75     protected List JavaDoc<Source JavaDoc> metadata;
76     protected Executor JavaDoc executor;
77     protected JAXBContext context;
78     protected Schema JavaDoc schema;
79     protected Map JavaDoc<String JavaDoc, Object JavaDoc> properties;
80     protected ServerBinding serverBinding;
81     
82     protected boolean doInit;
83     protected boolean initialised;
84     
85     //Implemetor (SEI) specific members
86
protected List JavaDoc<Class JavaDoc<?>> seiClass;
87     
88     //Implementor (Provider) specific members
89
protected ServiceMode serviceMode;
90     protected WebServiceProvider wsProvider;
91     protected Class JavaDoc<?> dataClass;
92     
93     protected Map JavaDoc<QName JavaDoc, ServerDataBindingCallback> callbackMap
94         = new ConcurrentHashMap JavaDoc<QName JavaDoc, ServerDataBindingCallback>();
95     
96     public EndpointImpl(Bus b, Object JavaDoc impl, String JavaDoc bindingId) {
97         this(b, impl, bindingId, EndpointReferenceUtils.getEndpointReference(b.getWSDLManager(), impl));
98     }
99     
100     public EndpointImpl(Bus b, Object JavaDoc impl, String JavaDoc bindingId, EndpointReferenceType ref) {
101         this(b, impl, impl.getClass(), bindingId, ref);
102     }
103     public EndpointImpl(Bus b, Object JavaDoc obj, Class JavaDoc<?> implClass, String JavaDoc bindingId, EndpointReferenceType ref) {
104
105         bus = b;
106         implementor = obj;
107         implementorClass = implClass;
108         reference = ref;
109         bindingURI = bindingId;
110
111         if (Provider.class.isAssignableFrom(implementorClass)) {
112             //Provider Implementor
113
wsProvider = implementorClass.getAnnotation(WebServiceProvider.class);
114             if (wsProvider == null) {
115                 throw new WebServiceException(
116                            "Provider based implementor must carry a WebServiceProvider annotation");
117             }
118             serviceMode = implementorClass.getAnnotation(ServiceMode.class);
119         } else {
120             //SEI Implementor
121
try {
122                 context = JAXBEncoderDecoder.createJAXBContextForClass(implementorClass);
123             } catch (JAXBException ex1) {
124                 ex1.printStackTrace();
125                 context = null;
126             }
127         }
128
129         if (bus != null) {
130             //NOTE EndpointRegistry need to check the Registry instrumentation is created
131
bus.getEndpointRegistry().registerEndpoint(this);
132         }
133
134         doInit = true;
135     }
136     
137     private synchronized void init() {
138         if (doInit) {
139             try {
140                 injectResources();
141                 initProperties();
142                 initMetaData();
143     
144                 configuration = createConfiguration();
145                 if (null != configuration) {
146                     serverBinding = createServerBinding(bindingURI);
147                     configureHandlers();
148                     configureSystemHandlers();
149                     configureSchemaValidation();
150                 }
151                 
152                 initOpMap();
153             } catch (Exception JavaDoc ex) {
154                 if (ex instanceof WebServiceException) {
155                     throw (WebServiceException)ex;
156                 }
157                 throw new WebServiceException("Creation of Endpoint failed", ex);
158             }
159         }
160         doInit = false;
161     }
162     private void initOpMap() throws WSDLException {
163         Definition def = EndpointReferenceUtils.getWSDLDefinition(bus.getWSDLManager(), reference);
164         if (def == null) {
165             return;
166         }
167         Port port = EndpointReferenceUtils.getPort(bus.getWSDLManager(), reference);
168         List JavaDoc ops = port.getBinding().getBindingOperations();
169         Iterator JavaDoc opIt = ops.iterator();
170         while (opIt.hasNext()) {
171             BindingOperation op = (BindingOperation)opIt.next();
172             BindingInput bindingInput = op.getBindingInput();
173             List JavaDoc elements = bindingInput.getExtensibilityElements();
174             QName JavaDoc qn = new QName JavaDoc(def.getTargetNamespace(), op.getName());
175             for (Iterator JavaDoc i = elements.iterator(); i.hasNext();) {
176                 Object JavaDoc element = i.next();
177                 if (SOAPBody.class.isInstance(element)) {
178                     SOAPBody body = (SOAPBody)element;
179                     if (body.getNamespaceURI() != null) {
180                         qn = new QName JavaDoc(body.getNamespaceURI(), op.getName());
181                     }
182                 }
183             }
184             
185             ServerDataBindingCallback cb = getDataBindingCallback(qn, null,
186                                                                   DataBindingCallback.Mode.PARTS);
187             callbackMap.put(qn, cb);
188             if (!"".equals(cb.getRequestWrapperQName().getLocalPart())) {
189                 callbackMap.put(cb.getRequestWrapperQName(), cb);
190             }
191         }
192     }
193     
194     private void initProperties() {
195         if (null != properties) {
196             QName JavaDoc serviceName = (QName JavaDoc)properties.get(Endpoint.WSDL_SERVICE);
197             QName JavaDoc portName = (QName JavaDoc)properties.get(Endpoint.WSDL_PORT);
198             if (null != serviceName && null != portName) {
199                 EndpointReferenceUtils.setServiceAndPortName(reference, serviceName,
200                                                                        portName.getLocalPart());
201             }
202         }
203     }
204     
205     private void initMetaData() {
206         if (null != metadata) {
207             EndpointReferenceUtils.setMetadata(reference, metadata);
208         }
209     }
210     
211     /*
212      * (non-Javadoc)
213      *
214      * @see javax.xml.ws.Endpoint#getBinding()
215      */

216     public Binding getBinding() {
217         //Initialise the Endpoint so HandlerChain is set up on Binding.
218
if (doInit) {
219             init();
220         }
221         return serverBinding.getBinding();
222     }
223
224
225     /*
226      * (non-Javadoc)
227      *
228      * @see javax.xml.ws.Endpoint#getImplementor()
229      */

230     public Object JavaDoc getImplementor() {
231         return implementor;
232     }
233     
234     public void releaseImplementor(Object JavaDoc impl) {
235         //no-op for normal cases
236
}
237
238     /**
239      * @return Returns the Implementor Class.
240      */

241     public Class JavaDoc getImplementorClass() {
242         return implementorClass;
243     }
244
245     /*
246      * (non-Javadoc) Not sure if this is meant to return the effective metadata -
247      * or the default metadata previously assigned with
248      * javax.xml.ws.Endpoint#setHandlerChain()
249      *
250      * @see javax.xml.ws.Endpoint#getMetadata()
251      */

252     public List JavaDoc<Source JavaDoc> getMetadata() {
253         return metadata;
254     }
255
256     /**
257      * documented but not yet implemented in RI
258      */

259
260     public Executor JavaDoc getExecutor() {
261         return executor;
262     }
263
264     /*
265      * (non-Javadoc)
266      *
267      * @see javax.xml.ws.Endpoint#isPublished()
268      */

269     public boolean isPublished() {
270         return published;
271     }
272
273     /*
274      * (non-Javadoc)
275      *
276      * @see javax.xml.ws.Endpoint#publish(java.lang.Object)
277      */

278     public void publish(Object JavaDoc serverContext) {
279         if (doInit) {
280             init();
281             initialised = true;
282         }
283         if (isPublished()) {
284             LOG.warning("ENDPOINT_ALREADY_PUBLISHED_MSG");
285         }
286         // apply all changes to configuration and metadata and (re-)activate
287
try {
288             String JavaDoc address = getAddressFromContext(serverContext);
289             if (!isContextBindingCompatible(address)) {
290                 throw new IllegalArgumentException JavaDoc(
291                     new BusException(new Message("BINDING_INCOMPATIBLE_CONTEXT_EXC", LOG)));
292             }
293             publish(address);
294         } catch (Exception JavaDoc ex) {
295             throw new WebServiceException(ex);
296         }
297     }
298
299     /*
300      * (non-Javadoc)
301      *
302      * @see javax.xml.ws.Endpoint#publish(java.lang.String)
303      */

304     public void publish(String JavaDoc address) {
305         
306         SecurityManager JavaDoc security = System.getSecurityManager();
307         if (security != null) {
308             security.checkPermission(new WebServicePermission("endpointPublish"));
309         }
310         if (doInit && !initialised) {
311             init();
312         }
313         if (isPublished()) {
314             LOG.warning("ENDPOINT_ALREADY_PUBLISHED_MSG");
315         }
316         doPublish(address);
317     }
318
319     /*
320      * (non-Javadoc)
321      *
322      * @see javax.xml.ws.Endpoint#setMetadata(java.util.List)
323      */

324     public void setMetadata(List JavaDoc<Source JavaDoc> m) {
325         if (isPublished()) {
326             throw new IllegalStateException JavaDoc("Endpoint has already been published");
327         }
328         metadata = m;
329         doInit = true;
330     }
331
332     /**
333      * documented but not yet implemented in RI
334      */

335     public void setExecutor(Executor JavaDoc ex) {
336         executor = ex;
337     }
338
339     /*
340      * (non-Javadoc)
341      *
342      * @see javax.xml.ws.Endpoint#stop()
343      */

344     public void stop() {
345         if (!isPublished()) {
346             LOG.warning("ENDPOINT_INACTIVE_MSG");
347         }
348         try {
349             serverBinding.deactivate();
350         } catch (IOException JavaDoc ex) {
351             throw new WebServiceException(ex);
352         }
353         published = false;
354     }
355
356     public Bus getBus() {
357         return bus;
358     }
359     
360     public ServerBinding getServerBinding() {
361         if (doInit) {
362             init();
363         }
364
365         return serverBinding;
366     }
367     
368     public EndpointReferenceType getEndpointReferenceType() {
369         return reference;
370     }
371
372     private String JavaDoc getBindingIdFromWSDL() {
373         Port port = null;
374         try {
375             port = EndpointReferenceUtils.getPort(bus.getWSDLManager(), reference);
376         } catch (WSDLException we) {
377             return null;
378         }
379         return ((ExtensibilityElement)port.getExtensibilityElements().get(0)).
380             getElementType().getNamespaceURI();
381     }
382
383     ServerBinding createServerBinding(String JavaDoc bindingId) throws BusException, WSDLException, IOException JavaDoc {
384         if (null == bindingId) {
385             BindingType bType = implementorClass.getAnnotation(BindingType.class);
386             if (bType != null) {
387                 bindingId = bType.value();
388             }
389         }
390         
391         String JavaDoc bindingIdFromWSDL = null;
392         if (bindingId == null) {
393             bindingIdFromWSDL = getBindingIdFromWSDL();
394         }
395         
396         if (null == bindingId && null != bindingIdFromWSDL) {
397             bindingId = bindingIdFromWSDL;
398         }
399         
400         if (null == bindingId) {
401             // Use SOAP1.1/HTTP Binding as default. JAX-WS Spec 5.2.1
402
bindingId = SOAPBinding.SOAP11HTTP_BINDING;
403         }
404         
405         BindingFactory factory = bus.getBindingManager().getBindingFactory(bindingId);
406         if (null == factory) {
407             throw new BusException(new Message("BINDING_FACTORY_MISSING_EXC", LOG, bindingId));
408         }
409         ServerBinding bindingImpl = factory.createServerBinding(reference, this);
410         assert null != bindingImpl;
411         return bindingImpl;
412
413     }
414
415     String JavaDoc getAddressFromContext(Object JavaDoc ctx) throws Exception JavaDoc {
416         List JavaDoc<String JavaDoc> strs = configuration.getStringList("serverContextInspectors");
417         Iterator JavaDoc iter = strs.iterator();
418         String JavaDoc address = null;
419         while (iter.hasNext()) {
420             String JavaDoc className = (String JavaDoc)iter.next();
421             
422             try {
423                 LOG.log(Level.FINE, "loading context inspector", className);
424
425                 Class JavaDoc<? extends ContextInspector> inspectorClass =
426                     Class.forName(className, true,
427                                   getContextInspectorClassLoader()).asSubclass(ContextInspector.class);
428
429                 ContextInspector inspector = inspectorClass.newInstance();
430                 address = inspector.getAddress(ctx);
431                 if (address != null) {
432                     return address;
433                 }
434             } catch (ClassNotFoundException JavaDoc e) {
435                 throw new WebServiceException(
436                     new Message("CONTEXT_INSPECTOR_INSTANTIATION_EXC", LOG).toString(), e);
437             } catch (InstantiationException JavaDoc e) {
438                 throw new WebServiceException(
439                     new Message("CONTEXT_INSPECTOR_INSTANTIATION_EXC", LOG).toString(), e);
440             } catch (IllegalAccessException JavaDoc e) {
441                 throw new WebServiceException(
442                     new Message("CONTEXT_INSPECTOR_INSTANTIATION_EXC", LOG).toString(), e);
443             }
444         }
445         return address;
446     }
447
448     protected boolean isContextBindingCompatible(String JavaDoc address) {
449         return serverBinding.isBindingCompatible(address);
450     }
451
452     void doPublish(String JavaDoc address) {
453
454         EndpointReferenceUtils.setAddress(reference, address);
455         try {
456             serverBinding.activate();
457             published = true;
458         } catch (WSDLException ex) {
459             LOG.log(Level.SEVERE, "SERVER_BINDING_ACTIVATION_FAILURE_MSG", ex);
460             throw new WebServiceException(ex);
461         } catch (IOException JavaDoc ex) {
462             LOG.log(Level.SEVERE, "SERVER_BINDING_ACTIVATION_FAILURE_MSG", ex);
463             throw new WebServiceException(ex);
464         }
465     }
466
467     public Map JavaDoc<String JavaDoc, Object JavaDoc> getProperties() {
468         return properties;
469     }
470
471     public void setProperties(Map JavaDoc<String JavaDoc, Object JavaDoc> arg0) {
472         properties = arg0;
473         doInit = true;
474     }
475
476
477     /**
478      * inject resources into servant. The resources are injected
479      * according to @Resource annotations. See JSR 250 for more
480      * information.
481      */

482     protected void injectResources(Object JavaDoc instance) {
483         if (instance != null) {
484             ResourceInjector injector = new ResourceInjector(bus.getResourceManager());
485             injector.inject(instance);
486         }
487     }
488
489     /**
490      * inject resources into servant. The resources are injected
491      * according to @Resource annotations. See JSR 250 for more
492      * information.
493      */

494     protected void injectResources() {
495         injectResources(implementor);
496     }
497
498
499     /**
500      * Obtain handler chain from configuration first. If none is specified,
501      * default to the chain configured in the code, i.e. in annotations.
502      *
503      */

504     private void configureHandlers() {
505
506         LOG.fine("loading handler chain for endpoint");
507         AnnotationHandlerChainBuilder builder = new AnnotationHandlerChainBuilder();
508         HandlerChainType hc = (HandlerChainType)configuration.getObject("handlerChain");
509         List JavaDoc<Handler> chain = builder.buildHandlerChainFromConfiguration(hc);
510         if (null == chain || chain.size() == 0) {
511             chain = builder.buildHandlerChainFor(implementorClass);
512         }
513         serverBinding.getBinding().setHandlerChain(chain);
514     }
515
516     private void configureSystemHandlers() {
517         serverBinding.configureSystemHandlers(configuration);
518     }
519
520     private void configureSchemaValidation() {
521         Boolean JavaDoc enableSchemaValidation = configuration.getObject(Boolean JavaDoc.class,
522             "enableSchemaValidation");
523
524         if (enableSchemaValidation != null && enableSchemaValidation.booleanValue()) {
525             LOG.fine("endpoint schema validation enabled");
526             schema = EndpointReferenceUtils.getSchema(bus.getWSDLManager(), reference);
527         }
528     }
529
530     public DataBindingCallback getFaultDataBindingCallback(ObjectMessageContext objContext) {
531         return new JAXBDataBindingCallback(null,
532                                          DataBindingCallback.Mode.PARTS,
533                                          context,
534                                          schema,
535                                          this);
536     }
537
538     @SuppressWarnings JavaDoc("unchecked")
539     public ServerDataBindingCallback getDataBindingCallback(QName JavaDoc operationName,
540                                                             ObjectMessageContext objContext,
541                                                             DataBindingCallback.Mode mode) {
542         if (mode == DataBindingCallback.Mode.PARTS) {
543             ServerDataBindingCallback cb = callbackMap.get(operationName);
544             if (null == cb) {
545                 cb = new JAXBDataBindingCallback(getMethod(operationName),
546                                                  DataBindingCallback.Mode.PARTS,
547                                                  context,
548                                                  schema,
549                                                  this);
550             }
551             
552             return cb;
553         }
554         
555         if (dataClass == null) {
556             dataClass = EndpointUtils.getProviderParameterType(this);
557         }
558
559         return new ServerDynamicDataBindingCallback(dataClass, mode, (Provider<?>) implementor);
560     }
561
562     public Method JavaDoc getMethod(QName JavaDoc operationName) {
563
564         if (wsProvider == null) {
565             return EndpointUtils.getMethod(this, operationName);
566         }
567
568         Method JavaDoc invokeMethod = null;
569         if (operationName.getLocalPart().equals("invoke")) {
570
571             try {
572                 if (dataClass == null) {
573                     dataClass = EndpointUtils.getProviderParameterType(this);
574                 }
575                 invokeMethod = implementorClass.getMethod("invoke", dataClass);
576             } catch (NoSuchMethodException JavaDoc ex) {
577                 //TODO
578
}
579         }
580         return invokeMethod;
581     }
582
583     public DataBindingCallback.Mode getServiceMode() {
584         DataBindingCallback.Mode mode = DataBindingCallback.Mode.PARTS;
585
586         if (wsProvider != null) {
587             mode = serviceMode != null
588                     ? DataBindingCallback.Mode.fromServiceMode(serviceMode.value())
589                     : DataBindingCallback.Mode.PAYLOAD;
590         }
591         return mode;
592     }
593
594     public WebServiceProvider getWebServiceProvider() {
595         return wsProvider;
596     }
597
598     public synchronized List JavaDoc<Class JavaDoc<?>> getWebServiceAnnotatedClass() {
599         if (null == seiClass) {
600             seiClass = EndpointUtils.getWebServiceAnnotatedClass(implementorClass);
601         }
602         return seiClass;
603     }
604
605     private Configuration createConfiguration() {
606
607         Configuration busCfg = bus.getConfiguration();
608         if (null == busCfg) {
609             return null;
610         }
611
612         Configuration cfg = null;
613         String JavaDoc id = EndpointReferenceUtils.getServiceName(reference).toString();
614         ConfigurationBuilder cb = ConfigurationBuilderFactory.getBuilder(null);
615         cfg = cb.getConfiguration(ENDPOINT_CONFIGURATION_URI, id, busCfg);
616         if (null == cfg) {
617             cfg = cb.buildConfiguration(ENDPOINT_CONFIGURATION_URI, id, busCfg);
618         }
619         return cfg;
620     }
621     
622     private ClassLoader JavaDoc getContextInspectorClassLoader() {
623         return getClass().getClassLoader();
624     }
625         
626     void start() {
627         if (published) {
628             return;
629         } else {
630             try {
631                 serverBinding.activate();
632                 published = true;
633             } catch (IOException JavaDoc e) {
634                 //e.printStackTrace();
635
} catch (WSDLException e) {
636                 //e.printStackTrace();
637
}
638         }
639     }
640
641
642     public Map JavaDoc<QName JavaDoc, ? extends DataBindingCallback> getOperations() {
643         return callbackMap;
644     }
645
646     public Style getStyle() {
647         javax.jws.soap.SOAPBinding bind = implementorClass
648             .getAnnotation(javax.jws.soap.SOAPBinding.class);
649         if (bind != null) {
650             return bind.style();
651         }
652         return javax.jws.soap.SOAPBinding.Style.DOCUMENT;
653     }
654    
655 }
656
Popular Tags