Commit Graph

430 Commits

Author SHA1 Message Date
Oliver Gierke
2b347daaab DATAREST-1050 - PUT for create now makes sure the resource id is set on the instance to create.
So far, we handed the plain instance deserialized from the request body to the repository to persist it. That caused issues in PUT for create scenarios where the URI contains the identifier to be used for the aggregate to create and identifier generation being used in the backend. In that case the identifier submitted was never considered and subsequent requests would've created new instances, effectively breaking the idempotent nature of PUT.

We now make sure the backend identifier derived from the resource is set on the aggregate instance about to be created, so that backend can either accept that situation (new entity + manually defined identifier) or reject it (in case it insists on identifier generation).
2017-04-11 09:10:04 +02:00
Oliver Gierke
359513fe9b DATAREST-1030 - Reinstantiate PATCH behaviour for associations.
We now completely opt out of merging values if the property is a linkable association.
2017-04-10 19:08:03 +02:00
Oliver Gierke
b9957d1a6c DATAREST-1008 - Adapt to API changes in Spring Data Commons, Java 8 upgrades and Mockito 2.7. 2017-03-24 11:02:54 +01:00
Oliver Gierke
8ad81978b0 DATAREST-995 - Removed support for ~ to reference a last collection element in JSON Patch.
Completely removed the support for ~ in favor of the previously introduced support for the correct indicator -.
2017-02-08 19:59:08 +01:00
Oliver Gierke
4e2edd2d37 DATAREST-995 - Fixed detection of collection append operations for JSON Patch requests.
We previously erroneously looked for a ~ in a JSON Pointer to indicate collection append in e.g. an add operation. We now also support the actually correct - keeping the original behavior for now to not break clients that currently make use of it.
2017-02-08 19:59:08 +01:00
Jens Schauder
ea482e0577 DATAREST-994 - Fixed two argument constructor of RepositoryRestHandlerMapping.
Repositories in RepositoryCorsConfigurationAccessor may be null now. findCorsConfiguration returns null when no repositories are provided.

Original pull request: #257.
2017-02-03 09:07:20 +01:00
Oliver Gierke
7c3bf750b3 DATAREST-944 - DomainObjectMerger now also merges associations for PUT.
We now explicitly merge associations skipping the linkable ones. We also try to reuse the existing collections and maps if they're mutable falling back to a completely new one if not.

Extracted PropertyHandler and AssociationHandler implementations.
2017-01-26 07:45:25 +01:00
Oliver Gierke
ca9d7f7b1d DATAREST-977 - Fixed reading of complex enums on collection expansion for PATCH.
When merging collections on PATCH we now don't use the first collection item's type for all elements but inspect the values for each existing element found. When it comes to appending elements to the collection, wen now just stick to the declared component type as type hint for reading the provided value.
2017-01-24 16:15:15 +01:00
Oliver Gierke
fe1c4b1e1c DATAREST-957 - Improved PUT handling for transient properties not backed by a field.
When copying the transient properties of an aggregate, we now try field based access first and fall back to accessor based copying in case both a setter and getter are exposed on the type.

Previously we always expected a field to be present which doesn't necessarily has to be the case.

Related ticket: DATAREST-986.
2017-01-24 13:22:04 +01:00
Oliver Gierke
08f012d4aa DATAREST-965 - Switched to property based application of PUT requests.
Jacksons ObjectMapper.readerForUpdate(…) unfortunately doesn't handle nested objects properly. We already have a manual merge process in place for PATCH requests but tweaking that to also handle PUT requests gracefully caused more complexity than anticipated.

We now switched to an object based merge so that we can read in the source JSON structure into a new object and then merge the objects.

Related pull request: #247.
2017-01-23 16:42:41 +01:00
Oliver Gierke
96ff0cb465 DATAREST-986 - DomainObjectReader now merges complex nested maps correctly.
We now use a Map property's generic type information to make sure we convert both the key and the value into the declared types. Previously we just used Object if the source value to map was null. Object is still used as fallback for raw maps though.
2017-01-23 09:30:49 +01:00
Oliver Gierke
2ad00c0dd7 DATAREST-982 - Adapt to changes in Jackson default time rendering in test case.
We now configure a more explicit pattern to verify the ISO date rendering of Jackson.
2017-01-16 17:27:42 +01:00
Mark Paluch
69c39377ec DATAREST-976 - Embedded properties are now considered in sort property paths.
We now allow sorting by properties of embedded objects. An embedded object is not linkable to a root object but embedded in the resource itself. If any part of the sort property path points to a linkable association, the whole sort property path is discarded silently and not used for sorting any further.

