Using ResourceProcessors again now as some kind of middle ground between the two former design ideas. We use a value returning callback now to allow manipulating the ResourceSupport instance in its entirety. This enables implementations to be either mutable or immutable. The ResourceProcessor interface is a little less flexible than in the first iteration as we require the same type to be returned.
ResourceEnricherInvokingHandlerAdapter now has a copy constructor to
allow setting it up from a default RequestMappingHandlerAdapter. The
reason we introduce this is that WebMvcConfigurationSupport unfortunately
does not allow customizing the handler adapter class to be used as its
instantiations is buried in a method with more setup code. With the copy
constructor introduced one can simply take the configured instance
WebMvcConfigurationSupport provides and pipe it into the custom
ResourceEnricherInvokingHandlerAdapter.
Dropped usage of separate interface for ResourceProcessor and
ResourcesProcessor and go with general ResourceEnricher interface. The
custom HandlerAdapter now also invokes enrichers for Resources' content
elements before invoking enrichers for the Resources instance itself.
This commit implements the components described in DATAREST-40. The core
of it is the ResourceProcessingHandlerMethodReturnValueHandler. It gets
ResourceProcessor and ResourcesProcessor instances handed into its
constructor and selects the ones that need to be invoked in the calls to
handleReturnValue(…). In this process it does a variety of generics
checks to ensure only the correct post-processors. To do so it inspects
the controller method's return type, the object value type as well as
the returned value potentially.
Assume we have a specialized Resource type
StringResource extends Resource<String>. Beyond that we have a
ResourceProcessor<Resource<String>> registered. Here's the decision
matrix:
Return type Returned type What get's used?
Resource<?> Resource<String> object value inspected (Resource.getContent())
Resource<String> Resource<String> method return type
Resource<String> StringResource object value type as it's more specialized
StringResource StringResource method return type
Resource<?> Resource<Long> no invocation, object value doesn't match
Resource<? extends Number> Resource<Long> no invocation, object value doesn't match
Resource<Long> Resource<Long> no invocation, object value doesn't match
This works exactly the same for Resources returned. We peek into the
collection returned by getContent() in case return value inspection is
needed for type matches. If the collection is empty we don't match. The
same applies to null values returned.
The second component added is the ResourcePostProcessorInvokingHandlerAdapter
which customizes the setup of a RequestMappingHandlerAdapter by fronting
the current configuration with the
ResourceProcessingHandlerMethodReturnValueHandler to let it intercept
the handling and potentially call the post-processors.
Upgraded to snapshots of Spring Data Commons until we get to the next
release and added Mockito as dependency.
There were some issues with how results were being displayed in searches versus entity lists. This code changes the way all results are displayed by offereing several options for output. The default is to inline the entity in the response and page the results (defaults to 20). If the UA sends an `Accept` header of `application/x-spring-data-compact+json` or `text/uri-list`, however, SD REST will output a compact list of only links and will not inline the entities.
The method of output was completely rewritten to use HttpMessageConverters exclusively. Views and the subsequent ContentNegotiatingViewResolver machinery have been elimintated. This should make it easier to embed inside an existing Spring MVC application. This is also easily extendable so the user can plug in their own set of HttpMessageConverters for any output format they like (JAXB, Atom/XML, etc...).
Also added was JSONPE support. By setting the `jsonpParamName` property on the `RepositoryRestConfiguration` customization class, the user can change the default JSONP param name of `callback`. There's also a `jsonpOnErrParamName` property on that configuration (defaults to `null`) that will allow you to capture errors using JSONP. Normally this would not be possible using script element injection, but the REST controller changes the status code to 200 and pass your javascript function the actual response code and wraps the error as the second parameter.
This makes it easier to integrate the RepositoryRestController into an existing Spring MVC application because all you have to do is include the RepositoryRestMvcConfiguration JavaConfig bean into your existing application.
Also included some changes to the way views are resolved so that only views starting with "org.springframework.data.rest" will be recognized as our own special views.