/** * Method that will construct a regular bean property setter using the given setter method. * * @return Property constructed, if any; or null to indicate that there should be no property * based on given definitions. */ protected SettableBeanProperty constructSettableProperty( DeserializationContext ctxt, BeanDescription beanDesc, BeanPropertyDefinition propDef, Type jdkType) throws JsonMappingException { // need to ensure method is callable (for non-public) AnnotatedMember mutator = propDef.getMutator(); if (ctxt.canOverrideAccessModifiers()) { mutator.fixAccess(); } // note: this works since we know there's exactly one argument for methods JavaType t0 = beanDesc.resolveType(jdkType); BeanProperty.Std property = new BeanProperty.Std(propDef.getName(), t0, beanDesc.getClassAnnotations(), mutator); JavaType type = resolveType(ctxt, beanDesc, t0, mutator); // did type change? if (type != t0) { property = property.withType(type); } /* First: does the Method specify the deserializer to use? * If so, let's use it. */ JsonDeserializer<Object> propDeser = findDeserializerFromAnnotation(ctxt, mutator); type = modifyTypeByAnnotation(ctxt, mutator, type); TypeDeserializer typeDeser = type.getTypeHandler(); SettableBeanProperty prop; if (mutator instanceof AnnotatedMethod) { prop = new MethodProperty( propDef, type, typeDeser, beanDesc.getClassAnnotations(), (AnnotatedMethod) mutator); } else { prop = new FieldProperty( propDef, type, typeDeser, beanDesc.getClassAnnotations(), (AnnotatedField) mutator); } if (propDeser != null) { prop = prop.withValueDeserializer(propDeser); } // [JACKSON-235]: need to retain name of managed forward references: AnnotationIntrospector.ReferenceProperty ref = propDef.findReferenceType(); if (ref != null && ref.isManagedReference()) { prop.setManagedReferenceName(ref.getName()); } return prop; }
public void testSimpleWithType() { // first for serialization; should base choice on getter POJOPropertiesCollector coll = collector(mapper, TypeTestBean.class, true); List<BeanPropertyDefinition> props = coll.getProperties(); assertEquals(1, props.size()); assertEquals("value", props.get(0).getName()); AnnotatedMember m = props.get(0).getAccessor(); assertTrue(m instanceof AnnotatedMethod); assertEquals(Integer.class, m.getRawType()); // then for deserialization; prefer ctor param coll = collector(mapper, TypeTestBean.class, false); props = coll.getProperties(); assertEquals(1, props.size()); assertEquals("value", props.get(0).getName()); m = props.get(0).getMutator(); assertEquals(AnnotatedParameter.class, m.getClass()); assertEquals(String.class, m.getRawType()); }
/** * Method called locate all members used for value injection (if any), constructor {@link * com.fasterxml.jackson.databind.deser.impl.ValueInjector} instances, and add them to builder. */ protected void addInjectables( DeserializationContext ctxt, BeanDescription beanDesc, BeanDeserializerBuilder builder) throws JsonMappingException { Map<Object, AnnotatedMember> raw = beanDesc.findInjectables(); if (raw != null) { boolean fixAccess = ctxt.canOverrideAccessModifiers(); for (Map.Entry<Object, AnnotatedMember> entry : raw.entrySet()) { AnnotatedMember m = entry.getValue(); if (fixAccess) { m.fixAccess(); // to ensure we can call it } builder.addInjectable( m.getName(), beanDesc.resolveType(m.getGenericType()), beanDesc.getClassAnnotations(), m, entry.getKey()); } } }
/** * Method that will find if bean has any managed- or back-reference properties, and if so add them * to bean, to be linked during resolution phase. */ protected void addReferenceProperties( DeserializationContext ctxt, BeanDescription beanDesc, BeanDeserializerBuilder builder) throws JsonMappingException { // and then back references, not necessarily found as regular properties Map<String, AnnotatedMember> refs = beanDesc.findBackReferenceProperties(); if (refs != null) { for (Map.Entry<String, AnnotatedMember> en : refs.entrySet()) { String name = en.getKey(); AnnotatedMember m = en.getValue(); Type genericType; if (m instanceof AnnotatedMethod) { genericType = ((AnnotatedMethod) m).getGenericParameterType(0); } else { genericType = m.getRawType(); } SimpleBeanPropertyDefinition propDef = new SimpleBeanPropertyDefinition(m); builder.addBackReferenceProperty( name, constructSettableProperty(ctxt, beanDesc, propDef, genericType)); } } }
@Override public Object findInjectableValueId(AnnotatedMember m) { JacksonInject ann = _findAnnotation(m, JacksonInject.class); if (ann == null) { return null; } /* Empty String means that we should use name of declared * value class. */ String id = ann.value(); if (id.length() == 0) { // slight complication; for setters, type if (!(m instanceof AnnotatedMethod)) { return m.getRawType().getName(); } AnnotatedMethod am = (AnnotatedMethod) m; if (am.getParameterCount() == 0) { return m.getRawType().getName(); } return am.getRawParameterType(0).getName(); } return id; }