Removed a bit of reflection from ApplicationContext interaction. Some generics tweaks to avoid unnecessary casts and compiler warnings. Static methods where possible. JavaDoc polish in ProjectingJackson2HttpMessageConverter.
Added a test for loading of QuerydslPredicateArgumentResolver, but it fails presumably because EnableSpringDataWebSupport is not in effect.
Renamed SpringDataWebConfigurationUnitTests to SpringDataWebConfigurationIntegrationTests since it is actually an integration test.
Related ticket: DATACMNS-993.
ProxyingHandlerMethodArgumentResolver is now more lenient when it comes to which types to support for proxying. As indicated in the ticket, we've been to aggressive opting in for all interfaces which - depending on the order of converter registrations - caused us interfering with other interface based resolutions (e.g. in Spring Mobile, Security etc.).
We now only aggressively kick in if either the type or parameter is annotated with @ProjectedPayload or the type itself is not a Spring Framework or native Java one. This should leave user defined types still be accepted whereas the types we previously erroneously interfered with should now be ignored.
Both the configuration code looking up Spring Data specific Jackson modules as well as the code detecting whether we have multiple Spring Data modules on the classpath used component scanning. That can have quite significant impact on startup times.
This commit replaces the classpath scanning with the use of SpringFactoriesLoader that now requires modules that want to extend the behavior of Spring Data's web configuration or indicate a repository implementation being present by shipping a file called META-INF/spring.factories. Spring Data relies on the following keys:
- org.springframework.data.web.config.SpringDataJacksonModules - list the Spring configuration classes that will expose additional Jackson modules that are supposed to be registered for Spring Data's Jackson web support
- org.springframework.data.repository.core.support.RepositoryFactorySupport - list the Spring Data repository factory implementation class that implements repository support for your module. The general detection and configuration mechanism for user repositories is not affected by this. Currently Spring Data only uses the pure number of different entries for that key to switch into strict configuration mode in case we find more than one entry.
PageableHandlerMethodArgumentResolver.isFallbackPageable() now correctly guards against the fallback Pageable being null, a situation that's explicitly deemed valid in setFallbackPageable(…).
After the Spring 5 build profile has been activated properly in Spring Data build [0], the test cases for RepositoryPopulators failed as there was only an explicit detection of Spring 4 to point the test to the right resource file. Removed the guard now as all supported versions can now use the same file.
Adapt to the stricter contract in Spring 5's MethodParameter in unit test for QuerydsPredicateArgumentResolver.
[0] 31df5de907
Changed the implementation of both the JSON Path and XPath based projecting HttpMessageConverters to make sure the cached decisions don't depend on the media type. Reuse the evaluation of the media type in AbstractHttpMessageConverter.
When a recursive decent operator is used in a JSON Path expression there's no way to get out of the array mode again to indicate one is interested in a particular element (e.g. "the first one no matter where in the document") [0]. We now work around this by always letting the parser return lists, so that the mapping library finally kicking in can be equipped with the correct target type to create.
Unfortunately this causes arrays to be double-wrapped for definite paths so that we basically have to adapt the type handed to Jackson in another round to the unwrap the mapping result in turn [1].
[0] https://github.com/jayway/JsonPath/issues/248
[1] https://github.com/jayway/JsonPath/issues/249
Projection types annotated with @ProjectedPayload can now be used as parameters for @RequestBody annotated Spring MVC controller method parameters.
Accessor methods will be translated into JSON path property expressions which can be customized by using the @JsonPath annotation. The methods are allowed to return simple types, nested projection interfaces or complex classes which will will be mapped using a Jackson ObjectMapper.
Introduced a template method to override the creation of a PagedResource to allow subclasses to create a more concrete instance than PagedResource itself.
If a single path is now handed to QuerydslBindings.bind(…), a specialized AliasingPathBinder is returned which allows defining an alias the binding will be exposed under.
By default that alias will cause the original binding being black-listed and thus become unavailable for binding. This can be overridden by explicitly white-listing the properties to be bindable.
Switched to new Querydsl 4 artifacts and adapted to changed package names and API changes.
Cleaned up some JavaDoc and APIs in QuerydslBindingsFactory and QuerydslBinderCustomizer.
We now correctly inspect the sort parameter values and also fall back to the default if a single, empty parameter value is given.
Related ticket: DATACMNS-408.
Related pull request: #138.
QuerydslBindingsFactory creates a completely build up and customized QuerydslBindings instance for a given QuerydslBinderCustomizer type and domain type.
This basically involves creating or obtaining an instance of the customizer with the following algorithm:
1. If an explicit customizer type is given and no BeanFactory is configured, we'll simply instantiate the configured type. This allows simple customizer implementations with a no-arg constructor.
2. If a BeanFactory is configured and a customizer type configured, we're trying to locate a bean of that type in the BeanFactory, falling back to creating an instance of the customizer through the BeanFactory if no existing bean definition can be found. This allows unique customizer bean definitions or complex prototype scoped customizer beans created on the fly.
3. If no customizer type is configured, we check whether the the repository of the domain type implements QuerydslBinderCustomizer and use it if so.
The extraction of that functionality allows that algorithm being used by Spring Data REST, although only step 3 is currently used there as no explicit customizer can currently be configured with Spring Data REST.
Introduced dedicated querydsl.bindings package to contain all non-web projects to make sure domain types and repositories don't have to depend on types in a web package.
Updated Sonargraph architecture description accordingly.
Original pull request: #132.
Mostly Javadoc. Removed all API that took String paths so far.
Changed return type of bean definition for QuerydslPredicateArgumentResolver to HandlerMethodArgumentResolver so that Querydsl stays optional during class loading.
Original pull request: #132.
If no QuerydslBinderCustomizer is configured on @QuerydslPredicate specifically, we now also consider the domain types repository as candidate for binding customization.
The lookup algorithm for explicitly configured customizers has been refined to try to find a bean in the BeanFactory first, resorting to on-the-fly creation eventually.
QuerydslPredicateArgumentResolver is now registered as a lazily initialized bean and its usage is guarded by checking presence of Querydsl itself.
The according test needs to do some reflection in order to stay out of trouble when types are loaded by different class loaders required to hide certain types.
Original pull request: #132.
Javadoc on MultiValueBinding. Hide QuerydslBindings.bind(…), ….include(…) and ….exclude(…) methods that take String arguments to reduce the probability of no query class being present.
Refined the value handling for empty request values which are represented as String[] containing an empty String. We now massage those into an empty Collection for MultiValueBindings and a null value for SingleValueInvocations.
We currently skip property values that match this pattern entirely but are prepared to allow a configuration flip switch to handle those scenarios in the future. We currently stick to skipping those values to prevent the bindings from having to deal with null values.
We now also allow the bindings to return null to indicate they don't want to get applied in the resulting predicate at all.
Switched to interface based customization to make it easier to use customizations with Spring Data REST. Added Querydsl-specific adapter of RepositoryInvoker to allow Spring Data REST to hook in the execution of the predicate obtained from request parameters.
Original pull request: #132.
We now ignore invalid PropertyPaths on property binding to Querydsl Predicates. Those may occur since the request also holds non-property-related arguments, such as pagination parameters.
Fixed two potential NullPointerExceptions along the way since we no longer depend on the presence of @QuerydslPredicate.
Original pull request: #132.
QuerydslBindings now uses a builder style pattern to define custom bindings. This allows to define the same binding for multiple properties of the same type in one configuration call.
Introduced MultiValueBinding to be able to register a binding for multiple source values (i.e. if multiple values are provided for the same parameter). The previously named QuerydslBinding is now a SingleValueBinding which gets adapted to by extracting the first element of the values provided considered as collection.
Slightly refined the generics signature in QuerydslBinding for better type derivation in Lambdas. Removed the need for QuerydslBindingContext by moving a few properties around. The ConversionService instance is now piped into the QuerydslPredicateBuilder directly.
Added a bit of sample data to the Users test domain type to be able to execute the generated Predicates in tests to validate their correctness.
Original pull request: #132.
Adding @QuerydslPredicate to a parameter within SpringMVC Controller when having registered the QueryDslPredicateArgumentResolver allows to generate a Querydsl Predicate based on the request parameters.
Parameters will be converted into their corresponding property types before using the as predicate value. Given more than one attribute will connect those using 'and'. Collections of values will force usage of 'in' while single values on collection like properties result in 'contains'.
The base type for building the Querydsl Path is extracted from the methods return type. In case of non domain type return values it can optionally be specified via @QueydslPredicate(root = …). Specific Predicate conversions can be registered via '@QuerydslSpecification'.
This allows to sneak in specific property path handlings more easily.
new QueryDslPredicateSpecification() {
{
define(new StringPath("address.city"), (path, value) -> path.like(value.toString()));
}
};
Renamed resolver, accessor etc. to express operation of binding properties to a resolved path and introduced explicit binding context which allows reuse of predicate builder within the ArgumentResolver.
Added registration of QuerydslPredicateArgumentResolver directly in SpringDataWebConfiguration reusing the provided ConversionService.
Added Javadoc and changed visibility of non public API and types.
Original pull request: #132.
We now always render both first and last links in case the page returned is navigable, which essentially means: whenever the result spans across more than one page. I.e. whenever either a next or prev link will be rendered, both first and last links are rendered, too.
Clients can still reason about the fact whether they're on the first or last page by the non-presence of prev (indicates you're on the first page) or next (indicates you're on the last page).
We now add first and last links to the PagedResources created in line with the appearance of the prev and next links. The PagedResourcesAssembler can be configured to enforce the rendering using setForceFirstAndLastRels(…).
PagedResourcesAssembler now creates the self, prev and next links for a PagedResource to be canonical and not contain any template parameters. This is to make sure a client can not actually tweak the links and follow a link that's not strictly conforming to semantics of the rel.
In case the PageableHandlerMethodArgumentResolver was configured to use one-indexed parameters, it wasn't defaulting the lower bounds for the page number. This caused indexes out of the allowed bound submitted causing an invalid index handed tor PageRequest. We now apply better range shifting before the bounds are applied.
Introduced @SpringDataWebConfigurationMixing that can be used on configuration classes that are supposed to contribute components to the Application context when @EnableSpringDataWebSupport is used.
SpringDataWebConfigurationImportSelector scans the org.springframework.data package for classes annotated with that annotation and adds them to the classes to be considered config classes.
We now ship a ProxyingHandlerMethodArgumentResolver that gets registered when @EnableSpringDataWebSupport is activated. It creates Map-based proxy instances for interfaces used as Spring MVC controller method parameters.
Ported Spring Data REST's converters for Distance and Point and turned them into Formatter instances. Extended Metric interface to return an abbreviation. Added getUnit() to Distance and tweaked Jackson setup to ignore the additional property.
We now automatically register the news introduced Formatters when using @EnableSpringDataWebSupport so that Point and Distance values can be parsed and printed from and to Strings out of the box.
We're now using the newly introduced method on ControllerLinkBuilderFactory that takes both a type and a method to forward the method the invocation is happening on independently from the method being invoked.
We now explicitly check for the configured default being null and subsequently return that value if we don't have both the page and the size parameter configured.
Added a JavaConfig class to declare a Spring bean for the newly introduced GeoModule.
@EnableSpringDataWebSupport automatically registers this config class in case Jackson is on the classpath. This comes in handy in combination with Spring Boot which auto-registers all global Module beans with all global ObjectMappers.
Removed support for Jackson 1 based repository populators in favor of Jackson 2 based ones. Removed PageableArgumentResolver in favor of PageableHandlerMethodArgumentResolver. Removed legacy setup code of the new HandlerMethodArgumentResolver implementations.