1 package com.fasterxml.jackson.module.paramnames;
2
3 import java.lang.reflect.MalformedParametersException;
4 import java.lang.reflect.Parameter;
5
6 import com.fasterxml.jackson.annotation.JsonCreator;
7 import com.fasterxml.jackson.databind.AnnotationIntrospector;
8 import com.fasterxml.jackson.databind.cfg.MapperConfig;
9 import com.fasterxml.jackson.databind.introspect.*;
10
11 /**
12  * Introspector that uses parameter name information provided by the Java Reflection API additions in Java 8 to
13  * determine the parameter name for methods and constructors.
14  *
15  * @author Lovro Pandzic
16  * @see AnnotationIntrospector
17  * @see Parameter
18  */

19 public class ParameterNamesAnnotationIntrospector extends NopAnnotationIntrospector {
20     private static final long serialVersionUID = 1L;
21
22     private final JsonCreator.Mode creatorBinding;
23     private final ParameterExtractor parameterExtractor;
24
25     ParameterNamesAnnotationIntrospector(JsonCreator.Mode creatorBinding, ParameterExtractor parameterExtractor)
26     {
27         this.creatorBinding = creatorBinding;
28         this.parameterExtractor = parameterExtractor;
29     }
30
31     @Override
32     public String findImplicitPropertyName(AnnotatedMember m) {
33         if (m instanceof AnnotatedParameter) {
34             return findParameterName((AnnotatedParameter) m);
35         }
36         return null;
37     }
38
39     private String findParameterName(AnnotatedParameter annotatedParameter) {
40
41         Parameter[] params;
42         try {
43             params = getParameters(annotatedParameter.getOwner());
44         } catch (MalformedParametersException e) {
45             return null;
46         }
47
48         Parameter p = params[annotatedParameter.getIndex()];
49         return p.isNamePresent() ? p.getName() : null;
50     }
51
52     private Parameter[] getParameters(AnnotatedWithParams owner) {
53         if (owner instanceof AnnotatedConstructor) {
54             return parameterExtractor.getParameters(((AnnotatedConstructor) owner).getAnnotated());
55         }
56         if (owner instanceof AnnotatedMethod) {
57             return parameterExtractor.getParameters(((AnnotatedMethod) owner).getAnnotated());
58         }
59
60         return null;
61     }
62
63     /*
64     /**********************************************************
65     /* Creator information handling
66     /**********************************************************
67      */

68
69     @Override
70     public JsonCreator.Mode findCreatorAnnotation(MapperConfig<?> config, Annotated a) {
71         JsonCreator ann = _findAnnotation(a, JsonCreator.class);
72         if (ann != null) {
73             JsonCreator.Mode mode = ann.mode();
74             // but keep in mind that there may be explicit default for this module
75             if ((creatorBinding != null)
76                     && (mode == JsonCreator.Mode.DEFAULT)) {
77                 mode = creatorBinding;
78             }
79             return mode;
80         }
81         return null;
82     }
83
84     @Override
85     @Deprecated // remove AFTER 2.9
86     public JsonCreator.Mode findCreatorBinding(Annotated a) {
87         JsonCreator ann = _findAnnotation(a, JsonCreator.class);
88         if (ann != null) {
89             JsonCreator.Mode mode = ann.mode();
90             if ((creatorBinding != null)
91                     && (mode == JsonCreator.Mode.DEFAULT)) {
92                 mode = creatorBinding;
93             }
94             return mode;
95         }
96         return creatorBinding;
97     }
98
99     @Override
100     @Deprecated // since 2.9
101     public boolean hasCreatorAnnotation(Annotated a)
102     {
103         // 02-Mar-2017, tatu: Copied from base AnnotationIntrospector
104         JsonCreator ann = _findAnnotation(a, JsonCreator.class);
105         if (ann != null) {
106             return (ann.mode() != JsonCreator.Mode.DISABLED);
107         }
108         return false;
109     }
110 }
111