View Javadoc
1   package edu.internet2.middleware.grouperClientExt.com.fasterxml.jackson.databind.deser.impl;
2   
3   import java.io.IOException;
4   import java.lang.annotation.Annotation;
5   import java.lang.reflect.Method;
6   
7   import edu.internet2.middleware.grouperClientExt.com.fasterxml.jackson.core.JsonParser;
8   import edu.internet2.middleware.grouperClientExt.com.fasterxml.jackson.core.JsonToken;
9   
10  import edu.internet2.middleware.grouperClientExt.com.fasterxml.jackson.databind.*;
11  import edu.internet2.middleware.grouperClientExt.com.fasterxml.jackson.databind.deser.NullValueProvider;
12  import edu.internet2.middleware.grouperClientExt.com.fasterxml.jackson.databind.deser.SettableBeanProperty;
13  import edu.internet2.middleware.grouperClientExt.com.fasterxml.jackson.databind.introspect.AnnotatedMember;
14  import edu.internet2.middleware.grouperClientExt.com.fasterxml.jackson.databind.introspect.AnnotatedMethod;
15  import edu.internet2.middleware.grouperClientExt.com.fasterxml.jackson.databind.introspect.BeanPropertyDefinition;
16  import edu.internet2.middleware.grouperClientExt.com.fasterxml.jackson.databind.jsontype.TypeDeserializer;
17  import edu.internet2.middleware.grouperClientExt.com.fasterxml.jackson.databind.util.Annotations;
18  
19  /**
20   * This concrete sub-class implements Collection or Map property that is
21   * indirectly by getting the property value and directly modifying it.
22   */
23  public final class SetterlessProperty
24      extends SettableBeanProperty
25  {
26      private static final long serialVersionUID = 1L;
27  
28      protected final AnnotatedMethod _annotated;
29  
30      /**
31       * Get method for accessing property value used to access property
32       * (of Collection or Map type) to modify.
33       */
34      protected final Method _getter;
35  
36      public SetterlessProperty(BeanPropertyDefinition propDef, JavaType type,
37              TypeDeserializer typeDeser, Annotations contextAnnotations, AnnotatedMethod method)
38      {
39          super(propDef, type, typeDeser, contextAnnotations);
40          _annotated = method;
41          _getter = method.getAnnotated();
42      }
43  
44      protected SetterlessProperty/../../../../../../../../../edu/internet2/middleware/grouperClientExt/com/fasterxml/jackson/databind/deser/impl/SetterlessProperty.html#SetterlessProperty">SetterlessProperty(SetterlessProperty src, JsonDeserializer<?> deser,
45              NullValueProvider nva) {
46          super(src, deser, nva);
47          _annotated = src._annotated;
48          _getter = src._getter;
49      }
50  
51      protected SetterlessProperty/../../../../../../../../../edu/internet2/middleware/grouperClientExt/com/fasterxml/jackson/databind/deser/impl/SetterlessProperty.html#SetterlessProperty">SetterlessProperty(SetterlessProperty src, PropertyName newName) {
52          super(src, newName);
53          _annotated = src._annotated;
54          _getter = src._getter;
55      }
56  
57      @Override
58      public SettableBeanProperty withName(PropertyName newName) {
59          return new SetterlessProperty(this, newName);
60      }
61  
62      @Override
63      public SettableBeanProperty withValueDeserializer(JsonDeserializer<?> deser) {
64          if (_valueDeserializer == deser) {
65              return this;
66          }
67          // 07-May-2019, tatu: As per [databind#2303], must keep VD/NVP in-sync if they were
68          NullValueProvider nvp = (_valueDeserializer == _nullProvider) ? deser : _nullProvider;
69          return new SetterlessProperty(this, deser, nvp);
70      }
71  
72      @Override
73      public SettableBeanProperty withNullProvider(NullValueProvider nva) {
74          return new SetterlessProperty(this, _valueDeserializer, nva);
75      }
76  
77      @Override
78      public void fixAccess(DeserializationConfig config) {
79          _annotated.fixAccess(
80                  config.isEnabled(MapperFeature.OVERRIDE_PUBLIC_ACCESS_MODIFIERS));
81      }
82  
83      /*
84      /**********************************************************
85      /* BeanProperty impl
86      /**********************************************************
87       */
88      
89      @Override
90      public <A extends Annotation> A getAnnotation(Class<A> acls) {
91          return _annotated.getAnnotation(acls);
92      }
93  
94      @Override public AnnotatedMember getMember() {  return _annotated; }
95  
96      /*
97      /**********************************************************
98      /* Overridden methods
99      /**********************************************************
100      */
101     
102     @Override
103     public final void deserializeAndSet(JsonParser p, DeserializationContext ctxt,
104             Object instance) throws IOException
105     {
106         if (p.hasToken(JsonToken.VALUE_NULL)) {
107             // Hmmh. Is this a problem? We won't be setting anything, so it's
108             // equivalent of empty Collection/Map in this case
109             return;
110         }
111         // For [databind#501] fix we need to implement this but:
112         if (_valueTypeDeserializer != null) {
113             ctxt.reportBadDefinition(getType(), String.format(
114                     "Problem deserializing 'setterless' property (\"%s\"): no way to handle typed deser with setterless yet",
115                     getName()));
116 //            return _valueDeserializer.deserializeWithType(p, ctxt, _valueTypeDeserializer);
117         }
118         // Ok: then, need to fetch Collection/Map to modify:
119         Object toModify;
120         try {
121             toModify = _getter.invoke(instance, (Object[]) null);
122         } catch (Exception e) {
123             _throwAsIOE(p, e);
124             return; // never gets here
125         }
126         // Note: null won't work, since we can't then inject anything in. At least
127         // that's not good in common case. However, theoretically the case where
128         // we get JSON null might be compatible. If so, implementation could be changed.
129         if (toModify == null) {
130             ctxt.reportBadDefinition(getType(), String.format(
131                     "Problem deserializing 'setterless' property '%s': get method returned null",
132                     getName()));
133         }
134         _valueDeserializer.deserialize(p, ctxt, toModify);
135     }
136 
137     @Override
138     public Object deserializeSetAndReturn(JsonParser p,
139     		DeserializationContext ctxt, Object instance) throws IOException
140     {
141         deserializeAndSet(p, ctxt, instance);
142         return instance;
143     }
144 
145     @Override
146     public final void set(Object instance, Object value) throws IOException {
147         throw new UnsupportedOperationException("Should never call `set()` on setterless property ('"+getName()+"')");
148     }
149 
150     @Override
151     public Object setAndReturn(Object instance, Object value) throws IOException
152     {
153         set(instance, value);
154         return instance;
155     }
156 }