Add nullability support

This reviews the entire code base to explicitly declare APIs that
accept and/or return a null value. The code base is validated using
ErrorProne.

Closes gh-1562
This commit is contained in:
Stéphane Nicoll
2025-06-05 16:02:05 +02:00
358 changed files with 1899 additions and 1101 deletions

View File

@@ -15,6 +15,7 @@ dependencies {
checkstyle("io.spring.javaformat:spring-javaformat-checkstyle:${javaFormatVersion}")
implementation("com.github.ben-manes:gradle-versions-plugin:$gradleVersionsPluginVersion")
implementation("io.spring.gradle.nullability:nullability-plugin:$nullabilityPluginVersion")
implementation("io.spring.javaformat:spring-javaformat-gradle-plugin:$javaFormatVersion")
testImplementation("org.junit.jupiter:junit-jupiter")

View File

@@ -16,6 +16,7 @@
package org.springframework.ws.gradle.conventions;
import io.spring.gradle.nullability.NullabilityPlugin;
import org.gradle.api.Plugin;
import org.gradle.api.Project;
import org.gradle.api.plugins.JavaBasePlugin;
@@ -37,7 +38,10 @@ public class ConventionsPlugin implements Plugin<Project> {
new JavaBasePluginConventions().apply(project);
new CheckstyleConventions().apply(project);
});
project.getPlugins().withType(JavaPlugin.class).all((plugin) -> new JavaPluginConventions().apply(project));
project.getPlugins().withType(JavaPlugin.class).all((plugin) -> {
project.getPlugins().apply(NullabilityPlugin.class);
new JavaPluginConventions().apply(project);
});
project.getPlugins()
.withType(MavenPublishPlugin.class)
.all((plugin) -> new MavenPublishPluginConventions().apply(project));

View File

@@ -1,4 +1,5 @@
assertJVersion=3.25.3
gradleVersionsPluginVersion=0.52.0
javaFormatVersion=0.0.45
javaFormatVersion=0.0.46
junitVersion=5.11.0
nullabilityPluginVersion=0.0.1

View File

@@ -18,6 +18,8 @@ package org.springframework.ws;
import javax.xml.namespace.QName;
import org.jspecify.annotations.Nullable;
/**
* Sub-interface of {@link WebServiceMessage} that can contain special Fault messages.
* Fault messages (such as {@link org.springframework.ws.soap.SoapFault} SOAP Faults)
@@ -39,7 +41,7 @@ public interface FaultAwareWebServiceMessage extends WebServiceMessage {
/**
* Returns the fault code, if any.
*/
QName getFaultCode();
@Nullable QName getFaultCode();
/**
* Returns the fault reason message.
@@ -47,6 +49,6 @@ public interface FaultAwareWebServiceMessage extends WebServiceMessage {
* present.
* @see #hasFault()
*/
String getFaultReason();
@Nullable String getFaultReason();
}

View File

