Commit Graph

91 Commits

Author SHA1 Message Date
Oliver Gierke
d73e0a1f8f DATACMNS-1324 - Introduced extensible proxy detection infrastructure.
Introduced ProxyUtils.getUserClass(…) that by default is basically a facade for Spring's ClassUtils.getUserClass(…) but allows the registration of ProxyDetector implementations via Spring's SpringFactoriesLoader mechanism.

Moved all existing usages of ClassUtils.getUserClass(…) to ProxyUtils.
2018-05-17 16:20:11 +02:00
Oliver Gierke
ac324b22a5 DATACMNS-1275 - Introduced MappingContext.findPersistentPropertyPaths(Class<?>, Predicate<P>).
MappingContext now exposes a method to detect all property paths pointing to properties matching a given predicate.

Extracted PersistentPropertyPath creation into a dedicated factory class so that it can be tested individually. DefaultPersistentPropertyPath now exposes a ….containsPropertyOfType(…) to detect whether we've already processed a particular type in the path. Also applied a bit of Java 8 and Lombok polish.

InvalidPersistentPropertyPath now collects suggested alternatives to create a better exception message. PersistentEntities now allows to map over a MappingContext and PersistentEntity that a given type is corresponding to. Streamable now exposes an ….isEmpty(). Removed references to equivalent methods implemented in subtypes.
2018-04-09 14:31:20 +02:00
Oliver Gierke
32ea1f77c0 DATACMNS-1271 - Streamlined implementation of AnnotationBasedPersistentProperty to avoid NullPointerExceptions.
We now use the annotation cache's ….computeIfAbsent(…) to avoid inconsistencies between ….contains(…) and ….get(…) in multi-threaded scenarios.
2018-03-01 16:25:06 +01:00
Mark Paluch
4d9329fab8 DATACMNS-1249 - Fix line endings to LF. 2018-01-24 12:32:29 +01:00
Mark Paluch
7c61bdf2c8 DATACMNS-1245 - Consider Kotlin metadata annotation for Kotlin class kind retrieval.
We now inspect Kotlin's Metadata annotation to determine the kind of a Kotlin class.

Previously we used Kotlins internal API to introspect classes. Because this API is not public and can be changed at any time we rely on Kotlins annotations as they are supposed to not change in near future.

Original pull request: #269.
2018-01-19 13:38:29 +01:00
Oliver Gierke
4a2df6299b DATACMNS-1241 - Improved Lazy.
Expanded generics to make sure we can take Functions and Suppliers of sub- and supertypes properly. Added factory method to create a Lazy from a fixed value. Added method to access Optional result. Added methods to allow chaining Lazy instances via ….or(…). Reduced visibility of ….orElseGet(…) as it basically equates to ….or(…).get(Optional)().

More unit tests.
2018-01-10 12:07:31 +01:00
Oliver Gierke
dcb8166bbc DATACMNS-1235 - Polishing.
Introduced BeanLookup to easily create a Lazy<T>-based lookup of a unique bean by type on a ListableBeanFactory. This is in support of making it easy for downstream Spring Data modules to consume the EntityPathResolver declared in an ApplicationContext using XML configuration.

QuerydslWebConfiguration now uses a plain ObjectProvider to access the bean defined falling back to our default.

Original pull request: #265.
2018-01-10 12:07:31 +01:00
Mark Paluch
51e7e1b7f5 DATACMNS-1240 - Update copyright years to 2018.
Also, remove some trailing whitespaces and align outdated license header format.
2018-01-08 16:04:34 +01:00
Oliver Gierke
34cadd0b9b DATACMNS-1224 - Polishing of nullability annotations.
Refactored code to properly check for null fields in Eclipse. Added warning suppressions where suitable.
2017-11-30 00:29:32 +01:00
Oliver Gierke
3c96e4e079 DATACMNS-1158 - Polishing.
Some code reorganization, polishing of nullable annotations, JavaDoc.

Original pull request: #243.
Related issue: DATAJPA-1173.
2017-11-24 11:05:28 +01:00
Oliver Gierke
48db42ced8 DATACMNS-1180 - Polishing.
Avoid premature resolution of type in TypeDiscoverer.createInfo(…) and thereby simplify constructor in ParameterizedTypeInformation.
2017-10-27 10:47:20 +02:00
Oliver Gierke
32536067f1 DATACMNS-1197 - Polishing.
Some cleanups in KorlinReflectionUtils. Removed compiler warnings about nullability and raw types.

Original pull request: #254.
2017-10-13 17:32:44 +02:00
Mark Paluch
634d8cbbd6 DATACMNS-1197 - Resolve Kotlin interface properties for nullability inspection.
We now resolve Kotlin interface properties to inspect these for nullability. Kotlin-reflect does not resolve interface property accessors yet so we need to handle this aspect ourselves.

