1 package com.fasterxml.jackson.databind.introspect;
2
3 import java.lang.reflect.*;
4
5 import com.fasterxml.jackson.databind.JavaType;
6 import com.fasterxml.jackson.databind.util.ClassUtil;
7
8 public final class AnnotatedConstructor
9     extends AnnotatedWithParams
10 {
11     private static final long serialVersionUID = 1L;
12
13     protected final Constructor<?> _constructor;
14
15     /**
16      * Field that is used to make JDK serialization work with this
17      * object.
18      * 
19      * @since 2.1
20      */

21     protected Serialization _serialization;
22
23     /*
24     /**********************************************************
25     /* Life-cycle
26     /**********************************************************
27      */

28
29     public AnnotatedConstructor(TypeResolutionContext ctxt, Constructor<?> constructor,
30             AnnotationMap classAnn, AnnotationMap[] paramAnn)
31     {
32         super(ctxt, classAnn, paramAnn);
33         if (constructor == null) {
34             throw new IllegalArgumentException("Null constructor not allowed");
35         }
36         _constructor = constructor;
37     }
38
39     /**
40      * Method used for JDK serialization support
41      * @since 2.1
42      */

43     protected AnnotatedConstructor(Serialization ser)
44     {
45         super(nullnullnull);
46         _constructor = null;
47         _serialization = ser;
48     }
49     
50     @Override
51     public AnnotatedConstructor withAnnotations(AnnotationMap ann) {
52         return new AnnotatedConstructor(_typeContext, _constructor, ann, _paramAnnotations);
53     }
54     
55     /*
56     /**********************************************************
57     /* Annotated impl
58     /**********************************************************
59      */

60
61     @Override
62     public Constructor<?> getAnnotated() { return _constructor; }
63
64     @Override
65     public int getModifiers() { return _constructor.getModifiers(); }
66
67     @Override
68     public String getName() { return _constructor.getName(); }
69
70     @Override
71     public JavaType getType() {
72         return _typeContext.resolveType(getRawType());
73     }
74
75     @Override
76     public Class<?> getRawType() {
77         return _constructor.getDeclaringClass();
78     }
79
80     /*
81     /**********************************************************
82     /* Extended API
83     /**********************************************************
84      */

85
86     @Override
87     public int getParameterCount() {
88         return _constructor.getParameterTypes().length;
89     }
90
91     @Override
92     public Class<?> getRawParameterType(int index)
93     {
94         Class<?>[] types = _constructor.getParameterTypes();
95         return (index >= types.length) ? null : types[index];
96     }
97
98     @Override
99     public JavaType getParameterType(int index) {
100         Type[] types = _constructor.getGenericParameterTypes();
101         if (index >= types.length) {
102             return null;
103         }
104         return _typeContext.resolveType(types[index]);
105     }
106
107     @Override
108     @Deprecated // since 2.7
109     public Type getGenericParameterType(int index) {
110         Type[] types = _constructor.getGenericParameterTypes();
111         if (index >= types.length) {
112             return null;
113         }
114         return types[index];
115     }
116     
117     @Override
118     public final Object call() throws Exception {
119         return _constructor.newInstance();
120     }
121
122     @Override
123     public final Object call(Object[] args) throws Exception {
124         return _constructor.newInstance(args);
125     }
126
127     @Override
128     public final Object call1(Object arg) throws Exception {
129         return _constructor.newInstance(arg);
130     }
131     
132     /*
133     /**********************************************************
134     /* AnnotatedMember impl
135     /**********************************************************
136      */

137
138     @Override
139     public Class<?> getDeclaringClass() { return _constructor.getDeclaringClass(); }
140
141     @Override
142     public Member getMember() { return _constructor; }
143
144     @Override
145     public void setValue(Object pojo, Object value)
146         throws UnsupportedOperationException
147     {
148         throw new UnsupportedOperationException("Cannot call setValue() on constructor of "
149                 +getDeclaringClass().getName());
150     }
151
152     @Override
153     public Object getValue(Object pojo)
154         throws UnsupportedOperationException
155     {
156         throw new UnsupportedOperationException("Cannot call getValue() on constructor of "
157                 +getDeclaringClass().getName());
158     }
159     
160     /*
161     /**********************************************************
162     /* Extended API, specific annotations
163     /**********************************************************
164      */

165
166     @Override
167     public String toString() {
168         return "[constructor for "+getName()+", annotations: "+_annotations+"]";
169     }
170
171     @Override
172     public int hashCode() {
173         return _constructor.getName().hashCode();
174     }
175     
176     @Override
177     public boolean equals(Object o) {
178         if (o == thisreturn true;
179         return ClassUtil.hasClass(o, getClass())
180                 && (((AnnotatedConstructor) o)._constructor == _constructor);
181     }
182
183     /*
184     /**********************************************************
185     /* JDK serialization handling
186     /**********************************************************
187      */

188
189     Object writeReplace() {
190         return new AnnotatedConstructor(new Serialization(_constructor));
191     }
192
193     Object readResolve() {
194         Class<?> clazz = _serialization.clazz;
195         try {
196             Constructor<?> ctor = clazz.getDeclaredConstructor(_serialization.args);
197             // 06-Oct-2012, tatu: Has "lost" its security override, must force back
198             if (!ctor.isAccessible()) {
199                 ClassUtil.checkAndFixAccess(ctor, false);
200             }
201             return new AnnotatedConstructor(null, ctor, nullnull);
202         } catch (Exception e) {
203             throw new IllegalArgumentException("Could not find constructor with "
204                     +_serialization.args.length+" args from Class '"+clazz.getName());
205         }
206     }
207     
208     /**
209      * Helper class that is used as the workaround to persist
210      * Field references. It basically just stores declaring class
211      * and field name.
212      */

213     private final static class Serialization
214         implements java.io.Serializable
215     {
216         private static final long serialVersionUID = 1L;
217         protected Class<?> clazz;
218         protected Class<?>[] args;
219
220         public Serialization(Constructor<?> ctor) {
221             clazz = ctor.getDeclaringClass();
222             args = ctor.getParameterTypes();
223         }
224     }
225 }
226