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.writer 15 16import android.databinding.tool.LayoutBinder 17 18class DataBinderWriter(val pkg: String, val projectPackage: String, val className: String, 19 val layoutBinders : List<LayoutBinder>, val minSdk : kotlin.Int) { 20 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.getLayoutname()}.forEach { 33 val firstVal = it.value.get(0) 34 tab("case ${firstVal.getModulePackage()}.R.layout.${firstVal.getLayoutname()}:") { 35 if (it.value.size() == 1) { 36 if (firstVal.isMerge()) { 37 tab("return new ${firstVal.getPackage()}.${firstVal.getImplementationName()}(bindingComponent, new android.view.View[]{view});") 38 } else { 39 tab("return ${firstVal.getPackage()}.${firstVal.getImplementationName()}.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.getTag()}_0\".equals(tag)) {") { 48 if (it.isMerge()) { 49 tab("return new ${it.getPackage()}.${it.getImplementationName()}(bindingComponent, new android.view.View[]{view});") 50 } else { 51 tab("return new ${it.getPackage()}.${it.getImplementationName()}(bindingComponent, view);") 52 } 53 } tab("}") 54 } 55 }tab("}") 56 } 57 58 } 59 } 60 } 61 tab("}") 62 tab("return null;") 63 } 64 tab("}") 65 66 tab("android.databinding.ViewDataBinding getDataBinder(android.databinding.DataBindingComponent bindingComponent, android.view.View[] views, int layoutId) {") { 67 tab("switch(layoutId) {") { 68 layoutBinders.filter{it.isMerge()}.groupBy{it.getLayoutname()}.forEach { 69 val firstVal = it.value.get(0) 70 tab("case ${firstVal.getModulePackage()}.R.layout.${firstVal.getLayoutname()}:") { 71 if (it.value.size() == 1) { 72 tab("return new ${firstVal.getPackage()}.${firstVal.getImplementationName()}(bindingComponent, views);") 73 } else { 74 // we should check the tag to decide which layout we need to inflate 75 tab("{") { 76 tab("final Object tag = views[0].getTag();") 77 tab("if(tag == null) throw new java.lang.RuntimeException(\"view must have a tag\");") 78 it.value.forEach { 79 tab("if (\"${it.getTag()}_0\".equals(tag)) {") { 80 tab("return new ${it.getPackage()}.${it.getImplementationName()}(bindingComponent, views);") 81 } tab("}") 82 } 83 }tab("}") 84 } 85 } 86 } 87 } 88 tab("}") 89 tab("return null;") 90 } 91 tab("}") 92 93 tab("int getLayoutId(String tag) {") { 94 tab("if (tag == null) {") { 95 tab("return 0;"); 96 } 97 tab("}") 98 // String.hashCode is well defined in the API so we can rely on it being the same on the device and the host machine 99 tab("final int code = tag.hashCode();"); 100 tab("switch(code) {") { 101 layoutBinders.groupBy {"${it.getTag()}_0".hashCode()}.forEach { 102 tab("case ${it.key}:") { 103 it.value.forEach { 104 tab("if(tag.equals(\"${it.getTag()}_0\"))") { 105 tab("return ${it.getModulePackage()}.R.layout.${it.getLayoutname()};") 106 } 107 } 108 tab("break;") 109 } 110 111 } 112 } 113 tab("}") 114 tab("return 0;") 115 } 116 tab("}") 117 118 tab("String convertBrIdToString(int id) {") { 119 tab("if (id < 0 || id >= InnerBrLookup.sKeys.length) {") { 120 tab("return null;") 121 } tab("}") 122 tab("return InnerBrLookup.sKeys[id];") 123 } tab("}") 124 125 tab("private static class InnerBrLookup {") { 126 tab("static String[] sKeys = new String[]{") { 127 tab("\"_all\"") 128 brWriter.indexedProps.forEach { 129 tab(",\"${it.value}\"") 130 } 131 }.app("};") 132 } tab("}") 133 } 134 nl("}") 135 }.generate() 136}