下面列出了com.fasterxml.jackson.databind.deser.ValueInstantiators#com.fasterxml.jackson.databind.introspect.AnnotatedMethod 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
protected Optional<String> getName(Method method) {
ObjectMapper objectMapper = context.getObjectMapper();
SerializationConfig serializationConfig = objectMapper.getSerializationConfig();
if (serializationConfig != null && serializationConfig.getPropertyNamingStrategy() != null) {
String name = ClassUtils.getGetterFieldName(method);
Annotation[] declaredAnnotations = method.getDeclaredAnnotations();
AnnotationMap annotationMap = buildAnnotationMap(declaredAnnotations);
int paramsLength = method.getParameterAnnotations().length;
AnnotationMap[] paramAnnotations = new AnnotationMap[paramsLength];
for (int i = 0; i < paramsLength; i++) {
AnnotationMap parameterAnnotationMap = buildAnnotationMap(method.getParameterAnnotations()[i]);
paramAnnotations[i] = parameterAnnotationMap;
}
AnnotatedClass annotatedClass = AnnotatedClassBuilder.build(method.getDeclaringClass(), serializationConfig);
AnnotatedMethod annotatedField = AnnotatedMethodBuilder.build(annotatedClass, method, annotationMap, paramAnnotations);
return Optional.of(serializationConfig.getPropertyNamingStrategy().nameForGetterMethod(serializationConfig, annotatedField, name));
}
return Optional.empty();
}
@SuppressWarnings("unchecked")
public void set(Object instance, Object propName, Object value) throws IOException
{
try {
// if annotation in the field (only map is supported now)
if (_setterIsField) {
AnnotatedField field = (AnnotatedField) _setter;
Map<Object,Object> val = (Map<Object,Object>) field.getValue(instance);
/* 01-Jun-2016, tatu: At this point it is not quite clear what to do if
* field is `null` -- we cannot necessarily count on zero-args
* constructor except for a small set of types, so for now just
* ignore if null. May need to figure out something better in future.
*/
if (val != null) {
// add the property key and value
val.put(propName, value);
}
} else {
// note: cannot use 'setValue()' due to taking 2 args
((AnnotatedMethod) _setter).callOnWith(instance, propName, value);
}
} catch (Exception e) {
_throwAsIOE(e, propName, value);
}
}
/**
* This method was added to address the need to weed out
* CGLib-injected "getCallbacks" method.
* At this point caller has detected a potential getter method
* with name "getCallbacks" and we need to determine if it is
* indeed injectect by Cglib. We do this by verifying that the
* result type is "net.sf.cglib.proxy.Callback[]"
*/
protected static boolean isCglibGetCallbacks(AnnotatedMethod am)
{
Class<?> rt = am.getRawType();
// Ok, first: must return an array type
if (rt.isArray()) {
/* And that type needs to be "net.sf.cglib.proxy.Callback".
* Theoretically could just be a type that implements it, but
* for now let's keep things simple, fix if need be.
*/
Class<?> compType = rt.getComponentType();
// Actually, let's just verify it's a "net.sf.cglib.*" class/interface
String pkgName = ClassUtil.getPackageName(compType);
if (pkgName != null) {
if (pkgName.contains(".cglib")) {
return pkgName.startsWith("net.sf.cglib")
// also, as per [JACKSON-177]
|| pkgName.startsWith("org.hibernate.repackage.cglib")
// and [core#674]
|| pkgName.startsWith("org.springframework.cglib");
}
}
}
return false;
}
/**
* Extract name to be used by Katharsis from getter's name. It uses
* {@link ResourceFieldNameTransformer#getMethodName(Method)}, {@link JsonProperty} annotation and
* {@link PropertyNamingStrategy}.
*
* @param method method to extract name
* @return method name
*/
public String getName(Method method) {
String name = getMethodName(method);
if (method.isAnnotationPresent(JsonProperty.class) &&
!"".equals(method.getAnnotation(JsonProperty.class).value())) {
name = method.getAnnotation(JsonProperty.class).value();
} else if (serializationConfig != null && serializationConfig.getPropertyNamingStrategy() != null) {
Annotation[] declaredAnnotations = method.getDeclaredAnnotations();
AnnotationMap annotationMap = buildAnnotationMap(declaredAnnotations);
int paramsLength = method.getParameterAnnotations().length;
AnnotationMap[] paramAnnotations = new AnnotationMap[paramsLength];
for (int i = 0; i < paramsLength; i++) {
AnnotationMap parameterAnnotationMap = buildAnnotationMap(method.getParameterAnnotations()[i]);
paramAnnotations[i] = parameterAnnotationMap;
}
AnnotatedClass annotatedClass = AnnotatedClassBuilder.build(method.getDeclaringClass(), serializationConfig);
AnnotatedMethod annotatedField = AnnotatedMethodBuilder.build(annotatedClass, method, annotationMap, paramAnnotations);
name = serializationConfig.getPropertyNamingStrategy().nameForGetterMethod(serializationConfig, annotatedField, name);
}
return name;
}
@Override
public Object findDeserializationConverter(Annotated a) {
JtToMap ann = a.getAnnotation(JtToMap.class);
if (ann == null) {
return null;
}
JavaType javaType = a.getType();
if(a instanceof AnnotatedMethod) {
AnnotatedMethod am = (AnnotatedMethod) a;
if(am.getParameterCount() == 1) {
javaType = am.getParameterType(0);
} else {
throw new RuntimeException("Invalid property setter: " + am.getAnnotated());
}
}
return new DeserializationConverterImpl(ann, new Ctx(a, javaType));
}
@Override
public Object findDeserializationConverter(Annotated a) {
Class<? extends PropertyInterceptor>[] interceptors = getInterceptors(a);
if (interceptors == null) {
return null;
}
JavaType javaType = a.getType();
if(a instanceof AnnotatedMethod) {
AnnotatedMethod am = (AnnotatedMethod) a;
if(am.getParameterCount() == 1) {
javaType = am.getParameterType(0);
} else {
throw new RuntimeException("Invalid property setter: " + am.getAnnotated());
}
}
return new KvInterceptorsDeserializationConverter(interceptors, new KvPropertyContextImpl(a, javaType));
}
protected AnnotatedMethod _findFactory(AnnotatedClass cls, String name, Class<?>... argTypes)
{
final int argCount = argTypes.length;
for (AnnotatedMethod method : cls.getFactoryMethods()) {
if (!name.equals(method.getName())
|| (method.getParameterCount() != argCount)) {
continue;
}
for (int i = 0; i < argCount; ++i) {
Class<?> argType = method.getParameter(i).getRawType();
if (!argType.isAssignableFrom(argTypes[i])) {
continue;
}
}
return method;
}
return null;
}
public void testSingleIntAccessorGeneration() throws Exception
{
Method method = Bean1.class.getDeclaredMethod("getX");
AnnotatedMethod annMethod = new AnnotatedMethod(null, method, null, null);
PropertyAccessorCollector coll = new PropertyAccessorCollector(Bean1.class);
BeanPropertyWriter bpw = new BeanPropertyWriter(SimpleBeanPropertyDefinition
.construct(MAPPER_CONFIG, annMethod, new PropertyName("x")),
annMethod, null,
null,
null, null, null,
false, null, null);
coll.addIntGetter(bpw);
BeanPropertyAccessor acc = coll.findAccessor(null);
Bean1 bean = new Bean1();
int value = acc.intGetter(bean, 0);
assertEquals(bean.getX(), value);
}
protected AnnotatedMethod _findFactory(AnnotatedClass cls, String name, Class<?>... argTypes) {
final int argCount = argTypes.length;
for (AnnotatedMethod method : cls.getFactoryMethods()) {
if (!name.equals(method.getName())
|| (method.getParameterCount() != argCount)) {
continue;
}
for (int i = 0; i < argCount; ++i) {
Class<?> argType = method.getParameter(i).getRawType();
if (!argType.isAssignableFrom(argTypes[i])) {
continue;
}
}
return method;
}
return null;
}
@Override
public void setupModule(SetupContext context) {
context.insertAnnotationIntrospector(new NopAnnotationIntrospector() {
private static final long serialVersionUID = 479313244908256455L;
@Override
public boolean hasIgnoreMarker(AnnotatedMember m) {
if (!(m instanceof AnnotatedMethod)) {
return super.hasIgnoreMarker(m);
}
AnnotatedMethod method = (AnnotatedMethod) m;
return method.getName().startsWith("lambda$") ? true : super.hasIgnoreMarker(m);
}
});
}
@Override
public PropertyName findNameForDeserialization(Annotated annotatedEntity) {
// This logic relies on the fact that Immutables generates setters annotated with @JsonProperty.
// It thus becomes obsolete whenever we move away from Immutables and the deserialization target no longer
// carries those annotations.
JsonProperty propertyAnnotation = _findAnnotation(annotatedEntity, JsonProperty.class);
if (propertyAnnotation != null) {
String jsonFieldName = propertyAnnotation.value();
Preconditions.checkArgument(
KEBAB_CASE_PATTERN.matcher(jsonFieldName).matches(),
"Conjure grammar requires kebab-case field names: %s",
jsonFieldName);
}
if (annotatedEntity instanceof AnnotatedMethod) {
AnnotatedMethod maybeSetter = (AnnotatedMethod) annotatedEntity;
if (maybeSetter.getName().startsWith("set")) {
// As a pre-caution, require that all setters have a JsonProperty annotation.
Preconditions.checkArgument(
_findAnnotation(annotatedEntity, JsonProperty.class) != null,
"All setter ({@code set*}) deserialization targets require @JsonProperty annotations: %s",
maybeSetter.getName());
}
}
return null; // delegate to the next introspector in an AnnotationIntrospectorPair.
}
public static AnnotatedMethod build(final AnnotatedClass annotatedClass, final Method method,
final AnnotationMap annotationMap,
final AnnotationMap[] paramAnnotations) {
final Constructor<?> constructor = AnnotatedMethod.class.getConstructors()[0];
return ExceptionUtil.wrapCatchedExceptions(new Callable<AnnotatedMethod>() {
@Override
public AnnotatedMethod call() throws Exception {
return buildAnnotatedField(annotatedClass, method, annotationMap, paramAnnotations, constructor);
}
}, "Exception while building AnnotatedMethod");
}
private static AnnotatedMethod buildAnnotatedField(AnnotatedClass annotatedClass, Method method,
AnnotationMap annotationMap, AnnotationMap[] paramAnnotations,
Constructor<?> constructor)
throws IllegalAccessException, InstantiationException, InvocationTargetException {
Class<?> firstParameterType = constructor.getParameterTypes()[0];
PreconditionUtil.verify(firstParameterType == AnnotatedClass.class || TypeResolutionContext.class.equals(firstParameterType), CANNOT_FIND_PROPER_CONSTRUCTOR);
return (AnnotatedMethod) constructor.newInstance(annotatedClass, method, annotationMap, paramAnnotations);
}
/**
* Factory method used when Enum instances are to be deserialized
* using a creator (static factory method)
*
* @return Deserializer based on given factory method
*
* @since 2.8
*/
public static JsonDeserializer<?> deserializerForCreator(DeserializationConfig config,
Class<?> enumClass, AnnotatedMethod factory,
ValueInstantiator valueInstantiator, SettableBeanProperty[] creatorProps)
{
if (config.canOverrideAccessModifiers()) {
ClassUtil.checkAndFixAccess(factory.getMember(),
config.isEnabled(MapperFeature.OVERRIDE_PUBLIC_ACCESS_MODIFIERS));
}
return new FactoryBasedEnumDeserializer(enumClass, factory,
factory.getParameterType(0),
valueInstantiator, creatorProps);
}
/**
* Factory method used when Enum instances are to be deserialized
* using a zero-/no-args factory method
*
* @return Deserializer based on given no-args factory method
*
* @since 2.8
*/
public static JsonDeserializer<?> deserializerForNoArgsCreator(DeserializationConfig config,
Class<?> enumClass, AnnotatedMethod factory)
{
if (config.canOverrideAccessModifiers()) {
ClassUtil.checkAndFixAccess(factory.getMember(),
config.isEnabled(MapperFeature.OVERRIDE_PUBLIC_ACCESS_MODIFIERS));
}
return new FactoryBasedEnumDeserializer(enumClass, factory);
}
public FactoryBasedEnumDeserializer(Class<?> cls, AnnotatedMethod f, JavaType paramType,
ValueInstantiator valueInstantiator, SettableBeanProperty[] creatorProps)
{
super(cls);
_factory = f;
_hasArgs = true;
// We'll skip case of `String`, as well as no type (zero-args):
_inputType = paramType.hasRawClass(String.class) ? null : paramType;
_deser = null;
_valueInstantiator = valueInstantiator;
_creatorProps = creatorProps;
}
/**
* @since 2.8
*/
public FactoryBasedEnumDeserializer(Class<?> cls, AnnotatedMethod f)
{
super(cls);
_factory = f;
_hasArgs = false;
_inputType = null;
_deser = null;
_valueInstantiator = null;
_creatorProps = null;
}
public SetterlessProperty(BeanPropertyDefinition propDef, JavaType type,
TypeDeserializer typeDeser, Annotations contextAnnotations, AnnotatedMethod method)
{
super(propDef, type, typeDeser, contextAnnotations);
_annotated = method;
_getter = method.getAnnotated();
}
/**
* Main constructor used both for creating new instances (by
* {@link BeanDeserializer#asArrayDeserializer}) and for
* creating copies with different delegate.
*
* @since 2.9
*/
public BeanAsArrayBuilderDeserializer(BeanDeserializerBase delegate,
JavaType targetType,
SettableBeanProperty[] ordered,
AnnotatedMethod buildMethod)
{
super(delegate);
_delegate = delegate;
_targetType = targetType;
_orderedProperties = ordered;
_buildMethod = buildMethod;
}
/**
* @since 2.5
*/
public static String okNameForGetter(AnnotatedMethod am, boolean stdNaming) {
String name = am.getName();
String str = okNameForIsGetter(am, name, stdNaming);
if (str == null) {
str = okNameForRegularGetter(am, name, stdNaming);
}
return str;
}
/**
* @since 2.5
*/
public static String okNameForRegularGetter(AnnotatedMethod am, String name,
boolean stdNaming)
{
if (name.startsWith("get")) {
/* 16-Feb-2009, tatu: To handle [JACKSON-53], need to block
* CGLib-provided method "getCallbacks". Not sure of exact
* safe criteria to get decent coverage without false matches;
* but for now let's assume there's no reason to use any
* such getter from CGLib.
* But let's try this approach...
*/
if ("getCallbacks".equals(name)) {
if (isCglibGetCallbacks(am)) {
return null;
}
} else if ("getMetaClass".equals(name)) {
// 30-Apr-2009, tatu: Need to suppress serialization of a cyclic reference
if (isGroovyMetaClassGetter(am)) {
return null;
}
}
return stdNaming
? stdManglePropertyName(name, 3)
: legacyManglePropertyName(name, 3);
}
return null;
}
/**
* @since 2.5
*/
public static String okNameForIsGetter(AnnotatedMethod am, String name,
boolean stdNaming)
{
if (name.startsWith("is")) { // plus, must return a boolean
Class<?> rt = am.getRawType();
if (rt == Boolean.class || rt == Boolean.TYPE) {
return stdNaming
? stdManglePropertyName(name, 2)
: legacyManglePropertyName(name, 2);
}
}
return null;
}
/**
* @since 2.5
*/
@Deprecated // since 2.9, not used any more
public static String okNameForSetter(AnnotatedMethod am, boolean stdNaming) {
String name = okNameForMutator(am, "set", stdNaming);
if ((name != null)
// 26-Nov-2009, tatu: need to suppress this internal groovy method
&& (!"metaClass".equals(name) || !isGroovyMetaClassSetter(am))) {
return name;
}
return null;
}
/**
* @since 2.5
*/
public static String okNameForMutator(AnnotatedMethod am, String prefix,
boolean stdNaming) {
String name = am.getName();
if (name.startsWith(prefix)) {
return stdNaming
? stdManglePropertyName(name, prefix.length())
: legacyManglePropertyName(name, prefix.length());
}
return null;
}
/**
* Similar to {@link #isCglibGetCallbacks}, need to suppress
* a cyclic reference.
*/
protected static boolean isGroovyMetaClassSetter(AnnotatedMethod am)
{
Class<?> argType = am.getRawParameterType(0);
String pkgName = ClassUtil.getPackageName(argType);
return (pkgName != null) && pkgName.startsWith("groovy.lang");
}
@Override
public String nameForGetterMethod(MapperConfig<?> config, AnnotatedMethod method,
String defaultName) {
if (method.getDeclaringClass() == this.effectiveType) {
return fieldToJsonMapping
.getOrDefault(defaultName, super.nameForGetterMethod(config, method, defaultName));
} else {
return super.nameForGetterMethod(config, method, defaultName);
}
}
@Override
public String nameForSetterMethod(MapperConfig<?> config, AnnotatedMethod method,
String defaultName) {
if (method.getDeclaringClass() == this.effectiveType) {
return fieldToJsonMapping
.getOrDefault(defaultName, super.nameForSetterMethod(config, method, defaultName));
} else {
return super.nameForSetterMethod(config, method, defaultName);
}
}
private Class<?> rawDeserializationType(Annotated a) {
if (a instanceof AnnotatedMethod) {
AnnotatedMethod am = (AnnotatedMethod) a;
if (am.getParameterCount() == 1) {
return am.getRawParameterType(0);
}
}
return a.getRawType();
}
public static AnnotatedMethod build(AnnotatedClass annotatedClass, Method method, AnnotationMap annotationMap,
AnnotationMap[] paramAnnotations) {
for(Constructor<?> constructor : AnnotatedMethod.class.getConstructors()) {
try {
return buildAnnotatedField(annotatedClass, method, annotationMap, paramAnnotations, constructor);
} catch (IllegalAccessException | InstantiationException | InvocationTargetException e) {
throw new InternalException("Exception while building " + AnnotatedMethod.class.getCanonicalName(), e);
}
}
throw new InternalException(CANNOT_FIND_PROPER_CONSTRUCTOR);
}
private static AnnotatedMethod buildAnnotatedField(AnnotatedClass annotatedClass, Method method,
AnnotationMap annotationMap, AnnotationMap[] paramAnnotations,
Constructor<?> constructor)
throws IllegalAccessException, InstantiationException, InvocationTargetException {
Class<?> firstParameterType = constructor.getParameterTypes()[0];
if (firstParameterType == AnnotatedClass.class ||
"TypeResolutionContext".equals(firstParameterType.getSimpleName())) {
return (AnnotatedMethod) constructor.newInstance(annotatedClass, method, annotationMap, paramAnnotations);
} else {
throw new InternalException(CANNOT_FIND_PROPER_CONSTRUCTOR);
}
}