no direct interface to ObservableList's value
[mobile-ledger.git] / app / src / main / java / net / ktnx / mobileledger / utils / ObservableList.java
1 /*
2  * Copyright © 2019 Damyan Ivanov.
3  * This file is part of MoLe.
4  * MoLe is free software: you can distribute it and/or modify it
5  * under the term of the GNU General Public License as published by
6  * the Free Software Foundation, either version 3 of the License, or
7  * (at your opinion), any later version.
8  *
9  * MoLe is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License terms for details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with MoLe. If not, see <https://www.gnu.org/licenses/>.
16  */
17
18 package net.ktnx.mobileledger.utils;
19
20 import android.os.Build;
21 import android.util.Log;
22
23 import java.util.Collection;
24 import java.util.Comparator;
25 import java.util.Iterator;
26 import java.util.List;
27 import java.util.ListIterator;
28 import java.util.Observable;
29 import java.util.Spliterator;
30 import java.util.function.Consumer;
31 import java.util.function.Predicate;
32 import java.util.function.UnaryOperator;
33 import java.util.stream.Stream;
34
35 import androidx.annotation.NonNull;
36 import androidx.annotation.Nullable;
37 import androidx.annotation.RequiresApi;
38
39 public class ObservableList<T> extends Observable implements List<T> {
40     private List<T> list;
41     public ObservableList(List<T> list) {
42         this.list = list;
43     }
44     private void forceNotify() {
45         setChanged();
46         notifyObservers();
47     }
48     private void forceNotify(int index) {
49         setChanged();
50         notifyObservers(index);
51     }
52     public int size() {
53         return list.size();
54     }
55     public boolean isEmpty() {
56         return list.isEmpty();
57     }
58     public boolean contains(@Nullable Object o) {
59         return list.contains(o);
60     }
61     @NonNull
62     public Iterator<T> iterator() {
63         return list.iterator();
64     }
65     public Object[] toArray() {
66         return list.toArray();
67     }
68     public <T1> T1[] toArray(@Nullable T1[] a) {
69         return list.toArray(a);
70     }
71     public boolean add(T t) {
72         boolean result = list.add(t);
73         if (result) forceNotify();
74         return result;
75     }
76     public boolean remove(@Nullable Object o) {
77         boolean result = list.remove(o);
78         if (result) forceNotify();
79         return result;
80     }
81     public T removeQuietly(int index) {
82         return list.remove(index);
83     }
84     public boolean containsAll(@NonNull Collection<?> c) {
85         return list.containsAll(c);
86     }
87     public boolean addAll(@NonNull Collection<? extends T> c) {
88         boolean result = list.addAll(c);
89         if (result) forceNotify();
90         return result;
91     }
92     public boolean addAll(int index, @NonNull Collection<? extends T> c) {
93         boolean result = list.addAll(index, c);
94         if (result) forceNotify();
95         return result;
96     }
97     public boolean addAllQuietly(int index, Collection<? extends T> c) {
98         return list.addAll(index, c);
99     }
100     public boolean removeAll(@NonNull Collection<?> c) {
101         boolean result = list.removeAll(c);
102         if (result) forceNotify();
103         return result;
104     }
105     public boolean retainAll(@NonNull Collection<?> c) {
106         boolean result = list.retainAll(c);
107         if (result) forceNotify();
108         return result;
109     }
110     @RequiresApi(api = Build.VERSION_CODES.N)
111     public void replaceAll(@NonNull UnaryOperator<T> operator) {
112         list.replaceAll(operator);
113         forceNotify();
114     }
115     @RequiresApi(api = Build.VERSION_CODES.N)
116     public void sort(@Nullable Comparator<? super T> c) {
117         list.sort(c);
118         forceNotify();
119     }
120     public void clear() {
121         boolean wasEmpty = list.isEmpty();
122         list.clear();
123         if (!wasEmpty) forceNotify();
124     }
125     public T get(int index) {
126         return list.get(index);
127     }
128     public T set(int index, T element) {
129         T result = list.set(index, element);
130         forceNotify();
131         return result;
132     }
133     public void add(int index, T element) {
134         list.add(index, element);
135         forceNotify();
136     }
137     public T remove(int index) {
138         T result = list.remove(index);
139         forceNotify();
140         return result;
141     }
142     public int indexOf(@Nullable Object o) {
143         return list.indexOf(o);
144     }
145     public int lastIndexOf(@Nullable Object o) {
146         return list.lastIndexOf(o);
147     }
148     public ListIterator<T> listIterator() {
149         return list.listIterator();
150     }
151     public ListIterator<T> listIterator(int index) {
152         return list.listIterator(index);
153     }
154     public List<T> subList(int fromIndex, int toIndex) {
155         return list.subList(fromIndex, toIndex);
156     }
157     @RequiresApi(api = Build.VERSION_CODES.N)
158     public Spliterator<T> spliterator() {
159         return list.spliterator();
160     }
161     @RequiresApi(api = Build.VERSION_CODES.N)
162     public boolean removeIf(Predicate<? super T> filter) {
163         boolean result = list.removeIf(filter);
164         if (result) forceNotify();
165         return result;
166     }
167     @RequiresApi(api = Build.VERSION_CODES.N)
168     public Stream<T> stream() {
169         return list.stream();
170     }
171     @RequiresApi(api = Build.VERSION_CODES.N)
172     public Stream<T> parallelStream() {
173         return list.parallelStream();
174     }
175     @RequiresApi(api = Build.VERSION_CODES.N)
176     public void forEach(Consumer<? super T> action) {
177         list.forEach(action);
178     }
179     public List<T> getList() {
180         return list;
181     }
182     public void setList(List<T> aList) {
183         list = aList;
184         forceNotify();
185     }
186     public void triggerItemChangedNotification(T item) {
187         int index = list.indexOf(item);
188         if (index == -1) {
189             Log.d("ObList", "??? not sending notifications for item not found in the list");
190             return;
191         }
192         Log.d("ObList", "Notifying item change observers");
193         triggerItemChangedNotification(index);
194     }
195     public void triggerItemChangedNotification(int index) {
196         forceNotify(index);
197     }
198 }