Binding.java revision e9b33bac04bb1ce1444d7f1744fcec1ecd3a57da
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.Expr;
20import android.databinding.tool.reflection.ModelAnalyzer;
21import android.databinding.tool.reflection.ModelClass;
22import android.databinding.tool.store.SetterStore;
23import android.databinding.tool.store.SetterStore.SetterCall;
24import android.databinding.tool.writer.CodeGenUtil;
25
26public class Binding {
27
28    private final String mName;
29    private final Expr mExpr;
30    private final BindingTarget mTarget;
31    private SetterStore.SetterCall mSetterCall;
32
33    public Binding(BindingTarget target, String name, Expr expr) {
34        mTarget = target;
35        mName = name;
36        mExpr = expr;
37    }
38
39    private SetterStore.BindingSetterCall getSetterCall() {
40        if (mSetterCall == null) {
41            ModelClass viewType = mTarget.getResolvedType();
42            if (viewType != null && viewType.extendsViewStub()) {
43                if (isViewStubAttribute()) {
44                    mSetterCall = new ViewStubDirectCall(mName, viewType, mExpr);
45                } else {
46                    mSetterCall = new ViewStubSetterCall(mName);
47                }
48            } else {
49                mSetterCall = SetterStore.get(ModelAnalyzer.getInstance()).getSetterCall(mName,
50                        viewType, mExpr.getResolvedType(), mExpr.getModel().getImports());
51            }
52        }
53        return mSetterCall;
54    }
55
56    public BindingTarget getTarget() {
57        return mTarget;
58    }
59
60    public String toJavaCode(String targetViewName) {
61        String argCode = CodeGenUtil.Companion.toCode(getExpr(), false).generate();
62        return getSetterCall().toJava(targetViewName, argCode);
63    }
64
65    /**
66     * The min api level in which this binding should be executed.
67     * <p>
68     * This should be the minimum value among the dependencies of this binding. For now, we only
69     * check the setter.
70     */
71    public int getMinApi() {
72        return getSetterCall().getMinApi();
73    }
74
75    public String getName() {
76        return mName;
77    }
78
79    public Expr getExpr() {
80        return mExpr;
81    }
82
83    private boolean isViewStubAttribute() {
84        if ("android:inflatedId".equals(mName)) {
85            return true;
86        } else if ("android:layout".equals(mName)) {
87            return true;
88        } else if ("android:visibility".equals(mName)) {
89            return true;
90        } else {
91            return false;
92        }
93    }
94
95    private static class ViewStubSetterCall extends SetterCall {
96        private final String mName;
97
98        public ViewStubSetterCall(String name) {
99            mName = name.substring(name.lastIndexOf(':') + 1);
100        }
101
102        @Override
103        protected String toJavaInternal(String viewExpression, String converted) {
104            return "if (" + viewExpression + ".isInflated()) " + viewExpression +
105                    ".getBinding().setVariable(BR." + mName + ", " + converted + ")";
106        }
107
108        @Override
109        public int getMinApi() {
110            return 0;
111        }
112    }
113
114    private static class ViewStubDirectCall extends SetterCall {
115        private final SetterCall mWrappedCall;
116
117        public ViewStubDirectCall(String name, ModelClass viewType, Expr expr) {
118            mWrappedCall = SetterStore.get(ModelAnalyzer.getInstance()).getSetterCall(name,
119                    viewType, expr.getResolvedType(), expr.getModel().getImports());
120        }
121
122        @Override
123        protected String toJavaInternal(String viewExpression, String converted) {
124            return "if (!" + viewExpression + ".isInflated()) " +
125                    mWrappedCall.toJava(viewExpression + ".getViewStub()", converted);
126        }
127
128        @Override
129        public int getMinApi() {
130            return 0;
131        }
132    }
133}
134