View Javadoc
1   /*
2    * Licensed under the Apache License, Version 2.0 (the "License");
3    * you may not use this file except in compliance with the License.
4    * You may obtain a copy of the License at
5    *
6    * http://www.apache.org/licenses/LICENSE-2.0
7    *
8    * Unless required by applicable law or agreed to in writing, software
9    * distributed under the License is distributed on an "AS IS" BASIS,
10   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11   * See the License for the specific language governing permissions and
12   * limitations under the License.
13   */
14  package com.addthis.codec.jackson;
15  
16  import java.util.Iterator;
17  
18  import com.fasterxml.jackson.databind.BeanDescription;
19  import com.fasterxml.jackson.databind.DeserializationConfig;
20  import com.fasterxml.jackson.databind.JavaType;
21  import com.fasterxml.jackson.databind.JsonDeserializer;
22  import com.fasterxml.jackson.databind.JsonNode;
23  import com.fasterxml.jackson.databind.deser.BeanDeserializerBase;
24  import com.fasterxml.jackson.databind.deser.BeanDeserializerModifier;
25  import com.fasterxml.jackson.databind.deser.SettableBeanProperty;
26  import com.fasterxml.jackson.databind.deser.std.DelegatingDeserializer;
27  import com.fasterxml.jackson.databind.deser.std.EnumDeserializer;
28  import com.fasterxml.jackson.databind.node.ObjectNode;
29  import com.typesafe.config.Config;
30  import com.typesafe.config.ConfigValue;
31  
32  import org.slf4j.Logger;
33  import org.slf4j.LoggerFactory;
34  
35  public class CodecBeanDeserializerModifier extends BeanDeserializerModifier {
36      private static final Logger log = LoggerFactory.getLogger(CodecBeanDeserializerModifier.class);
37  
38      private final Config globalDefaults;
39      private final boolean modifyEnum;
40  
41      public CodecBeanDeserializerModifier(Config globalDefaults) {
42          this.globalDefaults = globalDefaults;
43          this.modifyEnum = globalDefaults.getBoolean("addthis.codec.jackson.ignore.enum-case");
44      }
45  
46      @Override public JsonDeserializer<?> modifyDeserializer(DeserializationConfig config,
47                                                              BeanDescription beanDesc,
48                                                              JsonDeserializer<?> deserializer) {
49          if (deserializer instanceof DelegatingDeserializer) {
50              JsonDeserializer<?> delegatee = ((DelegatingDeserializer) deserializer).getDelegatee();
51              JsonDeserializer<?> replacementDelegatee = modifyDeserializer(config, beanDesc, delegatee);
52              return deserializer.replaceDelegatee(replacementDelegatee);
53          } else if (deserializer instanceof BeanDeserializerBase) {
54              BeanDeserializerBase beanDeserializer = (BeanDeserializerBase)  deserializer;
55              ObjectNode fieldDefaults = config.getNodeFactory().objectNode();
56              Iterator<SettableBeanProperty> propertyIterator = beanDeserializer.properties();
57              while (propertyIterator.hasNext()) {
58                  SettableBeanProperty prop = propertyIterator.next();
59                  Class<?> declaringClass = prop.getMember().getDeclaringClass();
60                  String canonicalClassName = declaringClass.getCanonicalName();
61                  if ((canonicalClassName != null) && globalDefaults.hasPath(canonicalClassName)) {
62                      Config declarerDefaults = globalDefaults.getConfig(canonicalClassName);
63                      String propertyName = prop.getName();
64                      if (declarerDefaults.hasPath(propertyName)) {
65                          ConfigValue defaultValue = declarerDefaults.getValue(propertyName);
66                          JsonNode fieldDefault = Jackson.configConverter(defaultValue);
67                          fieldDefaults.set(propertyName, fieldDefault);
68                      }
69                  }
70              }
71              return new CodecBeanDeserializer(beanDeserializer, fieldDefaults);
72          } else {
73              return deserializer;
74          }
75      }
76  
77      @Override public JsonDeserializer<?> modifyEnumDeserializer(DeserializationConfig config,
78                                                                  JavaType type,
79                                                                  BeanDescription beanDesc,
80                                                                  JsonDeserializer<?> deserializer) {
81          if (deserializer instanceof DelegatingDeserializer) {
82              JsonDeserializer<?> delegatee = ((DelegatingDeserializer) deserializer).getDelegatee();
83              JsonDeserializer<?> replacementDelegatee = modifyEnumDeserializer(config, type, beanDesc, delegatee);
84              return deserializer.replaceDelegatee(replacementDelegatee);
85          } else if (modifyEnum && (deserializer instanceof EnumDeserializer)) {
86              return new CaseIgnoringEnumDeserializer((EnumDeserializer) deserializer);
87          } else {
88              return deserializer;
89          }
90      }
91  }