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 */
16package android.databinding;
17
18import android.support.v4.util.ArrayMap;
19
20import java.util.Collection;
21
22public class ObservableArrayMap<K, V> extends ArrayMap<K, V> implements ObservableMap<K, V> {
23
24    private transient MapChangeRegistry mListeners;
25
26    @Override
27    public void addOnMapChangedCallback(
28            OnMapChangedCallback<? extends ObservableMap<K, V>, K, V> listener) {
29        if (mListeners == null) {
30            mListeners = new MapChangeRegistry();
31        }
32        mListeners.add(listener);
33    }
34
35    @Override
36    public void removeOnMapChangedCallback(
37            OnMapChangedCallback<? extends ObservableMap<K, V>, K, V> listener) {
38        if (mListeners != null) {
39            mListeners.remove(listener);
40        }
41    }
42
43    @Override
44    public void clear() {
45        boolean wasEmpty = isEmpty();
46        if (!wasEmpty) {
47            super.clear();
48            notifyChange(null);
49        }
50    }
51
52    public V put(K k, V v) {
53        V val = super.put(k, v);
54        notifyChange(k);
55        return v;
56    }
57
58    @Override
59    public boolean removeAll(Collection<?> collection) {
60        boolean removed = false;
61        for (Object key : collection) {
62            int index = indexOfKey(key);
63            if (index >= 0) {
64                removed = true;
65                removeAt(index);
66            }
67        }
68        return removed;
69    }
70
71    @Override
72    public boolean retainAll(Collection<?> collection) {
73        boolean removed = false;
74        for (int i = size() - 1; i >= 0; i--) {
75            Object key = keyAt(i);
76            if (!collection.contains(key)) {
77                removeAt(i);
78                removed = true;
79            }
80        }
81        return removed;
82    }
83
84    @Override
85    public V removeAt(int index) {
86        K key = keyAt(index);
87        V value = super.removeAt(index);
88        if (value != null) {
89            notifyChange(key);
90        }
91        return value;
92    }
93
94    @Override
95    public V setValueAt(int index, V value) {
96        K key = keyAt(index);
97        V oldValue = super.setValueAt(index, value);
98        notifyChange(key);
99        return oldValue;
100    }
101
102    private void notifyChange(Object key) {
103        if (mListeners != null) {
104            mListeners.notifyCallbacks(this, 0, key);
105        }
106    }
107}
108