Skip to content

Commit

Permalink
feat: BREAKING CHANGE: remove ability to name transformer
Browse files Browse the repository at this point in the history
  • Loading branch information
Idane committed Jul 18, 2022
1 parent a0ee8b6 commit 1a5f5e8
Show file tree
Hide file tree
Showing 9 changed files with 17 additions and 123 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -18,27 +18,24 @@ data class MappingTransformerRegistration<From : Any?, To : Any?>(
val fromClazz: Class<From>,
val toClazz: Class<To>,
val transformer: MappingTransformer<From, To>,
val default: Boolean = false,
val name: String? = null
val default: Boolean = false
) {
companion object {
val EMPTY = MappingTransformerRegistration(
Any::class.java,
Any::class.java,
EmptyTransformer,
false,
"empty"
false
)

val <From : Any?, To : Any?> MappingTransformerRegistration<From, To>.id: ClassPair<From, To> get() = ClassPair(fromClazz, toClazz)

inline fun <reified From : Any, reified To : Any> MappingTransformer<From, To>.toRegistration(default: Boolean = false, name: String? = null): MappingTransformerRegistration<From, To> {
inline fun <reified From : Any, reified To : Any> MappingTransformer<From, To>.toRegistration(default: Boolean = false): MappingTransformerRegistration<From, To> {
return MappingTransformerRegistration(
From::class.java,
To::class.java,
this,
default,
name
default
)
}
}
Expand Down
36 changes: 6 additions & 30 deletions shapeshift/src/main/kotlin/dev/krud/shapeshift/ShapeShift.kt
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,6 @@ class ShapeShift internal constructor(
val decoratorRegistrations: Set<MappingDecoratorRegistration<out Any, out Any>>
) {
val transformerRegistrations: MutableList<MappingTransformerRegistration<out Any, out Any>> = mutableListOf()
internal val transformersByNameCache: MutableMap<String, MappingTransformerRegistration<out Any, out Any>> = concurrentMapOf()
internal val transformersByTypeCache: MutableMap<Class<out MappingTransformer<out Any?, out Any?>>, MappingTransformerRegistration<out Any?, out Any?>> =
concurrentMapOf()
internal val defaultTransformers: MutableMap<ClassPair<out Any, out Any>, MappingTransformerRegistration<out Any, out Any>> = mutableMapOf()
Expand Down Expand Up @@ -187,12 +186,6 @@ class ShapeShift internal constructor(
return getFieldInstanceByNodes(nodes.drop(1), subTarget, type)
}

private fun getTransformerByName(name: String): MappingTransformerRegistration<out Any, out Any> {
return transformersByNameCache.computeIfAbsent(name) { _ ->
transformerRegistrations.find { it.name == name } ?: MappingTransformerRegistration.EMPTY
}
}

private fun getTransformerByType(type: Class<out MappingTransformer<out Any?, out Any?>>): MappingTransformerRegistration<out Any?, out Any?> {
return transformersByTypeCache.computeIfAbsent(type) { _ ->
transformerRegistrations.find { it.transformer::class.java == type } ?: MappingTransformerRegistration.EMPTY
Expand Down Expand Up @@ -230,16 +223,6 @@ class ShapeShift internal constructor(
val transformationPair = fromPair to toPair
log.trace("Attempting to find transformer for transformation pair [ $transformationPair ]")
var transformerRegistration: MappingTransformerRegistration<*, *> = MappingTransformerRegistration.EMPTY
log.trace("Checking transformerRef field")
if (!coordinates.name.isNullOrBlank()) {
log.trace("transformerRef is not empty with value [ " + coordinates.name + " ]")
transformerRegistration = getTransformerByName(coordinates.name)
if (transformerRegistration != MappingTransformerRegistration.EMPTY) {
log.trace("Found transformer by ref [ ${coordinates.name} ] of type [ " + transformerRegistration.transformer.javaClass.name + " ]")
} else {
error("Could not find transformer by ref [ ${coordinates.name} ] on $fromPair")
}
}
if (transformerRegistration == MappingTransformerRegistration.EMPTY) {
log.trace("Checking transformer field")
if (coordinates.type == null) {
Expand Down Expand Up @@ -270,23 +253,16 @@ class ShapeShift internal constructor(
}

private fun <From : Any, To : Any> registerTransformer(registration: MappingTransformerRegistration<From, To>) {
val name = registration.name ?: registration.transformer::class.simpleName!!
val newRegistration = registration.copy(name = name)
val existingTransformer = getTransformerByName(name)
if (existingTransformer != MappingTransformerRegistration.EMPTY) {
error("Transformer with name $name already exists with type ${existingTransformer.transformer::class}")
}
if (newRegistration.default) {
val existingDefaultTransformer = defaultTransformers[newRegistration.id]
if (registration.default) {
val existingDefaultTransformer = defaultTransformers[registration.id]
if (existingDefaultTransformer != null) {
error("Default transformer with pair ${newRegistration.id} already exists")
error("Default transformer with pair ${registration.id} already exists")
}
defaultTransformers[newRegistration.id] = newRegistration
defaultTransformers[registration.id] = registration
}

transformerRegistrations.add(newRegistration)
transformersByNameCache.remove(name)
transformersByTypeCache.remove(newRegistration.transformer::class.java)
transformerRegistrations.add(registration)
transformersByTypeCache.remove(registration.transformer::class.java)
}

companion object {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -84,8 +84,8 @@ class ShapeShiftBuilder {
/**
* Add a transformer to the ShapeShift instance
*/
inline fun <reified From : Any, reified To : Any> withTransformer(mappingTransformer: MappingTransformer<From, To>, default: Boolean = false, name: String? = null): ShapeShiftBuilder {
return withTransformer(mappingTransformer.toRegistration(default, name))
inline fun <reified From : Any, reified To : Any> withTransformer(mappingTransformer: MappingTransformer<From, To>, default: Boolean = false): ShapeShiftBuilder {
return withTransformer(mappingTransformer.toRegistration(default))
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,10 @@ import dev.krud.shapeshift.transformer.EmptyTransformer
import dev.krud.shapeshift.transformer.base.MappingTransformer

data class TransformerCoordinates(
val name: String? = null,
val type: Class<out MappingTransformer<out Any?, out Any?>>? = null
) {
companion object {
val NONE = TransformerCoordinates()
fun ofName(name: String) = TransformerCoordinates(name)
fun ofType(
type: Class<out MappingTransformer<out Any?, out Any?>>
): TransformerCoordinates {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,11 +26,7 @@ class AnnotationMappingDefinitionResolver : MappingDefinitionResolver {

val resolvedMappedFields = mutableListOf<ResolvedMappedField>()
for ((mappedField, field) in mappedFieldReferences) {
val transformerCoordinates = if (mappedField.transformerRef.isBlank()) {
TransformerCoordinates.ofType(mappedField.transformer.java)
} else {
TransformerCoordinates.ofName(mappedField.transformerRef)
}
val transformerCoordinates = TransformerCoordinates.ofType(mappedField.transformer.java)

val mapFromCoordinates = resolveNodesToFields(mappedField.mapFrom.splitIgnoreEmpty(NODE_DELIMITER), field, fromClazz)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,11 +40,6 @@ annotation class MappedField(
* The [MappingTransformer] to use on the value
*/
val transformer: KClass<out MappingTransformer<*, *>> = EmptyTransformer::class,
/**
* Bean name for a defined [MappingTransformer] bean to use on the value
* Supersedes [MappedField.transformer] if specified
*/
val transformerRef: String = "",

/**
* The condition to use to determine if the field should be mapped
Expand Down
62 changes: 0 additions & 62 deletions shapeshift/src/test/kotlin/dev/krud/shapeshift/ShapeShiftTests.kt
Original file line number Diff line number Diff line change
Expand Up @@ -60,19 +60,6 @@ internal class ShapeShiftTests {
.isEqualTo("1")
}

@Test
internal fun `simple mapping with transformer by name`() {
shapeShift = ShapeShiftBuilder()
.withTransformer(
LongToStringTransformer().toRegistration(name = "myTransformer")
)
.build()
val result = shapeShift.map(NameTransformerFrom(), StringTo::class.java)

expectThat(result.long)
.isEqualTo("1")
}

@Test
internal fun `simple mapping with default transformer`() {
shapeShift = ShapeShiftBuilder()
Expand Down Expand Up @@ -241,55 +228,6 @@ internal class ShapeShiftTests {
}
}

@Test
internal fun `registering transformer with null name should use simple class name when registering`() {
val registration = ExampleFieldTransformer().toRegistration()
shapeShift = ShapeShiftBuilder()
.excludeDefaultTransformers()
.withTransformer(registration)
.build()
expectThat(shapeShift.transformerRegistrations.first().name)
.isEqualTo(
"ExampleFieldTransformer"
)
}

@Test
internal fun `registering same transformer twice should result in 1 transformer`() {
val registration = ExampleFieldTransformer().toRegistration(name = "first")

val builder = ShapeShiftBuilder()
.excludeDefaultTransformers()
.withTransformer(registration)
.withTransformer(registration)

val shapeShift = builder.build()
expectThat(shapeShift.transformerRegistrations.size)
.isEqualTo(1)
}

@Test
internal fun `registering transformer with an existing name twice should throw exception`() {
val registration = ExampleFieldTransformer().toRegistration(name = "first")

val secondRegistration = ExampleFieldTransformer().toRegistration(name = "first")

val builder = ShapeShiftBuilder()
.withTransformer(registration)
.withTransformer(secondRegistration)

expectThrows<IllegalStateException> {
builder.build()
}
}

@Test
internal fun `using unregistered transformer by name should throw exception`() {
expectThrows<IllegalStateException> {
shapeShift.map(NameTransformerFrom(), StringTo::class.java)
}
}

@Test
internal fun `using unregistered transformer by type should throw exception`() {
expectThrows<IllegalStateException> {
Expand Down
5 changes: 0 additions & 5 deletions shapeshift/src/test/kotlin/dev/krud/shapeshift/_fixtures.kt
Original file line number Diff line number Diff line change
Expand Up @@ -177,11 +177,6 @@ internal class DefaultTransformerFrom {
val long: Long = 1L
}

internal class NameTransformerFrom {
@MappedField(target = StringTo::class, transformerRef = "myTransformer")
val long: Long = 1L
}

internal class TypeTransformerFrom {
@MappedField(target = StringTo::class, transformer = LongToStringTransformer::class)
val long: Long = 1L
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,17 +21,16 @@ import org.springframework.core.GenericTypeResolver
@Configuration
class ShapeShiftTransformerCustomizer : ShapeShiftBuilderCustomizer {
@Autowired(required = false)
private val mappingTransformers: Map<String, MappingTransformer<out Any, out Any>>? = null
private val mappingTransformers: List<MappingTransformer<out Any, out Any>>? = null

override fun customize(builder: ShapeShiftBuilder) {
mappingTransformers?.forEach { (name, mappingTransformer) ->
mappingTransformers?.forEach { mappingTransformer ->
val types = GenericTypeResolver.resolveTypeArguments(mappingTransformer::class.java, MappingTransformer::class.java)
val registration = MappingTransformerRegistration(
types[0] as Class<Any>,
types!![0] as Class<Any>,
types[1] as Class<Any>,
mappingTransformer as MappingTransformer<Any, Any>,
false,
name
false
)
builder.withTransformer(
registration
Expand Down

0 comments on commit 1a5f5e8

Please sign in to comment.