Skip to content

Commit f15b4a7

Browse files
committed
Update the example Jackson policy, make it configurable, to show
how an extension of the default policy can still be configurable.
1 parent 3c73391 commit f15b4a7

File tree

3 files changed

+65
-36
lines changed

3 files changed

+65
-36
lines changed

examples/JACKSON.md

Lines changed: 38 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -22,22 +22,32 @@ data class Team(val members: List<Person>, val colors: List<String> = listOf())
2222
```kotlin
2323
/**
2424
* Example policy that (very crudely) mimicks the way that Jackson serializes xml. It starts by eliding defaults.
25-
* Note that this version doesn't handle the jackson annotations.
25+
* Note that this version doesn't handle the jackson annotations, and is not configurable.
2626
*/
27-
object JacksonPolicy :
28-
DefaultXmlSerializationPolicy(false, encodeDefault = XmlSerializationPolicy.XmlEncodeDefault.NEVER) {
27+
class JacksonPolicy(formatCache: FormatCache = defaultSharedFormatCache(), config: Builder.() -> Unit = {}) :
28+
DefaultXmlSerializationPolicy(formatCache, {
29+
pedantic = false
30+
encodeDefault = XmlSerializationPolicy.XmlEncodeDefault.NEVER
31+
config()
32+
}) {
33+
34+
constructor(config: Builder.() -> Unit): this(defaultSharedFormatCache(), config)
35+
2936
/*
3037
* Rather than replacing the method wholesale, just make attributes into elements unless the [XmlElement] annotation
3138
* is present with a `false` value on the value attribute.
3239
*/
33-
override fun effectiveOutputKind(serializerParent: SafeParentInfo, tagParent: SafeParentInfo): OutputKind {
34-
val r = super.effectiveOutputKind(serializerParent, tagParent)
40+
override fun effectiveOutputKind(
41+
serializerParent: SafeParentInfo,
42+
tagParent: SafeParentInfo,
43+
canBeAttribute: Boolean
44+
): OutputKind {
45+
val r = super.effectiveOutputKind(serializerParent, tagParent, canBeAttribute)
3546
return when {
3647
// Do take into account the XmlElement annotation
3748
r == OutputKind.Attribute &&
38-
serializerParent.elementUseAnnotations.mapNotNull { it as? XmlElement }
39-
.firstOrNull()?.value != false
40-
-> OutputKind.Element
49+
serializerParent.useAnnIsElement != false ->
50+
OutputKind.Element
4151

4252
else -> r
4353
}
@@ -53,14 +63,28 @@ object JacksonPolicy :
5363
tagParent: SafeParentInfo,
5464
outputKind: OutputKind,
5565
useName: XmlSerializationPolicy.DeclaredNameInfo
56-
): QName {
66+
): QName {
5767
return useName.annotatedName
58-
?: serializerParent.elemenTypeDescriptor.typeQname
59-
?: serialNameToQName(useName.serialName, tagParent.namespace)
68+
?: serializerParent.elementTypeDescriptor.typeQname
69+
?: serialUseNameToQName(useName, tagParent.namespace)
6070
}
6171

6272
}
6373
```
74+
For allowing elegant configuration, the below code prvoides for configuration.
75+
Note that this function's implementation could be adjusted to allow for
76+
a class (not object) policy that would also allow for further configuration.
77+
78+
```kotlin
79+
fun XmlConfig.Builder.jacksonPolicy(config: Builder.() -> Unit = {}) {
80+
@OptIn(ExperimentalXmlUtilApi::class)
81+
policy = JacksonPolicy {
82+
setDefaults_0_91_0()
83+
encodeDefault = XmlSerializationPolicy.XmlEncodeDefault.NEVER
84+
config()
85+
}
86+
}
87+
```
6488

6589

6690
## Example usage
@@ -69,15 +93,15 @@ object JacksonPolicy :
6993
fun main() {
7094
val t = Team(listOf(Person("Joe", 15)))
7195
val xml = XML {
72-
policy = JacksonPolicy
96+
jacksonPolicy()
7397
}
7498

7599
val encodedString = xml.encodeToString(t) // both versions are available
76100
println("jackson output:\n${encodedString.prependIndent(" ")}\n")
77101

78-
// the inline reified version is is also available
102+
// the inline reified version is also available
79103
val reparsedData = xml.decodeFromString<Team>(encodedString)
80104
println("jackson input: $reparsedData")
81105

82106
}
83-
```
107+
```

