MergedBinding.java revision a128d1c99ea98bb48c45d648906652e3d618d513
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 */ 16 17package android.databinding.tool; 18 19import android.databinding.tool.expr.ArgListExpr; 20import android.databinding.tool.expr.Expr; 21import android.databinding.tool.expr.ExprModel; 22import android.databinding.tool.store.SetterStore; 23import android.databinding.tool.util.L; 24import android.databinding.tool.writer.WriterPackage; 25 26import java.lang.reflect.Array; 27import java.util.ArrayList; 28import java.util.Arrays; 29import java.util.List; 30 31/** 32 * Multiple binding expressions can be evaluated using a single adapter. In those cases, 33 * we replace the Binding with a MergedBinding. 34 */ 35public class MergedBinding extends Binding { 36 private final SetterStore.MultiAttributeSetter mMultiAttributeSetter; 37 public MergedBinding(ExprModel model, SetterStore.MultiAttributeSetter multiAttributeSetter, 38 BindingTarget target, Iterable<Binding> bindings) { 39 super(target, createMergedName(bindings), createArgListExpr(model, bindings)); 40 mMultiAttributeSetter = multiAttributeSetter; 41 } 42 43 private static Expr createArgListExpr(ExprModel model, final Iterable<Binding> bindings) { 44 List<Expr> args = new ArrayList<>(); 45 for (Binding binding : bindings) { 46 args.add(binding.getExpr()); 47 } 48 Expr expr = model.argListExpr(args); 49 expr.setBindingExpression(true); 50 return expr; 51 } 52 53 private static String createMergedName(Iterable<Binding> bindings) { 54 StringBuilder sb = new StringBuilder(); 55 for (Binding binding : bindings) { 56 sb.append(binding.getName()); 57 } 58 return sb.toString(); 59 } 60 61 public Expr[] getComponentExpressions() { 62 ArgListExpr args = (ArgListExpr) getExpr(); 63 return args.getChildren().toArray(new Expr[args.getChildren().size()]); 64 } 65 66 @Override 67 public String getBindingAdapterInstanceClass() { 68 return mMultiAttributeSetter.getBindingAdapterInstanceClass(); 69 } 70 71 @Override 72 public boolean requiresOldValue() { 73 return mMultiAttributeSetter.requiresOldValue(); 74 } 75 76 @Override 77 public int getMinApi() { 78 return 1; 79 } 80 81 @Override 82 public String toJavaCode(String targetViewName, String bindingComponent) { 83 final ArgListExpr args = (ArgListExpr) getExpr(); 84 final List<String> newValues = new ArrayList<>(); 85 for (Expr expr : args.getChildren()) { 86 newValues.add(expr.toCode().generate()); 87 } 88 final List<String> oldValues; 89 if (requiresOldValue()) { 90 oldValues = new ArrayList<>(); 91 for (Expr expr : args.getChildren()) { 92 oldValues.add("this." + WriterPackage.getOldValueName(expr)); 93 } 94 } else { 95 oldValues = Arrays.asList(new String[args.getChildren().size()]); 96 } 97 final String[] expressions = concat(oldValues, newValues, String.class); 98 L.d("merged binding arg: %s", args.getUniqueKey()); 99 return mMultiAttributeSetter.toJava(bindingComponent, targetViewName, expressions); 100 } 101 102 private static <T> T[] concat(List<T> l1, List<T> l2, Class<T> klass) { 103 List<T> result = new ArrayList<>(); 104 result.addAll(l1); 105 result.addAll(l2); 106 return result.toArray((T[]) Array.newInstance(klass, result.size())); 107 } 108} 109