DATAREST-1104 - Adapt to API changes in mapping subsystem.

This commit is contained in:
Oliver Gierke
2017-07-04 10:29:09 +02:00
committed by Mark Paluch
parent 069869a69b
commit 2ad963074c
19 changed files with 163 additions and 159 deletions

View File

@@ -86,7 +86,7 @@ public class ValidationErrors extends AbstractPropertyBindingResult {
String segment = iterator.next();
Optional<? extends PersistentProperty<?>> property = entities.getPersistentEntity(value.getClass())//
.flatMap(it -> it.getPersistentProperty(PropertyAccessorUtils.getPropertyName(segment)));
.map(it -> it.getPersistentProperty(PropertyAccessorUtils.getPropertyName(segment)));
value = getValue(value, property, segment, propertyName);

View File

@@ -56,8 +56,9 @@ class MappingResourceMetadata extends TypeBasedCollectionResourceMapping impleme
this.entity.doWithAssociations(propertyMappings);
this.entity.doWithProperties(propertyMappings);
Optional<RestResource> annotation = entity.findAnnotation(RestResource.class);
this.explicitlyExported = annotation.map(it -> it.exported()).orElse(false);
this.explicitlyExported = Optional.ofNullable(entity.findAnnotation(RestResource.class))//
.map(it -> it.exported())//
.orElse(false);
}
/*

View File

@@ -49,8 +49,9 @@ class PersistentPropertyResourceMapping implements PropertyAwareResourceMapping
this.property = property;
this.mappings = mappings;
this.annotation = property.isAssociation() ? property.findAnnotation(RestResource.class) : Optional.empty();
this.description = property.findAnnotation(Description.class);
this.annotation = Optional
.ofNullable(property.isAssociation() ? property.findAnnotation(RestResource.class) : null);
this.description = Optional.ofNullable(property.findAnnotation(Description.class));
}
/*
@@ -111,10 +112,9 @@ class PersistentPropertyResourceMapping implements PropertyAwareResourceMapping
CollectionResourceMapping ownerTypeMapping = mappings.getMetadataFor(property.getOwner().getType());
ResourceDescription fallback = TypedResourceDescription.defaultFor(ownerTypeMapping.getItemResourceRel(), property);
return Optionals
.<ResourceDescription> firstNonEmpty(//
() -> description.map(it -> new AnnotationBasedResourceDescription(it, fallback)), //
() -> annotation.map(it -> new AnnotationBasedResourceDescription(it.description(), fallback)))
return Optionals.<ResourceDescription> firstNonEmpty(//
() -> description.map(it -> new AnnotationBasedResourceDescription(it, fallback)), //
() -> annotation.map(it -> new AnnotationBasedResourceDescription(it.description(), fallback)))
.orElse(fallback);
}

View File

@@ -88,7 +88,6 @@ public class DefaultSelfLinkProvider implements SelfLinkProvider {
private Object identifierOrNull(Object instance) {
return entities.getRequiredPersistentEntity(instance.getClass())//
.getIdentifierAccessor(instance).getIdentifier()//
.orElse(null);
.getIdentifierAccessor(instance).getIdentifier();
}
}

View File

@@ -17,8 +17,6 @@ package org.springframework.data.rest.core.support;
import static org.springframework.data.rest.core.support.DomainObjectMerger.NullHandlingPolicy.*;
import java.util.Optional;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.convert.ConversionService;
import org.springframework.data.mapping.Association;
@@ -89,18 +87,18 @@ public class DomainObjectMerger {
@Override
public void doWithPersistentProperty(PersistentProperty<?> persistentProperty) {
Optional<Object> sourceValue = sourceWrapper.getProperty(persistentProperty);
Optional<Object> targetValue = targetWrapper.getProperty(persistentProperty);
Object sourceValue = sourceWrapper.getProperty(persistentProperty);
Object targetValue = targetWrapper.getProperty(persistentProperty);
if (targetEntity.isIdProperty(persistentProperty)) {
return;
}
if (sourceValue.equals(targetValue)) {
if (sourceValue != null && sourceValue.equals(targetValue)) {
return;
}
if (nullPolicy == APPLY_NULLS || sourceValue.isPresent()) {
if (nullPolicy == APPLY_NULLS || sourceValue != null) {
targetWrapper.setProperty(persistentProperty, sourceValue);
}
}
@@ -116,7 +114,7 @@ public class DomainObjectMerger {
public void doWithAssociation(Association<? extends PersistentProperty<?>> association) {
PersistentProperty<?> persistentProperty = association.getInverse();
Optional<Object> fromVal = sourceWrapper.getProperty(persistentProperty);
Object fromVal = sourceWrapper.getProperty(persistentProperty);
if (!isNullOrEmpty(fromVal) && !fromVal.equals(targetWrapper.getProperty(persistentProperty))) {
targetWrapper.setProperty(persistentProperty, fromVal);
@@ -132,21 +130,21 @@ public class DomainObjectMerger {
* @param source can be {@literal null}.
* @return
*/
static boolean isNullOrEmpty(Optional<Object> source) {
static boolean isNullOrEmpty(Object source) {
return source.map(it -> {
if (source == null) {
return true;
}
if (it instanceof Iterable) {
return !((Iterable<?>) it).iterator().hasNext();
}
if (source instanceof Iterable) {
return !((Iterable<?>) source).iterator().hasNext();
}
if (ObjectUtils.isArray(it)) {
return ObjectUtils.isEmpty((Object[]) it);
}
if (ObjectUtils.isArray(source)) {
return ObjectUtils.isEmpty((Object[]) source);
}
return false;
}).orElse(true);
return false;
}
/**

View File

@@ -20,7 +20,6 @@ import static org.springframework.data.rest.core.support.DomainObjectMerger.*;
import java.util.Collections;
import java.util.Iterator;
import java.util.Optional;
import org.junit.Test;
@@ -34,16 +33,16 @@ public class DomainObjectMergerUnitTests {
@Test // DATAREST-327
public void considersEmptyObjectsEmpty() {
assertThat(isNullOrEmpty(Optional.empty())).isTrue();
assertThat(isNullOrEmpty(Optional.of(Collections.emptyList()))).isTrue();
assertThat(isNullOrEmpty(Optional.of(new Object[0]))).isTrue();
assertThat(isNullOrEmpty(Optional.of(new String[0]))).isTrue();
assertThat(isNullOrEmpty(Optional.of(new MyIterable()))).isTrue();
assertThat(isNullOrEmpty(null)).isTrue();
assertThat(isNullOrEmpty(Collections.emptyList())).isTrue();
assertThat(isNullOrEmpty(new Object[0])).isTrue();
assertThat(isNullOrEmpty(new String[0])).isTrue();
assertThat(isNullOrEmpty(new MyIterable())).isTrue();
assertThat(isNullOrEmpty(Optional.of(new Object()))).isFalse();
assertThat(isNullOrEmpty(Optional.of(Collections.singleton(new Object())))).isFalse();
assertThat(isNullOrEmpty(Optional.of(new Object[] { "1" }))).isFalse();
assertThat(isNullOrEmpty(Optional.of(new String[] { "1" }))).isFalse();
assertThat(isNullOrEmpty(new Object())).isFalse();
assertThat(isNullOrEmpty(Collections.singleton(new Object()))).isFalse();
assertThat(isNullOrEmpty(new Object[] { "1" })).isFalse();
assertThat(isNullOrEmpty(new String[] { "1" })).isFalse();
}
class MyIterable implements Iterable<Object> {

View File

@@ -526,7 +526,7 @@ public class JpaWebTests extends CommonWebTests {
String concurrencyTag = createdReceipt.getHeader("ETag");
mvc.perform(patch(builder.build().toUriString()).content("{ \"saleItem\" : \"SpringyBurritos\" }")
.contentType(MediaType.APPLICATION_JSON).header(IF_MATCH, concurrencyTag))
.contentType(MediaType.APPLICATION_JSON).header(IF_MATCH, concurrencyTag)) //
.andExpect(status().is2xxSuccessful());
mvc.perform(patch(builder.build().toUriString()).content("{ \"saleItem\" : \"SpringyTequila\" }")

View File

@@ -74,32 +74,35 @@ public class EmbeddedResourcesAssembler {
return;
}
accessor.getProperty(association.getInverse()).ifPresent(it -> {
Object value = accessor.getProperty(association.getInverse());
String rel = metadata.getMappingFor(property).getRel();
if (value == null) {
return;
}
if (it instanceof Collection) {
String rel = metadata.getMappingFor(property).getRel();
Collection<?> collection = (Collection<?>) it;
if (value instanceof Collection) {
if (collection.isEmpty()) {
return;
}
Collection<?> collection = (Collection<?>) value;
List<Object> nestedCollection = new ArrayList<Object>();
for (Object element : collection) {
if (element != null) {
nestedCollection.add(projector.projectExcerpt(element));
}
}
associationProjections.add(wrappers.wrap(nestedCollection, rel));
} else {
associationProjections.add(wrappers.wrap(projector.projectExcerpt(it), rel));
if (collection.isEmpty()) {
return;
}
});
List<Object> nestedCollection = new ArrayList<Object>();
for (Object element : collection) {
if (element != null) {
nestedCollection.add(projector.projectExcerpt(element));
}
}
associationProjections.add(wrappers.wrap(nestedCollection, rel));
} else {
associationProjections.add(wrappers.wrap(projector.projectExcerpt(value), rel));
}
});
return associationProjections;

View File

@@ -425,7 +425,7 @@ class RepositoryEntityController extends AbstractRepositoryRestController implem
eTag.verify(entity, it);
publisher.publishEvent(new BeforeDeleteEvent(it));
invoker.invokeDeleteById((Serializable) entity.getIdentifierAccessor(it).getIdentifier().orElse(null));
invoker.invokeDeleteById(entity.getIdentifierAccessor(it).getIdentifier());
publisher.publishEvent(new AfterDeleteEvent(it));
return new ResponseEntity<Object>(HttpStatus.NO_CONTENT);

View File

@@ -113,9 +113,9 @@ class RepositoryPropertyReferenceController extends AbstractRepositoryRestContro
@BackendId Serializable id, final @PathVariable String property,
final PersistentEntityResourceAssembler assembler) throws Exception {
final HttpHeaders headers = new HttpHeaders();
HttpHeaders headers = new HttpHeaders();
Function<ReferencedProperty, ResourceSupport> handler = prop -> prop.propertyValue.map(it -> {
Function<ReferencedProperty, ResourceSupport> handler = prop -> prop.mapValue(it -> {
if (prop.property.isCollectionLike()) {
@@ -145,10 +145,10 @@ class RepositoryPropertyReferenceController extends AbstractRepositoryRestContro
}
@RequestMapping(value = BASE_MAPPING, method = DELETE)
public ResponseEntity<? extends ResourceSupport> deletePropertyReference(final RootResourceInformation repoRequest,
public ResponseEntity<? extends ResourceSupport> deletePropertyReference(RootResourceInformation repoRequest,
@BackendId Serializable id, @PathVariable String property) throws Exception {
Function<ReferencedProperty, ResourceSupport> handler = prop -> prop.propertyValue.map(it -> {
Function<ReferencedProperty, ResourceSupport> handler = prop -> prop.mapValue(it -> {
if (prop.property.isCollectionLike() || prop.property.isMap()) {
throw HttpRequestMethodNotSupportedException.forRejectedMethod(HttpMethod.DELETE)
@@ -171,13 +171,13 @@ class RepositoryPropertyReferenceController extends AbstractRepositoryRestContro
}
@RequestMapping(value = BASE_MAPPING + "/{propertyId}", method = GET)
public ResponseEntity<ResourceSupport> followPropertyReference(final RootResourceInformation repoRequest,
@BackendId Serializable id, @PathVariable String property, final @PathVariable String propertyId,
final PersistentEntityResourceAssembler assembler) throws Exception {
public ResponseEntity<ResourceSupport> followPropertyReference(RootResourceInformation repoRequest,
@BackendId Serializable id, @PathVariable String property, @PathVariable String propertyId,
PersistentEntityResourceAssembler assembler) throws Exception {
final HttpHeaders headers = new HttpHeaders();
HttpHeaders headers = new HttpHeaders();
Function<ReferencedProperty, ResourceSupport> handler = prop -> prop.propertyValue.map(it -> {
Function<ReferencedProperty, ResourceSupport> handler = prop -> prop.mapValue(it -> {
if (prop.property.isCollectionLike()) {
@@ -268,13 +268,12 @@ class RepositoryPropertyReferenceController extends AbstractRepositoryRestContro
@RequestMapping(value = BASE_MAPPING, method = { PATCH, PUT, POST }, //
consumes = { MediaType.APPLICATION_JSON_VALUE, SPRING_DATA_COMPACT_JSON_VALUE, TEXT_URI_LIST_VALUE })
public ResponseEntity<? extends ResourceSupport> createPropertyReference(
final RootResourceInformation resourceInformation, final HttpMethod requestMethod,
final @RequestBody(required = false) Resources<Object> incoming, @BackendId Serializable id,
public ResponseEntity<? extends ResourceSupport> createPropertyReference(RootResourceInformation resourceInformation,
HttpMethod requestMethod, @RequestBody(required = false) Resources<Object> incoming, @BackendId Serializable id,
@PathVariable String property) throws Exception {
final Resources<Object> source = incoming == null ? new Resources<Object>(Collections.emptyList()) : incoming;
final RepositoryInvoker invoker = resourceInformation.getInvoker();
Resources<Object> source = incoming == null ? new Resources<Object>(Collections.emptyList()) : incoming;
RepositoryInvoker invoker = resourceInformation.getInvoker();
Function<ReferencedProperty, ResourceSupport> handler = prop -> {
@@ -282,29 +281,29 @@ class RepositoryPropertyReferenceController extends AbstractRepositoryRestContro
if (prop.property.isCollectionLike()) {
Collection<Object> collection = AUGMENTING_METHODS.contains(requestMethod)
? (Collection<Object>) prop.propertyValue.orElse(null)
Collection<Object> collection = AUGMENTING_METHODS.contains(requestMethod) //
? (Collection<Object>) prop.propertyValue //
: CollectionFactory.createCollection(propertyType, 0);
// Add to the existing collection
for (Link l1 : source.getLinks()) {
collection.add(loadPropertyValue(prop.propertyType, l1).orElse(null));
collection.add(loadPropertyValue(prop.propertyType, l1));
}
prop.accessor.setProperty(prop.property, Optional.of(collection));
prop.accessor.setProperty(prop.property, collection);
} else if (prop.property.isMap()) {
Map<String, Object> map = AUGMENTING_METHODS.contains(requestMethod)
? (Map<String, Object>) prop.propertyValue.orElse(null)
Map<String, Object> map = AUGMENTING_METHODS.contains(requestMethod) //
? (Map<String, Object>) prop.propertyValue //
: CollectionFactory.<String, Object> createMap(propertyType, 0);
// Add to the existing collection
for (Link l2 : source.getLinks()) {
map.put(l2.getRel(), loadPropertyValue(prop.propertyType, l2).orElse(null));
map.put(l2.getRel(), loadPropertyValue(prop.propertyType, l2));
}
prop.accessor.setProperty(prop.property, Optional.of(map));
prop.accessor.setProperty(prop.property, map);
} else {
@@ -320,8 +319,7 @@ class RepositoryPropertyReferenceController extends AbstractRepositoryRestContro
"Must send only 1 link to update a property reference that isn't a List or a Map.");
}
Optional<Object> propVal = loadPropertyValue(prop.propertyType, source.getLinks().get(0));
prop.accessor.setProperty(prop.property, propVal);
prop.accessor.setProperty(prop.property, loadPropertyValue(prop.propertyType, source.getLinks().get(0)));
}
publisher.publishEvent(new BeforeLinkSaveEvent(prop.accessor.getBean(), prop.propertyValue));
@@ -337,11 +335,11 @@ class RepositoryPropertyReferenceController extends AbstractRepositoryRestContro
}
@RequestMapping(value = BASE_MAPPING + "/{propertyId}", method = DELETE)
public ResponseEntity<ResourceSupport> deletePropertyReferenceId(final RootResourceInformation repoRequest,
@BackendId Serializable backendId, @PathVariable String property, final @PathVariable String propertyId)
public ResponseEntity<ResourceSupport> deletePropertyReferenceId(RootResourceInformation repoRequest,
@BackendId Serializable backendId, @PathVariable String property, @PathVariable String propertyId)
throws Exception {
Function<ReferencedProperty, ResourceSupport> handler = prop -> prop.propertyValue.map(it -> {
Function<ReferencedProperty, ResourceSupport> handler = prop -> prop.mapValue(it -> {
if (prop.property.isCollectionLike()) {
@@ -352,7 +350,7 @@ class RepositoryPropertyReferenceController extends AbstractRepositoryRestContro
Object obj = iterator.next();
prop.entity.getIdentifierAccessor(obj).getIdentifier()//
Optional.ofNullable(prop.entity.getIdentifierAccessor(obj).getIdentifier())//
.map(Object::toString)//
.filter(id -> propertyId.equals(id))//
.ifPresent(__ -> iterator.remove());
@@ -367,7 +365,7 @@ class RepositoryPropertyReferenceController extends AbstractRepositoryRestContro
Object key = iterator.next().getKey();
prop.entity.getIdentifierAccessor(m.get(key)).getIdentifier()//
Optional.ofNullable(prop.entity.getIdentifierAccessor(m.get(key)).getIdentifier())//
.map(Object::toString)//
.filter(id -> propertyId.equals(id))//
.ifPresent(__ -> iterator.remove());
@@ -390,14 +388,14 @@ class RepositoryPropertyReferenceController extends AbstractRepositoryRestContro
return ControllerUtils.toEmptyResponse(HttpStatus.NO_CONTENT);
}
private Optional<Object> loadPropertyValue(Class<?> type, Link link) {
private Object loadPropertyValue(Class<?> type, Link link) {
String href = link.expand().getHref();
String id = href.substring(href.lastIndexOf('/') + 1);
RepositoryInvoker invoker = repositoryInvokerFactory.getInvokerFor(type);
return invoker.invokeFindById(id);
return invoker.invokeFindById(id).orElse(null);
}
private Optional<ResourceSupport> doWithReferencedProperty(RootResourceInformation resourceInformation,
@@ -431,10 +429,10 @@ class RepositoryPropertyReferenceController extends AbstractRepositoryRestContro
final PersistentEntity<?, ?> entity;
final PersistentProperty<?> property;
final Class<?> propertyType;
final Optional<Object> propertyValue;
final Object propertyValue;
final PersistentPropertyAccessor accessor;
private ReferencedProperty(PersistentProperty<?> property, Optional<Object> propertyValue,
private ReferencedProperty(PersistentProperty<?> property, Object propertyValue,
PersistentPropertyAccessor wrapper) {
this.property = property;
@@ -444,12 +442,12 @@ class RepositoryPropertyReferenceController extends AbstractRepositoryRestContro
this.entity = repositories.getPersistentEntity(propertyType);
}
public void writeValue() {
accessor.setProperty(property, propertyValue);
public void wipeValue() {
accessor.setProperty(property, null);
}
public void wipeValue() {
accessor.setProperty(property, Optional.empty());
public <T> Optional<T> mapValue(Function<Object, T> function) {
return Optional.ofNullable(propertyValue).map(function);
}
}

View File

@@ -138,16 +138,15 @@ public class PersistentEntityResourceHandlerMethodArgumentResolver implements Ha
PersistentEntity<?, ?> entity = resourceInformation.getPersistentEntity();
boolean forUpdate = objectToUpdate.isPresent();
Optional<Object> entityIdentifier = objectToUpdate
.flatMap(it -> entity.getIdentifierAccessor(it).getIdentifier());
Optional<Object> entityIdentifier = objectToUpdate.map(it -> entity.getIdentifierAccessor(it).getIdentifier());
entityIdentifier.ifPresent(
it -> entity.getPropertyAccessor(obj).setProperty(entity.getRequiredIdProperty(), entityIdentifier));
entityIdentifier.ifPresent(it -> entity.getPropertyAccessor(obj).setProperty(entity.getRequiredIdProperty(),
entityIdentifier.orElse(null)));
id.ifPresent(it -> {
ConvertingPropertyAccessor accessor = new ConvertingPropertyAccessor(entity.getPropertyAccessor(obj),
conversionService);
accessor.setProperty(entity.getRequiredIdProperty(), id);
accessor.setProperty(entity.getRequiredIdProperty(), it);
});
Builder build = PersistentEntityResource.build(obj, entity);

View File

@@ -230,7 +230,7 @@ public class DomainObjectReader {
PersistentProperty<?> property = mappedProperties.getPersistentProperty(fieldName);
PersistentPropertyAccessor accessor = entity.getPropertyAccessor(target);
Optional<Object> rawValue = accessor.getProperty(property);
Optional<Object> rawValue = Optional.ofNullable(accessor.getProperty(property));
if (!rawValue.isPresent() || associationLinks.isLinkableAssociation(property)) {
continue;
@@ -315,7 +315,7 @@ public class DomainObjectReader {
* @return whether an object merge has been applied to the {@link ArrayNode}.
*/
private boolean handleArrayNode(ArrayNode array, Collection<Object> collection, ObjectMapper mapper,
Optional<TypeInformation<?>> componentType) throws Exception {
TypeInformation<?> componentType) throws Exception {
Assert.notNull(array, "ArrayNode must not be null!");
Assert.notNull(collection, "Source collection must not be null!");
@@ -373,7 +373,7 @@ public class DomainObjectReader {
Iterator<Entry<String, JsonNode>> fields = node.fields();
Class<?> keyType = typeOrObject(type.getComponentType());
Optional<TypeInformation<?>> valueType = type.getMapValueType();
TypeInformation<?> valueType = type.getMapValueType();
while (fields.hasNext()) {
@@ -391,7 +391,7 @@ public class DomainObjectReader {
} else if (value instanceof ArrayNode && sourceValue != null) {
handleArray(value, sourceValue, mapper, getTypeToMap(sourceValue, Optional.of(typeToMap)));
handleArray(value, sourceValue, mapper, getTypeToMap(sourceValue, typeToMap));
} else {
@@ -528,9 +528,8 @@ public class DomainObjectReader {
* @param type can be {@literal null}.
* @return
*/
@SuppressWarnings({ "rawtypes", "unchecked" })
private static Class<?> typeOrObject(Optional<TypeInformation<?>> type) {
return type.map(it -> it.getType()).orElse((Class) Object.class);
private static Class<?> typeOrObject(TypeInformation<?> type) {
return type == null ? Object.class : type.getType();
}
/**
@@ -542,21 +541,22 @@ public class DomainObjectReader {
* @param type can be {@literal null}.
* @return
*/
private static TypeInformation<?> getTypeToMap(Object value, Optional<TypeInformation<?>> type) {
private static TypeInformation<?> getTypeToMap(Object value, TypeInformation<?> type) {
return type.map(it -> {
if (type == null) {
return ClassTypeInformation.OBJECT;
}
if (value == null) {
return it;
}
if (value == null) {
return type;
}
if (Enum.class.isInstance(value)) {
return ClassTypeInformation.from(((Enum<?>) value).getDeclaringClass());
}
if (Enum.class.isInstance(value)) {
return ClassTypeInformation.from(((Enum<?>) value).getDeclaringClass());
}
return value.getClass().equals(it.getType()) ? it : ClassTypeInformation.from(value.getClass());
return value.getClass().equals(type.getType()) ? type : ClassTypeInformation.from(value.getClass());
}).orElse(ClassTypeInformation.OBJECT);
}
/**
@@ -636,8 +636,8 @@ public class DomainObjectReader {
return;
}
Optional<Object> sourceValue = sourceAccessor.getProperty(property);
Optional<Object> targetValue = targetAccessor.getProperty(property);
Optional<Object> sourceValue = Optional.ofNullable(sourceAccessor.getProperty(property));
Optional<Object> targetValue = Optional.ofNullable(targetAccessor.getProperty(property));
Optional<?> result = Optional.empty();
if (property.isMap()) {
@@ -650,7 +650,7 @@ public class DomainObjectReader {
result = sourceValue;
}
targetAccessor.setProperty(property, result);
targetAccessor.setProperty(property, result.orElse(null));
}
}

View File

@@ -69,8 +69,8 @@ class MappedProperties {
for (BeanPropertyDefinition property : description.findProperties()) {
Optional<? extends PersistentProperty<?>> persistentProperty = entity
.getPersistentProperty(property.getInternalName());
Optional<? extends PersistentProperty<?>> persistentProperty = //
Optional.ofNullable(entity.getPersistentProperty(property.getInternalName()));
persistentProperty.ifPresent(it -> {
propertyToFieldName.put(it, property);

View File

@@ -309,7 +309,7 @@ public class PersistentEntityJackson2Module extends SimpleModule {
return description.findProperties().stream()//
.filter(it -> it.getName().equals(finalName))//
.findFirst().flatMap(it -> entity.getPersistentProperty(it.getInternalName()));
.findFirst().map(it -> entity.getPersistentProperty(it.getInternalName()));
}
}
@@ -422,28 +422,31 @@ public class PersistentEntityJackson2Module extends SimpleModule {
SettableBeanProperty property = properties.next();
entity.getPersistentProperty(property.getName()).ifPresent(persistentProperty -> {
PersistentProperty<?> persistentProperty = entity.getPersistentProperty(property.getName());
if (associationLinks.isLookupType(persistentProperty)) {
if (persistentProperty == null) {
continue;
}
RepositoryInvokingDeserializer repositoryInvokingDeserializer = new RepositoryInvokingDeserializer(
factory, persistentProperty);
JsonDeserializer<?> deserializer = wrapIfCollection(persistentProperty, repositoryInvokingDeserializer,
config);
if (associationLinks.isLookupType(persistentProperty)) {
builder.addOrReplaceProperty(property.withValueDeserializer(deserializer), false);
return;
}
if (!associationLinks.isLinkableAssociation(persistentProperty)) {
return;
}
UriStringDeserializer uriStringDeserializer = new UriStringDeserializer(persistentProperty, converter);
JsonDeserializer<?> deserializer = wrapIfCollection(persistentProperty, uriStringDeserializer, config);
RepositoryInvokingDeserializer repositoryInvokingDeserializer = new RepositoryInvokingDeserializer(factory,
persistentProperty);
JsonDeserializer<?> deserializer = wrapIfCollection(persistentProperty, repositoryInvokingDeserializer,
config);
builder.addOrReplaceProperty(property.withValueDeserializer(deserializer), false);
});
continue;
}
if (!associationLinks.isLinkableAssociation(persistentProperty)) {
continue;
}
UriStringDeserializer uriStringDeserializer = new UriStringDeserializer(persistentProperty, converter);
JsonDeserializer<?> deserializer = wrapIfCollection(persistentProperty, uriStringDeserializer, config);
builder.addOrReplaceProperty(property.withValueDeserializer(deserializer), false);
}
});

View File

@@ -175,10 +175,10 @@ public class PersistentEntityToJsonSchemaConverter implements ConditionalGeneric
for (BeanPropertyDefinition definition : jackson) {
JacksonProperty jacksonProperty = new JacksonProperty(jackson,
entity.getPersistentProperty(definition.getInternalName()), definition);
Optional<? extends PersistentProperty<?>> prop = Optional
.ofNullable(entity.getPersistentProperty(definition.getInternalName()));
Optional<? extends PersistentProperty<?>> prop = entity.getPersistentProperty(definition.getInternalName());
JacksonProperty jacksonProperty = new JacksonProperty(jackson, prop, definition);
// First pass, early drops to avoid unnecessary calculation
if (prop.isPresent()) {

View File

@@ -144,7 +144,7 @@ class WrappedProperties {
for (BeanPropertyDefinition property : getMappedProperties(entity)) {
Optionals.ifAllPresent(entity.getPersistentProperty(property.getInternalName()), //
Optionals.ifAllPresent(Optional.ofNullable(entity.getPersistentProperty(property.getInternalName())), //
findAnnotatedMember(property), //
(prop, member) -> {
@@ -194,7 +194,7 @@ class WrappedProperties {
for (BeanPropertyDefinition property : properties) {
Optionals.ifAllPresent(findAnnotatedMember(property), //
entity.getPersistentProperty(property.getInternalName()), //
Optional.ofNullable(entity.getPersistentProperty(property.getInternalName())), //
(member, prop) -> withInternalName.add(property));
}

View File

@@ -19,10 +19,10 @@ import java.util.ArrayList;
import java.util.List;
import org.springframework.data.mapping.Association;
import org.springframework.data.mapping.MappingException;
import org.springframework.data.mapping.PersistentProperty;
import org.springframework.data.mapping.SimpleAssociationHandler;
import org.springframework.data.mapping.context.PersistentEntities;
import org.springframework.data.mapping.model.MappingException;
import org.springframework.data.rest.core.Path;
import org.springframework.hateoas.Link;
import org.springframework.hateoas.Links;

View File

@@ -25,12 +25,12 @@ import java.util.Collections;
import java.util.List;
import org.springframework.data.mapping.Association;
import org.springframework.data.mapping.MappingException;
import org.springframework.data.mapping.PersistentEntity;
import org.springframework.data.mapping.PersistentProperty;
import org.springframework.data.mapping.PersistentPropertyAccessor;
import org.springframework.data.mapping.SimpleAssociationHandler;
import org.springframework.data.mapping.context.PersistentEntities;
import org.springframework.data.mapping.model.MappingException;
import org.springframework.data.rest.core.Path;
import org.springframework.data.rest.core.mapping.ResourceMapping;
import org.springframework.data.rest.core.mapping.ResourceMetadata;
@@ -216,16 +216,20 @@ public class LinkCollector {
PersistentProperty<?> property = association.getInverse();
accessor.getProperty(property).ifPresent(it -> {
Object value = accessor.getProperty(property);
ResourceMetadata metadata = associations.getMappings().getMetadataFor(property.getOwner().getType());
ResourceMapping propertyMapping = metadata.getMappingFor(property);
if (value == null) {
return;
}
for (Object element : asCollection(it)) {
if (element != null)
links.add(getLinkFor(element, propertyMapping));
ResourceMetadata metadata = associations.getMappings().getMetadataFor(property.getOwner().getType());
ResourceMapping propertyMapping = metadata.getMappingFor(property);
for (Object element : asCollection(value)) {
if (element != null) {
links.add(getLinkFor(element, propertyMapping));
}
});
}
}
/**

View File

@@ -169,8 +169,8 @@ public final class ETag {
PersistentPropertyAccessor accessor = entity.getPropertyAccessor(bean);
return entity.getVersionProperty()//
.flatMap(it -> accessor.getProperty(it))//
return Optional.ofNullable(entity.getVersionProperty())//
.map(it -> accessor.getProperty(it))//
.map(Object::toString);
}
}