View Javadoc

    1   package org.codehaus.xfire.spring.remoting;
    2
    3   import org.codehaus.xfire.XFire;
    4   import org.codehaus.xfire.aegis.AegisBindingProvider;
    5   import org.codehaus.xfire.aegis.type.TypeMappingRegistry;
    6   import org.codehaus.xfire.annotations.AnnotationServiceFactory;
    7   import org.codehaus.xfire.annotations.WebAnnotations;
    8   import org.codehaus.xfire.service.Service;
    9   import org.codehaus.xfire.service.ServiceInfo;
    10  import org.codehaus.xfire.service.binding.BeanInvoker;
    11  import org.codehaus.xfire.service.binding.ObjectBinding;
    12  import org.codehaus.xfire.wsdl11.WSDL11ParameterBinding;
    13  import org.springframework.beans.BeansException;
    14  import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
    15  import org.springframework.context.ApplicationContextException;
    16  import org.springframework.context.ConfigurableApplicationContext;
    17  import org.springframework.web.servlet.handler.AbstractUrlHandlerMapping;
    18  import org.springframework.web.servlet.mvc.Controller;
    19
    20  /***
    21   * Implementation of the {@link org.springframework.web.servlet.HandlerMapping} interface that recognizes {@link
    22   * org.codehaus.xfire.annotations.WebServiceAnnotation web service annotations} on Spring-managed beans and
    23   * automatically wires them into the current servlet's WebApplicationContext.
    24   * <p/>
    25   * All beans Services are exposed by their {@link org.codehaus.xfire.annotations.WebServiceAnnotation#getServiceName()
    26   * service name}, with a defined {@link #setUrlPrefix(String) prefix}. For instance, a bean annotated with the service
    27   * name <code>EchoService</code> will be exposed as <code>/services/EchoService</code>.
    28   *
    29   * @author <a href="mailto:poutsma@mac.com">Arjen Poutsma</a>
    30   * @see WebAnnotations
    31   * @see org.codehaus.xfire.annotations.WebServiceAnnotation
    32   */
    33  public class Jsr181HandlerMapping
    34          extends AbstractUrlHandlerMapping
    35  {
    36      private WebAnnotations webAnnotations;
    37      private XFire xFire;
    38      private TypeMappingRegistry typeMappingRegistry;
    39      private String urlPrefix = "/services/";
    40
    41
    42      protected void initApplicationContext()
    43              throws BeansException
    44      {
    45          if (!(getApplicationContext() instanceof ConfigurableApplicationContext))
    46          {
    47              throw new ApplicationContextException(
    48                      "[" + getClass().getName() + "] needs to run in a ConfigurableApplicationContext");
    49          }
    50          ConfigurableListableBeanFactory beanFactory =
    51                  ((ConfigurableApplicationContext) getApplicationContext()).getBeanFactory();
    52
    53          String[] beanNames = getApplicationContext().getBeanDefinitionNames();
    54
    55          AnnotationServiceFactory serviceFactory =
    56                  new AnnotationServiceFactory(webAnnotations,
    57                                               xFire.getTransportManager(),
    58                                               new AegisBindingProvider(typeMappingRegistry));
    59
    60          // Take any bean name or alias that has a web service annotation
    61          for (int i = 0; i < beanNames.length; i++)
    62          {
    63              Class clazz = getApplicationContext().getType(beanNames[i]);
    64              if (webAnnotations.hasWebServiceAnnotation(clazz))
    65              {
    66                  Service endpoint = serviceFactory.create(clazz);
    67                  ServiceInfo service = endpoint.getServiceInfo();
    68                  if (logger.isInfoEnabled())
    69                  {
    70                      WSDL11ParameterBinding binding = (WSDL11ParameterBinding) endpoint.getBinding();
    71                      logger.info("Exposing SOAP v." + endpoint.getSoapVersion().getVersion() + " service " +
    72                                  service.getName() + " to " + urlPrefix + endpoint.getName() +
    73                                  " as " + binding.getStyle() + "/" + binding.getUse());
    74                  }
    75
    76                  xFire.getServiceRegistry().register(endpoint);
    77                  ((ObjectBinding) endpoint.getBinding()).setInvoker(new BeanInvoker(beanFactory.getBean(beanNames[i])));
    78                  Controller controller = new XFireServletControllerAdapter(xFire, endpoint.getServiceInfo().getName());
    79                  registerHandler(urlPrefix + endpoint.getName(), controller);
    80              }
    81              else
    82              {
    83                  if (logger.isDebugEnabled())
    84                  {
    85                      logger.debug("Rejected bean '" + beanNames[i] + "' since it has no WebService annotation");
    86                  }
    87              }
    88          }
    89      }
    90
    91      /***
    92       * Sets the web annotations implementation to use.
    93       */
    94      public void setWebAnnotations(WebAnnotations webAnnotations)
    95      {
    96          this.webAnnotations = webAnnotations;
    97      }
    98
    99      /***
    100      * Sets the XFire instance.
    101      */
    102     public void setXfire(XFire xFire)
    103     {
    104         this.xFire = xFire;
    105     }
    106
    107     /***
    108      * Sets the type mapping registry.
    109      */
    110     public void setTypeMappingRegistry(TypeMappingRegistry typeMappingRegistry)
    111     {
    112         this.typeMappingRegistry = typeMappingRegistry;
    113     }
    114
    115     /***
    116      * Sets the url prefix used when exposing services. Defaults to <code>/services/</code>.
    117      */
    118     public void setUrlPrefix(String urlPrefix)
    119     {
    120         this.urlPrefix = urlPrefix;
    121     }
    122 }