blob: 0a849c0c148b3d614b6b61b2aacea5a414841712 [file] [log] [blame]
Tatu Salorantae4f23bb2011-12-23 00:31:35 -08001package com.fasterxml.jackson.databind.deser.std;
2
3import java.io.IOException;
4import java.util.*;
5
Tatu Saloranta8ac635b2011-12-23 09:05:39 -08006import com.fasterxml.jackson.core.*;
Tatu Salorantae4f23bb2011-12-23 00:31:35 -08007
Tatu333a7f22012-01-17 14:54:44 -08008import com.fasterxml.jackson.databind.*;
Tatubf355ca2012-01-24 14:46:25 -08009import com.fasterxml.jackson.databind.deser.ResolvableDeserializer;
Tatu Salorantadf6302f2011-12-23 20:05:35 -080010import com.fasterxml.jackson.databind.jsontype.TypeDeserializer;
Tatu Salorantae4f23bb2011-12-23 00:31:35 -080011
12/**
13 *
14 * <p>
15 * Note: casting within this class is all messed up -- just could not figure out a way
16 * to properly deal with recursive definition of "EnumSet<K extends Enum<K>, V>
17 *
18 * @author tsaloranta
Tatu Salorantae4f23bb2011-12-23 00:31:35 -080019 */
20@SuppressWarnings("rawtypes")
21public class EnumSetDeserializer
22 extends StdDeserializer<EnumSet<?>>
Tatubf355ca2012-01-24 14:46:25 -080023 implements ResolvableDeserializer
Tatu Salorantae4f23bb2011-12-23 00:31:35 -080024{
Tatubf355ca2012-01-24 14:46:25 -080025 protected final JavaType _enumType;
26
27 protected final BeanProperty _property;
28
Tatu Salorantae4f23bb2011-12-23 00:31:35 -080029 protected final Class<Enum> _enumClass;
30
Tatubf355ca2012-01-24 14:46:25 -080031 protected JsonDeserializer<Enum<?>> _enumDeserializer;
Tatu Salorantae4f23bb2011-12-23 00:31:35 -080032
33 @SuppressWarnings("unchecked" )
Tatubf355ca2012-01-24 14:46:25 -080034 public EnumSetDeserializer(JavaType enumType, BeanProperty prop,
35 JsonDeserializer<?> deser)
Tatu Salorantae4f23bb2011-12-23 00:31:35 -080036 {
37 super(EnumSet.class);
Tatubf355ca2012-01-24 14:46:25 -080038 _enumType = enumType;
39 _property = prop;
40 _enumClass = (Class<Enum>) enumType.getRawClass();
Tatu333a7f22012-01-17 14:54:44 -080041 _enumDeserializer = (JsonDeserializer<Enum<?>>) deser;
Tatu Salorantae4f23bb2011-12-23 00:31:35 -080042 }
43
Tatu Saloranta530067b2011-12-28 10:35:22 -080044 /**
45 * Because of costs associated with constructing Enum resolvers,
46 * let's cache instances by default.
47 */
48 @Override
49 public boolean isCachable() { return true; }
50
Tatubf355ca2012-01-24 14:46:25 -080051 @SuppressWarnings("unchecked")
52 @Override
53 public void resolve(DeserializationContext ctxt) throws JsonMappingException
54 {
55 if (_enumDeserializer == null) {
56 _enumDeserializer = (JsonDeserializer<Enum<?>>)(JsonDeserializer<?>)
57 ctxt.findValueDeserializer(_enumType, _property);
58 }
59 }
60
Tatu Salorantae4f23bb2011-12-23 00:31:35 -080061 @SuppressWarnings("unchecked")
62 @Override
63 public EnumSet<?> deserialize(JsonParser jp, DeserializationContext ctxt)
64 throws IOException, JsonProcessingException
65 {
66 // Ok: must point to START_ARRAY (or equivalent)
67 if (!jp.isExpectedStartArrayToken()) {
68 throw ctxt.mappingException(EnumSet.class);
69 }
70 EnumSet result = constructSet();
71 JsonToken t;
72
73 while ((t = jp.nextToken()) != JsonToken.END_ARRAY) {
74 /* What to do with nulls? Fail or ignore? Fail, for now
75 * (note: would fail if we passed it to EnumDeserializer, too,
76 * but in general nulls should never be passed to non-container
77 * deserializers)
78 */
79 if (t == JsonToken.VALUE_NULL) {
80 throw ctxt.mappingException(_enumClass);
81 }
82 Enum<?> value = _enumDeserializer.deserialize(jp, ctxt);
83 result.add(value);
84 }
85 return result;
86 }
87
88 @Override
89 public Object deserializeWithType(JsonParser jp, DeserializationContext ctxt,
90 TypeDeserializer typeDeserializer)
91 throws IOException, JsonProcessingException
92 {
93 return typeDeserializer.deserializeTypedFromArray(jp, ctxt);
94 }
95
96 @SuppressWarnings("unchecked")
97 private EnumSet constructSet()
98 {
99 // superbly ugly... but apparently necessary
100 return EnumSet.noneOf(_enumClass);
101 }
102}