From 9f9e06d0d2fe9daa5e4b18cef0e0fb29b5842983 Mon Sep 17 00:00:00 2001 From: Arjen Poutsma Date: Thu, 6 Oct 2011 11:07:23 +0000 Subject: [PATCH] SWS-713 - Order of interceptor calls is dependent on the way the interceptors are included --- .../InterceptorsBeanDefinitionParser.java | 114 +++++++++--------- .../DelegatingSmartEndpointInterceptor.java | 4 +- .../InterceptorsBeanDefinitionParserTest.java | 28 +++-- .../ws/config/MyInterceptor.java | 51 ++++++++ ...erceptorsBeanDefinitionParserOrderTest.xml | 34 ++++++ 5 files changed, 161 insertions(+), 70 deletions(-) create mode 100644 core/src/test/java/org/springframework/ws/config/MyInterceptor.java create mode 100644 core/src/test/resources/org/springframework/ws/config/interceptorsBeanDefinitionParserOrderTest.xml diff --git a/core/src/main/java/org/springframework/ws/config/InterceptorsBeanDefinitionParser.java b/core/src/main/java/org/springframework/ws/config/InterceptorsBeanDefinitionParser.java index 08dca70e..a8f52e4d 100644 --- a/core/src/main/java/org/springframework/ws/config/InterceptorsBeanDefinitionParser.java +++ b/core/src/main/java/org/springframework/ws/config/InterceptorsBeanDefinitionParser.java @@ -74,73 +74,71 @@ class InterceptorsBeanDefinitionParser implements BeanDefinitionParser { } else if ("payloadRoot".equals(childElement.getLocalName())) { - // bean elements - List beanElements = DomUtils.getChildElementsByTagName(childElement, "bean"); - for (Element beanElement : beanElements) { - RootBeanDefinition smartInterceptorDef = - createSmartInterceptorDefinition(PayloadRootSmartSoapEndpointInterceptor.class, childElement, - parserContext); - BeanDefinitionHolder interceptorDef = createInterceptorDefinition(parserContext, beanElement); + List payloadRootChildren = DomUtils.getChildElements(childElement); + for (Element payloadRootChild : payloadRootChildren) { + if ("bean".equals(payloadRootChild.getLocalName())) { + RootBeanDefinition smartInterceptorDef = + createSmartInterceptorDefinition(PayloadRootSmartSoapEndpointInterceptor.class, + childElement, parserContext); + BeanDefinitionHolder interceptorDef = + createInterceptorDefinition(parserContext, payloadRootChild); - String namespaceUri = childElement.getAttribute("namespaceUri"); - String localPart = childElement.getAttribute("localPart"); + String namespaceUri = childElement.getAttribute("namespaceUri"); + String localPart = childElement.getAttribute("localPart"); - smartInterceptorDef.getConstructorArgumentValues().addIndexedArgumentValue(0, interceptorDef); - smartInterceptorDef.getConstructorArgumentValues().addIndexedArgumentValue(1, namespaceUri); - smartInterceptorDef.getConstructorArgumentValues().addIndexedArgumentValue(2, localPart); + smartInterceptorDef.getConstructorArgumentValues().addIndexedArgumentValue(0, interceptorDef); + smartInterceptorDef.getConstructorArgumentValues().addIndexedArgumentValue(1, namespaceUri); + smartInterceptorDef.getConstructorArgumentValues().addIndexedArgumentValue(2, localPart); - registerSmartInterceptor(parserContext, smartInterceptorDef); - } + registerSmartInterceptor(parserContext, smartInterceptorDef); + } + else if ("ref".equals(payloadRootChild.getLocalName())) { + RootBeanDefinition smartInterceptorDef = + createSmartInterceptorDefinition(PayloadRootSmartSoapEndpointInterceptor.class, + childElement, parserContext); + BeanReference interceptorRef = createInterceptorReference(parserContext, payloadRootChild); - // ref elements - List refElements = DomUtils.getChildElementsByTagName(childElement, "ref"); - for (Element refElement : refElements) { - RootBeanDefinition smartInterceptorDef = - createSmartInterceptorDefinition(PayloadRootSmartSoapEndpointInterceptor.class, childElement, - parserContext); - BeanReference interceptorRef = createInterceptorReference(parserContext, refElement); + String namespaceUri = childElement.getAttribute("namespaceUri"); + String localPart = childElement.getAttribute("localPart"); - String namespaceUri = childElement.getAttribute("namespaceUri"); - String localPart = childElement.getAttribute("localPart"); + smartInterceptorDef.getConstructorArgumentValues().addIndexedArgumentValue(0, interceptorRef); + smartInterceptorDef.getConstructorArgumentValues().addIndexedArgumentValue(1, namespaceUri); + smartInterceptorDef.getConstructorArgumentValues().addIndexedArgumentValue(2, localPart); - smartInterceptorDef.getConstructorArgumentValues().addIndexedArgumentValue(0, interceptorRef); - smartInterceptorDef.getConstructorArgumentValues().addIndexedArgumentValue(1, namespaceUri); - smartInterceptorDef.getConstructorArgumentValues().addIndexedArgumentValue(2, localPart); - - registerSmartInterceptor(parserContext, smartInterceptorDef); + registerSmartInterceptor(parserContext, smartInterceptorDef); + } } } else if ("soapAction".equals(childElement.getLocalName())) { - // bean elements - List beanElements = DomUtils.getChildElementsByTagName(childElement, "bean"); - for (Element beanElement : beanElements) { - RootBeanDefinition smartInterceptorDef = - createSmartInterceptorDefinition(SoapActionSmartEndpointInterceptor.class, childElement, - parserContext); - BeanDefinitionHolder interceptorDef = createInterceptorDefinition(parserContext, beanElement); + List soapActionChildren = DomUtils.getChildElements(childElement); + for (Element soapActionChild : soapActionChildren) { + if ("bean".equals(soapActionChild.getLocalName())) { + RootBeanDefinition smartInterceptorDef = + createSmartInterceptorDefinition(SoapActionSmartEndpointInterceptor.class, childElement, + parserContext); + BeanDefinitionHolder interceptorDef = + createInterceptorDefinition(parserContext, soapActionChild); - String soapAction = childElement.getAttribute("value"); + String soapAction = childElement.getAttribute("value"); - smartInterceptorDef.getConstructorArgumentValues().addIndexedArgumentValue(0, interceptorDef); - smartInterceptorDef.getConstructorArgumentValues().addIndexedArgumentValue(1, soapAction); + smartInterceptorDef.getConstructorArgumentValues().addIndexedArgumentValue(0, interceptorDef); + smartInterceptorDef.getConstructorArgumentValues().addIndexedArgumentValue(1, soapAction); - registerSmartInterceptor(parserContext, smartInterceptorDef); - } + registerSmartInterceptor(parserContext, smartInterceptorDef); + } + else if ("ref".equals(soapActionChild.getLocalName())) { + RootBeanDefinition smartInterceptorDef = + createSmartInterceptorDefinition(SoapActionSmartEndpointInterceptor.class, childElement, + parserContext); + BeanReference interceptorRef = createInterceptorReference(parserContext, soapActionChild); - // ref elements - List refElements = DomUtils.getChildElementsByTagName(childElement, "ref"); - for (Element refElement : refElements) { - RootBeanDefinition smartInterceptorDef = - createSmartInterceptorDefinition(SoapActionSmartEndpointInterceptor.class, childElement, - parserContext); - BeanReference interceptorRef = createInterceptorReference(parserContext, refElement); + String soapAction = childElement.getAttribute("value"); - String soapAction = childElement.getAttribute("value"); + smartInterceptorDef.getConstructorArgumentValues().addIndexedArgumentValue(0, interceptorRef); + smartInterceptorDef.getConstructorArgumentValues().addIndexedArgumentValue(1, soapAction); - smartInterceptorDef.getConstructorArgumentValues().addIndexedArgumentValue(0, interceptorRef); - smartInterceptorDef.getConstructorArgumentValues().addIndexedArgumentValue(1, soapAction); - - registerSmartInterceptor(parserContext, smartInterceptorDef); + registerSmartInterceptor(parserContext, smartInterceptorDef); + } } } } @@ -150,17 +148,13 @@ class InterceptorsBeanDefinitionParser implements BeanDefinitionParser { } private void registerSmartInterceptor(ParserContext parserContext, RootBeanDefinition smartInterceptorDef) { - String mappedInterceptorName = - parserContext.getReaderContext().registerWithGeneratedName(smartInterceptorDef); - parserContext - .registerComponent(new BeanComponentDefinition(smartInterceptorDef, mappedInterceptorName)); + String mappedInterceptorName = parserContext.getReaderContext().registerWithGeneratedName(smartInterceptorDef); + parserContext.registerComponent(new BeanComponentDefinition(smartInterceptorDef, mappedInterceptorName)); } private BeanDefinitionHolder createInterceptorDefinition(ParserContext parserContext, Element element) { - BeanDefinitionHolder interceptorDef = - parserContext.getDelegate().parseBeanDefinitionElement(element); - interceptorDef = - parserContext.getDelegate().decorateBeanDefinitionIfRequired(element, interceptorDef); + BeanDefinitionHolder interceptorDef = parserContext.getDelegate().parseBeanDefinitionElement(element); + interceptorDef = parserContext.getDelegate().decorateBeanDefinitionIfRequired(element, interceptorDef); return interceptorDef; } diff --git a/core/src/main/java/org/springframework/ws/server/endpoint/interceptor/DelegatingSmartEndpointInterceptor.java b/core/src/main/java/org/springframework/ws/server/endpoint/interceptor/DelegatingSmartEndpointInterceptor.java index 53e3244d..d0d4848b 100644 --- a/core/src/main/java/org/springframework/ws/server/endpoint/interceptor/DelegatingSmartEndpointInterceptor.java +++ b/core/src/main/java/org/springframework/ws/server/endpoint/interceptor/DelegatingSmartEndpointInterceptor.java @@ -45,9 +45,9 @@ public class DelegatingSmartEndpointInterceptor implements SmartEndpointIntercep /** * Returns the delegate. - * @return + * @return the delegate */ - protected EndpointInterceptor getDelegate() { + public EndpointInterceptor getDelegate() { return delegate; } diff --git a/core/src/test/java/org/springframework/ws/config/InterceptorsBeanDefinitionParserTest.java b/core/src/test/java/org/springframework/ws/config/InterceptorsBeanDefinitionParserTest.java index e2a69118..1d81896f 100644 --- a/core/src/test/java/org/springframework/ws/config/InterceptorsBeanDefinitionParserTest.java +++ b/core/src/test/java/org/springframework/ws/config/InterceptorsBeanDefinitionParserTest.java @@ -16,6 +16,8 @@ package org.springframework.ws.config; +import java.util.ArrayList; +import java.util.List; import java.util.Map; import org.springframework.context.ApplicationContext; @@ -24,22 +26,16 @@ import org.springframework.ws.server.endpoint.interceptor.DelegatingSmartEndpoin import org.springframework.ws.soap.server.endpoint.interceptor.PayloadRootSmartSoapEndpointInterceptor; import org.springframework.ws.soap.server.endpoint.interceptor.SoapActionSmartEndpointInterceptor; -import org.junit.Before; import org.junit.Test; import static org.junit.Assert.assertEquals; public class InterceptorsBeanDefinitionParserTest { - private ApplicationContext applicationContext; - - @Before - public void setUp() throws Exception { - applicationContext = new ClassPathXmlApplicationContext("interceptorsBeanDefinitionParserTest.xml", getClass()); - } - @Test public void namespace() throws Exception { + ApplicationContext applicationContext = + new ClassPathXmlApplicationContext("interceptorsBeanDefinitionParserTest.xml", getClass()); Map result = applicationContext.getBeansOfType(DelegatingSmartEndpointInterceptor.class); assertEquals("no smart interceptors found", 8, result.size()); @@ -50,4 +46,20 @@ public class InterceptorsBeanDefinitionParserTest { assertEquals("no interceptors found", 3, result.size()); } + @Test + public void ordering() throws Exception { + ApplicationContext applicationContext = + new ClassPathXmlApplicationContext("interceptorsBeanDefinitionParserOrderTest.xml", getClass()); + + List interceptors = new ArrayList( + applicationContext.getBeansOfType(DelegatingSmartEndpointInterceptor.class).values()); + assertEquals("not enough smart interceptors found", 6, interceptors.size()); + + for (int i = 0; i < interceptors.size(); i++) { + DelegatingSmartEndpointInterceptor delegatingInterceptor = interceptors.get(i); + MyInterceptor interceptor = (MyInterceptor) delegatingInterceptor.getDelegate(); + assertEquals("Invalid ordering found for [" + delegatingInterceptor + "]", i, interceptor.getOrder()); + } + } + } diff --git a/core/src/test/java/org/springframework/ws/config/MyInterceptor.java b/core/src/test/java/org/springframework/ws/config/MyInterceptor.java new file mode 100644 index 00000000..22b83cc2 --- /dev/null +++ b/core/src/test/java/org/springframework/ws/config/MyInterceptor.java @@ -0,0 +1,51 @@ +/* + * Copyright 2005-2011 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.ws.config; + +import org.springframework.ws.context.MessageContext; +import org.springframework.ws.server.EndpointInterceptor; + +/** + * @author Arjen Poutsma + */ +public class MyInterceptor implements EndpointInterceptor { + + private int order; + + public int getOrder() { + return order; + } + + public void setOrder(int order) { + this.order = order; + } + + public boolean handleRequest(MessageContext messageContext, Object endpoint) throws Exception { + return true; + } + + public boolean handleResponse(MessageContext messageContext, Object endpoint) throws Exception { + return true; + } + + public boolean handleFault(MessageContext messageContext, Object endpoint) throws Exception { + return true; + } + + public void afterCompletion(MessageContext messageContext, Object endpoint, Exception ex) { + } +} diff --git a/core/src/test/resources/org/springframework/ws/config/interceptorsBeanDefinitionParserOrderTest.xml b/core/src/test/resources/org/springframework/ws/config/interceptorsBeanDefinitionParserOrderTest.xml new file mode 100644 index 00000000..1ba65c42 --- /dev/null +++ b/core/src/test/resources/org/springframework/ws/config/interceptorsBeanDefinitionParserOrderTest.xml @@ -0,0 +1,34 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +