diff --git a/spring-integration-hazelcast/src/main/java/org/springframework/integration/hazelcast/message/EntryEventMessagePayload.java b/spring-integration-hazelcast/src/main/java/org/springframework/integration/hazelcast/message/EntryEventMessagePayload.java index c55b960d321..f1fad539d98 100644 --- a/spring-integration-hazelcast/src/main/java/org/springframework/integration/hazelcast/message/EntryEventMessagePayload.java +++ b/spring-integration-hazelcast/src/main/java/org/springframework/integration/hazelcast/message/EntryEventMessagePayload.java @@ -16,7 +16,7 @@ package org.springframework.integration.hazelcast.message; -import org.springframework.util.Assert; +import org.jspecify.annotations.Nullable; /** * Hazelcast Message Payload for Entry Events. @@ -28,59 +28,11 @@ * @author Artem Bilan * * @since 6.0 + * + * @param key The entry key. + * @param value The entry value. + * @param oldValue The entry old value if any. */ -public class EntryEventMessagePayload { - - /** - * The entry key. - */ - public final K key; - - /** - * The entry value. - */ - public final V value; - - /** - * The entry old value if any. - */ - public final V oldValue; - - public EntryEventMessagePayload(final K key, final V value, final V oldValue) { - Assert.notNull(key, "'key' must not be null"); - this.key = key; - this.value = value; - this.oldValue = oldValue; - } - - @Override - public String toString() { - return "EntryEventMessagePayload [key=" + this.key + ", value=" + this.value + ", oldValue=" + this.oldValue + "]"; - } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - - EntryEventMessagePayload that = (EntryEventMessagePayload) o; - - return this.key.equals(that.key) && !(this.value != null ? !this.value.equals(that.value) - : that.value != null) && !(this.oldValue != null - ? !this.oldValue.equals(that.oldValue) : that.oldValue != null); - - } - - @Override - public int hashCode() { - int result = this.key.hashCode(); - result = 31 * result + (this.value != null ? this.value.hashCode() : 0); - result = 31 * result + (this.oldValue != null ? this.oldValue.hashCode() : 0); - return result; - } +public record EntryEventMessagePayload(K key, @Nullable V value, @Nullable V oldValue) { } diff --git a/spring-integration-hazelcast/src/main/java/org/springframework/integration/hazelcast/message/package-info.java b/spring-integration-hazelcast/src/main/java/org/springframework/integration/hazelcast/message/package-info.java index 0a659bfb043..7266abeb54f 100644 --- a/spring-integration-hazelcast/src/main/java/org/springframework/integration/hazelcast/message/package-info.java +++ b/spring-integration-hazelcast/src/main/java/org/springframework/integration/hazelcast/message/package-info.java @@ -1,4 +1,5 @@ /** * Provides classes supporting Hazelcast message headers and payload. */ +@org.jspecify.annotations.NullMarked package org.springframework.integration.hazelcast.message; diff --git a/spring-integration-hazelcast/src/test/java/org/springframework/integration/hazelcast/inbound/HazelcastCQDistributedMapInboundChannelAdapterTests.java b/spring-integration-hazelcast/src/test/java/org/springframework/integration/hazelcast/inbound/HazelcastCQDistributedMapInboundChannelAdapterTests.java index 6fe99e4bcd4..39979c631e2 100644 --- a/spring-integration-hazelcast/src/test/java/org/springframework/integration/hazelcast/inbound/HazelcastCQDistributedMapInboundChannelAdapterTests.java +++ b/spring-integration-hazelcast/src/test/java/org/springframework/integration/hazelcast/inbound/HazelcastCQDistributedMapInboundChannelAdapterTests.java @@ -97,13 +97,13 @@ public void testContinuousQueryForOnlyREMOVEDEntryEvent() { assertThat(msg.getHeaders().get(HazelcastHeaders.CACHE_NAME)).isEqualTo("cqDistributedMap2"); assertThat(((EntryEventMessagePayload) msg - .getPayload()).key).isEqualTo(Integer.valueOf(2)); + .getPayload()).key()).isEqualTo(Integer.valueOf(2)); assertThat((((EntryEventMessagePayload) msg - .getPayload()).oldValue).getId()).isEqualTo(2); + .getPayload()).oldValue()).getId()).isEqualTo(2); assertThat((((EntryEventMessagePayload) msg - .getPayload()).oldValue).getName()).isEqualTo("TestName2"); + .getPayload()).oldValue()).getName()).isEqualTo("TestName2"); assertThat((((EntryEventMessagePayload) msg - .getPayload()).oldValue).getSurname()).isEqualTo("TestSurname2"); + .getPayload()).oldValue()).getSurname()).isEqualTo("TestSurname2"); } @Test @@ -129,19 +129,19 @@ public void testContinuousQueryForOnlyUPDATEDEntryEvent() { assertThat(msg.getHeaders().get(HazelcastHeaders.CACHE_NAME)).isEqualTo("cqDistributedMap4"); assertThat(((EntryEventMessagePayload) msg - .getPayload()).key).isEqualTo(Integer.valueOf(1)); + .getPayload()).key()).isEqualTo(Integer.valueOf(1)); assertThat((((EntryEventMessagePayload) msg - .getPayload()).oldValue).getId()).isEqualTo(1); + .getPayload()).oldValue()).getId()).isEqualTo(1); assertThat((((EntryEventMessagePayload) msg - .getPayload()).oldValue).getName()).isEqualTo("TestName1"); + .getPayload()).oldValue()).getName()).isEqualTo("TestName1"); assertThat((((EntryEventMessagePayload) msg - .getPayload()).oldValue).getSurname()).isEqualTo("TestSurname1"); + .getPayload()).oldValue()).getSurname()).isEqualTo("TestSurname1"); assertThat((((EntryEventMessagePayload) msg - .getPayload()).value).getId()).isEqualTo(2); + .getPayload()).value()).getId()).isEqualTo(2); assertThat((((EntryEventMessagePayload) msg - .getPayload()).value).getName()).isEqualTo("TestName2"); + .getPayload()).value()).getName()).isEqualTo("TestName2"); assertThat((((EntryEventMessagePayload) msg - .getPayload()).value).getSurname()).isEqualTo("TestSurname2"); + .getPayload()).value()).getSurname()).isEqualTo("TestSurname2"); } @Test diff --git a/spring-integration-hazelcast/src/test/java/org/springframework/integration/hazelcast/inbound/HazelcastDistributedMapEventDrivenInboundChannelAdapterTests.java b/spring-integration-hazelcast/src/test/java/org/springframework/integration/hazelcast/inbound/HazelcastDistributedMapEventDrivenInboundChannelAdapterTests.java index 0cb8dad51b7..5f2ff43070d 100644 --- a/spring-integration-hazelcast/src/test/java/org/springframework/integration/hazelcast/inbound/HazelcastDistributedMapEventDrivenInboundChannelAdapterTests.java +++ b/spring-integration-hazelcast/src/test/java/org/springframework/integration/hazelcast/inbound/HazelcastDistributedMapEventDrivenInboundChannelAdapterTests.java @@ -92,19 +92,19 @@ public void testEventDrivenForOnlyUPDATEDEntryEvent() { assertThat(msg.getHeaders().get(HazelcastHeaders.CACHE_NAME)).isEqualTo("edDistributedMap2"); assertThat(((EntryEventMessagePayload) msg - .getPayload()).key).isEqualTo(Integer.valueOf(2)); + .getPayload()).key()).isEqualTo(Integer.valueOf(2)); assertThat((((EntryEventMessagePayload) msg - .getPayload()).oldValue).getId()).isEqualTo(1); + .getPayload()).oldValue()).getId()).isEqualTo(1); assertThat((((EntryEventMessagePayload) msg - .getPayload()).oldValue).getName()).isEqualTo("TestName1"); + .getPayload()).oldValue()).getName()).isEqualTo("TestName1"); assertThat((((EntryEventMessagePayload) msg - .getPayload()).oldValue).getSurname()).isEqualTo("TestSurname1"); + .getPayload()).oldValue()).getSurname()).isEqualTo("TestSurname1"); assertThat((((EntryEventMessagePayload) msg - .getPayload()).value).getId()).isEqualTo(2); + .getPayload()).value()).getId()).isEqualTo(2); assertThat((((EntryEventMessagePayload) msg - .getPayload()).value).getName()).isEqualTo("TestName2"); + .getPayload()).value()).getName()).isEqualTo("TestName2"); assertThat((((EntryEventMessagePayload) msg - .getPayload()).value).getSurname()).isEqualTo("TestSurname2"); + .getPayload()).value()).getSurname()).isEqualTo("TestSurname2"); } @Test @@ -124,13 +124,13 @@ public void testEventDrivenForOnlyREMOVEDEntryEvent() { assertThat(msg.getHeaders().get(HazelcastHeaders.CACHE_NAME)).isEqualTo("edDistributedMap3"); assertThat(((EntryEventMessagePayload) msg - .getPayload()).key).isEqualTo(Integer.valueOf(2)); + .getPayload()).key()).isEqualTo(Integer.valueOf(2)); assertThat((((EntryEventMessagePayload) msg - .getPayload()).oldValue).getId()).isEqualTo(2); + .getPayload()).oldValue()).getId()).isEqualTo(2); assertThat((((EntryEventMessagePayload) msg - .getPayload()).oldValue).getName()).isEqualTo("TestName2"); + .getPayload()).oldValue()).getName()).isEqualTo("TestName2"); assertThat((((EntryEventMessagePayload) msg - .getPayload()).oldValue).getSurname()).isEqualTo("TestSurname2"); + .getPayload()).oldValue()).getSurname()).isEqualTo("TestSurname2"); } @Test diff --git a/spring-integration-hazelcast/src/test/java/org/springframework/integration/hazelcast/inbound/HazelcastMultiMapEventDrivenInboundChannelAdapterTests.java b/spring-integration-hazelcast/src/test/java/org/springframework/integration/hazelcast/inbound/HazelcastMultiMapEventDrivenInboundChannelAdapterTests.java index 4ac0268ebc0..e3d2d5745fb 100644 --- a/spring-integration-hazelcast/src/test/java/org/springframework/integration/hazelcast/inbound/HazelcastMultiMapEventDrivenInboundChannelAdapterTests.java +++ b/spring-integration-hazelcast/src/test/java/org/springframework/integration/hazelcast/inbound/HazelcastMultiMapEventDrivenInboundChannelAdapterTests.java @@ -77,13 +77,13 @@ public void testEventDrivenForOnlyADDEDEntryEvent() { assertThat(msg.getHeaders().get(HazelcastHeaders.CACHE_NAME)).isEqualTo("edMultiMap1"); assertThat(((EntryEventMessagePayload) msg - .getPayload()).key).isEqualTo(Integer.valueOf(1)); + .getPayload()).key()).isEqualTo(Integer.valueOf(1)); assertThat((((EntryEventMessagePayload) msg - .getPayload()).value).getId()).isEqualTo(1); + .getPayload()).value()).getId()).isEqualTo(1); assertThat((((EntryEventMessagePayload) msg - .getPayload()).value).getName()).isEqualTo("TestName1"); + .getPayload()).value()).getName()).isEqualTo("TestName1"); assertThat((((EntryEventMessagePayload) msg - .getPayload()).value).getSurname()).isEqualTo("TestSurname1"); + .getPayload()).value()).getSurname()).isEqualTo("TestSurname1"); } @Test @@ -103,14 +103,14 @@ public void testEventDrivenForOnlyREMOVEDEntryEvent() { assertThat(msg.getHeaders().get(HazelcastHeaders.CACHE_NAME)).isEqualTo("edMultiMap2"); assertThat(((EntryEventMessagePayload) msg - .getPayload()).key).isEqualTo(Integer.valueOf(2)); - assertThat(((EntryEventMessagePayload) msg.getPayload()).value).isNull(); + .getPayload()).key()).isEqualTo(Integer.valueOf(2)); + assertThat(((EntryEventMessagePayload) msg.getPayload()).value()).isNull(); assertThat((((EntryEventMessagePayload) msg - .getPayload()).oldValue).getId()).isEqualTo(2); + .getPayload()).oldValue()).getId()).isEqualTo(2); assertThat((((EntryEventMessagePayload) msg - .getPayload()).oldValue).getName()).isEqualTo("TestName2"); + .getPayload()).oldValue()).getName()).isEqualTo("TestName2"); assertThat((((EntryEventMessagePayload) msg - .getPayload()).oldValue).getSurname()).isEqualTo("TestSurname2"); + .getPayload()).oldValue()).getSurname()).isEqualTo("TestSurname2"); } @Test diff --git a/spring-integration-hazelcast/src/test/java/org/springframework/integration/hazelcast/inbound/HazelcastReplicatedMapEventDrivenInboundChannelAdapterTests.java b/spring-integration-hazelcast/src/test/java/org/springframework/integration/hazelcast/inbound/HazelcastReplicatedMapEventDrivenInboundChannelAdapterTests.java index e03d988bb76..5b00ecfdf34 100644 --- a/spring-integration-hazelcast/src/test/java/org/springframework/integration/hazelcast/inbound/HazelcastReplicatedMapEventDrivenInboundChannelAdapterTests.java +++ b/spring-integration-hazelcast/src/test/java/org/springframework/integration/hazelcast/inbound/HazelcastReplicatedMapEventDrivenInboundChannelAdapterTests.java @@ -83,13 +83,13 @@ public void testEventDrivenForOnlyADDEDEntryEvent() { assertThat(msg.getHeaders().get(HazelcastHeaders.CACHE_NAME)).isEqualTo("edReplicatedMap1"); assertThat(((EntryEventMessagePayload) msg - .getPayload()).key).isEqualTo(Integer.valueOf(1)); + .getPayload()).key()).isEqualTo(Integer.valueOf(1)); assertThat((((EntryEventMessagePayload) msg - .getPayload()).value).getId()).isEqualTo(1); + .getPayload()).value()).getId()).isEqualTo(1); assertThat((((EntryEventMessagePayload) msg - .getPayload()).value).getName()).isEqualTo("TestName1"); + .getPayload()).value()).getName()).isEqualTo("TestName1"); assertThat((((EntryEventMessagePayload) msg - .getPayload()).value).getSurname()).isEqualTo("TestSurname1"); + .getPayload()).value()).getSurname()).isEqualTo("TestSurname1"); } @Test @@ -109,19 +109,19 @@ public void testEventDrivenForOnlyUPDATEDEntryEvent() { assertThat(msg.getHeaders().get(HazelcastHeaders.CACHE_NAME)).isEqualTo("edReplicatedMap2"); assertThat(((EntryEventMessagePayload) msg - .getPayload()).key).isEqualTo(Integer.valueOf(2)); + .getPayload()).key()).isEqualTo(Integer.valueOf(2)); assertThat((((EntryEventMessagePayload) msg - .getPayload()).oldValue).getId()).isEqualTo(1); + .getPayload()).oldValue()).getId()).isEqualTo(1); assertThat((((EntryEventMessagePayload) msg - .getPayload()).oldValue).getName()).isEqualTo("TestName1"); + .getPayload()).oldValue()).getName()).isEqualTo("TestName1"); assertThat((((EntryEventMessagePayload) msg - .getPayload()).oldValue).getSurname()).isEqualTo("TestSurname1"); + .getPayload()).oldValue()).getSurname()).isEqualTo("TestSurname1"); assertThat((((EntryEventMessagePayload) msg - .getPayload()).value).getId()).isEqualTo(2); + .getPayload()).value()).getId()).isEqualTo(2); assertThat((((EntryEventMessagePayload) msg - .getPayload()).value).getName()).isEqualTo("TestName2"); + .getPayload()).value()).getName()).isEqualTo("TestName2"); assertThat((((EntryEventMessagePayload) msg - .getPayload()).value).getSurname()).isEqualTo("TestSurname2"); + .getPayload()).value()).getSurname()).isEqualTo("TestSurname2"); } @Test @@ -141,13 +141,13 @@ public void testEventDrivenForOnlyREMOVEDEntryEvent() { assertThat(msg.getHeaders().get(HazelcastHeaders.CACHE_NAME)).isEqualTo("edReplicatedMap3"); assertThat(((EntryEventMessagePayload) msg - .getPayload()).key).isEqualTo(Integer.valueOf(2)); + .getPayload()).key()).isEqualTo(Integer.valueOf(2)); assertThat((((EntryEventMessagePayload) msg - .getPayload()).oldValue).getId()).isEqualTo(2); + .getPayload()).oldValue()).getId()).isEqualTo(2); assertThat((((EntryEventMessagePayload) msg - .getPayload()).oldValue).getName()).isEqualTo("TestName2"); + .getPayload()).oldValue()).getName()).isEqualTo("TestName2"); assertThat((((EntryEventMessagePayload) msg - .getPayload()).oldValue).getSurname()).isEqualTo("TestSurname2"); + .getPayload()).oldValue()).getSurname()).isEqualTo("TestSurname2"); } @Test diff --git a/spring-integration-hazelcast/src/test/java/org/springframework/integration/hazelcast/inbound/util/HazelcastInboundChannelAdapterTestUtils.java b/spring-integration-hazelcast/src/test/java/org/springframework/integration/hazelcast/inbound/util/HazelcastInboundChannelAdapterTestUtils.java index df41a0f4f46..716e20d01e0 100644 --- a/spring-integration-hazelcast/src/test/java/org/springframework/integration/hazelcast/inbound/util/HazelcastInboundChannelAdapterTestUtils.java +++ b/spring-integration-hazelcast/src/test/java/org/springframework/integration/hazelcast/inbound/util/HazelcastInboundChannelAdapterTestUtils.java @@ -88,13 +88,13 @@ public static void testEventDrivenForADDEDDistributedMapEntryEvent( assertThat(msg.getHeaders().get(HazelcastHeaders.CACHE_NAME)).isEqualTo(cacheName); assertThat(((EntryEventMessagePayload) msg - .getPayload()).key).isEqualTo(Integer.valueOf(1)); + .getPayload()).key()).isEqualTo(Integer.valueOf(1)); assertThat((((EntryEventMessagePayload) msg - .getPayload()).value).getId()).isEqualTo(1); + .getPayload()).value()).getId()).isEqualTo(1); assertThat((((EntryEventMessagePayload) msg - .getPayload()).value).getName()).isEqualTo("TestName1"); + .getPayload()).value()).getName()).isEqualTo("TestName1"); assertThat((((EntryEventMessagePayload) msg - .getPayload()).value).getSurname()).isEqualTo("TestSurname1"); + .getPayload()).value()).getSurname()).isEqualTo("TestSurname1"); } public static void testEventDrivenForDistributedMapEntryEvents( @@ -223,11 +223,11 @@ public static void testContinuousQueryForUPDATEDEntryEventWhenIncludeValueIsFals assertThat(msg.getHeaders().get(HazelcastHeaders.CACHE_NAME)).isEqualTo(cacheName); assertThat(((EntryEventMessagePayload) msg - .getPayload()).key).isEqualTo(Integer.valueOf(1)); + .getPayload()).key()).isEqualTo(Integer.valueOf(1)); assertThat(((EntryEventMessagePayload) msg - .getPayload()).oldValue).isNull(); + .getPayload()).oldValue()).isNull(); assertThat(((EntryEventMessagePayload) msg - .getPayload()).value).isNull(); + .getPayload()).value()).isNull(); } public static void testDistributedSQLForENTRYIterationType( diff --git a/spring-integration-jpa/src/main/java/org/springframework/integration/jpa/support/parametersource/BeanPropertyParameterSource.java b/spring-integration-jpa/src/main/java/org/springframework/integration/jpa/support/parametersource/BeanPropertyParameterSource.java index 26aa420bcd2..7e46b21fff2 100644 --- a/spring-integration-jpa/src/main/java/org/springframework/integration/jpa/support/parametersource/BeanPropertyParameterSource.java +++ b/spring-integration-jpa/src/main/java/org/springframework/integration/jpa/support/parametersource/BeanPropertyParameterSource.java @@ -18,8 +18,11 @@ import java.beans.PropertyDescriptor; import java.util.ArrayList; +import java.util.Arrays; import java.util.List; +import org.jspecify.annotations.Nullable; + import org.springframework.beans.BeanWrapper; import org.springframework.beans.NotReadablePropertyException; import org.springframework.beans.PropertyAccessorFactory; @@ -29,6 +32,7 @@ * @author Gunnar Hillert * @author Gary Russell * @author Ngoc Nhan + * @author Artem Bilan * * @since 2.2 * @@ -37,7 +41,7 @@ public class BeanPropertyParameterSource implements ParameterSource { private final BeanWrapper beanWrapper; - private String[] propertyNames; + private String @Nullable [] propertyNames; /** * Create a new BeanPropertySqlParameterSource for the given bean. @@ -53,19 +57,18 @@ public boolean hasValue(String paramName) { } @Override - public Object getValue(String paramName) { + public @Nullable Object getValue(String paramName) { try { return this.beanWrapper.getPropertyValue(paramName); } catch (NotReadablePropertyException ex) { - throw new IllegalArgumentException(ex.getMessage()); // NOSONAR - lost stack trace + throw new IllegalArgumentException(ex.getMessage()); } } /** * Provide access to the property names of the wrapped bean. - * Uses support provided in the {@link org.springframework.beans.PropertyAccessor} - * interface. + * Uses support provided in the {@link org.springframework.beans.PropertyAccessor} interface. * @return an array containing all the known property names */ public String[] getReadablePropertyNames() { @@ -77,9 +80,9 @@ public String[] getReadablePropertyNames() { names.add(pd.getName()); } } - this.propertyNames = names.toArray(new String[names.size()]); + this.propertyNames = names.toArray(new String[0]); } - return this.propertyNames; // NOSONAR - expose internals + return Arrays.copyOf(this.propertyNames, this.propertyNames.length); } } diff --git a/spring-integration-jpa/src/main/java/org/springframework/integration/jpa/support/parametersource/BeanPropertyParameterSourceFactory.java b/spring-integration-jpa/src/main/java/org/springframework/integration/jpa/support/parametersource/BeanPropertyParameterSourceFactory.java index e29e6852ddc..4122537a1c5 100644 --- a/spring-integration-jpa/src/main/java/org/springframework/integration/jpa/support/parametersource/BeanPropertyParameterSourceFactory.java +++ b/spring-integration-jpa/src/main/java/org/springframework/integration/jpa/support/parametersource/BeanPropertyParameterSourceFactory.java @@ -20,10 +20,14 @@ import java.util.HashMap; import java.util.Map; +import org.jspecify.annotations.Nullable; + /** * * @author Gunnar Hillert * @author Gary Russell + * @author Artem Bilan + * * @since 2.2 * */ @@ -32,13 +36,12 @@ public class BeanPropertyParameterSourceFactory implements ParameterSourceFactor private volatile Map staticParameters; public BeanPropertyParameterSourceFactory() { - this.staticParameters = Collections.unmodifiableMap(new HashMap()); + this.staticParameters = Collections.unmodifiableMap(new HashMap<>()); } /** * If the input is a List or a Map, the output is a map parameter source, and in that case some static parameters * can be added (default is empty). If the input is not a List or a Map then this value is ignored. - * * @param staticParameters the static parameters to set */ public void setStaticParameters(Map staticParameters) { @@ -50,8 +53,7 @@ public ParameterSource createParameterSource(Object input) { return new StaticBeanPropertyParameterSource(input, this.staticParameters); } - private static final class StaticBeanPropertyParameterSource implements - ParameterSource { + private static final class StaticBeanPropertyParameterSource implements ParameterSource { private final BeanPropertyParameterSource input; @@ -63,9 +65,10 @@ private static final class StaticBeanPropertyParameterSource implements } @Override - public Object getValue(String paramName) { - return this.staticParameters.containsKey(paramName) ? this.staticParameters.get(paramName) : this.input - .getValue(paramName); + public @Nullable Object getValue(String paramName) { + return this.staticParameters.containsKey(paramName) + ? this.staticParameters.get(paramName) + : this.input.getValue(paramName); } @Override diff --git a/spring-integration-jpa/src/main/java/org/springframework/integration/jpa/support/parametersource/ExpressionEvaluatingParameterSourceFactory.java b/spring-integration-jpa/src/main/java/org/springframework/integration/jpa/support/parametersource/ExpressionEvaluatingParameterSourceFactory.java index d6212888e40..bb534b096dc 100644 --- a/spring-integration-jpa/src/main/java/org/springframework/integration/jpa/support/parametersource/ExpressionEvaluatingParameterSourceFactory.java +++ b/spring-integration-jpa/src/main/java/org/springframework/integration/jpa/support/parametersource/ExpressionEvaluatingParameterSourceFactory.java @@ -30,7 +30,6 @@ import org.springframework.expression.Expression; import org.springframework.expression.ExpressionException; import org.springframework.integration.jpa.support.JpaParameter; -import org.springframework.integration.jpa.support.parametersource.ExpressionEvaluatingParameterSourceUtils.ParameterExpressionEvaluator; import org.springframework.util.Assert; /** @@ -101,14 +100,16 @@ protected ExpressionEvaluatingParameterSource(Object input, List p this.parameters = parameters; this.parametersMap = new HashMap<>(parameters.size()); for (JpaParameter parameter : parameters) { - this.parametersMap.put(parameter.getName(), parameter); + String name = parameter.getName(); + if (name != null) { + this.parametersMap.put(name, parameter); + } } this.values.putAll(ExpressionEvaluatingParameterSourceUtils.convertStaticParameters(parameters)); } @Override - @Nullable - public Object getValueByPosition(int position) { + public @Nullable Object getValueByPosition(int position) { Assert.isTrue(position > 0, "The position must be non-negative."); if (position <= this.parameters.size()) { JpaParameter parameter = this.parameters.get(position - 1); @@ -124,8 +125,7 @@ public Object getValueByPosition(int position) { } @Override - @Nullable - public Object getValue(String paramName) { + public @Nullable Object getValue(String paramName) { return this.values.computeIfAbsent(paramName, (key) -> { JpaParameter jpaParameter = @@ -139,13 +139,11 @@ public Object getValue(String paramName) { }); } - @Nullable - private Object obtainParameterValue(JpaParameter jpaParameter) { - Object value = null; - if (jpaParameter.getValue() != null) { - value = jpaParameter.getValue(); - } - if (jpaParameter.getExpression() != null) { + private @Nullable Object obtainParameterValue(JpaParameter jpaParameter) { + Object value = jpaParameter.getValue(); + if (value == null) { + Assert.notNull(jpaParameter.getExpression(), + () -> "One of the 'value' or 'expression' must be provided for 'JpaParameter': " + jpaParameter); Expression expression; if (this.input instanceof Collection) { expression = jpaParameter.getProjectionExpression(); @@ -153,9 +151,11 @@ private Object obtainParameterValue(JpaParameter jpaParameter) { else { expression = jpaParameter.getSpelExpression(); } - value = this.expressionEvaluator.evaluateExpression(expression, this.input); // NOSONAR - if (LOGGER.isDebugEnabled()) { - LOGGER.debug("Resolved expression " + expression + " to " + value); + if (expression != null) { + value = this.expressionEvaluator.evaluateExpression(expression, this.input); + if (LOGGER.isDebugEnabled()) { + LOGGER.debug("Resolved expression " + expression + " to " + value); + } } } return value; diff --git a/spring-integration-jpa/src/main/java/org/springframework/integration/jpa/support/parametersource/ExpressionEvaluatingParameterSourceUtils.java b/spring-integration-jpa/src/main/java/org/springframework/integration/jpa/support/parametersource/ExpressionEvaluatingParameterSourceUtils.java index 45ad821328d..2020d68580d 100644 --- a/spring-integration-jpa/src/main/java/org/springframework/integration/jpa/support/parametersource/ExpressionEvaluatingParameterSourceUtils.java +++ b/spring-integration-jpa/src/main/java/org/springframework/integration/jpa/support/parametersource/ExpressionEvaluatingParameterSourceUtils.java @@ -20,12 +20,7 @@ import java.util.HashMap; import java.util.Map; -import org.jspecify.annotations.Nullable; - -import org.springframework.expression.EvaluationContext; -import org.springframework.expression.Expression; import org.springframework.integration.jpa.support.JpaParameter; -import org.springframework.integration.util.AbstractExpressionEvaluator; import org.springframework.util.Assert; /** @@ -58,31 +53,14 @@ public static Map convertStaticParameters(Collection staticParameters = new HashMap<>(); for (JpaParameter parameter : jpaParameters) { - if (parameter.getValue() != null) { - staticParameters.put(parameter.getName(), parameter.getValue()); + String name = parameter.getName(); + Object value = parameter.getValue(); + if (name != null && value != null) { + staticParameters.put(name, value); } } return staticParameters; } - /** - * Simple {@link AbstractExpressionEvaluator} implementation - * to increase the visibility of protected methods. - */ - public static class ParameterExpressionEvaluator extends AbstractExpressionEvaluator { - - @Override - public EvaluationContext getEvaluationContext() { // NOSONAR - not useless, increases visibility - return super.getEvaluationContext(); - } - - @Override - @Nullable - public Object evaluateExpression(Expression expression, Object input) { // NOSONAR - not useless, increases vis. - return super.evaluateExpression(expression, input); - } - - } - } diff --git a/spring-integration-jpa/src/main/java/org/springframework/integration/jpa/support/parametersource/ParameterExpressionEvaluator.java b/spring-integration-jpa/src/main/java/org/springframework/integration/jpa/support/parametersource/ParameterExpressionEvaluator.java new file mode 100644 index 00000000000..bfd5214dca8 --- /dev/null +++ b/spring-integration-jpa/src/main/java/org/springframework/integration/jpa/support/parametersource/ParameterExpressionEvaluator.java @@ -0,0 +1,45 @@ +/* + * Copyright 2025-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.integration.jpa.support.parametersource; + +import org.jspecify.annotations.Nullable; + +import org.springframework.expression.EvaluationContext; +import org.springframework.expression.Expression; +import org.springframework.integration.util.AbstractExpressionEvaluator; + +/** + * Simple {@link AbstractExpressionEvaluator} implementation + * to increase the visibility of protected methods. + * + * @author Artem Bilan + * + * @since 7.0 + */ +public class ParameterExpressionEvaluator extends AbstractExpressionEvaluator { + + @Override + public EvaluationContext getEvaluationContext() { + return super.getEvaluationContext(); + } + + @Override + public @Nullable Object evaluateExpression(Expression expression, Object input) { + return super.evaluateExpression(expression, input); + } + +} diff --git a/spring-integration-jpa/src/main/java/org/springframework/integration/jpa/support/parametersource/ParameterSource.java b/spring-integration-jpa/src/main/java/org/springframework/integration/jpa/support/parametersource/ParameterSource.java index 66667626124..b111d5ee0f1 100644 --- a/spring-integration-jpa/src/main/java/org/springframework/integration/jpa/support/parametersource/ParameterSource.java +++ b/spring-integration-jpa/src/main/java/org/springframework/integration/jpa/support/parametersource/ParameterSource.java @@ -16,9 +16,13 @@ package org.springframework.integration.jpa.support.parametersource; +import org.jspecify.annotations.Nullable; + /** * * @author Gunnar Hillert + * @author Artem Bilan + * * @since 2.2 * */ @@ -36,6 +40,7 @@ public interface ParameterSource { * @param paramName the name of the parameter * @return the value of the specified parameter */ + @Nullable Object getValue(String paramName); } diff --git a/spring-integration-jpa/src/main/java/org/springframework/integration/jpa/support/parametersource/PositionSupportingParameterSource.java b/spring-integration-jpa/src/main/java/org/springframework/integration/jpa/support/parametersource/PositionSupportingParameterSource.java index db0a765ced3..506bbc51d0c 100644 --- a/spring-integration-jpa/src/main/java/org/springframework/integration/jpa/support/parametersource/PositionSupportingParameterSource.java +++ b/spring-integration-jpa/src/main/java/org/springframework/integration/jpa/support/parametersource/PositionSupportingParameterSource.java @@ -16,14 +16,19 @@ package org.springframework.integration.jpa.support.parametersource; +import org.jspecify.annotations.Nullable; + /** * * @author Gunnar Hillert + * @author Artem Bilan + * * @since 2.2 * */ public interface PositionSupportingParameterSource extends ParameterSource { + @Nullable Object getValueByPosition(int position); } diff --git a/spring-integration-jpa/src/main/java/org/springframework/integration/jpa/support/parametersource/package-info.java b/spring-integration-jpa/src/main/java/org/springframework/integration/jpa/support/parametersource/package-info.java index 332a290284b..92a0e58b0d0 100644 --- a/spring-integration-jpa/src/main/java/org/springframework/integration/jpa/support/parametersource/package-info.java +++ b/spring-integration-jpa/src/main/java/org/springframework/integration/jpa/support/parametersource/package-info.java @@ -1,6 +1,7 @@ /** * Provides generic support for ParameterSources and ParameterSource Factories. - * This classes are modeled after the equivalent classes in the JDBC Module. However, + * These classes are modeled after the equivalent classes in the JDBC Module. However, * the provided classes here do not have any SQL or JPA specific dependencies. */ +@org.jspecify.annotations.NullMarked package org.springframework.integration.jpa.support.parametersource; diff --git a/spring-integration-test-support/src/main/java/org/springframework/integration/test/rule/Log4j2LevelAdjuster.java b/spring-integration-test-support/src/main/java/org/springframework/integration/test/rule/Log4j2LevelAdjuster.java index 4fbc44a40c3..73aeb2f91cf 100644 --- a/spring-integration-test-support/src/main/java/org/springframework/integration/test/rule/Log4j2LevelAdjuster.java +++ b/spring-integration-test-support/src/main/java/org/springframework/integration/test/rule/Log4j2LevelAdjuster.java @@ -20,6 +20,7 @@ import java.util.stream.Stream; import org.apache.logging.log4j.Level; +import org.jspecify.annotations.Nullable; import org.junit.rules.MethodRule; import org.junit.runners.model.FrameworkMethod; import org.junit.runners.model.Statement; @@ -57,7 +58,7 @@ private Log4j2LevelAdjuster(Level level) { this(level, null, new String[] {"org.springframework.integration"}); } - private Log4j2LevelAdjuster(Level level, Class[] classes, String[] categories) { + private Log4j2LevelAdjuster(Level level, Class @Nullable [] classes, String[] categories) { Assert.notNull(level, "'level' must be null"); this.level = level; this.classes = classes != null ? classes : new Class[0]; diff --git a/spring-integration-test-support/src/main/java/org/springframework/integration/test/rule/package-info.java b/spring-integration-test-support/src/main/java/org/springframework/integration/test/rule/package-info.java index f42e7946cb5..b1fc7e9b48f 100644 --- a/spring-integration-test-support/src/main/java/org/springframework/integration/test/rule/package-info.java +++ b/spring-integration-test-support/src/main/java/org/springframework/integration/test/rule/package-info.java @@ -1,4 +1,5 @@ /** * Provides various test rules. */ +@org.jspecify.annotations.NullMarked package org.springframework.integration.test.rule;