1e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount/* 2e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount * Copyright (C) 2015 The Android Open Source Project 3e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount * 4e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount * Licensed under the Apache License, Version 2.0 (the "License"); 5e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount * you may not use this file except in compliance with the License. 6e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount * You may obtain a copy of the License at 7e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount * 8e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount * http://www.apache.org/licenses/LICENSE-2.0 9e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount * 10e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount * Unless required by applicable law or agreed to in writing, software 11e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount * distributed under the License is distributed on an "AS IS" BASIS, 12e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount * See the License for the specific language governing permissions and 14e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount * limitations under the License. 15e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount */ 16e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mountpackage android.databinding.tool.writer; 17e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount 18e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mountimport android.databinding.tool.Binding; 19e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mountimport android.databinding.tool.BindingTarget; 20e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mountimport android.databinding.tool.LayoutBinder; 21e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mountimport android.databinding.tool.processing.ScopedException; 22e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount 23e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mountimport java.util.ArrayList; 24e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mountimport java.util.HashMap; 25e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mountimport java.util.List; 26e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mountimport java.util.Map.Entry; 27e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount 28e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mountpublic class ComponentWriter { 29e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount private static final String INDENT = " "; 30e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount private final HashMap<String, ArrayList<String>> mBindingAdapters = new HashMap<>(); 31e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount 32e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount public ComponentWriter(List<LayoutBinder> binders) { 33e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount HashMap<Binding, ArrayList<String>> bindings = new HashMap<>(); 34e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount 35e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount for (LayoutBinder layoutBinder : binders) { 36e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount try { 37e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount android.databinding.tool.processing.Scope.enter(layoutBinder); 38e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount for (BindingTarget target : layoutBinder.getBindingTargets()) { 39e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount try { 40e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount android.databinding.tool.processing.Scope.enter(target); 41e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount for (Binding binding : target.getBindings()) { 42e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount try { 43e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount android.databinding.tool.processing.Scope.enter(binding); 44e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount final String bindingAdapter = binding 45e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount .getBindingAdapterInstanceClass(); 46e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount if (bindingAdapter != null) { 47e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount final String simpleName = simpleName(bindingAdapter); 48e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount ArrayList<String> classes = mBindingAdapters.get(simpleName); 49e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount if (classes == null) { 50e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount classes = new ArrayList<>(); 51e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount mBindingAdapters.put(simpleName, classes); 52e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount classes.add(bindingAdapter); 53e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount } else if (!classes.contains(bindingAdapter)) { 54e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount classes.add(bindingAdapter); 55e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount } 56e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount bindings.put(binding, classes); 57e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount } 58e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount } catch (ScopedException ex) { 59e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount android.databinding.tool.processing.Scope.defer(ex); 60e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount } finally{ 61e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount android.databinding.tool.processing.Scope.exit(); 62e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount } 63e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount } 64e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount } finally { 65e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount android.databinding.tool.processing.Scope.exit(); 66e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount } 67e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount } 68e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount } finally { 69e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount android.databinding.tool.processing.Scope.exit(); 70e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount } 71e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount } 72e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount 73e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount for (Entry<Binding, ArrayList<String>> entry : bindings.entrySet()) { 74e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount final Binding binding = entry.getKey(); 75e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount final ArrayList<String> classes = entry.getValue(); 76e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount final String call; 77e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount if (classes.size() == 1) { 78e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount call = "get" + simpleName(classes.get(0)) + "()"; 79e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount } else { 80e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount int index = classes.indexOf(binding.getBindingAdapterInstanceClass()); 81e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount call = "get" + simpleName(classes.get(index)) + (index + 1) + "()"; 82e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount } 83e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount binding.setBindingAdapterCall(call); 84e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount } 85e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount } 86e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount 87e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount public String createComponent() { 88e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount final StringBuilder builder = new StringBuilder(); 89e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount builder.append("package android.databinding;\n\n"); 90e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount builder.append("public interface DataBindingComponent {\n"); 91e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount for (final String simpleName : mBindingAdapters.keySet()) { 92e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount final ArrayList<String> classes = mBindingAdapters.get(simpleName); 93e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount if (classes.size() > 1) { 94e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount int index = 1; 95e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount for (String className : classes) { 96e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount addGetter(builder, simpleName, className, index++); 97e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount } 98e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount } else { 99e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount addGetter(builder, simpleName, classes.iterator().next(), 0); 100e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount } 101e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount } 102e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount builder.append("}\n"); 103e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount return builder.toString(); 104e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount } 105e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount 106e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount private static String simpleName(String className) { 107e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount int dotIndex = className.lastIndexOf('.'); 108e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount if (dotIndex < 0) { 109e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount return className; 110e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount } else { 111e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount return className.substring(dotIndex + 1); 112e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount } 113e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount } 114e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount 115e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount private static void addGetter(StringBuilder builder, String simpleName, String className, 116e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount int index) { 117e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount builder.append(INDENT) 118e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount .append(className) 119e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount .append(" get") 120e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount .append(simpleName); 121e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount if (index > 0) { 122e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount builder.append(index); 123e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount } 124e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount builder.append("();\n"); 125e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount } 126e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount} 127