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