DATAREST-1523 - Delombok production sources.
Hacking.
This commit is contained in:
7
pom.xml
7
pom.xml
@@ -139,13 +139,6 @@
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.projectlombok</groupId>
|
||||
<artifactId>lombok</artifactId>
|
||||
<version>${lombok}</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
<repositories>
|
||||
|
||||
@@ -15,13 +15,9 @@
|
||||
*/
|
||||
package org.springframework.data.rest.core.config;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.NonNull;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.Value;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
|
||||
import org.springframework.core.convert.converter.Converter;
|
||||
@@ -56,6 +52,7 @@ class EntityLookupConfiguration implements EntityLookupRegistrar {
|
||||
Converter<T, ID> converter, Lookup<R, ID> lookup) {
|
||||
|
||||
new MappingBuilder<T, ID, R>(repositoryType).withIdMapping(converter).withLookup(lookup);
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -65,7 +62,9 @@ class EntityLookupConfiguration implements EntityLookupRegistrar {
|
||||
*/
|
||||
@Override
|
||||
public <T, ID, R extends Repository<T, ?>> IdMappingRegistrar<T, R> forLookupRepository(Class<R> type) {
|
||||
|
||||
this.lookupTypes.add(AbstractRepositoryMetadata.getMetadata(type).getDomainType());
|
||||
|
||||
return forRepository(type);
|
||||
}
|
||||
|
||||
@@ -87,6 +86,7 @@ class EntityLookupConfiguration implements EntityLookupRegistrar {
|
||||
Converter<T, ID> identifierMapping, Lookup<R, ID> lookup) {
|
||||
|
||||
this.lookupTypes.add(AbstractRepositoryMetadata.getMetadata(type).getDomainType());
|
||||
|
||||
return forRepository(type, identifierMapping, lookup);
|
||||
}
|
||||
|
||||
@@ -95,13 +95,24 @@ class EntityLookupConfiguration implements EntityLookupRegistrar {
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
@RequiredArgsConstructor
|
||||
private class MappingBuilder<T, ID, R extends Repository<T, ?>>
|
||||
implements LookupRegistrar<T, ID, R>, IdMappingRegistrar<T, R> {
|
||||
|
||||
private @NonNull final Class<R> repositoryType;
|
||||
private final Class<R> repositoryType;
|
||||
private Converter<T, ID> idMapping;
|
||||
|
||||
/**
|
||||
* Creates a new {@link MappingBuilder} for the given repository type.
|
||||
*
|
||||
* @param type must not be {@literal null}.
|
||||
*/
|
||||
public MappingBuilder(Class<R> type) {
|
||||
|
||||
Assert.notNull(type, "Repository type must not be null!");
|
||||
|
||||
this.repositoryType = type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new {@link MappingBuilder} using the given repository type and identifier mapping.
|
||||
*
|
||||
@@ -109,11 +120,8 @@ class EntityLookupConfiguration implements EntityLookupRegistrar {
|
||||
* @param mapping must not be {@literal null}.
|
||||
*/
|
||||
private MappingBuilder(Class<R> repositoryType, Converter<T, ID> mapping) {
|
||||
|
||||
this(repositoryType);
|
||||
|
||||
Assert.notNull(mapping, "Converter must not be null!");
|
||||
|
||||
this.idMapping = mapping;
|
||||
}
|
||||
|
||||
@@ -152,8 +160,8 @@ class EntityLookupConfiguration implements EntityLookupRegistrar {
|
||||
|
||||
Assert.notNull(repositories, "Repositories must not be null!");
|
||||
|
||||
return lookupInformation.stream()//
|
||||
.map(it -> new RepositoriesEntityLookup<>(repositories, it))//
|
||||
return lookupInformation.stream() //
|
||||
.map(it -> new RepositoriesEntityLookup<>(repositories, it)) //
|
||||
.collect(StreamUtils.toUnmodifiableList());
|
||||
}
|
||||
|
||||
@@ -171,7 +179,7 @@ class EntityLookupConfiguration implements EntityLookupRegistrar {
|
||||
private final LookupInformation<Object, Object, Repository<? extends T, ?>> lookupInfo;
|
||||
private final Repository<? extends T, ?> repository;
|
||||
private final Class<?> domainType;
|
||||
private final @Getter Optional<String> lookupProperty;
|
||||
private final Optional<String> lookupProperty;
|
||||
|
||||
/**
|
||||
* Creates a new {@link RepositoriesEntityLookup} for the given {@link Repositories} and {@link LookupInformation}.
|
||||
@@ -182,24 +190,21 @@ class EntityLookupConfiguration implements EntityLookupRegistrar {
|
||||
@SuppressWarnings("unchecked")
|
||||
public RepositoriesEntityLookup(Repositories repositories,
|
||||
LookupInformation<Object, Object, Repository<? extends T, ?>> lookupInformation) {
|
||||
|
||||
Assert.notNull(repositories, "Repositories must not be null!");
|
||||
Assert.notNull(lookupInformation, "LookupInformation must not be null!");
|
||||
|
||||
RepositoryInformation information = repositories.getRepositoryInformation(lookupInformation.repositoryType)//
|
||||
.orElseThrow(() -> new IllegalStateException(
|
||||
"No repository found for type " + lookupInformation.repositoryType.getName() + "!"));
|
||||
|
||||
RepositoryInformation information = //
|
||||
repositories.getRepositoryInformation(lookupInformation.repositoryType)
|
||||
.orElseThrow(() -> new IllegalStateException(
|
||||
"No repository found for type " + lookupInformation.repositoryType.getName() + "!"));
|
||||
this.domainType = information.getDomainType();
|
||||
this.lookupInfo = lookupInformation;
|
||||
this.repository = (Repository<? extends T, ?>) repositories.getRepositoryFor(information.getDomainType())//
|
||||
.orElseThrow(() -> new IllegalStateException(
|
||||
"No repository found for type " + information.getDomainType().getName() + "!"));
|
||||
|
||||
this.lookupProperty = Optional.of(domainType) //
|
||||
.flatMap(it -> MethodInvocationRecorder.forProxyOf(it) //
|
||||
.record(lookupInfo.identifierMapping::convert) //
|
||||
.getPropertyPath());
|
||||
this.repository = (Repository<? extends T, ?>) //
|
||||
repositories.getRepositoryFor(information.getDomainType()).orElseThrow(() -> new IllegalStateException(
|
||||
"No repository found for type " + information.getDomainType().getName() + "!"));
|
||||
this.lookupProperty = //
|
||||
Optional.of(domainType).flatMap(it -> //
|
||||
//
|
||||
MethodInvocationRecorder.forProxyOf(it).record(lookupInfo.identifierMapping::convert).getPropertyPath());
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -232,13 +237,86 @@ class EntityLookupConfiguration implements EntityLookupRegistrar {
|
||||
public boolean supports(Class<?> delimiter) {
|
||||
return domainType.isAssignableFrom(delimiter);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.rest.core.support.EntityLookup#getLookupProperty()
|
||||
*/
|
||||
public Optional<String> getLookupProperty() {
|
||||
return this.lookupProperty;
|
||||
}
|
||||
}
|
||||
|
||||
@Value
|
||||
private static class LookupInformation<T, ID, R extends Repository<? extends T, ?>> {
|
||||
private static final class LookupInformation<T, ID, R extends Repository<? extends T, ?>> {
|
||||
|
||||
private final Class<R> repositoryType;
|
||||
private final Converter<T, ID> identifierMapping;
|
||||
private final Lookup<R, ID> lookup;
|
||||
|
||||
public LookupInformation(Class<R> repositoryType, Converter<T, ID> identifierMapping,
|
||||
Lookup<R, ID> lookup) {
|
||||
|
||||
Assert.notNull(repositoryType, "Repository type must not be null!");
|
||||
Assert.notNull(identifierMapping, "Identifier mapping must not be null!");
|
||||
Assert.notNull(lookup, "Lookup must not be null!");
|
||||
|
||||
this.repositoryType = repositoryType;
|
||||
this.identifierMapping = identifierMapping;
|
||||
this.lookup = lookup;
|
||||
}
|
||||
|
||||
public Class<R> getRepositoryType() {
|
||||
return this.repositoryType;
|
||||
}
|
||||
|
||||
public Converter<T, ID> getIdentifierMapping() {
|
||||
return this.identifierMapping;
|
||||
}
|
||||
|
||||
public Lookup<R, ID> getLookup() {
|
||||
return this.lookup;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see java.lang.Object#equals(java.lang.Object)
|
||||
*/
|
||||
@Override
|
||||
public boolean equals(final java.lang.Object o) {
|
||||
|
||||
if (o == this) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!(o instanceof EntityLookupConfiguration.LookupInformation)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
LookupInformation<?, ?, ?> that = (LookupInformation<?, ?, ?>) o;
|
||||
|
||||
return Objects.equals(getRepositoryType(), that.getRepositoryType()) //
|
||||
&& Objects.equals(getIdentifierMapping(), that.getIdentifierMapping()) //
|
||||
&& Objects.equals(getLookup(), that.getLookup());
|
||||
}
|
||||
|
||||
/*
|
||||
*
|
||||
* (non-Javadoc)
|
||||
* @see java.lang.Object#hashCode()
|
||||
*/
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(getRepositoryType(), getIdentifierMapping(), getLookup());
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see java.lang.Object#toString()
|
||||
*/
|
||||
@Override
|
||||
public java.lang.String toString() {
|
||||
return "EntityLookupConfiguration.LookupInformation(repositoryType=" + this.getRepositoryType()
|
||||
+ ", identifierMapping=" + this.getIdentifierMapping() + ", lookup=" + this.getLookup() + ")";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,14 +15,10 @@
|
||||
*/
|
||||
package org.springframework.data.rest.core.config;
|
||||
|
||||
import lombok.AccessLevel;
|
||||
import lombok.NonNull;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.Value;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
|
||||
import org.springframework.core.annotation.AnnotationUtils;
|
||||
@@ -80,6 +76,7 @@ public class ProjectionDefinitionConfiguration implements ProjectionDefinitions
|
||||
public ProjectionDefinitionConfiguration addProjection(Class<?> projectionType) {
|
||||
|
||||
Assert.notNull(projectionType, "Projection type must not be null!");
|
||||
|
||||
Projection annotation = AnnotationUtils.findAnnotation(projectionType, Projection.class);
|
||||
|
||||
if (annotation == null) {
|
||||
@@ -89,7 +86,8 @@ public class ProjectionDefinitionConfiguration implements ProjectionDefinitions
|
||||
String name = annotation.name();
|
||||
Class<?>[] sourceTypes = annotation.types();
|
||||
|
||||
return StringUtils.hasText(name) ? addProjection(projectionType, name, sourceTypes)
|
||||
return StringUtils.hasText(name) //
|
||||
? addProjection(projectionType, name, sourceTypes) //
|
||||
: addProjection(projectionType, sourceTypes);
|
||||
}
|
||||
|
||||
@@ -104,6 +102,7 @@ public class ProjectionDefinitionConfiguration implements ProjectionDefinitions
|
||||
public ProjectionDefinitionConfiguration addProjection(Class<?> projectionType, Class<?>... sourceTypes) {
|
||||
|
||||
Assert.notNull(projectionType, "Projection type must not be null!");
|
||||
|
||||
return addProjection(projectionType, StringUtils.uncapitalize(projectionType.getSimpleName()), sourceTypes);
|
||||
}
|
||||
|
||||
@@ -146,6 +145,7 @@ public class ProjectionDefinitionConfiguration implements ProjectionDefinitions
|
||||
public boolean hasProjectionFor(Class<?> sourceType) {
|
||||
|
||||
for (ProjectionDefinition definition : projectionDefinitions) {
|
||||
|
||||
if (definition.sourceType.isAssignableFrom(sourceType)) {
|
||||
return true;
|
||||
}
|
||||
@@ -194,12 +194,21 @@ public class ProjectionDefinitionConfiguration implements ProjectionDefinitions
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
@Value
|
||||
@RequiredArgsConstructor(access = AccessLevel.PRIVATE)
|
||||
static final class ProjectionDefinition {
|
||||
|
||||
private final @NonNull Class<?> sourceType, targetType;
|
||||
private final @NonNull String name;
|
||||
private final Class<?> sourceType, targetType;
|
||||
private final String name;
|
||||
|
||||
private ProjectionDefinition(Class<?> sourceType, Class<?> targetType, String name) {
|
||||
|
||||
Assert.notNull(sourceType, "Source type must not be null!");
|
||||
Assert.notNull(targetType, "Target type must not be null!");
|
||||
Assert.notNull(name, "Name must not be null!");
|
||||
|
||||
this.sourceType = sourceType;
|
||||
this.targetType = targetType;
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new {@link ProjectionDefinitionKey} for the given source type and name;
|
||||
@@ -214,5 +223,58 @@ public class ProjectionDefinitionConfiguration implements ProjectionDefinitions
|
||||
|
||||
return new ProjectionDefinition(sourceType, targetType, name);
|
||||
}
|
||||
|
||||
public Class<?> getSourceType() {
|
||||
return this.sourceType;
|
||||
}
|
||||
|
||||
public Class<?> getTargetType() {
|
||||
return this.targetType;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return this.name;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see java.lang.Object#equals(java.lang.Object)
|
||||
*/
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
|
||||
if (o == this) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!(o instanceof ProjectionDefinitionConfiguration.ProjectionDefinition)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
ProjectionDefinition that = (ProjectionDefinitionConfiguration.ProjectionDefinition) o;
|
||||
|
||||
return Objects.equals(getSourceType(), that.getSourceType()) //
|
||||
&& Objects.equals(getTargetType(), that.getTargetType()) //
|
||||
&& Objects.equals(getName(), that.getName());
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see java.lang.Object#hashCode()
|
||||
*/
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(getSourceType(), getTargetType(), getName());
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see java.lang.Object#toString()
|
||||
*/
|
||||
@Override
|
||||
public java.lang.String toString() {
|
||||
return "ProjectionDefinitionConfiguration.ProjectionDefinition(sourceType=" + this.getSourceType()
|
||||
+ ", targetType=" + this.getTargetType() + ", name=" + this.getName() + ")";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,10 +15,6 @@
|
||||
*/
|
||||
package org.springframework.data.rest.core.config;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.NonNull;
|
||||
import lombok.Setter;
|
||||
|
||||
import java.net.URI;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
@@ -74,13 +70,12 @@ public class RepositoryRestConfiguration {
|
||||
/**
|
||||
* The {@link RelProvider} to be used to calculate the link relation defaults for repositories.
|
||||
*/
|
||||
private @Getter @Setter @NonNull LinkRelationProvider relProvider = new EvoInflectorLinkRelationProvider();
|
||||
|
||||
private LinkRelationProvider relProvider = new EvoInflectorLinkRelationProvider();
|
||||
private final ProjectionDefinitionConfiguration projectionConfiguration;
|
||||
private final MetadataConfiguration metadataConfiguration;
|
||||
private final EntityLookupConfiguration entityLookupConfiguration;
|
||||
private final @Getter ExposureConfiguration exposureConfiguration;
|
||||
|
||||
private final ExposureConfiguration exposureConfiguration;
|
||||
private final EnumTranslationConfiguration enumTranslationConfiguration;
|
||||
private boolean enableEnumTranslation = false;
|
||||
|
||||
@@ -667,4 +662,25 @@ public class RepositoryRestConfiguration {
|
||||
public boolean isLookupType(Class<?> type) {
|
||||
return this.entityLookupConfiguration.isLookupType(type);
|
||||
}
|
||||
|
||||
/**
|
||||
* The {@link RelProvider} to be used to calculate the link relation defaults for repositories.
|
||||
*/
|
||||
public LinkRelationProvider getRelProvider() {
|
||||
return this.relProvider;
|
||||
}
|
||||
|
||||
/**
|
||||
* The {@link RelProvider} to be used to calculate the link relation defaults for repositories.
|
||||
*/
|
||||
public void setRelProvider(LinkRelationProvider relProvider) {
|
||||
|
||||
Assert.notNull(relProvider, "LinkRelationProvider must not be null!");
|
||||
|
||||
this.relProvider = relProvider;
|
||||
}
|
||||
|
||||
public ExposureConfiguration getExposureConfiguration() {
|
||||
return this.exposureConfiguration;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,15 +15,12 @@
|
||||
*/
|
||||
package org.springframework.data.rest.core.event;
|
||||
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.ToString;
|
||||
|
||||
import java.lang.annotation.Annotation;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
@@ -36,6 +33,7 @@ import org.springframework.core.annotation.AnnotationAwareOrderComparator;
|
||||
import org.springframework.core.annotation.AnnotationUtils;
|
||||
import org.springframework.data.rest.core.annotation.*;
|
||||
import org.springframework.data.util.ProxyUtils;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.ClassUtils;
|
||||
import org.springframework.util.LinkedMultiValueMap;
|
||||
import org.springframework.util.MultiValueMap;
|
||||
@@ -175,18 +173,27 @@ public class AnnotatedEventHandlerInvoker implements ApplicationListener<Reposit
|
||||
handlerMethods.put(eventType, events);
|
||||
}
|
||||
|
||||
@ToString
|
||||
@EqualsAndHashCode
|
||||
@RequiredArgsConstructor
|
||||
static class EventHandlerMethod implements Comparable<EventHandlerMethod> {
|
||||
|
||||
final Class<?> targetType;
|
||||
final Method method;
|
||||
final Object handler;
|
||||
|
||||
public EventHandlerMethod(Class<?> targetType, Method method, Object handler) {
|
||||
|
||||
Assert.notNull(targetType, "Target type must not be null!");
|
||||
Assert.notNull(method, "Method must not be null!");
|
||||
Assert.notNull(handler, "Handler must not be null!");
|
||||
|
||||
this.targetType = targetType;
|
||||
this.method = method;
|
||||
this.handler = handler;
|
||||
}
|
||||
|
||||
public static EventHandlerMethod of(Class<?> targetType, Object handler, Method method) {
|
||||
|
||||
ReflectionUtils.makeAccessible(method);
|
||||
|
||||
return new EventHandlerMethod(targetType, method, handler);
|
||||
}
|
||||
|
||||
@@ -198,5 +205,46 @@ public class AnnotatedEventHandlerInvoker implements ApplicationListener<Reposit
|
||||
public int compareTo(EventHandlerMethod o) {
|
||||
return AnnotationAwareOrderComparator.INSTANCE.compare(this.method, o.method);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see java.lang.Object#equals(java.lang.Object)
|
||||
*/
|
||||
@Override
|
||||
public boolean equals(final java.lang.Object o) {
|
||||
|
||||
if (o == this) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!(o instanceof EventHandlerMethod)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
EventHandlerMethod other = (AnnotatedEventHandlerInvoker.EventHandlerMethod) o;
|
||||
|
||||
return Objects.equals(targetType, other.targetType) //
|
||||
&& Objects.equals(method, other.method) //
|
||||
&& Objects.equals(handler, other.handler);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see java.lang.Object#hashCode()
|
||||
*/
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(targetType, method, handler);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see java.lang.Object#toString()
|
||||
*/
|
||||
@Override
|
||||
public java.lang.String toString() {
|
||||
return "AnnotatedEventHandlerInvoker.EventHandlerMethod(targetType=" + this.targetType + ", method=" + this.method
|
||||
+ ", handler=" + this.handler + ")";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,9 +15,6 @@
|
||||
*/
|
||||
package org.springframework.data.rest.core.mapping;
|
||||
|
||||
import lombok.AccessLevel;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Iterator;
|
||||
@@ -34,7 +31,6 @@ import org.springframework.util.Assert;
|
||||
* @author Oliver Gierke
|
||||
* @since 3.1
|
||||
*/
|
||||
@RequiredArgsConstructor(staticName = "of", access = AccessLevel.PACKAGE)
|
||||
public class ConfigurableHttpMethods implements HttpMethods {
|
||||
|
||||
public static final ConfigurableHttpMethods NONE = ConfigurableHttpMethods.of();
|
||||
@@ -42,6 +38,17 @@ public class ConfigurableHttpMethods implements HttpMethods {
|
||||
|
||||
private final Collection<HttpMethod> methods;
|
||||
|
||||
private ConfigurableHttpMethods(Collection<HttpMethod> methods) {
|
||||
|
||||
Assert.notNull(methods, "HttpMethods must not be null!");
|
||||
|
||||
this.methods = methods;
|
||||
}
|
||||
|
||||
static ConfigurableHttpMethods of(Collection<HttpMethod> methods) {
|
||||
return new ConfigurableHttpMethods(methods);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new {@link ConfigurableHttpMethods} of the given {@link HttpMethod}s.
|
||||
*
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
// Generated by delombok at Tue Aug 11 12:16:38 CEST 2020
|
||||
/*
|
||||
* Copyright 2018-2020 the original author or authors.
|
||||
*
|
||||
@@ -15,27 +16,36 @@
|
||||
*/
|
||||
package org.springframework.data.rest.core.mapping;
|
||||
|
||||
import lombok.NonNull;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
import org.springframework.data.mapping.PersistentProperty;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* Adapter for a {@link SupportedHttpMethods} instance that applies settings made through {@link ExposureConfiguration}
|
||||
* to the calculated {@link ConfigurableHttpMethods}
|
||||
*
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
* @see ExposureConfiguration
|
||||
* @since 3.1
|
||||
*/
|
||||
@RequiredArgsConstructor
|
||||
public class ConfigurationApplyingSupportedHttpMethodsAdapter implements SupportedHttpMethods {
|
||||
class ConfigurationApplyingSupportedHttpMethodsAdapter implements SupportedHttpMethods {
|
||||
|
||||
private final @NonNull ExposureConfiguration configuration;
|
||||
private final @NonNull ResourceMetadata resourceMetadata;
|
||||
private final @NonNull SupportedHttpMethods delegate;
|
||||
private final ExposureConfiguration configuration;
|
||||
private final ResourceMetadata resourceMetadata;
|
||||
private final SupportedHttpMethods delegate;
|
||||
|
||||
/*
|
||||
ConfigurationApplyingSupportedHttpMethodsAdapter(ExposureConfiguration configuration,
|
||||
ResourceMetadata resourceMetadata, SupportedHttpMethods delegate) {
|
||||
|
||||
Assert.notNull(configuration, "Configuration must not be null!");
|
||||
Assert.notNull(resourceMetadata, "ResourceMetadata must not be null!");
|
||||
Assert.notNull(delegate, "SupportedHttpMethods must not be null!");
|
||||
|
||||
this.configuration = configuration;
|
||||
this.resourceMetadata = resourceMetadata;
|
||||
this.delegate = delegate;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.rest.core.mapping.SupportedHttpMethods#getMethodsFor(org.springframework.data.rest.core.mapping.ResourceType)
|
||||
*/
|
||||
@@ -47,7 +57,7 @@ public class ConfigurationApplyingSupportedHttpMethodsAdapter implements Support
|
||||
return configuration.filter(ConfigurableHttpMethods.of(methods), type, resourceMetadata);
|
||||
}
|
||||
|
||||
/*
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.rest.core.mapping.SupportedHttpMethods#getMethodsFor(org.springframework.data.mapping.PersistentProperty)
|
||||
*/
|
||||
@@ -66,7 +76,7 @@ public class ConfigurationApplyingSupportedHttpMethodsAdapter implements Support
|
||||
return configuration.filter(methods, PropertyAwareResourceMapping.class.cast(mapping));
|
||||
}
|
||||
|
||||
/*
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.rest.core.mapping.SupportedHttpMethods#allowsPutForCreation()
|
||||
*/
|
||||
|
||||
@@ -17,8 +17,6 @@ package org.springframework.data.rest.core.mapping;
|
||||
|
||||
import static org.springframework.http.HttpMethod.*;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
import java.util.function.Function;
|
||||
|
||||
import org.springframework.http.HttpMethod;
|
||||
@@ -28,7 +26,7 @@ import org.springframework.util.Assert;
|
||||
* Configuration type to register filters customizing the HTTP methods supported. By default, filters registered are
|
||||
* applied globally. Domain type specific filters can be registered via {@link #forDomainType(Class)}. Useful global
|
||||
* shortcuts like {@link #disablePutOnItemResources()} do exist as well.
|
||||
*
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
* @see #forDomainType(Class)
|
||||
* @since 3.1
|
||||
@@ -92,7 +90,7 @@ public class ExposureConfiguration implements ExposureConfigurer {
|
||||
* {@link AggregateResourceHttpMethodsFilter} and {@link AssociationResourceHttpMethodsFilter}s which means the
|
||||
* configured filters will only be invoked for aggregates of the given type and properties owned by that type
|
||||
* respectively.
|
||||
*
|
||||
*
|
||||
* @param type must not be {@literal null}.
|
||||
* @return
|
||||
*/
|
||||
@@ -104,7 +102,7 @@ public class ExposureConfiguration implements ExposureConfigurer {
|
||||
|
||||
/**
|
||||
* Disables the support for {@link HttpMethod#PUT} for item resources.
|
||||
*
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public ExposureConfiguration disablePutOnItemResources() {
|
||||
@@ -115,7 +113,7 @@ public class ExposureConfiguration implements ExposureConfigurer {
|
||||
|
||||
/**
|
||||
* Disables the support for {@link HttpMethod#PATCH} for item resources.
|
||||
*
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public ExposureConfiguration disablePatchOnItemResources() {
|
||||
@@ -127,7 +125,7 @@ public class ExposureConfiguration implements ExposureConfigurer {
|
||||
/**
|
||||
* Returns whether PUT requests can be used to create new instances for the type backing the given
|
||||
* {@link ResourceMetadata}.
|
||||
*
|
||||
*
|
||||
* @param metadata must not be {@literal null}.
|
||||
* @return
|
||||
*/
|
||||
@@ -140,7 +138,7 @@ public class ExposureConfiguration implements ExposureConfigurer {
|
||||
|
||||
/**
|
||||
* Returns whether PUT requests can be used to create new instances of the given domain type.
|
||||
*
|
||||
*
|
||||
* @param metadata must not be {@literal null}.
|
||||
* @return
|
||||
*/
|
||||
@@ -182,11 +180,17 @@ public class ExposureConfiguration implements ExposureConfigurer {
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
@RequiredArgsConstructor
|
||||
private class TypeBasedExposureConfigurer implements ExposureConfigurer {
|
||||
|
||||
private final Class<?> type;
|
||||
|
||||
public TypeBasedExposureConfigurer(Class<?> type) {
|
||||
|
||||
Assert.notNull(type, " must not be null!");
|
||||
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.rest.core.mapping.ExposureConfigurer#withCollectionExposure(org.springframework.data.rest.core.mapping.ExposureConfigurer.AggregateResourceHttpMethodsFilter)
|
||||
@@ -211,7 +215,7 @@ public class ExposureConfiguration implements ExposureConfigurer {
|
||||
return this;
|
||||
}
|
||||
|
||||
/*
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.rest.core.mapping.ExposureConfiguration.ExposureConfigurer#withAssociationExposure(java.util.function.BiFunction)
|
||||
*/
|
||||
@@ -229,7 +233,7 @@ public class ExposureConfiguration implements ExposureConfigurer {
|
||||
return this;
|
||||
}
|
||||
|
||||
/*
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.rest.core.mapping.ExposureConfigurer#disableCreationViaPut()
|
||||
*/
|
||||
|
||||
@@ -15,9 +15,6 @@
|
||||
*/
|
||||
package org.springframework.data.rest.core.support;
|
||||
|
||||
import lombok.NonNull;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.List;
|
||||
@@ -75,11 +72,19 @@ public class UnwrappingRepositoryInvokerFactory implements RepositoryInvokerFact
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
@RequiredArgsConstructor
|
||||
private static class UnwrappingRepositoryInvoker implements RepositoryInvoker {
|
||||
|
||||
private final @NonNull RepositoryInvoker delegate;
|
||||
private final @NonNull Optional<EntityLookup<?>> lookup;
|
||||
private final RepositoryInvoker delegate;
|
||||
private final Optional<EntityLookup<?>> lookup;
|
||||
|
||||
public UnwrappingRepositoryInvoker(RepositoryInvoker delegate, Optional<EntityLookup<?>> lookup) {
|
||||
|
||||
Assert.notNull(delegate, "Delegate RepositoryInvoker must not be null!");
|
||||
Assert.notNull(lookup, "EntityLookup must not be null!");
|
||||
|
||||
this.delegate = delegate;
|
||||
this.lookup = lookup;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
|
||||
@@ -15,8 +15,6 @@
|
||||
*/
|
||||
package org.springframework.data.rest.core.util;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
@@ -29,11 +27,14 @@ import org.springframework.plugin.core.PluginRegistry;
|
||||
* @deprecated since 3.2, for removal 3.3.
|
||||
*/
|
||||
@Deprecated
|
||||
@RequiredArgsConstructor
|
||||
public class Java8PluginRegistry<T extends Plugin<S>, S> {
|
||||
|
||||
private final PluginRegistry<T, S> registry;
|
||||
|
||||
public Java8PluginRegistry(PluginRegistry<T, S> registry) {
|
||||
this.registry = registry;
|
||||
}
|
||||
|
||||
public static <T extends Plugin<S>, S> Java8PluginRegistry<T, S> of(List<? extends T> plugins) {
|
||||
return Java8PluginRegistry.of(PluginRegistry.of(plugins));
|
||||
}
|
||||
|
||||
@@ -43,6 +43,13 @@
|
||||
<version>${groovy.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.projectlombok</groupId>
|
||||
<artifactId>lombok</artifactId>
|
||||
<version>${lombok}</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
</project>
|
||||
|
||||
@@ -15,9 +15,6 @@
|
||||
*/
|
||||
package org.springframework.data.rest.webmvc;
|
||||
|
||||
import lombok.NonNull;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
@@ -38,13 +35,24 @@ import org.springframework.util.Assert;
|
||||
/**
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
@RequiredArgsConstructor
|
||||
public class EmbeddedResourcesAssembler {
|
||||
|
||||
private final @NonNull PersistentEntities entities;
|
||||
private final @NonNull Associations associations;
|
||||
private final @NonNull ExcerptProjector projector;
|
||||
private final @NonNull EmbeddedWrappers wrappers = new EmbeddedWrappers(false);
|
||||
private final PersistentEntities entities;
|
||||
private final Associations associations;
|
||||
private final ExcerptProjector projector;
|
||||
private final EmbeddedWrappers wrappers = new EmbeddedWrappers(false);
|
||||
|
||||
public EmbeddedResourcesAssembler(PersistentEntities entities, Associations associations,
|
||||
ExcerptProjector projector) {
|
||||
|
||||
Assert.notNull(entities, "PersistentEntities must not be null!");
|
||||
Assert.notNull(associations, "Associations must not be null!");
|
||||
Assert.notNull(projector, "ExcerptProjector must not be null!");
|
||||
|
||||
this.entities = entities;
|
||||
this.associations = associations;
|
||||
this.projector = projector;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the embedded resources to render. This will add an {@link RelatedResource} for linkable associations if
|
||||
|
||||
@@ -15,9 +15,6 @@
|
||||
*/
|
||||
package org.springframework.data.rest.webmvc;
|
||||
|
||||
import lombok.NonNull;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
import java.time.Instant;
|
||||
import java.util.Date;
|
||||
import java.util.Optional;
|
||||
@@ -39,14 +36,18 @@ import org.springframework.util.Assert;
|
||||
* @author Oliver Gierke
|
||||
* @soundtrack Ron Spielman Trio - Matchstick
|
||||
*/
|
||||
@RequiredArgsConstructor
|
||||
public class HttpHeadersPreparer {
|
||||
|
||||
private final @NonNull AuditableBeanWrapperFactory auditableBeanWrapperFactory;
|
||||
private final AuditableBeanWrapperFactory auditableBeanWrapperFactory;
|
||||
private final ConfigurableConversionService conversionService = new DefaultConversionService();
|
||||
|
||||
{
|
||||
public HttpHeadersPreparer(AuditableBeanWrapperFactory auditableBeanWrapperFactory) {
|
||||
|
||||
Assert.notNull(auditableBeanWrapperFactory, "AuditableBeanWrapperFactory must not be null!");
|
||||
|
||||
Jsr310Converters.getConvertersToRegister().forEach(conversionService::addConverter);
|
||||
|
||||
this.auditableBeanWrapperFactory = auditableBeanWrapperFactory;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -15,8 +15,6 @@
|
||||
*/
|
||||
package org.springframework.data.rest.webmvc;
|
||||
|
||||
import lombok.Getter;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
@@ -46,15 +44,7 @@ public class PersistentEntityResource extends EntityModel<Object> {
|
||||
|
||||
private final PersistentEntity<?, ?> entity;
|
||||
private final Iterable<EmbeddedWrapper> embeddeds;
|
||||
|
||||
/**
|
||||
* Returns whether the content of the resource is a new entity about to be created. Used to distinguish between
|
||||
* creation and updates for incoming requests.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
private final @Getter boolean isNew;
|
||||
private final @Getter boolean nested;
|
||||
private final boolean isNew, nested;
|
||||
|
||||
/**
|
||||
* Creates a new {@link PersistentEntityResource} for the given {@link PersistentEntity}, content, embedded
|
||||
@@ -79,6 +69,20 @@ public class PersistentEntityResource extends EntityModel<Object> {
|
||||
this.nested = nested;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the content of the resource is a new entity about to be created. Used to distinguish between
|
||||
* creation and updates for incoming requests.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public boolean isNew() {
|
||||
return this.isNew;
|
||||
}
|
||||
|
||||
public boolean isNested() {
|
||||
return this.nested;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the {@link PersistentEntity} for the underlying instance.
|
||||
*
|
||||
|
||||
@@ -19,9 +19,6 @@ import static java.util.stream.Collectors.*;
|
||||
import static org.springframework.data.rest.webmvc.RestMediaTypes.*;
|
||||
import static org.springframework.web.bind.annotation.RequestMethod.*;
|
||||
|
||||
import lombok.AccessLevel;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
@@ -62,6 +59,8 @@ import org.springframework.http.HttpMethod;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.web.bind.annotation.ExceptionHandler;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
@@ -460,7 +459,6 @@ class RepositoryPropertyReferenceController extends AbstractRepositoryRestContro
|
||||
}
|
||||
}
|
||||
|
||||
@RequiredArgsConstructor(access = AccessLevel.PRIVATE)
|
||||
static class HttpRequestMethodNotSupportedException extends RuntimeException {
|
||||
|
||||
private static final long serialVersionUID = 3704212056962845475L;
|
||||
@@ -469,6 +467,17 @@ class RepositoryPropertyReferenceController extends AbstractRepositoryRestContro
|
||||
private final HttpMethod[] allowedMethods;
|
||||
private final String message;
|
||||
|
||||
private HttpRequestMethodNotSupportedException(HttpMethod rejectedMethod, HttpMethod[] allowedMethods,
|
||||
@Nullable String message) {
|
||||
|
||||
Assert.notNull(rejectedMethod, "Rejected HttpMethod must not be null!");
|
||||
Assert.notNull(allowedMethods, "Allowed HttpMethod must not be null!");
|
||||
|
||||
this.rejectedMethod = rejectedMethod;
|
||||
this.allowedMethods = allowedMethods;
|
||||
this.message = message;
|
||||
}
|
||||
|
||||
public static HttpRequestMethodNotSupportedException forRejectedMethod(HttpMethod method) {
|
||||
return new HttpRequestMethodNotSupportedException(method, new HttpMethod[0], null);
|
||||
}
|
||||
@@ -486,6 +495,7 @@ class RepositoryPropertyReferenceController extends AbstractRepositoryRestContro
|
||||
* (non-Javadoc)
|
||||
* @see java.lang.Throwable#getMessage()
|
||||
*/
|
||||
@Nullable
|
||||
@Override
|
||||
public String getMessage() {
|
||||
return message;
|
||||
|
||||
@@ -15,9 +15,6 @@
|
||||
*/
|
||||
package org.springframework.data.rest.webmvc;
|
||||
|
||||
import lombok.NonNull;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.List;
|
||||
@@ -300,12 +297,23 @@ public class RepositoryRestHandlerMapping extends BasePathAwareHandlerMapping {
|
||||
* @author Oliver Gierke
|
||||
* @since 2.6
|
||||
*/
|
||||
@RequiredArgsConstructor
|
||||
static class RepositoryCorsConfigurationAccessor {
|
||||
|
||||
private final @NonNull ResourceMappings mappings;
|
||||
private final @NonNull StringValueResolver embeddedValueResolver;
|
||||
private final @NonNull Optional<Repositories> repositories;
|
||||
private final ResourceMappings mappings;
|
||||
private final StringValueResolver embeddedValueResolver;
|
||||
private final Optional<Repositories> repositories;
|
||||
|
||||
public RepositoryCorsConfigurationAccessor(ResourceMappings mappings, StringValueResolver embeddedValueResolver,
|
||||
Optional<Repositories> repositories) {
|
||||
|
||||
Assert.notNull(mappings, "ResourceMappings must not be null!");
|
||||
Assert.notNull(embeddedValueResolver, "StringValueResolver must not be null!");
|
||||
Assert.notNull(repositories, "Repositories must not be null!");
|
||||
|
||||
this.mappings = mappings;
|
||||
this.embeddedValueResolver = embeddedValueResolver;
|
||||
this.repositories = repositories;
|
||||
}
|
||||
|
||||
Optional<CorsConfiguration> findCorsConfiguration(String lookupPath) {
|
||||
|
||||
|
||||
@@ -15,11 +15,6 @@
|
||||
*/
|
||||
package org.springframework.data.rest.webmvc;
|
||||
|
||||
import lombok.AccessLevel;
|
||||
import lombok.Getter;
|
||||
import lombok.NonNull;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
@@ -39,12 +34,22 @@ import org.springframework.util.Assert;
|
||||
* @since 2.6
|
||||
* @soundtrack Blumentopf - Dass ich nicht lache (Kein Zufall)
|
||||
*/
|
||||
@RequiredArgsConstructor(staticName = "of")
|
||||
class ResourceStatus {
|
||||
|
||||
private static final String INVALID_DOMAIN_OBJECT = "Domain object %s is not an instance of the given PersistentEntity of type %s!";
|
||||
|
||||
private final @NonNull HttpHeadersPreparer preparer;
|
||||
private final HttpHeadersPreparer preparer;
|
||||
|
||||
private ResourceStatus(HttpHeadersPreparer preparer) {
|
||||
|
||||
Assert.notNull(preparer, "HttpHeadersPreparer must not be null!");
|
||||
|
||||
this.preparer = preparer;
|
||||
}
|
||||
|
||||
public static ResourceStatus of(HttpHeadersPreparer preparer) {
|
||||
return new ResourceStatus(preparer);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the {@link StatusAndHeaders} calculated from the given {@link HttpHeaders}, domain object and
|
||||
@@ -77,11 +82,22 @@ class ResourceStatus {
|
||||
: StatusAndHeaders.modified(responseHeaders);
|
||||
}
|
||||
|
||||
@RequiredArgsConstructor(access = AccessLevel.PRIVATE)
|
||||
public static class StatusAndHeaders {
|
||||
|
||||
private final @NonNull HttpHeaders headers;
|
||||
private final @Getter(AccessLevel.PACKAGE) boolean modified;
|
||||
private final HttpHeaders headers;
|
||||
private final boolean modified;
|
||||
|
||||
private StatusAndHeaders(HttpHeaders headers, boolean modified) {
|
||||
|
||||
Assert.notNull(headers, "HttpHeaders must not be null!");
|
||||
|
||||
this.headers = headers;
|
||||
this.modified = modified;
|
||||
}
|
||||
|
||||
boolean isModified() {
|
||||
return this.modified;
|
||||
}
|
||||
|
||||
private static StatusAndHeaders notModified(HttpHeaders headers) {
|
||||
return new StatusAndHeaders(headers, false);
|
||||
@@ -99,7 +115,9 @@ class ResourceStatus {
|
||||
* @return
|
||||
*/
|
||||
public ResponseEntity<EntityModel<?>> toResponseEntity(Supplier<PersistentEntityResource> supplier) {
|
||||
return modified ? new ResponseEntity<EntityModel<?>>(supplier.get(), headers, HttpStatus.OK)
|
||||
|
||||
return modified //
|
||||
? new ResponseEntity<EntityModel<?>>(supplier.get(), headers, HttpStatus.OK) //
|
||||
: new ResponseEntity<EntityModel<?>>(headers, HttpStatus.NOT_MODIFIED);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,9 +17,6 @@ package org.springframework.data.rest.webmvc.alps;
|
||||
|
||||
import static org.springframework.hateoas.mediatype.alps.Alps.*;
|
||||
|
||||
import lombok.NonNull;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
@@ -66,6 +63,7 @@ import org.springframework.hateoas.mediatype.alps.Format;
|
||||
import org.springframework.hateoas.mediatype.alps.Type;
|
||||
import org.springframework.hateoas.server.EntityLinks;
|
||||
import org.springframework.http.HttpMethod;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
@@ -78,19 +76,41 @@ import com.fasterxml.jackson.databind.introspect.BeanPropertyDefinition;
|
||||
* @author Oliver Gierke
|
||||
* @author Greg Turnquist
|
||||
*/
|
||||
@RequiredArgsConstructor
|
||||
public class RootResourceInformationToAlpsDescriptorConverter {
|
||||
|
||||
private static final List<HttpMethod> UNDOCUMENTED_METHODS = Arrays.asList(HttpMethod.OPTIONS, HttpMethod.HEAD);
|
||||
|
||||
private final @NonNull Associations associations;
|
||||
private final @NonNull Repositories repositories;
|
||||
private final @NonNull PersistentEntities persistentEntities;
|
||||
private final @NonNull EntityLinks entityLinks;
|
||||
private final @NonNull MessageResolver resolver;
|
||||
private final @NonNull RepositoryRestConfiguration configuration;
|
||||
private final @NonNull ObjectMapper mapper;
|
||||
private final @NonNull EnumTranslator translator;
|
||||
private final Associations associations;
|
||||
private final Repositories repositories;
|
||||
private final PersistentEntities persistentEntities;
|
||||
private final EntityLinks entityLinks;
|
||||
private final MessageResolver resolver;
|
||||
private final RepositoryRestConfiguration configuration;
|
||||
private final ObjectMapper mapper;
|
||||
private final EnumTranslator translator;
|
||||
|
||||
public RootResourceInformationToAlpsDescriptorConverter(Associations associations, Repositories repositories,
|
||||
PersistentEntities persistentEntities, EntityLinks entityLinks, MessageResolver resolver,
|
||||
RepositoryRestConfiguration configuration, ObjectMapper mapper, EnumTranslator translator) {
|
||||
|
||||
Assert.notNull(associations, "Associations must not be null!");
|
||||
Assert.notNull(repositories, "Repositories must not be null!");
|
||||
Assert.notNull(persistentEntities, "PersistentEntities must not be null!");
|
||||
Assert.notNull(entityLinks, "EntityLinks must not be null!");
|
||||
Assert.notNull(resolver, "MessageResolver must not be null!");
|
||||
Assert.notNull(configuration, "RepositoryRestConfiguration must not be null!");
|
||||
Assert.notNull(mapper, "ObjectMapper must not be null!");
|
||||
Assert.notNull(translator, "EnumTranslator must not be null!");
|
||||
|
||||
this.associations = associations;
|
||||
this.repositories = repositories;
|
||||
this.persistentEntities = persistentEntities;
|
||||
this.entityLinks = entityLinks;
|
||||
this.resolver = resolver;
|
||||
this.configuration = configuration;
|
||||
this.mapper = mapper;
|
||||
this.translator = translator;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
|
||||
@@ -15,12 +15,9 @@
|
||||
*/
|
||||
package org.springframework.data.rest.webmvc.config;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.NonNull;
|
||||
import lombok.Value;
|
||||
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
@@ -47,7 +44,7 @@ import org.springframework.web.util.pattern.PathPatternParser;
|
||||
class DelegatingHandlerMapping extends AbstractHandlerMapping
|
||||
implements org.springframework.data.rest.webmvc.support.DelegatingHandlerMapping {
|
||||
|
||||
private final @Getter List<HandlerMapping> delegates;
|
||||
private final List<HandlerMapping> delegates;
|
||||
|
||||
/**
|
||||
* Creates a new {@link DelegatingHandlerMapping} for the given delegates.
|
||||
@@ -61,6 +58,11 @@ class DelegatingHandlerMapping extends AbstractHandlerMapping
|
||||
this.delegates = delegates;
|
||||
}
|
||||
|
||||
@java.lang.SuppressWarnings("all")
|
||||
public List<HandlerMapping> getDelegates() {
|
||||
return this.delegates;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setPatternParser(PathPatternParser parser) {
|
||||
|
||||
@@ -113,13 +115,12 @@ class DelegatingHandlerMapping extends AbstractHandlerMapping
|
||||
}
|
||||
}
|
||||
|
||||
@Value
|
||||
private static class HandlerSelectionResult {
|
||||
|
||||
@NonNull HttpServletRequest request;
|
||||
HandlerMapping mapping;
|
||||
HandlerExecutionChain result;
|
||||
Exception ignoredException;
|
||||
private final HttpServletRequest request;
|
||||
private final HandlerMapping mapping;
|
||||
private final HandlerExecutionChain result;
|
||||
private final Exception ignoredException;
|
||||
|
||||
public static HandlerSelectionResult from(HttpServletRequest request, Iterable<HandlerMapping> delegates)
|
||||
throws Exception {
|
||||
@@ -174,5 +175,58 @@ class DelegatingHandlerMapping extends AbstractHandlerMapping
|
||||
? ((MatchableHandlerMapping) mapping).match(request, pattern) //
|
||||
: null;
|
||||
}
|
||||
|
||||
public HandlerSelectionResult(HttpServletRequest request, HandlerMapping mapping, HandlerExecutionChain result,
|
||||
Exception ignoredException) {
|
||||
|
||||
Assert.notNull(request, "HttpServletRequest must not be null!");
|
||||
|
||||
this.request = request;
|
||||
this.mapping = mapping;
|
||||
this.result = result;
|
||||
this.ignoredException = ignoredException;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see java.lang.Object#equals(java.lang.Object)
|
||||
*/
|
||||
@Override
|
||||
public boolean equals(final java.lang.Object o) {
|
||||
|
||||
if (o == this) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!(o instanceof DelegatingHandlerMapping.HandlerSelectionResult)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
HandlerSelectionResult other = (HandlerSelectionResult) o;
|
||||
|
||||
return Objects.equals(request, other.request) //
|
||||
&& Objects.equals(mapping, other.mapping) //
|
||||
&& Objects.equals(result, other.result) //
|
||||
&& Objects.equals(ignoredException, other.ignoredException);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see java.lang.Object#hashCode()
|
||||
*/
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(request, mapping, result, ignoredException);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see java.lang.Object#toString()
|
||||
*/
|
||||
@Override
|
||||
public java.lang.String toString() {
|
||||
return "DelegatingHandlerMapping.HandlerSelectionResult(request=" + request + ", mapping=" + mapping + ", result="
|
||||
+ result + ", ignoredException=" + ignoredException + ")";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,9 +15,6 @@
|
||||
*/
|
||||
package org.springframework.data.rest.webmvc.config;
|
||||
|
||||
import lombok.NonNull;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
import org.springframework.core.MethodParameter;
|
||||
import org.springframework.data.mapping.context.PersistentEntities;
|
||||
import org.springframework.data.projection.ProjectionFactory;
|
||||
@@ -26,6 +23,7 @@ import org.springframework.data.rest.core.support.SelfLinkProvider;
|
||||
import org.springframework.data.rest.webmvc.PersistentEntityResourceAssembler;
|
||||
import org.springframework.data.rest.webmvc.mapping.Associations;
|
||||
import org.springframework.data.rest.webmvc.support.PersistentEntityProjector;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.web.bind.support.WebDataBinderFactory;
|
||||
import org.springframework.web.context.request.NativeWebRequest;
|
||||
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
|
||||
@@ -36,14 +34,30 @@ import org.springframework.web.method.support.ModelAndViewContainer;
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
@RequiredArgsConstructor
|
||||
public class PersistentEntityResourceAssemblerArgumentResolver implements HandlerMethodArgumentResolver {
|
||||
|
||||
private final @NonNull PersistentEntities entities;
|
||||
private final @NonNull SelfLinkProvider linkProvider;
|
||||
private final @NonNull ProjectionDefinitions projectionDefinitions;
|
||||
private final @NonNull ProjectionFactory projectionFactory;
|
||||
private final @NonNull Associations links;
|
||||
private final PersistentEntities entities;
|
||||
private final SelfLinkProvider linkProvider;
|
||||
private final ProjectionDefinitions projectionDefinitions;
|
||||
private final ProjectionFactory projectionFactory;
|
||||
private final Associations associations;
|
||||
|
||||
public PersistentEntityResourceAssemblerArgumentResolver(PersistentEntities entities, SelfLinkProvider linkProvider,
|
||||
ProjectionDefinitions projectionDefinitions, ProjectionFactory projectionFactory,
|
||||
Associations associations) {
|
||||
|
||||
Assert.notNull(entities, "PersistentEntities must not be null!");
|
||||
Assert.notNull(linkProvider, "SelfLinkProvider must not be null!");
|
||||
Assert.notNull(projectionDefinitions, "ProjectionDefinitions must not be null!");
|
||||
Assert.notNull(projectionFactory, "ProjectionFactory must not be null!");
|
||||
Assert.notNull(associations, "Associations must not be null!");
|
||||
|
||||
this.entities = entities;
|
||||
this.linkProvider = linkProvider;
|
||||
this.projectionDefinitions = projectionDefinitions;
|
||||
this.projectionFactory = projectionFactory;
|
||||
this.associations = associations;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
@@ -64,8 +78,8 @@ public class PersistentEntityResourceAssemblerArgumentResolver implements Handle
|
||||
|
||||
String projectionParameter = webRequest.getParameter(projectionDefinitions.getParameterName());
|
||||
PersistentEntityProjector projector = new PersistentEntityProjector(projectionDefinitions, projectionFactory,
|
||||
projectionParameter, links.getMappings());
|
||||
projectionParameter, associations.getMappings());
|
||||
|
||||
return new PersistentEntityResourceAssembler(entities, projector, links, linkProvider);
|
||||
return new PersistentEntityResourceAssembler(entities, projector, associations, linkProvider);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,9 +15,6 @@
|
||||
*/
|
||||
package org.springframework.data.rest.webmvc.config;
|
||||
|
||||
import lombok.NonNull;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.Serializable;
|
||||
import java.util.List;
|
||||
@@ -48,6 +45,7 @@ import org.springframework.http.converter.json.MappingJackson2HttpMessageConvert
|
||||
import org.springframework.http.server.ServerHttpRequest;
|
||||
import org.springframework.http.server.ServletServerHttpRequest;
|
||||
import org.springframework.plugin.core.PluginRegistry;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.web.bind.support.WebDataBinderFactory;
|
||||
import org.springframework.web.context.request.NativeWebRequest;
|
||||
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
|
||||
@@ -63,19 +61,37 @@ import com.fasterxml.jackson.databind.node.ObjectNode;
|
||||
* @author Jon Brisbin
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
@RequiredArgsConstructor
|
||||
public class PersistentEntityResourceHandlerMethodArgumentResolver implements HandlerMethodArgumentResolver {
|
||||
|
||||
private static final String ERROR_MESSAGE = "Could not read an object of type %s from the request!";
|
||||
private static final String NO_CONVERTER_FOUND = "No suitable HttpMessageConverter found to read request body into object of type %s from request with content type of %s!";
|
||||
|
||||
private final @NonNull List<HttpMessageConverter<?>> messageConverters;
|
||||
private final @NonNull RootResourceInformationHandlerMethodArgumentResolver resourceInformationResolver;
|
||||
private final @NonNull BackendIdHandlerMethodArgumentResolver idResolver;
|
||||
private final @NonNull DomainObjectReader reader;
|
||||
private final @NonNull PluginRegistry<EntityLookup<?>, Class<?>> lookups;
|
||||
private final List<HttpMessageConverter<?>> messageConverters;
|
||||
private final RootResourceInformationHandlerMethodArgumentResolver resourceInformationResolver;
|
||||
private final BackendIdHandlerMethodArgumentResolver idResolver;
|
||||
private final DomainObjectReader reader;
|
||||
private final PluginRegistry<EntityLookup<?>, Class<?>> lookups;
|
||||
private final ConversionService conversionService = new DefaultConversionService();
|
||||
|
||||
public PersistentEntityResourceHandlerMethodArgumentResolver(
|
||||
List<HttpMessageConverter<?>> messageConverters,
|
||||
RootResourceInformationHandlerMethodArgumentResolver resourceInformationResolver,
|
||||
BackendIdHandlerMethodArgumentResolver idResolver, DomainObjectReader reader,
|
||||
PluginRegistry<EntityLookup<?>, Class<?>> lookups) {
|
||||
|
||||
Assert.notNull(messageConverters, "HttpMessageConverters must not be null!");
|
||||
Assert.notNull(resourceInformationResolver, "RootResourceInformation resolver must not be null!");
|
||||
Assert.notNull(idResolver, "IdResolver must not be null!");
|
||||
Assert.notNull(reader, "DomainObjectReader must not be null!");
|
||||
Assert.notNull(lookups, "EntityLookups must not be null!");
|
||||
|
||||
this.messageConverters = messageConverters;
|
||||
this.resourceInformationResolver = resourceInformationResolver;
|
||||
this.idResolver = idResolver;
|
||||
this.reader = reader;
|
||||
this.lookups = lookups;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.web.method.support.HandlerMethodArgumentResolver#supportsParameter(org.springframework.core.MethodParameter)
|
||||
|
||||
@@ -15,10 +15,6 @@
|
||||
*/
|
||||
package org.springframework.data.rest.webmvc.json;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.NonNull;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
@@ -66,11 +62,19 @@ import com.fasterxml.jackson.databind.node.ObjectNode;
|
||||
* @author Thomas Mrozinski
|
||||
* @since 2.2
|
||||
*/
|
||||
@RequiredArgsConstructor
|
||||
public class DomainObjectReader {
|
||||
|
||||
private final @NonNull PersistentEntities entities;
|
||||
private final @NonNull Associations associationLinks;
|
||||
private final PersistentEntities entities;
|
||||
private final Associations associationLinks;
|
||||
|
||||
public DomainObjectReader(PersistentEntities entities, Associations associationLinks) {
|
||||
|
||||
Assert.notNull(entities, "PersistentEntities must not be null!");
|
||||
Assert.notNull(associationLinks, "Associations must not be null!");
|
||||
|
||||
this.entities = entities;
|
||||
this.associationLinks = associationLinks;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads the given input stream into an {@link ObjectNode} and applies that to the given existing instance.
|
||||
@@ -572,11 +576,19 @@ public class DomainObjectReader {
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
@RequiredArgsConstructor
|
||||
private final class LinkedAssociationSkippingAssociationHandler implements SimpleAssociationHandler {
|
||||
private static final class LinkedAssociationSkippingAssociationHandler implements SimpleAssociationHandler {
|
||||
|
||||
private final @NonNull Associations associations;
|
||||
private final @NonNull SimplePropertyHandler delegate;
|
||||
private final Associations associations;
|
||||
private final SimplePropertyHandler delegate;
|
||||
|
||||
public LinkedAssociationSkippingAssociationHandler(Associations associations, SimplePropertyHandler delegate) {
|
||||
|
||||
Assert.notNull(associations, "Associations must not be null!");
|
||||
Assert.notNull(delegate, "Delegate SimplePropertyHandler must not be null!");
|
||||
|
||||
this.associations = associations;
|
||||
this.delegate = delegate;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
@@ -585,7 +597,7 @@ public class DomainObjectReader {
|
||||
@Override
|
||||
public void doWithAssociation(Association<? extends PersistentProperty<?>> association) {
|
||||
|
||||
if (associationLinks.isLinkableAssociation(association)) {
|
||||
if (associations.isLinkableAssociation(association)) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -600,7 +612,7 @@ public class DomainObjectReader {
|
||||
*/
|
||||
private class MergingPropertyHandler implements SimplePropertyHandler {
|
||||
|
||||
private final @Getter MappedProperties properties;
|
||||
private final MappedProperties properties;
|
||||
private final PersistentPropertyAccessor<?> targetAccessor;
|
||||
private final PersistentPropertyAccessor<?> sourceAccessor;
|
||||
private final ObjectMapper mapper;
|
||||
@@ -628,6 +640,10 @@ public class DomainObjectReader {
|
||||
this.mapper = mapper;
|
||||
}
|
||||
|
||||
public MappedProperties getProperties() {
|
||||
return this.properties;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.mapping.SimplePropertyHandler#doWithPersistentProperty(org.springframework.data.mapping.PersistentProperty)
|
||||
|
||||
@@ -15,8 +15,6 @@
|
||||
*/
|
||||
package org.springframework.data.rest.webmvc.json;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
@@ -178,12 +176,21 @@ public class EnumTranslator implements EnumTranslationConfiguration {
|
||||
* @since 3.2
|
||||
* @soundtrack Dave Matthews Band - #41 [4.20.02] (Best of What's Around – Encore Vol. 1)
|
||||
*/
|
||||
@RequiredArgsConstructor(staticName = "of")
|
||||
private static class TranslatedEnum implements MessageSourceResolvable {
|
||||
|
||||
private final Enum<?> value;
|
||||
private final boolean withDefaultTranslation;
|
||||
|
||||
private TranslatedEnum(Enum<?> value, boolean withDefaultTranslation) {
|
||||
|
||||
this.value = value;
|
||||
this.withDefaultTranslation = withDefaultTranslation;
|
||||
}
|
||||
|
||||
public static TranslatedEnum of(Enum<?> value, boolean withDefaultTranslation) {
|
||||
return new TranslatedEnum(value, withDefaultTranslation);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.context.MessageSourceResolvable#getCodes()
|
||||
|
||||
@@ -15,9 +15,6 @@
|
||||
*/
|
||||
package org.springframework.data.rest.webmvc.json;
|
||||
|
||||
import lombok.NonNull;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
@@ -49,7 +46,6 @@ import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
* @author Oliver Gierke
|
||||
* @since 2.6
|
||||
*/
|
||||
@RequiredArgsConstructor
|
||||
public class JacksonMappingAwareSortTranslator {
|
||||
|
||||
private final Repositories repositories;
|
||||
@@ -111,7 +107,6 @@ public class JacksonMappingAwareSortTranslator {
|
||||
* @author Oliver Gierke
|
||||
* @since 2.6
|
||||
*/
|
||||
@RequiredArgsConstructor
|
||||
public static class SortTranslator {
|
||||
|
||||
private static final String DELIMITERS = "_\\.";
|
||||
@@ -119,9 +114,20 @@ public class JacksonMappingAwareSortTranslator {
|
||||
|
||||
private static final Pattern SPLITTER = Pattern.compile("(?:[%s]?([%s]*?[^%s]+))".replaceAll("%s", DELIMITERS));
|
||||
|
||||
private final @NonNull PersistentEntities persistentEntities;
|
||||
private final @NonNull ObjectMapper objectMapper;
|
||||
private final @NonNull Associations associations;
|
||||
private final PersistentEntities entities;
|
||||
private final ObjectMapper objectMapper;
|
||||
private final Associations associations;
|
||||
|
||||
public SortTranslator(PersistentEntities entities, ObjectMapper objectMapper, Associations associations) {
|
||||
|
||||
Assert.notNull(entities, "PersistentEntities must not be null!");
|
||||
Assert.notNull(objectMapper, "ObjectMapper must not be null!");
|
||||
Assert.notNull(associations, "Associations must not be null!");
|
||||
|
||||
this.entities = entities;
|
||||
this.objectMapper = objectMapper;
|
||||
this.associations = associations;
|
||||
}
|
||||
|
||||
/**
|
||||
* Translates {@link Sort} orders from Jackson-mapped field names to {@link PersistentProperty} names. Properties
|
||||
@@ -172,7 +178,7 @@ public class JacksonMappingAwareSortTranslator {
|
||||
|
||||
List<String> persistentPropertyPath = new ArrayList<String>(iteratorSource.size());
|
||||
|
||||
TypedSegment typedSegment = TypedSegment.create(persistentEntities, objectMapper, rootEntity);
|
||||
TypedSegment typedSegment = TypedSegment.create(entities, objectMapper, rootEntity);
|
||||
|
||||
for (String field : iteratorSource) {
|
||||
|
||||
|
||||
@@ -15,9 +15,6 @@
|
||||
*/
|
||||
package org.springframework.data.rest.webmvc.json;
|
||||
|
||||
import lombok.AccessLevel;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
@@ -46,7 +43,6 @@ import com.fasterxml.jackson.databind.introspect.ClassIntrospector;
|
||||
* @author Mark Paluch
|
||||
* @author Mathias Düsterhöft
|
||||
*/
|
||||
@RequiredArgsConstructor(access = AccessLevel.PRIVATE)
|
||||
class MappedProperties {
|
||||
|
||||
private final Map<PersistentProperty<?>, BeanPropertyDefinition> propertyToFieldName;
|
||||
@@ -55,6 +51,17 @@ class MappedProperties {
|
||||
private final Set<String> ignoredPropertyNames;
|
||||
private final boolean anySetterFound;
|
||||
|
||||
private MappedProperties(Map<PersistentProperty<?>, BeanPropertyDefinition> propertyToFieldName,
|
||||
Map<String, PersistentProperty<?>> fieldNameToProperty, Set<BeanPropertyDefinition> unmappedProperties,
|
||||
Set<String> ignoredPropertyNames, boolean anySetterFound) {
|
||||
|
||||
this.propertyToFieldName = propertyToFieldName;
|
||||
this.fieldNameToProperty = fieldNameToProperty;
|
||||
this.unmappedProperties = unmappedProperties;
|
||||
this.ignoredPropertyNames = ignoredPropertyNames;
|
||||
this.anySetterFound = anySetterFound;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new {@link MappedProperties} instance for the given {@link PersistentEntity} and {@link BeanDescription}.
|
||||
*
|
||||
|
||||
@@ -15,15 +15,13 @@
|
||||
*/
|
||||
package org.springframework.data.rest.webmvc.json;
|
||||
|
||||
import lombok.NonNull;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
import org.springframework.core.MethodParameter;
|
||||
import org.springframework.data.domain.PageRequest;
|
||||
import org.springframework.data.domain.Pageable;
|
||||
import org.springframework.data.domain.Sort;
|
||||
import org.springframework.data.rest.webmvc.support.DefaultedPageable;
|
||||
import org.springframework.data.web.PageableHandlerMethodArgumentResolver;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.web.bind.support.WebDataBinderFactory;
|
||||
import org.springframework.web.context.request.NativeWebRequest;
|
||||
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
|
||||
@@ -41,11 +39,20 @@ import org.springframework.web.method.support.ModelAndViewContainer;
|
||||
* @author Oliver Gierke
|
||||
* @since 2.6
|
||||
*/
|
||||
@RequiredArgsConstructor
|
||||
public class MappingAwareDefaultedPageableArgumentResolver implements HandlerMethodArgumentResolver {
|
||||
|
||||
private final @NonNull JacksonMappingAwareSortTranslator translator;
|
||||
private final @NonNull PageableHandlerMethodArgumentResolver delegate;
|
||||
private final JacksonMappingAwareSortTranslator translator;
|
||||
private final PageableHandlerMethodArgumentResolver delegate;
|
||||
|
||||
public MappingAwareDefaultedPageableArgumentResolver(JacksonMappingAwareSortTranslator translator,
|
||||
PageableHandlerMethodArgumentResolver delegate) {
|
||||
|
||||
Assert.notNull(translator, "JacksonMappingAwareSortTranslator must not be null!");
|
||||
Assert.notNull(delegate, "Delegate PageableHandlerMethodArgumentResolver must not be null!");
|
||||
|
||||
this.translator = translator;
|
||||
this.delegate = delegate;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
|
||||
@@ -15,14 +15,12 @@
|
||||
*/
|
||||
package org.springframework.data.rest.webmvc.json;
|
||||
|
||||
import lombok.NonNull;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
import org.springframework.core.MethodParameter;
|
||||
import org.springframework.data.domain.PageRequest;
|
||||
import org.springframework.data.domain.Pageable;
|
||||
import org.springframework.data.domain.Sort;
|
||||
import org.springframework.data.web.PageableArgumentResolver;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.web.bind.support.WebDataBinderFactory;
|
||||
import org.springframework.web.context.request.NativeWebRequest;
|
||||
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
|
||||
@@ -40,11 +38,20 @@ import org.springframework.web.method.support.ModelAndViewContainer;
|
||||
* @author Oliver Gierke
|
||||
* @since 2.6
|
||||
*/
|
||||
@RequiredArgsConstructor
|
||||
public class MappingAwarePageableArgumentResolver implements HandlerMethodArgumentResolver, PageableArgumentResolver {
|
||||
|
||||
private final @NonNull JacksonMappingAwareSortTranslator translator;
|
||||
private final @NonNull PageableArgumentResolver delegate;
|
||||
private final JacksonMappingAwareSortTranslator translator;
|
||||
private final PageableArgumentResolver delegate;
|
||||
|
||||
public MappingAwarePageableArgumentResolver(JacksonMappingAwareSortTranslator translator,
|
||||
PageableArgumentResolver delegate) {
|
||||
|
||||
Assert.notNull(translator, "JacksonMappingAwareSortTranslator must not be null!");
|
||||
Assert.notNull(delegate, "Delegate PageableArgumentResolver must not be null!");
|
||||
|
||||
this.translator = translator;
|
||||
this.delegate = delegate;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
|
||||
@@ -15,13 +15,11 @@
|
||||
*/
|
||||
package org.springframework.data.rest.webmvc.json;
|
||||
|
||||
import lombok.NonNull;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
import org.springframework.core.MethodParameter;
|
||||
import org.springframework.data.domain.Sort;
|
||||
import org.springframework.data.web.SortArgumentResolver;
|
||||
import org.springframework.data.web.SortHandlerMethodArgumentResolver;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.web.bind.support.WebDataBinderFactory;
|
||||
import org.springframework.web.context.request.NativeWebRequest;
|
||||
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
|
||||
@@ -38,11 +36,19 @@ import org.springframework.web.method.support.ModelAndViewContainer;
|
||||
* @author Oliver Gierke
|
||||
* @since 2.6
|
||||
*/
|
||||
@RequiredArgsConstructor
|
||||
public class MappingAwareSortArgumentResolver implements HandlerMethodArgumentResolver, SortArgumentResolver {
|
||||
|
||||
private final @NonNull JacksonMappingAwareSortTranslator translator;
|
||||
private final @NonNull SortArgumentResolver delegate;
|
||||
private final JacksonMappingAwareSortTranslator translator;
|
||||
private final SortArgumentResolver delegate;
|
||||
|
||||
public MappingAwareSortArgumentResolver(JacksonMappingAwareSortTranslator translator, SortArgumentResolver delegate) {
|
||||
|
||||
Assert.notNull(translator, "JacksonMappingAwareSortTranslator must not be null!");
|
||||
Assert.notNull(delegate, "Delegate SortArgumentResolver must not be null!");
|
||||
|
||||
this.translator = translator;
|
||||
this.delegate = delegate;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
|
||||
@@ -15,9 +15,6 @@
|
||||
*/
|
||||
package org.springframework.data.rest.webmvc.json;
|
||||
|
||||
import lombok.NonNull;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.Field;
|
||||
import java.net.URI;
|
||||
@@ -231,13 +228,26 @@ public class PersistentEntityJackson2Module extends SimpleModule {
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
@RequiredArgsConstructor
|
||||
static class AssociationOmittingSerializerModifier extends BeanSerializerModifier {
|
||||
|
||||
private final @NonNull PersistentEntities entities;
|
||||
private final @NonNull Associations associations;
|
||||
private final @NonNull NestedEntitySerializer nestedEntitySerializer;
|
||||
private final @NonNull LookupObjectSerializer lookupObjectSerializer;
|
||||
private final PersistentEntities entities;
|
||||
private final Associations associations;
|
||||
private final NestedEntitySerializer nestedEntitySerializer;
|
||||
private final LookupObjectSerializer lookupObjectSerializer;
|
||||
|
||||
public AssociationOmittingSerializerModifier(PersistentEntities entities, Associations associations,
|
||||
NestedEntitySerializer nestedEntitySerializer, LookupObjectSerializer lookupObjectSerializer) {
|
||||
|
||||
Assert.notNull(entities, "PersistentEntities must not be null!");
|
||||
Assert.notNull(associations, "Associations must not be null!");
|
||||
Assert.notNull(nestedEntitySerializer, "NestedEntitySerializer must not be null!");
|
||||
Assert.notNull(lookupObjectSerializer, "LookupObjectSerializer must not be null!");
|
||||
|
||||
this.entities = entities;
|
||||
this.associations = associations;
|
||||
this.nestedEntitySerializer = nestedEntitySerializer;
|
||||
this.lookupObjectSerializer = lookupObjectSerializer;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
@@ -403,13 +413,27 @@ public class PersistentEntityJackson2Module extends SimpleModule {
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
@RequiredArgsConstructor
|
||||
public static class AssociationUriResolvingDeserializerModifier extends BeanDeserializerModifier {
|
||||
|
||||
private final @NonNull PersistentEntities entities;
|
||||
private final @NonNull Associations associationLinks;
|
||||
private final @NonNull UriToEntityConverter converter;
|
||||
private final @NonNull RepositoryInvokerFactory factory;
|
||||
private final PersistentEntities entities;
|
||||
private final Associations associationLinks;
|
||||
private final UriToEntityConverter converter;
|
||||
private final RepositoryInvokerFactory factory;
|
||||
|
||||
@java.lang.SuppressWarnings("all")
|
||||
public AssociationUriResolvingDeserializerModifier(PersistentEntities entities, Associations associations,
|
||||
UriToEntityConverter converter, RepositoryInvokerFactory factory) {
|
||||
|
||||
Assert.notNull(entities, "PersistentEntities must not be null!");
|
||||
Assert.notNull(associations, "Associations must not be null!");
|
||||
Assert.notNull(converter, "UriToEntityConverter must not be null!");
|
||||
Assert.notNull(factory, "RepositoryInvokerFactory must not be null!");
|
||||
|
||||
this.entities = entities;
|
||||
this.associationLinks = associations;
|
||||
this.converter = converter;
|
||||
this.factory = factory;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
@@ -846,12 +870,19 @@ public class PersistentEntityJackson2Module extends SimpleModule {
|
||||
}
|
||||
}
|
||||
|
||||
@RequiredArgsConstructor
|
||||
public static class LookupObjectSerializer extends ToStringSerializer {
|
||||
|
||||
private static final long serialVersionUID = -3033458643050330913L;
|
||||
|
||||
private final PluginRegistry<EntityLookup<?>, Class<?>> lookups;
|
||||
|
||||
public LookupObjectSerializer(PluginRegistry<EntityLookup<?>, Class<?>> lookups) {
|
||||
|
||||
Assert.notNull(lookups, "EntityLookups must not be null!");
|
||||
|
||||
this.lookups = lookups;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see com.fasterxml.jackson.databind.ser.std.ToStringSerializer#serialize(java.lang.Object, com.fasterxml.jackson.core.JsonGenerator, com.fasterxml.jackson.databind.SerializerProvider)
|
||||
|
||||
@@ -15,9 +15,6 @@
|
||||
*/
|
||||
package org.springframework.data.rest.webmvc.json;
|
||||
|
||||
import lombok.NonNull;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
@@ -91,7 +88,7 @@ public class PersistentEntityToJsonSchemaConverter implements ConditionalGeneric
|
||||
*
|
||||
* @param entities must not be {@literal null}.
|
||||
* @param mappings must not be {@literal null}.
|
||||
* @param accessor must not be {@literal null}.
|
||||
* @param resolver must not be {@literal null}.
|
||||
* @param objectMapper must not be {@literal null}.
|
||||
* @param configuration must not be {@literal null}.
|
||||
*/
|
||||
@@ -275,28 +272,8 @@ public class PersistentEntityToJsonSchemaConverter implements ConditionalGeneric
|
||||
return getPropertiesFor(property.getActualType(),
|
||||
associations.getMappings().getMetadataFor(property.getActualType()), descriptors);
|
||||
}
|
||||
//
|
||||
// private JsonSchemaProperty getSchemaProperty(BeanPropertyDefinition definition, TypeInformation<?> type,
|
||||
// ResourceDescription description) {
|
||||
//
|
||||
// String name = definition.getName();
|
||||
// String title = resolver.resolveWithDefault(new ResolvableProperty(definition));
|
||||
// String resolvedDescription = resolver.resolve(description);
|
||||
// boolean required = definition.isRequired();
|
||||
// Class<?> rawType = type.getType();
|
||||
//
|
||||
// if (!rawType.isEnum()) {
|
||||
// return new JsonSchemaProperty(name, title, resolvedDescription, required).with(type);
|
||||
// }
|
||||
//
|
||||
// String message = resolver.resolve(new DefaultMessageSourceResolvable(description.getMessage()));
|
||||
//
|
||||
// return new EnumProperty(name, title, rawType,
|
||||
// description.getDefaultMessage().equals(resolvedDescription) ? message : resolvedDescription, required);
|
||||
// }
|
||||
|
||||
private ResourceDescription getDescriptionFor(PersistentProperty<?> property, ResourceMetadata metadata) {
|
||||
|
||||
ResourceMapping propertyMapping = metadata.getMappingFor(property);
|
||||
return propertyMapping.getDescription();
|
||||
}
|
||||
@@ -308,7 +285,6 @@ public class PersistentEntityToJsonSchemaConverter implements ConditionalGeneric
|
||||
* @since 2.4
|
||||
*/
|
||||
private class JsonSchemaPropertyRegistrar {
|
||||
|
||||
private final JacksonMetadata metadata;
|
||||
private final List<AbstractJsonSchemaProperty<?>> properties;
|
||||
|
||||
@@ -318,32 +294,25 @@ public class PersistentEntityToJsonSchemaConverter implements ConditionalGeneric
|
||||
* @param metadata must not be {@literal null}.
|
||||
*/
|
||||
public JsonSchemaPropertyRegistrar(JacksonMetadata metadata) {
|
||||
|
||||
Assert.notNull(metadata, "Metadata must not be null!");
|
||||
|
||||
this.metadata = metadata;
|
||||
this.properties = new ArrayList<AbstractJsonSchemaProperty<?>>();
|
||||
}
|
||||
|
||||
public void register(JsonSchemaProperty property, TypeInformation<?> type) {
|
||||
|
||||
if (type == null) {
|
||||
properties.add(property);
|
||||
return;
|
||||
}
|
||||
|
||||
JsonSerializer<?> serializer = metadata.getTypeSerializer(type.getType());
|
||||
|
||||
if (serializer instanceof JsonSchemaPropertyCustomizer) {
|
||||
properties.add(((JsonSchemaPropertyCustomizer) serializer).customize(property, type));
|
||||
return;
|
||||
}
|
||||
|
||||
if (configuration.isLookupType(type.getType())) {
|
||||
properties.add(customizerFactory.getCustomizerFor(type.getType()).customize(property, type));
|
||||
return;
|
||||
}
|
||||
|
||||
properties.add(property);
|
||||
}
|
||||
|
||||
@@ -352,10 +321,16 @@ public class PersistentEntityToJsonSchemaConverter implements ConditionalGeneric
|
||||
}
|
||||
}
|
||||
|
||||
@RequiredArgsConstructor
|
||||
public static class ValueTypeSchemaPropertyCustomizerFactory {
|
||||
|
||||
private final @NonNull RepositoryInvokerFactory factory;
|
||||
private final RepositoryInvokerFactory factory;
|
||||
|
||||
public ValueTypeSchemaPropertyCustomizerFactory(RepositoryInvokerFactory factory) {
|
||||
|
||||
Assert.notNull(factory, "RepositoryInvokerFactory must not be null!");
|
||||
|
||||
this.factory = factory;
|
||||
}
|
||||
|
||||
public JsonSchemaPropertyCustomizer getCustomizerFor(final Class<?> type) {
|
||||
|
||||
@@ -442,13 +417,24 @@ public class PersistentEntityToJsonSchemaConverter implements ConditionalGeneric
|
||||
}
|
||||
}
|
||||
|
||||
@RequiredArgsConstructor
|
||||
private static class JacksonProperty {
|
||||
|
||||
private final JacksonMetadata metadata;
|
||||
private final Optional<? extends PersistentProperty<?>> property;
|
||||
private final BeanPropertyDefinition definition;
|
||||
|
||||
public JacksonProperty(JacksonMetadata metadata, Optional<? extends PersistentProperty<?>> property,
|
||||
BeanPropertyDefinition definition) {
|
||||
|
||||
Assert.notNull(metadata, "JacksonMetadata must not be null!");
|
||||
Assert.notNull(property, "PersistentProperty must not be null!");
|
||||
Assert.notNull(definition, "BeanPropertyDefinition must not be null!");
|
||||
|
||||
this.metadata = metadata;
|
||||
this.property = property;
|
||||
this.definition = definition;
|
||||
}
|
||||
|
||||
@SuppressWarnings("rawtypes")
|
||||
public TypeInformation<?> getPropertyType() {
|
||||
return property.map(it -> (TypeInformation) it.getTypeInformation())
|
||||
@@ -499,12 +485,20 @@ public class PersistentEntityToJsonSchemaConverter implements ConditionalGeneric
|
||||
}
|
||||
}
|
||||
|
||||
@RequiredArgsConstructor
|
||||
private static class DefaultMessageResolver implements InternalMessageResolver {
|
||||
|
||||
private final MessageResolver accessor;
|
||||
private final MessageResolver resolver;
|
||||
private final RepositoryRestConfiguration configuration;
|
||||
|
||||
public DefaultMessageResolver(MessageResolver resolver, RepositoryRestConfiguration configuration) {
|
||||
|
||||
Assert.notNull(resolver, "MessageResolver must not be null!");
|
||||
Assert.notNull(configuration, "RepositoryRestConfiguration must not be null!");
|
||||
|
||||
this.resolver = resolver;
|
||||
this.configuration = configuration;
|
||||
}
|
||||
|
||||
public String resolve(MessageSourceResolvable resolvable) {
|
||||
|
||||
if (resolvable == null) {
|
||||
@@ -512,7 +506,7 @@ public class PersistentEntityToJsonSchemaConverter implements ConditionalGeneric
|
||||
}
|
||||
|
||||
try {
|
||||
return accessor.resolve(resolvable);
|
||||
return resolver.resolve(resolvable);
|
||||
} catch (NoSuchMessageException o_O) {
|
||||
|
||||
if (configuration.getMetadataConfiguration().omitUnresolvableDescriptionKeys()) {
|
||||
@@ -532,9 +526,7 @@ public class PersistentEntityToJsonSchemaConverter implements ConditionalGeneric
|
||||
* @since 2.4
|
||||
*/
|
||||
private static class DefaultingMessageSourceResolvable implements MessageSourceResolvable {
|
||||
|
||||
private static Pattern SPLIT_CAMEL_CASE = Pattern.compile("(?<!(^|[A-Z]))(?=[A-Z])|(?<!^)(?=[A-Z][a-z])");
|
||||
|
||||
private final MessageSourceResolvable delegate;
|
||||
|
||||
/**
|
||||
@@ -570,17 +562,13 @@ public class PersistentEntityToJsonSchemaConverter implements ConditionalGeneric
|
||||
*/
|
||||
@Override
|
||||
public String getDefaultMessage() {
|
||||
|
||||
String defaultMessage = delegate.getDefaultMessage();
|
||||
|
||||
if (defaultMessage != null) {
|
||||
return defaultMessage;
|
||||
}
|
||||
|
||||
String[] split = getCodes()[0].split("\\.");
|
||||
String tail = split[split.length - 1];
|
||||
tail = "_title".equals(tail) ? split[split.length - 2] : tail;
|
||||
|
||||
return StringUtils.capitalize(StringUtils
|
||||
.collectionToDelimitedString(Arrays.asList(SPLIT_CAMEL_CASE.split(tail)), " ").toLowerCase(Locale.US));
|
||||
}
|
||||
|
||||
@@ -15,9 +15,6 @@
|
||||
*/
|
||||
package org.springframework.data.rest.webmvc.json;
|
||||
|
||||
import lombok.NonNull;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
@@ -117,11 +114,19 @@ class WrappedProperties {
|
||||
*
|
||||
* @author Mark Paluch
|
||||
*/
|
||||
@RequiredArgsConstructor
|
||||
static class JacksonUnwrappedPropertiesResolver {
|
||||
|
||||
private final @NonNull PersistentEntities persistentEntities;
|
||||
private final @NonNull ObjectMapper mapper;
|
||||
private final PersistentEntities entities;
|
||||
private final ObjectMapper mapper;
|
||||
|
||||
public JacksonUnwrappedPropertiesResolver(PersistentEntities entities, ObjectMapper mapper) {
|
||||
|
||||
Assert.notNull(entities, "PersistentEntities must not be null!");
|
||||
Assert.notNull(mapper, "ObjectMapper must not be null!");
|
||||
|
||||
this.entities = entities;
|
||||
this.mapper = mapper;
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolve {@code @JsonUnwrapped} field names to a list of involved {@link PersistentProperty properties}.
|
||||
@@ -139,7 +144,7 @@ class WrappedProperties {
|
||||
private Map<String, List<PersistentProperty<?>>> findUnwrappedPropertyPaths(Class<?> type,
|
||||
NameTransformer nameTransformer, boolean considerRegularProperties) {
|
||||
|
||||
return persistentEntities.getPersistentEntity(type).map(entity -> {
|
||||
return entities.getPersistentEntity(type).map(entity -> {
|
||||
|
||||
Map<String, List<PersistentProperty<?>>> mapping = new HashMap<String, List<PersistentProperty<?>>>();
|
||||
|
||||
|
||||
@@ -15,9 +15,8 @@
|
||||
*/
|
||||
package org.springframework.data.rest.webmvc.json.patch;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
import org.springframework.data.rest.webmvc.json.patch.SpelPath.UntypedSpelPath;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
@@ -62,11 +61,17 @@ class CopyOperation extends PatchOperation {
|
||||
return new CopyOperationBuilder(from);
|
||||
}
|
||||
|
||||
@RequiredArgsConstructor
|
||||
static class CopyOperationBuilder {
|
||||
|
||||
private final String from;
|
||||
|
||||
public CopyOperationBuilder(String from) {
|
||||
|
||||
Assert.hasText(from, "From must not be null!");
|
||||
|
||||
this.from = from;
|
||||
}
|
||||
|
||||
CopyOperation to(String to) {
|
||||
return new CopyOperation(SpelPath.untyped(to), SpelPath.untyped(from));
|
||||
}
|
||||
|
||||
@@ -15,8 +15,7 @@
|
||||
*/
|
||||
package org.springframework.data.rest.webmvc.json.patch;
|
||||
|
||||
import lombok.NonNull;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
import com.fasterxml.jackson.databind.JsonNode;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
@@ -29,11 +28,19 @@ import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
* @author Oliver Gierke
|
||||
* @author Simon Allegraud
|
||||
*/
|
||||
@RequiredArgsConstructor
|
||||
class JsonLateObjectEvaluator implements LateObjectEvaluator {
|
||||
|
||||
private final @NonNull ObjectMapper mapper;
|
||||
private final @NonNull JsonNode valueNode;
|
||||
private final ObjectMapper mapper;
|
||||
private final JsonNode node;
|
||||
|
||||
public JsonLateObjectEvaluator(ObjectMapper mapper, JsonNode node) {
|
||||
|
||||
Assert.notNull(mapper, "ObjectMapper must not be null!");
|
||||
Assert.notNull(node, "JsonNode must not be null!");
|
||||
|
||||
this.mapper = mapper;
|
||||
this.node = node;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
@@ -43,9 +50,9 @@ class JsonLateObjectEvaluator implements LateObjectEvaluator {
|
||||
public Object evaluate(Class<?> type) {
|
||||
|
||||
try {
|
||||
return mapper.readValue(valueNode.traverse(mapper.getFactory().getCodec()), type);
|
||||
return mapper.readValue(node.traverse(mapper.getFactory().getCodec()), type);
|
||||
} catch (Exception o_O) {
|
||||
throw new PatchException(String.format("Could not read %s into %s!", valueNode, type), o_O);
|
||||
throw new PatchException(String.format("Could not read %s into %s!", node, type), o_O);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,13 +15,12 @@
|
||||
*/
|
||||
package org.springframework.data.rest.webmvc.json.patch;
|
||||
|
||||
import lombok.NonNull;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
import com.fasterxml.jackson.databind.JsonNode;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.fasterxml.jackson.databind.node.ArrayNode;
|
||||
@@ -34,10 +33,16 @@ import com.fasterxml.jackson.databind.node.ArrayNode;
|
||||
* @author Mathias Düsterhöft
|
||||
* @author Oliver Trosien
|
||||
*/
|
||||
@RequiredArgsConstructor
|
||||
public class JsonPatchPatchConverter implements PatchConverter<JsonNode> {
|
||||
|
||||
private final @NonNull ObjectMapper mapper;
|
||||
private final ObjectMapper mapper;
|
||||
|
||||
public JsonPatchPatchConverter(ObjectMapper mapper) {
|
||||
|
||||
Assert.notNull(mapper, "ObjectMapper must not be null!");
|
||||
|
||||
this.mapper = mapper;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a {@link Patch} object given a JsonNode.
|
||||
@@ -99,7 +104,7 @@ public class JsonPatchPatchConverter implements PatchConverter<JsonNode> {
|
||||
return valueNode.asInt();
|
||||
} else if (valueNode.isLong()) {
|
||||
return valueNode.asLong();
|
||||
} else if (valueNode.isObject() || (valueNode.isArray())) {
|
||||
} else if (valueNode.isObject() || valueNode.isArray()) {
|
||||
return new JsonLateObjectEvaluator(mapper, valueNode);
|
||||
}
|
||||
|
||||
|
||||
@@ -15,10 +15,8 @@
|
||||
*/
|
||||
package org.springframework.data.rest.webmvc.json.patch;
|
||||
|
||||
import lombok.AccessLevel;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
import org.springframework.data.rest.webmvc.json.patch.SpelPath.UntypedSpelPath;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
@@ -56,11 +54,17 @@ class MoveOperation extends PatchOperation {
|
||||
return new MoveOperationBuilder(from);
|
||||
}
|
||||
|
||||
@RequiredArgsConstructor(access = AccessLevel.PRIVATE)
|
||||
static class MoveOperationBuilder {
|
||||
|
||||
private final String from;
|
||||
|
||||
private MoveOperationBuilder(String from) {
|
||||
|
||||
Assert.hasText(from, "From must not be null or empty!");
|
||||
|
||||
this.from = from;
|
||||
}
|
||||
|
||||
public MoveOperation to(String to) {
|
||||
return new MoveOperation(SpelPath.untyped(to), SpelPath.untyped(from));
|
||||
}
|
||||
|
||||
@@ -15,10 +15,8 @@
|
||||
*/
|
||||
package org.springframework.data.rest.webmvc.json.patch;
|
||||
|
||||
import lombok.NonNull;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
import org.springframework.data.rest.webmvc.json.patch.SpelPath.UntypedSpelPath;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* Abstract base class representing and providing support methods for patch operations.
|
||||
@@ -27,11 +25,10 @@ import org.springframework.data.rest.webmvc.json.patch.SpelPath.UntypedSpelPath;
|
||||
* @author Mathias Düsterhöft
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
@RequiredArgsConstructor
|
||||
public abstract class PatchOperation {
|
||||
|
||||
protected final @NonNull String op;
|
||||
protected final @NonNull UntypedSpelPath path;
|
||||
protected final String op;
|
||||
protected final UntypedSpelPath path;
|
||||
protected final Object value;
|
||||
|
||||
/**
|
||||
@@ -44,6 +41,16 @@ public abstract class PatchOperation {
|
||||
this(op, path, null);
|
||||
}
|
||||
|
||||
protected PatchOperation(String op, UntypedSpelPath path, Object value) {
|
||||
|
||||
Assert.hasText(op, "Operation must not be null or empty!");
|
||||
Assert.notNull(path, "UntypedSpelPath must not be null!");
|
||||
|
||||
this.op = op;
|
||||
this.path = path;
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs late-value evaluation on the operation value if the value is a {@link LateObjectEvaluator}.
|
||||
*
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
// Generated by delombok at Tue Aug 11 12:51:25 CEST 2020
|
||||
/*
|
||||
* Copyright 2014-2020 the original author or authors.
|
||||
*
|
||||
@@ -15,9 +16,6 @@
|
||||
*/
|
||||
package org.springframework.data.rest.webmvc.json.patch;
|
||||
|
||||
import lombok.AccessLevel;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
import org.springframework.data.rest.webmvc.json.patch.SpelPath.UntypedSpelPath;
|
||||
|
||||
/**
|
||||
@@ -27,7 +25,6 @@ import org.springframework.data.rest.webmvc.json.patch.SpelPath.UntypedSpelPath;
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
class ReplaceOperation extends PatchOperation {
|
||||
|
||||
/**
|
||||
* Constructs the replace operation
|
||||
*
|
||||
@@ -42,14 +39,18 @@ class ReplaceOperation extends PatchOperation {
|
||||
return new ReplaceOperationBuilder(path);
|
||||
}
|
||||
|
||||
@RequiredArgsConstructor(access = AccessLevel.PRIVATE)
|
||||
static class ReplaceOperationBuilder {
|
||||
|
||||
static class ReplaceOperationBuilder {
|
||||
private final String path;
|
||||
|
||||
public ReplaceOperation with(Object value) {
|
||||
return new ReplaceOperation(SpelPath.untyped(path), value);
|
||||
}
|
||||
|
||||
@java.lang.SuppressWarnings("all")
|
||||
private ReplaceOperationBuilder(final String path) {
|
||||
this.path = path;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -15,16 +15,11 @@
|
||||
*/
|
||||
package org.springframework.data.rest.webmvc.json.patch;
|
||||
|
||||
import lombok.AccessLevel;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.Getter;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.Value;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
@@ -52,14 +47,24 @@ import org.springframework.util.StringUtils;
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
@RequiredArgsConstructor(access = AccessLevel.PRIVATE)
|
||||
class SpelPath {
|
||||
|
||||
private static final SpelExpressionParser SPEL_EXPRESSION_PARSER = new SpelExpressionParser();
|
||||
private static final String APPEND_CHARACTER = "-";
|
||||
private static final Map<String, UntypedSpelPath> UNTYPED_PATHS = new ConcurrentReferenceHashMap<>(32);
|
||||
|
||||
protected final @Getter String path;
|
||||
protected final String path;
|
||||
|
||||
private SpelPath(String path) {
|
||||
|
||||
Assert.notNull(path, "Path must not be null!");
|
||||
|
||||
this.path = path;
|
||||
}
|
||||
|
||||
public String getPath() {
|
||||
return this.path;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a {@link UntypedSpelPath} for the given source.
|
||||
@@ -153,7 +158,6 @@ class SpelPath {
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
static class TypedSpelPath extends SpelPath {
|
||||
|
||||
private static final String INVALID_PATH_REFERENCE = "Invalid path reference %s on type %s!";
|
||||
@@ -164,10 +168,62 @@ class SpelPath {
|
||||
private final Expression expression;
|
||||
private final Class<?> type;
|
||||
|
||||
@Value(staticConstructor = "of")
|
||||
private static class CacheKey {
|
||||
Class<?> type;
|
||||
UntypedSpelPath path;
|
||||
private static final class CacheKey {
|
||||
|
||||
private final Class<?> type;
|
||||
private final UntypedSpelPath path;
|
||||
|
||||
private CacheKey(Class<?> type, UntypedSpelPath path) {
|
||||
|
||||
Assert.notNull(type, "Type must not be null!");
|
||||
Assert.notNull(path, "UntypedSpelPath must not be null!");
|
||||
|
||||
this.type = type;
|
||||
this.path = path;
|
||||
}
|
||||
|
||||
public static CacheKey of(final Class<?> type, final UntypedSpelPath path) {
|
||||
return new CacheKey(type, path);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see java.lang.Object#equals(java.lang.Object)
|
||||
*/
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
|
||||
if (o == this) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!(o instanceof CacheKey)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
CacheKey that = (CacheKey) o;
|
||||
|
||||
return Objects.equals(type, that.type) //
|
||||
&& Objects.equals(path, that.path);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see java.lang.Object#hashCode()
|
||||
*/
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(type, path);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see java.lang.Object#toString()
|
||||
*/
|
||||
@Override
|
||||
public java.lang.String toString() {
|
||||
return "SpelPath.TypedSpelPath.CacheKey(type=" + type + ", path=" + path + ")";
|
||||
}
|
||||
}
|
||||
|
||||
private TypedSpelPath(UntypedSpelPath path, Class<?> type) {
|
||||
@@ -441,17 +497,31 @@ class SpelPath {
|
||||
}
|
||||
}
|
||||
|
||||
@Value
|
||||
@RequiredArgsConstructor(access = AccessLevel.PRIVATE, staticName = "of")
|
||||
private static class SkippedPropertyPath {
|
||||
private static final class SkippedPropertyPath {
|
||||
|
||||
PropertyPath path;
|
||||
boolean skipped;
|
||||
private final PropertyPath path;
|
||||
private final boolean skipped;
|
||||
|
||||
private SkippedPropertyPath(PropertyPath path, boolean skipped) {
|
||||
|
||||
Assert.notNull(path, "PropertyPath must not be null!");
|
||||
|
||||
this.path = path;
|
||||
this.skipped = skipped;
|
||||
}
|
||||
|
||||
public static SkippedPropertyPath of(String segment, Class<?> type) {
|
||||
return of(PropertyPath.from(segment, type), false);
|
||||
}
|
||||
|
||||
private static SkippedPropertyPath of(PropertyPath path, boolean skipped) {
|
||||
return new SkippedPropertyPath(path, skipped);
|
||||
}
|
||||
|
||||
public PropertyPath getPath() {
|
||||
return this.path;
|
||||
}
|
||||
|
||||
public SkippedPropertyPath nested(String segment) {
|
||||
|
||||
if (skipped) {
|
||||
@@ -464,6 +534,44 @@ class SpelPath {
|
||||
? SkippedPropertyPath.of(path, true) //
|
||||
: SkippedPropertyPath.of(path.nested(segment), false);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see java.lang.Object#equals(java.lang.Object)
|
||||
*/
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
|
||||
if (o == this) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!(o instanceof SkippedPropertyPath)) {
|
||||
return false;
|
||||
}
|
||||
SkippedPropertyPath other = (SkippedPropertyPath) o;
|
||||
|
||||
return Objects.equals(path, other.path) //
|
||||
&& skipped == other.skipped;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see java.lang.Object#hashCode()
|
||||
*/
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(path, skipped);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see java.lang.Object#toString()
|
||||
*/
|
||||
@Override
|
||||
public java.lang.String toString() {
|
||||
return "SpelPath.TypedSpelPath.SkippedPropertyPath(path=" + path + ", skipped=" + skipped + ")";
|
||||
}
|
||||
}
|
||||
|
||||
private static Expression toSpel(String path, Class<?> type) {
|
||||
@@ -494,8 +602,7 @@ class SpelPath {
|
||||
.orElseGet(() -> SkippedPropertyPath.of(next, type));
|
||||
}
|
||||
|
||||
@Value
|
||||
private static class SpelExpressionBuilder {
|
||||
private static final class SpelExpressionBuilder {
|
||||
|
||||
private static final TypeInformation<String> STRING_TYPE = ClassTypeInformation.from(String.class);
|
||||
|
||||
@@ -504,6 +611,35 @@ class SpelPath {
|
||||
private final String spelSegment;
|
||||
private final boolean skipped;
|
||||
|
||||
public SpelExpressionBuilder(@Nullable PropertyPath basePath, Class<?> type, String spelSegment,
|
||||
boolean skipped) {
|
||||
|
||||
Assert.notNull(type, "Type must not be null!");
|
||||
Assert.notNull(spelSegment, "SpEL segment must not be null!");
|
||||
|
||||
this.basePath = basePath;
|
||||
this.type = type;
|
||||
this.spelSegment = spelSegment;
|
||||
this.skipped = skipped;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public PropertyPath getBasePath() {
|
||||
return this.basePath;
|
||||
}
|
||||
|
||||
public Class<?> getType() {
|
||||
return this.type;
|
||||
}
|
||||
|
||||
public String getSpelSegment() {
|
||||
return this.spelSegment;
|
||||
}
|
||||
|
||||
public boolean isSkipped() {
|
||||
return this.skipped;
|
||||
}
|
||||
|
||||
public String getExpression() {
|
||||
return StringUtils.hasText(spelSegment) ? spelSegment : null;
|
||||
}
|
||||
@@ -570,6 +706,77 @@ class SpelPath {
|
||||
|
||||
return nested(segment);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see java.lang.Object#equals(java.lang.Object)
|
||||
*/
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
|
||||
if (o == this) {
|
||||
return true;
|
||||
}
|
||||
if (!(o instanceof SpelExpressionBuilder)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
SpelExpressionBuilder that = (SpelExpressionBuilder) o;
|
||||
|
||||
return Objects.equals(basePath, that.basePath) //
|
||||
&& Objects.equals(type, that.type) //
|
||||
&& Objects.equals(spelSegment, that.spelSegment) //
|
||||
&& skipped == that.skipped;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see java.lang.Object#hashCode()
|
||||
*/
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(basePath, type, spelSegment, skipped);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see java.lang.Object#toString()
|
||||
*/
|
||||
@Override
|
||||
public java.lang.String toString() {
|
||||
return "SpelPath.TypedSpelPath.SpelExpressionBuilder(basePath=" + this.getBasePath() + ", type="
|
||||
+ this.getType() + ", spelSegment=" + this.getSpelSegment() + ", skipped=" + this.isSkipped() + ")";
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.rest.webmvc.json.patch.SpelPath#equals(java.lang.Object)
|
||||
*/
|
||||
@Override
|
||||
public boolean equals(final java.lang.Object o) {
|
||||
|
||||
if (o == this) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!(o instanceof TypedSpelPath) || !super.equals(o)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
TypedSpelPath that = (TypedSpelPath) o;
|
||||
|
||||
return Objects.equals(expression, that.expression) //
|
||||
&& Objects.equals(type, that.type);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.rest.webmvc.json.patch.SpelPath#hashCode()
|
||||
*/
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(expression, type);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,13 +15,11 @@
|
||||
*/
|
||||
package org.springframework.data.rest.webmvc.json.patch;
|
||||
|
||||
import lombok.AccessLevel;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.math.BigInteger;
|
||||
|
||||
import org.springframework.data.rest.webmvc.json.patch.SpelPath.UntypedSpelPath;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.ObjectUtils;
|
||||
|
||||
/**
|
||||
@@ -52,11 +50,17 @@ class TestOperation extends PatchOperation {
|
||||
return new TestOperationBuilder(path);
|
||||
}
|
||||
|
||||
@RequiredArgsConstructor(access = AccessLevel.PRIVATE)
|
||||
static class TestOperationBuilder {
|
||||
|
||||
private final String path;
|
||||
|
||||
private TestOperationBuilder(String path) {
|
||||
|
||||
Assert.hasText(path, "Path must not be null or empty!");
|
||||
|
||||
this.path = path;
|
||||
}
|
||||
|
||||
public TestOperation hasValue(Object value) {
|
||||
return new TestOperation(SpelPath.untyped(path), value);
|
||||
}
|
||||
|
||||
@@ -17,10 +17,6 @@ package org.springframework.data.rest.webmvc.mapping;
|
||||
|
||||
import static org.springframework.hateoas.TemplateVariable.VariableType.*;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.NonNull;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
@@ -47,11 +43,23 @@ import org.springframework.util.Assert;
|
||||
* @author Haroun Pacquee
|
||||
* @since 2.1
|
||||
*/
|
||||
@RequiredArgsConstructor
|
||||
public class Associations {
|
||||
|
||||
private final @NonNull @Getter ResourceMappings mappings;
|
||||
private final @NonNull RepositoryRestConfiguration config;
|
||||
private final ResourceMappings mappings;
|
||||
private final RepositoryRestConfiguration config;
|
||||
|
||||
public Associations(ResourceMappings mappings, RepositoryRestConfiguration config) {
|
||||
|
||||
Assert.notNull(mappings, "ResourceMappings must not be null!");
|
||||
Assert.notNull(config, "RepositoryRestConfiguration must not be null!");
|
||||
|
||||
this.mappings = mappings;
|
||||
this.config = config;
|
||||
}
|
||||
|
||||
public ResourceMappings getMappings() {
|
||||
return this.mappings;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the links to render for the given {@link Association}.
|
||||
|
||||
@@ -33,7 +33,10 @@ import org.springframework.util.Assert;
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
* @since 2.1
|
||||
* @deprecated no replacement, internal usage only. For removal in 3.5.
|
||||
* @see LinkCollector
|
||||
*/
|
||||
@Deprecated
|
||||
public class LinkCollectingAssociationHandler implements SimpleAssociationHandler {
|
||||
|
||||
private static final String AMBIGUOUS_ASSOCIATIONS = "Detected multiple association links with same relation type! Disambiguate association %s using @RestResource!";
|
||||
|
||||
@@ -15,10 +15,6 @@
|
||||
*/
|
||||
package org.springframework.data.rest.webmvc.mapping;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.NonNull;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
@@ -99,7 +95,7 @@ public class LinkCollector {
|
||||
|
||||
Path path = new Path(selfLink.expand().getHref());
|
||||
|
||||
LinkCollectingAssociationHandler handler = new LinkCollectingAssociationHandler(entities, path, associationLinks);
|
||||
LinkCollectingAssociationHandler handler = new LinkCollectingAssociationHandler(path, associationLinks);
|
||||
entities.getRequiredPersistentEntity(object.getClass()).doWithAssociations(handler);
|
||||
|
||||
return addSelfLinkIfNecessary(object, existingLinks.and(handler.getLinks()));
|
||||
@@ -117,11 +113,8 @@ public class LinkCollector {
|
||||
}
|
||||
|
||||
private Links addSelfLinkIfNecessary(Object object, Links existing) {
|
||||
|
||||
return existing.hasLink(IanaLinkRelations.SELF) //
|
||||
? existing //
|
||||
: Links.of(createSelfLink(object, existing)) //
|
||||
.and(existing);
|
||||
return existing.andIf(!existing.hasLink(IanaLinkRelations.SELF),
|
||||
() -> links.createSelfLinkFor(object).withSelfRel());
|
||||
}
|
||||
|
||||
private Link createSelfLink(Object object, Links existing) {
|
||||
@@ -136,15 +129,22 @@ public class LinkCollector {
|
||||
* @author Oliver Gierke
|
||||
* @since 2.1
|
||||
*/
|
||||
@RequiredArgsConstructor
|
||||
private static class LinkCollectingAssociationHandler implements SimpleAssociationHandler {
|
||||
|
||||
private static final String AMBIGUOUS_ASSOCIATIONS = "Detected multiple association links with same relation type! Disambiguate association %s using @RestResource!";
|
||||
|
||||
private final @NonNull PersistentEntities entities;
|
||||
private final @NonNull Path basePath;
|
||||
private final @NonNull Associations associationLinks;
|
||||
private final @NonNull List<Link> links = new ArrayList<Link>();
|
||||
private final Path basePath;
|
||||
private final Associations associationLinks;
|
||||
private final List<Link> links = new ArrayList<Link>();
|
||||
|
||||
public LinkCollectingAssociationHandler(Path basePath, Associations associationLinks) {
|
||||
|
||||
Assert.notNull(basePath, "Base Path must not be null!");
|
||||
Assert.notNull(associationLinks, "Associations must not be null!");
|
||||
|
||||
this.basePath = basePath;
|
||||
this.associationLinks = associationLinks;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the links collected after the {@link Association} has been traversed.
|
||||
@@ -178,13 +178,28 @@ public class LinkCollector {
|
||||
}
|
||||
}
|
||||
|
||||
@RequiredArgsConstructor
|
||||
private static class NestedLinkCollectingAssociationHandler implements SimpleAssociationHandler {
|
||||
|
||||
private final SelfLinkProvider selfLinks;
|
||||
private final PersistentPropertyAccessor<?> accessor;
|
||||
private final Associations associations;
|
||||
private final @Getter List<Link> links = new ArrayList<Link>();
|
||||
private final List<Link> links = new ArrayList<Link>();
|
||||
|
||||
public NestedLinkCollectingAssociationHandler(SelfLinkProvider selfLinks,
|
||||
PersistentPropertyAccessor<?> accessor, Associations associations) {
|
||||
|
||||
Assert.notNull(selfLinks, "SelfLinkProvider must not be null!");
|
||||
Assert.notNull(accessor, "PersistentPropertyAccessor must not be null!");
|
||||
Assert.notNull(associations, "Associations must not be null!");
|
||||
|
||||
this.selfLinks = selfLinks;
|
||||
this.accessor = accessor;
|
||||
this.associations = associations;
|
||||
}
|
||||
|
||||
public List<Link> getLinks() {
|
||||
return this.links;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
@@ -198,7 +213,6 @@ public class LinkCollector {
|
||||
}
|
||||
|
||||
PersistentProperty<?> property = association.getInverse();
|
||||
|
||||
Object value = accessor.getProperty(property);
|
||||
|
||||
if (value == null) {
|
||||
@@ -236,11 +250,9 @@ public class LinkCollector {
|
||||
@SuppressWarnings("unchecked")
|
||||
private static Collection<Object> asCollection(Object object) {
|
||||
|
||||
if (object instanceof Collection) {
|
||||
return (Collection<Object>) object;
|
||||
}
|
||||
|
||||
return Collections.singleton(object);
|
||||
return object instanceof Collection //
|
||||
? (Collection<Object>) object //
|
||||
: Collections.singleton(object);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
// Generated by delombok at Tue Aug 11 12:51:25 CEST 2020
|
||||
/*
|
||||
* Copyright 2016-2020 the original author or authors.
|
||||
*
|
||||
@@ -15,9 +16,6 @@
|
||||
*/
|
||||
package org.springframework.data.rest.webmvc.mapping;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
@@ -37,16 +35,28 @@ import org.springframework.hateoas.server.EntityLinks;
|
||||
|
||||
/**
|
||||
* @author Oliver Gierke
|
||||
* @deprecated no replacement, internal usage only. For removal in 3.5
|
||||
* @see LinkCollector
|
||||
*/
|
||||
@RequiredArgsConstructor
|
||||
@Deprecated
|
||||
public class NestedLinkCollectingAssociationHandler implements SimpleAssociationHandler {
|
||||
|
||||
private final EntityLinks entityLinks;
|
||||
private final PersistentEntities entities;
|
||||
private final PersistentPropertyAccessor<?> accessor;
|
||||
private final ResourceMappings mappings;
|
||||
private final List<Link> links = new ArrayList<Link>();
|
||||
|
||||
private final @Getter List<Link> links = new ArrayList<Link>();
|
||||
public NestedLinkCollectingAssociationHandler(final EntityLinks entityLinks, final PersistentEntities entities,
|
||||
final PersistentPropertyAccessor<?> accessor, final ResourceMappings mappings) {
|
||||
this.entityLinks = entityLinks;
|
||||
this.entities = entities;
|
||||
this.accessor = accessor;
|
||||
this.mappings = mappings;
|
||||
}
|
||||
|
||||
public List<Link> getLinks() {
|
||||
return this.links;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
@@ -54,29 +64,20 @@ public class NestedLinkCollectingAssociationHandler implements SimpleAssociation
|
||||
*/
|
||||
@Override
|
||||
public void doWithAssociation(Association<? extends PersistentProperty<?>> association) {
|
||||
|
||||
PersistentProperty<?> property = association.getInverse();
|
||||
Object propertyValue = accessor.getProperty(property);
|
||||
|
||||
ResourceMetadata metadata = mappings.getMetadataFor(property.getOwner().getType());
|
||||
ResourceMapping propertyMapping = metadata.getMappingFor(property);
|
||||
|
||||
if (property.isCollectionLike()) {
|
||||
|
||||
for (Object element : (Collection<?>) propertyValue) {
|
||||
|
||||
PersistentEntity<?, ?> entity = entities.getRequiredPersistentEntity(element.getClass());
|
||||
IdentifierAccessor identifierAccessor = entity.getIdentifierAccessor(element);
|
||||
|
||||
links.add(entityLinks.linkForItemResource(element.getClass(), identifierAccessor.getIdentifier())
|
||||
.withRel(propertyMapping.getRel()));
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
PersistentEntity<?, ?> entity = entities.getRequiredPersistentEntity(propertyValue.getClass());
|
||||
IdentifierAccessor identifierAccessor = entity.getIdentifierAccessor(propertyValue);
|
||||
|
||||
links.add(entityLinks.linkForItemResource(propertyValue.getClass(), identifierAccessor.getIdentifier())
|
||||
.withRel(propertyMapping.getRel()));
|
||||
}
|
||||
|
||||
@@ -15,8 +15,6 @@
|
||||
*/
|
||||
package org.springframework.data.rest.webmvc.support;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
import org.springframework.data.projection.ProjectionFactory;
|
||||
@@ -31,12 +29,20 @@ import org.springframework.util.Assert;
|
||||
* @author Oliver Gierke
|
||||
* @since 2.5
|
||||
*/
|
||||
@RequiredArgsConstructor
|
||||
public class DefaultExcerptProjector implements ExcerptProjector {
|
||||
|
||||
private final ProjectionFactory factory;
|
||||
private final ResourceMappings mappings;
|
||||
|
||||
public DefaultExcerptProjector(ProjectionFactory factory, ResourceMappings mappings) {
|
||||
|
||||
Assert.notNull(factory, "ProjectionFactory must not be null!");
|
||||
Assert.notNull(mappings, "ResourceMappings must not be null!");
|
||||
|
||||
this.factory = factory;
|
||||
this.mappings = mappings;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.rest.webmvc.support.ExcerptProjector#projectExcerpt(java.lang.Object)
|
||||
|
||||
@@ -15,28 +15,37 @@
|
||||
*/
|
||||
package org.springframework.data.rest.webmvc.support;
|
||||
|
||||
import lombok.AccessLevel;
|
||||
import lombok.Getter;
|
||||
import lombok.NonNull;
|
||||
import lombok.Value;
|
||||
import java.util.Objects;
|
||||
|
||||
import org.springframework.data.domain.Pageable;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* Value object to capture a {@link Pageable} as well whether it is the default one configured.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
@Value
|
||||
public class DefaultedPageable {
|
||||
public final class DefaultedPageable {
|
||||
|
||||
private final Pageable pageable;
|
||||
private final boolean isDefault;
|
||||
|
||||
public DefaultedPageable(Pageable pageable, boolean isDefault) {
|
||||
|
||||
Assert.notNull(pageable, "Pageable must not be null!");
|
||||
|
||||
this.pageable = pageable;
|
||||
this.isDefault = isDefault;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the delegate {@link Pageable}.
|
||||
*
|
||||
* @return can be {@literal null}.
|
||||
*/
|
||||
private final @NonNull Pageable pageable;
|
||||
private final @Getter(value = AccessLevel.NONE) boolean isDefault;
|
||||
public Pageable getPageable() {
|
||||
return this.pageable;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the contained {@link Pageable} is the default one configured.
|
||||
@@ -56,4 +65,43 @@ public class DefaultedPageable {
|
||||
public Pageable unpagedIfDefault() {
|
||||
return isDefault ? Pageable.unpaged() : pageable;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see java.lang.Object#equals(java.lang.Object)
|
||||
*/
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
|
||||
if (o == this) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!(o instanceof DefaultedPageable)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
DefaultedPageable that = (DefaultedPageable) o;
|
||||
|
||||
return Objects.equals(pageable, that.pageable) //
|
||||
&& isDefault == that.isDefault;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see java.lang.Object#hashCode()
|
||||
*/
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(pageable, isDefault);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see java.lang.Object#toString()
|
||||
*/
|
||||
@Override
|
||||
public java.lang.String toString() {
|
||||
return "DefaultedPageable(pageable=" + pageable + ", isDefault=" + isDefault + ")";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,9 +15,6 @@
|
||||
*/
|
||||
package org.springframework.data.rest.webmvc.support;
|
||||
|
||||
import lombok.NonNull;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.List;
|
||||
|
||||
@@ -38,12 +35,28 @@ import org.springframework.web.context.request.NativeWebRequest;
|
||||
* @author Oliver Gierke
|
||||
* @since 2.6
|
||||
*/
|
||||
@RequiredArgsConstructor(staticName = "of")
|
||||
public class DomainClassResolver {
|
||||
|
||||
private final @NonNull Repositories repositories;
|
||||
private final @NonNull ResourceMappings mappings;
|
||||
private final @NonNull BaseUri baseUri;
|
||||
private final Repositories repositories;
|
||||
private final ResourceMappings mappings;
|
||||
private final BaseUri baseUri;
|
||||
|
||||
private DomainClassResolver(Repositories repositories, ResourceMappings mappings,
|
||||
BaseUri baseUri) {
|
||||
|
||||
Assert.notNull(repositories, "Repositories must not be null!");
|
||||
Assert.notNull(mappings, "ResourceMappings must not be null!");
|
||||
Assert.notNull(baseUri, "BaseUri must not be null!");
|
||||
|
||||
this.repositories = repositories;
|
||||
this.mappings = mappings;
|
||||
this.baseUri = baseUri;
|
||||
}
|
||||
|
||||
public static DomainClassResolver of(Repositories repositories,
|
||||
ResourceMappings mappings, BaseUri baseUri) {
|
||||
return new DomainClassResolver(repositories, mappings, baseUri);
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolves a domain class that is associated with the {@link NativeWebRequest}
|
||||
|
||||
@@ -17,8 +17,7 @@ package org.springframework.data.rest.webmvc.support;
|
||||
|
||||
import static org.springframework.util.StringUtils.*;
|
||||
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
|
||||
import org.springframework.data.mapping.PersistentEntity;
|
||||
@@ -33,7 +32,6 @@ import org.springframework.util.Assert;
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
@EqualsAndHashCode
|
||||
public final class ETag {
|
||||
|
||||
public static final ETag NO_ETAG = new ETag(null);
|
||||
@@ -173,4 +171,33 @@ public final class ETag {
|
||||
.map(it -> accessor.getProperty(it))//
|
||||
.map(Object::toString);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see java.lang.Object#equals(java.lang.Object)
|
||||
*/
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
|
||||
if (o == this) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!(o instanceof ETag)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
ETag other = (ETag) o;
|
||||
|
||||
return Objects.equals(value, other.value);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see java.lang.Object#hashCode()
|
||||
*/
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(value);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,13 +15,13 @@
|
||||
*/
|
||||
package org.springframework.data.rest.webmvc.support;
|
||||
|
||||
import lombok.Value;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
import org.springframework.context.support.MessageSourceAccessor;
|
||||
import org.springframework.data.rest.core.RepositoryConstraintViolationException;
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.validation.FieldError;
|
||||
|
||||
@@ -59,10 +59,86 @@ public class RepositoryConstraintViolationExceptionMessage {
|
||||
return errors;
|
||||
}
|
||||
|
||||
@Value(staticConstructor = "of")
|
||||
public static class ValidationError {
|
||||
String entity, property;
|
||||
Object invalidValue;
|
||||
String message;
|
||||
public static final class ValidationError {
|
||||
|
||||
private final String entity;
|
||||
private final String property;
|
||||
private final @Nullable Object invalidValue;
|
||||
private final String message;
|
||||
|
||||
private ValidationError(String entity, String property, Object invalidValue, String message) {
|
||||
|
||||
Assert.hasText(entity, "Entity must not be null or empty!");
|
||||
Assert.hasText(property, "Property must not be null or empty!");
|
||||
Assert.hasText(message, "Message must not be null or empty!");
|
||||
|
||||
this.entity = entity;
|
||||
this.property = property;
|
||||
this.invalidValue = invalidValue;
|
||||
this.message = message;
|
||||
}
|
||||
|
||||
public static ValidationError of(String entity, String property, Object invalidValue, String message) {
|
||||
return new ValidationError(entity, property, invalidValue, message);
|
||||
}
|
||||
|
||||
public String getEntity() {
|
||||
return this.entity;
|
||||
}
|
||||
|
||||
public String getProperty() {
|
||||
return this.property;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public Object getInvalidValue() {
|
||||
return this.invalidValue;
|
||||
}
|
||||
|
||||
public String getMessage() {
|
||||
return this.message;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see java.lang.Object#equals(java.lang.Object)
|
||||
*/
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
|
||||
if (o == this) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!(o instanceof ValidationError)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
ValidationError other = (ValidationError) o;
|
||||
|
||||
return Objects.equals(entity, other.entity) //
|
||||
&& Objects.equals(property, other.property) //
|
||||
&& Objects.equals(invalidValue, other.invalidValue) //
|
||||
&& Objects.equals(message, other.message);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see java.lang.Object#hashCode()
|
||||
*/
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(entity, property, invalidValue, message);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see java.lang.Object#toString()
|
||||
*/
|
||||
@Override
|
||||
public java.lang.String toString() {
|
||||
return "RepositoryConstraintViolationExceptionMessage.ValidationError(entity=" + entity + ", property=" + property
|
||||
+ ", invalidValue=" + invalidValue + ", message=" + message + ")";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,9 +17,6 @@ package org.springframework.data.rest.webmvc.support;
|
||||
|
||||
import static org.springframework.hateoas.TemplateVariable.VariableType.*;
|
||||
|
||||
import lombok.NonNull;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
@@ -60,14 +57,29 @@ import org.springframework.web.util.UriComponentsBuilder;
|
||||
* @author Jon Brisbin
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
@RequiredArgsConstructor
|
||||
public class RepositoryEntityLinks extends AbstractEntityLinks {
|
||||
|
||||
private final @NonNull Repositories repositories;
|
||||
private final @NonNull ResourceMappings mappings;
|
||||
private final @NonNull RepositoryRestConfiguration config;
|
||||
private final @NonNull PagingAndSortingTemplateVariables templateVariables;
|
||||
private final @NonNull PluginRegistry<BackendIdConverter, Class<?>> idConverters;
|
||||
private final Repositories repositories;
|
||||
private final ResourceMappings mappings;
|
||||
private final RepositoryRestConfiguration config;
|
||||
private final PagingAndSortingTemplateVariables templateVariables;
|
||||
private final PluginRegistry<BackendIdConverter, Class<?>> idConverters;
|
||||
|
||||
public RepositoryEntityLinks(Repositories repositories, ResourceMappings mappings, RepositoryRestConfiguration config,
|
||||
PagingAndSortingTemplateVariables templateVariables, PluginRegistry<BackendIdConverter, Class<?>> idConverters) {
|
||||
|
||||
Assert.notNull(repositories, "Repositories must not be null!");
|
||||
Assert.notNull(mappings, "ResourceMappings must not be null!");
|
||||
Assert.notNull(config, "RepositoryRestConfiguration must not be null!");
|
||||
Assert.notNull(templateVariables, "PagingAndSortingTemplateVariables must not be null!");
|
||||
Assert.notNull(idConverters, "BackendIdConverters must not be null!");
|
||||
|
||||
this.repositories = repositories;
|
||||
this.mappings = mappings;
|
||||
this.config = config;
|
||||
this.templateVariables = templateVariables;
|
||||
this.idConverters = idConverters;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
|
||||
@@ -15,23 +15,39 @@
|
||||
*/
|
||||
package org.springframework.data.rest.webmvc.util;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
import java.io.InputStream;
|
||||
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.http.HttpInputMessage;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* {@link HttpInputMessage} based on a plain {@link InputStream}, i.e. exposing no headers.
|
||||
*
|
||||
* @author Oliver Drotbohm
|
||||
*/
|
||||
@RequiredArgsConstructor(staticName = "of")
|
||||
public class InputStreamHttpInputMessage implements HttpInputMessage {
|
||||
|
||||
private final @Getter InputStream body;
|
||||
private final InputStream body;
|
||||
|
||||
private InputStreamHttpInputMessage(final InputStream body) {
|
||||
|
||||
Assert.notNull(body, "InputStream must not be null!");
|
||||
|
||||
this.body = body;
|
||||
}
|
||||
|
||||
public static InputStreamHttpInputMessage of(final InputStream body) {
|
||||
return new InputStreamHttpInputMessage(body);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.http.HttpInputMessage#getBody()
|
||||
*/
|
||||
public InputStream getBody() {
|
||||
return this.body;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
|
||||
Reference in New Issue
Block a user