• 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.LayoutBinderWriterKt;
26 
27 import java.lang.reflect.Array;
28 import java.util.ArrayList;
29 import java.util.Arrays;
30 import java.util.List;
31 
32 /**
33  * Multiple binding expressions can be evaluated using a single adapter. In those cases,
34  * we replace the Binding with a MergedBinding.
35  */
36 public class MergedBinding extends Binding {
37     private final SetterStore.MultiAttributeSetter mMultiAttributeSetter;
MergedBinding(ExprModel model, SetterStore.MultiAttributeSetter multiAttributeSetter, BindingTarget target, Iterable<Binding> bindings)38     public MergedBinding(ExprModel model, SetterStore.MultiAttributeSetter multiAttributeSetter,
39             BindingTarget target, Iterable<Binding> bindings) {
40         super(target, createMergedName(bindings), createArgListExpr(model, bindings));
41         mMultiAttributeSetter = multiAttributeSetter;
42     }
43 
44     @Override
resolveListeners()45     public void resolveListeners() {
46         ModelClass[] parameters = mMultiAttributeSetter.getParameterTypes();
47         List<Expr> children = getExpr().getChildren();
48         final Expr expr = getExpr();
49         for (int i = 0; i < children.size(); i++) {
50             final Expr child = children.get(i);
51             child.resolveListeners(parameters[i], expr);
52         }
53     }
54 
createArgListExpr(ExprModel model, final Iterable<Binding> bindings)55     private static Expr createArgListExpr(ExprModel model, final Iterable<Binding> bindings) {
56         List<Expr> args = new ArrayList<Expr>();
57         for (Binding binding : bindings) {
58             args.add(binding.getExpr());
59         }
60         Expr expr = model.argListExpr(args);
61         expr.setBindingExpression(true);
62         return expr;
63     }
64 
createMergedName(Iterable<Binding> bindings)65     private static String createMergedName(Iterable<Binding> bindings) {
66         StringBuilder sb = new StringBuilder();
67         for (Binding binding : bindings) {
68             sb.append(binding.getName());
69         }
70         return sb.toString();
71     }
72 
getComponentExpressions()73     public Expr[] getComponentExpressions() {
74         ArgListExpr args = (ArgListExpr) getExpr();
75         return args.getChildren().toArray(new Expr[args.getChildren().size()]);
76     }
77 
getAttributes()78     public String[] getAttributes() {
79         return mMultiAttributeSetter.attributes;
80     }
81 
82     @Override
getBindingAdapterInstanceClass()83     public String getBindingAdapterInstanceClass() {
84         return mMultiAttributeSetter.getBindingAdapterInstanceClass();
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<String>();
101         for (Expr expr : args.getChildren()) {
102             newValues.add(expr.toCode().generate());
103         }
104         final List<String> oldValues;
105         if (requiresOldValue()) {
106             oldValues = new ArrayList<String>();
107             for (Expr expr : args.getChildren()) {
108                 oldValues.add("this." + LayoutBinderWriterKt.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<T>();
120         result.addAll(l1);
121         result.addAll(l2);
122         return result.toArray((T[]) Array.newInstance(klass, result.size()));
123     }
124 }
125