DATAREST-1104 - Adapt to API changes in mapping subsystem.
This commit is contained in:
committed by
Mark Paluch
parent
069869a69b
commit
2ad963074c
@@ -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);
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -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> {
|
||||
|
||||
@@ -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\" }")
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
@@ -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()) {
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user