Coverage Report - org.apache.commons.events.observable.ObservableList
 
Classes in this File Line Coverage Branch Coverage Complexity
ObservableList
0%
0/35
0%
0/10
1.429
ObservableList$ObservableListIterator
0%
0/22
0%
0/6
1.429
 
 1  
 /*
 2  
  * Copyright 2003-2004 The Apache Software Foundation
 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 org.apache.commons.events.observable;
 17  
 
 18  
 import java.util.Collection;
 19  
 import java.util.List;
 20  
 import java.util.ListIterator;
 21  
 
 22  
 import org.apache.commons.collections.iterators.AbstractListIteratorDecorator;
 23  
 
 24  
 /**
 25  
  * Decorates a <code>List</code> implementation to observe modifications.
 26  
  * <p>
 27  
  * Each modifying method call made on this <code>List</code> is forwarded to a
 28  
  * {@link ModificationHandler}.
 29  
  * The handler manages the event, notifying listeners and optionally vetoing changes.
 30  
  * The default handler is
 31  
  * {@link org.apache.commons.events.observable.standard.StandardModificationHandler StandardModificationHandler}.
 32  
  * See this class for details of configuration available.
 33  
  * <p>
 34  
  * All indices on events returned by <code>subList</code> are relative to the
 35  
  * base <code>List</code>.
 36  
  *
 37  
  * @since Commons Events 1.0
 38  
  * @version $Revision: 155443 $ $Date: 2005-02-26 13:19:51 +0000 (Sat, 26 Feb 2005) $
 39  
  * 
 40  
  * @author Stephen Colebourne
 41  
  */
 42  
 public class ObservableList extends ObservableCollection implements List {
 43  
 
 44  
     // Factories
 45  
     //-----------------------------------------------------------------------
 46  
     /**
 47  
      * Factory method to create an observable list.
 48  
      * <p>
 49  
      * A {@link org.apache.commons.events.observable.standard.StandardModificationHandler} will be created.
 50  
      * This can be accessed by {@link #getHandler()} to add listeners.
 51  
      *
 52  
      * @param list  the list to decorate, must not be null
 53  
      * @return the observed List
 54  
      * @throws IllegalArgumentException if the list is null
 55  
      */
 56  
     public static ObservableList decorate(final List list) {
 57  0
         return new ObservableList(list, null);
 58  
     }
 59  
 
 60  
     /**
 61  
      * Factory method to create an observable list using a listener or a handler.
 62  
      * <p>
 63  
      * A lot of functionality is available through this method.
 64  
      * If you don't need the extra functionality, simply implement the
 65  
      * {@link org.apache.commons.events.observable.standard.StandardModificationListener}
 66  
      * interface and pass it in as the second parameter.
 67  
      * <p>
 68  
      * Internally, an <code>ObservableList</code> relies on a {@link ModificationHandler}.
 69  
      * The handler receives all the events and processes them, typically by
 70  
      * calling listeners. Different handler implementations can be plugged in
 71  
      * to provide a flexible event system.
 72  
      * <p>
 73  
      * The handler implementation is determined by the listener parameter via
 74  
      * the registered factories. The listener may be a manually configured 
 75  
      * <code>ModificationHandler</code> instance.
 76  
      * <p>
 77  
      * The listener is defined as an Object for maximum flexibility.
 78  
      * It does not have to be a listener in the classic JavaBean sense.
 79  
      * It is entirely up to the factory and handler as to how the parameter
 80  
      * is interpretted. An IllegalArgumentException is thrown if no suitable
 81  
      * handler can be found for this listener.
 82  
      * <p>
 83  
      * A <code>null</code> listener will create a
 84  
      * {@link org.apache.commons.events.observable.standard.StandardModificationHandler}.
 85  
      *
 86  
      * @param list  the list to decorate, must not be null
 87  
      * @param listener  list listener, may be null
 88  
      * @return the observed list
 89  
      * @throws IllegalArgumentException if the list is null
 90  
      * @throws IllegalArgumentException if there is no valid handler for the listener
 91  
      */
 92  
     public static ObservableList decorate(
 93  
             final List list,
 94  
             final Object listener) {
 95  
         
 96  0
         if (list == null) {
 97  0
             throw new IllegalArgumentException("List must not be null");
 98  
         }
 99  0
         return new ObservableList(list, listener);
 100  
     }
 101  
 
 102  
     // Constructors
 103  
     //-----------------------------------------------------------------------
 104  
     /**
 105  
      * Constructor that wraps (not copies) and takes a handler.
 106  
      * <p>
 107  
      * The handler implementation is determined by the listener parameter via
 108  
      * the registered factories. The listener may be a manually configured 
 109  
      * <code>ModificationHandler</code> instance.
 110  
      * 
 111  
      * @param list  the list to decorate, must not be null
 112  
      * @param listener  the listener, may be null
 113  
      * @throws IllegalArgumentException if the list is null
 114  
      */
 115  
     protected ObservableList(
 116  
             final List list,
 117  
             final Object listener) {
 118  0
         super(list, listener);
 119  0
     }
 120  
     
 121  
     /**
 122  
      * Constructor used by subclass views, such as subList.
 123  
      * 
 124  
      * @param handler  the handler to use, must not be null
 125  
      * @param list  the subList to decorate, must not be null
 126  
      * @throws IllegalArgumentException if the list is null
 127  
      */
 128  
     protected ObservableList(
 129  
             final ModificationHandler handler,
 130  
             final List list) {
 131  0
         super(handler, list);
 132  0
     }
 133  
     
 134  
     /**
 135  
      * Typecast the collection to a List.
 136  
      * 
 137  
      * @return the wrapped collection as a List
 138  
      */
 139  
     private List getList() {
 140  0
         return (List) getCollection();
 141  
     }
 142  
 
 143  
     // List API
 144  
     //-----------------------------------------------------------------------
 145  
     public Object get(int index) {
 146  0
         return getList().get(index);
 147  
     }
 148  
 
 149  
     public int indexOf(Object object) {
 150  0
         return getList().indexOf(object);
 151  
     }
 152  
 
 153  
     public int lastIndexOf(Object object) {
 154  0
         return getList().lastIndexOf(object);
 155  
     }
 156  
 
 157  
     //-----------------------------------------------------------------------
 158  
     public void add(int index, Object object) {
 159  0
         if (handler.preAddIndexed(index, object)) {
 160  0
             getList().add(index, object);
 161  0
             handler.postAddIndexed(index, object);
 162  
         }
 163  0
     }
 164  
 
 165  
     public boolean addAll(int index, Collection coll) {
 166  0
         boolean result = false;
 167  0
         if (handler.preAddAllIndexed(index, coll)) {
 168  0
             result = getList().addAll(index, coll);
 169  0
             handler.postAddAllIndexed(index, coll, result);
 170  
         }
 171  0
         return result;
 172  
     }
 173  
 
 174  
     public Object remove(int index) {
 175  0
         Object result = null;
 176  0
         if (handler.preRemoveIndexed(index)) {
 177  0
             result = getList().remove(index);
 178  0
             handler.postRemoveIndexed(index, result);
 179  
         }
 180  0
         return result;
 181  
     }
 182  
 
 183  
     public Object set(int index, Object object) {
 184  0
         Object result = null;
 185  0
         if (handler.preSetIndexed(index, object)) {
 186  0
             result = getList().set(index, object);
 187  0
             handler.postSetIndexed(index, object, result);
 188  
         }
 189  0
         return result;
 190  
     }
 191  
 
 192  
     public ListIterator listIterator() {
 193  0
         return new ObservableListIterator(getList().listIterator());
 194  
     }
 195  
 
 196  
     public ListIterator listIterator(int index) {
 197  0
         return new ObservableListIterator(getList().listIterator(index));
 198  
     }
 199  
 
 200  
     /**
 201  
      * Returns a subList view on the original base <code>List</code>.
 202  
      * <p>
 203  
      * Changes to the subList affect the underlying List. Change events will
 204  
      * return change indices relative to the underlying List, not the subList.
 205  
      * 
 206  
      * @param fromIndex  inclusive start index of the range
 207  
      * @param toIndex  exclusive end index of the range
 208  
      * @return the subList view
 209  
      */
 210  
     public List subList(int fromIndex, int toIndex) {
 211  0
         List subList = getList().subList(fromIndex, toIndex);
 212  0
         return new ObservableList(subList, getHandler().createSubListHandler(fromIndex, toIndex));
 213  
     }
 214  
 
 215  
     // ListIterator
 216  
     //-----------------------------------------------------------------------
 217  
     /**
 218  
      * Inner class ListIterator for the ObservableList.
 219  
      */
 220  
     protected class ObservableListIterator extends AbstractListIteratorDecorator {
 221  
         
 222  
         protected Object last;
 223  
         
 224  0
         protected ObservableListIterator(ListIterator iterator) {
 225  0
             super(iterator);
 226  0
         }
 227  
         
 228  
         public Object next() {
 229  0
             last = super.next();
 230  0
             return last;
 231  
         }
 232  
 
 233  
         public Object previous() {
 234  0
             last = iterator.previous();
 235  0
             return last;
 236  
         }
 237  
 
 238  
         public void remove() {
 239  0
             int index = iterator.previousIndex();
 240  0
             if (handler.preRemoveIterated(index, last)) {
 241  0
                 iterator.remove();
 242  0
                 handler.postRemoveIterated(index, last);
 243  
             }
 244  0
         }
 245  
         
 246  
         public void add(Object object) {
 247  0
             int index = iterator.nextIndex();
 248  0
             if (handler.preAddIterated(index, object)) {
 249  0
                 iterator.add(object);
 250  0
                 handler.postAddIterated(index, object);
 251  
             }
 252  0
         }
 253  
 
 254  
         public void set(Object object) {
 255  0
             int index = iterator.previousIndex();
 256  0
             if (handler.preSetIterated(index, object, last)) {
 257  0
                 iterator.set(object);
 258  0
                 handler.postSetIterated(index, object, last);
 259  
             }
 260  0
         }
 261  
     }
 262  
 
 263  
 }