Skip to content

Commit 99bea96

Browse files
committed
Apply Nullability to remaining spring-integration-ws module packages
* Add `@NullMarked` to all the `ws` packages * Add `@Nullable` or `@SuppressWarnings("NullAway.Init")` whenever it is requested * Add defensive null checks for better safety (`DefaultSoapHeaderMapper`, `SimpleWebServiceOutboundGateway`) Signed-off-by: Jooyoung Pyoung <[email protected]>
1 parent 09840bb commit 99bea96

File tree

9 files changed

+63
-36
lines changed

9 files changed

+63
-36
lines changed

spring-integration-ws/src/main/java/org/springframework/integration/ws/AbstractWebServiceOutboundGateway.java

Lines changed: 19 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2024 the original author or authors.
2+
* Copyright 2002-2025 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -25,6 +25,8 @@
2525

2626
import javax.xml.transform.TransformerException;
2727

28+
import org.jspecify.annotations.Nullable;
29+
2830
import org.springframework.expression.Expression;
2931
import org.springframework.expression.spel.support.StandardEvaluationContext;
3032
import org.springframework.integration.expression.ExpressionEvalMap;
@@ -68,13 +70,14 @@ public abstract class AbstractWebServiceOutboundGateway extends AbstractReplyPro
6870

6971
private final String uri;
7072

71-
private final DestinationProvider destinationProvider;
73+
private final @Nullable DestinationProvider destinationProvider;
7274

7375
private final Map<String, Expression> uriVariableExpressions = new HashMap<>();
7476

77+
@SuppressWarnings("NullAway.Init")
7578
private StandardEvaluationContext evaluationContext;
7679

77-
private WebServiceMessageCallback requestCallback;
80+
private @Nullable WebServiceMessageCallback requestCallback;
7881

7982
private WebServiceTemplate webServiceTemplate;
8083

@@ -84,15 +87,17 @@ public abstract class AbstractWebServiceOutboundGateway extends AbstractReplyPro
8487

8588
private boolean webServiceTemplateExplicitlySet;
8689

