Skip to content

Commit 336b366

Browse files
authored
GH-10083: Implement Nullability in XML module
Related to: #10083 * Add `@org.jspecify.annotations.NullMarked` to all the packages in the XML module * Apply JSpecify null safety annotation improvements Signed-off-by: Eddie Cho <[email protected]>
1 parent e21d843 commit 336b366

21 files changed

+65
-37
lines changed
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 XML namespace support.
33
*/
4+
@org.jspecify.annotations.NullMarked
45
package org.springframework.integration.xml.config;
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
/**
22
* Root package of the XML Module.
33
*/
4+
@org.jspecify.annotations.NullMarked
45
package org.springframework.integration.xml;

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,5 @@
33
* will return {@link javax.xml.transform.Result}, possibly taking into account
44
* payload instance.
55
*/
6+
@org.jspecify.annotations.NullMarked
67
package org.springframework.integration.xml.result;

spring-integration-xml/src/main/java/org/springframework/integration/xml/router/XPathRouter.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
import java.util.List;
2222
import java.util.Map;
2323

24+
import org.jspecify.annotations.Nullable;
2425
import org.w3c.dom.DOMException;
2526
import org.w3c.dom.Node;
2627

@@ -128,7 +129,7 @@ private static class TextContentNodeMapper implements NodeMapper<Object> {
128129
}
129130

