001    /*
002      GRANITE DATA SERVICES
003      Copyright (C) 2012 GRANITE DATA SERVICES S.A.S.
004    
005      This file is part of Granite Data Services.
006    
007      Granite Data Services is free software; you can redistribute it and/or modify
008      it under the terms of the GNU Library General Public License as published by
009      the Free Software Foundation; either version 2 of the License, or (at your
010      option) any later version.
011    
012      Granite Data Services is distributed in the hope that it will be useful, but
013      WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
014      FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License
015      for more details.
016    
017      You should have received a copy of the GNU Library General Public License
018      along with this library; if not, see <http://www.gnu.org/licenses/>.
019    */
020    
021    package org.granite.client.tide.collections.javafx;
022    
023    import java.util.Collection;
024    import java.util.Iterator;
025    import java.util.List;
026    import java.util.ListIterator;
027    
028    import javafx.beans.InvalidationListener;
029    import javafx.collections.ListChangeListener;
030    import javafx.collections.ObservableList;
031    
032    import org.granite.client.persistence.LazyableCollection;
033    import org.granite.client.tide.collections.ManagedPersistentCollection;
034    import org.granite.client.tide.data.Identifiable;
035    
036    
037    /**
038     *  Internal implementation of persistent collection handling automatic lazy loading.<br/>
039     *  Used for wrapping persistent collections received from the server.<br/>
040     *  Should not be used directly.
041     * 
042     *  @author William DRAI
043     */
044    public class JavaFXManagedPersistentCollection<T> extends AbstractJavaFXManagedPersistentAssociation implements ObservableList<T>, ManagedPersistentCollection<T> {
045        
046        private final ObservableList<T> list;
047        
048        
049        @SuppressWarnings("unchecked")
050            public JavaFXManagedPersistentCollection(Identifiable entity, String propertyName, LazyableCollection list) {
051            super(entity, propertyName);
052            this.list = (ObservableList<T>)list;
053        }
054        
055        
056        public Object getObject() {
057            return list;
058        }
059    
060        @Override
061        public LazyableCollection getCollection() {
062            return (LazyableCollection)list;
063        }
064       
065        public boolean isInitialized() {
066            return ((LazyableCollection)list).isInitialized();
067        }    
068        
069        public int size() {
070            if (checkForRead())
071                return list.size();
072            return 0;
073        }
074    
075        public boolean isEmpty() {
076            if (checkForRead())
077                return list.isEmpty();
078            return true;
079        }
080    
081        @Override
082        public void clear() {
083            boolean wasInitialized = checkForRead(false);
084            list.clear();
085            if (!wasInitialized)
086                initialize();
087        }
088        
089        public T get(int index) {
090            if (checkForRead())
091                return list.get(index);
092            return null;
093        }
094    
095        @Override
096        public boolean contains(Object item) {
097            if (checkForRead())
098                return list.contains(item);
099            return false;
100        }
101    
102        @Override
103        public boolean containsAll(Collection<?> items) {
104            if (checkForRead())
105                return list.containsAll(items);
106            return false;
107        }
108    
109        @Override
110        public Object[] toArray() {
111            if (checkForRead())
112                return list.toArray();
113            return null;
114        }
115    
116        @SuppressWarnings("hiding")
117            @Override
118        public <T> T[] toArray(T[] a) {
119            if (checkForRead())
120                return list.toArray(a);
121            return null;
122        }
123        
124        public boolean add(T item) {
125            checkForWrite();
126            return list.add(item);
127        }
128        
129        public void add(int index, T item) {
130            checkForWrite();
131            list.add(index, item);
132        }
133        
134        public boolean addAll(Collection<? extends T> items) {
135            checkForWrite();
136            return list.addAll(items);
137        }
138        
139        public boolean addAll(int index, Collection<? extends T> items) {
140            checkForWrite();
141            return list.addAll(index, items);
142        }
143        
144        public boolean addAll(T... items) {
145            checkForWrite();
146            return list.addAll(items);
147        }
148        
149        public T set(int index, T item) {
150            checkForWrite();
151            return list.set(index, item);
152        }
153        
154        public boolean setAll(Collection<? extends T> items) {
155            checkForWrite();
156            return list.setAll(items);
157        }
158        
159        public boolean setAll(T... items) {
160            checkForWrite();
161            return list.setAll(items);
162        }
163        
164        public T remove(int index) {
165            checkForWrite();
166            return list.remove(index);
167        }
168        
169        public boolean remove(Object item) {
170            checkForWrite();
171            return list.remove(item);
172        }
173        
174        public void remove(int fromIndex, int toIndex) {
175            checkForWrite();
176            list.remove(fromIndex, toIndex);
177        }
178        
179        public boolean removeAll(Collection<?> items) {
180            checkForWrite();
181            return list.removeAll(items);
182        }
183        
184        public boolean removeAll(T... items) {
185            checkForWrite();
186            return list.removeAll(items);
187        }
188    
189        @Override
190        public boolean retainAll(Collection<?> items) {
191            checkForWrite();
192            return list.retainAll(items);
193        }
194    
195        @Override
196        public boolean retainAll(T... items) {
197            checkForWrite();
198            return list.retainAll(items);
199        }
200    
201        @Override
202        public int indexOf(Object item) {
203            if (checkForRead())
204                return list.indexOf(item);
205            return -1;
206        }
207    
208        @Override
209        public int lastIndexOf(Object item) {
210            if (checkForRead())
211                return list.lastIndexOf(item);
212            return -1;
213        }
214    
215        @Override
216        public Iterator<T> iterator() {
217            return new CheckReadIterator(0);
218        }
219    
220        @Override
221        public ListIterator<T> listIterator() {
222            return new CheckReadIterator(0);
223        }
224    
225        @Override
226        public ListIterator<T> listIterator(int index) {
227            return new CheckReadIterator(index);
228        }
229        
230        public class CheckReadIterator implements ListIterator<T> {
231            
232            private final ListIterator<T> listIterator;
233            
234            public CheckReadIterator(int index) {
235                    if (checkForRead())
236                            listIterator = list.listIterator(index);
237                    else
238                            listIterator = null;
239            }
240    
241                    @Override
242                    public boolean hasNext() {
243                            return listIterator != null ? listIterator.hasNext() : false;
244                    }
245    
246                    @Override
247                    public T next() {
248                            if (listIterator != null)
249                                    return listIterator.next();
250                            throw new IllegalStateException("Cannot call next() on uninitialized collection");
251                    }
252    
253                    @Override
254                    public boolean hasPrevious() {
255                            return listIterator != null ? listIterator.hasNext() : false;
256                    }
257    
258                    @Override
259                    public T previous() {
260                            if (listIterator != null)
261                                    return listIterator.previous();
262                            throw new IllegalStateException("Cannot call previous() on iterator for uninitialized collection");
263                    }
264    
265                    @Override
266                    public int nextIndex() {
267                            return listIterator != null ? listIterator.nextIndex() : 0;
268                    }
269    
270                    @Override
271                    public int previousIndex() {
272                            return listIterator != null ? listIterator.previousIndex() : 0;
273                    }
274    
275                    @Override
276                    public void remove() {
277                            if (listIterator != null)
278                                    listIterator.remove();
279                            else
280                                    throw new IllegalStateException("Cannot call remove() on iterator for uninitialized collection");
281                    }
282    
283                    @Override
284                    public void set(T e) {
285                            if (listIterator != null)
286                                    listIterator.set(e);
287                            else
288                                    throw new IllegalStateException("Cannot call set() on iterator for uninitialized collection");
289                    }
290    
291                    @Override
292                    public void add(T e) {
293                            if (listIterator != null)
294                                    listIterator.add(e);
295                            else
296                                    throw new IllegalStateException("Cannot call add() on iterator for uninitialized collection");
297                    }
298            
299        }
300    
301        @Override
302        public List<T> subList(int fromIndex, int toIndex) {
303            if (checkForRead())
304                return list.subList(fromIndex, toIndex);
305            return null;
306        }
307    
308        @Override
309        public void addListener(InvalidationListener listener) {
310            list.addListener(listener);
311        }
312    
313        @Override
314        public void addListener(ListChangeListener<? super T> listener) {
315            list.addListener(listener);
316        }
317    
318        @Override
319        public void removeListener(InvalidationListener listener) {
320            list.removeListener(listener);
321        }
322    
323        @Override
324        public void removeListener(ListChangeListener<? super T> listener) {
325            list.removeListener(listener);
326        }
327    
328        @Override
329        public LazyableCollection clone(boolean uninitialize) {
330            JavaFXManagedPersistentCollection<T> coll = new JavaFXManagedPersistentCollection<T>(getOwner(), getPropertyName(), ((LazyableCollection)list).clone(uninitialize));
331            coll.setServerSession(getServerSession());
332            return coll;
333        }
334    }