examples/src/main/kotlin/net/devrieze/serialization/examples/jackson/JacksonPolicy.kt

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -23,19 +23,22 @@ package net.devrieze.serialization.examples.jackson
2323
import nl.adaptivity.xmlutil.ExperimentalXmlUtilApi
2424
import nl.adaptivity.xmlutil.QName
2525
import nl.adaptivity.xmlutil.serialization.*
26+
import nl.adaptivity.xmlutil.serialization.DefaultXmlSerializationPolicy.Builder
2627
import nl.adaptivity.xmlutil.serialization.structure.SafeParentInfo
2728

2829
/**
2930
* Example policy that (very crudely) mimicks the way that Jackson serializes xml. It starts by eliding defaults.
30-
* Note that this version doesn't handle the jackson annotations.
31+
* Note that this version doesn't handle the jackson annotations, and is not configurable.
3132
*/
32-
object JacksonPolicy : DefaultXmlSerializationPolicy(
33-
defaultSharedFormatCache(),
34-
{
33+
class JacksonPolicy(formatCache: FormatCache = defaultSharedFormatCache(), config: Builder.() -> Unit = {}) :
34+
DefaultXmlSerializationPolicy(formatCache, {
3535
pedantic = false
3636
encodeDefault = XmlSerializationPolicy.XmlEncodeDefault.NEVER
37-
},
38-
) {
37+
config()
38+
}) {
39+
40+
constructor(config: Builder.() -> Unit): this(defaultSharedFormatCache(), config)
41+
3942
/*
4043
* Rather than replacing the method wholesale, just make attributes into elements unless the [XmlElement] annotation
4144
* is present with a `false` value on the value attribute.
@@ -75,7 +78,11 @@ object JacksonPolicy : DefaultXmlSerializationPolicy(
7578
}
7679

7780
/** Extension function for elegant configuration */
78-
fun XmlConfig.Builder.jacksonPolicy() {
81+
fun XmlConfig.Builder.jacksonPolicy(config: Builder.() -> Unit = {}) {
7982
@OptIn(ExperimentalXmlUtilApi::class)
80-
policy = JacksonPolicy
83+
policy = JacksonPolicy {
84+
setDefaults_0_91_0()
85+
encodeDefault = XmlSerializationPolicy.XmlEncodeDefault.NEVER
86+
config()
87+
}
8188
}

examples/src/main/kotlin/net/devrieze/serialization/examples/jackson/main.kt

Lines changed: 12 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,27 @@
11
/*
2-
* Copyright (c) 2020.
2+
* Copyright (c) 2020-2025.
33
*
44
* This file is part of xmlutil.
55
*
6-
* This file is licenced to you under the Apache License, Version 2.0 (the
7-
* "License"); you may not use this file except in compliance
8-
* with the License. You should have received a copy of the license with the source distribution.
9-
* Alternatively, you may obtain a copy of the License at
6+
* This file is licenced to you under the Apache License, Version 2.0
7+
* (the "License"); you may not use this file except in compliance
8+
* with the License. You should have received a copy of the license
9+
* with the source distribution. Alternatively, you may obtain a copy
10+
* of the License at
1011
*
1112
* http://www.apache.org/licenses/LICENSE-2.0
1213
*
13-
* Unless required by applicable law or agreed to in writing,
14-
* software distributed under the License is distributed on an
15-
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16-
* KIND, either express or implied. See the License for the
17-
* specific language governing permissions and limitations
18-
* under the License.
14+
* Unless required by applicable law or agreed to in writing, software
15+
* distributed under the License is distributed on an "AS IS" BASIS,
16+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
17+
* implied. See the License for the specific language governing
18+
* permissions and limitations under the License.
1919
*/
2020

2121
package net.devrieze.serialization.examples.jackson
2222

2323
import kotlinx.serialization.decodeFromString
2424
import kotlinx.serialization.encodeToString
25-
import kotlinx.serialization.serializer
26-
import nl.adaptivity.xmlutil.ExperimentalXmlUtilApi
2725
import nl.adaptivity.xmlutil.serialization.XML
2826

2927
fun main() {
@@ -35,7 +33,7 @@ fun main() {
3533
val encodedString = xml.encodeToString(t) // both versions are available
3634
println("jackson output:\n${encodedString.prependIndent(" ")}\n")
3735

38-
// the inline reified version is is also available
36+
// the inline reified version is also available
3937
val reparsedData = xml.decodeFromString<Team>(encodedString)
4038
println("jackson input: $reparsedData")
4139

0 commit comments

Comments
 (0)