87-
public AbstractWebServiceOutboundGateway(final String uri, WebServiceMessageFactory messageFactory) {
90+
@SuppressWarnings("NullAway")
91+
public AbstractWebServiceOutboundGateway(final String uri, @Nullable WebServiceMessageFactory messageFactory) {
8892
Assert.hasText(uri, "URI must not be empty");
8993
this.webServiceTemplate = new WebServiceTemplate(messageFactory);
9094
this.destinationProvider = null;
9195
this.uri = uri;
9296
}
9397

98+
@SuppressWarnings("NullAway")
9499
public AbstractWebServiceOutboundGateway(DestinationProvider destinationProvider,
95-
WebServiceMessageFactory messageFactory) {
100+
@Nullable WebServiceMessageFactory messageFactory) {
96101

97102
Assert.notNull(destinationProvider, "DestinationProvider must not be null");
98103
this.webServiceTemplate = new WebServiceTemplate(messageFactory);
@@ -165,7 +170,7 @@ public void setMessageFactory(WebServiceMessageFactory messageFactory) {
165170
this.webServiceTemplate.setMessageFactory(messageFactory);
166171
}
167172

168-
public void setRequestCallback(WebServiceMessageCallback requestCallback) {
173+
public void setRequestCallback(@Nullable WebServiceMessageCallback requestCallback) {
169174
this.requestCallback = requestCallback;
170175
}
171176

@@ -199,7 +204,7 @@ protected WebServiceTemplate getWebServiceTemplate() {
199204
}
200205

201206
@Override
202-
public final Object handleRequestMessage(Message<?> requestMessage) {
207+
public final @Nullable Object handleRequestMessage(Message<?> requestMessage) {
203208
URI uriWithVariables = prepareUri(requestMessage);
204209
if (uriWithVariables == null) {
205210
throw new MessageDeliveryException(requestMessage, "Failed to determine URI for " +
@@ -215,7 +220,7 @@ public final Object handleRequestMessage(Message<?> requestMessage) {
215220
return null;
216221
}
217222

218-
private URI prepareUri(Message<?> requestMessage) {
223+
private @Nullable URI prepareUri(Message<?> requestMessage) {
219224
if (this.destinationProvider != null) {
220225
return this.destinationProvider.getDestination();
221226
}
@@ -229,17 +234,17 @@ private URI prepareUri(Message<?> requestMessage) {
229234
return this.uriFactory.expand(this.uri, uriVariables);
230235
}
231236

232-
protected abstract Object doHandle(String theUri, Message<?> requestMessage,
233-
WebServiceMessageCallback reqCallback);
237+
protected abstract @Nullable Object doHandle(String theUri, Message<?> requestMessage,
238+
@Nullable WebServiceMessageCallback reqCallback);
234239

235240
protected abstract class RequestMessageCallback extends TransformerObjectSupport
236241
implements WebServiceMessageCallback {
237242

238-
private final WebServiceMessageCallback reqCallback;
243+
private final @Nullable WebServiceMessageCallback reqCallback;
239244

240245
private final Message<?> requestMessage;
241246

242-
public RequestMessageCallback(WebServiceMessageCallback requestCallback, Message<?> requestMessage) {
247+
public RequestMessageCallback(@Nullable WebServiceMessageCallback requestCallback, Message<?> requestMessage) {
243248
this.reqCallback = requestCallback;
244249
this.requestMessage = requestMessage;
245250
}
@@ -266,7 +271,7 @@ protected abstract class ResponseMessageExtractor extends TransformerObjectSuppo
266271
implements WebServiceMessageExtractor<Object> {
267272

268273
@Override
269-
public Object extractData(WebServiceMessage message)
274+
public @Nullable Object extractData(WebServiceMessage message)
270275
throws IOException, TransformerException {
271276

272277
Object resultObject = this.doExtractData(message);
@@ -284,7 +289,7 @@ public Object extractData(WebServiceMessage message)
284289
}
285290
}
286291

287-
public abstract Object doExtractData(WebServiceMessage message) throws IOException, TransformerException;
292+
public abstract @Nullable Object doExtractData(WebServiceMessage message) throws IOException, TransformerException;
288293

289294
}
290295

spring-integration-ws/src/main/java/org/springframework/integration/ws/DefaultSoapHeaderMapper.java

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2019 the original author or authors.
2+
* Copyright 2002-2025 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -53,6 +53,7 @@
5353
* @author Mauro Molinari
5454
* @author Artem Bilan
5555
* @author Gary Russell
56+
* @author Jooyoung Pyoung
5657
*
5758
* @since 2.0
5859
*/
@@ -126,6 +127,10 @@ else if (!StringUtils.hasText(target.getSoapAction())) {
126127
@Override
127128
protected void populateUserDefinedHeader(String headerName, Object headerValue, SoapMessage target) {
128129
SoapHeader soapHeader = target.getSoapHeader();
130+
if (soapHeader == null) {
131+
return;
132+
}
133+
129134
if (headerValue instanceof String) {
130135
QName qname = QNameUtils.parseQNameString(headerName);
131136
soapHeader.addAttribute(qname, (String) headerValue);

spring-integration-ws/src/main/java/org/springframework/integration/ws/MarshallingWebServiceInboundGateway.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2024 the original author or authors.
2+
* Copyright 2002-2025 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -35,8 +35,10 @@
3535
*/
3636
public class MarshallingWebServiceInboundGateway extends AbstractWebServiceInboundGateway {
3737

38+
@SuppressWarnings("NullAway.Init")
3839
private Marshaller marshaller;
3940

41+
@SuppressWarnings("NullAway.Init")
4042
private Unmarshaller unmarshaller;
4143

4244
/**

spring-integration-ws/src/main/java/org/springframework/integration/ws/MarshallingWebServiceOutboundGateway.java

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -46,11 +46,12 @@ public class MarshallingWebServiceOutboundGateway extends AbstractWebServiceOutb
4646

4747
@SuppressWarnings("this-escape")
4848
public MarshallingWebServiceOutboundGateway(DestinationProvider destinationProvider, Marshaller marshaller,
49-
Unmarshaller unmarshaller, WebServiceMessageFactory messageFactory) {
49+
@Nullable Unmarshaller unmarshaller, @Nullable WebServiceMessageFactory messageFactory) {
5050
super(destinationProvider, messageFactory);
5151
configureMarshallers(marshaller, unmarshaller);
5252
}
5353

54+
@SuppressWarnings("NullAway")
5455
public MarshallingWebServiceOutboundGateway(DestinationProvider destinationProvider, Marshaller marshaller,
5556
Unmarshaller unmarshaller) {
5657
this(destinationProvider, marshaller, unmarshaller, null);
@@ -61,17 +62,19 @@ public MarshallingWebServiceOutboundGateway(DestinationProvider destinationProvi
6162
this(destinationProvider, marshaller, null, messageFactory);
6263
}
6364

65+
@SuppressWarnings("NullAway")
6466
public MarshallingWebServiceOutboundGateway(DestinationProvider destinationProvider, Marshaller marshaller) {
6567
this(destinationProvider, marshaller, (WebServiceMessageFactory) null);
6668
}
6769

6870
@SuppressWarnings("this-escape")
69-
public MarshallingWebServiceOutboundGateway(String uri, Marshaller marshaller, Unmarshaller unmarshaller,
70-
WebServiceMessageFactory messageFactory) {
71+
public MarshallingWebServiceOutboundGateway(String uri, Marshaller marshaller, @Nullable Unmarshaller unmarshaller,
72+
@Nullable WebServiceMessageFactory messageFactory) {
7173
super(uri, messageFactory);
7274
configureMarshallers(marshaller, unmarshaller);
7375
}
7476

77+
@SuppressWarnings("NullAway")
7578
public MarshallingWebServiceOutboundGateway(String uri, Marshaller marshaller, Unmarshaller unmarshaller) {
7679
this(uri, marshaller, unmarshaller, null);
7780
}
@@ -81,6 +84,7 @@ public MarshallingWebServiceOutboundGateway(String uri, Marshaller marshaller,
8184
this(uri, marshaller, null, messageFactory);
8285
}
8386

87+
@SuppressWarnings("NullAway")
8488
public MarshallingWebServiceOutboundGateway(String uri, Marshaller marshaller) {
8589
this(uri, marshaller, (WebServiceMessageFactory) null);
8690
}
@@ -91,7 +95,7 @@ public MarshallingWebServiceOutboundGateway(String uri, Marshaller marshaller) {
9195
* @param webServiceTemplate the WebServiceTemplate
9296
* @since 5.0
9397
*/
94-
@SuppressWarnings("this-escape")
98+
@SuppressWarnings({"this-escape", "NullAway"})
9599
public MarshallingWebServiceOutboundGateway(String uri, WebServiceTemplate webServiceTemplate) {
96100
super(uri, null);
97101
doSetWebServiceTemplate(webServiceTemplate);
@@ -103,7 +107,7 @@ public MarshallingWebServiceOutboundGateway(String uri, WebServiceTemplate webSe
103107
* @param webServiceTemplate the WebServiceTemplate
104108
* @since 5.0
105109
*/
106-
@SuppressWarnings("this-escape")
110+
@SuppressWarnings({"this-escape", "NullAway"})
107111
public MarshallingWebServiceOutboundGateway(DestinationProvider destinationProvider,
108112
WebServiceTemplate webServiceTemplate) {
109113
super(destinationProvider, null);
@@ -140,15 +144,15 @@ public String getComponentType() {
140144
}
141145

142146
@Override
143-
protected Object doHandle(String uri, Message<?> requestMessage, WebServiceMessageCallback requestCallback) {
147+
protected @Nullable Object doHandle(String uri, Message<?> requestMessage, @Nullable WebServiceMessageCallback requestCallback) {
144148
return getWebServiceTemplate()
145149
.marshalSendAndReceive(uri, requestMessage.getPayload(),
146150
new PassThroughRequestMessageCallback(requestCallback, requestMessage));
147151
}
148152

149153
private final class PassThroughRequestMessageCallback extends RequestMessageCallback {
150154

151-
PassThroughRequestMessageCallback(WebServiceMessageCallback requestCallback, Message<?> requestMessage) {
155+
PassThroughRequestMessageCallback(@Nullable WebServiceMessageCallback requestCallback, Message<?> requestMessage) {
152156
super(requestCallback, requestMessage);
153157
}
154158

spring-integration-ws/src/main/java/org/springframework/integration/ws/SimpleWebServiceOutboundGateway.java

Lines changed: 17 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@
4949
* @author Oleg Zhurakousky
5050
* @author Artem Bilan
5151
* @author Gary Russell
52+
* @author Jooyoung Pyoung
5253
*/
5354
public class SimpleWebServiceOutboundGateway extends AbstractWebServiceOutboundGateway {
5455

@@ -68,7 +69,7 @@ public SimpleWebServiceOutboundGateway(DestinationProvider destinationProvider,
6869

6970
public SimpleWebServiceOutboundGateway(DestinationProvider destinationProvider,
7071
@Nullable SourceExtractor<?> sourceExtractor,
71-
WebServiceMessageFactory messageFactory) {
72+
@Nullable WebServiceMessageFactory messageFactory) {
7273

7374
super(destinationProvider, messageFactory);
7475
this.sourceExtractor = (sourceExtractor != null) ? sourceExtractor : new DefaultSourceExtractor();
@@ -83,7 +84,7 @@ public SimpleWebServiceOutboundGateway(String uri, SourceExtractor<?> sourceExtr
8384
}
8485

8586
public SimpleWebServiceOutboundGateway(String uri, @Nullable SourceExtractor<?> sourceExtractor,
86-
WebServiceMessageFactory messageFactory) {
87+
@Nullable WebServiceMessageFactory messageFactory) {
8788

8889
super(uri, messageFactory);
8990
this.sourceExtractor = (sourceExtractor != null) ? sourceExtractor : new DefaultSourceExtractor();
@@ -107,8 +108,8 @@ public String getComponentType() {
107108
}
108109

109110
@Override
110-
protected Object doHandle(String uri, final Message<?> requestMessage,
111-
final WebServiceMessageCallback requestCallback) {
111+
protected @Nullable Object doHandle(String uri, final Message<?> requestMessage,
112+
final @Nullable WebServiceMessageCallback requestCallback) {
112113

113114
Object requestPayload = requestMessage.getPayload();
114115
Result responseResultInstance = null;
@@ -126,21 +127,24 @@ else if (requestPayload instanceof Document) {
126127

127128
private final class SimpleRequestMessageCallback extends RequestMessageCallback {
128129

129-
SimpleRequestMessageCallback(WebServiceMessageCallback requestCallback, Message<?> requestMessage) {
130+
SimpleRequestMessageCallback(@Nullable WebServiceMessageCallback requestCallback, Message<?> requestMessage) {
130131
super(requestCallback, requestMessage);
131132
}
132133

133134
@Override
134135
public void doWithMessageInternal(WebServiceMessage message, Object payload)
135136
throws IOException, TransformerException {
136137
Source source = this.extractSource(payload);
138+
if (source == null) {
139+
source = new DOMSource();
140+
}
137141
transform(source, message.getPayloadResult());
138142
if (message instanceof MimeMessage && payload instanceof MimeMessage) {
139143
copyAttachments((MimeMessage) payload, (MimeMessage) message);
140144
}
141145
}
142146

143-
private Source extractSource(Object requestPayload) throws IOException, TransformerException {
147+
private @Nullable Source extractSource(Object requestPayload) throws IOException, TransformerException {
144148
Source source = null;
145149

146150
if (requestPayload instanceof Source) {
@@ -181,14 +185,14 @@ private void copyAttachments(MimeMessage source, MimeMessage target) {
181185

182186
private final class SimpleResponseMessageExtractor extends ResponseMessageExtractor {
183187

184-
private final Result result;
188+
private final @Nullable Result result;
185189

186-
SimpleResponseMessageExtractor(Result result) {
190+
SimpleResponseMessageExtractor(@Nullable Result result) {
187191
this.result = result;
188192
}
189193

190194
@Override
191-
public Object doExtractData(WebServiceMessage message) throws TransformerException {
195+
public @Nullable Object doExtractData(WebServiceMessage message) throws TransformerException {
192196
if (!SimpleWebServiceOutboundGateway.this.extractPayload) {
193197
return message;
194198
}
@@ -220,10 +224,13 @@ private static class DefaultSourceExtractor extends TransformerObjectSupport imp
220224
}
221225

222226
@Override
223-
public DOMSource extractData(Source source) throws TransformerException {
227+
public @Nullable DOMSource extractData(@Nullable Source source) throws TransformerException {
224228
if (source instanceof DOMSource) {
225229
return (DOMSource) source;
226230
}
231+
else if (source == null) {
232+
return new DOMSource();
233+
}
227234
DOMResult result = new DOMResult();
228235
this.transform(source, result);
229236
return new DOMSource(result.getNode());
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
/**
22
* Contains parser classes for the Web Services namespace support.
33
*/
4+
@org.jspecify.annotations.NullMarked
45
package org.springframework.integration.ws.config;

spring-integration-ws/src/main/java/org/springframework/integration/ws/dsl/BaseWsOutboundGatewaySpec.java

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -53,11 +53,13 @@ public abstract class BaseWsOutboundGatewaySpec<
5353

5454
private final Map<String, Expression> uriVariableExpressions = new HashMap<>();
5555

56-
protected @Nullable WebServiceTemplate template; // NOSONAR
56+
@SuppressWarnings("NullAway.Init")
57+
protected WebServiceTemplate template; // NOSONAR
5758

5859
protected @Nullable DestinationProvider destinationProvider; // NOSONAR
5960

60-
protected @Nullable String uri; // NOSONAR
61+
@SuppressWarnings("NullAway.Init")
62+
protected String uri; // NOSONAR
6163

6264
protected @Nullable WebServiceMessageFactory webServiceMessageFactory; // NOSONAR
6365

spring-integration-ws/src/main/java/org/springframework/integration/ws/dsl/MarshallingWsOutboundGatewaySpec.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ public static class MarshallingWsOutboundGatewayNoTemplateSpec
6666
extends BaseWsOutboundGatewaySpec<MarshallingWsOutboundGatewayNoTemplateSpec,
6767
MarshallingWebServiceOutboundGateway> {
6868

69-
protected Marshaller gatewayMarshaller = new Jaxb2Marshaller(); // NOSONAR
69+
protected Marshaller gatewayMarshaller = new Jaxb2Marshaller();
7070

7171
protected @Nullable Unmarshaller gatewayUnmarshaller; // NOSONAR
7272

spring-integration-ws/src/main/java/org/springframework/integration/ws/package-info.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,5 @@
22
* Provides several inbound and outbound Web Service components. Also contains
33
* support classes (e.g. Header Mapper)
44
*/
5+
@org.jspecify.annotations.NullMarked
56
package org.springframework.integration.ws;

0 commit comments

Comments
 (0)