11b9940e612fc73202837fbe9db2f9035f307b5d1George Mount/* 21b9940e612fc73202837fbe9db2f9035f307b5d1George Mount * Copyright (C) 2015 The Android Open Source Project 31b9940e612fc73202837fbe9db2f9035f307b5d1George Mount * 41b9940e612fc73202837fbe9db2f9035f307b5d1George Mount * Licensed under the Apache License, Version 2.0 (the "License"); 51b9940e612fc73202837fbe9db2f9035f307b5d1George Mount * you may not use this file except in compliance with the License. 61b9940e612fc73202837fbe9db2f9035f307b5d1George Mount * You may obtain a copy of the License at 71b9940e612fc73202837fbe9db2f9035f307b5d1George Mount * 81b9940e612fc73202837fbe9db2f9035f307b5d1George Mount * http://www.apache.org/licenses/LICENSE-2.0 91b9940e612fc73202837fbe9db2f9035f307b5d1George Mount * 101b9940e612fc73202837fbe9db2f9035f307b5d1George Mount * Unless required by applicable law or agreed to in writing, software 111b9940e612fc73202837fbe9db2f9035f307b5d1George Mount * distributed under the License is distributed on an "AS IS" BASIS, 121b9940e612fc73202837fbe9db2f9035f307b5d1George Mount * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 131b9940e612fc73202837fbe9db2f9035f307b5d1George Mount * See the License for the specific language governing permissions and 141b9940e612fc73202837fbe9db2f9035f307b5d1George Mount * limitations under the License. 151b9940e612fc73202837fbe9db2f9035f307b5d1George Mount */ 16fead9ca09b117136b35bc5bf137340a754f9edddGeorge Mountpackage android.databinding.tool.reflection; 171b9940e612fc73202837fbe9db2f9035f307b5d1George Mount 18fead9ca09b117136b35bc5bf137340a754f9edddGeorge Mountimport android.databinding.tool.reflection.annotation.AnnotationAnalyzer; 19fead9ca09b117136b35bc5bf137340a754f9edddGeorge Mountimport android.databinding.tool.util.L; 202611838bffef5a009ca71e3e9e59a93f29b098edYigit Boyarimport android.databinding.tool.util.Preconditions; 21fead9ca09b117136b35bc5bf137340a754f9edddGeorge Mount 22a7e767e576adebcddf043ad34ccb8dd167f777b3George Mountimport java.util.Map; 23fead9ca09b117136b35bc5bf137340a754f9edddGeorge Mount 241b9940e612fc73202837fbe9db2f9035f307b5d1George Mountimport javax.annotation.processing.ProcessingEnvironment; 251b9940e612fc73202837fbe9db2f9035f307b5d1George Mount 26fa9fe12980ef1103fabe33bf5ff0e2f53042a204George Mount/** 27fa9fe12980ef1103fabe33bf5ff0e2f53042a204George Mount * This is the base class for several implementations of something that 28fa9fe12980ef1103fabe33bf5ff0e2f53042a204George Mount * acts like a ClassLoader. Different implementations work with the Annotation 29fa9fe12980ef1103fabe33bf5ff0e2f53042a204George Mount * Processor, ClassLoader, and an Android Studio plugin. 30fa9fe12980ef1103fabe33bf5ff0e2f53042a204George Mount */ 3179fc7f3727815ab35bb1bb2e060bfb7db3176eedGeorge Mountpublic abstract class ModelAnalyzer { 3297d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar 3397d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar public static final String[] LIST_CLASS_NAMES = { 3497d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar "java.util.List", 3597d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar "android.util.SparseArray", 3697d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar "android.util.SparseBooleanArray", 3797d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar "android.util.SparseIntArray", 3897d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar "android.util.SparseLongArray", 3997d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar "android.util.LongSparseArray", 4097d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar "android.support.v4.util.LongSparseArray", 4197d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar }; 4297d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar 4397d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar public static final String MAP_CLASS_NAME = "java.util.Map"; 4497d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar 4597d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar public static final String STRING_CLASS_NAME = "java.lang.String"; 4697d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar 4797d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar public static final String OBJECT_CLASS_NAME = "java.lang.Object"; 4897d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar 49fead9ca09b117136b35bc5bf137340a754f9edddGeorge Mount public static final String OBSERVABLE_CLASS_NAME = "android.databinding.Observable"; 5097d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar 51fead9ca09b117136b35bc5bf137340a754f9edddGeorge Mount public static final String OBSERVABLE_LIST_CLASS_NAME = "android.databinding.ObservableList"; 5297d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar 53fead9ca09b117136b35bc5bf137340a754f9edddGeorge Mount public static final String OBSERVABLE_MAP_CLASS_NAME = "android.databinding.ObservableMap"; 5497d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar 5597d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar public static final String[] OBSERVABLE_FIELDS = { 56fead9ca09b117136b35bc5bf137340a754f9edddGeorge Mount "android.databinding.ObservableBoolean", 57fead9ca09b117136b35bc5bf137340a754f9edddGeorge Mount "android.databinding.ObservableByte", 58fead9ca09b117136b35bc5bf137340a754f9edddGeorge Mount "android.databinding.ObservableChar", 59fead9ca09b117136b35bc5bf137340a754f9edddGeorge Mount "android.databinding.ObservableShort", 60fead9ca09b117136b35bc5bf137340a754f9edddGeorge Mount "android.databinding.ObservableInt", 61fead9ca09b117136b35bc5bf137340a754f9edddGeorge Mount "android.databinding.ObservableLong", 62fead9ca09b117136b35bc5bf137340a754f9edddGeorge Mount "android.databinding.ObservableFloat", 63fead9ca09b117136b35bc5bf137340a754f9edddGeorge Mount "android.databinding.ObservableDouble", 64fead9ca09b117136b35bc5bf137340a754f9edddGeorge Mount "android.databinding.ObservableField", 65d37b47419005587c52ca4c099432327b7f06478dYigit Boyar "android.databinding.ObservableParcelable", 6697d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar }; 6797d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar 684c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount public static final String VIEW_DATA_BINDING = 69fead9ca09b117136b35bc5bf137340a754f9edddGeorge Mount "android.databinding.ViewDataBinding"; 7097d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar 71de38dd3ef0577d25b2d59863603abe5750d0c231George Mount public static final String VIEW_STUB_CLASS_NAME = "android.view.ViewStub"; 72de38dd3ef0577d25b2d59863603abe5750d0c231George Mount 73fa9fe12980ef1103fabe33bf5ff0e2f53042a204George Mount private ModelClass[] mListTypes; 74fa9fe12980ef1103fabe33bf5ff0e2f53042a204George Mount private ModelClass mMapType; 75fa9fe12980ef1103fabe33bf5ff0e2f53042a204George Mount private ModelClass mStringType; 76fa9fe12980ef1103fabe33bf5ff0e2f53042a204George Mount private ModelClass mObjectType; 77fa9fe12980ef1103fabe33bf5ff0e2f53042a204George Mount private ModelClass mObservableType; 78fa9fe12980ef1103fabe33bf5ff0e2f53042a204George Mount private ModelClass mObservableListType; 79fa9fe12980ef1103fabe33bf5ff0e2f53042a204George Mount private ModelClass mObservableMapType; 80fa9fe12980ef1103fabe33bf5ff0e2f53042a204George Mount private ModelClass[] mObservableFieldTypes; 81fa9fe12980ef1103fabe33bf5ff0e2f53042a204George Mount private ModelClass mViewBindingType; 82de38dd3ef0577d25b2d59863603abe5750d0c231George Mount private ModelClass mViewStubType; 83fa9fe12980ef1103fabe33bf5ff0e2f53042a204George Mount 8479fc7f3727815ab35bb1bb2e060bfb7db3176eedGeorge Mount private static ModelAnalyzer sAnalyzer; 851b9940e612fc73202837fbe9db2f9035f307b5d1George Mount 8697d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar protected void setInstance(ModelAnalyzer analyzer) { 8797d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar sAnalyzer = analyzer; 8897d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar } 8997d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar 9079fc7f3727815ab35bb1bb2e060bfb7db3176eedGeorge Mount public ModelClass findCommonParentOf(ModelClass modelClass1, 9179fc7f3727815ab35bb1bb2e060bfb7db3176eedGeorge Mount ModelClass modelClass2) { 9279fc7f3727815ab35bb1bb2e060bfb7db3176eedGeorge Mount ModelClass curr = modelClass1; 9379fc7f3727815ab35bb1bb2e060bfb7db3176eedGeorge Mount while (curr != null && !curr.isAssignableFrom(modelClass2)) { 9479fc7f3727815ab35bb1bb2e060bfb7db3176eedGeorge Mount curr = curr.getSuperclass(); 951b9940e612fc73202837fbe9db2f9035f307b5d1George Mount } 9679fc7f3727815ab35bb1bb2e060bfb7db3176eedGeorge Mount if (curr == null) { 9791beb3a1a89a58b1c0b6b874d889394a3be90b6cGeorge Mount if (modelClass1.isObject() && modelClass2.isInterface()) { 9891beb3a1a89a58b1c0b6b874d889394a3be90b6cGeorge Mount return modelClass1; 9991beb3a1a89a58b1c0b6b874d889394a3be90b6cGeorge Mount } else if (modelClass2.isObject() && modelClass1.isInterface()) { 10091beb3a1a89a58b1c0b6b874d889394a3be90b6cGeorge Mount return modelClass2; 10191beb3a1a89a58b1c0b6b874d889394a3be90b6cGeorge Mount } 10291beb3a1a89a58b1c0b6b874d889394a3be90b6cGeorge Mount 10379fc7f3727815ab35bb1bb2e060bfb7db3176eedGeorge Mount ModelClass primitive1 = modelClass1.unbox(); 10479fc7f3727815ab35bb1bb2e060bfb7db3176eedGeorge Mount ModelClass primitive2 = modelClass2.unbox(); 10579fc7f3727815ab35bb1bb2e060bfb7db3176eedGeorge Mount if (!modelClass1.equals(primitive1) || !modelClass2.equals(primitive2)) { 10679fc7f3727815ab35bb1bb2e060bfb7db3176eedGeorge Mount return findCommonParentOf(primitive1, primitive2); 1071b9940e612fc73202837fbe9db2f9035f307b5d1George Mount } 1081b9940e612fc73202837fbe9db2f9035f307b5d1George Mount } 10979fc7f3727815ab35bb1bb2e060bfb7db3176eedGeorge Mount Preconditions.checkNotNull(curr, 11079fc7f3727815ab35bb1bb2e060bfb7db3176eedGeorge Mount "must be able to find a common parent for " + modelClass1 + " and " + modelClass2); 11179fc7f3727815ab35bb1bb2e060bfb7db3176eedGeorge Mount return curr; 1121b9940e612fc73202837fbe9db2f9035f307b5d1George Mount 1131b9940e612fc73202837fbe9db2f9035f307b5d1George Mount } 1141b9940e612fc73202837fbe9db2f9035f307b5d1George Mount 11579fc7f3727815ab35bb1bb2e060bfb7db3176eedGeorge Mount public abstract ModelClass loadPrimitive(String className); 1161b9940e612fc73202837fbe9db2f9035f307b5d1George Mount 11779fc7f3727815ab35bb1bb2e060bfb7db3176eedGeorge Mount public static ModelAnalyzer getInstance() { 11879fc7f3727815ab35bb1bb2e060bfb7db3176eedGeorge Mount return sAnalyzer; 1191b9940e612fc73202837fbe9db2f9035f307b5d1George Mount } 1201b9940e612fc73202837fbe9db2f9035f307b5d1George Mount 12179fc7f3727815ab35bb1bb2e060bfb7db3176eedGeorge Mount public static void setProcessingEnvironment(ProcessingEnvironment processingEnvironment) { 12297d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar if (sAnalyzer != null) { 12397d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar throw new IllegalStateException("processing env is already created, you cannot " 12497d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar + "change class loader after that"); 12597d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar } 12697d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar L.d("setting processing env to %s", processingEnvironment); 12779fc7f3727815ab35bb1bb2e060bfb7db3176eedGeorge Mount AnnotationAnalyzer annotationAnalyzer = new AnnotationAnalyzer(processingEnvironment); 12879fc7f3727815ab35bb1bb2e060bfb7db3176eedGeorge Mount sAnalyzer = annotationAnalyzer; 1291b9940e612fc73202837fbe9db2f9035f307b5d1George Mount } 1301b9940e612fc73202837fbe9db2f9035f307b5d1George Mount 131895b618d9c6e3deb56465d0759cda57f50c46214Yigit Boyar /** 132895b618d9c6e3deb56465d0759cda57f50c46214Yigit Boyar * Takes a raw className (potentially w/ generics and arrays) and expands definitions using 133895b618d9c6e3deb56465d0759cda57f50c46214Yigit Boyar * the import statements. 134895b618d9c6e3deb56465d0759cda57f50c46214Yigit Boyar * <p> 135895b618d9c6e3deb56465d0759cda57f50c46214Yigit Boyar * For instance, this allows user to define variables 136895b618d9c6e3deb56465d0759cda57f50c46214Yigit Boyar * <variable type="User" name="user"/> 137895b618d9c6e3deb56465d0759cda57f50c46214Yigit Boyar * if they previously imported User. 138895b618d9c6e3deb56465d0759cda57f50c46214Yigit Boyar * <import name="com.example.User"/> 139895b618d9c6e3deb56465d0759cda57f50c46214Yigit Boyar */ 140895b618d9c6e3deb56465d0759cda57f50c46214Yigit Boyar public String applyImports(String className, Map<String, String> imports) { 141895b618d9c6e3deb56465d0759cda57f50c46214Yigit Boyar className = className.trim(); 142895b618d9c6e3deb56465d0759cda57f50c46214Yigit Boyar int numDimensions = 0; 143895b618d9c6e3deb56465d0759cda57f50c46214Yigit Boyar String generic = null; 144895b618d9c6e3deb56465d0759cda57f50c46214Yigit Boyar // handle array 145895b618d9c6e3deb56465d0759cda57f50c46214Yigit Boyar while (className.endsWith("[]")) { 146895b618d9c6e3deb56465d0759cda57f50c46214Yigit Boyar numDimensions++; 147895b618d9c6e3deb56465d0759cda57f50c46214Yigit Boyar className = className.substring(0, className.length() - 2); 148895b618d9c6e3deb56465d0759cda57f50c46214Yigit Boyar } 149895b618d9c6e3deb56465d0759cda57f50c46214Yigit Boyar // handle generics 150895b618d9c6e3deb56465d0759cda57f50c46214Yigit Boyar final int lastCharIndex = className.length() - 1; 151895b618d9c6e3deb56465d0759cda57f50c46214Yigit Boyar if ('>' == className.charAt(lastCharIndex)) { 152895b618d9c6e3deb56465d0759cda57f50c46214Yigit Boyar // has generic. 153895b618d9c6e3deb56465d0759cda57f50c46214Yigit Boyar int open = className.indexOf('<'); 154895b618d9c6e3deb56465d0759cda57f50c46214Yigit Boyar if (open == -1) { 155895b618d9c6e3deb56465d0759cda57f50c46214Yigit Boyar L.e("un-matching generic syntax for %s", className); 156895b618d9c6e3deb56465d0759cda57f50c46214Yigit Boyar return className; 157895b618d9c6e3deb56465d0759cda57f50c46214Yigit Boyar } 158895b618d9c6e3deb56465d0759cda57f50c46214Yigit Boyar generic = applyImports(className.substring(open + 1, lastCharIndex), imports); 159895b618d9c6e3deb56465d0759cda57f50c46214Yigit Boyar className = className.substring(0, open); 160895b618d9c6e3deb56465d0759cda57f50c46214Yigit Boyar } 161895b618d9c6e3deb56465d0759cda57f50c46214Yigit Boyar int dotIndex = className.indexOf('.'); 162895b618d9c6e3deb56465d0759cda57f50c46214Yigit Boyar final String qualifier; 163895b618d9c6e3deb56465d0759cda57f50c46214Yigit Boyar final String rest; 164895b618d9c6e3deb56465d0759cda57f50c46214Yigit Boyar if (dotIndex == -1) { 165895b618d9c6e3deb56465d0759cda57f50c46214Yigit Boyar qualifier = className; 166895b618d9c6e3deb56465d0759cda57f50c46214Yigit Boyar rest = null; 167895b618d9c6e3deb56465d0759cda57f50c46214Yigit Boyar } else { 168895b618d9c6e3deb56465d0759cda57f50c46214Yigit Boyar qualifier = className.substring(0, dotIndex); 169895b618d9c6e3deb56465d0759cda57f50c46214Yigit Boyar rest = className.substring(dotIndex); // includes dot 170895b618d9c6e3deb56465d0759cda57f50c46214Yigit Boyar } 171895b618d9c6e3deb56465d0759cda57f50c46214Yigit Boyar final String expandedQualifier = imports.get(qualifier); 172895b618d9c6e3deb56465d0759cda57f50c46214Yigit Boyar String result; 173895b618d9c6e3deb56465d0759cda57f50c46214Yigit Boyar if (expandedQualifier != null) { 174895b618d9c6e3deb56465d0759cda57f50c46214Yigit Boyar result = rest == null ? expandedQualifier : expandedQualifier + rest; 175895b618d9c6e3deb56465d0759cda57f50c46214Yigit Boyar } else { 176895b618d9c6e3deb56465d0759cda57f50c46214Yigit Boyar result = className; // no change 177895b618d9c6e3deb56465d0759cda57f50c46214Yigit Boyar } 178895b618d9c6e3deb56465d0759cda57f50c46214Yigit Boyar // now append back dimension and generics 179895b618d9c6e3deb56465d0759cda57f50c46214Yigit Boyar if (generic != null) { 180895b618d9c6e3deb56465d0759cda57f50c46214Yigit Boyar result = result + "<" + applyImports(generic, imports) + ">"; 181895b618d9c6e3deb56465d0759cda57f50c46214Yigit Boyar } 182895b618d9c6e3deb56465d0759cda57f50c46214Yigit Boyar while (numDimensions-- > 0) { 183895b618d9c6e3deb56465d0759cda57f50c46214Yigit Boyar result = result + "[]"; 184895b618d9c6e3deb56465d0759cda57f50c46214Yigit Boyar } 185895b618d9c6e3deb56465d0759cda57f50c46214Yigit Boyar return result; 186895b618d9c6e3deb56465d0759cda57f50c46214Yigit Boyar } 187895b618d9c6e3deb56465d0759cda57f50c46214Yigit Boyar 18879fc7f3727815ab35bb1bb2e060bfb7db3176eedGeorge Mount public String getDefaultValue(String className) { 18997d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar if ("int".equals(className)) { 19079fc7f3727815ab35bb1bb2e060bfb7db3176eedGeorge Mount return "0"; 1911b9940e612fc73202837fbe9db2f9035f307b5d1George Mount } 19297d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar if ("short".equals(className)) { 19379fc7f3727815ab35bb1bb2e060bfb7db3176eedGeorge Mount return "0"; 1941b9940e612fc73202837fbe9db2f9035f307b5d1George Mount } 19597d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar if ("long".equals(className)) { 19679fc7f3727815ab35bb1bb2e060bfb7db3176eedGeorge Mount return "0L"; 1971b9940e612fc73202837fbe9db2f9035f307b5d1George Mount } 19897d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar if ("float".equals(className)) { 19979fc7f3727815ab35bb1bb2e060bfb7db3176eedGeorge Mount return "0f"; 2001b9940e612fc73202837fbe9db2f9035f307b5d1George Mount } 20197d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar if ("double".equals(className)) { 20279fc7f3727815ab35bb1bb2e060bfb7db3176eedGeorge Mount return "0.0"; 2031b9940e612fc73202837fbe9db2f9035f307b5d1George Mount } 20497d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar if ("boolean".equals(className)) { 20579fc7f3727815ab35bb1bb2e060bfb7db3176eedGeorge Mount return "false"; 2061b9940e612fc73202837fbe9db2f9035f307b5d1George Mount } 20779fc7f3727815ab35bb1bb2e060bfb7db3176eedGeorge Mount if ("char".equals(className)) { 20879fc7f3727815ab35bb1bb2e060bfb7db3176eedGeorge Mount return "'\\u0000'"; 2091b9940e612fc73202837fbe9db2f9035f307b5d1George Mount } 21079fc7f3727815ab35bb1bb2e060bfb7db3176eedGeorge Mount if ("byte".equals(className)) { 21179fc7f3727815ab35bb1bb2e060bfb7db3176eedGeorge Mount return "0"; 2121b9940e612fc73202837fbe9db2f9035f307b5d1George Mount } 21379fc7f3727815ab35bb1bb2e060bfb7db3176eedGeorge Mount return "null"; 2141b9940e612fc73202837fbe9db2f9035f307b5d1George Mount } 2151b9940e612fc73202837fbe9db2f9035f307b5d1George Mount 216a7e767e576adebcddf043ad34ccb8dd167f777b3George Mount public abstract ModelClass findClass(String className, Map<String, String> imports); 2171b9940e612fc73202837fbe9db2f9035f307b5d1George Mount 21879fc7f3727815ab35bb1bb2e060bfb7db3176eedGeorge Mount public abstract ModelClass findClass(Class classType); 21997d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar 22097d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar public abstract TypeUtil createTypeUtil(); 221fa9fe12980ef1103fabe33bf5ff0e2f53042a204George Mount 222fa9fe12980ef1103fabe33bf5ff0e2f53042a204George Mount ModelClass[] getListTypes() { 223fa9fe12980ef1103fabe33bf5ff0e2f53042a204George Mount if (mListTypes == null) { 224fa9fe12980ef1103fabe33bf5ff0e2f53042a204George Mount mListTypes = new ModelClass[LIST_CLASS_NAMES.length]; 225fa9fe12980ef1103fabe33bf5ff0e2f53042a204George Mount for (int i = 0; i < mListTypes.length; i++) { 226fa9fe12980ef1103fabe33bf5ff0e2f53042a204George Mount final ModelClass modelClass = findClass(LIST_CLASS_NAMES[i], null); 227fa9fe12980ef1103fabe33bf5ff0e2f53042a204George Mount if (modelClass != null) { 228fa9fe12980ef1103fabe33bf5ff0e2f53042a204George Mount mListTypes[i] = modelClass.erasure(); 229fa9fe12980ef1103fabe33bf5ff0e2f53042a204George Mount } 230fa9fe12980ef1103fabe33bf5ff0e2f53042a204George Mount } 231fa9fe12980ef1103fabe33bf5ff0e2f53042a204George Mount } 232fa9fe12980ef1103fabe33bf5ff0e2f53042a204George Mount return mListTypes; 233fa9fe12980ef1103fabe33bf5ff0e2f53042a204George Mount } 234fa9fe12980ef1103fabe33bf5ff0e2f53042a204George Mount 235fa9fe12980ef1103fabe33bf5ff0e2f53042a204George Mount public ModelClass getMapType() { 236fa9fe12980ef1103fabe33bf5ff0e2f53042a204George Mount if (mMapType == null) { 237fa9fe12980ef1103fabe33bf5ff0e2f53042a204George Mount mMapType = loadClassErasure(MAP_CLASS_NAME); 238fa9fe12980ef1103fabe33bf5ff0e2f53042a204George Mount } 239fa9fe12980ef1103fabe33bf5ff0e2f53042a204George Mount return mMapType; 240fa9fe12980ef1103fabe33bf5ff0e2f53042a204George Mount } 241fa9fe12980ef1103fabe33bf5ff0e2f53042a204George Mount 242fa9fe12980ef1103fabe33bf5ff0e2f53042a204George Mount ModelClass getStringType() { 243fa9fe12980ef1103fabe33bf5ff0e2f53042a204George Mount if (mStringType == null) { 244fa9fe12980ef1103fabe33bf5ff0e2f53042a204George Mount mStringType = findClass(STRING_CLASS_NAME, null); 245fa9fe12980ef1103fabe33bf5ff0e2f53042a204George Mount } 246fa9fe12980ef1103fabe33bf5ff0e2f53042a204George Mount return mStringType; 247fa9fe12980ef1103fabe33bf5ff0e2f53042a204George Mount } 248fa9fe12980ef1103fabe33bf5ff0e2f53042a204George Mount 249fa9fe12980ef1103fabe33bf5ff0e2f53042a204George Mount ModelClass getObjectType() { 250fa9fe12980ef1103fabe33bf5ff0e2f53042a204George Mount if (mObjectType == null) { 251fa9fe12980ef1103fabe33bf5ff0e2f53042a204George Mount mObjectType = findClass(OBJECT_CLASS_NAME, null); 252fa9fe12980ef1103fabe33bf5ff0e2f53042a204George Mount } 253fa9fe12980ef1103fabe33bf5ff0e2f53042a204George Mount return mObjectType; 254fa9fe12980ef1103fabe33bf5ff0e2f53042a204George Mount } 255fa9fe12980ef1103fabe33bf5ff0e2f53042a204George Mount 256fa9fe12980ef1103fabe33bf5ff0e2f53042a204George Mount ModelClass getObservableType() { 257fa9fe12980ef1103fabe33bf5ff0e2f53042a204George Mount if (mObservableType == null) { 258fa9fe12980ef1103fabe33bf5ff0e2f53042a204George Mount mObservableType = findClass(OBSERVABLE_CLASS_NAME, null); 259fa9fe12980ef1103fabe33bf5ff0e2f53042a204George Mount } 260fa9fe12980ef1103fabe33bf5ff0e2f53042a204George Mount return mObservableType; 261fa9fe12980ef1103fabe33bf5ff0e2f53042a204George Mount } 262fa9fe12980ef1103fabe33bf5ff0e2f53042a204George Mount 263fa9fe12980ef1103fabe33bf5ff0e2f53042a204George Mount ModelClass getObservableListType() { 264fa9fe12980ef1103fabe33bf5ff0e2f53042a204George Mount if (mObservableListType == null) { 265fa9fe12980ef1103fabe33bf5ff0e2f53042a204George Mount mObservableListType = loadClassErasure(OBSERVABLE_LIST_CLASS_NAME); 266fa9fe12980ef1103fabe33bf5ff0e2f53042a204George Mount } 267fa9fe12980ef1103fabe33bf5ff0e2f53042a204George Mount return mObservableListType; 268fa9fe12980ef1103fabe33bf5ff0e2f53042a204George Mount } 269fa9fe12980ef1103fabe33bf5ff0e2f53042a204George Mount 270fa9fe12980ef1103fabe33bf5ff0e2f53042a204George Mount ModelClass getObservableMapType() { 271fa9fe12980ef1103fabe33bf5ff0e2f53042a204George Mount if (mObservableMapType == null) { 272fa9fe12980ef1103fabe33bf5ff0e2f53042a204George Mount mObservableMapType = loadClassErasure(OBSERVABLE_MAP_CLASS_NAME); 273fa9fe12980ef1103fabe33bf5ff0e2f53042a204George Mount } 274fa9fe12980ef1103fabe33bf5ff0e2f53042a204George Mount return mObservableMapType; 275fa9fe12980ef1103fabe33bf5ff0e2f53042a204George Mount } 276fa9fe12980ef1103fabe33bf5ff0e2f53042a204George Mount 277fa9fe12980ef1103fabe33bf5ff0e2f53042a204George Mount ModelClass getViewDataBindingType() { 278fa9fe12980ef1103fabe33bf5ff0e2f53042a204George Mount if (mViewBindingType == null) { 279fa9fe12980ef1103fabe33bf5ff0e2f53042a204George Mount mViewBindingType = findClass(VIEW_DATA_BINDING, null); 280fa9fe12980ef1103fabe33bf5ff0e2f53042a204George Mount } 281fa9fe12980ef1103fabe33bf5ff0e2f53042a204George Mount return mViewBindingType; 282fa9fe12980ef1103fabe33bf5ff0e2f53042a204George Mount } 283fa9fe12980ef1103fabe33bf5ff0e2f53042a204George Mount 284924fa7c597694ebc433fc0379d0015785351d1b7Yigit Boyar protected ModelClass[] getObservableFieldTypes() { 285fa9fe12980ef1103fabe33bf5ff0e2f53042a204George Mount if (mObservableFieldTypes == null) { 286fa9fe12980ef1103fabe33bf5ff0e2f53042a204George Mount mObservableFieldTypes = new ModelClass[OBSERVABLE_FIELDS.length]; 287fa9fe12980ef1103fabe33bf5ff0e2f53042a204George Mount for (int i = 0; i < OBSERVABLE_FIELDS.length; i++) { 288fa9fe12980ef1103fabe33bf5ff0e2f53042a204George Mount mObservableFieldTypes[i] = loadClassErasure(OBSERVABLE_FIELDS[i]); 289fa9fe12980ef1103fabe33bf5ff0e2f53042a204George Mount } 290fa9fe12980ef1103fabe33bf5ff0e2f53042a204George Mount } 291fa9fe12980ef1103fabe33bf5ff0e2f53042a204George Mount return mObservableFieldTypes; 292fa9fe12980ef1103fabe33bf5ff0e2f53042a204George Mount } 293fa9fe12980ef1103fabe33bf5ff0e2f53042a204George Mount 294de38dd3ef0577d25b2d59863603abe5750d0c231George Mount ModelClass getViewStubType() { 295de38dd3ef0577d25b2d59863603abe5750d0c231George Mount if (mViewStubType == null) { 296de38dd3ef0577d25b2d59863603abe5750d0c231George Mount mViewStubType = findClass(VIEW_STUB_CLASS_NAME, null); 297de38dd3ef0577d25b2d59863603abe5750d0c231George Mount } 298de38dd3ef0577d25b2d59863603abe5750d0c231George Mount return mViewStubType; 299de38dd3ef0577d25b2d59863603abe5750d0c231George Mount } 300de38dd3ef0577d25b2d59863603abe5750d0c231George Mount 301fa9fe12980ef1103fabe33bf5ff0e2f53042a204George Mount private ModelClass loadClassErasure(String className) { 302fa9fe12980ef1103fabe33bf5ff0e2f53042a204George Mount return findClass(className, null).erasure(); 303fa9fe12980ef1103fabe33bf5ff0e2f53042a204George Mount } 3041b9940e612fc73202837fbe9db2f9035f307b5d1George Mount} 305