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 package com.android.messaging.datamodel.binding;
17 
18 import com.android.messaging.util.Assert;
19 
20 /**
21  * A immutable wrapper around a Binding object. Callers can only access readonly methods like
22  * getData(), isBound() and ensureBound() but not bind() and unbind(). This is used for MVC pattern
23  * where both the View and the Controller needs access to a centrally bound Model object. The View
24  * is the one that owns the bind/unbind logic of the Binding, whereas controller only serves as a
25  * consumer.
26  */
27 public class ImmutableBindingRef<T extends BindableData> extends BindingBase<T> {
28     /**
29      * The referenced, read-only binding object.
30      */
31     private final BindingBase<T> mBinding;
32 
33     /**
34      * Hidden ctor.
35      */
ImmutableBindingRef(final BindingBase<T> binding)36     ImmutableBindingRef(final BindingBase<T> binding) {
37         mBinding = resolveBinding(binding);
38     }
39 
40     @Override
getData()41     public T getData() {
42         return mBinding.getData();
43     }
44 
45     @Override
isBound()46     public boolean isBound() {
47         return mBinding.isBound();
48     }
49 
50     @Override
isBound(final T data)51     public boolean isBound(final T data) {
52         return mBinding.isBound(data);
53     }
54 
55     @Override
ensureBound()56     public void ensureBound() {
57         mBinding.ensureBound();
58     }
59 
60     @Override
ensureBound(final T data)61     public void ensureBound(final T data) {
62         mBinding.ensureBound(data);
63     }
64 
65     @Override
getBindingId()66     public String getBindingId() {
67         return mBinding.getBindingId();
68     }
69 
70     /**
71      * Resolve the source binding to the real BindingImpl it's referencing. This avoids the
72      * redundancy of multiple wrapper calls when creating a binding reference from an existing
73      * binding reference.
74      */
resolveBinding(final BindingBase<T> binding)75     private BindingBase<T> resolveBinding(final BindingBase<T> binding) {
76         BindingBase<T> resolvedBinding = binding;
77         while (resolvedBinding instanceof ImmutableBindingRef<?>) {
78             resolvedBinding = ((ImmutableBindingRef<T>) resolvedBinding).mBinding;
79         }
80         Assert.isTrue(resolvedBinding instanceof Binding<?>);
81         return resolvedBinding;
82     }
83 }
84