forked from fabric8io/kubernetes-client
-
Notifications
You must be signed in to change notification settings - Fork 0
/
UnmatchedFieldTypeModule.java
118 lines (101 loc) · 3.96 KB
/
UnmatchedFieldTypeModule.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
/**
* Copyright (C) 2015 Red Hat, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.fabric8.kubernetes.model.jackson;
import com.fasterxml.jackson.databind.BeanDescription;
import com.fasterxml.jackson.databind.DeserializationConfig;
import com.fasterxml.jackson.databind.SerializationConfig;
import com.fasterxml.jackson.databind.deser.BeanDeserializerBuilder;
import com.fasterxml.jackson.databind.deser.BeanDeserializerModifier;
import com.fasterxml.jackson.databind.module.SimpleModule;
import com.fasterxml.jackson.databind.ser.BeanSerializerBuilder;
import com.fasterxml.jackson.databind.ser.BeanSerializerModifier;
import java.util.stream.Collectors;
/**
* Class that registers the capability of deserializing and serializing objects with properties that don't match the
* target's bean field types.
*
* <pre>{@code
* ObjectMapper mapper = new ObjectMapper();
* mapper.registerModule(new UnmatchedFieldTypeModule());
* }</pre>
*/
public class UnmatchedFieldTypeModule extends SimpleModule {
private boolean logWarnings;
private boolean restrictToTemplates;
private static final ThreadLocal<Boolean> IN_TEMPLATE = ThreadLocal.withInitial(() -> false);
public UnmatchedFieldTypeModule() {
this(true, true);
}
public UnmatchedFieldTypeModule(boolean logWarnings, boolean restrictToTemplates) {
this.logWarnings = logWarnings;
this.restrictToTemplates = restrictToTemplates;
setDeserializerModifier(new BeanDeserializerModifier() {
@Override
public BeanDeserializerBuilder updateBuilder(DeserializationConfig config, BeanDescription beanDesc,
BeanDeserializerBuilder builder) {
builder.getProperties().forEachRemaining(p -> builder.addOrReplaceProperty(
new SettableBeanPropertyDelegate(p, builder.getAnySetter(), UnmatchedFieldTypeModule.this::useAnySetter) {
}, true));
return builder;
}
});
setSerializerModifier(new BeanSerializerModifier() {
@Override
public BeanSerializerBuilder updateBuilder(SerializationConfig config, BeanDescription beanDesc,
BeanSerializerBuilder builder) {
builder.setProperties(builder.getProperties().stream()
.map(p -> new BeanPropertyWriterDelegate(p, builder.getBeanDescription().findAnyGetter(),
UnmatchedFieldTypeModule.this::isLogWarnings))
.collect(Collectors.toList()));
return builder;
}
});
}
boolean isLogWarnings() {
return logWarnings;
}
/**
* Set if warnings should be logged for ambiguous serializer and deserializer situations.
*
* @param logWarnings if true, warnings will be logged.
*/
public void setLogWarnings(boolean logWarnings) {
this.logWarnings = logWarnings;
}
boolean isRestrictToTemplates() {
return restrictToTemplates;
}
boolean useAnySetter() {
return !restrictToTemplates || isInTemplate();
}
/**
* Sets if the DeserializerModifier should only be applied to Templates or object trees contained in Templates.
*
* @param restrictToTemplates if true, the DeserializerModifier will only be applicable for Templates.
*/
public void setRestrictToTemplates(boolean restrictToTemplates) {
this.restrictToTemplates = restrictToTemplates;
}
public static boolean isInTemplate() {
return Boolean.TRUE.equals(IN_TEMPLATE.get());
}
public static void setInTemplate() {
IN_TEMPLATE.set(true);
}
public static void removeInTemplate() {
IN_TEMPLATE.remove();
}
}