DATAREST-95 - General overhaul of HTTP method handling.

Code polishing in DomainObjectMerger and related test cases. Fixed the related test cases. Cleanups in ControllerUtils to remove unneeded constants and make sure we really render no content for empty responses.

Refactorings in controller classes to reduce code duplication. We now do not allow POST requests for partial updates to property reference resources anymore but require the usage of PATCH.

Tweaked test helper methods to correctly implement basic interaction patterns.

Related pull request: #127.
This commit is contained in:
Oliver Gierke
2014-02-14 13:20:03 +01:00
parent d65179ccc8
commit b3b091e309
11 changed files with 204 additions and 203 deletions

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2012-2013 the original author or authors.
* Copyright 2012-2014 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -15,6 +15,8 @@
*/
package org.springframework.data.rest.core.support;
import static org.springframework.data.rest.core.support.DomainObjectMerger.NullHandlingPolicy.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.convert.ConversionService;
import org.springframework.data.mapping.Association;
@@ -60,10 +62,11 @@ public class DomainObjectMerger {
*
* @param from can be {@literal null}.
* @param target can be {@literal null}.
* @param nullPolicy how to handle {@literal null} values in the source object.
*/
public void merge(Object from, Object target, final MergeNullPolicy nullPolicy) {
public void merge(Object from, Object target, final NullHandlingPolicy nullPolicy) {
if (null == from || null == target) {
if (from == null || target == null) {
return;
}
@@ -87,10 +90,12 @@ public class DomainObjectMerger {
return;
}
if (!ObjectUtils.nullSafeEquals(sourceValue, targetValue)) {
if (nullPolicy == MergeNullPolicy.APPLY_NULLS || sourceValue != null) {
targetWrapper.setProperty(persistentProperty, sourceValue);
}
if (ObjectUtils.nullSafeEquals(sourceValue, targetValue)) {
return;
}
if (nullPolicy == APPLY_NULLS || sourceValue != null) {
targetWrapper.setProperty(persistentProperty, sourceValue);
}
}
});
@@ -106,7 +111,8 @@ public class DomainObjectMerger {
PersistentProperty<?> persistentProperty = association.getInverse();
Object fromVal = fromWrapper.getProperty(persistentProperty);
if (null != fromVal && !fromVal.equals(targetWrapper.getProperty(persistentProperty))) {
if (fromVal != null && !fromVal.equals(targetWrapper.getProperty(persistentProperty))) {
targetWrapper.setProperty(persistentProperty, fromVal);
}
}
@@ -114,13 +120,9 @@ public class DomainObjectMerger {
}
/**
* A switch on whether or not to ignore nulls.
* NOTE: This could have been a simple boolean flag but the enumerated value clearly
* denotes which version is being used.
* Strategy to express whether {@literal null} values should be ignored or set on the target domain object.
*/
public static enum MergeNullPolicy {
public static enum NullHandlingPolicy {
APPLY_NULLS, IGNORE_NULLS;
}
}

View File

@@ -22,5 +22,5 @@ package org.springframework.data.rest.core.util;
*/
public interface Function<S, T> {
T apply(S input);
T apply(S input) throws Exception;
}

View File

@@ -17,6 +17,7 @@ package org.springframework.data.rest.core.support;
import static org.hamcrest.Matchers.*;
import static org.junit.Assert.*;
import static org.springframework.data.rest.core.support.DomainObjectMerger.NullHandlingPolicy.*;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -57,7 +58,7 @@ public class DomainObjectMergerTests {
Person existingDomainObject = new Person("Frodo", "Baggins");
DomainObjectMerger merger = new DomainObjectMerger(repositories, conversionService);
merger.merge(incoming, existingDomainObject, DomainObjectMerger.MergeNullPolicy.APPLY_NULLS);
merger.merge(incoming, existingDomainObject, APPLY_NULLS);
assertThat(existingDomainObject.getFirstName(), equalTo(incoming.getFirstName()));
assertThat(existingDomainObject.getLastName(), equalTo(incoming.getLastName()));
@@ -76,7 +77,7 @@ public class DomainObjectMergerTests {
Person existingDomainObject = new Person("Frodo", "Baggins");
DomainObjectMerger merger = new DomainObjectMerger(repositories, conversionService);
merger.merge(incoming, existingDomainObject, DomainObjectMerger.MergeNullPolicy.APPLY_NULLS);
merger.merge(incoming, existingDomainObject, APPLY_NULLS);
assertThat(existingDomainObject.getFirstName(), equalTo(incoming.getFirstName()));
assertThat(existingDomainObject.getLastName(), equalTo(incoming.getLastName()));