Original pull request: #251.
2017-01-16 13:36:15 +01:00
Mark Paluch
6bb989018c DATAREST-978 - Migrate ticket references in test code to Spring Framework style. 2017-01-13 10:09:53 +01:00
Oliver Gierke
c03653b7e9 DATAREST-959 - Polishing.
Skip all merge logic if the source value is null. That frees all nested logic from handling with that case and us falling back to plain Jackson reading.

The array handling now also opts out if the source value is not a collection or array in the first place as it means we need to let Jackson override the value with the collection given to be deserialized.

Original pull request: #246.
2016-12-13 10:09:02 +01:00
Milos Cubrilo
0b1bbbab31 DATAREST-959 - Fix adding elements to empty array in DomainObjectReader.
Original pull request: #246.
2016-12-13 10:09:00 +01:00
Oliver Gierke
aa7eec4683 DATAREST-835 - Search resources returning a single resource now get and consider ETag and Last-Modified headers.
We now interpret If-None-Match and If-Modified-Since headers on requests to resources backed by query methods returning a single instance only. This allows clients to optimize GET requests to those resources to save bandwidth.
2016-12-08 21:35:37 +01:00
Oliver Gierke
c0df12d9fa DATAREST-956 - Polishing.
Some tiny refactorings in DomainObjectReader. We're now using TypeInformation instead of Class to preserve more generics information when it comes to deeper nesting.

Moved some code around in the unit tests.

Original pull request: #245.
2016-12-08 09:49:17 +01:00
Mathias Düsterhöft
667576c661 DATAREST-956 - Fixed handling of collection element addition and removal for PUT requests.
DomainObjectMerger now properly adds and removes elements to and from collections.

Original pull request: #245.
2016-12-08 09:48:20 +01:00
Oliver Gierke
6c99760621 DATAREST-953 - Added test case to verify this is fixed.
Seems the change for DATAREST-938 has also fixed this one. Added a test case similar to what was provided in the example for the original ticket.
2016-12-07 18:50:44 +01:00
Oliver Gierke
e7c4b2176e DATAREST-938 - Polishing.
Formatting and author.

Original pull request: #241.
2016-12-07 18:50:42 +01:00
Craig Andrews
b859b8b91f DATAREST-938 - Update nested entities instead of replacing them with new instances.
Original pull request: #241.
2016-12-07 18:50:38 +01:00
Oliver Gierke
a4f88fe1ac DATAREST-910 - Polishing.
Minor code reorganizations. Eagerly create SortTranslator to avoid repeated instantiation.

Original pull request: #232.
2016-12-06 12:00:39 +01:00
Mark Paluch
0dc97dcc56 DATAREST-910 - Support nested Sort properties.
We now support nested Sort properties considering Jackson mapping. Sort translation is optional and skipped if the domain class is not resolvable. Translation in the scope of a domain class maps property paths to apply sorting using embedded properties.

A sort string `nested-name` resolves to a property path `anotherWrap.embedded.name`.

class Aggregate {

	@JsonUnwrapped
	public UnwrapEmbedded anotherWrap;
}

class UnwrapEmbedded {

	@JsonUnwrapped(prefix = "nested-")
	public Embedded embedded;
}

class Embedded {
	public String name;
}

Original pull request: #232.
2016-12-06 12:00:38 +01:00
Oliver Gierke
7855613415 DATAREST-937 - Polishing.
Moved the newly added test case to the end of the list. Formatting.

Original pull request: #240.
2016-12-06 09:38:19 +01:00
Craig Andrews
4150688851 DATAREST-937 - Transient properties in JSON are now included in merge.
We now don't prematurely drop fields that don't have a persistent property exposed in DomainObjectReader. Doing so dropped values for transient fields as the latter are not exposed as persistent property in the first place. We still skip any nested merging though.

Original pull request: #240.
2016-12-06 09:38:19 +01:00
Oliver Gierke
7329e20fa8 DATAREST-919 - Merging of nested maps for PUT/PATCH requests now handles nested arrays and simple types. 2016-11-03 16:19:46 +01:00
Oliver Gierke
68d0a1aa6a DATAREST-931 - Polishing.
Switched to non-deprecated property naming strategy in test case.
2016-11-03 09:13:52 +01:00
Oliver Gierke
50d2678d01 DATAREST-931 - DomainObjectMerger now handles arrays with complex objects correctly.
We now explicitly manually merge array nodes that contain complex objects. Previously arrays would've been skipped and the subsequent Jackson update would wipe out all properties not contained in the original document even on PATCH requests.
2016-11-02 13:40:54 +01:00
Oliver Gierke
40bb8e8e6c DATAREST-573 - Polishing.
Removed RepositoryRestConfiguration.addCorsMapping(…) as we currently don't have any other shortcut methods for configuration like this.