Related ticket: https://youtrack.jetbrains.com/issue/KT-20768.
Original pull request: #254.
2017-10-13 17:32:41 +02:00
Oliver Gierke
8ce79c1810 DATACMNS-1196 - Fixed generics lookup for nested generics in ParameterizedTypeInformation.
We now eagerly resolve a generics declaration chain, which we previously - erroneously - expected GenericTypeResolver to do for us. Simplified TypeVariableTypeInformation implementation. Renamed ParameterizedTypeUnitTests to ParameterizedTypeInformationUnitTests.
2017-10-12 18:18:18 +02:00
Mark Paluch
d9d0d594e5 DATACMNS-1171 - Limit Kotlin reflection support to regular classes.
We now only inspect regular Kotlin classes with inspection to adapt Kotlin-specific behavior. Multipart-, synthetic and unknown classes are not supported. In such cases we fall back to the JVM reflection mechanism.

Non-regular classes are typically synthetic stubs, lambdas and SAM conversion which do not represent typical domain objects but rather technical bridge code.

Original pull request: #245.
2017-09-25 12:23:30 +02:00
Mark Paluch
fcf97e1e71 DATACMNS-1157 - Enforce nullable/non-null API constraints on repository query methods.
We now validate query method invocations to check method parameters whether they accept null values and reject execution if null values are not supported. We derive nullability support from repository interfaces declared using Kotlin and Spring's NonNullApi/Nullable annotations.

We also check whether a query method can return null. If a query method returns null which isn't supposed to do so, then we throw EmptyResultDataAccessException to prevent null return values.

interface UserRepository extends Repository<User, String> {

  List<User> findByLastname(@Nullable String firstname);

  @Nullable
  User findByFirstnameAndLastname(String firstname, String lastname);
}

interface UserRepository : Repository<User, String> {

  fun findByLastname(username: String?): List<User>

  fun findByFirstnameAndLastname(firstname: String, lastname: String): User?
}

Original pull request: #241.
2017-09-21 10:23:47 +02:00
Mark Paluch
b05c4e74fb DATACMNS-1126 - Polishing.
Trailing whitespace in ReflectionUtils.

Original pull request: #233.
2017-08-25 13:04:28 +02:00
Mark Paluch
22b37800ec DATACMNS-1126 - Add class-generating entity instantiation support for Kotlin.
We now discover Kotlin constructors and apply parameter defaulting to allow construction of immutable value objects. Constructor discovery uses primary constructors by default and considers PersistenceConstructor annotations.

KotlinClassGeneratingEntityInstantiator can instantiate Kotlin classes with default parameters by resolving the synthetic constructor. Null values translate to parameter defaults.

class Person(val firstname: String = "Walter") {
}

class Address(val street: String, val city: String) {

	@PersistenceConstructor
	constructor(street: String = "Unknown", city: String = "Unknown", country: String) : this(street, city)
}

Original pull request: #233.
2017-08-25 13:04:28 +02:00
Oliver Gierke
fab854c906 DATACMNS-1138 - TypeInformation.specialize(…) now only specializes unresolved parameterized types.
Type specialization - i.e. enrichment of a raw type with a current generic context - is now only done if the current type is not yet resolved completely. This allows wildcarded target references to just fall back to the type to specialize, which will then by definition carry more generics information than the one to be specialized.
2017-08-11 16:15:54 +02:00
Oliver Gierke
756396a065 DATACMNS-1135 - Fixed generics lookup for recursively nested container references.
Revert the merging of a parent type's type variable map and only apply the locally available declared generics in case of parameterized types. Moved that augmentation into ParameterizedTypeInformation.
2017-08-03 15:39:54 +02:00
Oliver Gierke
049970874d DATACMNS-1114 - Introduced usage of nullable annotations for API validation.
Marked all packages with Spring Frameworks @NonNullApi. Added Spring's @Nullable to methods, parameters and fields that take or produce null values. Adapted using code to make sure the IDE can evaluate the null flow properly. Fixed Javadoc in places where an invalid null handling policy was advertised. Strengthened null requirements for types that expose null-instances.

Removed null handling from converters for JodaTime and ThreeTenBP. Introduced factory methods Page.empty() and Page.empty(Pageable). Introduced default methods getRequiredGetter(), …Setter() and …Field() on PersistentProperty to allow non-nullable lookups of members. The same for TypeInformation.getrequiredActualType(), …SuperTypeInformation().

