1/*
2 * Copyright (C) 2016 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package android.databinding.tool.reflection;
18
19import android.databinding.tool.util.StringUtils;
20
21import java.util.ArrayList;
22import java.util.Arrays;
23import java.util.List;
24import java.util.Map;
25
26/**
27 * A class that can be used by ModelAnalyzer without any backing model. This is used
28 * for ViewDataBinding subclasses that haven't been generated yet, but we still want
29 * to resolve methods and fields for them.
30 *
31 * @see ModelAnalyzer#injectViewDataBinding(String, Map, Map)
32 */
33public class InjectedClass extends ModelClass {
34    private final String mClassName;
35    private final String mSuperClass;
36    private final List<InjectedMethod> mMethods = new ArrayList<InjectedMethod>();
37    private final List<InjectedField> mFields = new ArrayList<InjectedField>();
38
39    public InjectedClass(String className, String superClass) {
40        mClassName = className;
41        mSuperClass = superClass;
42    }
43
44    public void addField(InjectedField field) {
45        mFields.add(field);
46    }
47
48    public void addMethod(InjectedMethod method) {
49        mMethods.add(method);
50    }
51
52    @Override
53    public String toJavaCode() {
54        return mClassName;
55    }
56
57    @Override
58    public boolean isArray() {
59        return false;
60    }
61
62    @Override
63    public ModelClass getComponentType() {
64        return null;
65    }
66
67    @Override
68    public boolean isNullable() {
69        return true;
70    }
71
72    @Override
73    public boolean isPrimitive() {
74        return false;
75    }
76
77    @Override
78    public boolean isBoolean() {
79        return false;
80    }
81
82    @Override
83    public boolean isChar() {
84        return false;
85    }
86
87    @Override
88    public boolean isByte() {
89        return false;
90    }
91
92    @Override
93    public boolean isShort() {
94        return false;
95    }
96
97    @Override
98    public boolean isInt() {
99        return false;
100    }
101
102    @Override
103    public boolean isLong() {
104        return false;
105    }
106
107    @Override
108    public boolean isFloat() {
109        return false;
110    }
111
112    @Override
113    public boolean isDouble() {
114        return false;
115    }
116
117    @Override
118    public boolean isGeneric() {
119        return false;
120    }
121
122    @Override
123    public List<ModelClass> getTypeArguments() {
124        return null;
125    }
126
127    @Override
128    public boolean isTypeVar() {
129        return false;
130    }
131
132    @Override
133    public boolean isWildcard() {
134        return false;
135    }
136
137    @Override
138    public boolean isInterface() {
139        return false;
140    }
141
142    @Override
143    public boolean isVoid() {
144        return false;
145    }
146
147    @Override
148    public ModelClass unbox() {
149        return this;
150    }
151
152    @Override
153    public ModelClass box() {
154        return this;
155    }
156
157    @Override
158    public boolean isObservable() {
159        return getSuperclass().isObservable();
160    }
161
162    @Override
163    public boolean isAssignableFrom(ModelClass that) {
164        ModelClass superClass = that;
165        while (superClass != null && !superClass.isObject()) {
166            if (superClass.toJavaCode().equals(mClassName)) {
167                return true;
168            }
169        }
170        return false;
171    }
172
173    @Override
174    public ModelClass getSuperclass() {
175        return ModelAnalyzer.getInstance().findClass(mSuperClass, null);
176    }
177
178    @Override
179    public ModelClass erasure() {
180        return this;
181    }
182
183    @Override
184    public String getJniDescription() {
185        return TypeUtil.getInstance().getDescription(this);
186    }
187
188    @Override
189    protected ModelField[] getDeclaredFields() {
190        ModelClass superClass = getSuperclass();
191        final ModelField[] superFields = superClass.getDeclaredFields();
192        final int initialCount = superFields.length;
193        final int fieldCount = initialCount + mFields.size();
194        final ModelField[] fields = Arrays.copyOf(superFields, fieldCount);
195        for (int i = 0; i < mFields.size(); i++) {
196            fields[i + initialCount] = mFields.get(i);
197        }
198        return fields;
199    }
200
201    @Override
202    protected ModelMethod[] getDeclaredMethods() {
203        ModelClass superClass = getSuperclass();
204        final ModelMethod[] superMethods = superClass.getDeclaredMethods();
205        final int initialCount = superMethods.length;
206        final int methodCount = initialCount + mMethods.size();
207        final ModelMethod[] methods = Arrays.copyOf(superMethods, methodCount);
208        for (int i = 0; i < mMethods.size(); i++) {
209            methods[i + initialCount] = mMethods.get(i);
210        }
211        return methods;
212    }
213
214    @Override
215    public String toString() {
216        return "Injected Class: " + mClassName;
217    }
218}
219