1 package org.objectweb.celtix.bus.jaxws; 2 3 import java.io.IOException ; 4 import java.lang.reflect.Method ; 5 import java.util.Iterator ; 6 import java.util.List ; 7 import java.util.Map ; 8 import java.util.concurrent.ConcurrentHashMap ; 9 import java.util.concurrent.Executor ; 10 import java.util.logging.Level ; 11 import java.util.logging.Logger ; 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 ; 24 import javax.xml.transform.Source ; 25 import javax.xml.validation.Schema ; 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 ENDPOINT_CONFIGURATION_URI = 61 "http://celtix.objectweb.org/bus/jaxws/endpoint-config"; 62 63 private static final Logger 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 implementor; 71 protected Class <?> implementorClass; 72 protected final String bindingURI; 73 74 protected Configuration configuration; 75 protected List <Source > metadata; 76 protected Executor executor; 77 protected JAXBContext context; 78 protected Schema schema; 79 protected Map <String , Object > properties; 80 protected ServerBinding serverBinding; 81 82 protected boolean doInit; 83 protected boolean initialised; 84 85 protected List <Class <?>> seiClass; 87 88 protected ServiceMode serviceMode; 90 protected WebServiceProvider wsProvider; 91 protected Class <?> dataClass; 92 93 protected Map <QName , ServerDataBindingCallback> callbackMap 94 = new ConcurrentHashMap <QName , ServerDataBindingCallback>(); 95 96 public EndpointImpl(Bus b, Object impl, String bindingId) { 97 this(b, impl, bindingId, EndpointReferenceUtils.getEndpointReference(b.getWSDLManager(), impl)); 98 } 99 100 public EndpointImpl(Bus b, Object impl, String bindingId, EndpointReferenceType ref) { 101 this(b, impl, impl.getClass(), bindingId, ref); 102 } 103 public EndpointImpl(Bus b, Object obj, Class <?> implClass, String 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 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 try { 122 context = JAXBEncoderDecoder.createJAXBContextForClass(implementorClass); 123 } catch (JAXBException ex1) { 124 ex1.printStackTrace(); 125 context = null; 126 } 127 } 128 129 if (bus != null) { 130 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 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 ops = port.getBinding().getBindingOperations(); 169 Iterator opIt = ops.iterator(); 170 while (opIt.hasNext()) { 171 BindingOperation op = (BindingOperation)opIt.next(); 172 BindingInput bindingInput = op.getBindingInput(); 173 List elements = bindingInput.getExtensibilityElements(); 174 QName qn = new QName (def.getTargetNamespace(), op.getName()); 175 for (Iterator i = elements.iterator(); i.hasNext();) { 176 Object element = i.next(); 177 if (SOAPBody.class.isInstance(element)) { 178 SOAPBody body = (SOAPBody)element; 179 if (body.getNamespaceURI() != null) { 180 qn = new QName (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 serviceName = (QName )properties.get(Endpoint.WSDL_SERVICE); 197 QName portName = (QName )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 216 public Binding getBinding() { 217 if (doInit) { 219 init(); 220 } 221 return serverBinding.getBinding(); 222 } 223 224 225 230 public Object getImplementor() { 231 return implementor; 232 } 233 234 public void releaseImplementor(Object impl) { 235 } 237 238 241 public Class getImplementorClass() { 242 return implementorClass; 243 } 244 245 252 public List <Source > getMetadata() { 253 return metadata; 254 } 255 256 259 260 public Executor getExecutor() { 261 return executor; 262 } 263 264 269 public boolean isPublished() { 270 return published; 271 } 272 273 278 public void publish(Object serverContext) { 279 if (doInit) { 280 init(); 281 initialised = true; 282 } 283 if (isPublished()) { 284 LOG.warning("ENDPOINT_ALREADY_PUBLISHED_MSG"); 285 } 286 try { 288 String address = getAddressFromContext(serverContext); 289 if (!isContextBindingCompatible(address)) { 290 throw new IllegalArgumentException ( 291 new BusException(new Message("BINDING_INCOMPATIBLE_CONTEXT_EXC", LOG))); 292 } 293 publish(address); 294 } catch (Exception ex) { 295 throw new WebServiceException(ex); 296 } 297 } 298 299 304 public void publish(String address) { 305 306 SecurityManager 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 324 public void setMetadata(List <Source > m) { 325 if (isPublished()) { 326 throw new IllegalStateException ("Endpoint has already been published"); 327 } 328 metadata = m; 329 doInit = true; 330 } 331 332 335 public void setExecutor(Executor ex) { 336 executor = ex; 337 } 338 339 344 public void stop() { 345 if (!isPublished()) { 346 LOG.warning("ENDPOINT_INACTIVE_MSG"); 347 } 348 try { 349 serverBinding.deactivate(); 350 } catch (IOException 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 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 bindingId) throws BusException, WSDLException, IOException { 384 if (null == bindingId) { 385 BindingType bType = implementorClass.getAnnotation(BindingType.class); 386 if (bType != null) { 387 bindingId = bType.value(); 388 } 389 } 390 391 String 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 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 getAddressFromContext(Object ctx) throws Exception { 416 List <String > strs = configuration.getStringList("serverContextInspectors"); 417 Iterator iter = strs.iterator(); 418 String address = null; 419 while (iter.hasNext()) { 420 String className = (String )iter.next(); 421 422 try { 423 LOG.log(Level.FINE, "loading context inspector", className); 424 425 Class <? 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 e) { 435 throw new WebServiceException( 436 new Message("CONTEXT_INSPECTOR_INSTANTIATION_EXC", LOG).toString(), e); 437 } catch (InstantiationException e) { 438 throw new WebServiceException( 439 new Message("CONTEXT_INSPECTOR_INSTANTIATION_EXC", LOG).toString(), e); 440 } catch (IllegalAccessException 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 address) { 449 return serverBinding.isBindingCompatible(address); 450 } 451 452 void doPublish(String 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 ex) { 462 LOG.log(Level.SEVERE, "SERVER_BINDING_ACTIVATION_FAILURE_MSG", ex); 463 throw new WebServiceException(ex); 464 } 465 } 466 467 public Map <String , Object > getProperties() { 468 return properties; 469 } 470 471 public void setProperties(Map <String , Object > arg0) { 472 properties = arg0; 473 doInit = true; 474 } 475 476 477 482 protected void injectResources(Object instance) { 483 if (instance != null) { 484 ResourceInjector injector = new ResourceInjector(bus.getResourceManager()); 485 injector.inject(instance); 486 } 487 } 488 489 494 protected void injectResources() { 495 injectResources(implementor); 496 } 497 498 499 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 <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 enableSchemaValidation = configuration.getObject(Boolean .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 ("unchecked") 539 public ServerDataBindingCallback getDataBindingCallback(QName 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 getMethod(QName operationName) { 563 564 if (wsProvider == null) { 565 return EndpointUtils.getMethod(this, operationName); 566 } 567 568 Method 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 ex) { 577 } 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 <Class <?>> 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 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 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 e) { 634 } catch (WSDLException e) { 636 } 638 } 639 } 640 641 642 public Map <QName , ? 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 |