Skip to content

Commit daccb0d

Browse files
committed
Allow SmartEndpointInterceptor to be added as regular interceptor
Previously, only SmartEndpointInterceptor instances declared as bean were considered by AbstractEndpointMapping. Given that it extends from EndpointInterceptor, this meant that adding them using the regular setEndpointInterceptor mean they were not considered as such, that is added irrespective of their `shouldIntercept` contract. This commit considers both list as holding SmartEndpointInterceptor instances. As a result, these can now be added using regular hook points, such as WsConfigurer. Closes gh-1130
1 parent 50ca51e commit daccb0d

File tree

2 files changed

+79
-14
lines changed

2 files changed

+79
-14
lines changed

spring-ws-core/src/main/java/org/springframework/ws/server/endpoint/mapping/AbstractEndpointMapping.java

Lines changed: 26 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,26 @@ protected void initInterceptors() {
112112
*/
113113
@Override
114114
public final EndpointInvocationChain getEndpoint(MessageContext messageContext) throws Exception {
115+
Object endpoint = resoleEndpoint(messageContext);
116+
if (endpoint == null) {
117+
return null;
118+
}
119+
List<EndpointInterceptor> interceptors = new ArrayList<>();
120+
if (this.interceptors != null) {
121+
interceptors.addAll(Arrays.stream(this.interceptors)
122+
.filter(interceptor -> shouldIntercept(interceptor, messageContext, endpoint))
123+
.toList());
124+
}
125+
if (this.smartInterceptors != null) {
126+
interceptors.addAll(Arrays.stream(this.smartInterceptors)
127+
.filter(interceptor -> shouldIntercept(interceptor, messageContext, endpoint))
128+
.toList());
129+
}
130+
return createEndpointInvocationChain(messageContext, endpoint,
131+
interceptors.toArray(new EndpointInterceptor[0]));
132+
}
133+
134+
private Object resoleEndpoint(MessageContext messageContext) throws Exception {
115135
Object endpoint = getEndpointInternal(messageContext);
116136
if (endpoint == null) {
117137
endpoint = this.defaultEndpoint;
@@ -125,22 +145,14 @@ public final EndpointInvocationChain getEndpoint(MessageContext messageContext)
125145
return null;
126146
}
127147
}
148+
return endpoint;
149+
}
128150

129-
List<EndpointInterceptor> interceptors = new ArrayList<>();
130-
if (this.interceptors != null) {
131-
interceptors.addAll(Arrays.asList(this.interceptors));
151+
private boolean shouldIntercept(EndpointInterceptor interceptor, MessageContext messageContext, Object endpoint) {
152+
if (interceptor instanceof SmartEndpointInterceptor smartEndpointInterceptor) {
153+
return smartEndpointInterceptor.shouldIntercept(messageContext, endpoint);
132154
}
133-
134-
if (this.smartInterceptors != null) {
135-
for (SmartEndpointInterceptor smartInterceptor : this.smartInterceptors) {
136-
if (smartInterceptor.shouldIntercept(messageContext, endpoint)) {
137-
interceptors.add(smartInterceptor);
138-
}
139-
}
140-
}
141-
142-
return createEndpointInvocationChain(messageContext, endpoint,
143-
interceptors.toArray(new EndpointInterceptor[0]));
155+
return true;
144156
}
145157

146158
/**

spring-ws-core/src/test/java/org/springframework/ws/server/endpoint/mapping/EndpointMappingTest.java

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,10 +25,14 @@
2525
import org.springframework.ws.context.MessageContext;
2626
import org.springframework.ws.server.EndpointInterceptor;
2727
import org.springframework.ws.server.EndpointInvocationChain;
28+
import org.springframework.ws.server.SmartEndpointInterceptor;
2829
import org.springframework.ws.server.endpoint.interceptor.DelegatingSmartEndpointInterceptor;
2930
import org.springframework.ws.server.endpoint.interceptor.EndpointInterceptorAdapter;
3031

3132
import static org.assertj.core.api.Assertions.assertThat;
33+
import static org.mockito.BDDMockito.given;
34+
import static org.mockito.Mockito.mock;
35+
import static org.mockito.Mockito.verify;
3236

3337
/**
3438
* Test case for {@link AbstractEndpointMapping}.
@@ -124,6 +128,55 @@ protected Object getEndpointInternal(MessageContext givenRequest) {
124128
assertThat(result.getInterceptors()[1]).isInstanceOf(MySmartEndpointInterceptor.class);
125129
}
126130

131+
@Test
132+
void smartEndpointInterceptorAddedOnlyIfNecessary() throws Exception {
133+
StaticApplicationContext applicationContext = new StaticApplicationContext();
134+
Object endpoint = new Object();
135+
SmartEndpointInterceptor firstInterceptor = mock(SmartEndpointInterceptor.class);
136+
given(firstInterceptor.shouldIntercept(this.messageContext, endpoint)).willReturn(false);
137+
applicationContext.registerBean("first", SmartEndpointInterceptor.class, () -> firstInterceptor);
138+
SmartEndpointInterceptor secondInterceptor = mock(SmartEndpointInterceptor.class);
139+
given(secondInterceptor.shouldIntercept(this.messageContext, endpoint)).willReturn(true);
140+
applicationContext.registerBean("second", SmartEndpointInterceptor.class, () -> secondInterceptor);
141+
142+
AbstractEndpointMapping mapping = new AbstractEndpointMapping() {
143+
@Override
144+
protected Object getEndpointInternal(MessageContext givenRequest) {
145+
assertThat(givenRequest).isEqualTo(EndpointMappingTest.this.messageContext);
146+
return endpoint;
147+
}
148+
};
149+
mapping.setApplicationContext(applicationContext);
150+
EndpointInvocationChain result = mapping.getEndpoint(this.messageContext);
151+
assertThat(result).isNotNull();
152+
assertThat(result.getInterceptors()).singleElement().isSameAs(secondInterceptor);
153+
verify(firstInterceptor).shouldIntercept(this.messageContext, endpoint);
154+
verify(secondInterceptor).shouldIntercept(this.messageContext, endpoint);
155+
}
156+
157+
@Test
158+
void smartEndpointInterceptorSetAsInterceptorAreHandled() throws Exception {
159+
Object endpoint = new Object();
160+
SmartEndpointInterceptor firstInterceptor = mock(SmartEndpointInterceptor.class);
161+
given(firstInterceptor.shouldIntercept(this.messageContext, endpoint)).willReturn(false);
162+
SmartEndpointInterceptor secondInterceptor = mock(SmartEndpointInterceptor.class);
163+
given(secondInterceptor.shouldIntercept(this.messageContext, endpoint)).willReturn(true);
164+
165+
AbstractEndpointMapping mapping = new AbstractEndpointMapping() {
166+
@Override
167+
protected Object getEndpointInternal(MessageContext givenRequest) {
168+
assertThat(givenRequest).isEqualTo(EndpointMappingTest.this.messageContext);
169+
return endpoint;
170+
}
171+
};
172+
mapping.setInterceptors(new EndpointInterceptor[] { firstInterceptor, secondInterceptor });
173+
EndpointInvocationChain result = mapping.getEndpoint(this.messageContext);
174+
assertThat(result).isNotNull();
175+
assertThat(result.getInterceptors()).singleElement().isSameAs(secondInterceptor);
176+
verify(firstInterceptor).shouldIntercept(this.messageContext, endpoint);
177+
verify(secondInterceptor).shouldIntercept(this.messageContext, endpoint);
178+
}
179+
127180
@Test
128181
public void endpointBeanName() throws Exception {
129182

0 commit comments

Comments
 (0)