Tweaked PersistentPropertyCreator.addPropertiesForRemainingDescriptors() to filter unsuitable PropertyDescriptors before actually trying to create a Property instance from them as the new stronger nullability requirements would cause exceptions downstream.

Lazy.get() now expects a non-null return value. Clients being able to cope with null need to call ….orElse(…).

Original pull request: #232.
2017-07-24 10:47:28 +02:00
Oliver Gierke
75ac90150f DATACMNS-1119 - Cache for ClassTypeInformation is now a ConcurrentReferenceHashMap. 2017-07-20 12:56:11 +02:00
Oliver Gierke
4d2cc9ab8e DATACMNS-1110 - Introduced StreamUtils.createStreamFromIterator(CloseableIterator).
This is an overload for the already existing method taking a plain Iterator so that we only apply the close callback to the Stream in the newly introduced one.
2017-07-12 10:54:11 +02:00
Oliver Gierke
24704fc4de DATACMNS-1097 - Polishing.
Updated Sonargraph architecture description. Polished imports in domain package to avoid unnecessary imports (mostly due to Javadoc references).

Removed manually declared constructor in ExampleMatcherAccessor in favor of Lombok's @RequiredArgsConstructor. Removed deprecations in type information subsystem. Moved to different way of class loading to avoid null pointer warnings in ReflectionUtils.
2017-07-06 11:38:12 +02:00
Mark Paluch
0493d131e0 DATACMNS-1101 - Remove Optional from TypeDiscoverer API. 2017-07-04 14:30:44 +02:00
Mark Paluch
b2ce4b8f1b DATACMNS-1101 - Use array to store map types in TypeDiscoverer.
Prevent iterator creation.
2017-07-04 14:30:43 +02:00
Mark Paluch
6c65c02e78 DATACMNS-1101 - Remove Optional from mapping/convert use except for caching of absence and computations that are used to populate caches. 2017-07-04 14:30:42 +02:00
Oliver Gierke
0e36b43752 DATACMNS-1026 - Polishing.
Minor refactorings here in there for clarity.

Original pull request: #217.
2017-05-17 16:20:50 +02:00
Jens Schauder
42621086fe DATACMNS-1026 - ExtensionAwareEvaluationContextProvider now returns all overloaded methods as functions.
All overloaded methods are now available in SPeL expressions. Among methods with identical argument list from different sources in the same extension (extension, root object, aliases) the last one in the order in parens wins. If there is more than one method for an application the following rules are applied: if there is one method with exact matching types in the argument list it is used, otherwise an exception is thrown.

Original pull request: #217.
2017-05-17 16:20:38 +02:00
Oliver Gierke
b5af2e9d96 DATACMNS-1020 - Improvements to revision API.
RevisionRepository now returns Optional for methods that could previously return null. Revision exposes additional methods to lookup required revision numbers and dates. Revisions now implements Streamable and exposes a ….none() factory method to create an empty instance.

AnnotationBasedRevisionMetadata now uses Lazy to lookup the fields with revision annotations. AnnotationDetectionFieldCallback now also uses Optional in places it previously returned null. StreamUtils now exposes factory methods for Collector instances producing unmodifiable List and Set instances.

Related ticket: DATACMNS-867.
2017-03-25 12:34:24 +01:00
Oliver Gierke
fe5d543ff2 DATACMNS-867 - Further refinements to Optionals.
Made ifAllPresent(…) void as the returned value is never used. Added ifPresentOrElse(…).
2017-03-24 08:00:47 +01:00
Oliver Gierke
1c60ea8d36 DATACMNS-867 - Rework utility classes.
Removed the additional methods that reflectively checked for the Stream type and whether a Method instance is a default method. Turned utility classes into interfaces where possible. Make use of Lombok's @UtilityClass where not.

Removed obsolete implementation class in StreamUtils in favor of a lambda.
2017-03-24 08:00:45 +01:00
Oliver Gierke
628dc8b9c8 DATACMNS-867 - Introduced monadic methods on Streamable.
Streamable now exposes map(…), flatMap(…) and filter(…) to allow easy conversion into new Streamables. Introduced LazyStreamable to back those implementations. Simplified implementation of methods in PartTree to use those new methods.

