1 package com.fasterxml.classmate.types;
2
3 import java.lang.reflect.Modifier;
4 import java.util.Arrays;
5 import java.util.Collections;
6 import java.util.List;
7
8 import com.fasterxml.classmate.ResolvedType;
9 import com.fasterxml.classmate.TypeBindings;
10 import com.fasterxml.classmate.members.RawConstructor;
11 import com.fasterxml.classmate.members.RawField;
12 import com.fasterxml.classmate.members.RawMethod;
13
14 /**
15  * Type implementation for classes that do not represent interfaces,
16  * primitive or array types.
17  */

18 public class ResolvedObjectType extends ResolvedType
19 {
20     /**
21      * While fundamentally super class has to be {@link ResolvedObjectType}
22      * (or null for {@link java.lang.Object}), we may need to hold on to
23      * a {@link ResolvedRecursiveType} occasionally.
24      */

25     protected final ResolvedType _superClass;
26
27     /**
28      * List of interfaces this type implements; may be empty but never null
29      */

30     protected final ResolvedType[] _superInterfaces;
31
32     /**
33      * Modifiers of the underlying class.
34      */

35     protected final int _modifiers;
36
37     /**
38      * Constructors declared by the resolved Object class.
39      */

40     protected RawConstructor[] _constructors;
41
42     protected RawField[] _memberFields;
43     protected RawField[] _staticFields;
44
45     protected RawMethod[] _memberMethods;
46     protected RawMethod[] _staticMethods;
47     
48     /*
49     /**********************************************************************
50     /* Life cycle
51     /**********************************************************************
52      */

53     
54     public ResolvedObjectType(Class<?> erased, TypeBindings bindings,
55             ResolvedType superClass, List<ResolvedType> interfaces)
56     {
57         this(erased, bindings, superClass,
58                 (interfaces == null || interfaces.isEmpty()) ? NO_TYPES :
59                 interfaces.toArray(new ResolvedType[0]));
60     }
61
62     public ResolvedObjectType(Class<?> erased, TypeBindings bindings,
63             ResolvedType superClass, ResolvedType[] interfaces)
64     {
65         super(erased, bindings);
66         /* 19-Aug-2014, tatu: bit unclean, but has to do for now.
67          *   Problem is, there is no common super-type, nor can we yet
68          *   force or coerce recursive types. Rather, they may only get
69          *   resolved only slightly after construction. So... need to
70          *   keep a reference.
71          */

72         if (superClass != null) {
73             if (!(superClass instanceof ResolvedObjectType)
74                     && !(superClass instanceof ResolvedRecursiveType)
75                     ) {
76                 throw new IllegalArgumentException("Unexpected parent type for "
77                         +erased.getName()+": "+superClass.getClass().getName());
78             }
79         }
80         
81         _superClass = superClass;
82         _superInterfaces = (interfaces == null) ? NO_TYPES : interfaces;
83         _modifiers = erased.getModifiers();
84     }
85
86     @Deprecated // since 1.1; removed from 1.2 -- kept for binary backwards compatibility
87     public ResolvedObjectType(Class<?> erased, TypeBindings bindings,
88             ResolvedObjectType superClass, List<ResolvedType> interfaces)
89     {
90         this(erased, bindings, (ResolvedType) superClass, interfaces);
91     }
92
93     @Deprecated // since 1.1; removed from 1.2 -- kept for binary backwards compatibility
94     public ResolvedObjectType(Class<?> erased, TypeBindings bindings,
95             ResolvedObjectType superClass, ResolvedType[] interfaces)
96     {
97         this(erased, bindings, (ResolvedType) superClass, interfaces);
98     }
99
100     public static ResolvedObjectType create(Class<?> erased, TypeBindings bindings,
101             ResolvedType superClass, List<ResolvedType> interfaces)
102     {
103         return new ResolvedObjectType(erased, bindings, superClass, interfaces);
104     }
105     
106     @Override
107     public boolean canCreateSubtypes() {
108         return true;
109     }
110     
111     /*
112     /**********************************************************************
113     /* Accessors for related types
114     /**********************************************************************
115      */

116
117     @Override
118     public ResolvedObjectType getParentClass() {
119         
120         /* 19-Aug-2014, tatu: Ugly does it... sigh.
121          *   But can't be helped because ResolvedRecursiveType is typically only
122          *   resolved after instances of this type have been constructed.
123          *   This means that resolution will need to be done somewhat dynamically.
124          */

125         if (_superClass == null) {
126             return null;
127         }
128         if (_superClass instanceof ResolvedObjectType) {
129             return (ResolvedObjectType) _superClass;
130         }
131         ResolvedType rt = ((ResolvedRecursiveType) _superClass).getSelfReferencedType();
132         if (!(rt instanceof ResolvedObjectType)) {
133             throw new IllegalStateException("Internal error: self-referential parent type ("
134                     +_superClass+") does not resolve into proper ResolvedObjectType, but instead to: "
135                     +rt);
136         }
137         return (ResolvedObjectType) rt;
138     }
139
140     @Override
141     public ResolvedType getSelfReferencedType() { return null; }
142     
143     @Override
144     public List<ResolvedType> getImplementedInterfaces() {
145         return (_superInterfaces.length == 0) ?
146                 Collections.<ResolvedType>emptyList() : Arrays.asList(_superInterfaces);
147     }
148
149     /*
150     /**********************************************************************
151     /* Accessors for related types
152     /**********************************************************************
153      */

154     
155     @Override
156     public final ResolvedType getArrayElementType() { return null; }
157     
158     /*
159     /**********************************************************************
160     /* Simple property accessors
161     /**********************************************************************
162      */

163     
164     @Override
165     public final boolean isInterface() { return false; }
166
167     @Override
168     public boolean isAbstract() {
169         return Modifier.isAbstract(_modifiers);
170     }
171
172     @Override
173     public final boolean isArray() { return false; }
174
175     @Override
176     public final boolean isPrimitive() { return false; }
177
178     /*
179     /**********************************************************************
180     /* Accessors for raw (minimally procesed) members
181     /**********************************************************************
182      */

183
184     @Override
185     public synchronized List<RawField> getMemberFields()
186     {
187         if (_memberFields == null) {
188             _memberFields = _getFields(false);
189         }
190         if (_memberFields.length == 0) {
191             return Collections.emptyList();
192         }
193         return Arrays.asList(_memberFields);
194     }
195
196     @Override
197     public synchronized List<RawField> getStaticFields()
198     {
199         if (_staticFields == null) {
200             _staticFields = _getFields(true);
201         }
202         if (_staticFields.length == 0) {
203             return Collections.emptyList();
204         }
205         return Arrays.asList(_staticFields);
206     }
207
208     @Override
209     public synchronized List<RawMethod> getMemberMethods()
210     {
211         if (_memberMethods == null) {
212             _memberMethods = _getMethods(false);
213         }
214         if (_memberMethods.length == 0) {
215             return Collections.emptyList();
216         }
217         return Arrays.asList(_memberMethods);
218     } 
219
220     @Override
221     public synchronized List<RawMethod> getStaticMethods()
222     {
223         if (_staticMethods == null) {
224             _staticMethods = _getMethods(true);
225         }
226         if (_staticMethods.length == 0) {
227             return Collections.emptyList();
228         }
229         return Arrays.asList(_staticMethods);
230     } 
231
232     @Override
233     public synchronized List<RawConstructor> getConstructors()
234     {
235         if (_constructors == null) {
236             _constructors = _getConstructors();
237         }
238         if (_constructors.length == 0) {
239             return Collections.emptyList();
240         }
241         return Arrays.asList(_constructors);
242     }
243
244     /*
245     /**********************************************************************
246     /* String representations
247     /**********************************************************************
248      */

249
250     @Override
251     public StringBuilder appendSignature(StringBuilder sb) {
252         return _appendClassSignature(sb);
253     }
254
255     @Override
256     public StringBuilder appendErasedSignature(StringBuilder sb) {
257         return _appendErasedClassSignature(sb);
258     }
259
260     @Override
261     public StringBuilder appendBriefDescription(StringBuilder sb) {
262         return _appendClassDescription(sb);
263     }
264     
265     @Override
266     public StringBuilder appendFullDescription(StringBuilder sb)
267     {
268         sb = _appendClassDescription(sb);
269         if (_superClass != null) {
270             sb.append(extends ");
271             sb = _superClass.appendBriefDescription(sb);
272         }
273         // interfaces 'extend' other interfaces...
274         int count = _superInterfaces.length;
275         if (count > 0) {
276             sb.append(implements ");
277             for (int i = 0; i < count; ++i) {
278                 if (i > 0) {
279                     sb.append(",");
280                 }
281                 sb = _superInterfaces[i].appendBriefDescription(sb);
282             }
283         }
284         return sb;
285     }
286 }
287
288