@@ -16,6 +16,8 @@
package org.springframework.ws;
import org.jspecify.annotations.Nullable;
import org.springframework.core.NestedRuntimeException;
/**
@@ -31,7 +33,7 @@ public abstract class WebServiceException extends NestedRuntimeException {
* Create a new instance of the {@code WebServiceException} class.
* @param msg the detail message
*/
public WebServiceException(String msg) {
public WebServiceException(@Nullable String msg) {
super(msg);
}
@@ -40,7 +42,7 @@ public abstract class WebServiceException extends NestedRuntimeException {
* @param msg the detail message
* @param ex the root {@link Throwable exception}
*/
public WebServiceException(String msg, Throwable ex) {
public WebServiceException(@Nullable String msg, Throwable ex) {
super(msg, ex);
}

View File

@@ -22,6 +22,8 @@ import java.io.OutputStream;
import javax.xml.transform.Result;
import javax.xml.transform.Source;
import org.jspecify.annotations.Nullable;
/**
* Represents a protocol-agnostic XML message.
* <p>
@@ -41,7 +43,7 @@ public interface WebServiceMessage {
* single time.
* @return the message contents
*/
Source getPayloadSource();
@Nullable Source getPayloadSource();
/**
* Returns the contents of the message as a {@link Result}.

View File

@@ -16,6 +16,8 @@
package org.springframework.ws.client;
import org.jspecify.annotations.Nullable;
import org.springframework.ws.WebServiceException;
/**
@@ -31,7 +33,7 @@ public abstract class WebServiceClientException extends WebServiceException {
* Create a new instance of the {@code WebServiceClientException} class.
* @param msg the detail message
*/
public WebServiceClientException(String msg) {
public WebServiceClientException(@Nullable String msg) {
super(msg);
}

View File

@@ -16,6 +16,8 @@
package org.springframework.ws.client;
import org.jspecify.annotations.Nullable;
import org.springframework.ws.FaultAwareWebServiceMessage;
/**
@@ -27,7 +29,7 @@ import org.springframework.ws.FaultAwareWebServiceMessage;
@SuppressWarnings("serial")
public class WebServiceFaultException extends WebServiceClientException {
private final FaultAwareWebServiceMessage faultMessage;
private final @Nullable FaultAwareWebServiceMessage faultMessage;
/** Create a new instance of the {@code WebServiceFaultException} class. */
public WebServiceFaultException(String msg) {
@@ -45,7 +47,7 @@ public class WebServiceFaultException extends WebServiceClientException {
}
/** Returns the fault message. */
public FaultAwareWebServiceMessage getWebServiceMessage() {
public @Nullable FaultAwareWebServiceMessage getWebServiceMessage() {
return this.faultMessage;
}

View File

@@ -18,6 +18,8 @@ package org.springframework.ws.client;
import java.io.IOException;
import org.jspecify.annotations.Nullable;
/**
* Exception thrown whenever an I/O error occurs on the client-side.
*
@@ -31,7 +33,7 @@ public class WebServiceIOException extends WebServiceClientException {
* Create a new instance of the {@code WebServiceIOException} class.
* @param msg the detail message
*/
public WebServiceIOException(String msg) {
public WebServiceIOException(@Nullable String msg) {
super(msg);
}

View File

@@ -16,6 +16,8 @@
package org.springframework.ws.client;
import org.jspecify.annotations.Nullable;
import org.springframework.ws.transport.TransportException;
/**
@@ -31,7 +33,7 @@ public class WebServiceTransportException extends WebServiceIOException {
* Create a new instance of the {@code WebServiceTransportException} class.
* @param msg the detail message
*/
public WebServiceTransportException(String msg) {
public WebServiceTransportException(@Nullable String msg) {
super(msg);
}

View File

@@ -21,6 +21,8 @@ import java.io.IOException;
import javax.xml.transform.Source;
import javax.xml.transform.TransformerException;
import org.jspecify.annotations.Nullable;
/**
* Callback interface for extracting a result object from a
* {@link javax.xml.transform.Source} instance.
@@ -49,6 +51,6 @@ public interface SourceExtractor<T> {
* typically be stateful in the latter case)
* @throws IOException in case of I/O errors
*/
T extractData(Source source) throws IOException, TransformerException;
@Nullable T extractData(@Nullable Source source) throws IOException, TransformerException;
}

View File

@@ -20,6 +20,8 @@ import java.io.IOException;
import javax.xml.transform.TransformerException;
import org.jspecify.annotations.Nullable;
import org.springframework.ws.WebServiceMessage;
/**
@@ -50,6 +52,6 @@ public interface WebServiceMessageExtractor<T> {
* @throws IOException in case of I/O errors
* @throws TransformerException in case of transformation errors
*/
T extractData(WebServiceMessage message) throws IOException, TransformerException;
@Nullable T extractData(WebServiceMessage message) throws IOException, TransformerException;
}

View File

@@ -19,6 +19,8 @@ package org.springframework.ws.client.core;
import javax.xml.transform.Result;
import javax.xml.transform.Source;
import org.jspecify.annotations.Nullable;
import org.springframework.oxm.XmlMappingException;
import org.springframework.ws.client.WebServiceClientException;
@@ -46,8 +48,8 @@ public interface WebServiceOperations {
* @throws WebServiceClientException if there is a problem sending or receiving the
* message
*/
<T> T sendAndReceive(WebServiceMessageCallback requestCallback, WebServiceMessageExtractor<T> responseExtractor)
throws WebServiceClientException;
<T> @Nullable T sendAndReceive(WebServiceMessageCallback requestCallback,
WebServiceMessageExtractor<T> responseExtractor) throws WebServiceClientException;
/**
* Sends a web service message that can be manipulated with the given callback,
@@ -61,7 +63,7 @@ public interface WebServiceOperations {
* @throws WebServiceClientException if there is a problem sending or receiving the
* message
*/
<T> T sendAndReceive(String uri, WebServiceMessageCallback requestCallback,
<T> @Nullable T sendAndReceive(String uri, WebServiceMessageCallback requestCallback,
WebServiceMessageExtractor<T> responseExtractor) throws WebServiceClientException;
/**
@@ -112,7 +114,7 @@ public interface WebServiceOperations {
* @see WebServiceTemplate#setMarshaller(org.springframework.oxm.Marshaller)
* @see WebServiceTemplate#setUnmarshaller(org.springframework.oxm.Unmarshaller)
*/
Object marshalSendAndReceive(Object requestPayload) throws XmlMappingException, WebServiceClientException;
@Nullable Object marshalSendAndReceive(Object requestPayload) throws XmlMappingException, WebServiceClientException;
/**
* Sends a web service message that contains the given payload, marshalled by the
@@ -128,7 +130,7 @@ public interface WebServiceOperations {
* @see WebServiceTemplate#setMarshaller(org.springframework.oxm.Marshaller)
* @see WebServiceTemplate#setUnmarshaller(org.springframework.oxm.Unmarshaller)
*/
Object marshalSendAndReceive(String uri, Object requestPayload)
@Nullable Object marshalSendAndReceive(String uri, Object requestPayload)
throws XmlMappingException, WebServiceClientException;
/**
@@ -148,7 +150,7 @@ public interface WebServiceOperations {
* @see WebServiceTemplate#setMarshaller(org.springframework.oxm.Marshaller)
* @see WebServiceTemplate#setUnmarshaller(org.springframework.oxm.Unmarshaller)
*/
Object marshalSendAndReceive(Object requestPayload, WebServiceMessageCallback requestCallback)
@Nullable Object marshalSendAndReceive(Object requestPayload, @Nullable WebServiceMessageCallback requestCallback)
throws XmlMappingException, WebServiceClientException;
/**
@@ -167,8 +169,8 @@ public interface WebServiceOperations {
* @see WebServiceTemplate#setMarshaller(org.springframework.oxm.Marshaller)
* @see WebServiceTemplate#setUnmarshaller(org.springframework.oxm.Unmarshaller)
*/
Object marshalSendAndReceive(String uri, Object requestPayload, WebServiceMessageCallback requestCallback)
throws XmlMappingException, WebServiceClientException;
@Nullable Object marshalSendAndReceive(String uri, @Nullable Object requestPayload,
@Nullable WebServiceMessageCallback requestCallback) throws XmlMappingException, WebServiceClientException;
// -----------------------------------------------------------------------------------------------------------------
// Convenience methods for sending Sources
@@ -185,7 +187,7 @@ public interface WebServiceOperations {
* @throws WebServiceClientException if there is a problem sending or receiving the
* message
*/
<T> T sendSourceAndReceive(Source requestPayload, SourceExtractor<T> responseExtractor)
<T> @Nullable T sendSourceAndReceive(Source requestPayload, SourceExtractor<T> responseExtractor)
throws WebServiceClientException;
/**
@@ -198,7 +200,7 @@ public interface WebServiceOperations {
* @throws WebServiceClientException if there is a problem sending or receiving the
* message
*/
<T> T sendSourceAndReceive(String uri, Source requestPayload, SourceExtractor<T> responseExtractor)
<T> @Nullable T sendSourceAndReceive(String uri, Source requestPayload, SourceExtractor<T> responseExtractor)
throws WebServiceClientException;
/**
@@ -216,7 +218,7 @@ public interface WebServiceOperations {
* @throws WebServiceClientException if there is a problem sending or receiving the
* message
*/
<T> T sendSourceAndReceive(Source requestPayload, WebServiceMessageCallback requestCallback,
<T> @Nullable T sendSourceAndReceive(Source requestPayload, WebServiceMessageCallback requestCallback,
SourceExtractor<T> responseExtractor) throws WebServiceClientException;
/**
@@ -233,8 +235,9 @@ public interface WebServiceOperations {
* @throws WebServiceClientException if there is a problem sending or receiving the
* message
*/
<T> T sendSourceAndReceive(String uri, Source requestPayload, WebServiceMessageCallback requestCallback,
SourceExtractor<T> responseExtractor) throws WebServiceClientException;
<T> @Nullable T sendSourceAndReceive(String uri, Source requestPayload,
@Nullable WebServiceMessageCallback requestCallback, SourceExtractor<T> responseExtractor)
throws WebServiceClientException;
// -----------------------------------------------------------------------------------------------------------------
// Convenience methods for sending Sources and receiving to Results

View File

@@ -30,6 +30,7 @@ import javax.xml.transform.TransformerException;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.jspecify.annotations.Nullable;
import org.springframework.beans.factory.BeanInitializationException;
import org.springframework.oxm.Marshaller;
@@ -133,19 +134,19 @@ public class WebServiceTemplate extends WebServiceAccessor implements WebService
protected static final Log receivedMessageTracingLogger = LogFactory
.getLog(WebServiceTemplate.MESSAGE_TRACING_LOG_CATEGORY + ".received");
private Marshaller marshaller;
private @Nullable Marshaller marshaller;
private Unmarshaller unmarshaller;
private @Nullable Unmarshaller unmarshaller;
private FaultMessageResolver faultMessageResolver;
private @Nullable FaultMessageResolver faultMessageResolver;
private boolean checkConnectionForError = true;
private boolean checkConnectionForFault = true;
private ClientInterceptor[] interceptors;
private ClientInterceptor @Nullable [] interceptors;
private DestinationProvider destinationProvider;
private @Nullable DestinationProvider destinationProvider;
/** Creates a new {@code WebServiceTemplate} using default settings. */
public WebServiceTemplate() {
@@ -205,7 +206,7 @@ public class WebServiceTemplate extends WebServiceAccessor implements WebService
/**
* Returns the default URI to be used on operations that do not have a URI parameter.
*/
public String getDefaultUri() {
public @Nullable String getDefaultUri() {
if (this.destinationProvider != null) {
URI uri = this.destinationProvider.getDestination();
return (uri != null) ? uri.toString() : null;
@@ -241,7 +242,7 @@ public class WebServiceTemplate extends WebServiceAccessor implements WebService
* Returns the destination provider used on operations that do not have a URI
* parameter.
*/
public DestinationProvider getDestinationProvider() {
public @Nullable DestinationProvider getDestinationProvider() {
return this.destinationProvider;
}
@@ -264,7 +265,7 @@ public class WebServiceTemplate extends WebServiceAccessor implements WebService
}
/** Returns the marshaller for this template. */
public Marshaller getMarshaller() {
public @Nullable Marshaller getMarshaller() {
return this.marshaller;
}
@@ -274,7 +275,7 @@ public class WebServiceTemplate extends WebServiceAccessor implements WebService
}
/** Returns the unmarshaller for this template. */
public Unmarshaller getUnmarshaller() {
public @Nullable Unmarshaller getUnmarshaller() {
return this.unmarshaller;
}
@@ -284,7 +285,7 @@ public class WebServiceTemplate extends WebServiceAccessor implements WebService
}
/** Returns the fault message resolver for this template. */
public FaultMessageResolver getFaultMessageResolver() {
public @Nullable FaultMessageResolver getFaultMessageResolver() {
return this.faultMessageResolver;
}
@@ -346,7 +347,7 @@ public class WebServiceTemplate extends WebServiceAccessor implements WebService
* this template.
* @return array of endpoint interceptors, or {@code null} if none
*/
public ClientInterceptor[] getInterceptors() {
public ClientInterceptor @Nullable [] getInterceptors() {
return this.interceptors;
}
@@ -402,23 +403,26 @@ public class WebServiceTemplate extends WebServiceAccessor implements WebService
//
@Override
public Object marshalSendAndReceive(final Object requestPayload) {
public @Nullable Object marshalSendAndReceive(final Object requestPayload) {
return marshalSendAndReceive(requestPayload, null);
}
@Override
public Object marshalSendAndReceive(String uri, final Object requestPayload) {
public @Nullable Object marshalSendAndReceive(String uri, final Object requestPayload) {
return marshalSendAndReceive(uri, requestPayload, null);
}
@Override
public Object marshalSendAndReceive(final Object requestPayload, final WebServiceMessageCallback requestCallback) {
return marshalSendAndReceive(getDefaultUri(), requestPayload, requestCallback);
public @Nullable Object marshalSendAndReceive(final Object requestPayload,
final @Nullable WebServiceMessageCallback requestCallback) {
String defaultUri = getDefaultUri();
Assert.notNull(defaultUri, "'defaultUri' must not be null");
return marshalSendAndReceive(defaultUri, requestPayload, requestCallback);
}
@Override
public Object marshalSendAndReceive(String uri, final Object requestPayload,
final WebServiceMessageCallback requestCallback) {
public @Nullable Object marshalSendAndReceive(String uri, final @Nullable Object requestPayload,
final @Nullable WebServiceMessageCallback requestCallback) {
return sendAndReceive(uri, new WebServiceMessageCallback() {
public void doWithMessage(WebServiceMessage request) throws IOException, TransformerException {
@@ -436,7 +440,7 @@ public class WebServiceTemplate extends WebServiceAccessor implements WebService
}
}, new WebServiceMessageExtractor<>() {
public Object extractData(WebServiceMessage response) throws IOException {
public @Nullable Object extractData(WebServiceMessage response) throws IOException {
Unmarshaller unmarshaller = getUnmarshaller();
if (unmarshaller == null) {
throw new IllegalStateException(
@@ -462,20 +466,22 @@ public class WebServiceTemplate extends WebServiceAccessor implements WebService
}
@Override
public boolean sendSourceAndReceiveToResult(Source requestPayload, WebServiceMessageCallback requestCallback,
final Result responseResult) {
return sendSourceAndReceiveToResult(getDefaultUri(), requestPayload, requestCallback, responseResult);
public boolean sendSourceAndReceiveToResult(Source requestPayload,
@Nullable WebServiceMessageCallback requestCallback, final Result responseResult) {
String defaultUri = getDefaultUri();
Assert.notNull(defaultUri, "'defaultUri' must not be null");
return sendSourceAndReceiveToResult(defaultUri, requestPayload, requestCallback, responseResult);
}
@Override
public boolean sendSourceAndReceiveToResult(String uri, Source requestPayload,
WebServiceMessageCallback requestCallback, final Result responseResult) {
@Nullable WebServiceMessageCallback requestCallback, final Result responseResult) {
try {
final Transformer transformer = createTransformer();
Boolean retVal = doSendAndReceive(uri, transformer, requestPayload, requestCallback,
new SourceExtractor<>() {
public Boolean extractData(Source source) throws IOException, TransformerException {
public Boolean extractData(@Nullable Source source) throws IOException, TransformerException {
if (source != null) {
transformer.transform(source, responseResult);
}
@@ -494,25 +500,28 @@ public class WebServiceTemplate extends WebServiceAccessor implements WebService
//
@Override
public <T> T sendSourceAndReceive(final Source requestPayload, final SourceExtractor<T> responseExtractor) {
public <T> @Nullable T sendSourceAndReceive(final Source requestPayload,
final SourceExtractor<T> responseExtractor) {
return sendSourceAndReceive(requestPayload, null, responseExtractor);
}
@Override
public <T> T sendSourceAndReceive(String uri, final Source requestPayload,
public <T> @Nullable T sendSourceAndReceive(String uri, final Source requestPayload,
final SourceExtractor<T> responseExtractor) {
return sendSourceAndReceive(uri, requestPayload, null, responseExtractor);
}
@Override
public <T> T sendSourceAndReceive(final Source requestPayload, final WebServiceMessageCallback requestCallback,
final SourceExtractor<T> responseExtractor) {
return sendSourceAndReceive(getDefaultUri(), requestPayload, requestCallback, responseExtractor);
public <T> @Nullable T sendSourceAndReceive(final Source requestPayload,
final @Nullable WebServiceMessageCallback requestCallback, final SourceExtractor<T> responseExtractor) {
String defaultUri = getDefaultUri();
Assert.notNull(defaultUri, "'defaultUri' must not be null");
return sendSourceAndReceive(defaultUri, requestPayload, requestCallback, responseExtractor);
}
@Override
public <T> T sendSourceAndReceive(String uri, final Source requestPayload,
final WebServiceMessageCallback requestCallback, final SourceExtractor<T> responseExtractor) {
public <T> @Nullable T sendSourceAndReceive(String uri, final Source requestPayload,
final @Nullable WebServiceMessageCallback requestCallback, final SourceExtractor<T> responseExtractor) {
try {
return doSendAndReceive(uri, createTransformer(), requestPayload, requestCallback, responseExtractor);
@@ -522,8 +531,8 @@ public class WebServiceTemplate extends WebServiceAccessor implements WebService
}
}
private <T> T doSendAndReceive(String uri, final Transformer transformer, final Source requestPayload,
final WebServiceMessageCallback requestCallback, final SourceExtractor<T> responseExtractor) {
private <T> @Nullable T doSendAndReceive(String uri, final Transformer transformer, final Source requestPayload,
final @Nullable WebServiceMessageCallback requestCallback, final SourceExtractor<T> responseExtractor) {
Assert.notNull(responseExtractor, "responseExtractor must not be null");
return sendAndReceive(uri, new WebServiceMessageCallback() {
public void doWithMessage(WebServiceMessage message) throws IOException, TransformerException {
@@ -542,7 +551,9 @@ public class WebServiceTemplate extends WebServiceAccessor implements WebService
@Override
public boolean sendAndReceive(WebServiceMessageCallback requestCallback,
WebServiceMessageCallback responseCallback) {
return sendAndReceive(getDefaultUri(), requestCallback, responseCallback);
String defaultUri = getDefaultUri();
Assert.notNull(defaultUri, "'defaultUri' must not be null");
return sendAndReceive(defaultUri, requestCallback, responseCallback);
}
@Override
@@ -555,13 +566,15 @@ public class WebServiceTemplate extends WebServiceAccessor implements WebService
}
@Override
public <T> T sendAndReceive(WebServiceMessageCallback requestCallback,
public <T> @Nullable T sendAndReceive(WebServiceMessageCallback requestCallback,
WebServiceMessageExtractor<T> responseExtractor) {
return sendAndReceive(getDefaultUri(), requestCallback, responseExtractor);
String defaultUri = getDefaultUri();
Assert.notNull(defaultUri, "'defaultUri' must not be null");
return sendAndReceive(defaultUri, requestCallback, responseExtractor);
}
@Override
public <T> T sendAndReceive(String uriString, WebServiceMessageCallback requestCallback,
public <T> @Nullable T sendAndReceive(String uriString, WebServiceMessageCallback requestCallback,
WebServiceMessageExtractor<T> responseExtractor) {
Assert.notNull(responseExtractor, "'responseExtractor' must not be null");
Assert.hasLength(uriString, "'uri' must not be empty");
@@ -581,7 +594,9 @@ public class WebServiceTemplate extends WebServiceAccessor implements WebService
throw new WebServiceIOException("I/O error: " + ex.getMessage(), ex);
}
finally {
TransportUtils.closeConnection(connection);
if (connection != null) {
TransportUtils.closeConnection(connection);
}
TransportContextHolder.setTransportContext(previousTransportContext);
}
}
@@ -603,8 +618,8 @@ public class WebServiceTemplate extends WebServiceAccessor implements WebService
* @throws IOException in case of I/O errors
*/
@SuppressWarnings("unchecked")
protected <T> T doSendAndReceive(MessageContext messageContext, WebServiceConnection connection,
WebServiceMessageCallback requestCallback, WebServiceMessageExtractor<T> responseExtractor)
protected <T> @Nullable T doSendAndReceive(MessageContext messageContext, WebServiceConnection connection,
@Nullable WebServiceMessageCallback requestCallback, WebServiceMessageExtractor<T> responseExtractor)
throws IOException {
int interceptorIndex = -1;
try {
@@ -819,7 +834,7 @@ public class WebServiceTemplate extends WebServiceAccessor implements WebService
* @param ex exception thrown on handler execution, or {@code null} if none
* @see ClientInterceptor#afterCompletion
*/
private void triggerAfterCompletion(int interceptorIndex, MessageContext messageContext, Exception ex)
private void triggerAfterCompletion(int interceptorIndex, MessageContext messageContext, @Nullable Exception ex)
throws WebServiceClientException {
if (this.interceptors != null) {
for (int i = interceptorIndex; i >= 0; i--) {
@@ -843,7 +858,8 @@ public class WebServiceTemplate extends WebServiceAccessor implements WebService
* {@link #sendAndReceive(String,WebServiceMessageCallback, WebServiceMessageExtractor)},
* if any
*/
protected Object handleFault(WebServiceConnection connection, MessageContext messageContext) throws IOException {
protected @Nullable Object handleFault(WebServiceConnection connection, MessageContext messageContext)
throws IOException {
if (this.logger.isDebugEnabled()) {
this.logger.debug("Received Fault message for request [" + messageContext.getRequest() + "]");
}
@@ -887,7 +903,7 @@ public class WebServiceTemplate extends WebServiceAccessor implements WebService
}
@Override
public T extractData(WebServiceMessage message) throws IOException, TransformerException {
public @Nullable T extractData(WebServiceMessage message) throws IOException, TransformerException {
return this.sourceExtractor.extractData(message.getPayloadSource());
}

View File

@@ -18,4 +18,7 @@
* Core package of the Spring-WS client-side support. Provides a WebServiceTemplate class
* and various callback interfaces.
*/
@NullMarked
package org.springframework.ws.client.core;
import org.jspecify.annotations.NullMarked;

View File

@@ -18,6 +18,7 @@ package org.springframework.ws.client.core.support;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.jspecify.annotations.Nullable;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.oxm.Marshaller;
@@ -90,7 +91,7 @@ public abstract class WebServiceGatewaySupport implements InitializingBean {
}
/** Returns the default URI used by the gateway. */
public final String getDefaultUri() {
public final @Nullable String getDefaultUri() {
return this.webServiceTemplate.getDefaultUri();
}
@@ -100,7 +101,7 @@ public abstract class WebServiceGatewaySupport implements InitializingBean {
}
/** Returns the destination provider used by the gateway. */
public final DestinationProvider getDestinationProvider() {
public final @Nullable DestinationProvider getDestinationProvider() {
return this.webServiceTemplate.getDestinationProvider();
}
@@ -145,7 +146,7 @@ public abstract class WebServiceGatewaySupport implements InitializingBean {
}
/** Returns the {@code Marshaller} used by the gateway. */
public final Marshaller getMarshaller() {
public final @Nullable Marshaller getMarshaller() {
return this.webServiceTemplate.getMarshaller();
}
@@ -160,7 +161,7 @@ public abstract class WebServiceGatewaySupport implements InitializingBean {
}
/** Returns the {@code Unmarshaller} used by the gateway. */
public final Unmarshaller getUnmarshaller() {
public final @Nullable Unmarshaller getUnmarshaller() {
return this.webServiceTemplate.getUnmarshaller();
}
@@ -175,7 +176,7 @@ public abstract class WebServiceGatewaySupport implements InitializingBean {
}
/** Returns the {@code ClientInterceptors} used by the template. */
public final ClientInterceptor[] getInterceptors() {
public final ClientInterceptor @Nullable [] getInterceptors() {
return this.webServiceTemplate.getInterceptors();
}

View File

@@ -18,4 +18,7 @@
* Convenient super class for application classes that need Web service access. Contains a
* base class for WebServiceTemplate usage.
*/
@NullMarked
package org.springframework.ws.client.core.support;
import org.jspecify.annotations.NullMarked;

View File

@@ -18,4 +18,7 @@
* Contains classes for client-side Spring-WS support, allowing for Spring-style Web
* service access.
*/
@NullMarked
package org.springframework.ws.client;
import org.jspecify.annotations.NullMarked;

View File

@@ -41,8 +41,10 @@ import org.springframework.xml.transform.TransformerObjectSupport;
*/
public abstract class WebServiceAccessor extends TransformerObjectSupport implements InitializingBean {
@SuppressWarnings("NullAway.Init")
private WebServiceMessageFactory messageFactory;
@SuppressWarnings("NullAway.Init")
private WebServiceMessageSender[] messageSenders;
/** Returns the message factory used for creating messages. */

View File

@@ -20,6 +20,7 @@ import java.net.URI;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.jspecify.annotations.Nullable;
/**
* Abstract base class for {@link DestinationProvider} implementations that cache
@@ -36,7 +37,7 @@ public abstract class AbstractCachingDestinationProvider implements DestinationP
/** Logger available to subclasses. */
protected final Log logger = LogFactory.getLog(getClass());
private URI cachedUri;
private @Nullable URI cachedUri;
private boolean cache = true;
@@ -50,7 +51,7 @@ public abstract class AbstractCachingDestinationProvider implements DestinationP
}
@Override
public final URI getDestination() {
public final @Nullable URI getDestination() {
if (this.cache) {
if (this.cachedUri == null) {
this.cachedUri = lookupDestination();
@@ -69,6 +70,6 @@ public abstract class AbstractCachingDestinationProvider implements DestinationP
* called once.
* @return the destination URI
*/
protected abstract URI lookupDestination();
protected abstract @Nullable URI lookupDestination();
}

View File

@@ -18,6 +18,8 @@ package org.springframework.ws.client.support.destination;
import java.net.URI;
import org.jspecify.annotations.Nullable;
/**
* Strategy interface for providing a
* {@link org.springframework.ws.client.core.WebServiceTemplate} destination URI at
@@ -36,6 +38,6 @@ public interface DestinationProvider {
* Return the destination URI.
* @return the destination URI
*/
URI getDestination();
@Nullable URI getDestination();
}

View File

@@ -26,6 +26,7 @@ import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMResult;
import org.jspecify.annotations.Nullable;
import org.w3c.dom.Document;
import org.springframework.core.io.Resource;
@@ -64,7 +65,7 @@ public class Wsdl11DestinationProvider extends AbstractCachingDestinationProvide
private XPathExpression locationXPathExpression;
private Resource wsdlResource;
private @Nullable Resource wsdlResource;
public Wsdl11DestinationProvider() {
this.expressionNamespaces.put("wsdl", "http://schemas.xmlsoap.org/wsdl/");
@@ -120,7 +121,8 @@ public class Wsdl11DestinationProvider extends AbstractCachingDestinationProvide
}
@Override
protected URI lookupDestination() {
protected @Nullable URI lookupDestination() {
Assert.notNull(this.wsdlResource, "'wsdlResource' must not be null");
try {
DOMResult result = new DOMResult();
Transformer transformer = transformerFactory.newTransformer();

View File

@@ -17,4 +17,7 @@
/**
* Provides the {@code DestinationProvider} interface.
*/
@NullMarked
package org.springframework.ws.client.support.destination;
import org.jspecify.annotations.NullMarked;

View File

@@ -20,6 +20,7 @@ import java.io.IOException;
import javax.xml.transform.Source;
import org.jspecify.annotations.Nullable;
import org.xml.sax.SAXParseException;
import org.springframework.beans.factory.InitializingBean;
@@ -56,12 +57,14 @@ public abstract class AbstractValidatingInterceptor extends TransformerObjectSup
private String schemaLanguage = XmlValidatorFactory.SCHEMA_W3C_XML;
@SuppressWarnings("NullAway.Init")
private Resource[] schemas;
private boolean validateRequest = true;
private boolean validateResponse = false;
@SuppressWarnings("NullAway.Init")
private XmlValidator validator;
public String getSchemaLanguage() {
@@ -275,7 +278,8 @@ public abstract class AbstractValidatingInterceptor extends TransformerObjectSup
/** Does nothing by default. */
@Override
public void afterCompletion(MessageContext messageContext, Exception ex) throws WebServiceClientException {
public void afterCompletion(MessageContext messageContext, @Nullable Exception ex)
throws WebServiceClientException {
}
/**
@@ -285,7 +289,7 @@ public abstract class AbstractValidatingInterceptor extends TransformerObjectSup
* @return the part of the message that is to validated, or {@code null} not to
* validate anything
*/
protected abstract Source getValidationRequestSource(WebServiceMessage request);
protected abstract @Nullable Source getValidationRequestSource(WebServiceMessage request);
/**
* Abstract template method that returns the part of the response message that is to
@@ -294,6 +298,6 @@ public abstract class AbstractValidatingInterceptor extends TransformerObjectSup
* @return the part of the message that is to validated, or {@code null} not to
* validate anything
*/
protected abstract Source getValidationResponseSource(WebServiceMessage response);
protected abstract @Nullable Source getValidationResponseSource(WebServiceMessage response);
}

View File

@@ -16,6 +16,8 @@
package org.springframework.ws.client.support.interceptor;
import org.jspecify.annotations.Nullable;
import org.springframework.ws.client.WebServiceClientException;
import org.springframework.ws.context.MessageContext;
import org.springframework.ws.soap.SoapHeader;
@@ -102,6 +104,6 @@ public interface ClientInterceptor {
* @throws WebServiceClientException in case of errors
* @since 2.2
*/
void afterCompletion(MessageContext messageContext, Exception ex) throws WebServiceClientException;
void afterCompletion(MessageContext messageContext, @Nullable Exception ex) throws WebServiceClientException;
}

View File

@@ -18,6 +18,7 @@ package org.springframework.ws.client.support.interceptor;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.jspecify.annotations.Nullable;
import org.springframework.ws.client.WebServiceClientException;
import org.springframework.ws.context.MessageContext;
@@ -55,7 +56,8 @@ public abstract class ClientInterceptorAdapter implements ClientInterceptor {
* Does nothing by default.
*/
@Override
public void afterCompletion(MessageContext messageContext, Exception ex) throws WebServiceClientException {
public void afterCompletion(MessageContext messageContext, @Nullable Exception ex)
throws WebServiceClientException {
}

View File

@@ -18,6 +18,8 @@ package org.springframework.ws.client.support.interceptor;
import javax.xml.transform.Source;
import org.jspecify.annotations.Nullable;
import org.springframework.ws.WebServiceMessage;
/**
@@ -49,7 +51,7 @@ public class PayloadValidatingInterceptor extends AbstractValidatingInterceptor
* validate anything
*/
@Override
protected Source getValidationRequestSource(WebServiceMessage request) {
protected @Nullable Source getValidationRequestSource(WebServiceMessage request) {
return request.getPayloadSource();
}
@@ -60,7 +62,7 @@ public class PayloadValidatingInterceptor extends AbstractValidatingInterceptor
* validate anything
*/
@Override
protected Source getValidationResponseSource(WebServiceMessage response) {
protected @Nullable Source getValidationResponseSource(WebServiceMessage response) {
return response.getPayloadSource();
}

View File

@@ -17,4 +17,7 @@
/**
* Provides the {@code ClientInterceptor} interface, and validating interceptors.
*/
@NullMarked
package org.springframework.ws.client.support.interceptor;
import org.jspecify.annotations.NullMarked;

View File

@@ -18,4 +18,7 @@
* Classes supporting the org.springframework.ws.client.core package. Contains a base
* class for WebServiceTemplate usage.
*/
@NullMarked
package org.springframework.ws.client.support;
import org.jspecify.annotations.NullMarked;

View File

@@ -16,6 +16,7 @@
package org.springframework.ws.config;
import org.jspecify.annotations.Nullable;
import org.w3c.dom.Element;
import org.springframework.beans.BeanMetadataElement;
@@ -74,24 +75,24 @@ class AnnotationDrivenBeanDefinitionParser implements BeanDefinitionParser {
AnnotationDrivenBeanDefinitionParser.class.getClassLoader());
@Override
public BeanDefinition parse(Element element, ParserContext parserContext) {
public @Nullable BeanDefinition parse(Element element, ParserContext parserContext) {
Object source = parserContext.extractSource(element);
CompositeComponentDefinition compDefinition = new CompositeComponentDefinition(element.getTagName(), source);
parserContext.pushContainingComponent(compDefinition);
registerEndpointMappings(source, parserContext);
registerEndpointMappings(parserContext, source);
registerEndpointAdapters(element, source, parserContext);
registerEndpointAdapters(parserContext, element, source);
registerEndpointExceptionResolvers(source, parserContext);
registerEndpointExceptionResolvers(parserContext, source);
parserContext.popAndRegisterContainingComponent();
return null;
}
private void registerEndpointMappings(Object source, ParserContext parserContext) {
private void registerEndpointMappings(ParserContext parserContext, @Nullable Object source) {
RootBeanDefinition payloadRootMappingDef = createBeanDefinition(
PayloadRootAnnotationMethodEndpointMapping.class, source);
payloadRootMappingDef.getPropertyValues().add("order", 0);
@@ -107,7 +108,7 @@ class AnnotationDrivenBeanDefinitionParser implements BeanDefinitionParser {
parserContext.getReaderContext().registerWithGeneratedName(annActionMappingDef);
}
private void registerEndpointAdapters(Element element, Object source, ParserContext parserContext) {
private void registerEndpointAdapters(ParserContext parserContext, Element element, @Nullable Object source) {
RootBeanDefinition adapterDef = createBeanDefinition(DefaultMethodEndpointAdapter.class, source);
ManagedList<BeanMetadataElement> argumentResolvers = new ManagedList<>();
@@ -121,35 +122,35 @@ class AnnotationDrivenBeanDefinitionParser implements BeanDefinitionParser {
argumentResolvers.add(createBeanDefinition(SoapMethodArgumentResolver.class, source));
argumentResolvers.add(createBeanDefinition(SoapHeaderElementMethodArgumentResolver.class, source));
RuntimeBeanReference domProcessor = createBeanReference(DomPayloadMethodProcessor.class, source, parserContext);
RuntimeBeanReference domProcessor = createBeanReference(parserContext, DomPayloadMethodProcessor.class, source);
argumentResolvers.add(domProcessor);
returnValueHandlers.add(domProcessor);
RuntimeBeanReference sourceProcessor = createBeanReference(SourcePayloadMethodProcessor.class, source,
parserContext);
RuntimeBeanReference sourceProcessor = createBeanReference(parserContext, SourcePayloadMethodProcessor.class,
source);
argumentResolvers.add(sourceProcessor);
returnValueHandlers.add(sourceProcessor);
if (dom4jPresent) {
RuntimeBeanReference dom4jProcessor = createBeanReference(Dom4jPayloadMethodProcessor.class, source,
parserContext);
RuntimeBeanReference dom4jProcessor = createBeanReference(parserContext, Dom4jPayloadMethodProcessor.class,
source);
argumentResolvers.add(dom4jProcessor);
returnValueHandlers.add(dom4jProcessor);
}
if (jaxb2Present) {
RuntimeBeanReference xmlRootElementProcessor = createBeanReference(
XmlRootElementPayloadMethodProcessor.class, source, parserContext);
RuntimeBeanReference xmlRootElementProcessor = createBeanReference(parserContext,
XmlRootElementPayloadMethodProcessor.class, source);
argumentResolvers.add(xmlRootElementProcessor);
returnValueHandlers.add(xmlRootElementProcessor);
RuntimeBeanReference jaxbElementProcessor = createBeanReference(JaxbElementPayloadMethodProcessor.class,
source, parserContext);
RuntimeBeanReference jaxbElementProcessor = createBeanReference(parserContext,
JaxbElementPayloadMethodProcessor.class, source);
argumentResolvers.add(jaxbElementProcessor);
returnValueHandlers.add(jaxbElementProcessor);
}
if (jdomPresent) {
RuntimeBeanReference jdomProcessor = createBeanReference(JDomPayloadMethodProcessor.class, source,
parserContext);
RuntimeBeanReference jdomProcessor = createBeanReference(parserContext, JDomPayloadMethodProcessor.class,
source);
argumentResolvers.add(jdomProcessor);
returnValueHandlers.add(jdomProcessor);
}
@@ -157,8 +158,8 @@ class AnnotationDrivenBeanDefinitionParser implements BeanDefinitionParser {
argumentResolvers.add(createBeanDefinition(StaxPayloadMethodArgumentResolver.class, source));
}
if (xomPresent) {
RuntimeBeanReference xomProcessor = createBeanReference(XomPayloadMethodProcessor.class, source,
parserContext);
RuntimeBeanReference xomProcessor = createBeanReference(parserContext, XomPayloadMethodProcessor.class,
source);
argumentResolvers.add(xomProcessor);
returnValueHandlers.add(xomProcessor);
}
@@ -186,7 +187,7 @@ class AnnotationDrivenBeanDefinitionParser implements BeanDefinitionParser {
parserContext.getReaderContext().registerWithGeneratedName(adapterDef);
}
private void registerEndpointExceptionResolvers(Object source, ParserContext parserContext) {
private void registerEndpointExceptionResolvers(ParserContext parserContext, @Nullable Object source) {
RootBeanDefinition annotationResolverDef = createBeanDefinition(SoapFaultAnnotationExceptionResolver.class,
source);
annotationResolverDef.getPropertyValues().add("order", 0);
@@ -197,14 +198,15 @@ class AnnotationDrivenBeanDefinitionParser implements BeanDefinitionParser {
parserContext.getReaderContext().registerWithGeneratedName(simpleResolverDef);
}
private RuntimeBeanReference createBeanReference(Class<?> beanClass, Object source, ParserContext parserContext) {
private RuntimeBeanReference createBeanReference(ParserContext parserContext, Class<?> beanClass,
@Nullable Object source) {
RootBeanDefinition beanDefinition = createBeanDefinition(beanClass, source);
String beanName = parserContext.getReaderContext().registerWithGeneratedName(beanDefinition);
parserContext.registerComponent(new BeanComponentDefinition(beanDefinition, beanName));
return new RuntimeBeanReference(beanName);
}
private RootBeanDefinition createBeanDefinition(Class<?> beanClass, Object source) {
private RootBeanDefinition createBeanDefinition(Class<?> beanClass, @Nullable Object source) {
RootBeanDefinition beanDefinition = new RootBeanDefinition(beanClass);
beanDefinition.setSource(source);
beanDefinition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);

View File

@@ -18,6 +18,7 @@ package org.springframework.ws.config;
import java.util.List;
import org.jspecify.annotations.Nullable;
import org.w3c.dom.Element;
import org.springframework.beans.factory.config.BeanDefinition;
@@ -98,7 +99,7 @@ class DynamicWsdlBeanDefinitionParser extends AbstractBeanDefinitionParser {
}
}
private RootBeanDefinition createBeanDefinition(Class<?> beanClass, Object source) {
private RootBeanDefinition createBeanDefinition(Class<?> beanClass, @Nullable Object source) {
RootBeanDefinition beanDefinition = new RootBeanDefinition(beanClass);
beanDefinition.setSource(source);
beanDefinition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);

View File

@@ -18,6 +18,7 @@ package org.springframework.ws.config;
import java.util.List;
import org.jspecify.annotations.Nullable;
import org.w3c.dom.Element;
import org.springframework.beans.factory.config.BeanDefinition;
@@ -29,6 +30,7 @@ import org.springframework.beans.factory.parsing.CompositeComponentDefinition;
import org.springframework.beans.factory.support.RootBeanDefinition;
import org.springframework.beans.factory.xml.BeanDefinitionParser;
import org.springframework.beans.factory.xml.ParserContext;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;
import org.springframework.util.xml.DomUtils;
import org.springframework.ws.server.SmartEndpointInterceptor;
@@ -45,7 +47,7 @@ import org.springframework.ws.soap.server.endpoint.interceptor.SoapActionSmartEn
class InterceptorsBeanDefinitionParser implements BeanDefinitionParser {
@Override
public BeanDefinition parse(Element element, ParserContext parserContext) {
public @Nullable BeanDefinition parse(Element element, ParserContext parserContext) {
CompositeComponentDefinition compDefinition = new CompositeComponentDefinition(element.getTagName(),
parserContext.extractSource(element));
parserContext.pushContainingComponent(compDefinition);
@@ -149,11 +151,12 @@ class InterceptorsBeanDefinitionParser implements BeanDefinitionParser {
private BeanDefinitionHolder createInterceptorDefinition(ParserContext parserContext, Element element) {
BeanDefinitionHolder interceptorDef = parserContext.getDelegate().parseBeanDefinitionElement(element);
Assert.notNull(interceptorDef, "No interceptor definition found for element [" + element + "]");
interceptorDef = parserContext.getDelegate().decorateBeanDefinitionIfRequired(element, interceptorDef);
return interceptorDef;
}
private BeanReference createInterceptorReference(ParserContext parserContext, Element element) {
private @Nullable BeanReference createInterceptorReference(ParserContext parserContext, Element element) {
// A generic reference to any name of any bean.
String refName = element.getAttribute("bean");
if (!StringUtils.hasLength(refName)) {

View File

@@ -20,6 +20,8 @@ import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import org.jspecify.annotations.Nullable;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.Ordered;
@@ -79,7 +81,7 @@ import org.springframework.ws.soap.server.endpoint.mapping.SoapActionAnnotationM
*/
public class WsConfigurationSupport {
private List<EndpointInterceptor> interceptors;
private @Nullable List<EndpointInterceptor> interceptors;
/**
* Returns a {@link PayloadRootAnnotationMethodEndpointMapping} ordered at 0 for

View File

@@ -17,4 +17,7 @@
/**
* Annotations and supporting classes for declarative configuration.
*/
@NullMarked
package org.springframework.ws.config.annotation;
import org.jspecify.annotations.NullMarked;

View File

@@ -17,4 +17,7 @@
/**
* Provide a namespace handler for the Spring Web Services namespace.
*/
@NullMarked
package org.springframework.ws.config;
import org.jspecify.annotations.NullMarked;

View File

@@ -19,6 +19,8 @@ package org.springframework.ws.context;
import java.util.HashMap;
import java.util.Map;
import org.jspecify.annotations.Nullable;
import org.springframework.util.StringUtils;
/**
@@ -33,7 +35,7 @@ public abstract class AbstractMessageContext implements MessageContext {
* Keys are {@code Strings}, values are {@code Objects}. Lazily initialized by
* {@code getProperties()}.
*/
private Map<String, Object> properties;
private @Nullable Map<String, Object> properties;
@Override
public boolean containsProperty(String name) {
@@ -41,7 +43,7 @@ public abstract class AbstractMessageContext implements MessageContext {
}
@Override
public Object getProperty(String name) {
public @Nullable Object getProperty(String name) {
return getProperties().get(name);
}

View File

@@ -19,6 +19,8 @@ package org.springframework.ws.context;
import java.io.IOException;
import java.io.InputStream;
import org.jspecify.annotations.Nullable;
import org.springframework.util.Assert;
import org.springframework.ws.WebServiceMessage;
import org.springframework.ws.WebServiceMessageFactory;
@@ -35,7 +37,7 @@ public class DefaultMessageContext extends AbstractMessageContext {
private final WebServiceMessage request;
private WebServiceMessage response;
private @Nullable WebServiceMessage response;
/**
* Construct a new, empty instance of the {@code DefaultMessageContext} with the given
@@ -75,7 +77,7 @@ public class DefaultMessageContext extends AbstractMessageContext {
}
@Override
public void setResponse(WebServiceMessage response) {
public void setResponse(@Nullable WebServiceMessage response) {
checkForResponse();
this.response = response;
}

View File

@@ -19,6 +19,8 @@ package org.springframework.ws.context;
import java.io.IOException;
import java.io.InputStream;
import org.jspecify.annotations.Nullable;
import org.springframework.ws.WebServiceMessage;
import org.springframework.ws.server.EndpointInterceptor;
@@ -61,7 +63,7 @@ public interface MessageContext {
* @throws IllegalStateException if a response has already been created
* @since 1.5.0
*/
void setResponse(WebServiceMessage response);
void setResponse(@Nullable WebServiceMessage response);
/**
* Removes the response message, if any.
@@ -91,7 +93,7 @@ public interface MessageContext {
* @param name name of the property whose value is to be retrieved
* @return value of the property
*/
Object getProperty(String name);
@Nullable Object getProperty(String name);
/**
* Removes a property from the {@code MessageContext}.

View File

@@ -17,4 +17,7 @@
/**
* Contains the {@code MessageContext} interface and implementations thereof.
*/
@NullMarked
package org.springframework.ws.context;
import org.jspecify.annotations.NullMarked;

View File

@@ -93,7 +93,7 @@ public abstract class AbstractMimeMessage implements MimeMessage {
@Override
public String getName() {
if (this.inputStreamSource instanceof Resource resource) {
if (this.inputStreamSource instanceof Resource resource && resource.getFilename() != null) {
return resource.getFilename();
}
else {

View File

@@ -20,6 +20,7 @@ import java.io.File;
import java.util.Iterator;
import jakarta.activation.DataHandler;
import org.jspecify.annotations.Nullable;
import org.springframework.core.io.InputStreamSource;
import org.springframework.ws.WebServiceMessage;
@@ -58,7 +59,7 @@ public interface MimeMessage extends WebServiceMessage {
* be found
* @throws AttachmentException in case of errors
*/
Attachment getAttachment(String contentId) throws AttachmentException;
@Nullable Attachment getAttachment(String contentId) throws AttachmentException;
/**
* Returns an {@code Iterator} over all {@link Attachment} objects that are part of

View File

@@ -18,4 +18,7 @@
* Provides MIME functionality for use the Spring Web Services framework. Contains the
* Attachment and MimeMessage and related interfaces.
*/
@NullMarked
package org.springframework.ws.mime;
import org.jspecify.annotations.NullMarked;

View File

@@ -17,4 +17,7 @@
/**
* Provides the core functionality of the Spring Web Services framework.
*/
@NullMarked
package org.springframework.ws;
import org.jspecify.annotations.NullMarked;

View File

@@ -17,4 +17,7 @@
/**
* Contains an implementation of the POX interfaces that is based on DOM.
*/
@NullMarked
package org.springframework.ws.pox.dom;
import org.jspecify.annotations.NullMarked;

View File

@@ -18,4 +18,7 @@
* Provides the Plain Old XML (POX) functionality of the Spring Web Services framework.
* Contains the PoxMessage and related interfaces.
*/
@NullMarked
package org.springframework.ws.pox;
import org.jspecify.annotations.NullMarked;

View File

@@ -16,6 +16,8 @@
package org.springframework.ws.server;
import org.jspecify.annotations.Nullable;
import org.springframework.ws.context.MessageContext;
/**
@@ -35,6 +37,6 @@ public interface EndpointExceptionResolver {
* @param ex the exception that got thrown during endpoint execution
* @return {@code true} if resolved; {@code false} otherwise
*/
boolean resolveException(MessageContext messageContext, Object endpoint, Exception ex);
boolean resolveException(MessageContext messageContext, @Nullable Object endpoint, Exception ex);
}

View File

@@ -16,6 +16,8 @@
package org.springframework.ws.server;
import org.jspecify.annotations.Nullable;
import org.springframework.ws.context.MessageContext;
/**
@@ -125,6 +127,6 @@ public interface EndpointInterceptor {
* @throws Exception in case of errors
* @since 2.0.2
*/
void afterCompletion(MessageContext messageContext, Object endpoint, Exception ex) throws Exception;
void afterCompletion(MessageContext messageContext, Object endpoint, @Nullable Exception ex) throws Exception;
}

View File

@@ -16,6 +16,8 @@
package org.springframework.ws.server;
import org.jspecify.annotations.Nullable;
/**
* Endpoint invocation chain, consisting of an endpoint object and any preprocessing
* interceptors.
@@ -28,7 +30,7 @@ public class EndpointInvocationChain {
private final Object endpoint;
private EndpointInterceptor[] interceptors;
private EndpointInterceptor @Nullable [] interceptors;
/**
* Create new {@code EndpointInvocationChain}.
@@ -43,7 +45,7 @@ public class EndpointInvocationChain {
* @param endpoint the endpoint object to invoke
* @param interceptors the array of interceptors to apply
*/
public EndpointInvocationChain(Object endpoint, EndpointInterceptor[] interceptors) {
public EndpointInvocationChain(Object endpoint, EndpointInterceptor @Nullable [] interceptors) {
this.endpoint = endpoint;
this.interceptors = interceptors;
}
@@ -60,7 +62,7 @@ public class EndpointInvocationChain {
* Returns the array of interceptors to apply before the handler executes.
* @return the array of interceptors
*/
public EndpointInterceptor[] getInterceptors() {
public EndpointInterceptor @Nullable [] getInterceptors() {
return this.interceptors;
}

View File

@@ -16,6 +16,8 @@
package org.springframework.ws.server;
import org.jspecify.annotations.Nullable;
import org.springframework.ws.context.MessageContext;
/**
@@ -57,6 +59,6 @@ public interface EndpointMapping {
* interceptors, or {@code null} if no mapping is found
* @throws Exception if there is an internal error
*/
EndpointInvocationChain getEndpoint(MessageContext messageContext) throws Exception;
@Nullable EndpointInvocationChain getEndpoint(MessageContext messageContext) throws Exception;
}

View File

@@ -25,6 +25,7 @@ import java.util.Map;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.jspecify.annotations.Nullable;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanFactoryUtils;
@@ -103,15 +104,19 @@ public class MessageDispatcher implements WebServiceMessageReceiver, BeanNameAwa
private final DefaultStrategiesHelper defaultStrategiesHelper;
/** The registered bean name for this dispatcher. */
@SuppressWarnings("NullAway.Init")
private String beanName;
/** List of EndpointAdapters used in this dispatcher. */
@SuppressWarnings("NullAway.Init")
private List<EndpointAdapter> endpointAdapters;
/** List of EndpointExceptionResolvers used in this dispatcher. */
@SuppressWarnings("NullAway.Init")
private List<EndpointExceptionResolver> endpointExceptionResolvers;
/** List of EndpointMappings used in this dispatcher. */
@SuppressWarnings("NullAway.Init")
private List<EndpointMapping> endpointMappings;
/** Initializes a new instance of the {@code MessageDispatcher}. */
@@ -231,8 +236,8 @@ public class MessageDispatcher implements WebServiceMessageReceiver, BeanNameAwa
EndpointInterceptor interceptor = mappedEndpoint.getInterceptors()[i];
interceptorIndex = i;
if (!interceptor.handleRequest(messageContext, mappedEndpoint.getEndpoint())) {
triggerHandleResponse(mappedEndpoint, interceptorIndex, messageContext);
triggerAfterCompletion(mappedEndpoint, interceptorIndex, messageContext, null);
triggerHandleResponse(messageContext, mappedEndpoint, interceptorIndex);
triggerAfterCompletion(messageContext, mappedEndpoint, interceptorIndex, null);
return;
}
}
@@ -242,7 +247,7 @@ public class MessageDispatcher implements WebServiceMessageReceiver, BeanNameAwa
endpointAdapter.invoke(messageContext, mappedEndpoint.getEndpoint());
// Apply handleResponse methods of registered interceptors
triggerHandleResponse(mappedEndpoint, interceptorIndex, messageContext);
triggerHandleResponse(messageContext, mappedEndpoint, interceptorIndex);
}
catch (NoEndpointFoundException ex) {
// No triggering of interceptors if no endpoint is found
@@ -254,16 +259,16 @@ public class MessageDispatcher implements WebServiceMessageReceiver, BeanNameAwa
catch (Exception ex) {
Object endpoint = (mappedEndpoint != null) ? mappedEndpoint.getEndpoint() : null;
processEndpointException(messageContext, endpoint, ex);
triggerHandleResponse(mappedEndpoint, interceptorIndex, messageContext);
triggerHandleResponse(messageContext, mappedEndpoint, interceptorIndex);
}
triggerAfterCompletion(mappedEndpoint, interceptorIndex, messageContext, null);
triggerAfterCompletion(messageContext, mappedEndpoint, interceptorIndex, null);
}
catch (NoEndpointFoundException ex) {
throw ex;
}
catch (Exception ex) {
// Trigger after-completion for thrown exception.
triggerAfterCompletion(mappedEndpoint, interceptorIndex, messageContext, ex);
triggerAfterCompletion(messageContext, mappedEndpoint, interceptorIndex, ex);
throw ex;
}
}
@@ -273,7 +278,7 @@ public class MessageDispatcher implements WebServiceMessageReceiver, BeanNameAwa
* @return the {@code EndpointInvocationChain}, or {@code null} if no endpoint could
* be found.
*/
protected EndpointInvocationChain getEndpoint(MessageContext messageContext) throws Exception {
protected @Nullable EndpointInvocationChain getEndpoint(MessageContext messageContext) throws Exception {
for (EndpointMapping endpointMapping : getEndpointMappings()) {
EndpointInvocationChain endpoint = endpointMapping.getEndpoint(messageContext);
if (endpoint != null) {
@@ -331,7 +336,7 @@ public class MessageDispatcher implements WebServiceMessageReceiver, BeanNameAwa
* @param ex the exception that got thrown during handler execution
* @throws Exception if no suitable resolver is found
*/
protected void processEndpointException(MessageContext messageContext, Object endpoint, Exception ex)
protected void processEndpointException(MessageContext messageContext, @Nullable Object endpoint, Exception ex)
throws Exception {
if (!CollectionUtils.isEmpty(getEndpointExceptionResolvers())) {
for (EndpointExceptionResolver resolver : getEndpointExceptionResolvers()) {
@@ -351,14 +356,14 @@ public class MessageDispatcher implements WebServiceMessageReceiver, BeanNameAwa
* Trigger handleResponse or handleFault on the mapped EndpointInterceptors. Will just
* invoke said method on all interceptors whose handleRequest invocation returned
* {@code true}, in addition to the last interceptor who returned {@code false}.
* @param messageContext the message context, whose request and response are filled
* @param mappedEndpoint the mapped EndpointInvocationChain
* @param interceptorIndex index of last interceptor that was called
* @param messageContext the message context, whose request and response are filled
* @see EndpointInterceptor#handleResponse(MessageContext,Object)
* @see EndpointInterceptor#handleResponse(MessageContext, Object)
* @see EndpointInterceptor#handleFault(MessageContext, Object)
*/
private void triggerHandleResponse(EndpointInvocationChain mappedEndpoint, int interceptorIndex,
MessageContext messageContext) throws Exception {
private void triggerHandleResponse(MessageContext messageContext, @Nullable EndpointInvocationChain mappedEndpoint,
int interceptorIndex) throws Exception {
if (mappedEndpoint != null && messageContext.hasResponse()
&& !ObjectUtils.isEmpty(mappedEndpoint.getInterceptors())) {
boolean hasFault = false;
@@ -389,8 +394,8 @@ public class MessageDispatcher implements WebServiceMessageReceiver, BeanNameAwa
* @param ex exception thrown on handler execution, or {@code null} if none
* @see EndpointInterceptor#afterCompletion
*/
private void triggerAfterCompletion(EndpointInvocationChain mappedEndpoint, int interceptorIndex,
MessageContext messageContext, Exception ex) throws Exception {
private void triggerAfterCompletion(MessageContext messageContext, @Nullable EndpointInvocationChain mappedEndpoint,
int interceptorIndex, @Nullable Exception ex) throws Exception {
// Apply afterCompletion methods of registered interceptors.
if (mappedEndpoint != null) {

View File

@@ -20,6 +20,7 @@ import java.util.Set;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.jspecify.annotations.Nullable;
import org.springframework.core.Ordered;
import org.springframework.ws.context.MessageContext;
@@ -41,9 +42,9 @@ public abstract class AbstractEndpointExceptionResolver implements EndpointExcep
private int order = Integer.MAX_VALUE; // default: same as non-Ordered
private Set<?> mappedEndpoints;
private @Nullable Set<?> mappedEndpoints;
private Log warnLogger;
private @Nullable Log warnLogger;
/**
* Specify the set of endpoints that this exception resolver should map.
@@ -94,7 +95,7 @@ public abstract class AbstractEndpointExceptionResolver implements EndpointExcep
* @see #resolveExceptionInternal(MessageContext, Object, Exception)
*/
@Override
public final boolean resolveException(MessageContext messageContext, Object endpoint, Exception ex) {
public final boolean resolveException(MessageContext messageContext, @Nullable Object endpoint, Exception ex) {
Object mappedEndpoint = (endpoint instanceof MethodEndpoint methodEndpoint) ? methodEndpoint.getBean()
: endpoint;
if (this.mappedEndpoints != null && !this.mappedEndpoints.contains(mappedEndpoint)) {
@@ -105,7 +106,7 @@ public abstract class AbstractEndpointExceptionResolver implements EndpointExcep
}
boolean resolved = resolveExceptionInternal(messageContext, endpoint, ex);
if (resolved) {
logException(ex, messageContext);
logException(messageContext, ex);
}
return resolved;
}
@@ -116,39 +117,40 @@ public abstract class AbstractEndpointExceptionResolver implements EndpointExcep
* <p>
* Calls {@link #buildLogMessage} in order to determine the concrete message to log.
* Always passes the full exception to the logger.
* @param ex the exception that got thrown during handler execution
* @param messageContext current message context request
* @param ex the exception that got thrown during handler execution
* @see #setWarnLogCategory
* @see #buildLogMessage
* @see org.apache.commons.logging.Log#warn(Object, Throwable)
*/
protected void logException(Exception ex, MessageContext messageContext) {
protected void logException(MessageContext messageContext, Exception ex) {
if (this.warnLogger != null && this.warnLogger.isWarnEnabled()) {
this.warnLogger.warn(buildLogMessage(ex, messageContext), ex);
this.warnLogger.warn(buildLogMessage(messageContext, ex), ex);
}
}
/**
* Build a log message for the given exception, occured during processing the given
* message context.
* @param ex the exception that got thrown during handler execution
* @param messageContext the message context
* @param ex the exception that got thrown during handler execution
* @return the log message to use
*/
protected String buildLogMessage(Exception ex, MessageContext messageContext) {
protected String buildLogMessage(MessageContext messageContext, Exception ex) {
return "Endpoint execution resulted in exception";
}
/**
* Template method for resolving exceptions that is called by
* {@link #resolveException}.
* {@link EndpointExceptionResolver#resolveException}.
* @param messageContext current message context
* @param endpoint the executed endpoint, or {@code null} if none chosen at the time
* of the exception
* @param ex the exception that got thrown during endpoint execution
* @return {@code true} if resolved; {@code false} otherwise
* @see #resolveException(MessageContext, Object, Exception)
* @see EndpointExceptionResolver#resolveException(MessageContext, Object, Exception)
*/
protected abstract boolean resolveExceptionInternal(MessageContext messageContext, Object endpoint, Exception ex);
protected abstract boolean resolveExceptionInternal(MessageContext messageContext, @Nullable Object endpoint,
Exception ex);
}

View File

@@ -27,6 +27,7 @@ import javax.xml.transform.stream.StreamResult;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.jspecify.annotations.Nullable;
import org.springframework.ws.WebServiceMessage;
import org.springframework.ws.context.MessageContext;
@@ -116,7 +117,7 @@ public abstract class AbstractLoggingInterceptor extends TransformerObjectSuppor
* Does nothing by default.
*/
@Override
public void afterCompletion(MessageContext messageContext, Object endpoint, Exception ex) {
public void afterCompletion(MessageContext messageContext, Object endpoint, @Nullable Exception ex) {
}
/**
@@ -146,7 +147,7 @@ public abstract class AbstractLoggingInterceptor extends TransformerObjectSuppor
* @param source the source to be logged
* @throws TransformerException in case of errors
*/
protected void logMessageSource(String logMessage, Source source) throws TransformerException {
protected void logMessageSource(String logMessage, @Nullable Source source) throws TransformerException {
if (source != null) {
Transformer transformer = createNonIndentingTransformer();
StringWriter writer = new StringWriter();
@@ -173,6 +174,6 @@ public abstract class AbstractLoggingInterceptor extends TransformerObjectSuppor
* @param message the message
* @return the source of the message
*/
protected abstract Source getSource(WebServiceMessage message);
protected abstract @Nullable Source getSource(WebServiceMessage message);
}

View File

@@ -16,6 +16,8 @@
package org.springframework.ws.server.endpoint;
import org.jspecify.annotations.Nullable;
import org.springframework.ws.context.MessageContext;
import org.springframework.ws.server.EndpointExceptionResolver;
@@ -35,7 +37,7 @@ public class CompositeEndpointExceptionResolver implements EndpointExceptionReso
}
@Override
public final boolean resolveException(MessageContext messageContext, Object endpoint, Exception ex) {
public final boolean resolveException(MessageContext messageContext, @Nullable Object endpoint, Exception ex) {
AbstractEndpointExceptionResolver currentResolver = null;
for (AbstractEndpointExceptionResolver resolver : this.resolvers) {
currentResolver = resolver;
@@ -44,7 +46,7 @@ public class CompositeEndpointExceptionResolver implements EndpointExceptionReso
}
}
if (currentResolver != null) {
currentResolver.logException(ex, messageContext);
currentResolver.logException(messageContext, ex);
}
return false;
}

View File

@@ -19,6 +19,8 @@ package org.springframework.ws.server.endpoint;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import org.jspecify.annotations.Nullable;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.core.MethodParameter;
import org.springframework.util.Assert;
@@ -39,7 +41,7 @@ public final class MethodEndpoint {
private final Method method;
private final BeanFactory beanFactory;
private final @Nullable BeanFactory beanFactory;
/**
* Constructs a new method endpoint with the given bean and method.

View File

@@ -18,6 +18,8 @@ package org.springframework.ws.server.endpoint;
import javax.xml.transform.Source;
import org.jspecify.annotations.Nullable;
/**
* Defines the basic contract for Web Services interested in just the message payload.
* <p>
@@ -37,6 +39,6 @@ public interface PayloadEndpoint {
* response
* @throws Exception if an exception occurs
*/
Source invoke(Source request) throws Exception;
@Nullable Source invoke(@Nullable Source request) throws Exception;
}

View File

@@ -20,6 +20,8 @@ import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import org.jspecify.annotations.Nullable;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.BeanClassLoaderAware;
import org.springframework.beans.factory.InitializingBean;
@@ -66,11 +68,13 @@ public class DefaultMethodEndpointAdapter extends AbstractMethodEndpointAdapter
private static final String SOAP_HEADER_ELEMENT_ARGUMENT_RESOLVER_CLASS_NAME = "org.springframework.ws.soap.server.endpoint.adapter.method.SoapHeaderElementMethodArgumentResolver";
@SuppressWarnings("NullAway.Init")
private List<MethodArgumentResolver> methodArgumentResolvers;
@SuppressWarnings("NullAway.Init")
private List<MethodReturnValueHandler> methodReturnValueHandlers;
private ClassLoader classLoader;
private @Nullable ClassLoader classLoader;
/**
* Create a new instance with default method argument and return value resolvers.
@@ -247,7 +251,7 @@ public class DefaultMethodEndpointAdapter extends AbstractMethodEndpointAdapter
@Override
protected final void invokeInternal(MessageContext messageContext, MethodEndpoint methodEndpoint) throws Exception {
Object[] args = getMethodArguments(messageContext, methodEndpoint);
@Nullable Object[] args = getMethodArguments(messageContext, methodEndpoint);
if (this.logger.isTraceEnabled()) {
this.logger.trace("Invoking [" + methodEndpoint + "] with arguments " + Arrays.asList(args));
@@ -276,10 +280,10 @@ public class DefaultMethodEndpointAdapter extends AbstractMethodEndpointAdapter
* @return the arguments
* @throws Exception in case of errors
*/
protected Object[] getMethodArguments(MessageContext messageContext, MethodEndpoint methodEndpoint)
protected @Nullable Object[] getMethodArguments(MessageContext messageContext, MethodEndpoint methodEndpoint)
throws Exception {
MethodParameter[] parameters = methodEndpoint.getMethodParameters();
Object[] args = new Object[parameters.length];
@Nullable Object[] args = new Object[parameters.length];
for (int i = 0; i < parameters.length; i++) {
for (MethodArgumentResolver methodArgumentResolver : this.methodArgumentResolvers) {
if (methodArgumentResolver.supportsParameter(parameters[i])) {

View File

@@ -18,6 +18,8 @@ package org.springframework.ws.server.endpoint.adapter.method;
import javax.xml.transform.Source;
import org.jspecify.annotations.Nullable;
import org.springframework.core.MethodParameter;
import org.springframework.ws.WebServiceMessage;
import org.springframework.ws.context.MessageContext;
@@ -35,15 +37,15 @@ public abstract class AbstractPayloadSourceMethodProcessor extends AbstractPaylo
// MethodArgumentResolver
@Override
public final Object resolveArgument(MessageContext messageContext, MethodParameter parameter) throws Exception {
public final @Nullable Object resolveArgument(MessageContext messageContext, MethodParameter parameter)
throws Exception {
Source requestPayload = getRequestPayload(messageContext);
return (requestPayload != null) ? resolveRequestPayloadArgument(parameter, requestPayload) : null;
}
/** Returns the request payload as {@code Source}. */
private Source getRequestPayload(MessageContext messageContext) {
WebServiceMessage request = messageContext.getRequest();
return (request != null) ? request.getPayloadSource() : null;
private @Nullable Source getRequestPayload(MessageContext messageContext) {
return messageContext.getRequest().getPayloadSource();
}
/**
@@ -60,14 +62,12 @@ public abstract class AbstractPayloadSourceMethodProcessor extends AbstractPaylo
// MethodReturnValueHandler
@Override
public final void handleReturnValue(MessageContext messageContext, MethodParameter returnType, Object returnValue)
throws Exception {
public final void handleReturnValue(MessageContext messageContext, MethodParameter returnType,
@Nullable Object returnValue) throws Exception {
if (returnValue != null) {
Source responsePayload = createResponsePayload(returnType, returnValue);
if (responsePayload != null) {
WebServiceMessage response = messageContext.getResponse();
transform(responsePayload, response.getPayloadResult());
}
WebServiceMessage response = messageContext.getResponse();
transform(responsePayload, response.getPayloadResult());
}
}

View File

@@ -16,6 +16,8 @@
package org.springframework.ws.server.endpoint.adapter.method;
import org.jspecify.annotations.Nullable;
import org.springframework.core.MethodParameter;
import org.springframework.oxm.GenericMarshaller;
import org.springframework.oxm.GenericUnmarshaller;
@@ -35,9 +37,9 @@ import org.springframework.ws.support.MarshallingUtils;
*/
public class MarshallingPayloadMethodProcessor extends AbstractPayloadMethodProcessor {
private Marshaller marshaller;
private @Nullable Marshaller marshaller;
private Unmarshaller unmarshaller;
private @Nullable Unmarshaller unmarshaller;
/**
* Creates a new {@code MarshallingPayloadMethodProcessor}. The {@link Marshaller} and
@@ -83,7 +85,7 @@ public class MarshallingPayloadMethodProcessor extends AbstractPayloadMethodProc
/**
* Returns the marshaller used for transforming objects into XML.
*/
public Marshaller getMarshaller() {
public @Nullable Marshaller getMarshaller() {
return this.marshaller;
}
@@ -97,7 +99,7 @@ public class MarshallingPayloadMethodProcessor extends AbstractPayloadMethodProc
/**
* Returns the unmarshaller used for transforming XML into objects.
*/
public Unmarshaller getUnmarshaller() {
public @Nullable Unmarshaller getUnmarshaller() {
return this.unmarshaller;
}
@@ -123,7 +125,7 @@ public class MarshallingPayloadMethodProcessor extends AbstractPayloadMethodProc
}
@Override
public Object resolveArgument(MessageContext messageContext, MethodParameter parameter) throws Exception {
public @Nullable Object resolveArgument(MessageContext messageContext, MethodParameter parameter) throws Exception {
Unmarshaller unmarshaller = getUnmarshaller();
Assert.state(unmarshaller != null, "unmarshaller must not be null");
@@ -150,8 +152,8 @@ public class MarshallingPayloadMethodProcessor extends AbstractPayloadMethodProc
}
@Override
public void handleReturnValue(MessageContext messageContext, MethodParameter returnType, Object returnValue)
throws Exception {
public void handleReturnValue(MessageContext messageContext, MethodParameter returnType,
@Nullable Object returnValue) throws Exception {
if (returnValue == null) {
return;
}

View File

@@ -16,6 +16,8 @@
package org.springframework.ws.server.endpoint.adapter.method;
import org.jspecify.annotations.Nullable;
import org.springframework.core.MethodParameter;
import org.springframework.ws.context.MessageContext;
@@ -48,6 +50,6 @@ public interface MethodArgumentResolver {
* @return the resolved argument. May be {@code null}.
* @throws Exception in case of errors
*/
Object resolveArgument(MessageContext messageContext, MethodParameter parameter) throws Exception;
@Nullable Object resolveArgument(MessageContext messageContext, MethodParameter parameter) throws Exception;
}

View File

@@ -16,6 +16,8 @@
package org.springframework.ws.server.endpoint.adapter.method;
import org.jspecify.annotations.Nullable;
import org.springframework.core.MethodParameter;
import org.springframework.ws.context.MessageContext;
@@ -47,7 +49,7 @@ public interface MethodReturnValueHandler {
* @param returnValue the return value to handle
* @throws Exception in case of errors
*/
void handleReturnValue(MessageContext messageContext, MethodParameter returnType, Object returnValue)
void handleReturnValue(MessageContext messageContext, MethodParameter returnType, @Nullable Object returnValue)
throws Exception;
}

View File

@@ -30,6 +30,7 @@ import javax.xml.transform.sax.SAXSource;
import javax.xml.transform.stax.StAXSource;
import javax.xml.transform.stream.StreamSource;
import org.jspecify.annotations.Nullable;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.xml.sax.InputSource;
@@ -166,7 +167,7 @@ public class SourcePayloadMethodProcessor extends AbstractPayloadSourceMethodPro
return (parentLocation != null) ? parentLocation.getLineNumber() : -1;
}
public String getPublicId() {
public @Nullable String getPublicId() {
return (parentLocation != null) ? parentLocation.getPublicId() : null;
}

View File

@@ -27,6 +27,8 @@ import javax.xml.transform.Source;
import javax.xml.transform.TransformerException;
import javax.xml.transform.stream.StreamResult;
import org.jspecify.annotations.Nullable;
import org.springframework.core.MethodParameter;
import org.springframework.util.xml.StaxUtils;
import org.springframework.ws.context.MessageContext;
@@ -57,7 +59,7 @@ public class StaxPayloadMethodArgumentResolver extends TransformerObjectSupport
}
@Override
public Object resolveArgument(MessageContext messageContext, MethodParameter parameter)
public @Nullable Object resolveArgument(MessageContext messageContext, MethodParameter parameter)
throws TransformerException, XMLStreamException {
Source source = messageContext.getRequest().getPayloadSource();
if (source == null) {

View File

@@ -16,6 +16,8 @@
package org.springframework.ws.server.endpoint.adapter.method;
import java.lang.reflect.Method;
import javax.xml.namespace.QName;
import javax.xml.transform.Source;
import javax.xml.transform.TransformerException;
@@ -25,6 +27,7 @@ import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathExpressionException;
import javax.xml.xpath.XPathFactory;
import org.jspecify.annotations.Nullable;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
@@ -33,6 +36,7 @@ import org.w3c.dom.NodeList;
import org.springframework.core.MethodParameter;
import org.springframework.core.convert.ConversionService;
import org.springframework.core.convert.support.DefaultConversionService;
import org.springframework.util.Assert;
import org.springframework.ws.context.MessageContext;
import org.springframework.ws.server.endpoint.annotation.XPathParam;
import org.springframework.ws.server.endpoint.support.NamespaceUtils;
@@ -91,8 +95,10 @@ public class XPathParamMethodArgumentResolver implements MethodArgumentResolver
}
@Override
public Object resolveArgument(MessageContext messageContext, MethodParameter parameter)
public @Nullable Object resolveArgument(MessageContext messageContext, MethodParameter parameter)
throws TransformerException, XPathExpressionException {
Method method = parameter.getMethod();
Assert.notNull(method, "Method must not be null");
Class<?> parameterType = parameter.getParameterType();
QName evaluationReturnType = getReturnType(parameterType);
boolean useConversionService = false;
@@ -100,17 +106,20 @@ public class XPathParamMethodArgumentResolver implements MethodArgumentResolver
evaluationReturnType = XPathConstants.STRING;
useConversionService = true;
}
XPath xpath = createXPath();
xpath.setNamespaceContext(NamespaceUtils.getNamespaceContext(parameter.getMethod()));
xpath.setNamespaceContext(NamespaceUtils.getNamespaceContext(method));
Element rootElement = getRootElement(messageContext.getRequest().getPayloadSource());
String expression = parameter.getParameterAnnotation(XPathParam.class).value();
Source payloadSource = messageContext.getRequest().getPayloadSource();
Assert.notNull(payloadSource, "No payload source available");
Element rootElement = getRootElement(payloadSource);
XPathParam annotation = parameter.getParameterAnnotation(XPathParam.class);
Assert.state(annotation != null, "No @XPathParam annotation found");
String expression = annotation.value();
Object result = xpath.evaluate(expression, rootElement, evaluationReturnType);
return (useConversionService) ? this.conversionService.convert(result, parameterType) : result;
}
private QName getReturnType(Class<?> parameterType) {
private @Nullable QName getReturnType(Class<?> parameterType) {
if (Boolean.class.equals(parameterType) || Boolean.TYPE.equals(parameterType)) {
return XPathConstants.BOOLEAN;
}

View File

@@ -18,4 +18,7 @@
* Provides DOM-based implementations of the {@code MethodArgumentResolver} and
* {@code MethodReturnValueHandler} interfaces.
*/
@NullMarked
package org.springframework.ws.server.endpoint.adapter.method.dom;
import org.jspecify.annotations.NullMarked;

View File

@@ -44,6 +44,7 @@ import jakarta.xml.bind.JAXBIntrospector;
import jakarta.xml.bind.Marshaller;
import jakarta.xml.bind.Unmarshaller;
import jakarta.xml.bind.UnmarshallerHandler;
import org.jspecify.annotations.Nullable;
import org.w3c.dom.Node;
import org.xml.sax.ContentHandler;
import org.xml.sax.InputSource;
@@ -79,8 +80,8 @@ public abstract class AbstractJaxb2PayloadMethodProcessor extends AbstractPayloa
private final ConcurrentMap<Class<?>, JAXBContext> jaxbContexts = new ConcurrentHashMap<>();
@Override
public final void handleReturnValue(MessageContext messageContext, MethodParameter returnType, Object returnValue)
throws Exception {
public final void handleReturnValue(MessageContext messageContext, MethodParameter returnType,
@Nullable Object returnValue) throws Exception {
if (returnValue != null) {
handleReturnValueInternal(messageContext, returnType, returnValue);
}
@@ -130,7 +131,7 @@ public abstract class AbstractJaxb2PayloadMethodProcessor extends AbstractPayloa
* @return the unmarshalled object, or {@code null} if the request has no payload
* @throws JAXBException in case of JAXB2 errors
*/
protected final Object unmarshalFromRequestPayload(MessageContext messageContext, Class<?> clazz)
protected final @Nullable Object unmarshalFromRequestPayload(MessageContext messageContext, Class<?> clazz)
throws JAXBException {
Source requestPayload = getRequestPayload(messageContext);
if (requestPayload == null) {
@@ -156,8 +157,8 @@ public abstract class AbstractJaxb2PayloadMethodProcessor extends AbstractPayloa
* @return the unmarshalled element, or {@code null} if the request has no payload
* @throws JAXBException in case of JAXB2 errors
*/
protected final <T> JAXBElement<T> unmarshalElementFromRequestPayload(MessageContext messageContext, Class<T> clazz)
throws JAXBException {
protected final <T> @Nullable JAXBElement<T> unmarshalElementFromRequestPayload(MessageContext messageContext,
Class<T> clazz) throws JAXBException {
Source requestPayload = getRequestPayload(messageContext);
if (requestPayload == null) {
return null;
@@ -175,9 +176,8 @@ public abstract class AbstractJaxb2PayloadMethodProcessor extends AbstractPayloa
}
}
private Source getRequestPayload(MessageContext messageContext) {
WebServiceMessage request = messageContext.getRequest();
return (request != null) ? request.getPayloadSource() : null;
private @Nullable Source getRequestPayload(MessageContext messageContext) {
return messageContext.getRequest().getPayloadSource();
}
private JAXBException convertToJaxbException(Exception ex) {
@@ -237,7 +237,7 @@ public abstract class AbstractJaxb2PayloadMethodProcessor extends AbstractPayloa
private final Unmarshaller unmarshaller;
private Object result;
private @Nullable Object result;
Jaxb2SourceCallback(Class<?> clazz) throws JAXBException {
this.unmarshaller = createUnmarshaller(clazz);
@@ -307,7 +307,7 @@ public abstract class AbstractJaxb2PayloadMethodProcessor extends AbstractPayloa
private final Class<T> declaredType;
private JAXBElement<T> result;
private @Nullable JAXBElement<T> result;
JaxbElementSourceCallback(Class<T> declaredType) throws JAXBException {
this.unmarshaller = createUnmarshaller(declaredType);

View File

@@ -21,6 +21,7 @@ import java.lang.reflect.Type;
import jakarta.xml.bind.JAXBElement;
import jakarta.xml.bind.JAXBException;
import org.jspecify.annotations.Nullable;
import org.springframework.core.MethodParameter;
import org.springframework.ws.context.MessageContext;
@@ -45,7 +46,7 @@ public class JaxbElementPayloadMethodProcessor extends AbstractJaxb2PayloadMetho
}
@Override
public JAXBElement<?> resolveArgument(MessageContext messageContext, MethodParameter parameter)
public @Nullable JAXBElement<?> resolveArgument(MessageContext messageContext, MethodParameter parameter)
throws JAXBException {
ParameterizedType parameterizedType = (ParameterizedType) parameter.getGenericParameterType();
Class<?> clazz = (Class<?>) parameterizedType.getActualTypeArguments()[0];

View File

@@ -20,6 +20,7 @@ import jakarta.xml.bind.JAXBElement;
import jakarta.xml.bind.JAXBException;
import jakarta.xml.bind.annotation.XmlRootElement;
import jakarta.xml.bind.annotation.XmlType;
import org.jspecify.annotations.Nullable;
import org.springframework.core.MethodParameter;
import org.springframework.ws.context.MessageContext;
@@ -46,7 +47,8 @@ public class XmlRootElementPayloadMethodProcessor extends AbstractJaxb2PayloadMe
}
@Override
public Object resolveArgument(MessageContext messageContext, MethodParameter parameter) throws JAXBException {
public @Nullable Object resolveArgument(MessageContext messageContext, MethodParameter parameter)
throws JAXBException {
Class<?> parameterType = parameter.getParameterType();
if (parameterType.isAnnotationPresent(XmlRootElement.class)) {

View File

@@ -18,4 +18,7 @@
* Provides JAXB2-based implementations of the {@code MethodArgumentResolver} and
* {@code MethodReturnValueHandler} interfaces.
*/
@NullMarked
package org.springframework.ws.server.endpoint.adapter.method.jaxb;
import org.jspecify.annotations.NullMarked;

View File

@@ -18,4 +18,7 @@
* Provides the {@code MethodArgumentResolver} and {@code MethodReturnValueHandler}
* abstractions, and various implementations thereof.
*/
@NullMarked
package org.springframework.ws.server.endpoint.adapter.method;
import org.jspecify.annotations.NullMarked;

View File

@@ -17,4 +17,7 @@
/**
* Provides miscellaneous {@code EndpointAdapter} implementations.
*/
@NullMarked
package org.springframework.ws.server.endpoint.adapter;
import org.jspecify.annotations.NullMarked;

View File

@@ -17,4 +17,7 @@
/**
* JDK 1.5+ annotations for Spring-WS endpoints.
*/
@NullMarked
package org.springframework.ws.server.endpoint.annotation;
import org.jspecify.annotations.NullMarked;

View File

@@ -21,6 +21,7 @@ import java.io.IOException;
import javax.xml.transform.Source;
import javax.xml.transform.TransformerException;
import org.jspecify.annotations.Nullable;
import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;
@@ -60,15 +61,16 @@ public abstract class AbstractValidatingInterceptor extends TransformerObjectSup
private String schemaLanguage = XmlValidatorFactory.SCHEMA_W3C_XML;
private Resource[] schemas;
private Resource @Nullable [] schemas;
private boolean validateRequest = true;
private boolean validateResponse = false;
@SuppressWarnings("NullAway.Init")
private XmlValidator validator;
private ValidationErrorHandler errorHandler;
private @Nullable ValidationErrorHandler errorHandler;
public String getSchemaLanguage() {
return this.schemaLanguage;
@@ -87,7 +89,7 @@ public abstract class AbstractValidatingInterceptor extends TransformerObjectSup
/**
* Returns the schema resources to use for validation.
*/
public Resource[] getSchemas() {
public Resource @Nullable [] getSchemas() {
return this.schemas;
}
@@ -275,7 +277,7 @@ public abstract class AbstractValidatingInterceptor extends TransformerObjectSup
/** Does nothing by default. */
@Override
public void afterCompletion(MessageContext messageContext, Object endpoint, Exception ex) {
public void afterCompletion(MessageContext messageContext, Object endpoint, @Nullable Exception ex) {
}
/**
@@ -285,7 +287,7 @@ public abstract class AbstractValidatingInterceptor extends TransformerObjectSup
* @return the part of the message that is to validated, or {@code null} not to
* validate anything
*/
protected abstract Source getValidationRequestSource(WebServiceMessage request);
protected abstract @Nullable Source getValidationRequestSource(WebServiceMessage request);
/**
* Abstract template method that returns the part of the response message that is to
@@ -294,6 +296,6 @@ public abstract class AbstractValidatingInterceptor extends TransformerObjectSup
* @return the part of the message that is to validated, or {@code null} not to
* validate anything
*/
protected abstract Source getValidationResponseSource(WebServiceMessage response);
protected abstract @Nullable Source getValidationResponseSource(WebServiceMessage response);
}

View File

@@ -16,6 +16,8 @@
package org.springframework.ws.server.endpoint.interceptor;
import org.jspecify.annotations.Nullable;
import org.springframework.util.Assert;
import org.springframework.ws.WebServiceMessage;
import org.springframework.ws.context.MessageContext;
@@ -92,7 +94,8 @@ public class DelegatingSmartEndpointInterceptor implements SmartEndpointIntercep
}
@Override
public void afterCompletion(MessageContext messageContext, Object endpoint, Exception ex) throws Exception {
public void afterCompletion(MessageContext messageContext, Object endpoint, @Nullable Exception ex)
throws Exception {
getDelegate().afterCompletion(messageContext, endpoint, ex);
}

View File

@@ -18,6 +18,7 @@ package org.springframework.ws.server.endpoint.interceptor;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.jspecify.annotations.Nullable;
import org.w3c.dom.Element;
import org.springframework.ws.context.MessageContext;
@@ -75,7 +76,8 @@ public class EndpointInterceptorAdapter implements EndpointInterceptor {
* Does nothing by default.
*/
@Override
public void afterCompletion(MessageContext messageContext, Object endpoint, Exception ex) throws Exception {
public void afterCompletion(MessageContext messageContext, Object endpoint, @Nullable Exception ex)
throws Exception {
}
}

View File

@@ -18,6 +18,8 @@ package org.springframework.ws.server.endpoint.interceptor;
import javax.xml.transform.Source;
import org.jspecify.annotations.Nullable;
import org.springframework.ws.WebServiceMessage;
import org.springframework.ws.server.endpoint.AbstractLoggingInterceptor;
@@ -37,7 +39,7 @@ import org.springframework.ws.server.endpoint.AbstractLoggingInterceptor;
public class PayloadLoggingInterceptor extends AbstractLoggingInterceptor {
@Override
protected Source getSource(WebServiceMessage message) {
protected @Nullable Source getSource(WebServiceMessage message) {
return message.getPayloadSource();
}

View File

@@ -29,6 +29,7 @@ import javax.xml.transform.stream.StreamSource;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.jspecify.annotations.Nullable;
import org.xml.sax.XMLReader;
import org.springframework.beans.factory.InitializingBean;
@@ -61,13 +62,13 @@ public class PayloadTransformingInterceptor extends TransformerObjectSupport
private static final Log logger = LogFactory.getLog(PayloadTransformingInterceptor.class);
private Resource requestXslt;
private @Nullable Resource requestXslt;
private Resource responseXslt;
private @Nullable Resource responseXslt;
private Templates requestTemplates;
private @Nullable Templates requestTemplates;
private Templates responseTemplates;
private @Nullable Templates responseTemplates;
/** Sets the XSLT stylesheet to use for transforming incoming request. */
public void setRequestXslt(Resource requestXslt) {
@@ -130,7 +131,7 @@ public class PayloadTransformingInterceptor extends TransformerObjectSupport
/** Does nothing by default. */
@Override
public void afterCompletion(MessageContext messageContext, Object endpoint, Exception ex) {
public void afterCompletion(MessageContext messageContext, Object endpoint, @Nullable Exception ex) {
}
@Override

View File

@@ -17,4 +17,7 @@
/**
* Provides miscellaneous endpoints {@code EndpointInterceptor} implementations.
*/
@NullMarked
package org.springframework.ws.server.endpoint.interceptor;
import org.jspecify.annotations.NullMarked;

View File

@@ -20,7 +20,9 @@ import java.lang.annotation.Annotation;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanFactoryUtils;
import org.springframework.context.ApplicationContext;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.util.Assert;
import org.springframework.ws.server.endpoint.annotation.Endpoint;
/**
@@ -61,15 +63,17 @@ public abstract class AbstractAnnotationMethodEndpointMapping<T> extends Abstrac
@Override
protected void initApplicationContext() throws BeansException {
super.initApplicationContext();
ApplicationContext applicationContext = getApplicationContext();
Assert.notNull(applicationContext, "No ApplicationContext found");
if (this.logger.isDebugEnabled()) {
this.logger.debug("Looking for endpoints in application context: " + getApplicationContext());
this.logger.debug("Looking for endpoints in application context: " + applicationContext);
}
String[] beanNames = (this.detectEndpointsInAncestorContexts
? BeanFactoryUtils.beanNamesForTypeIncludingAncestors(getApplicationContext(), Object.class)
: getApplicationContext().getBeanNamesForType(Object.class));
? BeanFactoryUtils.beanNamesForTypeIncludingAncestors(applicationContext, Object.class)
: applicationContext.getBeanNamesForType(Object.class));
for (String beanName : beanNames) {
Class<?> endpointClass = getApplicationContext().getType(beanName);
Class<?> endpointClass = applicationContext.getType(beanName);
if (endpointClass != null
&& AnnotationUtils.findAnnotation(endpointClass, getEndpointAnnotationType()) != null) {
registerMethods(beanName);

View File

@@ -21,8 +21,11 @@ import java.util.Arrays;
import java.util.List;
import java.util.Map;
import org.jspecify.annotations.Nullable;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanFactoryUtils;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ApplicationObjectSupport;
import org.springframework.core.Ordered;
import org.springframework.ws.context.MessageContext;
@@ -44,18 +47,18 @@ public abstract class AbstractEndpointMapping extends ApplicationObjectSupport i
private int order = Integer.MAX_VALUE; // default: same as non-Ordered
private Object defaultEndpoint;
private @Nullable Object defaultEndpoint;
private EndpointInterceptor[] interceptors;
private EndpointInterceptor @Nullable [] interceptors;
private SmartEndpointInterceptor[] smartInterceptors;
private SmartEndpointInterceptor @Nullable [] smartInterceptors;
/**
* Returns the endpoint interceptors to apply to all endpoints mapped by this endpoint
* mapping.
* @return array of endpoint interceptors, or {@code null} if none
*/
public EndpointInterceptor[] getInterceptors() {
public EndpointInterceptor @Nullable [] getInterceptors() {
return this.interceptors;
}
@@ -98,7 +101,7 @@ public abstract class AbstractEndpointMapping extends ApplicationObjectSupport i
*/
protected void initInterceptors() {
Map<String, SmartEndpointInterceptor> smartInterceptors = BeanFactoryUtils
.beansOfTypeIncludingAncestors(getApplicationContext(), SmartEndpointInterceptor.class, true, false);
.beansOfTypeIncludingAncestors(obtainApplicationContext(), SmartEndpointInterceptor.class, true, false);
if (!smartInterceptors.isEmpty()) {
this.smartInterceptors = smartInterceptors.values().toArray(new SmartEndpointInterceptor[0]);
}
@@ -111,7 +114,7 @@ public abstract class AbstractEndpointMapping extends ApplicationObjectSupport i
* @see #getEndpointInternal(org.springframework.ws.context.MessageContext)
*/
@Override
public final EndpointInvocationChain getEndpoint(MessageContext messageContext) throws Exception {
public final @Nullable EndpointInvocationChain getEndpoint(MessageContext messageContext) throws Exception {
Object endpoint = resoleEndpoint(messageContext);
if (endpoint == null) {
return null;
@@ -131,7 +134,7 @@ public abstract class AbstractEndpointMapping extends ApplicationObjectSupport i
interceptors.toArray(new EndpointInterceptor[0]));
}
private Object resoleEndpoint(MessageContext messageContext) throws Exception {
private @Nullable Object resoleEndpoint(MessageContext messageContext) throws Exception {
Object endpoint = getEndpointInternal(messageContext);
if (endpoint == null) {
endpoint = this.defaultEndpoint;
@@ -141,9 +144,6 @@ public abstract class AbstractEndpointMapping extends ApplicationObjectSupport i
}
if (endpoint instanceof String endpointName) {
endpoint = resolveStringEndpoint(endpointName);
if (endpoint == null) {
return null;
}
}
return endpoint;
}
@@ -173,7 +173,7 @@ public abstract class AbstractEndpointMapping extends ApplicationObjectSupport i
* Returns the default endpoint for this endpoint mapping.
* @return the default endpoint mapping, or null if none
*/
protected final Object getDefaultEndpoint() {
protected final @Nullable Object getDefaultEndpoint() {
return this.defaultEndpoint;
}
@@ -194,9 +194,10 @@ public abstract class AbstractEndpointMapping extends ApplicationObjectSupport i
* @param endpointName the endpoint name
* @return the resolved endpoint, or {@code null} if the name could not be resolved
*/
protected Object resolveStringEndpoint(String endpointName) {
if (getApplicationContext().containsBean(endpointName)) {
return getApplicationContext().getBean(endpointName);
protected @Nullable Object resolveStringEndpoint(String endpointName) {
ApplicationContext applicationContext = obtainApplicationContext();
if (applicationContext.containsBean(endpointName)) {
return applicationContext.getBean(endpointName);
}
else {
return null;
@@ -214,6 +215,6 @@ public abstract class AbstractEndpointMapping extends ApplicationObjectSupport i
* @return the looked up endpoint instance, or null
* @throws Exception if there is an error
*/
protected abstract Object getEndpointInternal(MessageContext messageContext) throws Exception;
protected abstract @Nullable Object getEndpointInternal(MessageContext messageContext) throws Exception;
}

View File

@@ -20,8 +20,12 @@ import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
import org.jspecify.annotations.Nullable;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextException;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;
import org.springframework.ws.context.MessageContext;
@@ -42,10 +46,12 @@ public abstract class AbstractMapBasedEndpointMapping extends AbstractEndpointMa
private boolean registerBeanNames = false;
private boolean configured = false;
private final Map<String, Object> endpointMap = new HashMap<>();
// holds mappings set via setEndpointMap and setMappings
private Map<String, Object> temporaryEndpointMap = new HashMap<>();
private final Map<String, Object> temporaryEndpointMap = new HashMap<>();
/**
* Set whether to lazily initialize endpoints. Only applicable to singleton endpoints,
@@ -77,6 +83,7 @@ public abstract class AbstractMapBasedEndpointMapping extends AbstractEndpointMa
* @throws IllegalArgumentException if the endpoint is invalid
*/
public final void setEndpointMap(Map<String, Object> endpointMap) {
Assert.state(!this.configured, "Mappings have already been configured");
this.temporaryEndpointMap.putAll(endpointMap);
}
@@ -85,6 +92,7 @@ public abstract class AbstractMapBasedEndpointMapping extends AbstractEndpointMa
* exact subclass used. They can be qualified names, for instance, or mime headers.
*/
public void setMappings(Properties mappings) {
Assert.state(!this.configured, "Mappings have already been configured");
for (Map.Entry<Object, Object> entry : mappings.entrySet()) {
if (entry.getKey() instanceof String) {
this.temporaryEndpointMap.put((String) entry.getKey(), entry.getValue());
@@ -103,7 +111,7 @@ public abstract class AbstractMapBasedEndpointMapping extends AbstractEndpointMa
* key cannot be found.
* @return the registration key; or {@code null}
*/
protected abstract String getLookupKeyForMessage(MessageContext messageContext) throws Exception;
protected abstract @Nullable String getLookupKeyForMessage(MessageContext messageContext) throws Exception;
/**
* Lookup an endpoint for the given message. The extraction of the endpoint key is
@@ -111,7 +119,7 @@ public abstract class AbstractMapBasedEndpointMapping extends AbstractEndpointMa
* @return the looked up endpoint, or {@code null}
*/
@Override
protected final Object getEndpointInternal(MessageContext messageContext) throws Exception {
protected final @Nullable Object getEndpointInternal(MessageContext messageContext) throws Exception {
String key = getLookupKeyForMessage(messageContext);
if (!StringUtils.hasLength(key)) {
return null;
@@ -127,7 +135,7 @@ public abstract class AbstractMapBasedEndpointMapping extends AbstractEndpointMa
* @param key key the beans are mapped to
* @return the associated endpoint instance, or {@code null} if not found
*/
protected Object lookupEndpoint(String key) {
protected @Nullable Object lookupEndpoint(String key) {
return this.endpointMap.get(key);
}
@@ -176,18 +184,19 @@ public abstract class AbstractMapBasedEndpointMapping extends AbstractEndpointMa
}
registerEndpoint(key, endpoint);
}
this.temporaryEndpointMap = null;
this.temporaryEndpointMap.clear();
this.configured = true;
if (this.registerBeanNames) {
ApplicationContext applicationContext = obtainApplicationContext();
if (this.logger.isDebugEnabled()) {
this.logger
.debug("Looking for endpoint mappings in application context: [" + getApplicationContext() + "]");
this.logger.debug("Looking for endpoint mappings in application context: [" + applicationContext + "]");
}
String[] beanNames = getApplicationContext().getBeanDefinitionNames();
String[] beanNames = applicationContext.getBeanDefinitionNames();
for (String beanName : beanNames) {
if (validateLookupKey(beanName)) {
registerEndpoint(beanName, beanName);
}
String[] aliases = getApplicationContext().getAliases(beanName);
String[] aliases = applicationContext.getAliases(beanName);
for (String aliase : aliases) {
if (validateLookupKey(aliase)) {
registerEndpoint(aliase, beanName);

View File

@@ -26,8 +26,11 @@ import java.util.List;
import java.util.Map;
import java.util.Set;
import org.jspecify.annotations.Nullable;
import org.springframework.aop.support.AopUtils;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextException;
import org.springframework.core.BridgeMethodResolver;
import org.springframework.util.Assert;
@@ -59,7 +62,7 @@ public abstract class AbstractMethodEndpointMapping<T> extends AbstractEndpointM
* @see #getLookupKeyForMessage(MessageContext)
*/
@Override
protected Object getEndpointInternal(MessageContext messageContext) throws Exception {
protected @Nullable Object getEndpointInternal(MessageContext messageContext) throws Exception {
T key = getLookupKeyForMessage(messageContext);
if (key == null) {
return null;
@@ -74,14 +77,14 @@ public abstract class AbstractMethodEndpointMapping<T> extends AbstractEndpointM
* Returns the endpoint keys for the given message context.
* @return the registration keys
*/
protected abstract T getLookupKeyForMessage(MessageContext messageContext) throws Exception;
protected abstract @Nullable T getLookupKeyForMessage(MessageContext messageContext) throws Exception;
/**
* Looks up an endpoint instance for the given keys. All keys are tried in order.
* @param key key the beans are mapped to
* @return the associated endpoint instance, or {@code null} if not found
*/
protected MethodEndpoint lookupEndpoint(T key) {
protected @Nullable MethodEndpoint lookupEndpoint(T key) {
return this.endpointMap.get(key);
}
@@ -91,7 +94,7 @@ public abstract class AbstractMethodEndpointMapping<T> extends AbstractEndpointM
* @param endpoint the method endpoint instance
* @throws BeansException if the endpoint could not be registered
*/
protected void registerEndpoint(T key, MethodEndpoint endpoint) throws BeansException {
protected void registerEndpoint(T key, @Nullable MethodEndpoint endpoint) throws BeansException {
Object mappedEndpoint = this.endpointMap.get(key);
if (mappedEndpoint != null) {
throw new ApplicationContextException("Cannot map endpoint [" + endpoint + "] on registration key [" + key
@@ -136,8 +139,11 @@ public abstract class AbstractMethodEndpointMapping<T> extends AbstractEndpointM
* @see #getLookupKeysForMethod(Method)
*/
protected void registerMethods(String beanName) {
ApplicationContext applicationContext = getApplicationContext();
Assert.notNull(applicationContext, "'applicationContext' must not be null");
Assert.hasText(beanName, "'beanName' must not be empty");
Class<?> endpointType = getApplicationContext().getType(beanName);
Class<?> endpointType = applicationContext.getType(beanName);
Assert.state(endpointType != null, "No type found for bean with name [" + beanName + "]");
endpointType = ClassUtils.getUserClass(endpointType);
Set<Method> methods = findEndpointMethods(endpointType, new ReflectionUtils.MethodFilter() {
@@ -149,7 +155,7 @@ public abstract class AbstractMethodEndpointMapping<T> extends AbstractEndpointM
for (Method method : methods) {
List<T> keys = getLookupKeysForMethod(method);
for (T key : keys) {
registerEndpoint(key, new MethodEndpoint(beanName, getApplicationContext(), method));
registerEndpoint(key, new MethodEndpoint(beanName, applicationContext, method));
}
}
@@ -188,7 +194,7 @@ public abstract class AbstractMethodEndpointMapping<T> extends AbstractEndpointM
* @return a registration key, or {@code null} if the method is not to be registered
* @see #getLookupKeysForMethod(Method)
*/
protected T getLookupKeyForMethod(Method method) {
protected @Nullable T getLookupKeyForMethod(Method method) {
return null;
}

View File

@@ -18,6 +18,8 @@ package org.springframework.ws.server.endpoint.mapping;
import javax.xml.namespace.QName;
import org.jspecify.annotations.Nullable;
import org.springframework.ws.context.MessageContext;
import org.springframework.xml.namespace.QNameUtils;
@@ -31,7 +33,7 @@ import org.springframework.xml.namespace.QNameUtils;
public abstract class AbstractQNameEndpointMapping extends AbstractMapBasedEndpointMapping {
@Override
protected final String getLookupKeyForMessage(MessageContext messageContext) throws Exception {
protected final @Nullable String getLookupKeyForMessage(MessageContext messageContext) throws Exception {
QName qName = resolveQName(messageContext);
return (qName != null) ? qName.toString() : null;
}
@@ -40,7 +42,7 @@ public abstract class AbstractQNameEndpointMapping extends AbstractMapBasedEndpo
* Template method that resolves the qualified names from the given SOAP message.
* @return an array of qualified names that serve as registration keys
*/
protected abstract QName resolveQName(MessageContext messageContext) throws Exception;
protected abstract @Nullable QName resolveQName(MessageContext messageContext) throws Exception;
@Override
protected boolean validateLookupKey(String key) {

View File

@@ -23,6 +23,8 @@ import java.util.List;
import javax.xml.namespace.QName;
import javax.xml.transform.TransformerFactory;
import org.jspecify.annotations.Nullable;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.util.StringUtils;
import org.springframework.ws.context.MessageContext;
@@ -54,11 +56,7 @@ import org.springframework.xml.transform.TransformerFactoryUtils;
*/
public class PayloadRootAnnotationMethodEndpointMapping extends AbstractAnnotationMethodEndpointMapping<QName> {
private static TransformerFactory transformerFactory;
static {
setTransformerFactory(TransformerFactoryUtils.newInstance());
}
private static TransformerFactory transformerFactory = TransformerFactoryUtils.newInstance();
/**
* Override the default {@link TransformerFactory}.
@@ -69,7 +67,7 @@ public class PayloadRootAnnotationMethodEndpointMapping extends AbstractAnnotati
}
@Override
protected QName getLookupKeyForMessage(MessageContext messageContext) throws Exception {
protected @Nullable QName getLookupKeyForMessage(MessageContext messageContext) throws Exception {
return PayloadRootUtils.getPayloadRootQName(messageContext.getRequest().getPayloadSource(), transformerFactory);
}

View File

@@ -20,6 +20,8 @@ import javax.xml.namespace.QName;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import org.jspecify.annotations.Nullable;
import org.springframework.ws.context.MessageContext;
import org.springframework.ws.server.endpoint.support.PayloadRootUtils;
import org.springframework.xml.transform.TransformerFactoryUtils;
@@ -49,11 +51,7 @@ import org.springframework.xml.transform.TransformerFactoryUtils;
*/
public class PayloadRootQNameEndpointMapping extends AbstractQNameEndpointMapping {
private static TransformerFactory transformerFactory;
static {
setTransformerFactory(TransformerFactoryUtils.newInstance());
}
private static TransformerFactory transformerFactory = TransformerFactoryUtils.newInstance();
/**
* Override the default {@link TransformerFactory}.
@@ -64,7 +62,7 @@ public class PayloadRootQNameEndpointMapping extends AbstractQNameEndpointMappin
}
@Override
protected QName resolveQName(MessageContext messageContext) throws TransformerException {
protected @Nullable QName resolveQName(MessageContext messageContext) throws TransformerException {
return PayloadRootUtils.getPayloadRootQName(messageContext.getRequest().getPayloadSource(), transformerFactory);
}

View File

@@ -22,6 +22,8 @@ import javax.xml.namespace.QName;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import org.jspecify.annotations.Nullable;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.util.Assert;
import org.springframework.ws.WebServiceMessage;
@@ -42,7 +44,7 @@ import org.springframework.xml.transform.TransformerFactoryUtils;
*
* public Source handleMyMessage(Source source) {
* ...
* }
* }
* }
* </pre>
*
@@ -61,15 +63,16 @@ public class SimpleMethodEndpointMapping extends AbstractMethodEndpointMapping<S
/** Default method suffix. */
public static final String DEFAULT_METHOD_SUFFIX = "";
private Object[] endpoints;
private Object @Nullable [] endpoints;
private String methodPrefix = DEFAULT_METHOD_PREFIX;
private String methodSuffix = DEFAULT_METHOD_SUFFIX;
private TransformerFactory transformerFactory;
private final TransformerFactory transformerFactory = TransformerFactoryUtils.newInstance();
public Object[] getEndpoints() {
Assert.notEmpty(this.endpoints, "'endpoints' is required");
return this.endpoints;
}
@@ -111,8 +114,6 @@ public class SimpleMethodEndpointMapping extends AbstractMethodEndpointMapping<S
@Override
public final void afterPropertiesSet() throws Exception {
Assert.notEmpty(getEndpoints(), "'endpoints' is required");
this.transformerFactory = TransformerFactoryUtils.newInstance();
for (int i = 0; i < getEndpoints().length; i++) {
registerMethods(getEndpoints()[i]);
}
@@ -120,7 +121,7 @@ public class SimpleMethodEndpointMapping extends AbstractMethodEndpointMapping<S
/** Returns the name of the given method, with the prefix and suffix stripped off. */
@Override
protected String getLookupKeyForMethod(Method method) {
protected @Nullable String getLookupKeyForMethod(Method method) {
String methodName = method.getName();
String prefix = getMethodPrefix();
String suffix = getMethodSuffix();
@@ -134,10 +135,10 @@ public class SimpleMethodEndpointMapping extends AbstractMethodEndpointMapping<S
/** Returns the local part of the payload root element of the request. */
@Override
protected String getLookupKeyForMessage(MessageContext messageContext) throws TransformerException {
protected @Nullable String getLookupKeyForMessage(MessageContext messageContext) throws TransformerException {
WebServiceMessage request = messageContext.getRequest();
QName rootQName = PayloadRootUtils.getPayloadRootQName(request.getPayloadSource(), this.transformerFactory);
return rootQName.getLocalPart();
return (rootQName != null) ? rootQName.getLocalPart() : null;
}
}

View File

@@ -19,6 +19,8 @@ package org.springframework.ws.server.endpoint.mapping;
import java.net.URI;
import java.net.URISyntaxException;
import org.jspecify.annotations.Nullable;
import org.springframework.ws.context.MessageContext;
import org.springframework.ws.soap.saaj.SaajSoapMessageFactory;
import org.springframework.ws.transport.WebServiceConnection;
@@ -87,17 +89,14 @@ public class UriEndpointMapping extends AbstractMapBasedEndpointMapping {
}
@Override
protected String getLookupKeyForMessage(MessageContext messageContext) throws Exception {
protected @Nullable String getLookupKeyForMessage(MessageContext messageContext) throws Exception {
TransportContext transportContext = TransportContextHolder.getTransportContext();
if (transportContext != null) {
WebServiceConnection connection = transportContext.getConnection();
if (connection != null) {
URI connectionUri = connection.getUri();
if (this.usePath) {
return connectionUri.getPath();
}
else {
return connectionUri.toString();
if (connectionUri != null) {
return (this.usePath ? connectionUri.getPath() : connectionUri.toString());
}
}
}

View File

@@ -23,6 +23,7 @@ import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMResult;
import org.jspecify.annotations.Nullable;
import org.w3c.dom.Element;
import org.springframework.beans.factory.InitializingBean;
@@ -64,13 +65,15 @@ import org.springframework.xml.xpath.XPathExpressionFactory;
*/
public class XPathPayloadEndpointMapping extends AbstractMapBasedEndpointMapping implements InitializingBean {
@SuppressWarnings("NullAway.Init")
private String expressionString;
@SuppressWarnings("NullAway.Init")
private XPathExpression expression;
private Map<String, String> namespaces;
private @Nullable Map<String, String> namespaces;
private TransformerFactory transformerFactory;
private final TransformerFactory transformerFactory = TransformerFactoryUtils.newInstance();
/** Sets the XPath expression to be used. */
public void setExpression(String expression) {
@@ -94,11 +97,10 @@ public class XPathPayloadEndpointMapping extends AbstractMapBasedEndpointMapping
else {
this.expression = XPathExpressionFactory.createXPathExpression(this.expressionString, this.namespaces);
}
this.transformerFactory = TransformerFactoryUtils.newInstance();
}
@Override
protected String getLookupKeyForMessage(MessageContext messageContext) throws Exception {
protected @Nullable String getLookupKeyForMessage(MessageContext messageContext) throws Exception {
Element payloadElement = getMessagePayloadElement(messageContext.getRequest());
return this.expression.evaluateAsString(payloadElement);
}

View File

@@ -25,6 +25,7 @@ import jakarta.xml.bind.JAXBContext;
import jakarta.xml.bind.JAXBException;
import jakarta.xml.bind.JAXBIntrospector;
import jakarta.xml.bind.annotation.XmlRootElement;
import org.jspecify.annotations.Nullable;
import org.springframework.core.MethodParameter;
import org.springframework.ws.context.MessageContext;
@@ -64,7 +65,7 @@ public class XmlRootElementEndpointMapping extends AbstractAnnotationMethodEndpo
}
@Override
protected QName getLookupKeyForMethod(Method method) {
protected @Nullable QName getLookupKeyForMethod(Method method) {
Class<?>[] parameterTypes = method.getParameterTypes();
for (int i = 0; i < parameterTypes.length; i++) {
MethodParameter methodParameter = new MethodParameter(method, i);
@@ -80,7 +81,7 @@ public class XmlRootElementEndpointMapping extends AbstractAnnotationMethodEndpo
return null;
}
private QName handleRootElement(Class<?> parameterType) {
private @Nullable QName handleRootElement(Class<?> parameterType) {
try {
Object param = parameterType.getDeclaredConstructor().newInstance();
QName result = getElementName(parameterType, param);
@@ -94,7 +95,7 @@ public class XmlRootElementEndpointMapping extends AbstractAnnotationMethodEndpo
return null;
}
private QName getElementName(Class<?> parameterType, Object param) {
private @Nullable QName getElementName(Class<?> parameterType, Object param) {
try {
JAXBContext context = JAXBContext.newInstance(parameterType);
JAXBIntrospector introspector = context.createJAXBIntrospector();
@@ -106,7 +107,7 @@ public class XmlRootElementEndpointMapping extends AbstractAnnotationMethodEndpo
}
@Override
protected QName getLookupKeyForMessage(MessageContext messageContext) throws Exception {
protected @Nullable QName getLookupKeyForMessage(MessageContext messageContext) throws Exception {
return PayloadRootUtils.getPayloadRootQName(messageContext.getRequest().getPayloadSource(),
this.transformerHelper);
}

View File

@@ -17,4 +17,7 @@
/**
* Provides JAXB2-based {@code EndpointMapping} implementations.
*/
@NullMarked
package org.springframework.ws.server.endpoint.mapping.jaxb;
import org.jspecify.annotations.NullMarked;

View File

@@ -17,4 +17,7 @@
/**
* Provides miscellaneous endpoints {@code EndpointMapping} implementations.
*/
@NullMarked
package org.springframework.ws.server.endpoint.mapping;
import org.jspecify.annotations.NullMarked;

View File

@@ -17,4 +17,7 @@
/**
* Provides standard endpoint, and {@code EndpointAdapter} implementations.
*/
@NullMarked
package org.springframework.ws.server.endpoint;
import org.jspecify.annotations.NullMarked;

View File

@@ -30,11 +30,13 @@ import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMResult;
import org.jspecify.annotations.Nullable;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.xml.sax.InputSource;
import org.xml.sax.XMLReader;
import org.springframework.lang.Contract;
import org.springframework.xml.namespace.QNameUtils;
import org.springframework.xml.transform.TransformerHelper;
import org.springframework.xml.transform.TraxUtils;
@@ -57,12 +59,13 @@ public abstract class PayloadRootUtils {
* not a {@code DOMSource}
* @return the root element, or {@code null} if {@code source} is {@code null}
*/
public static QName getPayloadRootQName(Source source, TransformerFactory transformerFactory)
@Contract("!null, _ -> !null")
public static @Nullable QName getPayloadRootQName(@Nullable Source source, TransformerFactory transformerFactory)
throws TransformerException {
return getPayloadRootQName(source, new TransformerHelper(transformerFactory));
}
public static QName getPayloadRootQName(Source source, TransformerHelper transformerHelper)
public static @Nullable QName getPayloadRootQName(@Nullable Source source, TransformerHelper transformerHelper)
throws TransformerException {
if (source == null) {
return null;
@@ -91,7 +94,7 @@ public abstract class PayloadRootUtils {
private static final class PayloadRootSourceCallback implements TraxUtils.SourceCallback {
private QName result;
private @Nullable QName result;
@Override
public void domSource(Node node) throws Exception {

View File

@@ -18,4 +18,7 @@
* Provides helper classes for {@code EndpointAdapter}, {@code EndpointInterceptor}, and
* {@code EndpointMapping} implementations.
*/
@NullMarked
package org.springframework.ws.server.endpoint.support;
import org.jspecify.annotations.NullMarked;

View File

@@ -17,4 +17,7 @@
/**
* Contains classes for server-side Spring-WS support.
*/
@NullMarked
package org.springframework.ws.server;
import org.jspecify.annotations.NullMarked;

View File

@@ -20,6 +20,8 @@ import javax.xml.namespace.QName;
import javax.xml.transform.Result;
import javax.xml.transform.Source;
import org.jspecify.annotations.Nullable;
import org.springframework.ws.mime.AbstractMimeMessage;
/**
@@ -31,7 +33,7 @@ import org.springframework.ws.mime.AbstractMimeMessage;
*/
public abstract class AbstractSoapMessage extends AbstractMimeMessage implements SoapMessage {
private SoapVersion version;
private @Nullable SoapVersion version;
/** Returns {@code getEnvelope().getBody()}. */
@Override
@@ -41,13 +43,13 @@ public abstract class AbstractSoapMessage extends AbstractMimeMessage implements
/** Returns {@code getEnvelope().getHeader()}. */
@Override
public final SoapHeader getSoapHeader() {
public final @Nullable SoapHeader getSoapHeader() {
return getEnvelope().getHeader();
}
/** Returns {@code getSoapBody().getPayloadSource()}. */
@Override
public final Source getPayloadSource() {
public final @Nullable Source getPayloadSource() {
return getSoapBody().getPayloadSource();
}
@@ -65,8 +67,8 @@ public abstract class AbstractSoapMessage extends AbstractMimeMessage implements
/** Returns {@code getSoapBody().getFault().getFaultCode()}. */
@Override
public final QName getFaultCode() {
if (hasFault()) {
public final @Nullable QName getFaultCode() {
if (hasFault() && getSoapBody().getFault() != null) {
return getSoapBody().getFault().getFaultCode();
}
else {
@@ -76,8 +78,8 @@ public abstract class AbstractSoapMessage extends AbstractMimeMessage implements
/** Returns {@code getSoapBody().getFault().getFaultStringOrReason()}. */
@Override
public final String getFaultReason() {
if (hasFault()) {
public final @Nullable String getFaultReason() {
if (hasFault() && getSoapBody().getFault() != null) {
return getSoapBody().getFault().getFaultStringOrReason();
}
else {

View File

@@ -21,6 +21,8 @@ import java.util.Locale;
import javax.xml.transform.Result;
import javax.xml.transform.Source;
import org.jspecify.annotations.Nullable;
import org.springframework.ws.WebServiceMessage;
/**
@@ -45,7 +47,7 @@ public interface SoapBody extends SoapElement {
* @return the message contents
* @see WebServiceMessage#getPayloadSource()
*/
Source getPayloadSource();
@Nullable Source getPayloadSource();
/**
* Returns a {@code Result} that represents the contents of the body.
@@ -112,6 +114,6 @@ public interface SoapBody extends SoapElement {
* Returns the {@code SoapFault} of this body.
* @return the {@code SoapFault}, or {@code null} if none is present
*/
SoapFault getFault();
@Nullable SoapFault getFault();
}

View File

@@ -16,6 +16,8 @@
package org.springframework.ws.soap;
import org.jspecify.annotations.Nullable;
/**
* Represents the {@code Envelope} element in a SOAP message. The header contains the
* optional {@code SoapHeader} and {@code SoapBody}.
@@ -30,7 +32,7 @@ public interface SoapEnvelope extends SoapElement {
* @return the {@code SoapHeader}, or {@code null}
* @throws SoapHeaderException if the header cannot be returned
*/
SoapHeader getHeader() throws SoapHeaderException;
@Nullable SoapHeader getHeader() throws SoapHeaderException;
/**
* Returns the {@code SoapBody}.

View File

@@ -18,6 +18,8 @@ package org.springframework.ws.soap;
import javax.xml.namespace.QName;
import org.jspecify.annotations.Nullable;
/**
* Represent the {@code Fault} element in the body of a SOAP message.
* <p>
@@ -42,7 +44,7 @@ public interface SoapFault extends SoapElement {
* this returns the fault string. For SOAP 1.2, this returns the fault reason for the
* default locale.
*/
String getFaultStringOrReason();
@Nullable String getFaultStringOrReason();
/**
* Return the optional fault actor or role. For SOAP 1.1, this returns the URI of the
@@ -50,7 +52,7 @@ public interface SoapFault extends SoapElement {
* identifies the role in which the node was operating at the point the fault
* occurred.
*/
String getFaultActorOrRole();
@Nullable String getFaultActorOrRole();
/**
* Set the fault actor or role. For SOAP 1.1, this sets the actor. For SOAP 1.2, this
@@ -62,7 +64,7 @@ public interface SoapFault extends SoapElement {
* Return the optional {@linkplain SoapFaultDetail detail element} of this fault.
* @return a fault detail
*/
SoapFaultDetail getFaultDetail();
@Nullable SoapFaultDetail getFaultDetail();
/**
* Create a {@link SoapFaultDetail} and assign it to this fault.

View File

@@ -18,6 +18,8 @@ package org.springframework.ws.soap;
import javax.xml.transform.Result;
import org.jspecify.annotations.Nullable;
/**
* Represents the content for an individual SOAP detail entry in a SOAP Message. All
* {@code SoapFaultDetailElement}s are contained in a {@code SoapDetail}.
@@ -35,6 +37,6 @@ public interface SoapFaultDetailElement extends SoapElement {
Result getResult();
/** Adds a new text node to this element. */
void addText(String text);
void addText(@Nullable String text);
}

View File

@@ -16,6 +16,7 @@
package org.springframework.ws.soap;
import org.jspecify.annotations.Nullable;
import org.w3c.dom.Document;
import org.springframework.ws.FaultAwareWebServiceMessage;
@@ -64,7 +65,7 @@ public interface SoapMessage extends MimeMessage, FaultAwareWebServiceMessage {
* method for {@code getEnvelope().getHeader()}.
* @see SoapEnvelope#getHeader()
*/
SoapHeader getSoapHeader() throws SoapHeaderException;
@Nullable SoapHeader getSoapHeader() throws SoapHeaderException;
/**
* Returns the SOAP version of this message. This can be either SOAP 1.1 or SOAP 1.2.

Some files were not shown because too many files have changed in this diff Show More