All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.codehaus.xfire.spring.remoting.Jsr181HandlerMapping Maven / Gradle / Ivy

The newest version!
package org.codehaus.xfire.spring.remoting;

import java.lang.reflect.Modifier;
import java.util.List;

import javax.xml.namespace.QName;

import org.codehaus.xfire.XFire;
import org.codehaus.xfire.aegis.AegisBindingProvider;
import org.codehaus.xfire.aegis.type.TypeMappingRegistry;
import org.codehaus.xfire.annotations.AnnotationServiceFactory;
import org.codehaus.xfire.annotations.AnnotationsValidator;
import org.codehaus.xfire.annotations.WebAnnotations;
import org.codehaus.xfire.service.Service;
import org.codehaus.xfire.service.invoker.BeanInvoker;
import org.codehaus.xfire.spring.SpringUtils;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanIsAbstractException;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.web.servlet.handler.AbstractUrlHandlerMapping;

/**
 * Implementation of the {@link org.springframework.web.servlet.HandlerMapping} interface that recognizes {@link
 * org.codehaus.xfire.annotations.WebServiceAnnotation web service annotations} on Spring-managed beans and
 * automatically wires them into the current servlet's WebApplicationContext.
 * 

* All beans Services are exposed by their {@link org.codehaus.xfire.annotations.WebServiceAnnotation#getServiceName() * service name}, with a defined {@link #setUrlPrefix(String) prefix}. For instance, a bean annotated with the service * name EchoService will be exposed as /services/EchoService. * * @author Arjen Poutsma * @see WebAnnotations * @see org.codehaus.xfire.annotations.WebServiceAnnotation */ public class Jsr181HandlerMapping extends AbstractUrlHandlerMapping { private WebAnnotations webAnnotations; private XFire xFire; private TypeMappingRegistry typeMappingRegistry; private String urlPrefix = "/services/"; private String servletControllerAdapterName; private AnnotationServiceFactory serviceFactory; private AnnotationsValidator validator; private List inHandlers; private List outHandlers; private List faultHandlers; protected void initApplicationContext() throws BeansException { if (serviceFactory == null) { serviceFactory = createServiceFactory(); } ApplicationContext context = getApplicationContext(); while (true) { if (context == null) break; processBeans(context, serviceFactory); context = context.getParent(); } } public AnnotationServiceFactory getServiceFactory() { return serviceFactory; } public void setServiceFactory(AnnotationServiceFactory serviceFactory) { this.serviceFactory = serviceFactory; } private AnnotationServiceFactory createServiceFactory() { AegisBindingProvider provider; if (typeMappingRegistry == null) provider = new AegisBindingProvider(); else provider = new AegisBindingProvider(typeMappingRegistry); AnnotationServiceFactory serviceFactory = new AnnotationServiceFactory(webAnnotations, xFire.getTransportManager(), provider); if( validator != null ){ serviceFactory.setValidator(validator); } return serviceFactory; } private void processBeans(ApplicationContext beanFactory, AnnotationServiceFactory serviceFactory) { String[] beanNames = beanFactory.getBeanDefinitionNames(); ConfigurableApplicationContext ctxt = (ConfigurableApplicationContext) beanFactory; // Take any bean name or alias that has a web service annotation for (int i = 0; i < beanNames.length; i++) { BeanDefinition def = ctxt.getBeanFactory().getBeanDefinition(beanNames[i]); if (!def.isSingleton() || def.isAbstract()) continue; Class clazz; Object bean; try { clazz = getApplicationContext().getType(beanNames[i]); bean = beanFactory.getBean(beanNames[i]); try { clazz = SpringUtils.getUserTarget(bean).getClass(); } catch (Exception e) { logger.error("Failed to get the User Target Class of bean " + beanNames[i], e); } } catch (BeanIsAbstractException e) { // The bean is abstract, we won't be doing anything with it. continue; } if (clazz != null && !Modifier.isAbstract(clazz.getModifiers()) && webAnnotations.hasWebServiceAnnotation(clazz)) { Service endpoint = serviceFactory.create(clazz); customizeService(bean, endpoint); } else { if (logger.isDebugEnabled()) { logger.debug("Rejected bean '" + beanNames[i] + "' since it has no WebService annotation"); } } } } protected void customizeService(Object bean, Service endpoint) { if (logger.isInfoEnabled()) { logger.info("Exposing service " + endpoint.getName() + " to " + urlPrefix + endpoint.getSimpleName()); } if( getInHandlers()!= null ){ endpoint.getInHandlers().addAll(getInHandlers()); } if( getOutHandlers()!= null ){ endpoint.getOutHandlers().addAll(getOutHandlers()); } if( getFaultHandlers()!= null ){ endpoint.getFaultHandlers().addAll(getFaultHandlers()); } xFire.getServiceRegistry().register(endpoint); endpoint.setInvoker(new BeanInvoker(bean)); Object controller = createController(endpoint.getName()); registerHandler(urlPrefix + endpoint.getSimpleName(), controller); } public XFire getXFire() { return xFire; } /** * Creates the XFireServletControllerAdapter either indirectly using the * XFireServletControllerAdapter prototype bean declared in the Spring app context, * or directly through the the constructor of XFireServletControllerAdapter. * * @param endpointName The endpointName to inject into the XFireServletControllerAdapter * @return A new instance of XFireServletControllerAdapter */ private Object createController(QName endpointName) { if (servletControllerAdapterName != null) { Object controller = getApplicationContext().getBean(servletControllerAdapterName); if (controller == null) { logger.error("Failed to find bean with name " + servletControllerAdapterName); } else { try { XFireServletControllerAdapter xFireServletControllerAdapter = (XFireServletControllerAdapter) SpringUtils.getUserTarget(controller); xFireServletControllerAdapter.setServiceName(endpointName); return controller; } catch (Exception e) { logger.error("Failed to create a Controller for endpoint " + endpointName, e); } } } return new XFireServletControllerAdapter(xFire, endpointName); } /** * Sets the web annotations implementation to use. */ public void setWebAnnotations(WebAnnotations webAnnotations) { this.webAnnotations = webAnnotations; } /** * Sets the XFire instance. */ public void setXfire(XFire xFire) { this.xFire = xFire; } /** * Sets the type mapping registry. */ public void setTypeMappingRegistry(TypeMappingRegistry typeMappingRegistry) { this.typeMappingRegistry = typeMappingRegistry; } /** * Sets the url prefix used when exposing services. Defaults to /services/. */ public void setUrlPrefix(String urlPrefix) { this.urlPrefix = urlPrefix; } public void setServletControllerAdapterName(String servletControllerAdapterName) { this.servletControllerAdapterName = servletControllerAdapterName; } public List getInHandlers() { return inHandlers; } public void setInHandlers(List inHandlers) { this.inHandlers = inHandlers; } public List getOutHandlers() { return outHandlers; } public void setOutHandlers(List outHandlers) { this.outHandlers = outHandlers; } public List getFaultHandlers() { return faultHandlers; } public void setFaultHandlers(List faultHandlers) { this.faultHandlers = faultHandlers; } public void setValidator(AnnotationsValidator validator) { this.validator = validator; } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy