Skip to content

Commit 93343e7

Browse files
committed
JsonNode, ArrayNode and ObjectNode extensions
1 parent 4c18e43 commit 93343e7

File tree

3 files changed

+89
-7
lines changed

3 files changed

+89
-7
lines changed

README.md

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,26 @@ myMemberWithType = mapper.readValue(json)
100100
All inferred types for the extension functions carry in full generic information (reified generics).
101101
Therefore, using `readValue()` extension without the `Class` parameter will reify the type and automatically create a `TypeReference` for Jackson.
102102

103+
Also, there are some convenient operator overloading extension functions for JsonNode inheritors.
104+
```kotlin
105+
import com.fasterxml.jackson.databind.node.ArrayNode
106+
import com.fasterxml.jackson.databind.node.ObjectNode
107+
import com.fasterxml.jackson.module.kotlin.*
108+
109+
// ...
110+
val objectNode: ObjectNode = TODO()
111+
objectNode -= "foo1"
112+
objectNode -= listOf("foo2")
113+
114+
// ...
115+
val arrayNode: ArrayNode = TODO()
116+
arrayNode += "foo"
117+
arrayNode += true
118+
arrayNode += 1
119+
arrayNode -= 1.0
120+
arrayNode -= "bar".toByteArray()
121+
```
122+
103123
# Annotations
104124

105125
You can intermix non-field values in the constructor and `JsonProperty` annotation in the constructor.

src/main/kotlin/com/fasterxml/jackson/module/kotlin/Extensions.kt

Lines changed: 41 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,17 +3,16 @@ package com.fasterxml.jackson.module.kotlin
33
import com.fasterxml.jackson.core.JsonParser
44
import com.fasterxml.jackson.core.TreeNode
55
import com.fasterxml.jackson.core.type.TypeReference
6-
import com.fasterxml.jackson.databind.JsonMappingException
7-
import com.fasterxml.jackson.databind.MappingIterator
8-
import com.fasterxml.jackson.databind.ObjectMapper
9-
import com.fasterxml.jackson.databind.ObjectReader
10-
import com.fasterxml.jackson.databind.module.SimpleModule
11-
import com.fasterxml.jackson.databind.JsonDeserializer
12-
import com.fasterxml.jackson.databind.JsonSerializer
6+
import com.fasterxml.jackson.databind.*
137
import com.fasterxml.jackson.databind.json.JsonMapper
8+
import com.fasterxml.jackson.databind.module.SimpleModule
9+
import com.fasterxml.jackson.databind.node.ArrayNode
10+
import com.fasterxml.jackson.databind.node.ObjectNode
1411
import java.io.File
1512
import java.io.InputStream
1613
import java.io.Reader
14+
import java.math.BigDecimal
15+
import java.math.BigInteger
1716
import java.net.URL
1817
import java.util.*
1918
import kotlin.reflect.KClass
@@ -54,6 +53,41 @@ inline fun <reified T> ObjectReader.readValueTyped(jp: JsonParser): T = readValu
5453
inline fun <reified T> ObjectReader.readValuesTyped(jp: JsonParser): Iterator<T> = readValues(jp, jacksonTypeRef<T>())
5554
inline fun <reified T> ObjectReader.treeToValue(n: TreeNode): T? = treeToValue(n, T::class.java)
5655

