1/* 2 * Copyright (C) 2015 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 */ 16package android.databinding.tool.writer; 17 18import android.databinding.tool.Binding; 19import android.databinding.tool.BindingTarget; 20import android.databinding.tool.LayoutBinder; 21import android.databinding.tool.processing.ScopedException; 22 23import java.util.ArrayList; 24import java.util.HashMap; 25import java.util.List; 26import java.util.Map.Entry; 27 28public class ComponentWriter { 29 private static final String INDENT = " "; 30 private final HashMap<String, ArrayList<String>> mBindingAdapters = new HashMap<>(); 31 32 public ComponentWriter(List<LayoutBinder> binders) { 33 HashMap<Binding, ArrayList<String>> bindings = new HashMap<>(); 34 35 for (LayoutBinder layoutBinder : binders) { 36 try { 37 android.databinding.tool.processing.Scope.enter(layoutBinder); 38 for (BindingTarget target : layoutBinder.getBindingTargets()) { 39 try { 40 android.databinding.tool.processing.Scope.enter(target); 41 for (Binding binding : target.getBindings()) { 42 try { 43 android.databinding.tool.processing.Scope.enter(binding); 44 final String bindingAdapter = binding 45 .getBindingAdapterInstanceClass(); 46 if (bindingAdapter != null) { 47 final String simpleName = simpleName(bindingAdapter); 48 ArrayList<String> classes = mBindingAdapters.get(simpleName); 49 if (classes == null) { 50 classes = new ArrayList<>(); 51 mBindingAdapters.put(simpleName, classes); 52 classes.add(bindingAdapter); 53 } else if (!classes.contains(bindingAdapter)) { 54 classes.add(bindingAdapter); 55 } 56 bindings.put(binding, classes); 57 } 58 } catch (ScopedException ex) { 59 android.databinding.tool.processing.Scope.defer(ex); 60 } finally{ 61 android.databinding.tool.processing.Scope.exit(); 62 } 63 } 64 } finally { 65 android.databinding.tool.processing.Scope.exit(); 66 } 67 } 68 } finally { 69 android.databinding.tool.processing.Scope.exit(); 70 } 71 } 72 73 for (Entry<Binding, ArrayList<String>> entry : bindings.entrySet()) { 74 final Binding binding = entry.getKey(); 75 final ArrayList<String> classes = entry.getValue(); 76 final String call; 77 if (classes.size() == 1) { 78 call = "get" + simpleName(classes.get(0)) + "()"; 79 } else { 80 int index = classes.indexOf(binding.getBindingAdapterInstanceClass()); 81 call = "get" + simpleName(classes.get(index)) + (index + 1) + "()"; 82 } 83 binding.setBindingAdapterCall(call); 84 } 85 } 86 87 public String createComponent() { 88 final StringBuilder builder = new StringBuilder(); 89 builder.append("package android.databinding;\n\n"); 90 builder.append("public interface DataBindingComponent {\n"); 91 for (final String simpleName : mBindingAdapters.keySet()) { 92 final ArrayList<String> classes = mBindingAdapters.get(simpleName); 93 if (classes.size() > 1) { 94 int index = 1; 95 for (String className : classes) { 96 addGetter(builder, simpleName, className, index++); 97 } 98 } else { 99 addGetter(builder, simpleName, classes.iterator().next(), 0); 100 } 101 } 102 builder.append("}\n"); 103 return builder.toString(); 104 } 105 106 private static String simpleName(String className) { 107 int dotIndex = className.lastIndexOf('.'); 108 if (dotIndex < 0) { 109 return className; 110 } else { 111 return className.substring(dotIndex + 1); 112 } 113 } 114 115 private static void addGetter(StringBuilder builder, String simpleName, String className, 116 int index) { 117 builder.append(INDENT) 118 .append(className) 119 .append(" get") 120 .append(simpleName); 121 if (index > 0) { 122 builder.append(index); 123 } 124 builder.append("();\n"); 125 } 126} 127