1 package com.fasterxml.jackson.databind.introspect;
2
3 import java.util.Collection;
4 import java.util.Map;
5
6 import com.fasterxml.jackson.databind.AnnotationIntrospector;
7 import com.fasterxml.jackson.databind.DeserializationConfig;
8 import com.fasterxml.jackson.databind.JavaType;
9 import com.fasterxml.jackson.databind.JsonNode;
10 import com.fasterxml.jackson.databind.SerializationConfig;
11 import com.fasterxml.jackson.databind.annotation.JsonPOJOBuilder;
12 import com.fasterxml.jackson.databind.cfg.MapperConfig;
13 import com.fasterxml.jackson.databind.type.SimpleType;
14 import com.fasterxml.jackson.databind.util.ClassUtil;
15
16 public class BasicClassIntrospector
17 extends ClassIntrospector
18 implements java.io.Serializable
19 {
20 private static final long serialVersionUID = 2L;
21
22 private final static Class<?> CLS_OBJECT = Object.class;
23 private final static Class<?> CLS_STRING = String.class;
24 private final static Class<?> CLS_JSON_NODE = JsonNode.class;
25
26
34 protected final static BasicBeanDescription STRING_DESC;
35 static {
36 STRING_DESC = BasicBeanDescription.forOtherUse(null, SimpleType.constructUnsafe(String.class),
37 AnnotatedClassResolver.createPrimordial(CLS_STRING));
38 }
39 protected final static BasicBeanDescription BOOLEAN_DESC;
40 static {
41 BOOLEAN_DESC = BasicBeanDescription.forOtherUse(null, SimpleType.constructUnsafe(Boolean.TYPE),
42 AnnotatedClassResolver.createPrimordial(Boolean.TYPE));
43 }
44 protected final static BasicBeanDescription INT_DESC;
45 static {
46 INT_DESC = BasicBeanDescription.forOtherUse(null, SimpleType.constructUnsafe(Integer.TYPE),
47 AnnotatedClassResolver.createPrimordial(Integer.TYPE));
48 }
49 protected final static BasicBeanDescription LONG_DESC;
50 static {
51 LONG_DESC = BasicBeanDescription.forOtherUse(null, SimpleType.constructUnsafe(Long.TYPE),
52 AnnotatedClassResolver.createPrimordial(Long.TYPE));
53 }
54 protected final static BasicBeanDescription OBJECT_DESC;
55 static {
56 OBJECT_DESC = BasicBeanDescription.forOtherUse(null, SimpleType.constructUnsafe(Object.class),
57 AnnotatedClassResolver.createPrimordial(CLS_OBJECT));
58 }
59
60
65
66 public BasicClassIntrospector() {
67 }
68
69 @Override
70 public ClassIntrospector copy() {
71 return new BasicClassIntrospector();
72 }
73
74
79
80 @Override
81 public BasicBeanDescription forSerialization(SerializationConfig config,
82 JavaType type, MixInResolver r)
83 {
84
85 BasicBeanDescription desc = _findStdTypeDesc(config, type);
86 if (desc == null) {
87
88
89 desc = _findStdJdkCollectionDesc(config, type);
90 if (desc == null) {
91 desc = BasicBeanDescription.forSerialization(collectProperties(config,
92 type, r, true, "set"));
93 }
94 }
95 return desc;
96 }
97
98 @Override
99 public BasicBeanDescription forDeserialization(DeserializationConfig config,
100 JavaType type, MixInResolver r)
101 {
102
103 BasicBeanDescription desc = _findStdTypeDesc(config, type);
104 if (desc == null) {
105
106
107 desc = _findStdJdkCollectionDesc(config, type);
108 if (desc == null) {
109 desc = BasicBeanDescription.forDeserialization(collectProperties(config,
110 type, r, false, "set"));
111 }
112 }
113 return desc;
114 }
115
116 @Override
117 public BasicBeanDescription forDeserializationWithBuilder(DeserializationConfig config,
118 JavaType type, MixInResolver r)
119 {
120
121 return BasicBeanDescription.forDeserialization(collectPropertiesWithBuilder(config,
122 type, r, false));
123 }
124
125 @Override
126 public BasicBeanDescription forCreation(DeserializationConfig config,
127 JavaType type, MixInResolver r)
128 {
129 BasicBeanDescription desc = _findStdTypeDesc(config, type);
130 if (desc == null) {
131
132
133 desc = _findStdJdkCollectionDesc(config, type);
134 if (desc == null) {
135 desc = BasicBeanDescription.forDeserialization(
136 collectProperties(config, type, r, false, "set"));
137 }
138 }
139 return desc;
140 }
141
142 @Override
143 public BasicBeanDescription forClassAnnotations(MapperConfig<?> config,
144 JavaType type, MixInResolver r)
145 {
146 BasicBeanDescription desc = _findStdTypeDesc(config, type);
147 if (desc == null) {
148 desc = BasicBeanDescription.forOtherUse(config, type,
149 _resolveAnnotatedClass(config, type, r));
150 }
151 return desc;
152 }
153
154 @Override
155 public BasicBeanDescription forDirectClassAnnotations(MapperConfig<?> config,
156 JavaType type, MixInResolver r)
157 {
158 BasicBeanDescription desc = _findStdTypeDesc(config, type);
159 if (desc == null) {
160 desc = BasicBeanDescription.forOtherUse(config, type,
161 _resolveAnnotatedWithoutSuperTypes(config, type, r));
162 }
163 return desc;
164 }
165
166
171
172 protected POJOPropertiesCollector collectProperties(MapperConfig<?> config,
173 JavaType type, MixInResolver r, boolean forSerialization,
174 String mutatorPrefix)
175 {
176 return constructPropertyCollector(config,
177 _resolveAnnotatedClass(config, type, r),
178 type, forSerialization, mutatorPrefix);
179 }
180
181 protected POJOPropertiesCollector collectPropertiesWithBuilder(MapperConfig<?> config,
182 JavaType type, MixInResolver r, boolean forSerialization)
183 {
184 AnnotatedClass ac = _resolveAnnotatedClass(config, type, r);
185 AnnotationIntrospector ai = config.isAnnotationProcessingEnabled() ? config.getAnnotationIntrospector() : null;
186 JsonPOJOBuilder.Value builderConfig = (ai == null) ? null : ai.findPOJOBuilderConfig(ac);
187 String mutatorPrefix = (builderConfig == null) ? JsonPOJOBuilder.DEFAULT_WITH_PREFIX : builderConfig.withPrefix;
188 return constructPropertyCollector(config, ac, type, forSerialization, mutatorPrefix);
189 }
190
191
195 protected POJOPropertiesCollector constructPropertyCollector(MapperConfig<?> config,
196 AnnotatedClass ac, JavaType type, boolean forSerialization, String mutatorPrefix)
197 {
198 return new POJOPropertiesCollector(config, forSerialization, type, ac, mutatorPrefix);
199 }
200
201
205 protected BasicBeanDescription _findStdTypeDesc(MapperConfig<?> config, JavaType type)
206 {
207 Class<?> cls = type.getRawClass();
208 if (cls.isPrimitive()) {
209 if (cls == Integer.TYPE) {
210 return INT_DESC;
211 }
212 if (cls == Long.TYPE) {
213 return LONG_DESC;
214 }
215 if (cls == Boolean.TYPE) {
216 return BOOLEAN_DESC;
217 }
218 } else if (ClassUtil.isJDKClass(cls)) {
219 if (cls == CLS_OBJECT) {
220 return OBJECT_DESC;
221 }
222 if (cls == CLS_STRING) {
223 return STRING_DESC;
224 }
225 if (cls == Integer.class) {
226 return INT_DESC;
227 }
228 if (cls == Long.class) {
229 return LONG_DESC;
230 }
231 if (cls == Boolean.class) {
232 return BOOLEAN_DESC;
233 }
234 } else if (CLS_JSON_NODE.isAssignableFrom(cls)) {
235 return BasicBeanDescription.forOtherUse(config, type,
236 AnnotatedClassResolver.createPrimordial(cls));
237 }
238 return null;
239 }
240
241
246 protected boolean _isStdJDKCollection(JavaType type)
247 {
248 if (!type.isContainerType() || type.isArrayType()) {
249 return false;
250 }
251 Class<?> raw = type.getRawClass();
252 if (ClassUtil.isJDKClass(raw)) {
253
254
255 if (Collection.class.isAssignableFrom(raw)
256 || Map.class.isAssignableFrom(raw)) {
257 return true;
258 }
259 }
260 return false;
261 }
262
263 protected BasicBeanDescription _findStdJdkCollectionDesc(MapperConfig<?> cfg, JavaType type)
264 {
265 if (_isStdJDKCollection(type)) {
266 return BasicBeanDescription.forOtherUse(cfg, type,
267 _resolveAnnotatedClass(cfg, type, cfg));
268 }
269 return null;
270 }
271
272
275 protected AnnotatedClass _resolveAnnotatedClass(MapperConfig<?> config,
276 JavaType type, MixInResolver r) {
277 return AnnotatedClassResolver.resolve(config, type, r);
278 }
279
280
283 protected AnnotatedClass _resolveAnnotatedWithoutSuperTypes(MapperConfig<?> config,
284 JavaType type, MixInResolver r) {
285 return AnnotatedClassResolver.resolveWithoutSuperTypes(config, type, r);
286 }
287 }
288