• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
14 package android.databinding.tool.writer
15 
16 import android.databinding.tool.LayoutBinder
17 
18 class DataBinderWriter(val pkg: String, val projectPackage: String, val className: String,
19         val layoutBinders : List<LayoutBinder>, val minSdk : kotlin.Int) {
<lambda>null20     fun write(brWriter : BRWriter) = kcode("") {
21         nl("package $pkg;")
22         nl("import $projectPackage.BR;")
23         nl("class $className {") {
24             tab("final static int TARGET_MIN_SDK = $minSdk;")
25             nl("")
26             tab("public $className() {") {
27             }
28             tab("}")
29             nl("")
30             tab("public android.databinding.ViewDataBinding getDataBinder(android.databinding.DataBindingComponent bindingComponent, android.view.View view, int layoutId) {") {
31                 tab("switch(layoutId) {") {
32                     layoutBinders.groupBy{it.layoutname }.forEach {
33                         val firstVal = it.value[0]
34                         tab("case ${firstVal.modulePackage}.R.layout.${firstVal.layoutname}:") {
35                             if (it.value.size == 1) {
36                                 if (firstVal.isMerge) {
37                                     tab("return new ${firstVal.`package`}.${firstVal.implementationName}(bindingComponent, new android.view.View[]{view});")
38                                 } else {
39                                     tab("return ${firstVal.`package`}.${firstVal.implementationName}.bind(view, bindingComponent);")
40                                 }
41                             } else {
42                                 // we should check the tag to decide which layout we need to inflate
43                                 tab("{") {
44                                     tab("final Object tag = view.getTag();")
45                                     tab("if(tag == null) throw new java.lang.RuntimeException(\"view must have a tag\");")
46                                     it.value.forEach {
47                                         tab("if (\"${it.tag}_0\".equals(tag)) {") {
48                                             if (it.isMerge) {
49                                                 tab("return new ${it.`package`}.${it.implementationName}(bindingComponent, new android.view.View[]{view});")
50                                             } else {
51                                                 tab("return new ${it.`package`}.${it.implementationName}(bindingComponent, view);")
52                                             }
53                                         } tab("}")
54                                     }
55                                     tab("throw new java.lang.IllegalArgumentException(\"The tag for ${firstVal.layoutname} is invalid. Received: \" + tag);");
56                                 }tab("}")
57                             }
58 
59                         }
60                     }
61                 }
62                 tab("}")
63                 tab("return null;")
64             }
65             tab("}")
66 
67             tab("android.databinding.ViewDataBinding getDataBinder(android.databinding.DataBindingComponent bindingComponent, android.view.View[] views, int layoutId) {") {
68                 tab("switch(layoutId) {") {
69                     layoutBinders.filter{it.isMerge }.groupBy{it.layoutname }.forEach {
70                         val firstVal = it.value[0]
71                         tab("case ${firstVal.modulePackage}.R.layout.${firstVal.layoutname}:") {
72                             if (it.value.size == 1) {
73                                 tab("return new ${firstVal.`package`}.${firstVal.implementationName}(bindingComponent, views);")
74                             } else {
75                                 // we should check the tag to decide which layout we need to inflate
76                                 tab("{") {
77                                     tab("final Object tag = views[0].getTag();")
78                                     tab("if(tag == null) throw new java.lang.RuntimeException(\"view must have a tag\");")
79                                     it.value.forEach {
80                                         tab("if (\"${it.tag}_0\".equals(tag)) {") {
81                                             tab("return new ${it.`package`}.${it.implementationName}(bindingComponent, views);")
82                                         } tab("}")
83                                     }
84                                 }tab("}")
85                             }
86                         }
87                     }
88                 }
89                 tab("}")
90                 tab("return null;")
91             }
92             tab("}")
93 
94             tab("int getLayoutId(String tag) {") {
95                 tab("if (tag == null) {") {
96                     tab("return 0;");
97                 }
98                 tab("}")
99                 // String.hashCode is well defined in the API so we can rely on it being the same on the device and the host machine
100                 tab("final int code = tag.hashCode();");
101                 tab("switch(code) {") {
102                     layoutBinders.groupBy {"${it.tag}_0".hashCode()}.forEach {
103                         tab("case ${it.key}:") {
104                             it.value.forEach {
105                                 tab("if(tag.equals(\"${it.tag}_0\"))") {
106                                     tab("return ${it.modulePackage}.R.layout.${it.layoutname};")
107                                 }
108                             }
109                             tab("break;")
110                         }
111 
112                     }
113                 }
114                 tab("}")
115                 tab("return 0;")
116             }
117             tab("}")
118 
119             tab("String convertBrIdToString(int id) {") {
120                 tab("if (id < 0 || id >= InnerBrLookup.sKeys.length) {") {
121                     tab("return null;")
122                 } tab("}")
123                 tab("return InnerBrLookup.sKeys[id];")
124             } tab("}")
125 
126             tab("private static class InnerBrLookup {") {
127                 tab("static String[] sKeys = new String[]{") {
128                     tab("\"_all\"")
129                     brWriter.indexedProps.forEach {
130                         tab(",\"${it.value}\"")
131                     }
132                 }.app("};")
133             } tab("}")
134         }
135         nl("}")
136     }.generate()
137 }