Changed Page and Slice map(…) method to take a Function over a Converter so that act as specialization of the newly introduced map(…) method.
2017-03-24 08:00:45 +01:00
Oliver Gierke
e861d0343b DATACMNS-867 - Additions to Lazy.
Added mapping functions to Lazy.
2017-03-24 08:00:44 +01:00
Christoph Strobl
be347eaaab DATACMNS-867 - Additional Java 8 language feature cleanup.
Make use of lambdas and method references though out the codebase. Remove no longer required generic type parameters.
Additionally remove unused imports and replace single element list initialization with dedicated singletonList.
Use Assertion overloads taking Supplier for dynamic assertion error messages.
2017-03-24 08:00:43 +01:00
Christoph Strobl
8bcd8cb3da DATACMNS-867 - Fixed glitch causing failure in PropertyDescriptor lookup for ProjectionInformation.
Re added PropertyDescriptor collection. Looks like the method got dropped during one of the rebase operations.
Additionally make use of .distinct() name collection in tests as descriptors might appear multiple times for the same property name.
2017-03-24 08:00:43 +01:00
Oliver Gierke
cc1c07ecca DATACMNS-867 - Hacking. 2017-03-24 08:00:43 +01:00
Oliver Gierke
bdd55fc7ab DATACMNS-867 - Java 8 polish of ReflectiveRepositoryInformation.
Introduced Optionals.firstNonEmpty(…) to consume a set of Suppliers until one returns a non-empty Optional.
2017-03-24 08:00:25 +01:00
Oliver Gierke
d4811e29d9 DATACMNS-867 - Second draft. 2017-03-24 08:00:23 +01:00
Oliver Gierke
cc63e5b7a4 DATACMNS-867 - First draft. 2017-03-24 08:00:23 +01:00
Christoph Strobl
3e048a6dca DATACMNS-985 - Remove references to single-argument assertion methods. 2017-01-31 18:10:40 +01:00
Oliver Gierke
a9c3b9f66f DATACMNS-940 - Support for Javaslang collections as repository return types.
Javaslang's collection and map types can now be used on repository query methods and get adapted similarly to nullable wrapper types (like JDK's Optional). Also made TypeInformation infrastructure aware of the map type so that a value type lookup gets handle correctly.
2016-12-12 20:08:19 +01:00
Oliver Gierke
c52aba358d DATACMNS-956 - Ensure consistent use of ClassTypeInformation.from(…). 2016-12-12 17:09:35 +01:00
Oliver Gierke
5d591db848 DATACMNS-836 - Polishing.
RepositoryMetadata now exposes an ….isReactiveRepository() that's implemented by inspecting the backing repository interface for any reactive wrapper type appearing in method signatures. That allows us to move down the use of a ConversionService down to ReactiveRepositoryInformation.WrapperConversionMatch.

Made a couple of methods static that could be. Simplified some logic using streams. A bit better wording in assertions. Some formatting when using streams.
2016-11-14 15:41:54 +01:00
Mark Paluch
2b14d1ea54 DATACMNS-899 - Fix recursion in ParameterizedTypeInformation.getMapValueType().
Previously, calls to ParameterizedTypeInformation.getMapValueType() caused an infinite recursion when invoked on a type information that was not a map type. This lead to a StackOverflowError.

We now call the super method doGetMapValueType() instead of calling the entry super method getMapValueType() and return by that null in case the map value type is not resolvable.

Original pull request: #176.
2016-09-01 17:28:10 +02:00
Oliver Gierke
4fa84fc983 DATACMNS-896 - Improved detection of type variable mappings in recursively nested generics.
If the same generic type was used on recursively nested generics declarations, like this:

class GenericType<T> {}

class Nested extends GenericType<String> {}

class Concrete extends GenericType<Nested> {}

our traversal of the generics discovered T bound to String in Nested and as that is extending GenericType as well, the T detected here is the same instance as the T within the map discovered for Concrete. As we previously added the nested types after we added the original entry, the nested discovery overwrote the more local one.

We now make sure the detected nested type variable mappings don't overwrite already existing ones.
2016-08-19 19:49:24 +02:00
Pascal Grün
ce2e788374 DATACMNS-869 - Fix Javadoc for parametric types of Pair.
Original pull request: #164.
2016-06-11 18:21:20 +02:00
Oliver Gierke
65bfd5b33a DATACMNS-743 - Optimizations in TypeDiscoverer getProperty(…) in case if invalid property names.
We now also cache a failed property lookup so that we can return null on a subsequent call for the same invalid property name right away and don't have to reattempt the lookup unnecessarily.
2016-06-01 18:38:58 +02:00
Oliver Gierke
fa7ab50c5f DATACMNS-855 - Fixed generic type lookup in SyntheticParamterizedType.
The translation of the list of actual type parameters into an array now uses the loop index correctly. Previously, it always used the first type parameter.
2016-05-13 11:32:31 +02:00
Oliver Gierke
9db6278e77 DATACMNS-855 - Prevent memory leak in SyntheticParameterizedType.
Added proper equals(…) and hashCode() methods to SyntheticParameterizedType to make sure instances created for the same type information and type parameters are considered equal.
2016-05-12 16:48:01 +02:00