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
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
|
package com.fasterxml.jackson.databind.deser.std;
import java.io.IOException;
import com.fasterxml.jackson.core.JsonLocation;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.JsonToken;
import com.fasterxml.jackson.databind.BeanDescription;
import com.fasterxml.jackson.databind.DeserializationConfig;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.annotation.JacksonStdImpl;
import com.fasterxml.jackson.databind.deser.CreatorProperty;
import com.fasterxml.jackson.databind.deser.ValueInstantiator;
import com.fasterxml.jackson.databind.util.TokenBuffer;
/**
* Container class for core Jackson type deserializers.
*/
public class JacksonDeserializers
{
public static StdDeserializer<?>[] all()
{
// note: JsonLocation supported via ValueInstantiator
return new StdDeserializer[] {
new JavaTypeDeserializer(),
new TokenBufferDeserializer(),
};
}
public static ValueInstantiator findValueInstantiator(DeserializationConfig config,
BeanDescription beanDesc)
{
if (beanDesc.getBeanClass() == JsonLocation.class) {
return new JsonLocationInstantiator();
}
return null;
}
/*
/**********************************************************
/* Deserializer implementations
/**********************************************************
*/
/**
* Deserializer for {@link JavaType} values.
*/
public static class JavaTypeDeserializer
extends StdScalarDeserializer<JavaType>
{
public JavaTypeDeserializer() { super(JavaType.class); }
@Override
public JavaType deserialize(JsonParser jp, DeserializationContext ctxt)
throws IOException, JsonProcessingException
{
JsonToken curr = jp.getCurrentToken();
// Usually should just get string value:
if (curr == JsonToken.VALUE_STRING) {
String str = jp.getText().trim();
if (str.length() == 0) {
return getEmptyValue();
}
return ctxt.getTypeFactory().constructFromCanonical(str);
}
// or occasionally just embedded object maybe
if (curr == JsonToken.VALUE_EMBEDDED_OBJECT) {
return (JavaType) jp.getEmbeddedObject();
}
throw ctxt.mappingException(_valueClass);
}
}
/**
* For {@link JsonLocation}, we should be able to just implement
* {@link ValueInstantiator} (not that explicit one would be very
* hard but...)
*/
public static class JsonLocationInstantiator extends ValueInstantiator
{
@Override
public String getValueTypeDesc() {
return JsonLocation.class.getName();
}
@Override
public boolean canCreateFromObjectWith() { return true; }
@Override
public CreatorProperty[] getFromObjectArguments(DeserializationConfig config) {
JavaType intType = config.constructType(Integer.TYPE);
JavaType longType = config.constructType(Long.TYPE);
return new CreatorProperty[] {
new CreatorProperty("sourceRef", config.constructType(Object.class), null, null, null, 0, null),
new CreatorProperty("byteOffset", longType, null, null, null, 1, null),
new CreatorProperty("charOffset", longType, null, null, null, 2, null),
new CreatorProperty("lineNr", intType, null, null, null, 3, null),
new CreatorProperty("columnNr", intType, null, null, null, 4, null)
};
}
@Override
public Object createFromObjectWith(DeserializationContext ctxt, Object[] args) {
return new JsonLocation(args[0], _long(args[1]), _long(args[2]),
_int(args[3]), _int(args[4]));
}
private final static long _long(Object o) {
return (o == null) ? 0L : ((Number) o).longValue();
}
private final static int _int(Object o) {
return (o == null) ? 0 : ((Number) o).intValue();
}
}
/**
* We also want to directly support deserialization of {@link TokenBuffer}.
*<p>
* Note that we use scalar deserializer base just because we claim
* to be of scalar for type information inclusion purposes; actual
* underlying content can be of any (Object, Array, scalar) type.
*/
@JacksonStdImpl
public static class TokenBufferDeserializer
extends StdScalarDeserializer<TokenBuffer>
{
public TokenBufferDeserializer() { super(TokenBuffer.class); }
@Override
public TokenBuffer deserialize(JsonParser jp, DeserializationContext ctxt)
throws IOException, JsonProcessingException
{
TokenBuffer tb = new TokenBuffer(jp.getCodec());
// quite simple, given that TokenBuffer is a JsonGenerator:
tb.copyCurrentStructure(jp);
return tb;
}
}
}
|