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.
This commit is contained in:
Mark Paluch
2017-07-26 12:07:20 +02:00
committed by Oliver Gierke
parent e4e677d6b1
commit 22b37800ec
15 changed files with 894 additions and 216 deletions

View File

@@ -44,11 +44,15 @@ import org.springframework.util.ReflectionUtils.FieldFilter;
* @author Oliver Gierke
* @author Thomas Darimont
* @author Christoph Strobl
* @author Mark Paluch
* @since 1.5
*/
@UtilityClass
public class ReflectionUtils {
private static final boolean KOTLIN_IS_PRESENT = ClassUtils.isPresent("kotlin.Unit",
BeanUtils.class.getClassLoader());
/**
* Creates an instance of the class with the given fully qualified name or returns the given default instance if the
* class cannot be loaded or instantiated.
@@ -338,4 +342,17 @@ public class ReflectionUtils {
return true;
}
/**
* Return true if the specified class is a Kotlin one.
*
* @return {@literal true} if {@code type} is a Kotlin class.
* @since 2.0
*/
public static boolean isKotlinClass(Class<?> type) {
return KOTLIN_IS_PRESENT && Arrays.stream(type.getDeclaredAnnotations()) //
.map(Annotation::annotationType) //
.anyMatch(annotation -> annotation.getName().equals("kotlin.Metadata"));
}
}