56+
operator fun ArrayNode.plus(element: Boolean) = Unit.apply { add(element) }
57+
operator fun ArrayNode.plus(element: Short) = Unit.apply { add(element) }
58+
operator fun ArrayNode.plus(element: Int) = Unit.apply { add(element) }
59+
operator fun ArrayNode.plus(element: Long) = Unit.apply { add(element) }
60+
operator fun ArrayNode.plus(element: Float) = Unit.apply { add(element) }
61+
operator fun ArrayNode.plus(element: Double) = Unit.apply { add(element) }
62+
operator fun ArrayNode.plus(element: BigDecimal) = Unit.apply { add(element) }
63+
operator fun ArrayNode.plus(element: BigInteger) = Unit.apply { add(element) }
64+
operator fun ArrayNode.plus(element: String) = Unit.apply { add(element) }
65+
operator fun ArrayNode.plus(element: ByteArray) = Unit.apply { add(element) }
66+
operator fun ArrayNode.plus(element: JsonNode) = Unit.apply { add(element) }
67+
operator fun ArrayNode.plus(elements: ArrayNode) = Unit.apply { addAll(elements) }
68+
operator fun ArrayNode.plusAssign(element: Boolean) = Unit.apply { add(element) }
69+
operator fun ArrayNode.plusAssign(element: Short) = Unit.apply { add(element) }
70+
operator fun ArrayNode.plusAssign(element: Int) = Unit.apply { add(element) }
71+
operator fun ArrayNode.plusAssign(element: Long) = Unit.apply { add(element) }
72+
operator fun ArrayNode.plusAssign(element: Float) = Unit.apply { add(element) }
73+
operator fun ArrayNode.plusAssign(element: Double) = Unit.apply { add(element) }
74+
operator fun ArrayNode.plusAssign(element: BigDecimal) = Unit.apply { add(element) }
75+
operator fun ArrayNode.plusAssign(element: BigInteger) = Unit.apply { add(element) }
76+
operator fun ArrayNode.plusAssign(element: String) = Unit.apply { add(element) }
77+
operator fun ArrayNode.plusAssign(element: ByteArray) = Unit.apply { add(element) }
78+
operator fun ArrayNode.plusAssign(element: JsonNode) = Unit.apply { add(element) }
79+
operator fun ArrayNode.plusAssign(elements: ArrayNode) = Unit.apply { addAll(elements) }
80+
operator fun ArrayNode.minus(index: Int) = Unit.apply { remove(index) }
81+
operator fun ArrayNode.minusAssign(index: Int) = Unit.apply { remove(index) }
82+
83+
operator fun ObjectNode.minus(field: String) = Unit.apply { remove(field) }
84+
operator fun ObjectNode.minus(fields: Collection<String>) = Unit.apply { remove(fields) }
85+
operator fun ObjectNode.minusAssign(field: String) = Unit.apply { remove(field) }
86+
operator fun ObjectNode.minusAssign(fields: Collection<String>) = Unit.apply { remove(fields) }
87+
88+
operator fun JsonNode.contains(field: String) = has(field)
89+
operator fun JsonNode.contains(index: Int) = has(index)
90+
5791
internal fun JsonMappingException.wrapWithPath(refFrom: Any?, refFieldName: String) = JsonMappingException.wrapWithPath(this, refFrom, refFieldName)
5892
internal fun JsonMappingException.wrapWithPath(refFrom: Any?, index: Int) = JsonMappingException.wrapWithPath(this, refFrom, index)
5993

src/test/kotlin/com/fasterxml/jackson/module/kotlin/test/ExtensionMethodsTests.kt

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,9 @@ package com.fasterxml.jackson.module.kotlin.test
22

33
import com.fasterxml.jackson.databind.ObjectMapper
44
import com.fasterxml.jackson.databind.SerializationFeature
5+
import com.fasterxml.jackson.databind.node.JsonNodeFactory
56
import com.fasterxml.jackson.module.kotlin.*
7+
import org.hamcrest.CoreMatchers.`is`
68
import org.hamcrest.CoreMatchers.equalTo
79
import org.hamcrest.MatcherAssert.assertThat
810
import org.junit.Test
@@ -33,4 +35,30 @@ class TestExtensionMethods {
3335
val myList: List<MyData> = mapper.readValue(jsonStr)
3436
assertThat(myList, equalTo(listOf(MyData("value1", 1), MyData("value2", 2))))
3537
}
38+
39+
@Test fun testOperatorFunExtensions() {
40+
val factory = JsonNodeFactory.instance
41+
42+
val objectNode = factory.objectNode()
43+
objectNode.put("foo1", "bar")
44+
objectNode.put("foo2", "baz")
45+
objectNode.put("foo3", "bah")
46+
objectNode -= "foo1"
47+
objectNode -= listOf("foo2")
48+
49+
assertThat("foo1" !in objectNode, `is`(true))
50+
assertThat("foo3" in objectNode, `is`(true))
51+
52+
val arrayNode = factory.arrayNode()
53+
arrayNode += "foo"
54+
arrayNode += true
55+
arrayNode += 1
56+
arrayNode += 1.0
57+
arrayNode += "bar".toByteArray()
58+
59+
assertThat(arrayNode.size(), `is`(5))
60+
61+
(4 downTo 0).forEach { arrayNode -= it }
62+
assertThat(arrayNode.size(), `is`(0))
63+
}
3664
}

0 commit comments

Comments
 (0)