Add @Contract and @CheckReturnValue annotations.
Closes: #3195 Original pull request: #3210
This commit is contained in:
@@ -34,8 +34,6 @@ public @interface AccessType {
|
||||
|
||||
/**
|
||||
* The access type to be used.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
Type value();
|
||||
|
||||
|
||||
@@ -29,4 +29,5 @@ import java.lang.annotation.Target;
|
||||
*/
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target({ ElementType.CONSTRUCTOR, ElementType.METHOD, ElementType.ANNOTATION_TYPE })
|
||||
public @interface PersistenceCreator {}
|
||||
public @interface PersistenceCreator {
|
||||
}
|
||||
|
||||
@@ -36,8 +36,6 @@ public @interface Reference {
|
||||
/**
|
||||
* Explicitly define the target type of the reference. Used in case the annotated property is not the target type but
|
||||
* rather an identifier and/or if that identifier type is not uniquely identifying the target entity.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@AliasFor(attribute = "to")
|
||||
Class<?> value() default Class.class;
|
||||
@@ -45,8 +43,6 @@ public @interface Reference {
|
||||
/**
|
||||
* Explicitly define the target type of the reference. Used in case the annotated property is not the target type but
|
||||
* rather an identifier and/or if that identifier type is not uniquely identifying the target entity.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@AliasFor(attribute = "value")
|
||||
Class<?> to() default Class.class;
|
||||
|
||||
@@ -29,6 +29,7 @@ import org.springframework.data.mapping.PersistentEntity;
|
||||
* {@link PersistentEntity}s.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
* @see org.springframework.data.mapping.Alias
|
||||
*/
|
||||
@Documented
|
||||
@Inherited
|
||||
@@ -38,9 +39,7 @@ import org.springframework.data.mapping.PersistentEntity;
|
||||
public @interface TypeAlias {
|
||||
|
||||
/**
|
||||
* The type alias to be used when persisting
|
||||
*
|
||||
* @return
|
||||
* The type alias to be used when persisting.
|
||||
*/
|
||||
String value();
|
||||
}
|
||||
|
||||
@@ -33,5 +33,4 @@ import java.lang.annotation.Target;
|
||||
@Retention(RUNTIME)
|
||||
@Target(value = { FIELD, METHOD, ANNOTATION_TYPE })
|
||||
public @interface Version {
|
||||
|
||||
}
|
||||
|
||||
@@ -140,7 +140,7 @@ public interface AotContext {
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a {@link IntrospectedBeanDefinition} to obtain further detail about the underlying bean definition. A
|
||||
* Returns a {@link IntrospectedBeanDefinition} to obtain further detail about the underlying bean definition. An
|
||||
* introspected bean definition can also point to an absent bean definition.
|
||||
*
|
||||
* @param reference {@link BeanReference} to the managed bean.
|
||||
@@ -151,7 +151,7 @@ public interface AotContext {
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a {@link IntrospectedBeanDefinition} to obtain further detail about the underlying bean definition. A
|
||||
* Returns a {@link IntrospectedBeanDefinition} to obtain further detail about the underlying bean definition. An
|
||||
* introspected bean definition can also point to an absent bean definition.
|
||||
*
|
||||
* @param beanName {@link String} containing the {@literal name} of the bean to evaluate; must not be {@literal null}.
|
||||
@@ -251,7 +251,6 @@ public interface AotContext {
|
||||
* bean}.
|
||||
* @see BeanDefinition
|
||||
*/
|
||||
|
||||
BeanDefinition getBeanDefinition() throws NoSuchBeanDefinitionException;
|
||||
|
||||
/**
|
||||
|
||||
@@ -39,7 +39,6 @@ import org.springframework.util.ClassUtils;
|
||||
*/
|
||||
class AuditingBeanRegistrationAotProcessor implements BeanRegistrationAotProcessor {
|
||||
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public BeanRegistrationAotContribution processAheadOfTime(RegisteredBean registeredBean) {
|
||||
|
||||
@@ -29,6 +29,7 @@ import org.springframework.beans.factory.config.ConstructorArgumentValues.ValueH
|
||||
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
|
||||
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
|
||||
import org.springframework.data.domain.ManagedTypes;
|
||||
import org.springframework.lang.Contract;
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
import org.springframework.util.ObjectUtils;
|
||||
@@ -44,10 +45,11 @@ import org.springframework.util.ObjectUtils;
|
||||
*/
|
||||
public class ManagedTypesBeanFactoryInitializationAotProcessor implements BeanFactoryInitializationAotProcessor {
|
||||
|
||||
private static final Log logger = LogFactory.getLog(BeanFactoryInitializationAotProcessor.class);
|
||||
private static final Log logger = LogFactory.getLog(ManagedTypesBeanFactoryInitializationAotProcessor.class);
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
@Nullable
|
||||
@Contract("_ -> null")
|
||||
public BeanFactoryInitializationAotContribution processAheadOfTime(ConfigurableListableBeanFactory beanFactory) {
|
||||
|
||||
processManagedTypes(beanFactory);
|
||||
@@ -71,9 +73,9 @@ public class ManagedTypesBeanFactoryInitializationAotProcessor implements BeanFa
|
||||
|
||||
if (hasConstructorArguments(beanDefinition)) {
|
||||
|
||||
ValueHolder argumentValue = beanDefinition.getConstructorArgumentValues().getArgumentValue(0, null, null, null);
|
||||
ValueHolder holder = beanDefinition.getConstructorArgumentValues().getArgumentValue(0, null, null, null);
|
||||
|
||||
if (argumentValue.getValue()instanceof Supplier supplier) {
|
||||
if (holder != null && holder.getValue() instanceof Supplier<?> supplier) {
|
||||
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.info(String.format("Replacing ManagedType bean definition %s.", beanName));
|
||||
|
||||
@@ -78,9 +78,9 @@ public class ManagedTypesBeanRegistrationAotProcessor implements BeanRegistratio
|
||||
if (beanDefinition.hasConstructorArgumentValues()) {
|
||||
|
||||
ValueHolder indexedArgumentValue = beanDefinition.getConstructorArgumentValues().getIndexedArgumentValue(0, null);
|
||||
Object value = indexedArgumentValue.getValue();
|
||||
|
||||
if (value instanceof Collection<?> values && values.stream().allMatch(it -> it instanceof Class)) {
|
||||
if (indexedArgumentValue != null && indexedArgumentValue.getValue() instanceof Collection<?> values
|
||||
&& values.stream().allMatch(it -> it instanceof Class)) {
|
||||
return ManagedTypes.fromIterable((Collection<Class<?>>) values);
|
||||
}
|
||||
}
|
||||
@@ -115,7 +115,6 @@ public class ManagedTypesBeanRegistrationAotProcessor implements BeanRegistratio
|
||||
* @param managedTypes never {@literal null}.
|
||||
* @return new instance of {@link BeanRegistrationAotContribution} or {@literal null} if nothing to do.
|
||||
*/
|
||||
@Nullable
|
||||
protected BeanRegistrationAotContribution contribute(AotContext aotContext, ManagedTypes managedTypes,
|
||||
RegisteredBean registeredBean) {
|
||||
return new ManagedTypesRegistrationAotContribution(managedTypes, registeredBean, this::contributeType);
|
||||
|
||||
@@ -68,8 +68,8 @@ import org.springframework.util.ReflectionUtils;
|
||||
* @author John Blum
|
||||
* @author Christoph Strobl
|
||||
* @author Mark Paluch
|
||||
* @see org.springframework.beans.factory.aot.BeanRegistrationAotContribution
|
||||
* @since 3.0
|
||||
* @see org.springframework.beans.factory.aot.BeanRegistrationAotContribution
|
||||
*/
|
||||
class ManagedTypesRegistrationAotContribution implements RegisteredBeanAotContribution {
|
||||
|
||||
@@ -125,7 +125,7 @@ class ManagedTypesRegistrationAotContribution implements RegisteredBeanAotContri
|
||||
public static final ResolvableType MANAGED_TYPES_TYPE = ResolvableType.forType(ManagedTypes.class);
|
||||
private final List<Class<?>> sourceTypes;
|
||||
private final RegisteredBean source;
|
||||
private final Lazy<Method> instanceMethod = Lazy.of(this::findInstanceFactory);
|
||||
private final Lazy<Method> instanceMethod;
|
||||
|
||||
private static final TypeName WILDCARD = WildcardTypeName.subtypeOf(Object.class);
|
||||
private static final TypeName CLASS_OF_ANY = ParameterizedTypeName.get(ClassName.get(Class.class), WILDCARD);
|
||||
@@ -138,6 +138,7 @@ class ManagedTypesRegistrationAotContribution implements RegisteredBeanAotContri
|
||||
|
||||
this.sourceTypes = sourceTypes;
|
||||
this.source = source;
|
||||
this.instanceMethod = Lazy.of(() -> findInstanceFactory(source.getBeanClass()));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -229,15 +230,15 @@ class ManagedTypesRegistrationAotContribution implements RegisteredBeanAotContri
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private Method findInstanceFactory() {
|
||||
private static Method findInstanceFactory(Class<?> beanClass) {
|
||||
|
||||
for (Method beanMethod : ReflectionUtils.getDeclaredMethods(source.getBeanClass())) {
|
||||
for (Method beanMethod : ReflectionUtils.getDeclaredMethods(beanClass)) {
|
||||
|
||||
if (!isInstanceFactory(beanMethod)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
ResolvableType parameterType = ResolvableType.forMethodParameter(beanMethod, 0, source.getBeanClass());
|
||||
ResolvableType parameterType = ResolvableType.forMethodParameter(beanMethod, 0, beanClass);
|
||||
|
||||
if (parameterType.isAssignableFrom(LIST_TYPE) || parameterType.isAssignableFrom(MANAGED_TYPES_TYPE)) {
|
||||
return beanMethod;
|
||||
|
||||
@@ -20,6 +20,8 @@ import org.springframework.aot.hint.ReflectionHints;
|
||||
import org.springframework.aot.hint.annotation.SimpleReflectiveProcessor;
|
||||
|
||||
/**
|
||||
* Extension to {@link SimpleReflectiveProcessor} to register reflective hints for invoking public methods.
|
||||
*
|
||||
* @author Christoph Strobl
|
||||
*/
|
||||
public class PublicMethodReflectiveProcessor extends SimpleReflectiveProcessor {
|
||||
|
||||
@@ -19,7 +19,7 @@ import org.springframework.beans.factory.aot.BeanRegistrationAotContribution;
|
||||
import org.springframework.beans.factory.support.RegisteredBean;
|
||||
|
||||
/**
|
||||
* Extension to {@link BeanRegistrationAotContribution} that bases its contribution on a {@link RegisteredBean}. This
|
||||
* Extension to {@link BeanRegistrationAotContribution} that bases its contribution to a {@link RegisteredBean}. This
|
||||
* interface exposes its {@link #getSource() source}.
|
||||
*
|
||||
* @author Christoph Strobl
|
||||
|
||||
@@ -18,6 +18,9 @@ package org.springframework.data.auditing;
|
||||
import java.time.temporal.TemporalAccessor;
|
||||
import java.util.Optional;
|
||||
|
||||
import org.springframework.lang.Contract;
|
||||
import org.springframework.lang.Nullable;
|
||||
|
||||
/**
|
||||
* Interface to abstract the ways setting the auditing information can be implemented.
|
||||
*
|
||||
@@ -31,7 +34,9 @@ public interface AuditableBeanWrapper<T> {
|
||||
*
|
||||
* @param value
|
||||
*/
|
||||
Object setCreatedBy(Object value);
|
||||
@Nullable
|
||||
@Contract("null -> null; !null -> !null")
|
||||
Object setCreatedBy(@Nullable Object value);
|
||||
|
||||
/**
|
||||
* Set the date the object was created.
|
||||
@@ -45,7 +50,9 @@ public interface AuditableBeanWrapper<T> {
|
||||
*
|
||||
* @param value
|
||||
*/
|
||||
Object setLastModifiedBy(Object value);
|
||||
@Nullable
|
||||
@Contract("null -> null; !null -> !null")
|
||||
Object setLastModifiedBy(@Nullable Object value);
|
||||
|
||||
/**
|
||||
* Returns the date of the last modification date of the backing bean.
|
||||
|
||||
@@ -104,9 +104,10 @@ public class AuditingHandler extends AuditingHandlerSupport implements Initializ
|
||||
.orElse(Auditor.none());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterPropertiesSet() {
|
||||
|
||||
if (!auditorAware.isPresent()) {
|
||||
if (auditorAware.isEmpty()) {
|
||||
logger.debug("No AuditorAware set; Auditing will not be applied");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -151,11 +151,6 @@ public abstract class AuditingHandlerSupport {
|
||||
|
||||
/**
|
||||
* Sets modifying and creating auditor. Creating auditor is only set on new auditables.
|
||||
*
|
||||
* @param auditor
|
||||
* @param wrapper
|
||||
* @param isNew
|
||||
* @return
|
||||
*/
|
||||
private void touchAuditor(Auditor<?> auditor, AuditableBeanWrapper<?> wrapper, boolean isNew) {
|
||||
|
||||
@@ -176,10 +171,6 @@ public abstract class AuditingHandlerSupport {
|
||||
|
||||
/**
|
||||
* Touches the auditable regarding modification and creation date. Creation date is only set on new auditables.
|
||||
*
|
||||
* @param wrapper
|
||||
* @param isNew
|
||||
* @return
|
||||
*/
|
||||
private Optional<TemporalAccessor> touchDate(AuditableBeanWrapper<?> wrapper, boolean isNew) {
|
||||
|
||||
|
||||
@@ -28,7 +28,7 @@ import org.springframework.util.ObjectUtils;
|
||||
*/
|
||||
class Auditor<T> {
|
||||
|
||||
private static final Auditor NONE = new Auditor(null) {
|
||||
private static final Auditor<Object> NONE = new Auditor<>(null) {
|
||||
|
||||
@Override
|
||||
public boolean isPresent() {
|
||||
@@ -59,6 +59,7 @@ class Auditor<T> {
|
||||
* @param <T>
|
||||
* @return {@link Auditor#none()} if the given {@literal source} is {@literal null}. }
|
||||
*/
|
||||
@SuppressWarnings({ "unchecked", "rawtypes" })
|
||||
public static <T> Auditor<T> of(@Nullable T source) {
|
||||
|
||||
if (source instanceof Auditor) {
|
||||
@@ -77,7 +78,7 @@ class Auditor<T> {
|
||||
* @param <T>
|
||||
* @return {@link Auditor#none()} if the given {@literal source} is {@literal null}. }
|
||||
*/
|
||||
public static <T> Auditor<T> ofOptional(@Nullable Optional<T> source) {
|
||||
public static <T> Auditor<T> ofOptional(Optional<T> source) {
|
||||
return Auditor.of(source.orElse(null));
|
||||
}
|
||||
|
||||
@@ -87,8 +88,9 @@ class Auditor<T> {
|
||||
* @param <T>
|
||||
* @return never {@literal null}.
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public static <T> Auditor<T> none() {
|
||||
return NONE;
|
||||
return (Auditor<T>) NONE;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -115,7 +115,7 @@ class DefaultAuditableBeanWrapperFactory implements AuditableBeanWrapperFactory
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object setCreatedBy(Object value) {
|
||||
public Object setCreatedBy(@Nullable Object value) {
|
||||
|
||||
auditable.setCreatedBy(value);
|
||||
return value;
|
||||
@@ -267,7 +267,7 @@ class DefaultAuditableBeanWrapperFactory implements AuditableBeanWrapperFactory
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object setCreatedBy(Object value) {
|
||||
public Object setCreatedBy(@Nullable Object value) {
|
||||
return setField(metadata.getCreatedByField(), value);
|
||||
}
|
||||
|
||||
@@ -277,7 +277,7 @@ class DefaultAuditableBeanWrapperFactory implements AuditableBeanWrapperFactory
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object setLastModifiedBy(Object value) {
|
||||
public Object setLastModifiedBy(@Nullable Object value) {
|
||||
return setField(metadata.getLastModifiedByField(), value);
|
||||
}
|
||||
|
||||
@@ -308,7 +308,8 @@ class DefaultAuditableBeanWrapperFactory implements AuditableBeanWrapperFactory
|
||||
* @param field
|
||||
* @param value
|
||||
*/
|
||||
private <S> S setField(Optional<Field> field, S value) {
|
||||
@Nullable
|
||||
private <S> S setField(Optional<Field> field, @Nullable S value) {
|
||||
|
||||
field.ifPresent(it -> ReflectionUtils.setField(it, target, value));
|
||||
|
||||
|
||||
@@ -40,6 +40,8 @@ import org.springframework.data.mapping.PersistentPropertyPaths;
|
||||
import org.springframework.data.mapping.context.MappingContext;
|
||||
import org.springframework.data.mapping.context.PersistentEntities;
|
||||
import org.springframework.data.util.Lazy;
|
||||
import org.springframework.lang.Contract;
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
@@ -203,7 +205,7 @@ public class MappingAuditableBeanWrapperFactory extends DefaultAuditableBeanWrap
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object setLastModifiedBy(Object value) {
|
||||
public Object setLastModifiedBy(@Nullable Object value) {
|
||||
return setProperty(metadata.lastModifiedByPaths, value);
|
||||
}
|
||||
|
||||
@@ -226,8 +228,10 @@ public class MappingAuditableBeanWrapperFactory extends DefaultAuditableBeanWrap
|
||||
return accessor.getBean();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Contract("_, null -> null; _, !null -> !null")
|
||||
private <S> S setProperty(
|
||||
PersistentPropertyPaths<?, ? extends PersistentProperty<?>> paths, S value) {
|
||||
PersistentPropertyPaths<?, ? extends PersistentProperty<?>> paths, @Nullable S value) {
|
||||
|
||||
paths.forEach(it -> this.accessor.setProperty(it, value, OPTIONS));
|
||||
|
||||
|
||||
@@ -65,7 +65,7 @@ public abstract class AuditingBeanDefinitionRegistrarSupport implements ImportBe
|
||||
*
|
||||
* @param configuration must not be {@literal null}.
|
||||
* @param registry must not be {@literal null}.
|
||||
* @return
|
||||
* @return the {@link AbstractBeanDefinition} for the {@link AuditingConfiguration}.
|
||||
*/
|
||||
protected AbstractBeanDefinition registerAuditHandlerBeanDefinition(AuditingConfiguration configuration,
|
||||
BeanDefinitionRegistry registry) {
|
||||
@@ -96,7 +96,7 @@ public abstract class AuditingBeanDefinitionRegistrarSupport implements ImportBe
|
||||
* implementations.
|
||||
*
|
||||
* @param configuration must not be {@literal null}.
|
||||
* @return
|
||||
* @return the {@link BeanDefinitionBuilder} for the {@link AuditingConfiguration}.
|
||||
*/
|
||||
protected BeanDefinitionBuilder getAuditHandlerBeanDefinitionBuilder(AuditingConfiguration configuration) {
|
||||
|
||||
@@ -142,7 +142,7 @@ public abstract class AuditingBeanDefinitionRegistrarSupport implements ImportBe
|
||||
* Retrieve auditing configuration from the given {@link AnnotationMetadata}.
|
||||
*
|
||||
* @param annotationMetadata will never be {@literal null}.
|
||||
* @return
|
||||
* @return a new {@link AnnotationAuditingConfiguration}.
|
||||
*/
|
||||
protected AuditingConfiguration getConfiguration(AnnotationMetadata annotationMetadata) {
|
||||
return new AnnotationAuditingConfiguration(annotationMetadata, getAnnotation());
|
||||
@@ -167,7 +167,7 @@ public abstract class AuditingBeanDefinitionRegistrarSupport implements ImportBe
|
||||
/**
|
||||
* Return the name to be used to register the {@link AuditingHandler} under.
|
||||
*
|
||||
* @return
|
||||
* @return name of the {@link AuditingHandler} bean.
|
||||
*/
|
||||
protected abstract String getAuditingHandlerBeanName();
|
||||
|
||||
|
||||
@@ -29,9 +29,9 @@ import org.springframework.data.auditing.AuditingHandler;
|
||||
import org.springframework.data.config.ParsingUtils;
|
||||
import org.springframework.data.mapping.context.MappingContext;
|
||||
import org.springframework.data.repository.config.PersistentEntitiesFactoryBean;
|
||||
import org.springframework.lang.NonNull;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
import org.w3c.dom.Element;
|
||||
|
||||
/**
|
||||
@@ -69,7 +69,6 @@ public class AuditingHandlerBeanDefinitionParser extends AbstractSingleBeanDefin
|
||||
return resolvedBeanName;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
protected Class<?> getBeanClass(Element element) {
|
||||
return AuditingHandler.class;
|
||||
|
||||
@@ -38,7 +38,7 @@ public interface ConfigurationUtils {
|
||||
* @return
|
||||
* @throws IllegalArgumentException if no {@link ResourceLoader} can be obtained from the {@link XmlReaderContext}.
|
||||
*/
|
||||
public static ResourceLoader getRequiredResourceLoader(XmlReaderContext context) {
|
||||
static ResourceLoader getRequiredResourceLoader(XmlReaderContext context) {
|
||||
|
||||
Assert.notNull(context, "XmlReaderContext must not be null");
|
||||
|
||||
@@ -58,7 +58,7 @@ public interface ConfigurationUtils {
|
||||
* @return
|
||||
* @throws IllegalArgumentException if no {@link ClassLoader} can be obtained from the given {@link XmlReaderContext}.
|
||||
*/
|
||||
public static ClassLoader getRequiredClassLoader(XmlReaderContext context) {
|
||||
static ClassLoader getRequiredClassLoader(XmlReaderContext context) {
|
||||
return getRequiredClassLoader(getRequiredResourceLoader(context));
|
||||
}
|
||||
|
||||
@@ -69,7 +69,7 @@ public interface ConfigurationUtils {
|
||||
* @return
|
||||
* @throws IllegalArgumentException if the given {@link ResourceLoader} does not expose a {@link ClassLoader}.
|
||||
*/
|
||||
public static ClassLoader getRequiredClassLoader(ResourceLoader resourceLoader) {
|
||||
static ClassLoader getRequiredClassLoader(ResourceLoader resourceLoader) {
|
||||
|
||||
Assert.notNull(resourceLoader, "ResourceLoader must not be null");
|
||||
|
||||
@@ -89,7 +89,7 @@ public interface ConfigurationUtils {
|
||||
* @return
|
||||
* @throws IllegalArgumentException if the given {@link BeanDefinition} does not contain a bean class name.
|
||||
*/
|
||||
public static String getRequiredBeanClassName(BeanDefinition beanDefinition) {
|
||||
static String getRequiredBeanClassName(BeanDefinition beanDefinition) {
|
||||
|
||||
Assert.notNull(beanDefinition, "BeanDefinition must not be null");
|
||||
|
||||
|
||||
@@ -27,12 +27,15 @@ import org.springframework.util.Assert;
|
||||
*/
|
||||
class AnnotatedPropertyValueConverterAccessor {
|
||||
|
||||
private final String name;
|
||||
private final ValueConverter annotation;
|
||||
|
||||
public AnnotatedPropertyValueConverterAccessor(PersistentProperty<?> property) {
|
||||
|
||||
Assert.notNull(property, "PersistentProperty must not be null");
|
||||
annotation = property.findAnnotation(ValueConverter.class);
|
||||
|
||||
this.name = property.toString();
|
||||
this.annotation = property.findAnnotation(ValueConverter.class);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -48,6 +51,28 @@ class AnnotatedPropertyValueConverterAccessor {
|
||||
return annotation != null ? (Class) annotation.value() : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Obtain the required {@link PropertyValueConverter converter type} to be used for reading and writing property
|
||||
* values. Uses the {@link ValueConverter} annotation and extracts its {@link ValueConverter#value() value} attribute.
|
||||
* Throws {@link IllegalStateException} if no converter is defined.
|
||||
*
|
||||
* @return {@literal null} if none defined. Check {@link #hasValueConverter()} to check if the annotation is present
|
||||
* at all.
|
||||
* @since 4.0
|
||||
* @throws IllegalStateException if no converter is defined.
|
||||
*/
|
||||
public Class<? extends PropertyValueConverter<?, ?, ? extends ValueConversionContext<? extends PersistentProperty<?>>>> getRequiredValueConverterType()
|
||||
throws IllegalStateException {
|
||||
|
||||
Class<? extends PropertyValueConverter<?, ?, ? extends ValueConversionContext<? extends PersistentProperty<?>>>> converterType = getValueConverterType();
|
||||
|
||||
if (converterType == null) {
|
||||
throw new IllegalStateException("No converter defined for property '" + name + "'");
|
||||
}
|
||||
|
||||
return converterType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return whether a value converter is configured. Uses {@link ValueConverter} as annotation type.
|
||||
*
|
||||
|
||||
@@ -198,10 +198,6 @@ public class CustomConversions {
|
||||
* @param type {@link Class} to evaluate as a simple type, such as a primitive type.
|
||||
* @return a boolean value indicating whether the given, required {@link Class type} is simple.
|
||||
*/
|
||||
// TODO: Technically, an 'isXyz(..)' method (returning a boolean to answer a user's question should not throw an
|
||||
// Exception).
|
||||
// Rather, a null Class type argument should simply return false to indicate it is clearly not a "simple type".
|
||||
// How much data store specific code relies on the existing behavior?
|
||||
public boolean isSimpleType(Class<?> type) {
|
||||
|
||||
Assert.notNull(type, "Type must not be null");
|
||||
@@ -229,6 +225,7 @@ public class CustomConversions {
|
||||
* @param candidate must not be {@literal null}.
|
||||
* @param conversionService must not be {@literal null}.
|
||||
*/
|
||||
@SuppressWarnings("rawtypes")
|
||||
private void registerConverterIn(Object candidate, ConverterRegistry conversionService) {
|
||||
|
||||
if (candidate instanceof Converter converter) {
|
||||
@@ -669,7 +666,7 @@ public class CustomConversions {
|
||||
return isConverterOfSource(ConverterOrigin.DEFAULT);
|
||||
}
|
||||
|
||||
public ConverterRegistration getConverterRegistration() {
|
||||
ConverterRegistration getConverterRegistration() {
|
||||
return delegate;
|
||||
}
|
||||
|
||||
@@ -815,7 +812,7 @@ public class CustomConversions {
|
||||
* @param converter must not be {@literal null}.
|
||||
* @return
|
||||
*/
|
||||
public Streamable<ConverterRegistration> getRegistrationsFor(Object converter) {
|
||||
Streamable<ConverterRegistration> getRegistrationsFor(Object converter) {
|
||||
|
||||
Assert.notNull(converter, "Converter must not be null");
|
||||
|
||||
|
||||
@@ -141,8 +141,8 @@ public class DefaultTypeMapper<S> implements TypeMapper<S>, BeanClassLoaderAware
|
||||
|
||||
Class<T> rawType = basicType.getType();
|
||||
|
||||
boolean isMoreConcreteCustomType = (rawType == null)
|
||||
|| (rawType.isAssignableFrom(documentsTargetType) && !rawType.equals(documentsTargetType));
|
||||
boolean isMoreConcreteCustomType = (rawType.isAssignableFrom(documentsTargetType)
|
||||
&& !rawType.equals(documentsTargetType));
|
||||
|
||||
if (!isMoreConcreteCustomType) {
|
||||
return basicType;
|
||||
@@ -163,10 +163,9 @@ public class DefaultTypeMapper<S> implements TypeMapper<S>, BeanClassLoaderAware
|
||||
@Nullable
|
||||
private Class<?> getDefaultedTypeToBeUsed(S source) {
|
||||
|
||||
TypeInformation<?> documentsTargetTypeInformation = readType(source);
|
||||
documentsTargetTypeInformation = documentsTargetTypeInformation == null ? getFallbackTypeFor(source)
|
||||
: documentsTargetTypeInformation;
|
||||
return documentsTargetTypeInformation == null ? null : documentsTargetTypeInformation.getType();
|
||||
TypeInformation<?> type = readType(source);
|
||||
type = type == null ? getFallbackTypeFor(source) : type;
|
||||
return type == null ? null : type.getType();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -192,7 +191,7 @@ public class DefaultTypeMapper<S> implements TypeMapper<S>, BeanClassLoaderAware
|
||||
|
||||
Alias alias = getAliasFor(info);
|
||||
if (alias.isPresent()) {
|
||||
accessor.writeTypeTo(sink, alias.getValue());
|
||||
accessor.writeTypeTo(sink, alias.getRequiredValue());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -27,7 +27,7 @@ import org.springframework.data.mapping.context.MappingContext;
|
||||
import org.springframework.data.mapping.model.EntityInstantiator;
|
||||
import org.springframework.data.mapping.model.EntityInstantiators;
|
||||
import org.springframework.data.mapping.model.ParameterValueProvider;
|
||||
import org.springframework.lang.NonNull;
|
||||
import org.springframework.lang.Contract;
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
@@ -64,8 +64,8 @@ public class DtoInstantiatingConverter implements Converter<Object, Object> {
|
||||
this.instantiator = instantiators.getInstantiatorFor(context.getRequiredPersistentEntity(dtoType));
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
@Contract("_ -> !null")
|
||||
public Object convert(Object source) {
|
||||
|
||||
if (targetType.isInterface()) {
|
||||
@@ -82,6 +82,7 @@ public class DtoInstantiatingConverter implements Converter<Object, Object> {
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
@SuppressWarnings({ "rawtypes" })
|
||||
public Object getParameterValue(Parameter parameter) {
|
||||
|
||||
String name = parameter.getName();
|
||||
|
||||
@@ -27,7 +27,7 @@ public interface EntityReader<T, S> {
|
||||
*
|
||||
* @param type they type to convert the given source to.
|
||||
* @param source the source to create an object of the given type from.
|
||||
* @return
|
||||
* @return the converted object.
|
||||
*/
|
||||
<R extends T> R read(Class<R> type, S source);
|
||||
}
|
||||
|
||||
@@ -24,5 +24,11 @@ package org.springframework.data.convert;
|
||||
*/
|
||||
public interface EntityWriter<T, S> {
|
||||
|
||||
/**
|
||||
* Writes the given source object into a store specific sink.
|
||||
*
|
||||
* @param source the source to create an object of the given type from.
|
||||
* @param sink the sink to write into.
|
||||
*/
|
||||
void write(T source, S sink);
|
||||
}
|
||||
|
||||
@@ -54,8 +54,7 @@ public class JMoleculesConverters {
|
||||
|
||||
List<Object> converters = new ArrayList<>();
|
||||
|
||||
Supplier<ConversionService> conversionService = (Supplier<ConversionService>) () -> DefaultConversionService
|
||||
.getSharedInstance();
|
||||
Supplier<ConversionService> conversionService = DefaultConversionService::getSharedInstance;
|
||||
|
||||
IdentifierToPrimitivesConverter toPrimitives = new IdentifierToPrimitivesConverter(conversionService);
|
||||
PrimitivesToIdentifierConverter toIdentifier = new PrimitivesToIdentifierConverter(conversionService);
|
||||
|
||||
@@ -65,7 +65,7 @@ public class MappingContextTypeInformationMapper implements TypeInformationMappe
|
||||
|
||||
PersistentEntity<?, ? extends PersistentProperty<?>> entity = mappingContext.getPersistentEntity(key);
|
||||
|
||||
if (entity == null || entity.getTypeAlias() == null) {
|
||||
if (entity == null || entity.getTypeAlias().isEmpty()) {
|
||||
return Alias.NONE;
|
||||
}
|
||||
|
||||
|
||||
@@ -27,6 +27,7 @@ import org.springframework.beans.BeanUtils;
|
||||
import org.springframework.beans.factory.BeanFactory;
|
||||
import org.springframework.beans.factory.config.AutowireCapableBeanFactory;
|
||||
import org.springframework.data.mapping.PersistentProperty;
|
||||
import org.springframework.lang.Contract;
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
@@ -175,6 +176,7 @@ final class PropertyValueConverterFactories {
|
||||
* @author Christoph Strobl
|
||||
* @since 2.7
|
||||
*/
|
||||
@SuppressWarnings("OptionalAssignedToNull")
|
||||
static class CachingPropertyValueConverterFactory implements PropertyValueConverterFactory {
|
||||
|
||||
private final PropertyValueConverterFactory delegate;
|
||||
@@ -225,6 +227,8 @@ final class PropertyValueConverterFactories {
|
||||
return typeCache.get(type);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Contract("_, null -> null;_, !null -> !null")
|
||||
<S, T, C extends ValueConversionContext<?>> PropertyValueConverter<S, T, C> cache(PersistentProperty<?> property,
|
||||
@Nullable PropertyValueConverter<S, T, C> converter) {
|
||||
|
||||
@@ -241,6 +245,8 @@ final class PropertyValueConverterFactories {
|
||||
return converter;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Contract("_, null -> null;_, !null -> !null")
|
||||
<S, T, C extends ValueConversionContext<?>> PropertyValueConverter<S, T, C> cache(Class<?> type,
|
||||
@Nullable PropertyValueConverter<S, T, C> converter) {
|
||||
|
||||
|
||||
@@ -60,7 +60,7 @@ public interface PropertyValueConverterFactory {
|
||||
return null;
|
||||
}
|
||||
|
||||
return getConverter((Class<PropertyValueConverter<DV, SV, P>>) accessor.getValueConverterType());
|
||||
return getConverter((Class<PropertyValueConverter<DV, SV, P>>) accessor.getRequiredValueConverterType());
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -22,6 +22,7 @@ import java.util.function.Function;
|
||||
import org.springframework.data.convert.PropertyValueConverter.FunctionPropertyValueConverter;
|
||||
import org.springframework.data.mapping.PersistentProperty;
|
||||
import org.springframework.data.util.MethodInvocationRecorder;
|
||||
import org.springframework.lang.Contract;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
@@ -87,6 +88,7 @@ public class PropertyValueConverterRegistrar<P extends PersistentProperty<P>> {
|
||||
* @param converter the {@link PropertyValueConverter converter} to apply.
|
||||
* @return this.
|
||||
*/
|
||||
@Contract("_, _, _ -> this")
|
||||
public PropertyValueConverterRegistrar<P> registerConverter(Class<?> type, String path,
|
||||
PropertyValueConverter<?, ?, ? extends ValueConversionContext<?>> converter) {
|
||||
|
||||
|
||||
@@ -67,6 +67,7 @@ public class SimplePropertyValueConverterRegistry<P extends PersistentProperty<P
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public <S, T> PropertyValueConverter<S, T, ? extends ValueConversionContext<P>> getConverter(Class<?> type,
|
||||
String path) {
|
||||
|
||||
|
||||
@@ -35,12 +35,14 @@ public class ChangeSetBackedTransactionSynchronization implements TransactionSyn
|
||||
this.entity = entity;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterCommit() {
|
||||
logger.debug("After Commit called for " + entity);
|
||||
changeSetPersister.persistState(entity, entity.getChangeSet());
|
||||
changeSetTxStatus = 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterCompletion(int status) {
|
||||
logger.debug("After Completion called with status = " + status);
|
||||
if (changeSetTxStatus == 0) {
|
||||
@@ -54,20 +56,13 @@ public class ChangeSetBackedTransactionSynchronization implements TransactionSyn
|
||||
}
|
||||
}
|
||||
|
||||
public void beforeCommit(boolean readOnly) {
|
||||
}
|
||||
|
||||
public void beforeCompletion() {
|
||||
}
|
||||
|
||||
public void flush() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void resume() {
|
||||
throw new IllegalStateException(
|
||||
"ChangedSetBackedTransactionSynchronization does not support transaction suspension currently");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void suspend() {
|
||||
throw new IllegalStateException(
|
||||
"ChangedSetBackedTransactionSynchronization does not support transaction suspension currently");
|
||||
|
||||
@@ -15,6 +15,8 @@
|
||||
*/
|
||||
package org.springframework.data.crossstore;
|
||||
|
||||
import java.io.Serial;
|
||||
|
||||
import org.springframework.dao.DataAccessException;
|
||||
|
||||
/**
|
||||
@@ -59,7 +61,7 @@ public interface ChangeSetPersister<K> {
|
||||
*/
|
||||
class NotFoundException extends Exception {
|
||||
|
||||
private static final long serialVersionUID = -8604207973816331140L;
|
||||
private static final @Serial long serialVersionUID = -8604207973816331140L;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -21,6 +21,7 @@ import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.data.annotation.Transient;
|
||||
import org.springframework.lang.Contract;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
@@ -76,6 +77,7 @@ public class AbstractAggregateRoot<A extends AbstractAggregateRoot<A>> {
|
||||
* @return the aggregate
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
@Contract("_ -> this")
|
||||
protected final A andEventsFrom(A aggregate) {
|
||||
|
||||
Assert.notNull(aggregate, "Aggregate must not be null");
|
||||
@@ -86,15 +88,16 @@ public class AbstractAggregateRoot<A extends AbstractAggregateRoot<A>> {
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the given event to the aggregate for later publication
|
||||
* when calling a Spring Data repository's save or delete method.
|
||||
* Does the same as {@link #registerEvent(Object)} but returns the aggregate instead of the event.
|
||||
* Adds the given event to the aggregate for later publication when calling a Spring Data repository's {@code save} or
|
||||
* {@code delete} method. Does the same as {@link #registerEvent(Object)} but returns the aggregate instead of the
|
||||
* event.
|
||||
*
|
||||
* @param event must not be {@literal null}.
|
||||
* @return the aggregate
|
||||
* @see #registerEvent(Object)
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
@Contract("_ -> this")
|
||||
protected final A andEvent(Object event) {
|
||||
|
||||
registerEvent(event);
|
||||
|
||||
@@ -15,8 +15,11 @@
|
||||
*/
|
||||
package org.springframework.data.domain;
|
||||
|
||||
import java.io.Serial;
|
||||
import java.io.Serializable;
|
||||
|
||||
import org.springframework.util.ObjectUtils;
|
||||
|
||||
/**
|
||||
* Abstract Java Bean implementation of {@code Pageable}.
|
||||
*
|
||||
@@ -28,7 +31,7 @@ import java.io.Serializable;
|
||||
*/
|
||||
public abstract class AbstractPageRequest implements Pageable, Serializable {
|
||||
|
||||
private static final long serialVersionUID = 1232825578694716871L;
|
||||
private static final @Serial long serialVersionUID = 1232825578694716871L;
|
||||
|
||||
private final int pageNumber;
|
||||
private final int pageSize;
|
||||
@@ -85,7 +88,7 @@ public abstract class AbstractPageRequest implements Pageable, Serializable {
|
||||
/**
|
||||
* Returns the {@link Pageable} requesting the previous {@link Page}.
|
||||
*
|
||||
* @return
|
||||
* @return the previous {@link Pageable}
|
||||
*/
|
||||
public abstract Pageable previous();
|
||||
|
||||
@@ -93,29 +96,21 @@ public abstract class AbstractPageRequest implements Pageable, Serializable {
|
||||
public abstract Pageable first();
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
|
||||
final int prime = 31;
|
||||
int result = 1;
|
||||
|
||||
result = prime * result + pageNumber;
|
||||
result = prime * result + pageSize;
|
||||
|
||||
return result;
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) {
|
||||
return true;
|
||||
}
|
||||
if (!(o instanceof AbstractPageRequest that)) {
|
||||
return false;
|
||||
}
|
||||
if (pageNumber != that.pageNumber) {
|
||||
return false;
|
||||
}
|
||||
return pageSize == that.pageSize;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
|
||||
if (this == obj) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (obj == null || getClass() != obj.getClass()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
AbstractPageRequest other = (AbstractPageRequest) obj;
|
||||
return pageNumber == other.pageNumber && pageSize == other.pageSize;
|
||||
public int hashCode() {
|
||||
return ObjectUtils.nullSafeHash(pageNumber, pageSize);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,6 +18,8 @@ package org.springframework.data.domain;
|
||||
import java.time.temporal.TemporalAccessor;
|
||||
import java.util.Optional;
|
||||
|
||||
import org.springframework.lang.Nullable;
|
||||
|
||||
/**
|
||||
* Interface for auditable entities. Allows storing and retrieving creation and modification information. The changing
|
||||
* instance (typically some user) is to be defined by a generics definition.
|
||||
@@ -40,7 +42,7 @@ public interface Auditable<U, ID, T extends TemporalAccessor> extends Persistabl
|
||||
*
|
||||
* @param createdBy the creating entity to set
|
||||
*/
|
||||
void setCreatedBy(U createdBy);
|
||||
void setCreatedBy(@Nullable U createdBy);
|
||||
|
||||
/**
|
||||
* Returns the creation date of the entity.
|
||||
@@ -68,7 +70,7 @@ public interface Auditable<U, ID, T extends TemporalAccessor> extends Persistabl
|
||||
*
|
||||
* @param lastModifiedBy the last modifying entity to set
|
||||
*/
|
||||
void setLastModifiedBy(U lastModifiedBy);
|
||||
void setLastModifiedBy(@Nullable U lastModifiedBy);
|
||||
|
||||
/**
|
||||
* Returns the date of the last modification.
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
*/
|
||||
package org.springframework.data.domain;
|
||||
|
||||
import java.io.Serial;
|
||||
import java.io.Serializable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
@@ -24,6 +25,7 @@ import java.util.function.Function;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.ObjectUtils;
|
||||
|
||||
/**
|
||||
* A chunk of data restricted by the configured {@link Pageable}.
|
||||
@@ -34,9 +36,9 @@ import org.springframework.util.Assert;
|
||||
*/
|
||||
abstract class Chunk<T> implements Slice<T>, Serializable {
|
||||
|
||||
private static final long serialVersionUID = 867755909294344406L;
|
||||
private static final @Serial long serialVersionUID = 867755909294344406L;
|
||||
|
||||
private final List<T> content = new ArrayList<>();
|
||||
private final List<T> content;
|
||||
private final Pageable pageable;
|
||||
|
||||
/**
|
||||
@@ -50,7 +52,7 @@ abstract class Chunk<T> implements Slice<T>, Serializable {
|
||||
Assert.notNull(content, "Content must not be null");
|
||||
Assert.notNull(pageable, "Pageable must not be null");
|
||||
|
||||
this.content.addAll(content);
|
||||
this.content = new ArrayList<>(content);
|
||||
this.pageable = pageable;
|
||||
}
|
||||
|
||||
@@ -114,6 +116,7 @@ abstract class Chunk<T> implements Slice<T>, Serializable {
|
||||
return pageable.getSort();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterator<T> iterator() {
|
||||
return content.iterator();
|
||||
}
|
||||
@@ -128,34 +131,27 @@ abstract class Chunk<T> implements Slice<T>, Serializable {
|
||||
|
||||
Assert.notNull(converter, "Function must not be null");
|
||||
|
||||
return this.stream().map(converter::apply).collect(Collectors.toList());
|
||||
return this.stream().map(converter).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
public boolean equals(Object o) {
|
||||
|
||||
if (this == obj) {
|
||||
if (this == o) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!(obj instanceof Chunk<?> that)) {
|
||||
if (!(o instanceof Chunk<?> chunk)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
boolean contentEqual = this.content.equals(that.content);
|
||||
boolean pageableEqual = this.pageable.equals(that.pageable);
|
||||
|
||||
return contentEqual && pageableEqual;
|
||||
if (!ObjectUtils.nullSafeEquals(content, chunk.content)) {
|
||||
return false;
|
||||
}
|
||||
return ObjectUtils.nullSafeEquals(pageable, chunk.pageable);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
|
||||
int result = 17;
|
||||
|
||||
result += 31 * pageable.hashCode();
|
||||
result += 31 * content.hashCode();
|
||||
|
||||
return result;
|
||||
return ObjectUtils.nullSafeHash(content, pageable);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -35,4 +35,5 @@ import org.springframework.aot.hint.annotation.Reflective;
|
||||
@Reflective
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target({ ElementType.METHOD, ElementType.ANNOTATION_TYPE })
|
||||
public @interface DomainEvents {}
|
||||
public @interface DomainEvents {
|
||||
}
|
||||
|
||||
@@ -33,7 +33,7 @@ public interface Example<T> {
|
||||
* Create a new {@link Example} including all non-null properties by default.
|
||||
*
|
||||
* @param probe must not be {@literal null}.
|
||||
* @return
|
||||
* @return a new {@link Example} for {@code probe}.
|
||||
*/
|
||||
static <T> Example<T> of(T probe) {
|
||||
return new TypedExample<>(probe, ExampleMatcher.matching());
|
||||
@@ -44,7 +44,7 @@ public interface Example<T> {
|
||||
*
|
||||
* @param probe must not be {@literal null}.
|
||||
* @param matcher must not be {@literal null}.
|
||||
* @return
|
||||
* @return a new {@link Example} for {@code probe} and {@link ExampleMatcher}.
|
||||
*/
|
||||
static <T> Example<T> of(T probe, ExampleMatcher matcher) {
|
||||
return new TypedExample<>(probe, matcher);
|
||||
@@ -68,7 +68,7 @@ public interface Example<T> {
|
||||
* Get the actual type for the probe used. This is usually the given class, but the original class in case of a
|
||||
* CGLIB-generated subclass.
|
||||
*
|
||||
* @return
|
||||
* @return the underlying probe type, potentially an unwrapped proxy.
|
||||
* @see ProxyUtils#getUserClass(Class)
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
|
||||
@@ -22,6 +22,8 @@ import java.util.Optional;
|
||||
import java.util.Set;
|
||||
import java.util.function.Function;
|
||||
|
||||
import org.springframework.lang.CheckReturnValue;
|
||||
import org.springframework.lang.Contract;
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.ObjectUtils;
|
||||
@@ -81,6 +83,8 @@ public interface ExampleMatcher {
|
||||
* @param ignoredPaths must not be {@literal null} and not empty.
|
||||
* @return new instance of {@link ExampleMatcher}.
|
||||
*/
|
||||
@Contract("_ -> new")
|
||||
@CheckReturnValue
|
||||
ExampleMatcher withIgnorePaths(String... ignoredPaths);
|
||||
|
||||
/**
|
||||
@@ -90,6 +94,8 @@ public interface ExampleMatcher {
|
||||
* @param defaultStringMatcher must not be {@literal null}.
|
||||
* @return new instance of {@link ExampleMatcher}.
|
||||
*/
|
||||
@Contract("_ -> new")
|
||||
@CheckReturnValue
|
||||
ExampleMatcher withStringMatcher(StringMatcher defaultStringMatcher);
|
||||
|
||||
/**
|
||||
@@ -98,6 +104,8 @@ public interface ExampleMatcher {
|
||||
*
|
||||
* @return new instance of {@link ExampleMatcher}.
|
||||
*/
|
||||
@Contract("-> new")
|
||||
@CheckReturnValue
|
||||
default ExampleMatcher withIgnoreCase() {
|
||||
return withIgnoreCase(true);
|
||||
}
|
||||
@@ -106,9 +114,11 @@ public interface ExampleMatcher {
|
||||
* Returns a copy of this {@link ExampleMatcher} with {@code defaultIgnoreCase}. This instance is immutable and
|
||||
* unaffected by this method call.
|
||||
*
|
||||
* @param defaultIgnoreCase
|
||||
* @param defaultIgnoreCase {@literal true} to ignore case by default.
|
||||
* @return new instance of {@link ExampleMatcher}.
|
||||
*/
|
||||
@Contract("_ -> new")
|
||||
@CheckReturnValue
|
||||
ExampleMatcher withIgnoreCase(boolean defaultIgnoreCase);
|
||||
|
||||
/**
|
||||
@@ -119,6 +129,8 @@ public interface ExampleMatcher {
|
||||
* @param matcherConfigurer callback to configure a {@link GenericPropertyMatcher}, must not be {@literal null}.
|
||||
* @return new instance of {@link ExampleMatcher}.
|
||||
*/
|
||||
@Contract("_, _ -> new")
|
||||
@CheckReturnValue
|
||||
default ExampleMatcher withMatcher(String propertyPath, MatcherConfigurer<GenericPropertyMatcher> matcherConfigurer) {
|
||||
|
||||
Assert.hasText(propertyPath, "PropertyPath must not be empty");
|
||||
@@ -138,6 +150,8 @@ public interface ExampleMatcher {
|
||||
* @param genericPropertyMatcher callback to configure a {@link GenericPropertyMatcher}, must not be {@literal null}.
|
||||
* @return new instance of {@link ExampleMatcher}.
|
||||
*/
|
||||
@Contract("_, _ -> new")
|
||||
@CheckReturnValue
|
||||
ExampleMatcher withMatcher(String propertyPath, GenericPropertyMatcher genericPropertyMatcher);
|
||||
|
||||
/**
|
||||
@@ -148,6 +162,8 @@ public interface ExampleMatcher {
|
||||
* @param propertyValueTransformer must not be {@literal null}.
|
||||
* @return new instance of {@link ExampleMatcher}.
|
||||
*/
|
||||
@Contract("_, _ -> new")
|
||||
@CheckReturnValue
|
||||
ExampleMatcher withTransformer(String propertyPath, PropertyValueTransformer propertyValueTransformer);
|
||||
|
||||
/**
|
||||
@@ -157,6 +173,8 @@ public interface ExampleMatcher {
|
||||
* @param propertyPaths must not be {@literal null} and not empty.
|
||||
* @return new instance of {@link ExampleMatcher}.
|
||||
*/
|
||||
@Contract("_ -> new")
|
||||
@CheckReturnValue
|
||||
ExampleMatcher withIgnoreCase(String... propertyPaths);
|
||||
|
||||
/**
|
||||
@@ -165,6 +183,8 @@ public interface ExampleMatcher {
|
||||
*
|
||||
* @return new instance of {@link ExampleMatcher}.
|
||||
*/
|
||||
@Contract("-> new")
|
||||
@CheckReturnValue
|
||||
default ExampleMatcher withIncludeNullValues() {
|
||||
return withNullHandler(NullHandler.INCLUDE);
|
||||
}
|
||||
@@ -175,6 +195,8 @@ public interface ExampleMatcher {
|
||||
*
|
||||
* @return new instance of {@link ExampleMatcher}.
|
||||
*/
|
||||
@Contract("-> new")
|
||||
@CheckReturnValue
|
||||
default ExampleMatcher withIgnoreNullValues() {
|
||||
return withNullHandler(NullHandler.IGNORE);
|
||||
}
|
||||
@@ -186,19 +208,21 @@ public interface ExampleMatcher {
|
||||
* @param nullHandler must not be {@literal null}.
|
||||
* @return new instance of {@link ExampleMatcher}.
|
||||
*/
|
||||
@Contract("_ -> new")
|
||||
@CheckReturnValue
|
||||
ExampleMatcher withNullHandler(NullHandler nullHandler);
|
||||
|
||||
/**
|
||||
* Get defined null handling.
|
||||
* Get the defined null handling.
|
||||
*
|
||||
* @return never {@literal null}
|
||||
* @return the defined null handling.
|
||||
*/
|
||||
NullHandler getNullHandler();
|
||||
|
||||
/**
|
||||
* Get defined {@link ExampleMatcher.StringMatcher}.
|
||||
* Get the defined {@link ExampleMatcher.StringMatcher}.
|
||||
*
|
||||
* @return never {@literal null}.
|
||||
* @return the defined {@link ExampleMatcher.StringMatcher}.
|
||||
*/
|
||||
StringMatcher getDefaultStringMatcher();
|
||||
|
||||
@@ -226,10 +250,10 @@ public interface ExampleMatcher {
|
||||
PropertySpecifiers getPropertySpecifiers();
|
||||
|
||||
/**
|
||||
* Returns whether all of the predicates of the {@link Example} are supposed to match. If {@literal false} is
|
||||
* returned, it's sufficient if any of the predicates derived from the {@link Example} match.
|
||||
* Returns whether all the predicates of the {@link Example} are supposed to match. If {@literal false} is returned,
|
||||
* it's sufficient if any of the predicates derived from the {@link Example} match.
|
||||
*
|
||||
* @return whether all of the predicates of the {@link Example} are supposed to match or any of them is sufficient.
|
||||
* @return whether all the predicates of the {@link Example} are supposed to match or any of them is sufficient.
|
||||
*/
|
||||
default boolean isAllMatching() {
|
||||
return getMatchMode().equals(MatchMode.ALL);
|
||||
@@ -293,8 +317,7 @@ public interface ExampleMatcher {
|
||||
* Creates a new {@link GenericPropertyMatcher} with a {@link StringMatcher} and {@code ignoreCase}.
|
||||
*
|
||||
* @param stringMatcher must not be {@literal null}.
|
||||
* @param ignoreCase
|
||||
* @return
|
||||
* @param ignoreCase {@literal true} to ignore case.
|
||||
*/
|
||||
public static GenericPropertyMatcher of(StringMatcher stringMatcher, boolean ignoreCase) {
|
||||
return new GenericPropertyMatcher().stringMatcher(stringMatcher).ignoreCase(ignoreCase);
|
||||
@@ -304,7 +327,6 @@ public interface ExampleMatcher {
|
||||
* Creates a new {@link GenericPropertyMatcher} with a {@link StringMatcher} and {@code ignoreCase}.
|
||||
*
|
||||
* @param stringMatcher must not be {@literal null}.
|
||||
* @return
|
||||
*/
|
||||
public static GenericPropertyMatcher of(StringMatcher stringMatcher) {
|
||||
return new GenericPropertyMatcher().stringMatcher(stringMatcher);
|
||||
@@ -312,9 +334,8 @@ public interface ExampleMatcher {
|
||||
|
||||
/**
|
||||
* Sets ignores case to {@literal true}.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@Contract(" -> this")
|
||||
public GenericPropertyMatcher ignoreCase() {
|
||||
|
||||
this.ignoreCase = true;
|
||||
@@ -324,9 +345,9 @@ public interface ExampleMatcher {
|
||||
/**
|
||||
* Sets ignores case to {@code ignoreCase}.
|
||||
*
|
||||
* @param ignoreCase
|
||||
* @return
|
||||
* @param ignoreCase {@literal true} to ignore case.
|
||||
*/
|
||||
@Contract("_ -> this")
|
||||
public GenericPropertyMatcher ignoreCase(boolean ignoreCase) {
|
||||
|
||||
this.ignoreCase = ignoreCase;
|
||||
@@ -335,9 +356,8 @@ public interface ExampleMatcher {
|
||||
|
||||
/**
|
||||
* Sets ignores case to {@literal false}.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@Contract(" -> this")
|
||||
public GenericPropertyMatcher caseSensitive() {
|
||||
|
||||
this.ignoreCase = false;
|
||||
@@ -346,9 +366,8 @@ public interface ExampleMatcher {
|
||||
|
||||
/**
|
||||
* Sets string matcher to {@link StringMatcher#CONTAINING}.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@Contract(" -> this")
|
||||
public GenericPropertyMatcher contains() {
|
||||
|
||||
this.stringMatcher = StringMatcher.CONTAINING;
|
||||
@@ -357,9 +376,8 @@ public interface ExampleMatcher {
|
||||
|
||||
/**
|
||||
* Sets string matcher to {@link StringMatcher#ENDING}.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@Contract(" -> this")
|
||||
public GenericPropertyMatcher endsWith() {
|
||||
|
||||
this.stringMatcher = StringMatcher.ENDING;
|
||||
@@ -368,9 +386,8 @@ public interface ExampleMatcher {
|
||||
|
||||
/**
|
||||
* Sets string matcher to {@link StringMatcher#STARTING}.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@Contract(" -> this")
|
||||
public GenericPropertyMatcher startsWith() {
|
||||
|
||||
this.stringMatcher = StringMatcher.STARTING;
|
||||
@@ -379,9 +396,8 @@ public interface ExampleMatcher {
|
||||
|
||||
/**
|
||||
* Sets string matcher to {@link StringMatcher#EXACT}.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@Contract(" -> this")
|
||||
public GenericPropertyMatcher exact() {
|
||||
|
||||
this.stringMatcher = StringMatcher.EXACT;
|
||||
@@ -390,9 +406,8 @@ public interface ExampleMatcher {
|
||||
|
||||
/**
|
||||
* Sets string matcher to {@link StringMatcher#DEFAULT}.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@Contract(" -> this")
|
||||
public GenericPropertyMatcher storeDefaultMatching() {
|
||||
|
||||
this.stringMatcher = StringMatcher.DEFAULT;
|
||||
@@ -401,9 +416,8 @@ public interface ExampleMatcher {
|
||||
|
||||
/**
|
||||
* Sets string matcher to {@link StringMatcher#REGEX}.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@Contract(" -> this")
|
||||
public GenericPropertyMatcher regex() {
|
||||
|
||||
this.stringMatcher = StringMatcher.REGEX;
|
||||
@@ -414,8 +428,8 @@ public interface ExampleMatcher {
|
||||
* Sets string matcher to {@code stringMatcher}.
|
||||
*
|
||||
* @param stringMatcher must not be {@literal null}.
|
||||
* @return
|
||||
*/
|
||||
@Contract("_ -> this")
|
||||
public GenericPropertyMatcher stringMatcher(StringMatcher stringMatcher) {
|
||||
|
||||
Assert.notNull(stringMatcher, "StringMatcher must not be null");
|
||||
@@ -427,8 +441,8 @@ public interface ExampleMatcher {
|
||||
* Sets the {@link PropertyValueTransformer} to {@code propertyValueTransformer}.
|
||||
*
|
||||
* @param propertyValueTransformer must not be {@literal null}.
|
||||
* @return
|
||||
*/
|
||||
@Contract("_ -> this")
|
||||
public GenericPropertyMatcher transform(PropertyValueTransformer propertyValueTransformer) {
|
||||
|
||||
Assert.notNull(propertyValueTransformer, "PropertyValueTransformer must not be null");
|
||||
@@ -463,10 +477,7 @@ public interface ExampleMatcher {
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int result = ObjectUtils.nullSafeHashCode(stringMatcher);
|
||||
result = 31 * result + ObjectUtils.nullSafeHashCode(ignoreCase);
|
||||
result = 31 * result + ObjectUtils.nullSafeHashCode(valueTransformer);
|
||||
return result;
|
||||
return ObjectUtils.nullSafeHash(stringMatcher, ignoreCase, valueTransformer);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -478,9 +489,7 @@ public interface ExampleMatcher {
|
||||
class GenericPropertyMatchers {
|
||||
|
||||
/**
|
||||
* Creates a {@link GenericPropertyMatcher} that matches string case insensitive.
|
||||
*
|
||||
* @return
|
||||
* Creates a {@link GenericPropertyMatcher} that matches string case-insensitive.
|
||||
*/
|
||||
public static GenericPropertyMatcher ignoreCase() {
|
||||
return new GenericPropertyMatcher().ignoreCase();
|
||||
@@ -488,8 +497,6 @@ public interface ExampleMatcher {
|
||||
|
||||
/**
|
||||
* Creates a {@link GenericPropertyMatcher} that matches string case-sensitive.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public static GenericPropertyMatcher caseSensitive() {
|
||||
return new GenericPropertyMatcher().caseSensitive();
|
||||
@@ -497,8 +504,6 @@ public interface ExampleMatcher {
|
||||
|
||||
/**
|
||||
* Creates a {@link GenericPropertyMatcher} that matches string using {@link StringMatcher#CONTAINING}.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public static GenericPropertyMatcher contains() {
|
||||
return new GenericPropertyMatcher().contains();
|
||||
@@ -506,8 +511,6 @@ public interface ExampleMatcher {
|
||||
|
||||
/**
|
||||
* Creates a {@link GenericPropertyMatcher} that matches string using {@link StringMatcher#ENDING}.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public static GenericPropertyMatcher endsWith() {
|
||||
return new GenericPropertyMatcher().endsWith();
|
||||
@@ -516,8 +519,6 @@ public interface ExampleMatcher {
|
||||
|
||||
/**
|
||||
* Creates a {@link GenericPropertyMatcher} that matches string using {@link StringMatcher#STARTING}.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public static GenericPropertyMatcher startsWith() {
|
||||
return new GenericPropertyMatcher().startsWith();
|
||||
@@ -525,8 +526,6 @@ public interface ExampleMatcher {
|
||||
|
||||
/**
|
||||
* Creates a {@link GenericPropertyMatcher} that matches string using {@link StringMatcher#EXACT}.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public static GenericPropertyMatcher exact() {
|
||||
return new GenericPropertyMatcher().exact();
|
||||
@@ -534,8 +533,6 @@ public interface ExampleMatcher {
|
||||
|
||||
/**
|
||||
* Creates a {@link GenericPropertyMatcher} that matches string using {@link StringMatcher#DEFAULT}.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public static GenericPropertyMatcher storeDefaultMatching() {
|
||||
return new GenericPropertyMatcher().storeDefaultMatching();
|
||||
@@ -543,8 +540,6 @@ public interface ExampleMatcher {
|
||||
|
||||
/**
|
||||
* Creates a {@link GenericPropertyMatcher} that matches string using {@link StringMatcher#REGEX}.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public static GenericPropertyMatcher regex() {
|
||||
return new GenericPropertyMatcher().regex();
|
||||
@@ -648,8 +643,9 @@ public interface ExampleMatcher {
|
||||
* {@link StringMatcher} in the returned instance.
|
||||
*
|
||||
* @param stringMatcher must not be {@literal null}.
|
||||
* @return
|
||||
*/
|
||||
@Contract("_ -> new")
|
||||
@CheckReturnValue
|
||||
public PropertySpecifier withStringMatcher(StringMatcher stringMatcher) {
|
||||
|
||||
Assert.notNull(stringMatcher, "StringMatcher must not be null");
|
||||
@@ -660,9 +656,10 @@ public interface ExampleMatcher {
|
||||
* Creates a new {@link PropertySpecifier} containing all values from the current instance and sets
|
||||
* {@code ignoreCase}.
|
||||
*
|
||||
* @param ignoreCase must not be {@literal null}.
|
||||
* @return
|
||||
* @param ignoreCase {@literal true} to ignore case.
|
||||
*/
|
||||
@Contract("_ -> new")
|
||||
@CheckReturnValue
|
||||
public PropertySpecifier withIgnoreCase(boolean ignoreCase) {
|
||||
return new PropertySpecifier(this.path, this.stringMatcher, ignoreCase, this.valueTransformer);
|
||||
}
|
||||
@@ -672,8 +669,9 @@ public interface ExampleMatcher {
|
||||
* {@link PropertyValueTransformer} in the returned instance.
|
||||
*
|
||||
* @param valueTransformer must not be {@literal null}.
|
||||
* @return
|
||||
*/
|
||||
@Contract("_ -> new")
|
||||
@CheckReturnValue
|
||||
public PropertySpecifier withValueTransformer(PropertyValueTransformer valueTransformer) {
|
||||
|
||||
Assert.notNull(valueTransformer, "PropertyValueTransformer must not be null");
|
||||
@@ -719,7 +717,7 @@ public interface ExampleMatcher {
|
||||
/**
|
||||
* Transforms a given source using the {@link PropertyValueTransformer}.
|
||||
*
|
||||
* @param source
|
||||
* @param source source value to transform.
|
||||
* @return
|
||||
*/
|
||||
public Optional<Object> transformValue(Optional<Object> source) {
|
||||
@@ -753,11 +751,7 @@ public interface ExampleMatcher {
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int result = ObjectUtils.nullSafeHashCode(path);
|
||||
result = 31 * result + ObjectUtils.nullSafeHashCode(stringMatcher);
|
||||
result = 31 * result + ObjectUtils.nullSafeHashCode(ignoreCase);
|
||||
result = 31 * result + ObjectUtils.nullSafeHashCode(valueTransformer);
|
||||
return result;
|
||||
return ObjectUtils.nullSafeHash(path, stringMatcher, ignoreCase, valueTransformer);
|
||||
}
|
||||
|
||||
protected boolean canEqual(final Object other) {
|
||||
|
||||
@@ -113,7 +113,7 @@ public sealed interface Limit permits Limited, Unlimited {
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return max ^ max >>> 32;
|
||||
return max;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -123,6 +123,7 @@ public final class OffsetScrollPosition implements ScrollPosition {
|
||||
return offset == -1;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean equals(@Nullable Object o) {
|
||||
|
||||
|
||||
@@ -29,8 +29,6 @@ public interface Page<T> extends Slice<T> {
|
||||
|
||||
/**
|
||||
* Creates a new empty {@link Page}.
|
||||
*
|
||||
* @return
|
||||
* @since 2.0
|
||||
*/
|
||||
static <T> Page<T> empty() {
|
||||
@@ -41,7 +39,7 @@ public interface Page<T> extends Slice<T> {
|
||||
* Creates a new empty {@link Page} for the given {@link Pageable}.
|
||||
*
|
||||
* @param pageable must not be {@literal null}.
|
||||
* @return
|
||||
* @return a new, empty {@link Page} wrapping the given {@link Pageable}.
|
||||
* @since 2.0
|
||||
*/
|
||||
static <T> Page<T> empty(Pageable pageable) {
|
||||
|
||||
@@ -15,10 +15,12 @@
|
||||
*/
|
||||
package org.springframework.data.domain;
|
||||
|
||||
import java.io.Serial;
|
||||
import java.util.List;
|
||||
import java.util.function.Function;
|
||||
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
|
||||
/**
|
||||
* Basic {@code Page} implementation.
|
||||
@@ -29,7 +31,7 @@ import org.springframework.lang.Nullable;
|
||||
*/
|
||||
public class PageImpl<T> extends Chunk<T> implements Page<T> {
|
||||
|
||||
private static final long serialVersionUID = 867755909294344406L;
|
||||
private static final @Serial long serialVersionUID = 867755909294344406L;
|
||||
|
||||
private final long total;
|
||||
|
||||
@@ -58,7 +60,7 @@ public class PageImpl<T> extends Chunk<T> implements Page<T> {
|
||||
* @param content must not be {@literal null}.
|
||||
*/
|
||||
public PageImpl(List<T> content) {
|
||||
this(content, Pageable.unpaged(), null == content ? 0 : content.size());
|
||||
this(content, Pageable.unpaged(), CollectionUtils.isEmpty(content) ? 0 : content.size());
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -86,19 +88,6 @@ public class PageImpl<T> extends Chunk<T> implements Page<T> {
|
||||
return new PageImpl<>(getConvertedContent(converter), getPageable(), total);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
|
||||
String contentType = "UNKNOWN";
|
||||
List<T> content = getContent();
|
||||
|
||||
if (!content.isEmpty() && content.get(0) != null) {
|
||||
contentType = content.get(0).getClass().getName();
|
||||
}
|
||||
|
||||
return String.format("Page %s of %d containing %s instances", getNumber() + 1, getTotalPages(), contentType);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(@Nullable Object obj) {
|
||||
|
||||
@@ -115,12 +104,19 @@ public class PageImpl<T> extends Chunk<T> implements Page<T> {
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return 31 * super.hashCode() + Long.hashCode(total);
|
||||
}
|
||||
|
||||
int result = 17;
|
||||
@Override
|
||||
public String toString() {
|
||||
|
||||
result += 31 * (int) (total ^ total >>> 32);
|
||||
result += 31 * super.hashCode();
|
||||
String contentType = "UNKNOWN";
|
||||
List<T> content = getContent();
|
||||
|
||||
return result;
|
||||
if (!content.isEmpty() && content.get(0) != null) {
|
||||
contentType = content.get(0).getClass().getName();
|
||||
}
|
||||
|
||||
return String.format("Page %s of %d containing %s instances", getNumber() + 1, getTotalPages(), contentType);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,9 +15,14 @@
|
||||
*/
|
||||
package org.springframework.data.domain;
|
||||
|
||||
import java.io.Serial;
|
||||
|
||||
import org.springframework.data.domain.Sort.Direction;
|
||||
import org.springframework.lang.CheckReturnValue;
|
||||
import org.springframework.lang.Contract;
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.ObjectUtils;
|
||||
|
||||
/**
|
||||
* Basic Java Bean implementation of {@link Pageable}.
|
||||
@@ -30,7 +35,7 @@ import org.springframework.util.Assert;
|
||||
*/
|
||||
public class PageRequest extends AbstractPageRequest {
|
||||
|
||||
private static final long serialVersionUID = -4541509938956089562L;
|
||||
private static final @Serial long serialVersionUID = -4541509938956089562L;
|
||||
|
||||
private final Sort sort;
|
||||
|
||||
@@ -103,42 +108,36 @@ public class PageRequest extends AbstractPageRequest {
|
||||
}
|
||||
|
||||
@Override
|
||||
@Contract("_ -> new")
|
||||
@CheckReturnValue
|
||||
public PageRequest next() {
|
||||
return new PageRequest(getPageNumber() + 1, getPageSize(), getSort());
|
||||
}
|
||||
|
||||
@Override
|
||||
@Contract("_ -> new")
|
||||
@CheckReturnValue
|
||||
public PageRequest previous() {
|
||||
return getPageNumber() == 0 ? this : new PageRequest(getPageNumber() - 1, getPageSize(), getSort());
|
||||
}
|
||||
|
||||
@Override
|
||||
@Contract("_ -> new")
|
||||
@CheckReturnValue
|
||||
public PageRequest first() {
|
||||
return new PageRequest(0, getPageSize(), getSort());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(@Nullable Object obj) {
|
||||
|
||||
if (this == obj) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!(obj instanceof PageRequest that)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return super.equals(that) && sort.equals(that.sort);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new {@link PageRequest} with {@code pageNumber} applied.
|
||||
*
|
||||
* @param pageNumber
|
||||
* @param pageNumber the page number to apply.
|
||||
* @return a new {@link PageRequest}.
|
||||
* @since 2.5
|
||||
*/
|
||||
@Override
|
||||
@Contract("_ -> new")
|
||||
@CheckReturnValue
|
||||
public PageRequest withPage(int pageNumber) {
|
||||
return new PageRequest(pageNumber, getPageSize(), getSort());
|
||||
}
|
||||
@@ -151,6 +150,8 @@ public class PageRequest extends AbstractPageRequest {
|
||||
* @return a new {@link PageRequest}.
|
||||
* @since 2.5
|
||||
*/
|
||||
@Contract("_, _ -> new")
|
||||
@CheckReturnValue
|
||||
public PageRequest withSort(Direction direction, String... properties) {
|
||||
return new PageRequest(getPageNumber(), getPageSize(), Sort.by(direction, properties));
|
||||
}
|
||||
@@ -162,13 +163,30 @@ public class PageRequest extends AbstractPageRequest {
|
||||
* @return a new {@link PageRequest}.
|
||||
* @since 2.5
|
||||
*/
|
||||
@Contract("_ -> new")
|
||||
@CheckReturnValue
|
||||
public PageRequest withSort(Sort sort) {
|
||||
return new PageRequest(getPageNumber(), getPageSize(), sort);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
|
||||
if (this == o) {
|
||||
return true;
|
||||
}
|
||||
if (!(o instanceof PageRequest that)) {
|
||||
return false;
|
||||
}
|
||||
if (!super.equals(o)) {
|
||||
return false;
|
||||
}
|
||||
return ObjectUtils.nullSafeEquals(sort, that.sort);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return 31 * super.hashCode() + sort.hashCode();
|
||||
return super.hashCode() * 31 + ObjectUtils.nullSafeHash(sort);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -17,6 +17,8 @@ package org.springframework.data.domain;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
import org.springframework.lang.CheckReturnValue;
|
||||
import org.springframework.lang.Contract;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
@@ -30,8 +32,6 @@ public interface Pageable {
|
||||
|
||||
/**
|
||||
* Returns a {@link Pageable} instance representing no pagination setup.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
static Pageable unpaged() {
|
||||
return unpaged(Sort.unsorted());
|
||||
@@ -41,7 +41,8 @@ public interface Pageable {
|
||||
* Returns a {@link Pageable} instance representing no pagination setup having a defined result {@link Sort order}.
|
||||
*
|
||||
* @param sort must not be {@literal null}, use {@link Sort#unsorted()} if needed.
|
||||
* @return never {@literal null}.
|
||||
* @return an unpaged {@link Pageable} instance representing no pagination setup considering the given {@link Sort}
|
||||
* order.
|
||||
* @since 3.2
|
||||
*/
|
||||
static Pageable unpaged(Sort sort) {
|
||||
@@ -62,7 +63,7 @@ public interface Pageable {
|
||||
/**
|
||||
* Returns whether the current {@link Pageable} contains pagination information.
|
||||
*
|
||||
* @return
|
||||
* @return {@literal true} if the current {@link Pageable} contains pagination information.
|
||||
*/
|
||||
default boolean isPaged() {
|
||||
return true;
|
||||
@@ -71,7 +72,7 @@ public interface Pageable {
|
||||
/**
|
||||
* Returns whether the current {@link Pageable} does not contain pagination information.
|
||||
*
|
||||
* @return
|
||||
* @return {@literal true} if the current {@link Pageable} does not contain pagination information.
|
||||
*/
|
||||
default boolean isUnpaged() {
|
||||
return !isPaged();
|
||||
@@ -107,7 +108,7 @@ public interface Pageable {
|
||||
/**
|
||||
* Returns the sorting parameters.
|
||||
*
|
||||
* @return
|
||||
* @return the sorting order.
|
||||
*/
|
||||
Sort getSort();
|
||||
|
||||
@@ -115,7 +116,7 @@ public interface Pageable {
|
||||
* Returns the current {@link Sort} or the given one if the current one is unsorted.
|
||||
*
|
||||
* @param sort must not be {@literal null}.
|
||||
* @return
|
||||
* @return the current {@link Sort} or the {@code sort} one if the current one is unsorted.
|
||||
*/
|
||||
default Sort getSortOr(Sort sort) {
|
||||
|
||||
@@ -127,47 +128,55 @@ public interface Pageable {
|
||||
/**
|
||||
* Returns the {@link Pageable} requesting the next {@link Page}.
|
||||
*
|
||||
* @return
|
||||
* @return the {@link Pageable} requesting the next {@link Page}.
|
||||
*/
|
||||
@Contract("_ -> new")
|
||||
@CheckReturnValue
|
||||
Pageable next();
|
||||
|
||||
/**
|
||||
* Returns the previous {@link Pageable} or the first {@link Pageable} if the current one already is the first one.
|
||||
*
|
||||
* @return
|
||||
* @return the previous {@link Pageable} or the first {@link Pageable} if the current one already is the first one.
|
||||
*/
|
||||
@Contract("_ -> new")
|
||||
@CheckReturnValue
|
||||
Pageable previousOrFirst();
|
||||
|
||||
/**
|
||||
* Returns the {@link Pageable} requesting the first page.
|
||||
*
|
||||
* @return
|
||||
* @return the {@link Pageable} requesting the first page.
|
||||
*/
|
||||
@Contract("_ -> new")
|
||||
@CheckReturnValue
|
||||
Pageable first();
|
||||
|
||||
/**
|
||||
* Creates a new {@link Pageable} with {@code pageNumber} applied.
|
||||
*
|
||||
* @param pageNumber
|
||||
* @param pageNumber the page numbe, zero-based.
|
||||
* @return a new {@link PageRequest} or throws {@link UnsupportedOperationException} if the object is
|
||||
* {@link #isUnpaged()} and the {@code pageNumber} is not zero.
|
||||
* @since 2.5
|
||||
* @throws UnsupportedOperationException if the object is {@link #isUnpaged()}.
|
||||
*/
|
||||
@Contract("_ -> new")
|
||||
@CheckReturnValue
|
||||
Pageable withPage(int pageNumber);
|
||||
|
||||
/**
|
||||
* Returns whether there's a previous {@link Pageable} we can access from the current one. Will return
|
||||
* {@literal false} in case the current {@link Pageable} already refers to the first page.
|
||||
*
|
||||
* @return
|
||||
* @return {@literal true} if there's a previous {@link Pageable} we can access from the current one.
|
||||
*/
|
||||
boolean hasPrevious();
|
||||
|
||||
/**
|
||||
* Returns an {@link Optional} so that it can easily be mapped on.
|
||||
*
|
||||
* @return
|
||||
* @return an {@link Optional} so that it can easily be mapped on.
|
||||
*/
|
||||
default Optional<Pageable> toOptional() {
|
||||
return isUnpaged() ? Optional.empty() : Optional.of(this);
|
||||
@@ -177,7 +186,7 @@ public interface Pageable {
|
||||
* Returns an {@link Limit} from this pageable if the page request {@link #isPaged() is paged} or
|
||||
* {@link Limit#unlimited()} otherwise.
|
||||
*
|
||||
* @return
|
||||
* @return a {@link Limit} object based on the current page size.
|
||||
* @since 3.2
|
||||
*/
|
||||
default Limit toLimit() {
|
||||
@@ -193,7 +202,7 @@ public interface Pageable {
|
||||
* Returns an {@link OffsetScrollPosition} from this pageable if the page request {@link #isPaged() is paged}.
|
||||
* <p>
|
||||
* Given the exclusive nature of scrolling the {@link ScrollPosition} for {@code Page(0, 10)} translates an
|
||||
* {@link ScrollPosition#isInitial() initial} position, where as {@code Page(1, 10)} will point to the last element of
|
||||
* {@link ScrollPosition#isInitial() initial} position, whereas {@code Page(1, 10)} will point to the last element of
|
||||
* {@code Page(0,10)} resulting in {@link ScrollPosition#offset(long) ScrollPosition(9)}.
|
||||
*
|
||||
* @return new instance of {@link OffsetScrollPosition}.
|
||||
|
||||
@@ -19,6 +19,7 @@ import java.util.Comparator;
|
||||
import java.util.Optional;
|
||||
import java.util.function.Function;
|
||||
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.ObjectUtils;
|
||||
|
||||
@@ -55,7 +56,7 @@ public final class Range<T> {
|
||||
/**
|
||||
* Returns an unbounded {@link Range}.
|
||||
*
|
||||
* @return
|
||||
* @return an unbounded {@link Range}.
|
||||
* @since 2.0
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
@@ -66,10 +67,10 @@ public final class Range<T> {
|
||||
/**
|
||||
* Creates a new {@link Range} with inclusive bounds for both values.
|
||||
*
|
||||
* @param <T>
|
||||
* @param <T> the type of the range.
|
||||
* @param from must not be {@literal null}.
|
||||
* @param to must not be {@literal null}.
|
||||
* @return
|
||||
* @return a {@link Range} with the lower bound set inclusively and the upper bound inclusively.
|
||||
* @since 2.2
|
||||
*/
|
||||
public static <T> Range<T> closed(T from, T to) {
|
||||
@@ -79,10 +80,10 @@ public final class Range<T> {
|
||||
/**
|
||||
* Creates a new {@link Range} with exclusive bounds for both values.
|
||||
*
|
||||
* @param <T>
|
||||
* @param <T> the type of the range.
|
||||
* @param from must not be {@literal null}.
|
||||
* @param to must not be {@literal null}.
|
||||
* @return
|
||||
* @return a {@link Range} with the lower bound set exclusively and the upper bound exclusively.
|
||||
* @since 2.2
|
||||
*/
|
||||
public static <T> Range<T> open(T from, T to) {
|
||||
@@ -92,10 +93,10 @@ public final class Range<T> {
|
||||
/**
|
||||
* Creates a new left-open {@link Range}, i.e. left exclusive, right inclusive.
|
||||
*
|
||||
* @param <T>
|
||||
* @param <T> the type of the range.
|
||||
* @param from must not be {@literal null}.
|
||||
* @param to must not be {@literal null}.
|
||||
* @return
|
||||
* @return a {@link Range} with the lower bound set exclusively and the upper bound inclusively.
|
||||
* @since 2.2
|
||||
*/
|
||||
public static <T> Range<T> leftOpen(T from, T to) {
|
||||
@@ -105,10 +106,10 @@ public final class Range<T> {
|
||||
/**
|
||||
* Creates a new right-open {@link Range}, i.e. left inclusive, right exclusive.
|
||||
*
|
||||
* @param <T>
|
||||
* @param <T> the type of the range.
|
||||
* @param from must not be {@literal null}.
|
||||
* @param to must not be {@literal null}.
|
||||
* @return
|
||||
* @return a {@link Range} with the lower bound set inclusively and the upper bound exclusively.
|
||||
* @since 2.2
|
||||
*/
|
||||
public static <T> Range<T> rightOpen(T from, T to) {
|
||||
@@ -119,9 +120,9 @@ public final class Range<T> {
|
||||
* Creates a left-unbounded {@link Range} (the left bound set to {@link Bound#unbounded()}) with the given right
|
||||
* bound.
|
||||
*
|
||||
* @param <T>
|
||||
* @param <T> the type of the range.
|
||||
* @param to the right {@link Bound}, must not be {@literal null}.
|
||||
* @return
|
||||
* @return a {@link Range} with the upper bound set to the given value and the lower side unbounded.
|
||||
* @since 2.2
|
||||
*/
|
||||
public static <T> Range<T> leftUnbounded(Bound<T> to) {
|
||||
@@ -132,9 +133,9 @@ public final class Range<T> {
|
||||
* Creates a right-unbounded {@link Range} (the right bound set to {@link Bound#unbounded()}) with the given left
|
||||
* bound.
|
||||
*
|
||||
* @param <T>
|
||||
* @param <T> the type of the range.
|
||||
* @param from the left {@link Bound}, must not be {@literal null}.
|
||||
* @return
|
||||
* @return a {@link Range} with the lower bound set to the given value and the upper side unbounded.
|
||||
* @since 2.2
|
||||
*/
|
||||
public static <T> Range<T> rightUnbounded(Bound<T> from) {
|
||||
@@ -145,7 +146,7 @@ public final class Range<T> {
|
||||
* Create a {@link RangeBuilder} given the lower {@link Bound}.
|
||||
*
|
||||
* @param lower must not be {@literal null}.
|
||||
* @return
|
||||
* @return a range builder to continue creating a {@link Range} from the lower bound.
|
||||
* @since 2.0
|
||||
*/
|
||||
public static <T> RangeBuilder<T> from(Bound<T> lower) {
|
||||
@@ -170,9 +171,9 @@ public final class Range<T> {
|
||||
/**
|
||||
* Creates a new Range with the given value as sole member.
|
||||
*
|
||||
* @param <T>
|
||||
* @param <T> the type of the range.>
|
||||
* @param value must not be {@literal null}.
|
||||
* @return
|
||||
* @return a range containing the given value.
|
||||
* @see Range#closed(Object, Object)
|
||||
*/
|
||||
public static <T> Range<T> just(T value) {
|
||||
@@ -183,7 +184,7 @@ public final class Range<T> {
|
||||
* Returns whether the {@link Range} contains the given value.
|
||||
*
|
||||
* @param value must not be {@literal null}.
|
||||
* @return
|
||||
* @return {@literal true} if the range contains the value; {@literal false} otherwise.
|
||||
*/
|
||||
@SuppressWarnings({ "unchecked" })
|
||||
public boolean contains(Comparable<T> value) {
|
||||
@@ -200,7 +201,7 @@ public final class Range<T> {
|
||||
* Returns whether the {@link Range} contains the given value.
|
||||
*
|
||||
* @param value must not be {@literal null}.
|
||||
* @return
|
||||
* @return {@literal true} if the range contains the value; {@literal false} otherwise.
|
||||
* @since 3.0
|
||||
*/
|
||||
public boolean contains(T value, Comparator<T> comparator) {
|
||||
@@ -224,7 +225,7 @@ public final class Range<T> {
|
||||
* @param mapper must not be {@literal null}. If the mapper returns {@code null}, then the corresponding boundary
|
||||
* value represents an {@link Bound#unbounded()} boundary.
|
||||
* @return a new {@link Range} after applying the value to the mapper.
|
||||
* @param <R>
|
||||
* @param <R> target type of the mapping function.
|
||||
* @since 3.0
|
||||
*/
|
||||
public <R> Range<R> map(Function<? super T, ? extends R> mapper) {
|
||||
@@ -248,7 +249,7 @@ public final class Range<T> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
public boolean equals(@Nullable Object o) {
|
||||
|
||||
if (this == o) {
|
||||
return true;
|
||||
@@ -267,9 +268,7 @@ public final class Range<T> {
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int result = ObjectUtils.nullSafeHashCode(lowerBound);
|
||||
result = 31 * result + ObjectUtils.nullSafeHashCode(upperBound);
|
||||
return result;
|
||||
return ObjectUtils.nullSafeHash(lowerBound, upperBound);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -313,7 +312,6 @@ public final class Range<T> {
|
||||
* Creates a boundary including {@code value}.
|
||||
*
|
||||
* @param value must not be {@literal null}.
|
||||
* @return
|
||||
*/
|
||||
public static <T> Bound<T> inclusive(T value) {
|
||||
|
||||
@@ -325,7 +323,6 @@ public final class Range<T> {
|
||||
* Creates a boundary including {@code value}.
|
||||
*
|
||||
* @param value must not be {@literal null}.
|
||||
* @return
|
||||
*/
|
||||
public static Bound<Integer> inclusive(int value) {
|
||||
return inclusive((Integer) value);
|
||||
@@ -335,7 +332,6 @@ public final class Range<T> {
|
||||
* Creates a boundary including {@code value}.
|
||||
*
|
||||
* @param value must not be {@literal null}.
|
||||
* @return
|
||||
*/
|
||||
public static Bound<Long> inclusive(long value) {
|
||||
return inclusive((Long) value);
|
||||
@@ -345,7 +341,6 @@ public final class Range<T> {
|
||||
* Creates a boundary including {@code value}.
|
||||
*
|
||||
* @param value must not be {@literal null}.
|
||||
* @return
|
||||
*/
|
||||
public static Bound<Float> inclusive(float value) {
|
||||
return inclusive((Float) value);
|
||||
@@ -355,7 +350,6 @@ public final class Range<T> {
|
||||
* Creates a boundary including {@code value}.
|
||||
*
|
||||
* @param value must not be {@literal null}.
|
||||
* @return
|
||||
*/
|
||||
public static Bound<Double> inclusive(double value) {
|
||||
return inclusive((Double) value);
|
||||
@@ -365,7 +359,6 @@ public final class Range<T> {
|
||||
* Creates a boundary excluding {@code value}.
|
||||
*
|
||||
* @param value must not be {@literal null}.
|
||||
* @return
|
||||
*/
|
||||
public static <T> Bound<T> exclusive(T value) {
|
||||
|
||||
@@ -377,7 +370,6 @@ public final class Range<T> {
|
||||
* Creates a boundary excluding {@code value}.
|
||||
*
|
||||
* @param value must not be {@literal null}.
|
||||
* @return
|
||||
*/
|
||||
public static Bound<Integer> exclusive(int value) {
|
||||
return exclusive((Integer) value);
|
||||
@@ -387,7 +379,6 @@ public final class Range<T> {
|
||||
* Creates a boundary excluding {@code value}.
|
||||
*
|
||||
* @param value must not be {@literal null}.
|
||||
* @return
|
||||
*/
|
||||
public static Bound<Long> exclusive(long value) {
|
||||
return exclusive((Long) value);
|
||||
@@ -397,7 +388,6 @@ public final class Range<T> {
|
||||
* Creates a boundary excluding {@code value}.
|
||||
*
|
||||
* @param value must not be {@literal null}.
|
||||
* @return
|
||||
*/
|
||||
public static Bound<Float> exclusive(float value) {
|
||||
return exclusive((Float) value);
|
||||
@@ -407,7 +397,6 @@ public final class Range<T> {
|
||||
* Creates a boundary excluding {@code value}.
|
||||
*
|
||||
* @param value must not be {@literal null}.
|
||||
* @return
|
||||
*/
|
||||
public static Bound<Double> exclusive(double value) {
|
||||
return exclusive((Double) value);
|
||||
@@ -429,11 +418,6 @@ public final class Range<T> {
|
||||
.orElse("unbounded");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return value.map(Object::toString).orElse("unbounded");
|
||||
}
|
||||
|
||||
public Optional<T> getValue() {
|
||||
return this.value;
|
||||
}
|
||||
@@ -442,39 +426,6 @@ public final class Range<T> {
|
||||
return this.inclusive;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
|
||||
if (this == o) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!(o instanceof Bound<?> bound)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!value.isPresent() && !bound.value.isPresent()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (inclusive != bound.inclusive)
|
||||
return false;
|
||||
|
||||
return ObjectUtils.nullSafeEquals(value, bound.value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
|
||||
if (!value.isPresent()) {
|
||||
return ObjectUtils.nullSafeHashCode(value);
|
||||
}
|
||||
|
||||
int result = ObjectUtils.nullSafeHashCode(value);
|
||||
result = 31 * result + (inclusive ? 1 : 0);
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply a mapping {@link Function} to the boundary value.
|
||||
*
|
||||
@@ -500,6 +451,44 @@ public final class Range<T> {
|
||||
return unbounded();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(@Nullable Object o) {
|
||||
|
||||
if (this == o) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!(o instanceof Bound<?> bound)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (value.isEmpty() && bound.value.isEmpty()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (inclusive != bound.inclusive)
|
||||
return false;
|
||||
|
||||
return ObjectUtils.nullSafeEquals(value, bound.value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
|
||||
if (value.isEmpty()) {
|
||||
return ObjectUtils.nullSafeHashCode(value);
|
||||
}
|
||||
|
||||
int result = ObjectUtils.nullSafeHashCode(value);
|
||||
result = 31 * result + (inclusive ? 1 : 0);
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return value.map(Object::toString).orElse("unbounded");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -521,7 +510,6 @@ public final class Range<T> {
|
||||
* Create a {@link Range} given the upper {@link Bound}.
|
||||
*
|
||||
* @param upper must not be {@literal null}.
|
||||
* @return
|
||||
*/
|
||||
public Range<T> to(Bound<T> upper) {
|
||||
|
||||
|
||||
@@ -29,7 +29,7 @@ public interface ScrollPosition {
|
||||
/**
|
||||
* Returns whether the current scroll position is the initial one.
|
||||
*
|
||||
* @return
|
||||
* @return {@literal true} if the current scroll position is the initial one.
|
||||
*/
|
||||
boolean isInitial();
|
||||
|
||||
@@ -54,7 +54,7 @@ public interface ScrollPosition {
|
||||
/**
|
||||
* Creates a new {@link ScrollPosition} from an {@code offset}.
|
||||
*
|
||||
* @param offset
|
||||
* @param offset the scroll offset.
|
||||
* @return a new {@link OffsetScrollPosition} with the given {@code offset}.
|
||||
*/
|
||||
static OffsetScrollPosition offset(long offset) {
|
||||
@@ -111,4 +111,5 @@ public interface ScrollPosition {
|
||||
return this == FORWARD ? BACKWARD : FORWARD;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -54,35 +54,35 @@ public interface Slice<T> extends Streamable<T> {
|
||||
/**
|
||||
* Returns the page content as {@link List}.
|
||||
*
|
||||
* @return
|
||||
* @return the page content as {@link List}.
|
||||
*/
|
||||
List<T> getContent();
|
||||
|
||||
/**
|
||||
* Returns whether the {@link Slice} has content at all.
|
||||
*
|
||||
* @return
|
||||
* @return {@literal true} if the {@link Slice} has content at all.
|
||||
*/
|
||||
boolean hasContent();
|
||||
|
||||
/**
|
||||
* Returns the sorting parameters for the {@link Slice}.
|
||||
*
|
||||
* @return
|
||||
* @return the sorting parameters for the {@link Slice}.
|
||||
*/
|
||||
Sort getSort();
|
||||
|
||||
/**
|
||||
* Returns whether the current {@link Slice} is the first one.
|
||||
*
|
||||
* @return
|
||||
* @return {@literal true} if the current {@link Slice} is the first one.
|
||||
*/
|
||||
boolean isFirst();
|
||||
|
||||
/**
|
||||
* Returns whether the current {@link Slice} is the last one.
|
||||
*
|
||||
* @return
|
||||
* @return {@literal true} if the current {@link Slice} is the last one.
|
||||
*/
|
||||
boolean isLast();
|
||||
|
||||
@@ -103,7 +103,7 @@ public interface Slice<T> extends Streamable<T> {
|
||||
/**
|
||||
* Returns the {@link Pageable} that's been used to request the current {@link Slice}.
|
||||
*
|
||||
* @return
|
||||
* @return the {@link Pageable} that's been used to request the current {@link Slice}.
|
||||
* @since 2.0
|
||||
*/
|
||||
default Pageable getPageable() {
|
||||
@@ -114,7 +114,7 @@ public interface Slice<T> extends Streamable<T> {
|
||||
* Returns the {@link Pageable} to request the next {@link Slice}. Can be {@link Pageable#unpaged()} in case the
|
||||
* current {@link Slice} is already the last one. Clients should check {@link #hasNext()} before calling this method.
|
||||
*
|
||||
* @return
|
||||
* @return the {@link Pageable} to request the next {@link Slice}.
|
||||
* @see #nextOrLastPageable()
|
||||
*/
|
||||
Pageable nextPageable();
|
||||
@@ -124,11 +124,35 @@ public interface Slice<T> extends Streamable<T> {
|
||||
* current {@link Slice} is already the first one. Clients should check {@link #hasPrevious()} before calling this
|
||||
* method.
|
||||
*
|
||||
* @return
|
||||
* @return the {@link Pageable} to request the previous {@link Slice}.
|
||||
* @see #previousPageable()
|
||||
*/
|
||||
Pageable previousPageable();
|
||||
|
||||
/**
|
||||
* Returns the {@link Pageable} describing the next slice or the one describing the current slice in case it's the
|
||||
* last one.
|
||||
*
|
||||
* @return the {@link Pageable} describing the next slice or the one describing the current slice in case it's the
|
||||
* last one
|
||||
* @since 2.2
|
||||
*/
|
||||
default Pageable nextOrLastPageable() {
|
||||
return hasNext() ? nextPageable() : getPageable();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the {@link Pageable} describing the previous slice or the one describing the current slice in case it's the
|
||||
* first one.
|
||||
*
|
||||
* @return the {@link Pageable} describing the previous slice or the one describing the current slice in case it's the
|
||||
* first one.
|
||||
* @since 2.2
|
||||
*/
|
||||
default Pageable previousOrFirstPageable() {
|
||||
return hasPrevious() ? previousPageable() : getPageable();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a new {@link Slice} with the content of the current one mapped by the given {@link Converter}.
|
||||
*
|
||||
@@ -139,25 +163,4 @@ public interface Slice<T> extends Streamable<T> {
|
||||
@Override
|
||||
<U> Slice<U> map(Function<? super T, ? extends U> converter);
|
||||
|
||||
/**
|
||||
* Returns the {@link Pageable} describing the next slice or the one describing the current slice in case it's the
|
||||
* last one.
|
||||
*
|
||||
* @return
|
||||
* @since 2.2
|
||||
*/
|
||||
default Pageable nextOrLastPageable() {
|
||||
return hasNext() ? nextPageable() : getPageable();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the {@link Pageable} describing the previous slice or the one describing the current slice in case it's the
|
||||
* first one.
|
||||
*
|
||||
* @return
|
||||
* @since 2.2
|
||||
*/
|
||||
default Pageable previousOrFirstPageable() {
|
||||
return hasPrevious() ? previousPageable() : getPageable();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -30,8 +30,7 @@ import org.springframework.lang.Nullable;
|
||||
*/
|
||||
public class SliceImpl<T> extends Chunk<T> {
|
||||
|
||||
@Serial
|
||||
private static final long serialVersionUID = 867755909294344406L;
|
||||
private static final @Serial long serialVersionUID = 867755909294344406L;
|
||||
|
||||
private final boolean hasNext;
|
||||
private final Pageable pageable;
|
||||
@@ -71,19 +70,6 @@ public class SliceImpl<T> extends Chunk<T> {
|
||||
return new SliceImpl<>(getConvertedContent(converter), pageable, hasNext);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
|
||||
String contentType = "UNKNOWN";
|
||||
List<T> content = getContent();
|
||||
|
||||
if (!content.isEmpty()) {
|
||||
contentType = content.get(0).getClass().getName();
|
||||
}
|
||||
|
||||
return String.format("Slice %d containing %s instances", getNumber(), contentType);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(@Nullable Object obj) {
|
||||
|
||||
@@ -100,12 +86,20 @@ public class SliceImpl<T> extends Chunk<T> {
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
|
||||
int result = 17;
|
||||
|
||||
result += 31 * (hasNext ? 1 : 0);
|
||||
result += 31 * super.hashCode();
|
||||
|
||||
return result;
|
||||
return 31 * super.hashCode() + (hasNext ? 1 : 0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
|
||||
String contentType = "UNKNOWN";
|
||||
List<T> content = getContent();
|
||||
|
||||
if (!content.isEmpty()) {
|
||||
contentType = content.get(0).getClass().getName();
|
||||
}
|
||||
|
||||
return String.format("Slice %d containing %s instances", getNumber(), contentType);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -30,6 +30,8 @@ import java.util.stream.Collectors;
|
||||
import org.springframework.data.util.MethodInvocationRecorder;
|
||||
import org.springframework.data.util.MethodInvocationRecorder.Recorded;
|
||||
import org.springframework.data.util.Streamable;
|
||||
import org.springframework.lang.CheckReturnValue;
|
||||
import org.springframework.lang.Contract;
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.ObjectUtils;
|
||||
@@ -160,6 +162,7 @@ public class Sort implements Streamable<org.springframework.data.domain.Sort.Ord
|
||||
*
|
||||
* @return a new {@link Sort} with the current setup but descending order direction.
|
||||
*/
|
||||
@Contract("-> new")
|
||||
public Sort descending() {
|
||||
return withDirection(Direction.DESC);
|
||||
}
|
||||
@@ -169,6 +172,7 @@ public class Sort implements Streamable<org.springframework.data.domain.Sort.Ord
|
||||
*
|
||||
* @return a new {@link Sort} with the current setup but ascending order direction.
|
||||
*/
|
||||
@Contract("-> new")
|
||||
public Sort ascending() {
|
||||
return withDirection(Direction.ASC);
|
||||
}
|
||||
@@ -200,6 +204,8 @@ public class Sort implements Streamable<org.springframework.data.domain.Sort.Ord
|
||||
* @return a new {@link Sort} consisting of the {@link Order}s of the current {@link Sort} combined with the given
|
||||
* ones.
|
||||
*/
|
||||
@Contract("_ -> new")
|
||||
@CheckReturnValue
|
||||
public Sort and(Sort sort) {
|
||||
|
||||
Assert.notNull(sort, "Sort must not be null");
|
||||
@@ -220,6 +226,7 @@ public class Sort implements Streamable<org.springframework.data.domain.Sort.Ord
|
||||
* @return a new {@link Sort} object with reversed sort orders applied.
|
||||
* @since 3.1
|
||||
*/
|
||||
@Contract("-> new")
|
||||
public Sort reverse() {
|
||||
|
||||
List<Order> reversed = doReverse();
|
||||
@@ -277,10 +284,7 @@ public class Sort implements Streamable<org.springframework.data.domain.Sort.Ord
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
|
||||
int result = 17;
|
||||
result = 31 * result + orders.hashCode();
|
||||
return result;
|
||||
return orders.hashCode();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -381,14 +385,14 @@ public class Sort implements Streamable<org.springframework.data.domain.Sort.Ord
|
||||
NATIVE,
|
||||
|
||||
/**
|
||||
* A hint to the used data store to order entries with null values before non null entries.
|
||||
* A hint to the used data store to order entries with null values before non-null entries.
|
||||
*/
|
||||
NULLS_FIRST,
|
||||
|
||||
/**
|
||||
* A hint to the used data store to order entries with null values after non null entries.
|
||||
* A hint to the used data store to order entries with null values after non-null entries.
|
||||
*/
|
||||
NULLS_LAST;
|
||||
NULLS_LAST
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -541,6 +545,8 @@ public class Sort implements Streamable<org.springframework.data.domain.Sort.Ord
|
||||
* @param direction the new direction to use.
|
||||
* @return a new {@link Order} with the given {@link Direction} applied.
|
||||
*/
|
||||
@Contract("_ -> new")
|
||||
@CheckReturnValue
|
||||
public Order with(Direction direction) {
|
||||
return new Order(direction, this.property, this.ignoreCase, this.nullHandling);
|
||||
}
|
||||
@@ -551,6 +557,7 @@ public class Sort implements Streamable<org.springframework.data.domain.Sort.Ord
|
||||
* @return a reversed {@link Order} with the given {@link Direction} applied.
|
||||
* @since 3.1
|
||||
*/
|
||||
@Contract("-> new")
|
||||
public Order reverse() {
|
||||
return with(this.direction == Direction.ASC ? Direction.DESC : Direction.ASC);
|
||||
}
|
||||
@@ -562,6 +569,8 @@ public class Sort implements Streamable<org.springframework.data.domain.Sort.Ord
|
||||
* @return a new {@link Order} with the {@code property} name applied.
|
||||
* @since 1.13
|
||||
*/
|
||||
@Contract("_ -> new")
|
||||
@CheckReturnValue
|
||||
public Order withProperty(String property) {
|
||||
return new Order(this.direction, property, this.ignoreCase, this.nullHandling);
|
||||
}
|
||||
@@ -572,6 +581,8 @@ public class Sort implements Streamable<org.springframework.data.domain.Sort.Ord
|
||||
* @param properties properties to sort by.
|
||||
* @return a new {@link Sort} instance for the given properties using {@link #getDirection()}.
|
||||
*/
|
||||
@Contract("_ -> new")
|
||||
@CheckReturnValue
|
||||
public Sort withProperties(String... properties) {
|
||||
return Sort.by(this.direction, properties);
|
||||
}
|
||||
@@ -592,6 +603,8 @@ public class Sort implements Streamable<org.springframework.data.domain.Sort.Ord
|
||||
* @return a new {@link Order} with the given {@link NullHandling} applied.
|
||||
* @since 1.8
|
||||
*/
|
||||
@Contract("_ -> new")
|
||||
@CheckReturnValue
|
||||
public Order with(NullHandling nullHandling) {
|
||||
return new Order(direction, this.property, ignoreCase, nullHandling);
|
||||
}
|
||||
@@ -602,6 +615,7 @@ public class Sort implements Streamable<org.springframework.data.domain.Sort.Ord
|
||||
* @return a new {@link Order} with {@link NullHandling#NULLS_FIRST} as null handling hint applied.
|
||||
* @since 1.8
|
||||
*/
|
||||
@Contract("-> new")
|
||||
public Order nullsFirst() {
|
||||
return with(NullHandling.NULLS_FIRST);
|
||||
}
|
||||
@@ -612,6 +626,7 @@ public class Sort implements Streamable<org.springframework.data.domain.Sort.Ord
|
||||
* @return a new {@link Order} with {@link NullHandling#NULLS_LAST} as null handling hint applied.
|
||||
* @since 1.7
|
||||
*/
|
||||
@Contract("-> new")
|
||||
public Order nullsLast() {
|
||||
return with(NullHandling.NULLS_LAST);
|
||||
}
|
||||
@@ -622,6 +637,7 @@ public class Sort implements Streamable<org.springframework.data.domain.Sort.Ord
|
||||
* @return a new {@link Order} with {@link NullHandling#NATIVE} as null handling hint applied.
|
||||
* @since 1.7
|
||||
*/
|
||||
@Contract("-> new")
|
||||
public Order nullsNative() {
|
||||
return with(NullHandling.NATIVE);
|
||||
}
|
||||
@@ -636,19 +652,6 @@ public class Sort implements Streamable<org.springframework.data.domain.Sort.Ord
|
||||
return nullHandling;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
|
||||
int result = 17;
|
||||
|
||||
result = 31 * result + direction.hashCode();
|
||||
result = 31 * result + property.hashCode();
|
||||
result = 31 * result + (ignoreCase ? 1 : 0);
|
||||
result = 31 * result + nullHandling.hashCode();
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(@Nullable Object obj) {
|
||||
|
||||
@@ -664,6 +667,11 @@ public class Sort implements Streamable<org.springframework.data.domain.Sort.Ord
|
||||
&& this.ignoreCase == that.ignoreCase && this.nullHandling.equals(that.nullHandling);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return ObjectUtils.nullSafeHash(direction, property, ignoreCase, nullHandling);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
|
||||
@@ -679,6 +687,7 @@ public class Sort implements Streamable<org.springframework.data.domain.Sort.Ord
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
*/
|
||||
package org.springframework.data.domain;
|
||||
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.ObjectUtils;
|
||||
|
||||
@@ -49,7 +50,7 @@ class TypedExample<T> implements Example<T> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
public boolean equals(@Nullable Object o) {
|
||||
|
||||
if (this == o) {
|
||||
return true;
|
||||
@@ -68,9 +69,7 @@ class TypedExample<T> implements Example<T> {
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int result = ObjectUtils.nullSafeHashCode(probe);
|
||||
result = 31 * result + ObjectUtils.nullSafeHashCode(matcher);
|
||||
return result;
|
||||
return ObjectUtils.nullSafeHash(probe, matcher);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -20,6 +20,7 @@ import java.util.Collections;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.Set;
|
||||
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.ObjectUtils;
|
||||
|
||||
@@ -193,8 +194,9 @@ class TypedExampleMatcher implements ExampleMatcher {
|
||||
return new PropertySpecifier(propertyPath);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
public boolean equals(@Nullable Object o) {
|
||||
|
||||
if (this == o) {
|
||||
return true;
|
||||
@@ -217,7 +219,6 @@ class TypedExampleMatcher implements ExampleMatcher {
|
||||
}
|
||||
|
||||
if (!ObjectUtils.nullSafeEquals(propertySpecifiers, that.propertySpecifiers)) {
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -230,13 +231,8 @@ class TypedExampleMatcher implements ExampleMatcher {
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int result = ObjectUtils.nullSafeHashCode(nullHandler);
|
||||
result = 31 * result + ObjectUtils.nullSafeHashCode(defaultStringMatcher);
|
||||
result = 31 * result + ObjectUtils.nullSafeHashCode(propertySpecifiers);
|
||||
result = 31 * result + ObjectUtils.nullSafeHashCode(ignoredPaths);
|
||||
result = 31 * result + (defaultIgnoreCase ? 1 : 0);
|
||||
result = 31 * result + ObjectUtils.nullSafeHashCode(mode);
|
||||
return result;
|
||||
return ObjectUtils.nullSafeHash(nullHandler, defaultStringMatcher, propertySpecifiers, ignoredPaths,
|
||||
defaultIgnoreCase, mode);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -15,6 +15,8 @@
|
||||
*/
|
||||
package org.springframework.data.domain;
|
||||
|
||||
import org.springframework.lang.Nullable;
|
||||
|
||||
/**
|
||||
* {@link Pageable} implementation to represent the absence of pagination information.
|
||||
*
|
||||
@@ -91,7 +93,7 @@ final class Unpaged implements Pageable {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
public boolean equals(@Nullable Object o) {
|
||||
if (this == o) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -41,7 +41,6 @@ public interface Window<T> extends Streamable<T> {
|
||||
* @param items the list of data.
|
||||
* @param positionFunction the list of data.
|
||||
* @return the {@link Window}.
|
||||
* @param <T>
|
||||
*/
|
||||
static <T> Window<T> from(List<T> items, IntFunction<? extends ScrollPosition> positionFunction) {
|
||||
return new WindowImpl<>(items, positionFunction, false);
|
||||
@@ -54,7 +53,6 @@ public interface Window<T> extends Streamable<T> {
|
||||
* @param positionFunction the list of data.
|
||||
* @param hasNext
|
||||
* @return the {@link Window}.
|
||||
* @param <T>
|
||||
*/
|
||||
static <T> Window<T> from(List<T> items, IntFunction<? extends ScrollPosition> positionFunction, boolean hasNext) {
|
||||
return new WindowImpl<>(items, positionFunction, hasNext);
|
||||
@@ -78,14 +76,14 @@ public interface Window<T> extends Streamable<T> {
|
||||
/**
|
||||
* Returns the windows content as {@link List}.
|
||||
*
|
||||
* @return
|
||||
* @return the windows content as {@link List}.
|
||||
*/
|
||||
List<T> getContent();
|
||||
|
||||
/**
|
||||
* Returns whether the current window is the last one.
|
||||
*
|
||||
* @return
|
||||
* @return {@literal true} if the current window is the last one.
|
||||
*/
|
||||
default boolean isLast() {
|
||||
return !hasNext();
|
||||
@@ -101,13 +99,14 @@ public interface Window<T> extends Streamable<T> {
|
||||
/**
|
||||
* Returns whether the underlying scroll mechanism can provide a {@link ScrollPosition} at {@code index}.
|
||||
*
|
||||
* @param index
|
||||
* @param index the result index to check for a {@link ScrollPosition}.
|
||||
* @return {@code true} if a {@link ScrollPosition} can be created; {@code false} otherwise.
|
||||
* @see #positionAt(int)
|
||||
*/
|
||||
default boolean hasPosition(int index) {
|
||||
try {
|
||||
return positionAt(index) != null;
|
||||
positionAt(index);
|
||||
return true;
|
||||
} catch (IllegalStateException e) {
|
||||
return false;
|
||||
}
|
||||
@@ -116,8 +115,8 @@ public interface Window<T> extends Streamable<T> {
|
||||
/**
|
||||
* Returns the {@link ScrollPosition} at {@code index}.
|
||||
*
|
||||
* @param index
|
||||
* @return
|
||||
* @param index index of the window element to determine the scroll position for.
|
||||
* @return the scroll position for the given object index.
|
||||
* @throws IndexOutOfBoundsException if the index is out of range ({@code index < 0 || index >= size()}).
|
||||
* @throws IllegalStateException if the underlying scroll mechanism cannot provide a scroll position for the given
|
||||
* object.
|
||||
@@ -127,8 +126,8 @@ public interface Window<T> extends Streamable<T> {
|
||||
/**
|
||||
* Returns the {@link ScrollPosition} for {@code object}.
|
||||
*
|
||||
* @param object
|
||||
* @return
|
||||
* @param object member of the window to determine the scroll position for.
|
||||
* @return the scroll position for the given object.
|
||||
* @throws NoSuchElementException if the object is not part of the result.
|
||||
* @throws IllegalStateException if the underlying scroll mechanism cannot provide a scroll position for the given
|
||||
* object.
|
||||
|
||||
@@ -22,6 +22,8 @@ import java.util.function.IntFunction;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.ObjectUtils;
|
||||
|
||||
@@ -86,19 +88,23 @@ class WindowImpl<T> implements Window<T> {
|
||||
return new WindowImpl<>(stream().map(converter).collect(Collectors.toList()), positionFunction, hasNext);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public Iterator<T> iterator() {
|
||||
return items.iterator();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o)
|
||||
public boolean equals(@Nullable Object o) {
|
||||
|
||||
if (this == o) {
|
||||
return true;
|
||||
if (o == null || getClass() != o.getClass())
|
||||
}
|
||||
if (o == null || getClass() != o.getClass()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
WindowImpl<?> that = (WindowImpl<?>) o;
|
||||
|
||||
return ObjectUtils.nullSafeEquals(items, that.items)
|
||||
&& ObjectUtils.nullSafeEquals(positionFunction, that.positionFunction)
|
||||
&& ObjectUtils.nullSafeEquals(hasNext, that.hasNext);
|
||||
@@ -106,9 +112,11 @@ class WindowImpl<T> implements Window<T> {
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
|
||||
int result = ObjectUtils.nullSafeHashCode(items);
|
||||
result = 31 * result + ObjectUtils.nullSafeHashCode(positionFunction);
|
||||
result = 31 * result + ObjectUtils.nullSafeHashCode(hasNext);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
@@ -20,6 +20,7 @@ import jakarta.xml.bind.annotation.adapters.XmlAdapter;
|
||||
import org.springframework.data.domain.Sort;
|
||||
import org.springframework.data.domain.Sort.Order;
|
||||
import org.springframework.data.domain.jaxb.SpringDataJaxb.OrderDto;
|
||||
import org.springframework.lang.Contract;
|
||||
import org.springframework.lang.Nullable;
|
||||
|
||||
/**
|
||||
@@ -46,6 +47,7 @@ public class OrderAdapter extends XmlAdapter<OrderDto, Order> {
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Contract("null -> null")
|
||||
@Override
|
||||
public Order unmarshal(@Nullable OrderDto source) {
|
||||
|
||||
|
||||
@@ -23,6 +23,7 @@ import java.util.List;
|
||||
import org.springframework.data.domain.Page;
|
||||
import org.springframework.data.domain.jaxb.SpringDataJaxb.PageDto;
|
||||
import org.springframework.hateoas.Link;
|
||||
import org.springframework.lang.Contract;
|
||||
import org.springframework.lang.Nullable;
|
||||
|
||||
/**
|
||||
@@ -33,6 +34,7 @@ import org.springframework.lang.Nullable;
|
||||
public class PageAdapter extends XmlAdapter<PageDto, Page<Object>> {
|
||||
|
||||
@Nullable
|
||||
@Contract("null -> null; !null -> !null")
|
||||
@Override
|
||||
public PageDto marshal(@Nullable Page<Object> source) {
|
||||
|
||||
@@ -48,6 +50,7 @@ public class PageAdapter extends XmlAdapter<PageDto, Page<Object>> {
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Contract("_ -> null")
|
||||
@Override
|
||||
public Page<Object> unmarshal(@Nullable PageDto v) {
|
||||
return null;
|
||||
|
||||
@@ -19,6 +19,7 @@ import jakarta.xml.bind.annotation.adapters.XmlAdapter;
|
||||
|
||||
import org.springframework.data.domain.Sort;
|
||||
import org.springframework.data.domain.jaxb.SpringDataJaxb.SortDto;
|
||||
import org.springframework.lang.Contract;
|
||||
import org.springframework.lang.NonNull;
|
||||
import org.springframework.lang.Nullable;
|
||||
|
||||
@@ -32,6 +33,7 @@ public class SortAdapter extends XmlAdapter<SortDto, Sort> {
|
||||
public static final SortAdapter INSTANCE = new SortAdapter();
|
||||
|
||||
@Nullable
|
||||
@Contract("null -> null; !null -> !null")
|
||||
@Override
|
||||
public SortDto marshal(@Nullable Sort source) {
|
||||
|
||||
|
||||
@@ -109,7 +109,7 @@ public abstract class SpringDataJaxb {
|
||||
* @param adapter must not be {@literal null}.
|
||||
* @return
|
||||
*/
|
||||
public static <T, S> List<T> unmarshal(Collection<S> source, XmlAdapter<S, T> adapter) {
|
||||
public static <T, S> List<T> unmarshal(@Nullable Collection<S> source, XmlAdapter<S, T> adapter) {
|
||||
|
||||
Assert.notNull(adapter, "Adapter must not be null");
|
||||
|
||||
|
||||
@@ -15,8 +15,11 @@
|
||||
*/
|
||||
package org.springframework.data.geo;
|
||||
|
||||
import java.io.Serial;
|
||||
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.ObjectUtils;
|
||||
|
||||
/**
|
||||
* Represents a geospatial box value
|
||||
@@ -28,7 +31,7 @@ import org.springframework.util.Assert;
|
||||
*/
|
||||
public class Box implements Shape {
|
||||
|
||||
private static final long serialVersionUID = 8198095179084040711L;
|
||||
private static final @Serial long serialVersionUID = 8198095179084040711L;
|
||||
|
||||
private final Point first;
|
||||
private final Point second;
|
||||
@@ -66,7 +69,7 @@ public class Box implements Shape {
|
||||
/**
|
||||
* Returns the first {@link Point} making up the {@link Box}.
|
||||
*
|
||||
* @return
|
||||
* @return the first {@link Point} making up the {@link Box}.
|
||||
*/
|
||||
public Point getFirst() {
|
||||
return first;
|
||||
@@ -75,26 +78,15 @@ public class Box implements Shape {
|
||||
/**
|
||||
* Returns the second {@link Point} making up the {@link Box}.
|
||||
*
|
||||
* @return
|
||||
* @return the second {@link Point} making up the {@link Box}.
|
||||
*/
|
||||
public Point getSecond() {
|
||||
return second;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return String.format("Box [%s, %s]", first, second);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
|
||||
int result = 31;
|
||||
|
||||
result += 17 * first.hashCode();
|
||||
result += 17 * second.hashCode();
|
||||
|
||||
return result;
|
||||
return ObjectUtils.nullSafeHash(first, second);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -110,4 +102,9 @@ public class Box implements Shape {
|
||||
|
||||
return this.first.equals(that.first) && this.second.equals(that.second);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return String.format("Box [%s, %s]", first, second);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,7 +15,10 @@
|
||||
*/
|
||||
package org.springframework.data.geo;
|
||||
|
||||
import java.io.Serial;
|
||||
|
||||
import org.springframework.data.annotation.PersistenceCreator;
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.ObjectUtils;
|
||||
|
||||
@@ -29,7 +32,7 @@ import org.springframework.util.ObjectUtils;
|
||||
*/
|
||||
public class Circle implements Shape {
|
||||
|
||||
private static final long serialVersionUID = 5215611530535947924L;
|
||||
private static final @Serial long serialVersionUID = 5215611530535947924L;
|
||||
|
||||
private final Point center;
|
||||
private final Distance radius;
|
||||
@@ -65,8 +68,8 @@ public class Circle implements Shape {
|
||||
* Creates a new {@link Circle} from the given coordinates and radius as {@link Distance} with a
|
||||
* {@link Metrics#NEUTRAL}.
|
||||
*
|
||||
* @param centerX
|
||||
* @param centerY
|
||||
* @param centerX X coordinate of the center point.
|
||||
* @param centerY Y coordinate of the center point.
|
||||
* @param radius must be greater or equal to zero.
|
||||
*/
|
||||
public Circle(double centerX, double centerY, double radius) {
|
||||
@@ -85,14 +88,14 @@ public class Circle implements Shape {
|
||||
/**
|
||||
* Returns the radius of the {@link Circle}.
|
||||
*
|
||||
* @return
|
||||
* @return the radius.
|
||||
*/
|
||||
public Distance getRadius() {
|
||||
return radius;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
public boolean equals(@Nullable Object o) {
|
||||
|
||||
if (this == o) {
|
||||
return true;
|
||||
@@ -111,9 +114,7 @@ public class Circle implements Shape {
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int result = ObjectUtils.nullSafeHashCode(center);
|
||||
result = 31 * result + ObjectUtils.nullSafeHashCode(radius);
|
||||
return result;
|
||||
return ObjectUtils.nullSafeHash(center, radius);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -15,6 +15,8 @@
|
||||
*/
|
||||
package org.springframework.data.geo;
|
||||
|
||||
import java.io.Serial;
|
||||
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
@@ -26,7 +28,7 @@ import org.springframework.util.Assert;
|
||||
*/
|
||||
public class CustomMetric implements Metric {
|
||||
|
||||
private static final long serialVersionUID = -2972074177454114228L;
|
||||
private static final @Serial long serialVersionUID = -2972074177454114228L;
|
||||
|
||||
private final double multiplier;
|
||||
private final String abbreviation;
|
||||
@@ -34,7 +36,7 @@ public class CustomMetric implements Metric {
|
||||
/**
|
||||
* Creates a custom {@link Metric} using the given multiplier.
|
||||
*
|
||||
* @param multiplier
|
||||
* @param multiplier metric multiplier.
|
||||
*/
|
||||
public CustomMetric(double multiplier) {
|
||||
|
||||
@@ -44,7 +46,7 @@ public class CustomMetric implements Metric {
|
||||
/**
|
||||
* Creates a custom {@link Metric} using the given multiplier and abbreviation.
|
||||
*
|
||||
* @param multiplier
|
||||
* @param multiplier metric multiplier.
|
||||
* @param abbreviation must not be {@literal null}.
|
||||
*/
|
||||
public CustomMetric(double multiplier, String abbreviation) {
|
||||
|
||||
@@ -15,10 +15,13 @@
|
||||
*/
|
||||
package org.springframework.data.geo;
|
||||
|
||||
import java.io.Serial;
|
||||
import java.io.Serializable;
|
||||
|
||||
import org.springframework.data.domain.Range;
|
||||
import org.springframework.data.domain.Range.Bound;
|
||||
import org.springframework.lang.CheckReturnValue;
|
||||
import org.springframework.lang.Contract;
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.ObjectUtils;
|
||||
@@ -32,7 +35,7 @@ import org.springframework.util.ObjectUtils;
|
||||
*/
|
||||
public final class Distance implements Serializable, Comparable<Distance> {
|
||||
|
||||
private static final long serialVersionUID = 2460886201934027744L;
|
||||
private static final @Serial long serialVersionUID = 2460886201934027744L;
|
||||
|
||||
/**
|
||||
* The distance value in the current {@link Metric}.
|
||||
@@ -47,7 +50,7 @@ public final class Distance implements Serializable, Comparable<Distance> {
|
||||
/**
|
||||
* Creates a new {@link Distance} with a neutral metric. This means the provided value needs to be in normalized form.
|
||||
*
|
||||
* @param value
|
||||
* @param value distance value.
|
||||
*/
|
||||
public Distance(double value) {
|
||||
this(value, Metrics.NEUTRAL);
|
||||
@@ -81,11 +84,11 @@ public final class Distance implements Serializable, Comparable<Distance> {
|
||||
/**
|
||||
* Creates a new {@link Range} by creating minimum and maximum {@link Distance} from the given values.
|
||||
*
|
||||
* @param minValue
|
||||
* @param minValue minimum value.
|
||||
* @param minMetric can be {@literal null}.
|
||||
* @param maxValue
|
||||
* @param maxValue maximum value.
|
||||
* @param maxMetric can be {@literal null}.
|
||||
* @return
|
||||
* @return the {@link Range} between the given values.
|
||||
*/
|
||||
public static Range<Distance> between(double minValue, Metric minMetric, double maxValue, Metric maxMetric) {
|
||||
return between(new Distance(minValue, minMetric), new Distance(maxValue, maxMetric));
|
||||
@@ -94,7 +97,7 @@ public final class Distance implements Serializable, Comparable<Distance> {
|
||||
/**
|
||||
* Returns the normalized value regarding the underlying {@link Metric}.
|
||||
*
|
||||
* @return
|
||||
* @return the normalized value.
|
||||
*/
|
||||
public double getNormalizedValue() {
|
||||
return value / metric.getMultiplier();
|
||||
@@ -115,8 +118,10 @@ public final class Distance implements Serializable, Comparable<Distance> {
|
||||
* current one.
|
||||
*
|
||||
* @param other must not be {@literal null}.
|
||||
* @return
|
||||
* @return sum of this and the other distance.
|
||||
*/
|
||||
@Contract("_ -> new")
|
||||
@CheckReturnValue
|
||||
public Distance add(Distance other) {
|
||||
|
||||
Assert.notNull(other, "Distance to add must not be null");
|
||||
@@ -131,8 +136,9 @@ public final class Distance implements Serializable, Comparable<Distance> {
|
||||
*
|
||||
* @param other must not be {@literal null}.
|
||||
* @param metric must not be {@literal null}.
|
||||
* @return
|
||||
* @return sum of this and the other distance.
|
||||
*/
|
||||
@Contract("_, _ -> new")
|
||||
public Distance add(Distance other, Metric metric) {
|
||||
|
||||
Assert.notNull(other, "Distance to must not be null");
|
||||
@@ -149,8 +155,10 @@ public final class Distance implements Serializable, Comparable<Distance> {
|
||||
* same normalized value as the original instance.
|
||||
*
|
||||
* @param metric must not be {@literal null}.
|
||||
* @return
|
||||
* @return the converted {@link Distance}.
|
||||
*/
|
||||
@Contract("_ -> new")
|
||||
@CheckReturnValue
|
||||
public Distance in(Metric metric) {
|
||||
|
||||
Assert.notNull(metric, "Metric must not be null");
|
||||
@@ -170,19 +178,6 @@ public final class Distance implements Serializable, Comparable<Distance> {
|
||||
return difference == 0 ? 0 : difference > 0 ? 1 : -1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
|
||||
StringBuilder builder = new StringBuilder();
|
||||
builder.append(value);
|
||||
|
||||
if (metric != Metrics.NEUTRAL) {
|
||||
builder.append(" ").append(metric.toString());
|
||||
}
|
||||
|
||||
return builder.toString();
|
||||
}
|
||||
|
||||
public double getValue() {
|
||||
return this.value;
|
||||
}
|
||||
@@ -192,7 +187,7 @@ public final class Distance implements Serializable, Comparable<Distance> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
public boolean equals(@Nullable Object o) {
|
||||
|
||||
if (this == o) {
|
||||
return true;
|
||||
@@ -205,16 +200,25 @@ public final class Distance implements Serializable, Comparable<Distance> {
|
||||
if (value != distance.value) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return ObjectUtils.nullSafeEquals(metric, distance.metric);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int result;
|
||||
long temp;
|
||||
temp = Double.doubleToLongBits(value);
|
||||
result = (int) (temp ^ (temp >>> 32));
|
||||
result = 31 * result + ObjectUtils.nullSafeHashCode(metric);
|
||||
return result;
|
||||
return ObjectUtils.nullSafeHash(value, metric);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
|
||||
StringBuilder builder = new StringBuilder();
|
||||
builder.append(value);
|
||||
|
||||
if (metric != Metrics.NEUTRAL) {
|
||||
builder.append(" ").append(metric.toString());
|
||||
}
|
||||
|
||||
return builder.toString();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
*/
|
||||
package org.springframework.data.geo;
|
||||
|
||||
import java.io.Serial;
|
||||
import java.util.List;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||
@@ -30,9 +31,10 @@ import com.fasterxml.jackson.databind.module.SimpleModule;
|
||||
* @author Oliver Gierke
|
||||
* @since 1.8
|
||||
*/
|
||||
@SuppressWarnings("unused")
|
||||
public class GeoModule extends SimpleModule {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
private static final @Serial long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* Creates a new {@link GeoModule} registering mixins for common geo-spatial types.
|
||||
|
||||
@@ -15,6 +15,8 @@
|
||||
*/
|
||||
package org.springframework.data.geo;
|
||||
|
||||
import java.io.Serial;
|
||||
|
||||
import org.springframework.data.domain.Page;
|
||||
import org.springframework.data.domain.PageImpl;
|
||||
import org.springframework.data.domain.Pageable;
|
||||
@@ -31,7 +33,7 @@ import org.springframework.util.ObjectUtils;
|
||||
*/
|
||||
public class GeoPage<T> extends PageImpl<GeoResult<T>> {
|
||||
|
||||
private static final long serialVersionUID = -5655267379242128600L;
|
||||
private static final @Serial long serialVersionUID = -5655267379242128600L;
|
||||
|
||||
/**
|
||||
* The average distance of the underlying results.
|
||||
@@ -55,7 +57,7 @@ public class GeoPage<T> extends PageImpl<GeoResult<T>> {
|
||||
*
|
||||
* @param results must not be {@literal null}.
|
||||
* @param pageable must not be {@literal null}.
|
||||
* @param total
|
||||
* @param total total number of results.
|
||||
*/
|
||||
public GeoPage(GeoResults<T> results, Pageable pageable, long total) {
|
||||
|
||||
@@ -64,6 +66,10 @@ public class GeoPage<T> extends PageImpl<GeoResult<T>> {
|
||||
this.averageDistance = results.getAverageDistance();
|
||||
}
|
||||
|
||||
public Distance getAverageDistance() {
|
||||
return this.averageDistance;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(@Nullable Object obj) {
|
||||
|
||||
@@ -82,8 +88,4 @@ public class GeoPage<T> extends PageImpl<GeoResult<T>> {
|
||||
public int hashCode() {
|
||||
return super.hashCode() + ObjectUtils.nullSafeHashCode(this.averageDistance);
|
||||
}
|
||||
|
||||
public Distance getAverageDistance() {
|
||||
return this.averageDistance;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,8 +15,10 @@
|
||||
*/
|
||||
package org.springframework.data.geo;
|
||||
|
||||
import java.io.Serial;
|
||||
import java.io.Serializable;
|
||||
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.ObjectUtils;
|
||||
|
||||
@@ -29,7 +31,7 @@ import org.springframework.util.ObjectUtils;
|
||||
*/
|
||||
public final class GeoResult<T> implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 1637452570977581370L;
|
||||
private static final @Serial long serialVersionUID = 1637452570977581370L;
|
||||
|
||||
private final T content;
|
||||
private final Distance distance;
|
||||
@@ -52,7 +54,7 @@ public final class GeoResult<T> implements Serializable {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
public boolean equals(@Nullable Object o) {
|
||||
|
||||
if (this == o) {
|
||||
return true;
|
||||
@@ -71,9 +73,7 @@ public final class GeoResult<T> implements Serializable {
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int result = ObjectUtils.nullSafeHashCode(content);
|
||||
result = 31 * result + ObjectUtils.nullSafeHashCode(distance);
|
||||
return result;
|
||||
return ObjectUtils.nullSafeHash(content, distance);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -15,12 +15,15 @@
|
||||
*/
|
||||
package org.springframework.data.geo;
|
||||
|
||||
|
||||
import java.io.Serial;
|
||||
import java.io.Serializable;
|
||||
import java.util.Collections;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.data.annotation.PersistenceCreator;
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.ObjectUtils;
|
||||
import org.springframework.util.StringUtils;
|
||||
@@ -34,7 +37,7 @@ import org.springframework.util.StringUtils;
|
||||
*/
|
||||
public class GeoResults<T> implements Iterable<GeoResult<T>>, Serializable {
|
||||
|
||||
private static final long serialVersionUID = 8347363491300219485L;
|
||||
private static final @Serial long serialVersionUID = 8347363491300219485L;
|
||||
|
||||
private final List<? extends GeoResult<T>> results;
|
||||
private final Distance averageDistance;
|
||||
@@ -88,19 +91,20 @@ public class GeoResults<T> implements Iterable<GeoResult<T>>, Serializable {
|
||||
/**
|
||||
* Returns the actual content of the {@link GeoResults}.
|
||||
*
|
||||
* @return
|
||||
* @return the actual content.
|
||||
*/
|
||||
public List<GeoResult<T>> getContent() {
|
||||
return Collections.unmodifiableList(results);
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public Iterator<GeoResult<T>> iterator() {
|
||||
return (Iterator<GeoResult<T>>) results.iterator();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
public boolean equals(@Nullable Object o) {
|
||||
|
||||
if (this == o) {
|
||||
return true;
|
||||
@@ -119,9 +123,7 @@ public class GeoResults<T> implements Iterable<GeoResult<T>>, Serializable {
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int result = ObjectUtils.nullSafeHashCode(results);
|
||||
result = 31 * result + ObjectUtils.nullSafeHashCode(averageDistance);
|
||||
return result;
|
||||
return ObjectUtils.nullSafeHash(results, averageDistance);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -15,12 +15,14 @@
|
||||
*/
|
||||
package org.springframework.data.geo;
|
||||
|
||||
import java.io.Serial;
|
||||
import java.io.Serializable;
|
||||
import java.util.Locale;
|
||||
|
||||
import org.springframework.data.annotation.PersistenceCreator;
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.ObjectUtils;
|
||||
|
||||
/**
|
||||
* Represents a geospatial point value.
|
||||
@@ -32,7 +34,7 @@ import org.springframework.util.Assert;
|
||||
*/
|
||||
public class Point implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 3583151228933783558L;
|
||||
private static final @Serial long serialVersionUID = 3583151228933783558L;
|
||||
|
||||
private final double x;
|
||||
private final double y;
|
||||
@@ -40,8 +42,8 @@ public class Point implements Serializable {
|
||||
/**
|
||||
* Creates a {@link Point} from the given {@code x}, {@code y} coordinate.
|
||||
*
|
||||
* @param x
|
||||
* @param y
|
||||
* @param x x coordinate.
|
||||
* @param y y coordinate.
|
||||
*/
|
||||
@PersistenceCreator
|
||||
public Point(double x, double y) {
|
||||
@@ -65,7 +67,7 @@ public class Point implements Serializable {
|
||||
/**
|
||||
* Returns the x-coordinate of the {@link Point}.
|
||||
*
|
||||
* @return
|
||||
* @return the x-coordinate of the {@link Point}.
|
||||
*/
|
||||
public double getX() {
|
||||
return x;
|
||||
@@ -74,7 +76,7 @@ public class Point implements Serializable {
|
||||
/**
|
||||
* Returns the y-coordinate of the {@link Point}.
|
||||
*
|
||||
* @return
|
||||
* @return the y-coordinate of the {@link Point}.
|
||||
*/
|
||||
public double getY() {
|
||||
return y;
|
||||
@@ -82,16 +84,7 @@ public class Point implements Serializable {
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
|
||||
int result = 1;
|
||||
|
||||
long temp = Double.doubleToLongBits(x);
|
||||
result = 31 * result + (int) (temp ^ temp >>> 32);
|
||||
|
||||
temp = Double.doubleToLongBits(y);
|
||||
result = 31 * result + (int) (temp ^ temp >>> 32);
|
||||
|
||||
return result;
|
||||
return ObjectUtils.nullSafeHash(x, y);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -15,6 +15,8 @@
|
||||
*/
|
||||
package org.springframework.data.geo;
|
||||
|
||||
|
||||
import java.io.Serial;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
@@ -22,6 +24,7 @@ import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.data.annotation.PersistenceCreator;
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.ObjectUtils;
|
||||
import org.springframework.util.StringUtils;
|
||||
@@ -35,7 +38,7 @@ import org.springframework.util.StringUtils;
|
||||
*/
|
||||
public class Polygon implements Iterable<Point>, Shape {
|
||||
|
||||
private static final long serialVersionUID = -2705040068154648988L;
|
||||
private static final @Serial long serialVersionUID = -2705040068154648988L;
|
||||
|
||||
private final List<Point> points;
|
||||
|
||||
@@ -45,7 +48,7 @@ public class Polygon implements Iterable<Point>, Shape {
|
||||
* @param x must not be {@literal null}.
|
||||
* @param y must not be {@literal null}.
|
||||
* @param z must not be {@literal null}.
|
||||
* @param others
|
||||
* @param others other points.
|
||||
*/
|
||||
public Polygon(Point x, Point y, Point z, Point... others) {
|
||||
|
||||
@@ -91,12 +94,13 @@ public class Polygon implements Iterable<Point>, Shape {
|
||||
return this.points;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterator<Point> iterator() {
|
||||
return this.points.iterator();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
public boolean equals(@Nullable Object o) {
|
||||
|
||||
if (this == o) {
|
||||
return true;
|
||||
|
||||
@@ -27,6 +27,7 @@ import org.springframework.data.geo.Distance;
|
||||
import org.springframework.data.geo.Metric;
|
||||
import org.springframework.data.geo.Metrics;
|
||||
import org.springframework.format.Formatter;
|
||||
import org.springframework.lang.Contract;
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
@@ -57,15 +58,17 @@ public enum DistanceFormatter implements Converter<String, Distance>, Formatter<
|
||||
SUPPORTED_METRICS = Collections.unmodifiableMap(metrics);
|
||||
}
|
||||
|
||||
@Contract("null -> null; !null -> !null")
|
||||
@Nullable
|
||||
@Override
|
||||
public final Distance convert(String source) {
|
||||
public final Distance convert(@Nullable String source) {
|
||||
return source == null ? null : doConvert(source.trim().toLowerCase(Locale.US));
|
||||
}
|
||||
|
||||
@Override
|
||||
public String print(Distance distance, Locale locale) {
|
||||
return distance == null ? null : String.format("%s%s", distance.getValue(), distance.getUnit().toLowerCase(locale));
|
||||
public String print(@Nullable Distance distance, Locale locale) {
|
||||
return distance == null ? "null"
|
||||
: String.format("%s%s", distance.getValue(), distance.getUnit().toLowerCase(locale));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -78,7 +81,6 @@ public enum DistanceFormatter implements Converter<String, Distance>, Formatter<
|
||||
* in the {@link #SUPPORTED_METRICS} map.
|
||||
*
|
||||
* @param source must not be {@literal null}.
|
||||
* @return
|
||||
*/
|
||||
private static Distance doConvert(String source) {
|
||||
|
||||
@@ -101,7 +103,6 @@ public enum DistanceFormatter implements Converter<String, Distance>, Formatter<
|
||||
*
|
||||
* @param source the raw source {@link String}, must not be {@literal null} or empty.
|
||||
* @param metric the {@link Metric} detected keyed by the keyword it was detected for, must not be {@literal null}.
|
||||
* @return
|
||||
*/
|
||||
private static Distance fromString(String source, Entry<String, Metric> metric) {
|
||||
|
||||
|
||||
@@ -23,6 +23,7 @@ import org.springframework.core.convert.converter.GenericConverter.ConvertiblePa
|
||||
import org.springframework.data.geo.Point;
|
||||
import org.springframework.format.Formatter;
|
||||
import org.springframework.lang.NonNull;
|
||||
import org.springframework.lang.Nullable;
|
||||
|
||||
/**
|
||||
* Converter to parse two comma-separated doubles into a {@link Point}.
|
||||
@@ -60,8 +61,8 @@ public enum PointFormatter implements Converter<String, Point>, Formatter<Point>
|
||||
}
|
||||
|
||||
@Override
|
||||
public String print(Point point, Locale locale) {
|
||||
return point == null ? null : String.format("%s,%s", point.getY(), point.getX());
|
||||
public String print(@Nullable Point point, Locale locale) {
|
||||
return point == null ? "null" : String.format("%s,%s", point.getY(), point.getX());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
*/
|
||||
package org.springframework.data.history;
|
||||
|
||||
import java.io.Serial;
|
||||
import java.util.Arrays;
|
||||
|
||||
import org.springframework.data.domain.Sort;
|
||||
@@ -30,7 +31,7 @@ import org.springframework.util.Assert;
|
||||
*/
|
||||
public class RevisionSort extends Sort {
|
||||
|
||||
private static final long serialVersionUID = 618238321589063537L;
|
||||
private static final @Serial long serialVersionUID = 618238321589063537L;
|
||||
|
||||
private static final String PROPERTY = "__revisionNumber__";
|
||||
private static final RevisionSort ASC = new RevisionSort(Direction.ASC);
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
*/
|
||||
package org.springframework.data.mapping;
|
||||
|
||||
import java.util.NoSuchElementException;
|
||||
import java.util.Objects;
|
||||
|
||||
import org.springframework.lang.Nullable;
|
||||
@@ -41,9 +42,9 @@ public final class Alias {
|
||||
@SuppressWarnings("null") //
|
||||
public static final Alias NONE = new Alias(null);
|
||||
|
||||
private final Object value;
|
||||
private final @Nullable Object value;
|
||||
|
||||
private Alias(Object value) {
|
||||
private Alias(@Nullable Object value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
@@ -120,6 +121,14 @@ public final class Alias {
|
||||
return value != null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return {@literal true} if this {@link Alias} does not contain a value.
|
||||
* @since 4.0
|
||||
*/
|
||||
public boolean isEmpty() {
|
||||
return value == null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the value typed to {@code type} if the value is present and assignable to {@code type}.
|
||||
*
|
||||
@@ -135,15 +144,27 @@ public final class Alias {
|
||||
return isPresent() && type.isInstance(value) ? (T) value : null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return isPresent() ? value.toString() : "NONE";
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public Object getValue() {
|
||||
return this.value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the required value or throw {@link NoSuchElementException} if the value is {@link #isEmpty() absent}.
|
||||
*
|
||||
* @return the required value.
|
||||
*/
|
||||
public Object getRequiredValue() {
|
||||
|
||||
Object value = getValue();
|
||||
|
||||
if (value == null) {
|
||||
throw new NoSuchElementException("No value present");
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(@Nullable Object o) {
|
||||
|
||||
@@ -162,4 +183,9 @@ public final class Alias {
|
||||
public int hashCode() {
|
||||
return Objects.hashCode(value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return isPresent() ? value.toString() : "NONE";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -32,8 +32,8 @@ public class Association<P extends PersistentProperty<P>> {
|
||||
/**
|
||||
* Creates a new {@link Association} between the two given {@link PersistentProperty}s.
|
||||
*
|
||||
* @param inverse
|
||||
* @param obverse
|
||||
* @param inverse the inverse {@link PersistentProperty}.
|
||||
* @param obverse the obverse {@link PersistentProperty}. Can be {@literal null} if absent.
|
||||
*/
|
||||
public Association(P inverse, @Nullable P obverse) {
|
||||
this.inverse = inverse;
|
||||
|
||||
@@ -15,6 +15,8 @@
|
||||
*/
|
||||
package org.springframework.data.mapping;
|
||||
|
||||
import java.io.Serial;
|
||||
|
||||
import org.springframework.lang.Nullable;
|
||||
|
||||
/**
|
||||
@@ -22,7 +24,7 @@ import org.springframework.lang.Nullable;
|
||||
*/
|
||||
public class MappingException extends RuntimeException {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
private static final @Serial long serialVersionUID = 1L;
|
||||
|
||||
public MappingException(@Nullable String s) {
|
||||
super(s);
|
||||
|
||||
@@ -184,6 +184,7 @@ public class Parameter<T, P extends PersistentProperty<P>> {
|
||||
* @return the expression to be used when looking up a source data structure.
|
||||
* @since 3.3
|
||||
*/
|
||||
@SuppressWarnings("DataFlowIssue")
|
||||
public String getRequiredValueExpression() {
|
||||
|
||||
if (!hasValueExpression()) {
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
*/
|
||||
package org.springframework.data.mapping;
|
||||
|
||||
import java.io.Serial;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.HashSet;
|
||||
@@ -37,7 +38,7 @@ import org.springframework.util.StringUtils;
|
||||
*/
|
||||
public class PropertyReferenceException extends RuntimeException {
|
||||
|
||||
private static final long serialVersionUID = -5254424051438976570L;
|
||||
private static final @Serial long serialVersionUID = -5254424051438976570L;
|
||||
|
||||
static final String ERROR_TEMPLATE = "No property '%s' found for type '%s'";
|
||||
static final String HINTS_TEMPLATE = "Did you mean %s";
|
||||
|
||||
@@ -99,6 +99,7 @@ class DefaultReactiveEntityCallbacks implements ReactiveEntityCallbacks {
|
||||
|
||||
static class DefaultReactiveEntityCallbackInvoker implements ReactiveEntityCallbackInvoker {
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public <T> Mono<T> invokeCallback(EntityCallback<T> callback, T entity,
|
||||
BiFunction<EntityCallback<T>, T, Object> callbackInvokerFunction) {
|
||||
|
||||
@@ -53,11 +53,8 @@ class EntityCallbackDiscoverer {
|
||||
|
||||
private final CallbackRetriever defaultRetriever = new CallbackRetriever();
|
||||
private final Map<CallbackCacheKey, CallbackRetriever> retrieverCache = new ConcurrentHashMap<>(64);
|
||||
private final Map<Class<?>, ResolvableType> entityTypeCache = new ConcurrentHashMap<>(64);
|
||||
|
||||
@Nullable private ClassLoader beanClassLoader;
|
||||
|
||||
private Object retrievalMutex = this.defaultRetriever;
|
||||
private @Nullable ClassLoader beanClassLoader;
|
||||
|
||||
/**
|
||||
* Create a new {@link EntityCallback} instance.
|
||||
@@ -76,7 +73,7 @@ class EntityCallbackDiscoverer {
|
||||
|
||||
Assert.notNull(callback, "Callback must not be null");
|
||||
|
||||
synchronized (this.retrievalMutex) {
|
||||
synchronized (this.defaultRetriever) {
|
||||
|
||||
// Explicitly remove target for a proxy, if registered already,
|
||||
// in order to avoid double invocations of the same callback.
|
||||
@@ -91,14 +88,6 @@ class EntityCallbackDiscoverer {
|
||||
}
|
||||
}
|
||||
|
||||
void removeEntityCallback(EntityCallback<?> callback) {
|
||||
|
||||
synchronized (this.retrievalMutex) {
|
||||
this.defaultRetriever.entityCallbacks.remove(callback);
|
||||
this.retrieverCache.clear();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a {@link Collection} of all {@link EntityCallback}s matching the given entity type. Non-matching callbacks
|
||||
* get excluded early.
|
||||
@@ -112,8 +101,7 @@ class EntityCallbackDiscoverer {
|
||||
@SuppressWarnings({ "unchecked", "rawtypes" })
|
||||
<T extends S, S> Collection<EntityCallback<S>> getEntityCallbacks(Class<T> entity, ResolvableType callbackType) {
|
||||
|
||||
Class<?> sourceType = entity;
|
||||
CallbackCacheKey cacheKey = new CallbackCacheKey(callbackType, sourceType);
|
||||
CallbackCacheKey cacheKey = new CallbackCacheKey(callbackType, entity);
|
||||
|
||||
// Quick check for existing entry on ConcurrentHashMap...
|
||||
CallbackRetriever retriever = this.retrieverCache.get(cacheKey);
|
||||
@@ -122,16 +110,16 @@ class EntityCallbackDiscoverer {
|
||||
}
|
||||
|
||||
if (this.beanClassLoader == null || ClassUtils.isCacheSafe(entity, this.beanClassLoader)
|
||||
&& (sourceType == null || ClassUtils.isCacheSafe(sourceType, this.beanClassLoader))) {
|
||||
&& ClassUtils.isCacheSafe(entity, this.beanClassLoader)) {
|
||||
|
||||
// Fully synchronized building and caching of a CallbackRetriever
|
||||
synchronized (this.retrievalMutex) {
|
||||
synchronized (this.defaultRetriever) {
|
||||
retriever = this.retrieverCache.get(cacheKey);
|
||||
if (retriever != null) {
|
||||
return (Collection) retriever.getEntityCallbacks();
|
||||
}
|
||||
retriever = new CallbackRetriever();
|
||||
Collection<EntityCallback<?>> callbacks = retrieveEntityCallbacks(ResolvableType.forClass(sourceType),
|
||||
Collection<EntityCallback<?>> callbacks = retrieveEntityCallbacks(ResolvableType.forClass(entity),
|
||||
callbackType, retriever);
|
||||
this.retrieverCache.put(cacheKey, retriever);
|
||||
return (Collection) callbacks;
|
||||
@@ -142,19 +130,6 @@ class EntityCallbackDiscoverer {
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
ResolvableType resolveDeclaredEntityType(Class<?> callbackType) {
|
||||
|
||||
ResolvableType eventType = entityTypeCache.get(callbackType);
|
||||
|
||||
if (eventType == null) {
|
||||
eventType = ResolvableType.forClass(callbackType).as(EntityCallback.class).getGeneric();
|
||||
entityTypeCache.put(callbackType, eventType);
|
||||
}
|
||||
|
||||
return eventType != ResolvableType.NONE ? eventType : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Actually retrieve the callbacks for the given entity and callback type.
|
||||
*
|
||||
@@ -169,7 +144,7 @@ class EntityCallbackDiscoverer {
|
||||
List<EntityCallback<?>> allCallbacks = new ArrayList<>();
|
||||
Set<EntityCallback<?>> callbacks;
|
||||
|
||||
synchronized (this.retrievalMutex) {
|
||||
synchronized (this.defaultRetriever) {
|
||||
callbacks = new LinkedHashSet<>(this.defaultRetriever.entityCallbacks);
|
||||
}
|
||||
|
||||
@@ -211,15 +186,12 @@ class EntityCallbackDiscoverer {
|
||||
if (this.beanClassLoader == null) {
|
||||
this.beanClassLoader = cbf.getBeanClassLoader();
|
||||
}
|
||||
|
||||
this.retrievalMutex = new Object();
|
||||
}
|
||||
|
||||
defaultRetriever.discoverEntityCallbacks(beanFactory);
|
||||
this.retrieverCache.clear();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
static Method lookupCallbackMethod(Class<?> callbackType, Class<?> entityType, Object[] args) {
|
||||
|
||||
Collection<Method> methods = new ArrayList<>(1);
|
||||
@@ -299,6 +271,7 @@ class EntityCallbackDiscoverer {
|
||||
return this.entityCallbacks;
|
||||
}
|
||||
|
||||
@SuppressWarnings("rawtypes")
|
||||
void discoverEntityCallbacks(BeanFactory beanFactory) {
|
||||
|
||||
// We need both a ListableBeanFactory and BeanDefinitionRegistry here for advanced inspection.
|
||||
|
||||
@@ -29,7 +29,6 @@ interface EntityCallbackInvoker {
|
||||
* @param callback must not be {@literal null}.
|
||||
* @param entity must not be {@literal null}
|
||||
* @param callbackInvokerFunction must not be {@literal null}.
|
||||
* @param <T>
|
||||
* @return never {@literal null}.
|
||||
*/
|
||||
<T> Object invokeCallback(EntityCallback<T> callback, T entity,
|
||||
|
||||
@@ -19,9 +19,6 @@ import reactor.core.publisher.Mono;
|
||||
|
||||
import java.util.function.BiFunction;
|
||||
|
||||
import org.springframework.lang.NonNull;
|
||||
import org.springframework.lang.Nullable;
|
||||
|
||||
/**
|
||||
* @author Christoph Strobl
|
||||
* @since 2.2
|
||||
@@ -32,11 +29,9 @@ interface ReactiveEntityCallbackInvoker extends EntityCallbackInvoker {
|
||||
* @param callback must not be {@literal null}.
|
||||
* @param entity can be {@literal null}
|
||||
* @param callbackInvokerFunction must not be {@literal null}.
|
||||
* @param <T>
|
||||
* @return a {@link Mono} emitting the result of the invocation.
|
||||
*/
|
||||
@NonNull
|
||||
@Override
|
||||
<T> Mono<T> invokeCallback(EntityCallback<T> callback, @Nullable T entity,
|
||||
<T> Mono<T> invokeCallback(EntityCallback<T> callback, T entity,
|
||||
BiFunction<EntityCallback<T>, T, Object> callbackInvokerFunction);
|
||||
}
|
||||
|
||||
@@ -77,7 +77,7 @@ public interface ReactiveEntityCallbacks {
|
||||
/**
|
||||
* Obtain a new {@link ReactiveEntityCallbacks} instance.
|
||||
* <p>
|
||||
* {@link EntityCallback callbacks} are pre loaded from the given {@link BeanFactory}. <br />
|
||||
* {@link EntityCallback callbacks} are pre-loaded from the given {@link BeanFactory}. <br />
|
||||
* Use {@link #addEntityCallback(EntityCallback)} to register additional callbacks manually.
|
||||
*
|
||||
* @param beanFactory must not be {@literal null}.
|
||||
|
||||
@@ -141,7 +141,7 @@ public abstract class AbstractMappingContext<E extends MutablePersistentEntity<?
|
||||
* already set.
|
||||
*
|
||||
* @param applicationContext the ApplicationContext object to be used by this object.
|
||||
* @throws BeansException
|
||||
* @throws BeansException in case of initialization errors.
|
||||
*/
|
||||
@Override
|
||||
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
|
||||
@@ -159,7 +159,7 @@ public abstract class AbstractMappingContext<E extends MutablePersistentEntity<?
|
||||
|
||||
/**
|
||||
* @param beanFactory owning BeanFactory.
|
||||
* @throws BeansException
|
||||
* @throws BeansException in case of initialization errors.
|
||||
* @since 3.3
|
||||
*/
|
||||
@Override
|
||||
@@ -565,9 +565,9 @@ public abstract class AbstractMappingContext<E extends MutablePersistentEntity<?
|
||||
|
||||
/**
|
||||
* Returns whether a {@link PersistentEntity} instance should be created for the given {@link TypeInformation}. By
|
||||
* default this will reject all types considered simple and non-supported Kotlin classes, but it might be necessary to
|
||||
* tweak that in case you have registered custom converters for top level types (which renders them to be considered
|
||||
* simple) but still need meta-information about them.
|
||||
* default, this will reject all types considered simple and non-supported Kotlin classes, but it might be necessary
|
||||
* to tweak that in case you have registered custom converters for top level types (which renders them to be
|
||||
* considered simple) but still need meta-information about them.
|
||||
*
|
||||
* @param type will never be {@literal null}.
|
||||
* @return
|
||||
@@ -673,7 +673,7 @@ public abstract class AbstractMappingContext<E extends MutablePersistentEntity<?
|
||||
});
|
||||
}
|
||||
|
||||
protected boolean shouldSkipOverrideProperty(P property) {
|
||||
private boolean shouldSkipOverrideProperty(P property) {
|
||||
|
||||
P existingProperty = entity.getPersistentProperty(property.getName());
|
||||
|
||||
@@ -758,7 +758,7 @@ public abstract class AbstractMappingContext<E extends MutablePersistentEntity<?
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
static enum PersistentPropertyFilter implements FieldFilter {
|
||||
enum PersistentPropertyFilter implements FieldFilter {
|
||||
|
||||
INSTANCE;
|
||||
|
||||
|
||||
@@ -24,6 +24,7 @@ import org.springframework.core.convert.converter.Converter;
|
||||
import org.springframework.data.mapping.PersistentProperty;
|
||||
import org.springframework.data.mapping.PersistentPropertyPath;
|
||||
import org.springframework.data.util.TypeInformation;
|
||||
import org.springframework.lang.Contract;
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.ObjectUtils;
|
||||
@@ -56,7 +57,7 @@ class DefaultPersistentPropertyPath<P extends PersistentProperty<P>> implements
|
||||
/**
|
||||
* Creates an empty {@link DefaultPersistentPropertyPath}.
|
||||
*
|
||||
* @return
|
||||
* @return an empty {@link DefaultPersistentPropertyPath}.
|
||||
*/
|
||||
static <T extends PersistentProperty<T>> DefaultPersistentPropertyPath<T> empty() {
|
||||
return new DefaultPersistentPropertyPath<T>(Collections.emptyList());
|
||||
@@ -206,6 +207,7 @@ class DefaultPersistentPropertyPath<P extends PersistentProperty<P>> implements
|
||||
* @param type can be {@literal null}.
|
||||
* @return
|
||||
*/
|
||||
@Contract("null -> false")
|
||||
public boolean containsPropertyOfType(@Nullable TypeInformation<?> type) {
|
||||
|
||||
if (type == null) {
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
*/
|
||||
package org.springframework.data.mapping.context;
|
||||
|
||||
import java.io.Serial;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
@@ -36,7 +37,7 @@ import org.springframework.util.StringUtils;
|
||||
*/
|
||||
public class InvalidPersistentPropertyPath extends MappingException {
|
||||
|
||||
private static final long serialVersionUID = 2805815643641094488L;
|
||||
private static final @Serial long serialVersionUID = 2805815643641094488L;
|
||||
private static final String DEFAULT_MESSAGE = "No property '%s' found on %s; Did you mean: %s";
|
||||
|
||||
private final String source;
|
||||
@@ -109,9 +110,7 @@ public class InvalidPersistentPropertyPath extends MappingException {
|
||||
return "";
|
||||
}
|
||||
|
||||
String dotPath = path.toDotPath();
|
||||
|
||||
return dotPath == null ? "" : dotPath;
|
||||
return path.toDotPath();
|
||||
}
|
||||
|
||||
private static String createMessage(TypeInformation<?> type, String unresolvableSegment) {
|
||||
|
||||
@@ -15,6 +15,8 @@
|
||||
*/
|
||||
package org.springframework.data.mapping.context;
|
||||
|
||||
import java.io.Serial;
|
||||
|
||||
import org.springframework.context.ApplicationEvent;
|
||||
import org.springframework.data.mapping.PersistentEntity;
|
||||
import org.springframework.data.mapping.PersistentProperty;
|
||||
@@ -31,7 +33,7 @@ import org.springframework.util.Assert;
|
||||
public class MappingContextEvent<E extends PersistentEntity<?, P>, P extends PersistentProperty<P>> extends
|
||||
ApplicationEvent {
|
||||
|
||||
private static final long serialVersionUID = 1336466833846092490L;
|
||||
private static final @Serial long serialVersionUID = 1336466833846092490L;
|
||||
|
||||
private final MappingContext<?, ?> source;
|
||||
private final E entity;
|
||||
|
||||
@@ -53,7 +53,6 @@ public class PersistentEntities implements Streamable<PersistentEntity<?, ? exte
|
||||
*
|
||||
* @param contexts
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public PersistentEntities(Iterable<? extends MappingContext<?, ?>> contexts) {
|
||||
|
||||
Assert.notNull(contexts, "MappingContexts must not be null");
|
||||
@@ -208,7 +207,7 @@ public class PersistentEntities implements Streamable<PersistentEntity<?, ? exte
|
||||
|
||||
/**
|
||||
* Returns the type the given {@link PersistentProperty} ultimately refers to. In case it's of a unique identifier
|
||||
* type of an entity known it'll return the entity type.
|
||||
* type of entity known it'll return the entity type.
|
||||
*
|
||||
* @param property must not be {@literal null}.
|
||||
* @return
|
||||
|
||||
@@ -436,8 +436,8 @@ class PersistentPropertyPathFactory<E extends PersistentEntity<?, P>, P extends
|
||||
|
||||
private final PersistentPropertyPath<?> path;
|
||||
private final boolean resolvable;
|
||||
private @Nullable final String source;
|
||||
|
||||
private @Nullable final String source;
|
||||
private @Nullable final String segment;
|
||||
private @Nullable final TypeInformation<?> type;
|
||||
|
||||
|
||||
@@ -117,8 +117,7 @@ public class BasicPersistentEntity<T, P extends PersistentProperty<P>> implement
|
||||
|
||||
this.propertyCache = new HashMap<>(16, 1.0f);
|
||||
this.annotationCache = new ConcurrentHashMap<>(16);
|
||||
this.propertyAnnotationCache = CollectionUtils
|
||||
.toMultiValueMap(new ConcurrentHashMap<>(16));
|
||||
this.propertyAnnotationCache = CollectionUtils.toMultiValueMap(new ConcurrentHashMap<>(16));
|
||||
this.propertyAccessorFactory = BeanWrapperPropertyAccessorFactory.INSTANCE;
|
||||
this.typeAlias = Lazy.of(() -> getAliasFromAnnotation(getType()));
|
||||
this.isNewStrategy = Lazy.of(() -> Persistable.class.isAssignableFrom(information.getType()) //
|
||||
@@ -549,15 +548,8 @@ public class BasicPersistentEntity<T, P extends PersistentProperty<P>> implement
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
private static final class AssociationComparator<P extends PersistentProperty<P>>
|
||||
implements Comparator<Association<P>>, Serializable {
|
||||
|
||||
private static final long serialVersionUID = 4508054194886854513L;
|
||||
private final Comparator<P> delegate;
|
||||
|
||||
AssociationComparator(Comparator<P> delegate) {
|
||||
this.delegate = delegate;
|
||||
}
|
||||
private record AssociationComparator<P extends PersistentProperty<P>>(
|
||||
Comparator<P> delegate) implements Comparator<Association<P>>, Serializable {
|
||||
|
||||
@Override
|
||||
public int compare(@Nullable Association<P> left, @Nullable Association<P> right) {
|
||||
|
||||
@@ -141,7 +141,7 @@ class BeanWrapper<T> implements PersistentPropertyAccessor<T> {
|
||||
|
||||
} catch (IllegalStateException e) {
|
||||
throw new MappingException(
|
||||
String.format("Could not read property %s of %s", property.toString(), bean.toString()), e);
|
||||
String.format("Could not read property %s of %s", property, bean.toString()), e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -179,7 +179,7 @@ abstract class BytecodeUtil {
|
||||
* Returns the signature type for a {@link Class} including primitives.
|
||||
*
|
||||
* @param type must not be {@literal null}
|
||||
* @return
|
||||
* @return bytecode type name in the form of {@literal Ljava/lang/Object;}.
|
||||
*/
|
||||
static String signatureTypeName(Class<?> type) {
|
||||
|
||||
|
||||
@@ -379,12 +379,10 @@ public class ClassGeneratingPropertyAccessorFactory implements PersistentPropert
|
||||
final List<PersistentProperty<?>> persistentProperties = new ArrayList<>();
|
||||
|
||||
entity.doWithAssociations((SimpleAssociationHandler) association -> {
|
||||
if (association.getInverse() != null) {
|
||||
persistentProperties.add(association.getInverse());
|
||||
}
|
||||
persistentProperties.add(association.getInverse());
|
||||
});
|
||||
|
||||
entity.doWithProperties((SimplePropertyHandler) property -> persistentProperties.add(property));
|
||||
entity.doWithProperties((SimplePropertyHandler) persistentProperties::add);
|
||||
|
||||
return persistentProperties;
|
||||
}
|
||||
@@ -583,9 +581,9 @@ public class ClassGeneratingPropertyAccessorFactory implements PersistentPropert
|
||||
// keep it a lambda to infer the correct types, preventing
|
||||
// LambdaConversionException: Invalid receiver type class java.lang.reflect.AccessibleObject; not a subtype
|
||||
// of implementation type interface java.lang.reflect.Member
|
||||
.map(it -> it.getDeclaringClass());
|
||||
.map(Member::getDeclaringClass);
|
||||
|
||||
}).collect(Collectors.collectingAndThen(Collectors.toSet(), it -> new ArrayList<>(it)));
|
||||
}).collect(Collectors.collectingAndThen(Collectors.toSet(), ArrayList::new));
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -19,6 +19,7 @@ import org.springframework.core.convert.ConversionService;
|
||||
import org.springframework.data.mapping.PersistentProperty;
|
||||
import org.springframework.data.mapping.PersistentPropertyAccessor;
|
||||
import org.springframework.data.mapping.PersistentPropertyPath;
|
||||
import org.springframework.lang.Contract;
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.ClassUtils;
|
||||
@@ -99,6 +100,7 @@ public class ConvertingPropertyAccessor<T> extends SimplePersistentPropertyPathA
|
||||
* @return
|
||||
*/
|
||||
@Nullable
|
||||
@Contract("null, _ -> null")
|
||||
@SuppressWarnings("unchecked")
|
||||
private <S> S convertIfNecessary(@Nullable Object source, Class<S> type) {
|
||||
|
||||
|
||||
@@ -101,14 +101,8 @@ class KotlinInstantiationDelegate {
|
||||
|
||||
/**
|
||||
* Extract the actual construction arguments for a direct constructor call.
|
||||
*
|
||||
* @param params
|
||||
* @param entityCreator
|
||||
* @param provider
|
||||
* @return
|
||||
* @param <P>
|
||||
*/
|
||||
public <P extends PersistentProperty<P>> Object[] extractInvocationArguments(Object[] params,
|
||||
public <P extends PersistentProperty<P>> void extractInvocationArguments(Object[] params,
|
||||
@Nullable InstanceCreatorMetadata<P> entityCreator, ParameterValueProvider<P> provider) {
|
||||
|
||||
if (entityCreator == null) {
|
||||
@@ -155,8 +149,6 @@ class KotlinInstantiationDelegate {
|
||||
for (int i = 0; i < defaulting.length; i++) {
|
||||
params[userParameterCount + i] = defaulting[i];
|
||||
}
|
||||
|
||||
return params;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -214,7 +206,7 @@ class KotlinInstantiationDelegate {
|
||||
}
|
||||
} else {
|
||||
|
||||
int optionalParameterCount = (int) kotlinFunction.getParameters().stream().filter(it -> it.isOptional())
|
||||
int optionalParameterCount = (int) kotlinFunction.getParameters().stream().filter(KParameter::isOptional)
|
||||
.count();
|
||||
int syntheticParameters = KotlinDefaultMask.getExactMaskCount(optionalParameterCount);
|
||||
|
||||
|
||||
@@ -18,6 +18,7 @@ package org.springframework.data.mapping.model;
|
||||
import kotlin.reflect.KFunction;
|
||||
import kotlin.reflect.jvm.ReflectJvmMapping;
|
||||
|
||||
import java.io.Serial;
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.ArrayList;
|
||||
@@ -43,7 +44,7 @@ import org.springframework.util.ObjectUtils;
|
||||
*/
|
||||
public class MappingInstantiationException extends RuntimeException {
|
||||
|
||||
private static final long serialVersionUID = 822211065035487628L;
|
||||
private static final @Serial long serialVersionUID = 822211065035487628L;
|
||||
private static final String TEXT_TEMPLATE = "Failed to instantiate %s using constructor %s with arguments %s";
|
||||
|
||||
private final Class<?> entityType;
|
||||
|
||||
@@ -30,7 +30,7 @@ public interface ParameterValueProvider<P extends PersistentProperty<P>> {
|
||||
* Returns the value to be used for the given {@link Parameter} (usually when entity instances are created).
|
||||
*
|
||||
* @param parameter must not be {@literal null}.
|
||||
* @return
|
||||
* @return the property value. Can be {@literal null}.
|
||||
*/
|
||||
@Nullable
|
||||
<T> T getParameterValue(Parameter<T, P> parameter);
|
||||
|
||||
@@ -37,7 +37,7 @@ public class PersistentEntityParameterValueProvider<P extends PersistentProperty
|
||||
private final @Nullable Object parent;
|
||||
|
||||
public PersistentEntityParameterValueProvider(PersistentEntity<?, P> entity, PropertyValueProvider<P> provider,
|
||||
Object parent) {
|
||||
@Nullable Object parent) {
|
||||
this.entity = entity;
|
||||
this.provider = provider;
|
||||
this.parent = parent;
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user