JavaClass.java revision 716ba89e7f459f49ea85070d4710c1d79d715298
1/*
2 * Copyright (C) 2015 The Android Open Source Project
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *      http://www.apache.org/licenses/LICENSE-2.0
7 * Unless required by applicable law or agreed to in writing, software
8 * distributed under the License is distributed on an "AS IS" BASIS,
9 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10 * See the License for the specific language governing permissions and
11 * limitations under the License.
12 */
13
14package android.databinding.tool.reflection.java;
15
16import android.databinding.tool.reflection.ModelClass;
17import android.databinding.tool.reflection.ModelField;
18import android.databinding.tool.reflection.ModelMethod;
19import android.databinding.tool.reflection.TypeUtil;
20
21import java.lang.reflect.Field;
22import java.lang.reflect.Method;
23import java.util.List;
24
25public class JavaClass extends ModelClass {
26    public final Class mClass;
27
28    public JavaClass(Class clazz) {
29        mClass = clazz;
30    }
31
32    @Override
33    public String toJavaCode() {
34        return toJavaCode(mClass);
35    }
36
37    private static String toJavaCode(Class aClass) {
38        if (aClass.isArray()) {
39            Class component = aClass.getComponentType();
40            return toJavaCode(component) + "[]";
41        } else {
42            return aClass.getCanonicalName().replace('$', '.');
43        }
44    }
45
46    @Override
47    public boolean isArray() {
48        return mClass.isArray();
49    }
50
51    @Override
52    public ModelClass getComponentType() {
53        if (mClass.isArray()) {
54            return new JavaClass(mClass.getComponentType());
55        } else if (isList() || isMap()) {
56            return new JavaClass(Object.class);
57        } else {
58            return null;
59        }
60    }
61
62    @Override
63    public boolean isNullable() {
64        return Object.class.isAssignableFrom(mClass);
65    }
66
67    @Override
68    public boolean isPrimitive() {
69        return mClass.isPrimitive();
70    }
71
72    @Override
73    public boolean isBoolean() {
74        return boolean.class.equals(mClass);
75    }
76
77    @Override
78    public boolean isChar() {
79        return char.class.equals(mClass);
80    }
81
82    @Override
83    public boolean isByte() {
84        return byte.class.equals(mClass);
85    }
86
87    @Override
88    public boolean isShort() {
89        return short.class.equals(mClass);
90    }
91
92    @Override
93    public boolean isInt() {
94        return int.class.equals(mClass);
95    }
96
97    @Override
98    public boolean isLong() {
99        return long.class.equals(mClass);
100    }
101
102    @Override
103    public boolean isFloat() {
104        return float.class.equals(mClass);
105    }
106
107    @Override
108    public boolean isDouble() {
109        return double.class.equals(mClass);
110    }
111
112    @Override
113    public boolean isGeneric() {
114        return false;
115    }
116
117    @Override
118    public List<ModelClass> getTypeArguments() {
119        return null;
120    }
121
122    @Override
123    public boolean isTypeVar() {
124        return false;
125    }
126
127    @Override
128    public boolean isInterface() {
129        return mClass.isInterface();
130    }
131
132    @Override
133    public boolean isVoid() {
134        return void.class.equals(mClass);
135    }
136
137    @Override
138    public ModelClass unbox() {
139        if (mClass.isPrimitive()) {
140            return this;
141        }
142        if (Integer.class.equals(mClass)) {
143            return new JavaClass(int.class);
144        } else if (Long.class.equals(mClass)) {
145            return new JavaClass(long.class);
146        } else if (Short.class.equals(mClass)) {
147            return new JavaClass(short.class);
148        } else if (Byte.class.equals(mClass)) {
149            return new JavaClass(byte.class);
150        } else if (Character.class.equals(mClass)) {
151            return new JavaClass(char.class);
152        } else if (Double.class.equals(mClass)) {
153            return new JavaClass(double.class);
154        } else if (Float.class.equals(mClass)) {
155            return new JavaClass(float.class);
156        } else if (Boolean.class.equals(mClass)) {
157            return new JavaClass(boolean.class);
158        } else {
159            // not a boxed type
160            return this;
161        }
162
163    }
164
165    @Override
166    public JavaClass box() {
167        if (!mClass.isPrimitive()) {
168            return this;
169        }
170        if (int.class.equals(mClass)) {
171            return new JavaClass(Integer.class);
172        } else if (long.class.equals(mClass)) {
173            return new JavaClass(Long.class);
174        } else if (short.class.equals(mClass)) {
175            return new JavaClass(Short.class);
176        } else if (byte.class.equals(mClass)) {
177            return new JavaClass(Byte.class);
178        } else if (char.class.equals(mClass)) {
179            return new JavaClass(Character.class);
180        } else if (double.class.equals(mClass)) {
181            return new JavaClass(Double.class);
182        } else if (float.class.equals(mClass)) {
183            return new JavaClass(Float.class);
184        } else if (boolean.class.equals(mClass)) {
185            return new JavaClass(Boolean.class);
186        } else {
187            // not a valid type?
188            return this;
189        }
190    }
191
192    @Override
193    public boolean isAssignableFrom(ModelClass that) {
194        Class thatClass = ((JavaClass) that).mClass;
195        return mClass.isAssignableFrom(thatClass);
196    }
197
198    @Override
199    public ModelClass getSuperclass() {
200        if (mClass.getSuperclass() == null) {
201            return null;
202        }
203        return new JavaClass(mClass.getSuperclass());
204    }
205
206    @Override
207    public String getCanonicalName() {
208        return mClass.getCanonicalName();
209    }
210
211    @Override
212    public ModelClass erasure() {
213        return this;
214    }
215
216    @Override
217    public String getJniDescription() {
218        return TypeUtil.getInstance().getDescription(this);
219    }
220
221    @Override
222    protected ModelField[] getDeclaredFields() {
223        Field[] fields = mClass.getDeclaredFields();
224        ModelField[] modelFields;
225        if (fields == null) {
226            modelFields = new ModelField[0];
227        } else {
228            modelFields = new ModelField[fields.length];
229            for (int i = 0; i < fields.length; i++) {
230                modelFields[i] = new JavaField(fields[i]);
231            }
232        }
233        return modelFields;
234    }
235
236    @Override
237    protected ModelMethod[] getDeclaredMethods() {
238        Method[] methods = mClass.getDeclaredMethods();
239        if (methods == null) {
240            return new ModelMethod[0];
241        } else {
242            ModelMethod[] classMethods = new ModelMethod[methods.length];
243            for (int i = 0; i < methods.length; i++) {
244                classMethods[i] = new JavaMethod(methods[i]);
245            }
246            return classMethods;
247        }
248    }
249
250    @Override
251    public boolean equals(Object obj) {
252        if (obj instanceof JavaClass) {
253            return mClass.equals(((JavaClass) obj).mClass);
254        } else {
255            return false;
256        }
257    }
258
259    @Override
260    public int hashCode() {
261        return mClass.hashCode();
262    }
263}
264