130131
@Override
131-
public Object mapNode(Node node, int nodeNum) throws DOMException {
132+
public @Nullable Object mapNode(Node node, int nodeNum) throws DOMException {
132133
return node.getTextContent();
133134
}
134135

spring-integration-xml/src/main/java/org/springframework/integration/xml/selector/XmlValidatingMessageSelector.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
import java.io.UncheckedIOException;
2121
import java.util.Arrays;
2222

23+
import org.jspecify.annotations.Nullable;
2324
import org.xml.sax.SAXParseException;
2425

2526
import org.springframework.core.io.Resource;
@@ -83,7 +84,7 @@ public String getUrl() {
8384
* @param schemaType The schema type.
8485
* @throws IOException if the XmlValidatorFactory fails to create a validator
8586
*/
86-
public XmlValidatingMessageSelector(Resource schema, SchemaType schemaType) throws IOException {
87+
public XmlValidatingMessageSelector(Resource schema, @Nullable SchemaType schemaType) throws IOException {
8788
this(XmlValidatorFactory.createValidator(schema,
8889
schemaType == null
8990
? SchemaType.XML_SCHEMA.getUrl()
@@ -95,7 +96,7 @@ public XmlValidatingMessageSelector(XmlValidator xmlValidator) {
9596
this.xmlValidator = xmlValidator;
9697
}
9798

98-
public XmlValidatingMessageSelector(Resource schema, String schemaType) throws IOException {
99+
public XmlValidatingMessageSelector(Resource schema, @Nullable String schemaType) throws IOException {
99100
this(schema,
100101
StringUtils.hasText(schemaType)
101102
? SchemaType.valueOf(schemaType.toUpperCase().replaceFirst("-", "_"))

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,5 @@
22
* Provides XML-centric {@link org.springframework.integration.core.MessageSelector}
33
* implementations.
44
*/
5+
@org.jspecify.annotations.NullMarked
56
package org.springframework.integration.xml.selector;

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,5 @@
22
* Provides various {@link org.springframework.integration.xml.source.SourceFactory}
33
* implementations.
44
*/
5+
@org.jspecify.annotations.NullMarked
56
package org.springframework.integration.xml.source;

spring-integration-xml/src/main/java/org/springframework/integration/xml/splitter/XPathMessageSplitter.java

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@
3838
import javax.xml.xpath.XPathExpressionException;
3939
import javax.xml.xpath.XPathFactory;
4040

41+
import org.jspecify.annotations.Nullable;
4142
import org.w3c.dom.Document;
4243
import org.w3c.dom.Node;
4344
import org.w3c.dom.NodeList;
@@ -82,15 +83,15 @@ public class XPathMessageSplitter extends AbstractMessageSplitter {
8283

8384
private final XPathExpression xpathExpression;
8485

85-
private javax.xml.xpath.XPathExpression jaxpExpression;
86+
private javax.xml.xpath.@Nullable XPathExpression jaxpExpression;
8687

8788
private boolean createDocuments;
8889

8990
private DocumentBuilderFactory documentBuilderFactory;
9091

9192
private XmlPayloadConverter xmlPayloadConverter = new DefaultXmlPayloadConverter();
9293

93-
private Properties outputProperties;
94+
private @Nullable Properties outputProperties;
9495

9596
private boolean returnIterator = true;
9697

@@ -292,7 +293,7 @@ private Object splitDocument(Document document) throws ParserConfigurationExcept
292293
}
293294

294295
private Object splitNode(Node node) throws ParserConfigurationException {
295-
if (this.returnIterator) {
296+
if (this.returnIterator && this.jaxpExpression != null) {
296297
try {
297298
NodeList nodeList = (NodeList) this.jaxpExpression.evaluate(node, XPathConstants.NODESET);
298299
return new NodeListIterator(nodeList);
@@ -338,7 +339,7 @@ private DocumentBuilder getNewDocumentBuilder() throws ParserConfigurationExcept
338339

339340
private final class NodeListIterator implements Iterator<Node> {
340341

341-
private final DocumentBuilder documentBuilder;
342+
private final @Nullable DocumentBuilder documentBuilder;
342343

343344
private final NodeList nodeList;
344345

@@ -360,7 +361,7 @@ public boolean hasNext() {
360361
}
361362

362363
@Override
363-
public Node next() {
364+
public @Nullable Node next() {
364365
if (!hasNext()) {
365366
return null;
366367
}

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,5 @@
22
* Provides implementations of
33
* {@link org.springframework.integration.splitter.AbstractMessageSplitter}.
44
*/
5+
@org.jspecify.annotations.NullMarked
56
package org.springframework.integration.xml.splitter;

spring-integration-xml/src/main/java/org/springframework/integration/xml/transformer/AbstractXmlTransformer.java

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@
1616

1717
package org.springframework.integration.xml.transformer;
1818

19+
import org.jspecify.annotations.Nullable;
20+
1921
import org.springframework.beans.factory.BeanFactory;
2022
import org.springframework.integration.transformer.AbstractTransformer;
2123
import org.springframework.integration.xml.result.DomResultFactory;
@@ -39,9 +41,9 @@ public abstract class AbstractXmlTransformer extends AbstractTransformer {
3941

4042
public static final String STRING_RESULT = "StringResult";
4143

42-
private volatile String resultType;
44+
private volatile @Nullable String resultType;
4345

44-
private volatile String resultFactoryName;
46+
private volatile @Nullable String resultFactoryName;
4547

4648
private volatile ResultFactory resultFactory = new DomResultFactory();
4749

@@ -58,11 +60,11 @@ public void setResultFactory(ResultFactory resultFactory) {
5860
this.resultFactory = resultFactory;
5961
}
6062

61-
public String getResultType() {
63+
public @Nullable String getResultType() {
6264
return this.resultType;
6365
}
6466

65-
public String getResultFactoryName() {
67+
public @Nullable String getResultFactoryName() {
6668
return this.resultFactoryName;
6769
}
6870

@@ -85,7 +87,7 @@ protected void onInit() {
8587
* a bean definition for a {@link ResultFactory} based on either the
8688
* 'result-factory' or 'result-type' attributes.
8789
*/
88-
private ResultFactory configureResultFactory(String resultType, String resultFactoryName, BeanFactory beanFactory) {
90+
private @Nullable ResultFactory configureResultFactory(@Nullable String resultType, @Nullable String resultFactoryName, BeanFactory beanFactory) {
8991
boolean bothHaveText = StringUtils.hasText(resultFactoryName) && StringUtils.hasText(resultType);
9092
ResultFactory configuredResultFactory = null;
9193
Assert.state(!bothHaveText, "Only one of 'result-factory' or 'result-type' should be specified.");

spring-integration-xml/src/main/java/org/springframework/integration/xml/transformer/MarshallingTransformer.java

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@
2020

2121
import javax.xml.transform.Result;
2222

23+
import org.jspecify.annotations.Nullable;
24+
2325
import org.springframework.messaging.Message;
2426
import org.springframework.messaging.MessagingException;
2527
import org.springframework.oxm.Marshaller;
@@ -39,11 +41,11 @@ public class MarshallingTransformer extends AbstractXmlTransformer {
3941

4042
private final Marshaller marshaller;
4143

42-
private final ResultTransformer resultTransformer;
44+
private final @Nullable ResultTransformer resultTransformer;
4345

4446
private volatile boolean extractPayload = true;
4547

46-
public MarshallingTransformer(Marshaller marshaller, ResultTransformer resultTransformer) {
48+
public MarshallingTransformer(Marshaller marshaller, @Nullable ResultTransformer resultTransformer) {
4749
Assert.notNull(marshaller, "a marshaller is required");
4850
this.marshaller = marshaller;
4951
this.resultTransformer = resultTransformer;

spring-integration-xml/src/main/java/org/springframework/integration/xml/transformer/ResultToStringTransformer.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@
2828
import javax.xml.transform.dom.DOMResult;
2929
import javax.xml.transform.dom.DOMSource;
3030

31+
import org.jspecify.annotations.Nullable;
32+
3133
import org.springframework.messaging.MessagingException;
3234
import org.springframework.util.Assert;
3335
import org.springframework.xml.transform.StringResult;
@@ -48,7 +50,7 @@ public class ResultToStringTransformer implements ResultTransformer {
4850

4951
private final TransformerFactory transformerFactory;
5052

51-
private Properties outputProperties;
53+
private @Nullable Properties outputProperties;
5254

5355
public ResultToStringTransformer() {
5456
this.transformerFactory = TransformerFactoryUtils.newInstance();

spring-integration-xml/src/main/java/org/springframework/integration/xml/transformer/UnmarshallingTransformer.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
import javax.xml.transform.dom.DOMSource;
2828
import javax.xml.transform.stream.StreamSource;
2929

30+
import org.jspecify.annotations.Nullable;
3031
import org.w3c.dom.Document;
3132

3233
import org.springframework.integration.transformer.AbstractPayloadTransformer;
@@ -68,7 +69,7 @@ public class UnmarshallingTransformer extends AbstractPayloadTransformer<Object,
6869

6970
private boolean alwaysUseSourceFactory = false;
7071

71-
private MimeMessageUnmarshallerHelper mimeMessageUnmarshallerHelper;
72+
private @Nullable MimeMessageUnmarshallerHelper mimeMessageUnmarshallerHelper;
7273

7374
public UnmarshallingTransformer(Unmarshaller unmarshaller) {
7475
this.unmarshaller = unmarshaller;
@@ -162,7 +163,7 @@ private static class MimeMessageUnmarshallerHelper {
162163
this.delegate = unmarshaller;
163164
}
164165

165-
Object maybeUnmarshalMimeMessage(Object payload) throws IOException {
166+
@Nullable Object maybeUnmarshalMimeMessage(Object payload) throws IOException {
166167
if (payload instanceof org.springframework.ws.mime.MimeMessage mimeMessage) {
167168
return org.springframework.ws.support.MarshallingUtils.unmarshal(this.delegate,
168169
mimeMessage);

spring-integration-xml/src/main/java/org/springframework/integration/xml/transformer/XPathTransformer.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616

1717
package org.springframework.integration.xml.transformer;
1818

19+
import org.jspecify.annotations.Nullable;
1920
import org.w3c.dom.Node;
2021

2122
import org.springframework.integration.transformer.AbstractTransformer;
@@ -50,7 +51,7 @@ public class XPathTransformer extends AbstractTransformer {
5051

5152
private volatile XPathEvaluationType evaluationType = XPathEvaluationType.STRING_RESULT;
5253

53-
private volatile NodeMapper<?> nodeMapper;
54+
private volatile @Nullable NodeMapper<?> nodeMapper;
5455

5556
/**
5657
* Create an {@link XPathTransformer} that will create an XPath expression from the given String
@@ -110,7 +111,7 @@ public String getComponentType() {
110111
}
111112

112113
@Override
113-
protected Object doTransform(Message<?> message) {
114+
protected @Nullable Object doTransform(Message<?> message) {
114115
Node node = this.converter.convertToNode(message.getPayload());
115116
Object result = null;
116117
if (this.nodeMapper != null) {

spring-integration-xml/src/main/java/org/springframework/integration/xml/transformer/XsltPayloadTransformer.java

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
import javax.xml.transform.dom.DOMSource;
3434
import javax.xml.transform.stream.StreamSource;
3535

36+
import org.jspecify.annotations.Nullable;
3637
import org.w3c.dom.Document;
3738

3839
import org.springframework.beans.factory.BeanClassLoaderAware;
@@ -89,17 +90,19 @@
8990
*/
9091
public class XsltPayloadTransformer extends AbstractXmlTransformer implements BeanClassLoaderAware {
9192

92-
private final ResultTransformer resultTransformer;
93+
private final @Nullable ResultTransformer resultTransformer;
9394

94-
private final Resource xslResource;
95+
private final @Nullable Resource xslResource;
9596

97+
@SuppressWarnings("NullAway.Init")
9698
private Templates templates;
9799

98-
private String transformerFactoryClassName;
100+
private @Nullable String transformerFactoryClassName;
99101

102+
@SuppressWarnings("NullAway.Init")
100103
private volatile StandardEvaluationContext evaluationContext;
101104

102-
private Map<String, Expression> xslParameterMappings;
105+
private @Nullable Map<String, Expression> xslParameterMappings;
103106

104107
private SourceFactory sourceFactory = new DomSourceFactory();
105108

@@ -109,15 +112,15 @@ public class XsltPayloadTransformer extends AbstractXmlTransformer implements Be
109112

110113
private boolean alwaysUseResultFactory = false;
111114

112-
private String[] xsltParamHeaders;
115+
private String @Nullable [] xsltParamHeaders;
113116

114117
public XsltPayloadTransformer(Templates templates) {
115118
this(templates, null);
116119
}
117120

118-
private ClassLoader classLoader;
121+
private @Nullable ClassLoader classLoader;
119122

120-
public XsltPayloadTransformer(Templates templates, ResultTransformer resultTransformer) {
123+
public XsltPayloadTransformer(Templates templates, @Nullable ResultTransformer resultTransformer) {
121124
Assert.notNull(templates, "'templates' must not be null.");
122125
this.templates = templates;
123126
this.resultTransformer = resultTransformer;
@@ -136,8 +139,8 @@ public XsltPayloadTransformer(Resource xslResource, String transformerFactoryCla
136139
this(xslResource, null, transformerFactoryClassName);
137140
}
138141

139-
public XsltPayloadTransformer(Resource xslResource, ResultTransformer resultTransformer,
140-
String transformerFactoryClassName) {
142+
public XsltPayloadTransformer(Resource xslResource, @Nullable ResultTransformer resultTransformer,
143+
@Nullable String transformerFactoryClassName) {
141144

142145
Assert.notNull(xslResource, "'xslResource' must not be null.");
143146
Assert.isTrue(xslResource instanceof ClassPathResource ||
@@ -230,6 +233,7 @@ protected void onInit() {
230233
this.evaluationContext = ExpressionUtils.createStandardEvaluationContext(getBeanFactory());
231234
if (this.templates == null) {
232235
try {
236+
Assert.notNull(this.xslResource, "'xslResource' must not be null.");
233237
TransformerFactory transformerFactory = createTransformerFactory();
234238
this.templates = transformerFactory.newTemplates(createStreamSourceOnResource(this.xslResource));
235239
}
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
/**
22
* Provides Transformer and Enricher implementations.
33
*/
4+
@org.jspecify.annotations.NullMarked
45
package org.springframework.integration.xml.transformer;

spring-integration-xml/src/main/java/org/springframework/integration/xml/transformer/support/XPathExpressionEvaluatingHeaderValueMessageProcessor.java

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616

1717
package org.springframework.integration.xml.transformer.support;
1818

19+
import org.jspecify.annotations.Nullable;
1920
import org.w3c.dom.Node;
2021

2122
import org.springframework.beans.BeansException;
@@ -55,9 +56,9 @@ public class XPathExpressionEvaluatingHeaderValueMessageProcessor implements Hea
5556

5657
private XPathEvaluationType evaluationType = XPathEvaluationType.STRING_RESULT;
5758

58-
private TypeDescriptor headerTypeDescriptor;
59+
private @Nullable TypeDescriptor headerTypeDescriptor;
5960

60-
private Boolean overwrite;
61+
private @Nullable Boolean overwrite;
6162

6263
public XPathExpressionEvaluatingHeaderValueMessageProcessor(String expression) {
6364
this(expression, new DefaultXmlPayloadConverter());
@@ -107,7 +108,7 @@ public void setOverwrite(Boolean overwrite) {
107108
}
108109

109110
@Override
110-
public Boolean isOverwrite() {
111+
public @Nullable Boolean isOverwrite() {
111112
return this.overwrite;
112113
}
113114

@@ -120,7 +121,7 @@ public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
120121
}
121122

122123
@Override
123-
public Object processMessage(Message<?> message) {
124+
public @Nullable Object processMessage(Message<?> message) {
124125
Node node = this.converter.convertToNode(message.getPayload());
125126
Object result = this.evaluationType.evaluateXPath(this.expression, node);
126127
if (result instanceof String string && string.isEmpty()) {

spring-integration-xml/src/main/java/org/springframework/integration/xml/transformer/support/package-info.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,4 +4,5 @@
44
* @since 3.0
55
*
66
*/
7+
@org.jspecify.annotations.NullMarked
78
package org.springframework.integration.xml.transformer.support;

0 commit comments

Comments
 (0)