Tweaked the setup of (now Repository)CorsConfigurationAccessor to be created earlier so that we avoid recreation for every lookup. Introduced a NoOpStringValueResolver to be used by default so that we don't need to deal with the case of the resolver being null at the end of the call chain. Replaced constructor of RepositoryCorsConfigurationAccessor with corresponding Lombok annotation.

Updated reference documentation accordingly.

Original pull request: #233.
2016-10-28 14:19:26 +02:00
Mark Paluch
a3870ca528 DATAREST-573 - Add support for new CORS configuration mechanisms introduced in Spring 4.2.
We now support CORS configuration mechanisms introduced in Spring 4.2. CORS can be configured on multiple levels: Repository interface, Repository REST controller and global level. Spring Data REST CORS configuration is isolated so Spring Web MVC'S CORS configuration does not apply to Spring Data REST resources.

 Multiple configuration sources are merged so different aspects of CORS can be configured in separate locations.

@CrossOrigin
interface PersonRepository extends CrudRepository<Person, Long> {}

@RepositoryRestController
@RequestMapping("/person")
public class PersonController {

	@CrossOrigin(maxAge = 3600)
	@RequestMapping(method = RequestMethod.GET, "/xml/{id}", produces = MediaType.APPLICATION_XML_VALUE)
	public Person retrieve(@PathVariable Long id) {
		// ...
	}
}

@Component
public class SpringDataRestCustomization extends RepositoryRestConfigurerAdapter {

  @Override
  public void configureRepositoryRestConfiguration(RepositoryRestConfiguration config) {

    config.addCorsMapping("/person/**")
        .allowedOrigins("http://domain2.com")
        .allowedMethods("PUT", "DELETE")
        .allowedHeaders("header1", "header2", "header3")
        .exposedHeaders("header1", "header2")
        .allowCredentials(false).maxAge(3600);
  }
}
2016-10-28 14:19:26 +02:00
Oliver Gierke
b4f99b83a0 DATAREST-929 - EnumTranslatingDeserializers now handles container types correctly.
When translating enumerations, we now inspect the property and use a container type's value type as translation target.
2016-10-26 11:50:27 +02:00
Oliver Gierke
a516d8e61f DATAREST-575 - Fixed property lookup in MappedProperties.
Previously, MappedProperties didn't handle Jackson properties correctly, that do not expose a PersistentProperty, e.g. transient ones. That led to potential nullPointerExceptions in clients as the guarding hasPersistentPropertyForField(…) still answered true, as the backing cache contained an entry with a null value. We now skip those properties completely.
2016-10-23 20:36:59 +02:00
Mark Paluch
b436662304 DATAREST-906 - Consider default Pageable even if Sort is empty.
We now resolve default configured Pageable without dropping them if their Sort is empty. Previously, any default Pageable was dropped if its Sort was empty which caused null being handed to controller methods of @RepositoryRestController instances.

Original pull request: #231.
2016-09-23 15:20:56 +02:00
Oliver Gierke
216e267fce DATAREST-883 - Polishing.
Switched to use @RequiredArgsConstructor where possible. Slightly rearranged test cases. Inlined JacksonMappingAwareSortTranslator to not expose it as bean unless necessary. Use static Jackson BeanClassIntrospector to avoid unnecessary recreation.

Original pull request: #222.
2016-09-19 08:05:45 +02:00
Mark Paluch
a999bd3ca8 DATAREST-883 - Consider Jackson field names in Sort mapping.
We now consider Jackson field names when resolving Sort arguments. Domain model properties annotated with @JsonProperty("sales") can be specified by their Jackson-mapped field name in sort arguments. Field names are mapped to their according persistent property names to be used in repository query method sorting. Unknown field names are silently dropped.

Original pull request: #222.
2016-09-19 08:05:45 +02:00
Oliver Gierke
1c70b9175d DATAREST-889 - Polishing.
Improved test cases by using JUnit's ExpectedException for simpler assertions.

