Skip to content

Commit abbf153

Browse files
author
Adrian Tosca
committed
add json serialization support for RawId
1 parent 7d37f88 commit abbf153

File tree

10 files changed

+120
-5
lines changed

10 files changed

+120
-5
lines changed

README.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# typeid-kotlin
22
![Build Status](https://github.com/aleris/typeid-kotlin/actions/workflows/build-on-push.yml/badge.svg)
3-
![Current Version](https://img.shields.io/badge/Version-0.0.6-blue)
3+
![Current Version](https://img.shields.io/badge/Version-0.0.7-blue)
44

55

66
## A Kotlin implementation of [TypeID](https://github.com/jetpack-io/typeid).
@@ -23,14 +23,14 @@ To use with Maven:
2323
<dependency>
2424
<groupId>earth.adi</groupId>
2525
<artifactId>typeid-kotlin</artifactId>
26-
<version>0.0.6</version>
26+
<version>0.0.7</version>
2727
</dependency>
2828
```
2929

3030
To use via Gradle:
3131

3232
```kotlin
33-
implementation("earth.adi:typeid-kotlin:0.0.6")
33+
implementation("earth.adi:typeid-kotlin:0.0.7")
3434
```
3535

3636

build.gradle.kts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ plugins {
1414

1515
group = "earth.adi"
1616

17-
version = "0.0.6"
17+
version = "0.0.7"
1818

1919
repositories { mavenCentral() }
2020

src/main/java/earth/adi/typeid/JavaType.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,9 @@
44
* JavaType.
55
*/
66
public class JavaType {
7+
/**
8+
* Create a new JavaType instance.
9+
*/
710
public static JavaType of(Class<?> clazz) {
811
return new JavaType(clazz);
912
}
@@ -14,6 +17,9 @@ private JavaType(Class<?> clazz) {
1417
this.clazz = clazz;
1518
}
1619

20+
/**
21+
* Get the clazz.
22+
*/
1723
public Class<?> getClazz() {
1824
return clazz;
1925
}

src/main/kotlin/earth/adi/typeid/Id.kt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,9 @@ import java.util.*
2929
* }
3030
* ```
3131
*
32+
* It is possible to create an `Id` directly, but it is recommended to use the `TypeId` factory
33+
* methods.
34+
*
3235
* @param TEntity the type of the associated entity with the identifier
3336
* @constructor Creates a new typed identifier with the specified [typedPrefix] and [uuid].
3437
* @property typedPrefix the typed prefix of the identifier

src/main/kotlin/earth/adi/typeid/jackson/IdJsonDeserializer.kt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,12 @@ import earth.adi.typeid.Id
99
import earth.adi.typeid.TypeId
1010
import java.io.IOException
1111

12+
/**
13+
* A Jackson deserializer for [Id] objects.
14+
*
15+
* @param typeId the type id instance to use for parsing the id
16+
* @param valueType value type of the id
17+
*/
1218
class IdJsonDeserializer
1319
@JvmOverloads
1420
constructor(private val typeId: TypeId, valueType: JavaType? = null) :

src/main/kotlin/earth/adi/typeid/jackson/IdJsonSerializer.kt

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,15 @@ import com.fasterxml.jackson.databind.ser.std.StdSerializer
77
import earth.adi.typeid.Id
88
import java.io.IOException
99

10+
/**
11+
* A Jackson serializer for [Id] objects.
12+
*
13+
* @param t type of the id
14+
*/
1015
class IdJsonSerializer @JvmOverloads constructor(t: Class<Id<*>?>? = null) :
1116
StdSerializer<Id<*>?>(t) {
1217
@Throws(IOException::class, JsonProcessingException::class)
1318
override fun serialize(value: Id<*>?, jgen: JsonGenerator, provider: SerializerProvider?) {
14-
jgen.writeString(value.toString())
19+
jgen.writeString(value?.toString() ?: "")
1520
}
1621
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
package earth.adi.typeid.jackson
2+
3+
import com.fasterxml.jackson.core.JsonParser
4+
import com.fasterxml.jackson.core.JsonProcessingException
5+
import com.fasterxml.jackson.databind.*
6+
import com.fasterxml.jackson.databind.deser.std.StdDeserializer
7+
import earth.adi.typeid.RawId
8+
import earth.adi.typeid.TypeId
9+
import java.io.IOException
10+
11+
/** A Jackson deserializer for [RawId] objects. */
12+
class RawIdJsonDeserializer : StdDeserializer<RawId?>(RawId::class.java) {
13+
@Throws(IOException::class, JsonProcessingException::class)
14+
override fun deserialize(jp: JsonParser, ctxt: DeserializationContext?): RawId {
15+
val id = jp.codec.readValue(jp, String::class.java)
16+
return TypeId.parse(id)
17+
}
18+
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
package earth.adi.typeid.jackson
2+
3+
import com.fasterxml.jackson.core.JsonGenerator
4+
import com.fasterxml.jackson.core.JsonProcessingException
5+
import com.fasterxml.jackson.databind.SerializerProvider
6+
import com.fasterxml.jackson.databind.ser.std.StdSerializer
7+
import earth.adi.typeid.RawId
8+
import java.io.IOException
9+
10+
/**
11+
* A Jackson serializer for [RawId] objects.
12+
*
13+
* @param t type of the id
14+
*/
15+
class RawIdJsonSerializer @JvmOverloads constructor(t: Class<RawId?>? = null) :
16+
StdSerializer<RawId?>(t) {
17+
@Throws(IOException::class, JsonProcessingException::class)
18+
override fun serialize(value: RawId?, jgen: JsonGenerator, provider: SerializerProvider?) {
19+
jgen.writeString(value?.toString() ?: "")
20+
}
21+
}

src/main/kotlin/earth/adi/typeid/jackson/TypeIdModule.kt

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,26 @@ package earth.adi.typeid.jackson
33
import com.fasterxml.jackson.core.Version
44
import com.fasterxml.jackson.databind.module.SimpleModule
55
import earth.adi.typeid.Id
6+
import earth.adi.typeid.RawId
67
import earth.adi.typeid.TypeId
78

9+
/**
10+
* Jackson module for serializing and deserializing [Id] and [RawId] objects.
11+
*
12+
* To use the module:
13+
* ```
14+
* private val objectMapper = jacksonObjectMapper().registerModule(typeId.jacksonModule())
15+
* ```
16+
*
17+
* @param typeId the type id instance to use for parsing the id
18+
*/
819
class TypeIdModule(typeId: TypeId) : SimpleModule() {
920
init {
1021
addSerializer(Id::class.java, IdJsonSerializer())
1122
addDeserializer(Id::class.java, IdJsonDeserializer(typeId))
23+
24+
addSerializer(RawId::class.java, RawIdJsonSerializer())
25+
addDeserializer(RawId::class.java, RawIdJsonDeserializer())
1226
}
1327

1428
override fun version(): Version {

src/test/kotlin/earth/adi/typeid/JacksonJsonTest.kt

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,9 @@ import com.fasterxml.jackson.databind.PropertyName
66
import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper
77
import com.fasterxml.jackson.module.kotlin.readValue
88
import earth.adi.typeid.jackson.IdJsonDeserializer
9+
import earth.adi.typeid.jackson.IdJsonSerializer
10+
import earth.adi.typeid.jackson.RawIdJsonSerializer
11+
import java.io.ByteArrayOutputStream
912
import org.assertj.core.api.Assertions.assertThat
1013
import org.junit.jupiter.api.Test
1114

@@ -77,6 +80,29 @@ class JacksonJsonTest {
7780
assertThat(writtenJson).isEqualTo(JSON_IDS_ONLY)
7881
}
7982

83+
data class RawIds(
84+
@JsonProperty("user_id") val userId: RawId,
85+
@JsonProperty("org_id") val organizationId: RawId,
86+
)
87+
88+
@Test
89+
fun `deserialize raw ids from json`() {
90+
val json = objectMapper.readValue<RawIds>(JSON_IDS_ONLY)
91+
assertThat(json.userId).isEqualTo(typeId.parse("user_01hy0d96sgfx0rh975kqkspchh"))
92+
assertThat(json.organizationId).isEqualTo(typeId.parse("org_01hy0sk45qfmdsdme1j703yjet"))
93+
}
94+
95+
@Test
96+
fun `serialize raw ids to json`() {
97+
val json =
98+
RawIds(
99+
typeId.parse("user_01hy0d96sgfx0rh975kqkspchh"),
100+
typeId.parse("org_01hy0sk45qfmdsdme1j703yjet"),
101+
)
102+
val writtenJson = objectMapper.writerWithDefaultPrettyPrinter().writeValueAsString(json)
103+
assertThat(writtenJson).isEqualTo(JSON_IDS_ONLY)
104+
}
105+
80106
@Test
81107
fun `create IdJsonDeserializer null deserializerContext`() {
82108
val type = objectMapper.constructType(Id::class.java)
@@ -101,6 +127,22 @@ class JacksonJsonTest {
101127
assertThat(idJsonDeserializer.valueType).isNull()
102128
}
103129

130+
@Test
131+
fun `IdJsonSerializer null id`() {
132+
ByteArrayOutputStream().use { outputStream ->
133+
IdJsonSerializer().serialize(null, objectMapper.createGenerator(outputStream), null)
134+
assertThat(outputStream.toString()).isEqualTo("")
135+
}
136+
}
137+
138+
@Test
139+
fun `RawIdJsonSerializer null id`() {
140+
ByteArrayOutputStream().use { outputStream ->
141+
RawIdJsonSerializer().serialize(null, objectMapper.createGenerator(outputStream), null)
142+
assertThat(outputStream.toString()).isEqualTo("")
143+
}
144+
}
145+
104146
companion object {
105147
private val JSON_USER =
106148
"""

0 commit comments

Comments
 (0)