Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,6 @@ public interface ComponentSourceAware extends BeanNameAware {
* Return the bean name populated by the {@link BeanNameAware#setBeanName(String)}.
* @return the bean name.
*/
@Nullable
String getBeanName();

}
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,6 @@ public final void setBeanName(String beanName) {
}

@Override
@Nullable
public String getBeanName() {
return this.beanName;
}
Expand All @@ -127,7 +126,6 @@ public String getBeanName() {
* If {@link #componentName} was not set this method will default to the 'beanName' of this component;
*/
@Override
@Nullable
public String getComponentName() {
return StringUtils.hasText(this.componentName) ? this.componentName : this.beanName;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,6 @@ public void setBeanName(String name) {
this.beanName = name;
}

@Nullable
@Override
public String getBeanName() {
return this.beanName;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ public class StandardIntegrationFlow

private @Nullable MessageChannel inputChannel;

private @Nullable boolean running;
private boolean running;

@SuppressWarnings("NullAway.Init")
private String beanName;
Expand Down Expand Up @@ -125,7 +125,7 @@ public void setComponentDescription(String description) {
}

@Override
public @Nullable String getBeanName() {
public String getBeanName() {
return this.beanName;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -376,6 +376,9 @@ private static final class IntegrationFlowComponentSourceAwareAdapter

private final IntegrationFlow delegate;

@SuppressWarnings("NullAway.Init")
private String beanName;

private @Nullable Object beanSource;

private @Nullable String beanDescription;
Expand Down Expand Up @@ -404,15 +407,14 @@ public void setComponentDescription(String description) {
return this.beanDescription;
}

@Nullable
@Override
public String getBeanName() {
return null;
return this.beanName;
}

@Override
public void setBeanName(String name) {

this.beanName = name;
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ public Object processMessage(Message<?> message) {
@SuppressWarnings("unchecked")
List<Object> arguments =
message.getHeaders().get(IntegrationMessageHeaderAccessor.CONTROL_BUS_ARGUMENTS, List.class);
Class<?>[] parameterTypes = new Class<?>[0];
Class<?>[] parameterTypes = {};
if (!CollectionUtils.isEmpty(arguments)) {
parameterTypes =
arguments.stream()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.jspecify.annotations.Nullable;

import org.springframework.beans.factory.ObjectProvider;
import org.springframework.beans.factory.config.BeanDefinition;
Expand All @@ -42,9 +43,10 @@
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
public class ControlBusControllerConfiguration {

private static final Log LOGGER = LogFactory.getLog(IntegrationGraphControllerRegistrar.class);
private static final Log LOGGER = LogFactory.getLog(ControlBusControllerConfiguration.class);

@Bean
@Nullable
ControlBusController controlBusController(ControlBusCommandRegistry controlBusCommandRegistry,
ObjectProvider<FormattingConversionService> conversionService) {

Expand All @@ -56,7 +58,7 @@ ControlBusController controlBusController(ControlBusCommandRegistry controlBusCo

controlBusCommandRegistry.setEagerInitialization(true);

return new ControlBusController(controlBusCommandRegistry, conversionService.getIfUnique());
return new ControlBusController(controlBusCommandRegistry, conversionService.getObject());
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just curious. Swapping getIfUnique for getObject is because if there is no object it will throw an Exception instead returning null?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see your point.
I understand that it is a behavior change, but it should be a good one.
The ControlBusController cannot live without conversionService, so getIfUnique() is not OK for us since it may end up with a null.
Therefore I decide to go a hard failure with just getObject() to let the target application know that there is something off with a configuration.
In 99% it should not be a problem since most projects rely on the MVC auto-configuration and that's it.
They don't introduce a custom FormattingConversionService.
When they do, and this fails, they should mark one of the as @Primary to avoid injection collision.

With that I think just FormattingConversionService conversionService as injection point in this ControlBusControllerConfiguration should be enough.
The ObjectProvider.getObject() is total equivalent to regular by type injection.

Let me know if you have any other concerns before I go with clean up!

}

}
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@
import java.util.HashMap;
import java.util.Map;

import org.jspecify.annotations.Nullable;

import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.util.ClassUtils;
import org.springframework.util.ObjectUtils;
Expand Down Expand Up @@ -85,17 +87,18 @@ private HttpContextUtils() {
* @return the {@link RequestMapping} annotation.
* @since 5.0
*/
public static RequestMapping convertRequestMappingToAnnotation(
public static @Nullable RequestMapping convertRequestMappingToAnnotation(
org.springframework.integration.http.inbound.RequestMapping requestMapping) {

if (ObjectUtils.isEmpty(requestMapping.getPathPatterns())) {
String[] pathPatterns = requestMapping.getPathPatterns();
if (ObjectUtils.isEmpty(pathPatterns)) {
return null;
}

Map<String, Object> requestMappingAttributes = new HashMap<>();
requestMappingAttributes.put("name", requestMapping.getName());
requestMappingAttributes.put("value", requestMapping.getPathPatterns());
requestMappingAttributes.put("path", requestMapping.getPathPatterns());
requestMappingAttributes.put("value", pathPatterns);
requestMappingAttributes.put("path", pathPatterns);
requestMappingAttributes.put("method", requestMapping.getRequestMethods());
requestMappingAttributes.put("params", requestMapping.getParams());
requestMappingAttributes.put("headers", requestMapping.getHeaders());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,6 @@ protected AbstractBeanDefinition parseConsumer(Element element, ParserContext pa
if (StringUtils.hasText(mappedRequestHeaders)) {
parserContext.getReaderContext().error("The 'mapped-request-headers' attribute is not " +
"allowed when a 'header-mapper' has been specified.", parserContext.extractSource(element));
return null;
}
builder.addPropertyReference("headerMapper", headerMapper);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,6 @@ protected BeanDefinitionBuilder parseHandler(Element element, ParserContext pars
.error("Neither 'mapped-request-headers' or 'mapped-response-headers' " +
"attributes are allowed when a 'header-mapper' has been specified.",
parserContext.extractSource(element));
return null;
}
builder.addPropertyReference("headerMapper", headerMapper);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
import java.util.Map;
import java.util.Set;

import org.jspecify.annotations.Nullable;
import org.w3c.dom.Element;

import org.springframework.beans.factory.config.BeanDefinition;
Expand All @@ -41,13 +42,13 @@ public class IntegrationGraphControllerParser implements BeanDefinitionParser {
new IntegrationGraphControllerRegistrar();

@Override
public BeanDefinition parse(final Element element, ParserContext parserContext) {
public @Nullable BeanDefinition parse(final Element element, ParserContext parserContext) {
this.graphControllerRegistrar.registerBeanDefinitions(
new AnnotationMetadataAdapter() {

@Override
public Map<String, Object> getAnnotationAttributes(String annotationType) {
return Collections.singletonMap("value", element.getAttribute("path"));
public Map<String, @Nullable Object> getAnnotationAttributes(String annotationType) {
return Collections.<String, @Nullable Object>singletonMap("value", element.getAttribute("path"));
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@

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.config.BeanDefinition;
Expand All @@ -42,6 +43,7 @@
import org.springframework.integration.context.IntegrationContextUtils;
import org.springframework.integration.graph.IntegrationGraphServer;
import org.springframework.integration.http.management.IntegrationGraphController;
import org.springframework.util.Assert;

/**
* Registers the necessary beans for {@link EnableIntegrationGraphController}.
Expand All @@ -65,7 +67,7 @@ public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, B
return;
}

Map<String, Object> annotationAttributes =
Map<String, @Nullable Object> annotationAttributes =
importingClassMetadata.getAnnotationAttributes(EnableIntegrationGraphController.class.getName());
if (annotationAttributes == null) {
annotationAttributes = Collections.emptyMap(); // To satisfy sonar for subsequent references
Expand All @@ -76,14 +78,15 @@ public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, B
new RootBeanDefinition(IntegrationGraphServer.class));
}

String path = (String) annotationAttributes.get("value");
String path = (String) annotationAttributes.get(AnnotationUtils.VALUE);
Assert.state(path != null, "The 'path' has to be provided on the 'EnableIntegrationGraphController'.");
String[] allowedOrigins = (String[]) annotationAttributes.get("allowedOrigins");
if (allowedOrigins != null && allowedOrigins.length > 0) {
registerControllerCorsConfigurer(registry, path, allowedOrigins);
}

if (!registry.containsBeanDefinition(HttpContextUtils.GRAPH_CONTROLLER_BEAN_NAME)) {
registerIntegrationGraphController(registry, (String) annotationAttributes.get(AnnotationUtils.VALUE));
registerIntegrationGraphController(registry, path);
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
/**
* Provides classes for configuration - parsers, namespace handlers.
*/
@org.jspecify.annotations.NullMarked
package org.springframework.integration.http.config;
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@
import java.util.List;
import java.util.Map;

import org.jspecify.annotations.Nullable;

import org.springframework.http.HttpInputMessage;
import org.springframework.http.HttpOutputMessage;
import org.springframework.http.MediaType;
Expand Down Expand Up @@ -77,7 +79,7 @@ public List<MediaType> getSupportedMediaTypes() {
}

@Override
public boolean canRead(Class<?> clazz, MediaType mediaType) {
public boolean canRead(Class<?> clazz, @Nullable MediaType mediaType) {
if (!(MultiValueMap.class.isAssignableFrom(clazz) || byte[].class.isAssignableFrom(clazz))) {
return false;
}
Expand All @@ -91,18 +93,17 @@ public boolean canRead(Class<?> clazz, MediaType mediaType) {
}

@Override
public boolean canWrite(Class<?> clazz, MediaType mediaType) {
public boolean canWrite(Class<?> clazz, @Nullable MediaType mediaType) {
return this.wrappedConverter.canWrite(clazz, mediaType);
}

@Override
@SuppressWarnings("unchecked")
public MultiValueMap<String, ?> read(Class<? extends MultiValueMap<String, ?>> clazz,
HttpInputMessage inputMessage) throws IOException, HttpMessageNotReadableException {

MediaType contentType = inputMessage.getHeaders().getContentType();
if (!MediaType.MULTIPART_FORM_DATA.includes(contentType)) {
return (MultiValueMap<String, ?>) this.wrappedConverter.read(clazz, inputMessage);
return this.wrappedConverter.read(clazz, inputMessage);
}
Assert.state(inputMessage instanceof MultipartHttpInputMessage,
"A request with 'multipart/form-data' Content-Type must be a MultipartHttpInputMessage. "
Expand All @@ -127,7 +128,7 @@ public boolean canWrite(Class<?> clazz, MediaType mediaType) {
}

@Override
public void write(MultiValueMap<String, ?> map, MediaType contentType, HttpOutputMessage outputMessage)
public void write(MultiValueMap<String, ?> map, @Nullable MediaType contentType, HttpOutputMessage outputMessage)
throws IOException, HttpMessageNotWritableException {

this.wrappedConverter.write(map, contentType, outputMessage);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@
import java.io.ObjectOutputStream;
import java.io.Serializable;

import org.jspecify.annotations.Nullable;

import org.springframework.http.HttpInputMessage;
import org.springframework.http.HttpOutputMessage;
import org.springframework.http.MediaType;
Expand All @@ -43,7 +45,9 @@ public class SerializingHttpMessageConverter extends AbstractHttpMessageConverte
private static final MediaType APPLICATION_JAVA_SERIALIZED_OBJECT =
new MediaType("application", "x-java-serialized-object");

/** Creates a new instance of the {@code SerializingHttpMessageConverter}. */
/**
* Creates a new instance of the {@code SerializingHttpMessageConverter}.
*/
public SerializingHttpMessageConverter() {
super(APPLICATION_JAVA_SERIALIZED_OBJECT);
}
Expand All @@ -54,18 +58,19 @@ public boolean supports(Class<?> clazz) {
}

@Override
public boolean canWrite(Class<?> clazz, MediaType mediaType) {
public boolean canWrite(Class<?> clazz, @Nullable MediaType mediaType) {
return Serializable.class.isAssignableFrom(clazz) && canWrite(mediaType);
}

@Override
@SuppressWarnings("rawtypes")
public Serializable readInternal(Class clazz, HttpInputMessage inputMessage) throws IOException {
public Serializable readInternal(Class<? extends Serializable> clazz, HttpInputMessage inputMessage)
throws IOException {

try {
return (Serializable) new ObjectInputStream(inputMessage.getBody()).readObject(); //NOSONAR
return (Serializable) new ObjectInputStream(inputMessage.getBody()).readObject();
}
catch (ClassNotFoundException e) {
throw new IllegalArgumentException(e);
catch (ClassNotFoundException ex) {
throw new IllegalArgumentException(ex);
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
/**
* Provides classes supporting message conversion.
*/
@org.jspecify.annotations.NullMarked
package org.springframework.integration.http.converter;
Loading