Original pull request: #227.
2016-09-14 10:16:22 +02:00
Oliver Trosien
48125faea3 DATAREST-889 - JsonPatchPatchConverter explicitly rejects unknown paths and values.
JsonPatchPatchConverter now explicitly rejects problematic JSON Patch payloads (e.g. incorrect paths, incorrect values) throwing a PatchException.

Original pull request: #227.
2016-09-12 16:08:32 +02:00
Oliver Gierke
1513482b9c DATAREST-885 - Polishing.
Original pull request: #226.
2016-09-12 13:00:48 +02:00
Oliver Trosien
1fd9a03c68 DATAREST-885 - Support array values in JsonPatchPatchConverter.
Original pull request: #226.
2016-09-12 13:00:02 +02:00
Oliver Gierke
2710b988b5 DATAREST-885, DATAREST-885 - Cleanups in JSON Patch code. 2016-09-12 11:20:49 +02:00
Oliver Gierke
2493d3c2f1 DATAREST-885 - Polishing.
Formatting. Copyright ranges.
2016-09-12 11:02:15 +02:00
Mathias Düsterhöft
518cab040f DATAREST-885 - PatchOperation now evaluates SpEL expression.
Original pull request: #223.
2016-09-12 11:01:48 +02:00
Oliver Gierke
3643e06b1f DATAREST-887 - Polishing.
Code formatting. Author tags. Assertions in Constructor. JavaDoc.

Original pull request: #224.
2016-09-12 10:47:50 +02:00
Mathias Düsterhöft
0a6dcc9825 DATAREST-887 - JsonPatchPatchHandler now uses external ObjectMapper.
The previously static ObjectMapper used by JsonPatchPatchHandler now has to be provided by clients instantiating the handler.

Original pull request: #224.
2016-09-12 10:47:13 +02:00
Oliver Gierke
72e4ef025d DATAREST-837 - DomainObjectMerger doesn't nullify read-only properties on PUT.
PUT requests are supposed to replace the state of the resource with the request payload. However, Spring Data REST already handles a couple of domain object propoerties in a special way as theri values map to dedicated HTTP features: identifiers (URIs), last-modified dates (header) etc.

For users, it might be worthwhile to exclude other properties from being set by applying the payload, like properties that are completely under the control of the server, e.g. creation user and date, last modifying user etc. So far, users didn't have any means to exclude those properties as the handling of PUT requests treated every missing property of the payload as null value.

DomainObjectMerger now checks whether a property is actually writable before applying the implicit null value. The application can be disabled by annotation a property with @ReadOnlyProperty.
2016-08-18 13:07:02 +02:00
Oliver Gierke
344c3ac840 DATAREST-863 - Adapt to changes in Accept header lookup in Spring 4.3.
Spring 4.3's HeaderContentNegotiationStrategy switched from looking up the Accept header via the method returning a single (potentially comma separated) one to the method returning multiple headers in the first place. We now added an override of HttpServletRequestWrapper.getHeaders(…) to out custom adapter defaulting the media type to make sure the defaulting is visible and thus the right handler methods are looked up.

That previously missing caused the DelegatingHandlerMapping selecting the redirect to the HAL browser in case a request to the API root was sent without an accept header as the defaulting of the header to application/hal+json wasn't properly exposed anymore and the redirect to the browser — declaring a produces clause of text/html — was not causing any media type mismatch anymore.
2016-08-04 21:15:19 -07:00
Oliver Gierke
9e5fd30c68 DATAREST-837 - Move to ResourceProcessor invcation infrastructure in Spring HATEOAS.
Deprecated the ResourceProcessor invoking infrastructure in place here in favor of the types moved to Spring HATEOAS. Refactored our codebase to make use of these newly introduced types right away.

Related tickets: spring-projects/spring-hateoas#362.
2016-06-10 21:33:33 +02:00
Oliver Gierke
4bec3229b5 DATAREST-809 - Fixed application of explicit projections for excerpts.
A refactoring in the course of the 2.5 development dropped the application of explicit projection in case of excerpts being requested. This particularly applies to collection resources with explicit projection requests which need to get the explicit projection applied over the default excerpt projection potentially registered.

This is now fixed by the explicitly selected projection (if existing) always trumping the excerpt one.
2016-04-14 20:11:44 +02:00
Oliver Gierke
c8abdf0139 DATAREST-805 - ValidationError nor exposes rejected value as is.
Previously ValidationError captured the toString() variant of the rejected value. We now return the rejected value as is.
2016-04-14 20:11:40 +02:00