From 11924e462799e5a7146bc6abf2a4fdf5bfc61748 Mon Sep 17 00:00:00 2001 From: Arjen Poutsma Date: Mon, 30 Jun 2008 14:38:46 +0000 Subject: [PATCH] SWS-346 --- .../http/MessageDispatcherServlet.java | 98 ++++++++++++++++++- 1 file changed, 94 insertions(+), 4 deletions(-) diff --git a/core/src/main/java/org/springframework/ws/transport/http/MessageDispatcherServlet.java b/core/src/main/java/org/springframework/ws/transport/http/MessageDispatcherServlet.java index 50f4ca8d..9ea010dc 100644 --- a/core/src/main/java/org/springframework/ws/transport/http/MessageDispatcherServlet.java +++ b/core/src/main/java/org/springframework/ws/transport/http/MessageDispatcherServlet.java @@ -26,6 +26,7 @@ import org.springframework.beans.BeansException; import org.springframework.beans.factory.BeanFactoryUtils; import org.springframework.beans.factory.BeanInitializationException; import org.springframework.beans.factory.BeanNameAware; +import org.springframework.beans.factory.InitializingBean; import org.springframework.beans.factory.NoSuchBeanDefinitionException; import org.springframework.core.io.ClassPathResource; import org.springframework.web.servlet.DispatcherServlet; @@ -39,6 +40,7 @@ import org.springframework.ws.server.MessageDispatcher; import org.springframework.ws.support.DefaultStrategiesHelper; import org.springframework.ws.transport.WebServiceMessageReceiver; import org.springframework.ws.wsdl.WsdlDefinition; +import org.springframework.xml.xsd.XsdSchema; /** * Servlet for simplified dispatching of Web service messages. @@ -80,6 +82,9 @@ public class MessageDispatcherServlet extends FrameworkServlet { /** Well-known name for the {@link WsdlDefinitionHandlerAdapter} object in the bean factory for this namespace. */ public static final String DEFAULT_WSDL_DEFINITION_HANDLER_ADAPTER_BEAN_NAME = "wsdlDefinitionHandlerAdapter"; + /** Well-known name for the {@link XsdSchemaHandlerAdapter} object in the bean factory for this namespace. */ + public static final String DEFAULT_XSD_SCHEMA_HANDLER_ADAPTER_BEAN_NAME = "xsdSchemaHandlerAdapter"; + /** * Name of the class path resource (relative to the {@link MessageDispatcherServlet} class) that defines * MessageDispatcherServlet's default strategy names. @@ -89,6 +94,9 @@ public class MessageDispatcherServlet extends FrameworkServlet { /** Suffix of a WSDL request uri. */ private static final String WSDL_SUFFIX_NAME = ".wsdl"; + /** Suffix of a XSD request uri. */ + private static final String XSD_SUFFIX_NAME = ".xsd"; + private final DefaultStrategiesHelper defaultStrategiesHelper; private String messageFactoryBeanName = DEFAULT_MESSAGE_FACTORY_BEAN_NAME; @@ -103,6 +111,11 @@ public class MessageDispatcherServlet extends FrameworkServlet { /** The {@link WsdlDefinitionHandlerAdapter} used by this servlet. */ private WsdlDefinitionHandlerAdapter wsdlDefinitionHandlerAdapter; + private String xsdSchemaHandlerAdapterBeanName = DEFAULT_XSD_SCHEMA_HANDLER_ADAPTER_BEAN_NAME; + + /** The {@link XsdSchemaHandlerAdapter} used by this servlet. */ + private XsdSchemaHandlerAdapter xsdSchemaHandlerAdapter; + private String messageReceiverBeanName = DEFAULT_MESSAGE_RECEIVER_BEAN_NAME; /** The {@link WebServiceMessageReceiver} used by this servlet. */ @@ -111,6 +124,8 @@ public class MessageDispatcherServlet extends FrameworkServlet { /** Keys are bean names, values are {@link WsdlDefinition WsdlDefinitions}. */ private Map wsdlDefinitions; + private Map xsdSchemas; + private boolean transformWsdlLocations = false; /** Public constructor, necessary for some Web application servers. */ @@ -179,6 +194,19 @@ public class MessageDispatcherServlet extends FrameworkServlet { this.wsdlDefinitionHandlerAdapterBeanName = wsdlDefinitionHandlerAdapterBeanName; } + /** Returns the bean name used to lookup a {@link XsdSchemaHandlerAdapter}. */ + public String getXsdSchemaHandlerAdapterBeanName() { + return xsdSchemaHandlerAdapterBeanName; + } + + /** + * Sets the bean name used to lookup a {@link XsdSchemaHandlerAdapter}. Defaults to {@link + * #DEFAULT_XSD_SCHEMA_HANDLER_ADAPTER_BEAN_NAME}. + */ + public void setXsdSchemaHandlerAdapterBeanName(String xsdSchemaHandlerAdapterBeanName) { + this.xsdSchemaHandlerAdapterBeanName = xsdSchemaHandlerAdapterBeanName; + } + /** * Sets whether relative address locations in the WSDL are to be transformed using the request URI of the incoming * {@link HttpServletRequest}. Defaults to false. @@ -192,17 +220,23 @@ public class MessageDispatcherServlet extends FrameworkServlet { WsdlDefinition definition = getWsdlDefinition(httpServletRequest); if (definition != null) { wsdlDefinitionHandlerAdapter.handle(httpServletRequest, httpServletResponse, definition); + return; } - else { - messageReceiverHandlerAdapter.handle(httpServletRequest, httpServletResponse, messageReceiver); + XsdSchema schema = getXsdSchema(httpServletRequest); + if (schema != null) { + xsdSchemaHandlerAdapter.handle(httpServletRequest, httpServletResponse, schema); + return; } + messageReceiverHandlerAdapter.handle(httpServletRequest, httpServletResponse, messageReceiver); } protected void initFrameworkServlet() throws ServletException, BeansException { initMessageReceiverHandlerAdapter(); initWsdlDefinitionHandlerAdapter(); + initXsdSchemaHandlerAdapter(); initMessageReceiver(); initWsdlDefinitions(); + initXsdSchemas(); } protected long getLastModified(HttpServletRequest httpServletRequest) { @@ -210,9 +244,11 @@ public class MessageDispatcherServlet extends FrameworkServlet { if (definition != null) { return wsdlDefinitionHandlerAdapter.getLastModified(httpServletRequest, definition); } - else { - return messageReceiverHandlerAdapter.getLastModified(httpServletRequest, messageReceiver); + XsdSchema schema = getXsdSchema(httpServletRequest); + if (schema != null) { + return xsdSchemaHandlerAdapter.getLastModified(httpServletRequest, schema); } + return messageReceiverHandlerAdapter.getLastModified(httpServletRequest, messageReceiver); } /** Returns the {@link WebServiceMessageReceiver} used by this servlet. */ @@ -241,6 +277,27 @@ public class MessageDispatcherServlet extends FrameworkServlet { } } + /** + * Determines the {@link XsdSchema} for a given request, or null if none is found. + *

+ * Default implementation checks whether the request method is GET, whether the request uri ends with + * ".xsd", and if there is a XsdSchema with the same name as the filename in the request + * uri. + * + * @param request the HttpServletRequest + * @return a schema, or null + */ + protected XsdSchema getXsdSchema(HttpServletRequest request) { + if (HttpTransportConstants.METHOD_GET.equals(request.getMethod()) && + request.getRequestURI().endsWith(XSD_SUFFIX_NAME)) { + String fileName = WebUtils.extractFilenameFromUrlPath(request.getRequestURI()); + return (XsdSchema) xsdSchemas.get(fileName); + } + else { + return null; + } + } + private void initMessageReceiverHandlerAdapter() { try { try { @@ -293,6 +350,25 @@ public class MessageDispatcherServlet extends FrameworkServlet { } } + private void initXsdSchemaHandlerAdapter() { + try { + try { + xsdSchemaHandlerAdapter = (XsdSchemaHandlerAdapter) getWebApplicationContext() + .getBean(getXsdSchemaHandlerAdapterBeanName(), XsdSchemaHandlerAdapter.class); + + } + catch (NoSuchBeanDefinitionException ignored) { + xsdSchemaHandlerAdapter = new XsdSchemaHandlerAdapter(); + } + if (xsdSchemaHandlerAdapter instanceof InitializingBean) { + ((InitializingBean) xsdSchemaHandlerAdapter).afterPropertiesSet(); + } + } + catch (Exception ex) { + throw new BeanInitializationException("Could not initialize XsdSchemaHandlerAdapter", ex); + } + } + private void initMessageReceiver() { try { messageReceiver = (WebServiceMessageReceiver) getWebApplicationContext() @@ -323,4 +399,18 @@ public class MessageDispatcherServlet extends FrameworkServlet { } } } + + /** Find all {@link XsdSchema} in the ApplicationContext, incuding ancestor contexts. */ + private void initXsdSchemas() { + xsdSchemas = BeanFactoryUtils + .beansOfTypeIncludingAncestors(getWebApplicationContext(), XsdSchema.class, true, false); + if (logger.isDebugEnabled()) { + for (Iterator iterator = xsdSchemas.entrySet().iterator(); iterator.hasNext();) { + Map.Entry entry = (Map.Entry) iterator.next(); + String beanName = (String) entry.getKey(); + XsdSchema schema = (XsdSchema) entry.getValue(); + logger.debug("Published [" + schema + "] as " + beanName + XSD_SUFFIX_NAME); + } + } + } }