diff --git a/spring-ws-core/src/main/java/org/springframework/ws/server/endpoint/mapping/AbstractEndpointMapping.java b/spring-ws-core/src/main/java/org/springframework/ws/server/endpoint/mapping/AbstractEndpointMapping.java index ab712d80..ff005c88 100644 --- a/spring-ws-core/src/main/java/org/springframework/ws/server/endpoint/mapping/AbstractEndpointMapping.java +++ b/spring-ws-core/src/main/java/org/springframework/ws/server/endpoint/mapping/AbstractEndpointMapping.java @@ -112,6 +112,26 @@ public abstract class AbstractEndpointMapping extends ApplicationObjectSupport i */ @Override public final EndpointInvocationChain getEndpoint(MessageContext messageContext) throws Exception { + Object endpoint = resoleEndpoint(messageContext); + if (endpoint == null) { + return null; + } + List interceptors = new ArrayList<>(); + if (this.interceptors != null) { + interceptors.addAll(Arrays.stream(this.interceptors) + .filter(interceptor -> shouldIntercept(interceptor, messageContext, endpoint)) + .toList()); + } + if (this.smartInterceptors != null) { + interceptors.addAll(Arrays.stream(this.smartInterceptors) + .filter(interceptor -> shouldIntercept(interceptor, messageContext, endpoint)) + .toList()); + } + return createEndpointInvocationChain(messageContext, endpoint, + interceptors.toArray(new EndpointInterceptor[0])); + } + + private Object resoleEndpoint(MessageContext messageContext) throws Exception { Object endpoint = getEndpointInternal(messageContext); if (endpoint == null) { endpoint = this.defaultEndpoint; @@ -125,22 +145,14 @@ public abstract class AbstractEndpointMapping extends ApplicationObjectSupport i return null; } } + return endpoint; + } - List interceptors = new ArrayList<>(); - if (this.interceptors != null) { - interceptors.addAll(Arrays.asList(this.interceptors)); + private boolean shouldIntercept(EndpointInterceptor interceptor, MessageContext messageContext, Object endpoint) { + if (interceptor instanceof SmartEndpointInterceptor smartEndpointInterceptor) { + return smartEndpointInterceptor.shouldIntercept(messageContext, endpoint); } - - if (this.smartInterceptors != null) { - for (SmartEndpointInterceptor smartInterceptor : this.smartInterceptors) { - if (smartInterceptor.shouldIntercept(messageContext, endpoint)) { - interceptors.add(smartInterceptor); - } - } - } - - return createEndpointInvocationChain(messageContext, endpoint, - interceptors.toArray(new EndpointInterceptor[0])); + return true; } /** diff --git a/spring-ws-core/src/test/java/org/springframework/ws/server/endpoint/mapping/EndpointMappingTest.java b/spring-ws-core/src/test/java/org/springframework/ws/server/endpoint/mapping/EndpointMappingTest.java index e92e1974..38cc1da7 100644 --- a/spring-ws-core/src/test/java/org/springframework/ws/server/endpoint/mapping/EndpointMappingTest.java +++ b/spring-ws-core/src/test/java/org/springframework/ws/server/endpoint/mapping/EndpointMappingTest.java @@ -25,10 +25,14 @@ import org.springframework.ws.context.DefaultMessageContext; import org.springframework.ws.context.MessageContext; import org.springframework.ws.server.EndpointInterceptor; import org.springframework.ws.server.EndpointInvocationChain; +import org.springframework.ws.server.SmartEndpointInterceptor; import org.springframework.ws.server.endpoint.interceptor.DelegatingSmartEndpointInterceptor; import org.springframework.ws.server.endpoint.interceptor.EndpointInterceptorAdapter; import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.BDDMockito.given; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; /** * Test case for {@link AbstractEndpointMapping}. @@ -124,6 +128,55 @@ public class EndpointMappingTest { assertThat(result.getInterceptors()[1]).isInstanceOf(MySmartEndpointInterceptor.class); } + @Test + void smartEndpointInterceptorAddedOnlyIfNecessary() throws Exception { + StaticApplicationContext applicationContext = new StaticApplicationContext(); + Object endpoint = new Object(); + SmartEndpointInterceptor firstInterceptor = mock(SmartEndpointInterceptor.class); + given(firstInterceptor.shouldIntercept(this.messageContext, endpoint)).willReturn(false); + applicationContext.registerBean("first", SmartEndpointInterceptor.class, () -> firstInterceptor); + SmartEndpointInterceptor secondInterceptor = mock(SmartEndpointInterceptor.class); + given(secondInterceptor.shouldIntercept(this.messageContext, endpoint)).willReturn(true); + applicationContext.registerBean("second", SmartEndpointInterceptor.class, () -> secondInterceptor); + + AbstractEndpointMapping mapping = new AbstractEndpointMapping() { + @Override + protected Object getEndpointInternal(MessageContext givenRequest) { + assertThat(givenRequest).isEqualTo(EndpointMappingTest.this.messageContext); + return endpoint; + } + }; + mapping.setApplicationContext(applicationContext); + EndpointInvocationChain result = mapping.getEndpoint(this.messageContext); + assertThat(result).isNotNull(); + assertThat(result.getInterceptors()).singleElement().isSameAs(secondInterceptor); + verify(firstInterceptor).shouldIntercept(this.messageContext, endpoint); + verify(secondInterceptor).shouldIntercept(this.messageContext, endpoint); + } + + @Test + void smartEndpointInterceptorSetAsInterceptorAreHandled() throws Exception { + Object endpoint = new Object(); + SmartEndpointInterceptor firstInterceptor = mock(SmartEndpointInterceptor.class); + given(firstInterceptor.shouldIntercept(this.messageContext, endpoint)).willReturn(false); + SmartEndpointInterceptor secondInterceptor = mock(SmartEndpointInterceptor.class); + given(secondInterceptor.shouldIntercept(this.messageContext, endpoint)).willReturn(true); + + AbstractEndpointMapping mapping = new AbstractEndpointMapping() { + @Override + protected Object getEndpointInternal(MessageContext givenRequest) { + assertThat(givenRequest).isEqualTo(EndpointMappingTest.this.messageContext); + return endpoint; + } + }; + mapping.setInterceptors(new EndpointInterceptor[] { firstInterceptor, secondInterceptor }); + EndpointInvocationChain result = mapping.getEndpoint(this.messageContext); + assertThat(result).isNotNull(); + assertThat(result.getInterceptors()).singleElement().isSameAs(secondInterceptor); + verify(firstInterceptor).shouldIntercept(this.messageContext, endpoint); + verify(secondInterceptor).shouldIntercept(this.messageContext, endpoint); + } + @Test public void endpointBeanName() throws Exception {