You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@commons.apache.org by sc...@apache.org on 2003/09/03 02:11:28 UTC

cvs commit: jakarta-commons/collections/src/test/org/apache/commons/collections/decorators ObservedTestHelper.java TestObservedList.java TestObservedCollection.java TestAll.java TestObservedSet.java

scolebourne    2003/09/02 17:11:28

  Modified:    collections/src/java/org/apache/commons/collections/decorators
                        ObservedSet.java ObservedList.java
                        ObservedCollection.java
               collections/src/java/org/apache/commons/collections/event
                        ModificationHandler.java
                        StandardModificationHandler.java
               collections/src/test/org/apache/commons/collections/decorators
                        ObservedTestHelper.java TestObservedList.java
                        TestObservedCollection.java TestAll.java
                        TestObservedSet.java
  Added:       collections/src/java/org/apache/commons/collections/event
                        ModificationHandlerFactory.java
  Log:
  Refactor observed collections to include factory for handlers.
  Simple case of one listener is dealt with neatly at the expense of type safety.
  
  Revision  Changes    Path
  1.4       +35 -98    jakarta-commons/collections/src/java/org/apache/commons/collections/decorators/ObservedSet.java
  
  Index: ObservedSet.java
  ===================================================================
  RCS file: /home/cvs/jakarta-commons/collections/src/java/org/apache/commons/collections/decorators/ObservedSet.java,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- ObservedSet.java	31 Aug 2003 22:44:54 -0000	1.3
  +++ ObservedSet.java	3 Sep 2003 00:11:28 -0000	1.4
  @@ -60,10 +60,7 @@
   import java.util.Set;
   
   import org.apache.commons.collections.event.ModificationHandler;
  -import org.apache.commons.collections.event.StandardModificationHandler;
  -import org.apache.commons.collections.event.StandardModificationListener;
  -import org.apache.commons.collections.event.StandardPostModificationListener;
  -import org.apache.commons.collections.event.StandardPreModificationListener;
  +import org.apache.commons.collections.event.ModificationHandlerFactory;
   
   /**
    * <code>ObservedSet</code> decorates a <code>Set</code>
  @@ -105,112 +102,52 @@
       }
   
       /**
  -     * Factory method to create an observable set and register one
  -     * listener to receive events before the change is made.
  +     * Factory method to create an observable set using a listener or a handler.
        * <p>
  -     * A {@link StandardModificationHandler} will be created.
  -     * The listener will be added to the handler.
  -     *
  -     * @param coll  the set to decorate, must not be null
  -     * @param listener  set listener, must not be null
  -     * @return the observed set
  -     * @throws IllegalArgumentException if the set or listener is null
  -     */
  -    public static ObservedSet decorate(
  -            final Set coll,
  -            final StandardPreModificationListener listener) {
  -        
  -        if (coll == null) {
  -            throw new IllegalArgumentException("Set must not be null");
  -        }
  -        if (listener == null) {
  -            throw new IllegalArgumentException("Listener must not be null");
  -        }
  -        StandardModificationHandler handler = new StandardModificationHandler(
  -            listener, -1, null, 0
  -        );
  -        return new ObservedSet(coll, handler);
  -    }
  -
  -    /**
  -     * Factory method to create an observable set and register one
  -     * listener to receive events after the change is made.
  +     * A lot of functionality is available through this method.
  +     * If you don't need the extra functionality, simply implement the
  +     * {@link org.apache.commons.collections.event.StandardModificationListener}
  +     * interface and pass it in as the second parameter.
        * <p>
  -     * A {@link StandardModificationHandler} will be created.
  -     * The listener will be added to the handler.
  -     *
  -     * @param coll  the set to decorate, must not be null
  -     * @param listener  set listener, must not be null
  -     * @return the observed set
  -     * @throws IllegalArgumentException if the set or listener is null
  -     */
  -    public static ObservedSet decorate(
  -            final Set coll,
  -            final StandardPostModificationListener listener) {
  -        
  -        if (coll == null) {
  -            throw new IllegalArgumentException("Set must not be null");
  -        }
  -        if (listener == null) {
  -            throw new IllegalArgumentException("Listener must not be null");
  -        }
  -        StandardModificationHandler handler = new StandardModificationHandler(
  -            null, 0, listener, -1
  -        );
  -        return new ObservedSet(coll, handler);
  -    }
  -
  -    /**
  -     * Factory method to create an observable set and register one
  -     * listener to receive events both before and after the change is made.
  +     * Internally, an <code>ObservedSet</code> relies on a {@link ModificationHandler}.
  +     * The handler receives all the events and processes them, typically by
  +     * calling listeners. Different handler implementations can be plugged in
  +     * to provide a flexible event system.
        * <p>
  -     * A {@link StandardModificationHandler} will be created.
  -     * The listener will be added to the handler.
  -     *
  -     * @param coll  the set to decorate, must not be null
  -     * @param listener  set listener, must not be null
  -     * @return the observed set
  -     * @throws IllegalArgumentException if the set or listener is null
  -     */
  -    public static ObservedSet decorate(
  -            final Set coll,
  -            final StandardModificationListener listener) {
  -        
  -        if (coll == null) {
  -            throw new IllegalArgumentException("Set must not be null");
  -        }
  -        if (listener == null) {
  -            throw new IllegalArgumentException("Listener must not be null");
  -        }
  -        StandardModificationHandler handler = new StandardModificationHandler(
  -            listener, -1, listener, -1
  -        );
  -        return new ObservedSet(coll, handler);
  -    }
  -
  -    /**
  -     * Factory method to create an observable set using a
  -     * specific handler.
  +     * The handler implementation is determined by the listener parameter.
  +     * If the parameter is a <code>ModificationHandler</code> it is used directly.
  +     * Otherwise, the factory mechanism of {@link ModificationHandlerFactory} is used
  +     * to create the handler for the listener parameter.
  +     * <p>
  +     * The listener is defined as an Object for maximum flexibility.
  +     * It does not have to be a listener in the classic JavaBean sense.
  +     * It is entirely up to the factory and handler as to how the parameter
  +     * is interpretted. An IllegalArgumentException is thrown if no suitable
  +     * handler can be found for this listener.
  +     * <p>
  +     * A <code>null</code> listener will throw an IllegalArgumentException
  +     * unless a special handler factory has been registered.
        * <p>
  -     * The handler may be configured independently with listeners or other
  -     * event recognition.
        *
        * @param set  the set to decorate, must not be null
  -     * @param handler  observed handler, must not be null
  +     * @param listener  set listener, may be null
        * @return the observed set
  -     * @throws IllegalArgumentException if the set or handler is null
  +     * @throws IllegalArgumentException if the set is null
  +     * @throws IllegalArgumentException if there is no valid handler for the listener
        */
       public static ObservedSet decorate(
               final Set set,
  -            final ModificationHandler handler) {
  -                
  +            final Object listener) {
  +        
           if (set == null) {
               throw new IllegalArgumentException("Set must not be null");
           }
  -        if (handler == null) {
  -            throw new IllegalArgumentException("Handler must not be null");
  +        if (listener instanceof ModificationHandler) {
  +            return new ObservedSet(set, (ModificationHandler) listener);
  +        } else {
  +            ModificationHandler handler = ModificationHandlerFactory.createHandler(set, listener);
  +            return new ObservedSet(set, handler);
           }
  -        return new ObservedSet(set, handler);
       }
   
       // Constructors
  
  
  
  1.4       +35 -98    jakarta-commons/collections/src/java/org/apache/commons/collections/decorators/ObservedList.java
  
  Index: ObservedList.java
  ===================================================================
  RCS file: /home/cvs/jakarta-commons/collections/src/java/org/apache/commons/collections/decorators/ObservedList.java,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- ObservedList.java	31 Aug 2003 22:44:54 -0000	1.3
  +++ ObservedList.java	3 Sep 2003 00:11:28 -0000	1.4
  @@ -62,10 +62,7 @@
   import java.util.ListIterator;
   
   import org.apache.commons.collections.event.ModificationHandler;
  -import org.apache.commons.collections.event.StandardModificationHandler;
  -import org.apache.commons.collections.event.StandardModificationListener;
  -import org.apache.commons.collections.event.StandardPostModificationListener;
  -import org.apache.commons.collections.event.StandardPreModificationListener;
  +import org.apache.commons.collections.event.ModificationHandlerFactory;
   
   /**
    * <code>ObservedList</code> decorates a <code>List</code>
  @@ -107,112 +104,52 @@
       }
   
       /**
  -     * Factory method to create an observable list and register one
  -     * listener to receive events before the change is made.
  +     * Factory method to create an observable list using a listener or a handler.
        * <p>
  -     * A {@link StandardModificationHandler} will be created.
  -     * The listener will be added to the handler.
  -     *
  -     * @param coll  the list to decorate, must not be null
  -     * @param listener  list listener, must not be null
  -     * @return the observed list
  -     * @throws IllegalArgumentException if the list or listener is null
  -     */
  -    public static ObservedList decorate(
  -            final List coll,
  -            final StandardPreModificationListener listener) {
  -        
  -        if (coll == null) {
  -            throw new IllegalArgumentException("List must not be null");
  -        }
  -        if (listener == null) {
  -            throw new IllegalArgumentException("Listener must not be null");
  -        }
  -        StandardModificationHandler handler = new StandardModificationHandler(
  -            listener, -1, null, 0
  -        );
  -        return new ObservedList(coll, handler);
  -    }
  -
  -    /**
  -     * Factory method to create an observable list and register one
  -     * listener to receive events after the change is made.
  +     * A lot of functionality is available through this method.
  +     * If you don't need the extra functionality, simply implement the
  +     * {@link org.apache.commons.collections.event.StandardModificationListener}
  +     * interface and pass it in as the second parameter.
        * <p>
  -     * A {@link StandardModificationHandler} will be created.
  -     * The listener will be added to the handler.
  -     *
  -     * @param coll  the list to decorate, must not be null
  -     * @param listener  list listener, must not be null
  -     * @return the observed list
  -     * @throws IllegalArgumentException if the list or listener is null
  -     */
  -    public static ObservedList decorate(
  -            final List coll,
  -            final StandardPostModificationListener listener) {
  -        
  -        if (coll == null) {
  -            throw new IllegalArgumentException("List must not be null");
  -        }
  -        if (listener == null) {
  -            throw new IllegalArgumentException("Listener must not be null");
  -        }
  -        StandardModificationHandler handler = new StandardModificationHandler(
  -            null, 0, listener, -1
  -        );
  -        return new ObservedList(coll, handler);
  -    }
  -
  -    /**
  -     * Factory method to create an observable list and register one
  -     * listener to receive events both before and after the change is made.
  +     * Internally, an <code>ObservedList</code> relies on a {@link ModificationHandler}.
  +     * The handler receives all the events and processes them, typically by
  +     * calling listeners. Different handler implementations can be plugged in
  +     * to provide a flexible event system.
        * <p>
  -     * A {@link StandardModificationHandler} will be created.
  -     * The listener will be added to the handler.
  -     *
  -     * @param coll  the list to decorate, must not be null
  -     * @param listener  list listener, must not be null
  -     * @return the observed list
  -     * @throws IllegalArgumentException if the list or listener is null
  -     */
  -    public static ObservedList decorate(
  -            final List coll,
  -            final StandardModificationListener listener) {
  -        
  -        if (coll == null) {
  -            throw new IllegalArgumentException("List must not be null");
  -        }
  -        if (listener == null) {
  -            throw new IllegalArgumentException("Listener must not be null");
  -        }
  -        StandardModificationHandler handler = new StandardModificationHandler(
  -            listener, -1, listener, -1
  -        );
  -        return new ObservedList(coll, handler);
  -    }
  -
  -    /**
  -     * Factory method to create an observable list using a
  -     * specific handler.
  +     * The handler implementation is determined by the listener parameter.
  +     * If the parameter is a <code>ModificationHandler</code> it is used directly.
  +     * Otherwise, the factory mechanism of {@link ModificationHandlerFactory} is used
  +     * to create the handler for the listener parameter.
  +     * <p>
  +     * The listener is defined as an Object for maximum flexibility.
  +     * It does not have to be a listener in the classic JavaBean sense.
  +     * It is entirely up to the factory and handler as to how the parameter
  +     * is interpretted. An IllegalArgumentException is thrown if no suitable
  +     * handler can be found for this listener.
  +     * <p>
  +     * A <code>null</code> listener will throw an IllegalArgumentException
  +     * unless a special handler factory has been registered.
        * <p>
  -     * The handler may be configured independently with listeners or other
  -     * event recognition.
        *
        * @param list  the list to decorate, must not be null
  -     * @param handler  observed handler, must not be null
  +     * @param listener  list listener, may be null
        * @return the observed list
  -     * @throws IllegalArgumentException if the list or handler is null
  +     * @throws IllegalArgumentException if the list is null
  +     * @throws IllegalArgumentException if there is no valid handler for the listener
        */
       public static ObservedList decorate(
               final List list,
  -            final ModificationHandler handler) {
  -                
  +            final Object listener) {
  +        
           if (list == null) {
               throw new IllegalArgumentException("List must not be null");
           }
  -        if (handler == null) {
  -            throw new IllegalArgumentException("Handler must not be null");
  +        if (listener instanceof ModificationHandler) {
  +            return new ObservedList(list, (ModificationHandler) listener);
  +        } else {
  +            ModificationHandler handler = ModificationHandlerFactory.createHandler(list, listener);
  +            return new ObservedList(list, handler);
           }
  -        return new ObservedList(list, handler);
       }
   
       // Constructors
  
  
  
  1.5       +36 -144   jakarta-commons/collections/src/java/org/apache/commons/collections/decorators/ObservedCollection.java
  
  Index: ObservedCollection.java
  ===================================================================
  RCS file: /home/cvs/jakarta-commons/collections/src/java/org/apache/commons/collections/decorators/ObservedCollection.java,v
  retrieving revision 1.4
  retrieving revision 1.5
  diff -u -r1.4 -r1.5
  --- ObservedCollection.java	31 Aug 2003 22:44:54 -0000	1.4
  +++ ObservedCollection.java	3 Sep 2003 00:11:28 -0000	1.5
  @@ -61,10 +61,8 @@
   import java.util.Iterator;
   
   import org.apache.commons.collections.event.ModificationHandler;
  +import org.apache.commons.collections.event.ModificationHandlerFactory;
   import org.apache.commons.collections.event.StandardModificationHandler;
  -import org.apache.commons.collections.event.StandardModificationListener;
  -import org.apache.commons.collections.event.StandardPostModificationListener;
  -import org.apache.commons.collections.event.StandardPreModificationListener;
   
   /**
    * <code>ObservedCollection</code> decorates a <code>Collection</code>
  @@ -75,12 +73,6 @@
    * The handler manages the event, notifying listeners and optionally vetoing changes.
    * The default handler is {@link StandardModificationHandler}.
    * See this class for details of configuration available.
  - * <p>
  - * For convenience, add, remove and get listener methods are made available on
  - * this class. They accept a generic listener type, whereas handlers generally
  - * require a specific type. Thus a ClassCastException may be thrown from these
  - * methods. They may also throw UnsupportedOperationException if the handler
  - * uses a technique other than listeners to communicate events.
    *
    * @since Commons Collections 3.0
    * @version $Revision$ $Date$
  @@ -109,112 +101,52 @@
       }
   
       /**
  -     * Factory method to create an observable collection and register one
  -     * listener to receive events before the change is made.
  +     * Factory method to create an observable collection using a listener or a handler.
        * <p>
  -     * A {@link StandardModificationHandler} will be created.
  -     * The listener will be added to the handler.
  -     *
  -     * @param coll  the collection to decorate, must not be null
  -     * @param listener  collection listener, must not be null
  -     * @return the observed collection
  -     * @throws IllegalArgumentException if the collection or listener is null
  -     */
  -    public static ObservedCollection decorate(
  -            final Collection coll,
  -            final StandardPreModificationListener listener) {
  -        
  -        if (coll == null) {
  -            throw new IllegalArgumentException("Collection must not be null");
  -        }
  -        if (listener == null) {
  -            throw new IllegalArgumentException("Listener must not be null");
  -        }
  -        StandardModificationHandler handler = new StandardModificationHandler(
  -            listener, -1, null, 0
  -        );
  -        return new ObservedCollection(coll, handler);
  -    }
  -
  -    /**
  -     * Factory method to create an observable collection and register one
  -     * listener to receive events after the change is made.
  +     * A lot of functionality is available through this method.
  +     * If you don't need the extra functionality, simply implement the
  +     * {@link org.apache.commons.collections.event.StandardModificationListener}
  +     * interface and pass it in as the second parameter.
  +     * <p>
  +     * Internally, an <code>ObservedCollection</code> relies on a {@link ModificationHandler}.
  +     * The handler receives all the events and processes them, typically by
  +     * calling listeners. Different handler implementations can be plugged in
  +     * to provide a flexible event system.
  +     * <p>
  +     * The handler implementation is determined by the listener parameter.
  +     * If the parameter is a <code>ModificationHandler</code> it is used directly.
  +     * Otherwise, the factory mechanism of {@link ModificationHandlerFactory} is used
  +     * to create the handler for the listener parameter.
  +     * <p>
  +     * The listener is defined as an Object for maximum flexibility.
  +     * It does not have to be a listener in the classic JavaBean sense.
  +     * It is entirely up to the factory and handler as to how the parameter
  +     * is interpretted. An IllegalArgumentException is thrown if no suitable
  +     * handler can be found for this listener.
        * <p>
  -     * A {@link StandardModificationHandler} will be created.
  -     * The listener will be added to the handler.
  -     *
  -     * @param coll  the collection to decorate, must not be null
  -     * @param listener  collection listener, must not be null
  -     * @return the observed collection
  -     * @throws IllegalArgumentException if the collection or listener is null
  -     */
  -    public static ObservedCollection decorate(
  -            final Collection coll,
  -            final StandardPostModificationListener listener) {
  -        
  -        if (coll == null) {
  -            throw new IllegalArgumentException("Collection must not be null");
  -        }
  -        if (listener == null) {
  -            throw new IllegalArgumentException("Listener must not be null");
  -        }
  -        StandardModificationHandler handler = new StandardModificationHandler(
  -            null, 0, listener, -1
  -        );
  -        return new ObservedCollection(coll, handler);
  -    }
  -
  -    /**
  -     * Factory method to create an observable collection and register one
  -     * listener to receive events both before and after the change is made.
  +     * A <code>null</code> listener will throw an IllegalArgumentException
  +     * unless a special handler factory has been registered.
        * <p>
  -     * A {@link StandardModificationHandler} will be created.
  -     * The listener will be added to the handler.
        *
        * @param coll  the collection to decorate, must not be null
  -     * @param listener  collection listener, must not be null
  +     * @param listener  collection listener, may be null
        * @return the observed collection
  -     * @throws IllegalArgumentException if the collection or listener is null
  +     * @throws IllegalArgumentException if the collection is null
  +     * @throws IllegalArgumentException if there is no valid handler for the listener
        */
       public static ObservedCollection decorate(
               final Collection coll,
  -            final StandardModificationListener listener) {
  +            final Object listener) {
           
           if (coll == null) {
               throw new IllegalArgumentException("Collection must not be null");
           }
  -        if (listener == null) {
  -            throw new IllegalArgumentException("Listener must not be null");
  +        if (listener instanceof ModificationHandler) {
  +            return new ObservedCollection(coll, (ModificationHandler) listener);
  +        } else {
  +            ModificationHandler handler = ModificationHandlerFactory.createHandler(coll, listener);
  +            return new ObservedCollection(coll, handler);
           }
  -        StandardModificationHandler handler = new StandardModificationHandler(
  -            listener, -1, listener, -1
  -        );
  -        return new ObservedCollection(coll, handler);
  -    }
  -
  -    /**
  -     * Factory method to create an observable collection using a
  -     * specific handler.
  -     * <p>
  -     * The handler may be configured independently with listeners or other
  -     * event recognition.
  -     *
  -     * @param coll  the collection to decorate, must not be null
  -     * @param handler  observed handler, must not be null
  -     * @return the observed collection
  -     * @throws IllegalArgumentException if the collection or handler is null
  -     */
  -    public static ObservedCollection decorate(
  -            final Collection coll,
  -            final ModificationHandler handler) {
  -                
  -        if (coll == null) {
  -            throw new IllegalArgumentException("Collection must not be null");
  -        }
  -        if (handler == null) {
  -            throw new IllegalArgumentException("Handler must not be null");
  -        }
  -        return new ObservedCollection(coll, handler);
       }
   
       // Constructors
  @@ -234,7 +166,7 @@
               final ModificationHandler handler) {
           super(coll);
           this.handler = (handler == null ? new StandardModificationHandler() : handler);
  -        this.handler.init(this);
  +        ModificationHandlerFactory.initHandler(this.handler, this);
       }
   
       // Handler access
  @@ -246,46 +178,6 @@
        */
       public ModificationHandler getHandler() {
           return handler;
  -    }
  -    
  -    // Listener convenience methods
  -    //----------------------------------------------------------------------
  -    /**
  -     * Adds a listener to the handler to receive pre modification events.
  -     * This method simply delegates to the handler.
  -     * <p>
  -     * No error occurs if the listener is <code>null</code>.
  -     * <p>
  -     * The listener does not necessarily have to be a listener in the classic
  -     * JavaBean sense. It is entirely up to the handler as to how it interprets
  -     * the listener parameter. A ClassCastException is thrown if the handler
  -     * cannot interpret the parameter.
  -     * 
  -     * @param listener  the listener to add, may be null (ignored)
  -     * @throws ClassCastException if the listener is not of the correct type
  -     * @throws UnsupportedOperationException if the handler does not support listeners
  -     */
  -    public void addPreModificationListener(Object listener) {
  -        getHandler().addPreModificationListener(listener);
  -    }
  -    
  -    /**
  -     * Adds a listener to the handler to receive post modification events.
  -     * This method simply delegates to the handler.
  -     * <p>
  -     * No error occurs if the listener is <code>null</code>.
  -     * <p>
  -     * The listener does not necessarily have to be a listener in the classic
  -     * JavaBean sense. It is entirely up to the handler as to how it interprets
  -     * the listener parameter. A ClassCastException is thrown if the handler
  -     * cannot interpret the parameter.
  -     * 
  -     * @param listener  the listener to add, may be null (ignored)
  -     * @throws ClassCastException if the listener is not of the correct type
  -     * @throws UnsupportedOperationException if the handler does not support listeners
  -     */
  -    public void addPostModificationListener(Object listener) {
  -        getHandler().addPostModificationListener(listener);
       }
       
       // Collection
  
  
  
  1.5       +10 -7     jakarta-commons/collections/src/java/org/apache/commons/collections/event/ModificationHandler.java
  
  Index: ModificationHandler.java
  ===================================================================
  RCS file: /home/cvs/jakarta-commons/collections/src/java/org/apache/commons/collections/event/ModificationHandler.java,v
  retrieving revision 1.4
  retrieving revision 1.5
  diff -u -r1.4 -r1.5
  --- ModificationHandler.java	31 Aug 2003 22:44:54 -0000	1.4
  +++ ModificationHandler.java	3 Sep 2003 00:11:28 -0000	1.5
  @@ -62,11 +62,14 @@
   import org.apache.commons.collections.decorators.ObservedCollection;
   
   /**
  - * Abstract base implementation of a handler for collection modification.
  + * Defines a handler for collection modification events.
    * <p>
  - * All data storage and event sending is performed by a subclass.
  - * This class provides a default implementation for the event handling methods
  - * that forwards to single points.
  + * This class defines the event handling methods, following the 
  + * <code>preXxx</code> and <code>postXxx</code> naming convention.
  + * It also provides a default implementation that forwards to single methods.
  + * <p>
  + * This class could have been implemented as an interface, however to do so
  + * would prevent the addition of extra events in the future.
    *
    * @since Commons Collections 3.0
    * @version $Revision$ $Date$
  @@ -98,7 +101,7 @@
        * @throws IllegalArgumentException if the collection is null
        * @throws IllegalStateException if init has already been called
        */
  -    public void init(final ObservedCollection coll) {
  +    void init(final ObservedCollection coll) {
           if (coll == null) {
               throw new IllegalArgumentException("Collection must not be null");
           }
  
  
  
  1.5       +44 -2     jakarta-commons/collections/src/java/org/apache/commons/collections/event/StandardModificationHandler.java
  
  Index: StandardModificationHandler.java
  ===================================================================
  RCS file: /home/cvs/jakarta-commons/collections/src/java/org/apache/commons/collections/event/StandardModificationHandler.java,v
  retrieving revision 1.4
  retrieving revision 1.5
  diff -u -r1.4 -r1.5
  --- StandardModificationHandler.java	31 Aug 2003 22:44:54 -0000	1.4
  +++ StandardModificationHandler.java	3 Sep 2003 00:11:28 -0000	1.5
  @@ -57,6 +57,8 @@
    */
   package org.apache.commons.collections.event;
   
  +import java.util.Collection;
  +
   /**
    * The standard implementation of a <code>ModificationHandler</code> that
    * sends standard JavaBean style events to listeners.
  @@ -75,6 +77,10 @@
    * @author Stephen Colebourne
    */
   public class StandardModificationHandler extends ModificationHandler {
  +    
  +    static {
  +        ModificationHandlerFactory.addFactory(new Factory());
  +    }
   
       /** A reusable empty holders array. */    
       protected static final PreHolder[] EMPTY_PRE_HOLDERS = new PreHolder[0];
  @@ -524,4 +530,40 @@
           postEvent(preSize > 0, ModificationEventType.CLEAR, -1, null, 1, null);
       }
   
  +    // Factory
  +    //-----------------------------------------------------------------------
  +    /**
  +     * Factory implementation for the StandardModificationHandler.
  +     * 
  +     * @author Stephen Colebourne
  +     */
  +    static class Factory extends ModificationHandlerFactory {
  +        
  +        /**
  +         * Creates a StandardModificationHandler using the listener.
  +         * 
  +         * @param coll  the collection being decorated
  +         * @param listener  a listener object to create a handler for
  +         * @return an instantiated handler with the listener attached,
  +         *  or null if the listener type is unsuited to this factory
  +         */
  +        protected ModificationHandler create(Collection coll, Object listener) {
  +            if (listener instanceof StandardPreModificationListener) {
  +                if (listener instanceof StandardPostModificationListener) {
  +                    return new StandardModificationHandler(
  +                        (StandardPreModificationListener) listener, -1,
  +                        (StandardPostModificationListener) listener, -1);
  +                } else {
  +                    return new StandardModificationHandler(
  +                        (StandardPreModificationListener) listener, -1, null, 0);
  +                }
  +            }
  +            if (listener instanceof StandardPostModificationListener) {
  +                return new StandardModificationHandler(
  +                    null, 0, (StandardPostModificationListener) listener, -1);
  +            }
  +            return null;
  +        }
  +    }
  +    
   }
  
  
  
  1.1                  jakarta-commons/collections/src/java/org/apache/commons/collections/event/ModificationHandlerFactory.java
  
  Index: ModificationHandlerFactory.java
  ===================================================================
  /*
   * $Header: /home/cvs/jakarta-commons/collections/src/java/org/apache/commons/collections/event/ModificationHandlerFactory.java,v 1.1 2003/09/03 00:11:28 scolebourne Exp $
   * ====================================================================
   *
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 2003 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution, if
   *    any, must include the following acknowledgement:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowledgement may appear in the software itself,
   *    if and wherever such third-party acknowledgements normally appear.
   *
   * 4. The names "The Jakarta Project", "Commons", and "Apache Software
   *    Foundation" must not be used to endorse or promote products derived
   *    from this software without prior written permission. For written
   *    permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache"
   *    nor may "Apache" appear in their names without prior written
   *    permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   *
   */
  package org.apache.commons.collections.event;
  
  import java.util.Collection;
  
  import org.apache.commons.collections.decorators.ObservedCollection;
  
  /**
   * Defines a factory for creating ModificationHandler instances and utilities
   * for using the factories.
   * <p>
   * If an application wants to register its own event handler classes, it should
   * do so using this class. This must be done during initialization to be 
   * fully thread-safe. There are two steps:
   * <ol>
   * <li>A factory must be created that is a subclass of this class
   * <li>One of the <code>addFactory</code> methods must be called
   * </ol>
   *
   * @since Commons Collections 3.0
   * @version $Revision: 1.1 $ $Date: 2003/09/03 00:11:28 $
   * 
   * @author Stephen Colebourne
   */
  public abstract class ModificationHandlerFactory {
      
      /** The list of factories, cannot pre-populate as factories are subclasses */
      private static ModificationHandlerFactory[] factories = new ModificationHandlerFactory[0];
      
      // Static access to factories
      //-----------------------------------------------------------------------
      /**
       * Creates a handler subclass based on the specified listener.
       * <p>
       * The method is defined in terms of an Object to allow for unusual
       * listeners, such as a Swing model object.
       * 
       * @param listener  a listener object to create a handler for
       * @return an instantiated handler with the listener attached
       * @throws IllegalArgumentException if no suitable handler
       */
      public static final ModificationHandler createHandler(final Collection coll, final Object listener) {
          for (int i = 0; i < factories.length; i++) {
              ModificationHandler handler = factories[i].create(coll, listener);
              if (handler != null) {
                  return handler;
              }
          }
          throw new IllegalArgumentException("Unrecognised listener type: " +
              (listener == null ? "null" : listener.getClass().getName()));
      }
  
      /**
       * Adds a handler factory to the list available for use.
       * This factory will be checked after the others in the list.
       * <p>
       * This method is used to add your own event handler to the supplied ones.
       * Registering the factory will enable the standard <code>decorate</code>
       * method on <code>ObservedColection</code> to create your handler.
       * <p>
       * This method is NOT threadsafe! It should only be called during initialization.
       * 
       * @param factory  the factory to add, may be null
       */
      public static void addFactory(final ModificationHandlerFactory factory) {
          addFactory(factory, false);
      }
  
      /**
       * Adds a handler factory to the list available for use selecting whether
       * to override existing factories or not.
       * <p>
       * This method is used to add your own event handler to the supplied ones.
       * Registering the factory will enable the standard <code>decorate</code>
       * method on <code>ObservedColection</code> to create your handler.
       * <p>
       * It is also possible to replace the Jakarta handlers using this method.
       * Obviously this should be done with care in a shared web environment!
       * <p>
       * This method is NOT threadsafe! It should only be called during initialization.
       * 
       * @param factory  the factory to add, may be null
       */
      public static void addFactory(final ModificationHandlerFactory factory, final boolean override) {
          if (factory != null) {
              ModificationHandlerFactory[] array = new ModificationHandlerFactory[factories.length + 1];
              if (override) {
                  System.arraycopy(factories, 0, array, 1, factories.length);
                  array[0] = factory;
              } else {
                  System.arraycopy(factories, 0, array, 0, factories.length);
                  array[factories.length] = factory;
              }
              factories = array;
          }
      }
  
      // Initialize the collection-handler pair
      //-----------------------------------------------------------------------
      /**
       * Initializes handler specified with the collection.
       * <p>
       * The method avoids exposing an implementation detail on ModificationHandler.
       * 
       * @param handler  the handler to initialize
       * @param coll  the collection to store
       * @return an instantiated handler with the listener attached
       */
      public static void initHandler(final ModificationHandler handler, final ObservedCollection coll) {
          handler.init(coll);
      }
      
      // Constructor
      //-----------------------------------------------------------------------
      /**
       * Restrictive constructor.
       */
      protected ModificationHandlerFactory() {
          super();
      }
  
      // Abstract factory
      //-----------------------------------------------------------------------
      /**
       * Creates a handler subclass for the specified listener.
       * <p>
       * The implementation will normally check to see if the listener
       * is of a suitable type, and then cast it. <code>null</code> is
       * returned if this factory does not handle the specified type.
       * <p>
       * The listener is defined in terms of an Object to allow for unusual
       * listeners, such as a Swing model object.
       * <p>
       * The collection the handler is for is passed in to allow for a different
       * handler to be selected for the same listener type based on the collection.
       * 
       * @param coll  the collection being decorated
       * @param listener  a listener object to create a handler for
       * @return an instantiated handler with the listener attached,
       *  or null if the listener type is unsuited to this factory
       */
      protected abstract ModificationHandler create(Collection coll, Object listener);
      
  }
  
  
  
  1.5       +124 -19   jakarta-commons/collections/src/test/org/apache/commons/collections/decorators/ObservedTestHelper.java
  
  Index: ObservedTestHelper.java
  ===================================================================
  RCS file: /home/cvs/jakarta-commons/collections/src/test/org/apache/commons/collections/decorators/ObservedTestHelper.java,v
  retrieving revision 1.4
  retrieving revision 1.5
  diff -u -r1.4 -r1.5
  --- ObservedTestHelper.java	31 Aug 2003 22:44:54 -0000	1.4
  +++ ObservedTestHelper.java	3 Sep 2003 00:11:28 -0000	1.5
  @@ -119,6 +119,11 @@
           }
       }
       
  +    public static interface ObservedFactory {
  +        ObservedCollection createObservedCollection();
  +        ObservedCollection createObservedCollection(Object listener);
  +    }
  +    
       public static final Listener LISTENER = new Listener();
       public static final Listener LISTENER2 = new Listener();
       public static final PreListener PRE_LISTENER = new PreListener();
  @@ -129,13 +134,60 @@
       }
   
       //-----------------------------------------------------------------------
  -    public static void doTestFactoryPlain(ObservedCollection coll) {
  +    public static void bulkTestObservedCollection(ObservedFactory factory) {
  +        doTestFactoryPlain(factory);
  +        doTestFactoryWithListener(factory);
  +        doTestFactoryWithPreListener(factory);
  +        doTestFactoryWithPostListener(factory);
  +        doTestFactoryWithHandler(factory);
  +        doTestFactoryWithObject(factory);
  +        doTestFactoryWithNull(factory);
  +        
  +        doTestAddRemoveGetPreListeners(factory);
  +        doTestAddRemoveGetPostListeners(factory);
  +        
  +        doTestAdd(factory);
  +        doTestAddAll(factory);
  +        doTestClear(factory);
  +        doTestRemove(factory);
  +        doTestRemoveAll(factory);
  +        doTestRetainAll(factory);
  +        doTestIteratorRemove(factory);
  +    }
  +    
  +    public static void bulkTestObservedSet(ObservedFactory factory) {
  +        Assert.assertTrue(factory.createObservedCollection() instanceof ObservedSet);
  +        Assert.assertTrue(factory.createObservedCollection(LISTENER) instanceof ObservedSet);
  +        Assert.assertTrue(factory.createObservedCollection(new StandardModificationHandler()) instanceof ObservedSet);
  +        
  +        bulkTestObservedCollection(factory);
  +    }
  +    
  +    public static void bulkTestObservedList(ObservedFactory factory) {
  +        Assert.assertTrue(factory.createObservedCollection() instanceof ObservedList);
  +        Assert.assertTrue(factory.createObservedCollection(LISTENER) instanceof ObservedList);
  +        Assert.assertTrue(factory.createObservedCollection(new StandardModificationHandler()) instanceof ObservedList);
  +        
  +        bulkTestObservedCollection(factory);
  +        doTestAddIndexed(factory);
  +        doTestAddAllIndexed(factory);
  +        doTestRemoveIndexed(factory);
  +        doTestSetIndexed(factory);
  +        // ITERATOR add/set
  +    }
  +    
  +    //-----------------------------------------------------------------------
  +    public static void doTestFactoryPlain(ObservedFactory factory) {
  +        ObservedCollection coll = factory.createObservedCollection();
  +        
           Assert.assertEquals(StandardModificationHandler.class, coll.getHandler().getClass());
           Assert.assertEquals(0, coll.getHandler().getPreModificationListeners().length);
           Assert.assertEquals(0, coll.getHandler().getPostModificationListeners().length);
       }
       
  -    public static void doTestFactoryWithPreListener(ObservedCollection coll) {
  +    public static void doTestFactoryWithPreListener(ObservedFactory factory) {
  +        ObservedCollection coll = factory.createObservedCollection(PRE_LISTENER);
  +        
           Assert.assertEquals(StandardModificationHandler.class, coll.getHandler().getClass());
           Assert.assertEquals(1, coll.getHandler().getPreModificationListeners().length);
           Assert.assertEquals(0, coll.getHandler().getPostModificationListeners().length);
  @@ -146,7 +198,9 @@
           Assert.assertTrue(PRE_LISTENER.preEvent != null);
       }
       
  -    public static void doTestFactoryWithPostListener(ObservedCollection coll) {
  +    public static void doTestFactoryWithPostListener(ObservedFactory factory) {
  +        ObservedCollection coll = factory.createObservedCollection(POST_LISTENER);
  +        
           Assert.assertEquals(StandardModificationHandler.class, coll.getHandler().getClass());
           Assert.assertEquals(0, coll.getHandler().getPreModificationListeners().length);
           Assert.assertEquals(1, coll.getHandler().getPostModificationListeners().length);
  @@ -157,7 +211,9 @@
           Assert.assertTrue(POST_LISTENER.postEvent != null);
       }
       
  -    public static void doTestFactoryWithListener(ObservedCollection coll) {
  +    public static void doTestFactoryWithListener(ObservedFactory factory) {
  +        ObservedCollection coll = factory.createObservedCollection(LISTENER);
  +        
           Assert.assertEquals(StandardModificationHandler.class, coll.getHandler().getClass());
           Assert.assertEquals(1, coll.getHandler().getPreModificationListeners().length);
           Assert.assertEquals(1, coll.getHandler().getPostModificationListeners().length);
  @@ -171,8 +227,33 @@
           Assert.assertTrue(LISTENER.postEvent != null);
       }
       
  +    public static void doTestFactoryWithHandler(ObservedFactory factory) {
  +        StandardModificationHandler handler = new StandardModificationHandler();
  +        ObservedCollection coll = factory.createObservedCollection(handler);
  +        
  +        Assert.assertSame(handler, coll.getHandler());
  +        Assert.assertEquals(0, coll.getHandler().getPreModificationListeners().length);
  +        Assert.assertEquals(0, coll.getHandler().getPostModificationListeners().length);
  +    }
  +    
  +    public static void doTestFactoryWithObject(ObservedFactory factory) {
  +        try {
  +            factory.createObservedCollection(new Object());
  +            Assert.fail();
  +        } catch (IllegalArgumentException ex) {}
  +    }
  +    
  +    public static void doTestFactoryWithNull(ObservedFactory factory) {
  +        try {
  +            factory.createObservedCollection(null);
  +            Assert.fail();
  +        } catch (IllegalArgumentException ex) {}
  +    }
  +    
       //-----------------------------------------------------------------------
  -    public static void doTestAddRemoveGetPreListeners(ObservedCollection coll) {
  +    public static void doTestAddRemoveGetPreListeners(ObservedFactory factory) {
  +        ObservedCollection coll = factory.createObservedCollection();
  +        
           Assert.assertEquals(0, coll.getHandler().getPreModificationListeners().length);
           coll.getHandler().addPreModificationListener(LISTENER);
           Assert.assertEquals(1, coll.getHandler().getPreModificationListeners().length);
  @@ -201,7 +282,9 @@
           }
       }
       
  -    public static void doTestAddRemoveGetPostListeners(ObservedCollection coll) {
  +    public static void doTestAddRemoveGetPostListeners(ObservedFactory factory) {
  +        ObservedCollection coll = factory.createObservedCollection();
  +        
           Assert.assertEquals(0, coll.getHandler().getPostModificationListeners().length);
           coll.getHandler().addPostModificationListener(LISTENER);
           Assert.assertEquals(1, coll.getHandler().getPostModificationListeners().length);
  @@ -231,7 +314,9 @@
       }
       
       //-----------------------------------------------------------------------
  -    public static void doTestAdd(ObservedCollection coll) {
  +    public static void doTestAdd(ObservedFactory factory) {
  +        ObservedCollection coll = factory.createObservedCollection(LISTENER);
  +        
           LISTENER.preEvent = null;
           LISTENER.postEvent = null;
           Assert.assertEquals(0, coll.size());
  @@ -336,7 +421,9 @@
       }
   
       //-----------------------------------------------------------------------
  -    public static void doTestAddIndexed(ObservedList coll) {
  +    public static void doTestAddIndexed(ObservedFactory factory) {
  +        ObservedList coll = (ObservedList) factory.createObservedCollection(LISTENER);
  +        
           coll.addAll(SIX_SEVEN_LIST);
           LISTENER.preEvent = null;
           LISTENER.postEvent = null;
  @@ -374,7 +461,9 @@
       }
   
       //-----------------------------------------------------------------------
  -    public static void doTestAddAll(ObservedCollection coll) {
  +    public static void doTestAddAll(ObservedFactory factory) {
  +        ObservedCollection coll = factory.createObservedCollection(LISTENER);
  +        
           LISTENER.preEvent = null;
           LISTENER.postEvent = null;
           Assert.assertEquals(0, coll.size());
  @@ -409,7 +498,9 @@
       }
   
       //-----------------------------------------------------------------------
  -    public static void doTestAddAllIndexed(ObservedList coll) {
  +    public static void doTestAddAllIndexed(ObservedFactory factory) {
  +        ObservedList coll = (ObservedList) factory.createObservedCollection(LISTENER);
  +        
           coll.addAll(SIX_SEVEN_LIST);
           LISTENER.preEvent = null;
           LISTENER.postEvent = null;
  @@ -445,7 +536,9 @@
       }
   
       //-----------------------------------------------------------------------
  -    public static void doTestClear(ObservedCollection coll) {
  +    public static void doTestClear(ObservedFactory factory) {
  +        ObservedCollection coll = factory.createObservedCollection(LISTENER);
  +        
           coll.addAll(SIX_SEVEN_LIST);
           LISTENER.preEvent = null;
           LISTENER.postEvent = null;
  @@ -489,7 +582,9 @@
       }
   
       //-----------------------------------------------------------------------
  -    public static void doTestRemove(ObservedCollection coll) {
  +    public static void doTestRemove(ObservedFactory factory) {
  +        ObservedCollection coll = factory.createObservedCollection(LISTENER);
  +        
           coll.addAll(SIX_SEVEN_LIST);
           LISTENER.preEvent = null;
           LISTENER.postEvent = null;
  @@ -535,7 +630,9 @@
       }
   
       //-----------------------------------------------------------------------
  -    public static void doTestRemoveIndexed(ObservedList coll) {
  +    public static void doTestRemoveIndexed(ObservedFactory factory) {
  +        ObservedList coll = (ObservedList) factory.createObservedCollection(LISTENER);
  +        
           coll.addAll(SIX_SEVEN_LIST);
           LISTENER.preEvent = null;
           LISTENER.postEvent = null;
  @@ -571,7 +668,9 @@
       }
   
       //-----------------------------------------------------------------------
  -    public static void doTestRemoveAll(ObservedCollection coll) {
  +    public static void doTestRemoveAll(ObservedFactory factory) {
  +        ObservedCollection coll = factory.createObservedCollection(LISTENER);
  +        
           coll.add(EIGHT);
           coll.addAll(SIX_SEVEN_LIST);
           LISTENER.preEvent = null;
  @@ -616,7 +715,9 @@
       }
   
       //-----------------------------------------------------------------------
  -    public static void doTestRetainAll(ObservedCollection coll) {
  +    public static void doTestRetainAll(ObservedFactory factory) {
  +        ObservedCollection coll = factory.createObservedCollection(LISTENER);
  +        
           coll.add(EIGHT);
           coll.addAll(SIX_SEVEN_LIST);
           LISTENER.preEvent = null;
  @@ -661,7 +762,9 @@
       }
   
       //-----------------------------------------------------------------------
  -    public static void doTestIteratorRemove(ObservedCollection coll) {
  +    public static void doTestIteratorRemove(ObservedFactory factory) {
  +        ObservedCollection coll = factory.createObservedCollection(LISTENER);
  +        
           coll.addAll(SIX_SEVEN_LIST);
           LISTENER.preEvent = null;
           LISTENER.postEvent = null;
  @@ -710,7 +813,9 @@
       }
   
       //-----------------------------------------------------------------------
  -    public static void doTestSetIndexed(ObservedList coll) {
  +    public static void doTestSetIndexed(ObservedFactory factory) {
  +        ObservedList coll = (ObservedList) factory.createObservedCollection(LISTENER);
  +        
           coll.addAll(SIX_SEVEN_LIST);
           LISTENER.preEvent = null;
           LISTENER.postEvent = null;
  
  
  
  1.4       +16 -111   jakarta-commons/collections/src/test/org/apache/commons/collections/decorators/TestObservedList.java
  
  Index: TestObservedList.java
  ===================================================================
  RCS file: /home/cvs/jakarta-commons/collections/src/test/org/apache/commons/collections/decorators/TestObservedList.java,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- TestObservedList.java	31 Aug 2003 22:44:54 -0000	1.3
  +++ TestObservedList.java	3 Sep 2003 00:11:28 -0000	1.4
  @@ -65,7 +65,6 @@
   import junit.framework.TestSuite;
   
   import org.apache.commons.collections.TestList;
  -import org.apache.commons.collections.event.StandardModificationHandler;
   
   /**
    * Extension of {@link TestList} for exercising the
  @@ -76,14 +75,7 @@
    * 
    * @author Stephen Colebourne
    */
  -public class TestObservedList extends TestList {
  -    
  -    private static Integer SIX = new Integer(6);
  -    private static Integer SEVEN = new Integer(7);
  -    private static Integer EIGHT = new Integer(8);
  -    private static final ObservedTestHelper.Listener LISTENER = ObservedTestHelper.LISTENER;
  -    private static final ObservedTestHelper.PreListener PRE_LISTENER = ObservedTestHelper.PRE_LISTENER;
  -    private static final ObservedTestHelper.PostListener POST_LISTENER = ObservedTestHelper.POST_LISTENER;
  +public class TestObservedList extends TestList implements ObservedTestHelper.ObservedFactory {
       
       public TestObservedList(String testName) {
           super(testName);
  @@ -100,114 +92,27 @@
   
       //-----------------------------------------------------------------------
       public List makeEmptyList() {
  -        return ObservedList.decorate(new ArrayList(), LISTENER);
  +        return ObservedList.decorate(new ArrayList(), ObservedTestHelper.LISTENER);
       }
   
       protected List makeFullList() {
           List set = new ArrayList();
           set.addAll(Arrays.asList(getFullElements()));
  -        return ObservedList.decorate(set, LISTENER);
  +        return ObservedList.decorate(set, ObservedTestHelper.LISTENER);
       }
       
       //-----------------------------------------------------------------------
       public void testObservedList() {
  -        ObservedList coll = ObservedList.decorate(new ArrayList());
  -        ObservedTestHelper.doTestFactoryPlain(coll);
  -        
  -        coll = ObservedList.decorate(new ArrayList(), LISTENER);
  -        ObservedTestHelper.doTestFactoryWithListener(coll);
  -        
  -        coll = ObservedList.decorate(new ArrayList(), PRE_LISTENER);
  -        ObservedTestHelper.doTestFactoryWithPreListener(coll);
  -        
  -        coll = ObservedList.decorate(new ArrayList(), POST_LISTENER);
  -        ObservedTestHelper.doTestFactoryWithPostListener(coll);
  -        
  -        coll = ObservedList.decorate(new ArrayList());
  -        ObservedTestHelper.doTestAddRemoveGetPreListeners(coll);
  -        
  -        coll = ObservedList.decorate(new ArrayList());
  -        ObservedTestHelper.doTestAddRemoveGetPostListeners(coll);
  -        
  -        coll = ObservedList.decorate(new ArrayList(), LISTENER);
  -        ObservedTestHelper.doTestAdd(coll);
  -        
  -        coll = ObservedList.decorate(new ArrayList(), LISTENER);
  -        ObservedTestHelper.doTestAddIndexed(coll);
  -        
  -        coll = ObservedList.decorate(new ArrayList(), LISTENER);
  -        ObservedTestHelper.doTestAddAll(coll);
  -        
  -        coll = ObservedList.decorate(new ArrayList(), LISTENER);
  -        ObservedTestHelper.doTestAddAllIndexed(coll);
  -        
  -        coll = ObservedList.decorate(new ArrayList(), LISTENER);
  -        ObservedTestHelper.doTestClear(coll);
  -        
  -        coll = ObservedList.decorate(new ArrayList(), LISTENER);
  -        ObservedTestHelper.doTestRemove(coll);
  -        
  -        coll = ObservedList.decorate(new ArrayList(), LISTENER);
  -        ObservedTestHelper.doTestRemoveIndexed(coll);
  -        
  -        coll = ObservedList.decorate(new ArrayList(), LISTENER);
  -        ObservedTestHelper.doTestRemoveAll(coll);
  -        
  -        coll = ObservedList.decorate(new ArrayList(), LISTENER);
  -        ObservedTestHelper.doTestRetainAll(coll);
  -        
  -        coll = ObservedList.decorate(new ArrayList(), LISTENER);
  -        ObservedTestHelper.doTestIteratorRemove(coll);
  -        
  -        coll = ObservedList.decorate(new ArrayList(), LISTENER);
  -        ObservedTestHelper.doTestSetIndexed(coll);
  -    }
  -
  -    //-----------------------------------------------------------------------    
  -    public void testFactoryWithHandler() {
  -        StandardModificationHandler handler = new StandardModificationHandler();
  -        ObservedList coll = ObservedList.decorate(new ArrayList(), handler);
  -        
  -        assertSame(handler, coll.getHandler());
  -        assertEquals(0, coll.getHandler().getPreModificationListeners().length);
  -        assertEquals(0, coll.getHandler().getPostModificationListeners().length);
  +        ObservedTestHelper.bulkTestObservedList(this);
       }
  -    
  -//    public void testFactoryWithMasks() {
  -//        ObservedList coll = ObservedList.decorate(new ArrayList(), LISTENER, -1, 0);
  -//        LISTENER.preEvent = null;
  -//        LISTENER.postEvent = null;
  -//        coll.add(SIX);
  -//        assertTrue(LISTENER.preEvent != null);
  -//        assertTrue(LISTENER.postEvent == null);
  -//        
  -//        coll = ObservedList.decorate(new ArrayList(), LISTENER, 0, -1);
  -//        LISTENER.preEvent = null;
  -//        LISTENER.postEvent = null;
  -//        coll.add(SIX);
  -//        assertTrue(LISTENER.preEvent == null);
  -//        assertTrue(LISTENER.postEvent != null);
  -//        
  -//        coll = ObservedList.decorate(new ArrayList(), LISTENER, -1, -1);
  -//        LISTENER.preEvent = null;
  -//        LISTENER.postEvent = null;
  -//        coll.add(SIX);
  -//        assertTrue(LISTENER.preEvent != null);
  -//        assertTrue(LISTENER.postEvent != null);
  -//        
  -//        coll = ObservedList.decorate(new ArrayList(), LISTENER, 0, 0);
  -//        LISTENER.preEvent = null;
  -//        LISTENER.postEvent = null;
  -//        coll.add(SIX);
  -//        assertTrue(LISTENER.preEvent == null);
  -//        assertTrue(LISTENER.postEvent == null);
  -//        
  -//        coll = ObservedList.decorate(new ArrayList(), LISTENER, ModificationEventType.ADD, ModificationEventType.ADD_ALL);
  -//        LISTENER.preEvent = null;
  -//        LISTENER.postEvent = null;
  -//        coll.add(SIX);
  -//        assertTrue(LISTENER.preEvent != null);
  -//        assertTrue(LISTENER.postEvent == null);
  -//    }
  -//    
  +
  +    //-----------------------------------------------------------------------
  +    public ObservedCollection createObservedCollection() {
  +        return ObservedList.decorate(new ArrayList());
  +    }
  +
  +    public ObservedCollection createObservedCollection(Object listener) {
  +        return ObservedList.decorate(new ArrayList(), listener);
  +    }
  +
   }
  
  
  
  1.4       +48 -94    jakarta-commons/collections/src/test/org/apache/commons/collections/decorators/TestObservedCollection.java
  
  Index: TestObservedCollection.java
  ===================================================================
  RCS file: /home/cvs/jakarta-commons/collections/src/test/org/apache/commons/collections/decorators/TestObservedCollection.java,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- TestObservedCollection.java	31 Aug 2003 22:44:54 -0000	1.3
  +++ TestObservedCollection.java	3 Sep 2003 00:11:28 -0000	1.4
  @@ -66,7 +66,6 @@
   import junit.framework.TestSuite;
   
   import org.apache.commons.collections.TestCollection;
  -import org.apache.commons.collections.event.StandardModificationHandler;
   
   /**
    * Extension of {@link TestCollection} for exercising the
  @@ -77,14 +76,7 @@
    * 
    * @author Stephen Colebourne
    */
  -public class TestObservedCollection extends TestCollection {
  -    
  -    private static Integer SIX = new Integer(6);
  -    private static Integer SEVEN = new Integer(7);
  -    private static Integer EIGHT = new Integer(8);
  -    private static final ObservedTestHelper.Listener LISTENER = ObservedTestHelper.LISTENER;
  -    private static final ObservedTestHelper.PreListener PRE_LISTENER = ObservedTestHelper.PRE_LISTENER;
  -    private static final ObservedTestHelper.PostListener POST_LISTENER = ObservedTestHelper.POST_LISTENER;
  +public class TestObservedCollection extends TestCollection implements ObservedTestHelper.ObservedFactory {
       
       public TestObservedCollection(String testName) {
           super(testName);
  @@ -111,102 +103,64 @@
       }
       
       public Collection makeCollection() {
  -        return ObservedCollection.decorate(new ArrayList(), LISTENER);
  +        return ObservedCollection.decorate(new ArrayList(), ObservedTestHelper.LISTENER);
       }
   
       protected Collection makeFullCollection() {
           List list = new ArrayList();
           list.addAll(Arrays.asList(getFullElements()));
  -        return ObservedCollection.decorate(list, LISTENER);
  +        return ObservedCollection.decorate(list, ObservedTestHelper.LISTENER);
       }
       
       //-----------------------------------------------------------------------
       public void testObservedCollection() {
  -        ObservedCollection coll = ObservedCollection.decorate(new ArrayList());
  -        ObservedTestHelper.doTestFactoryPlain(coll);
  -        
  -        coll = ObservedCollection.decorate(new ArrayList(), LISTENER);
  -        ObservedTestHelper.doTestFactoryWithListener(coll);
  -        
  -        coll = ObservedCollection.decorate(new ArrayList(), PRE_LISTENER);
  -        ObservedTestHelper.doTestFactoryWithPreListener(coll);
  -        
  -        coll = ObservedCollection.decorate(new ArrayList(), POST_LISTENER);
  -        ObservedTestHelper.doTestFactoryWithPostListener(coll);
  -        
  -        coll = ObservedCollection.decorate(new ArrayList());
  -        ObservedTestHelper.doTestAddRemoveGetPreListeners(coll);
  -        
  -        coll = ObservedCollection.decorate(new ArrayList());
  -        ObservedTestHelper.doTestAddRemoveGetPostListeners(coll);
  -        
  -        coll = ObservedCollection.decorate(new ArrayList(), LISTENER);
  -        ObservedTestHelper.doTestAdd(coll);
  -        
  -        coll = ObservedCollection.decorate(new ArrayList(), LISTENER);
  -        ObservedTestHelper.doTestAddAll(coll);
  -        
  -        coll = ObservedCollection.decorate(new ArrayList(), LISTENER);
  -        ObservedTestHelper.doTestClear(coll);
  -        
  -        coll = ObservedCollection.decorate(new ArrayList(), LISTENER);
  -        ObservedTestHelper.doTestRemove(coll);
  -        
  -        coll = ObservedCollection.decorate(new ArrayList(), LISTENER);
  -        ObservedTestHelper.doTestRemoveAll(coll);
  -        
  -        coll = ObservedCollection.decorate(new ArrayList(), LISTENER);
  -        ObservedTestHelper.doTestRetainAll(coll);
  -        
  -        coll = ObservedCollection.decorate(new ArrayList(), LISTENER);
  -        ObservedTestHelper.doTestIteratorRemove(coll);
  -    }
  -
  -    //-----------------------------------------------------------------------    
  -    public void testFactoryWithHandler() {
  -        StandardModificationHandler handler = new StandardModificationHandler();
  -        ObservedCollection coll = ObservedCollection.decorate(new ArrayList(), handler);
  -        
  -        assertSame(handler, coll.getHandler());
  -        assertEquals(0, coll.getHandler().getPreModificationListeners().length);
  -        assertEquals(0, coll.getHandler().getPostModificationListeners().length);
  +        ObservedTestHelper.bulkTestObservedCollection(this);
       }
  -    
  -//    public void testFactoryWithMasks() {
  -//        ObservedCollection coll = ObservedCollection.decorate(new ArrayList(), LISTENER, -1, 0);
  -//        LISTENER.preEvent = null;
  -//        LISTENER.postEvent = null;
  -//        coll.add(SIX);
  -//        assertTrue(LISTENER.preEvent != null);
  -//        assertTrue(LISTENER.postEvent == null);
  +
  +    //-----------------------------------------------------------------------
  +    public ObservedCollection createObservedCollection() {
  +        return ObservedCollection.decorate(new ArrayList());
  +    }
  +
  +    public ObservedCollection createObservedCollection(Object listener) {
  +        return ObservedCollection.decorate(new ArrayList(), listener);
  +    }
  +
  +//  public void testFactoryWithMasks() {
  +//      ObservedCollection coll = ObservedCollection.decorate(new ArrayList(), LISTENER, -1, 0);
  +//      LISTENER.preEvent = null;
  +//      LISTENER.postEvent = null;
  +//      coll.add(SIX);
  +//      assertTrue(LISTENER.preEvent != null);
  +//      assertTrue(LISTENER.postEvent == null);
   //        
  -//        coll = ObservedCollection.decorate(new ArrayList(), LISTENER, 0, -1);
  -//        LISTENER.preEvent = null;
  -//        LISTENER.postEvent = null;
  -//        coll.add(SIX);
  -//        assertTrue(LISTENER.preEvent == null);
  -//        assertTrue(LISTENER.postEvent != null);
  +//      coll = ObservedCollection.decorate(new ArrayList(), LISTENER, 0, -1);
  +//      LISTENER.preEvent = null;
  +//      LISTENER.postEvent = null;
  +//      coll.add(SIX);
  +//      assertTrue(LISTENER.preEvent == null);
  +//      assertTrue(LISTENER.postEvent != null);
   //        
  -//        coll = ObservedCollection.decorate(new ArrayList(), LISTENER, -1, -1);
  -//        LISTENER.preEvent = null;
  -//        LISTENER.postEvent = null;
  -//        coll.add(SIX);
  -//        assertTrue(LISTENER.preEvent != null);
  -//        assertTrue(LISTENER.postEvent != null);
  +//      coll = ObservedCollection.decorate(new ArrayList(), LISTENER, -1, -1);
  +//      LISTENER.preEvent = null;
  +//      LISTENER.postEvent = null;
  +//      coll.add(SIX);
  +//      assertTrue(LISTENER.preEvent != null);
  +//      assertTrue(LISTENER.postEvent != null);
   //        
  -//        coll = ObservedCollection.decorate(new ArrayList(), LISTENER, 0, 0);
  -//        LISTENER.preEvent = null;
  -//        LISTENER.postEvent = null;
  -//        coll.add(SIX);
  -//        assertTrue(LISTENER.preEvent == null);
  -//        assertTrue(LISTENER.postEvent == null);
  +//      coll = ObservedCollection.decorate(new ArrayList(), LISTENER, 0, 0);
  +//      LISTENER.preEvent = null;
  +//      LISTENER.postEvent = null;
  +//      coll.add(SIX);
  +//      assertTrue(LISTENER.preEvent == null);
  +//      assertTrue(LISTENER.postEvent == null);
   //        
  -//        coll = ObservedCollection.decorate(new ArrayList(), LISTENER, ModificationEventType.ADD, ModificationEventType.ADD_ALL);
  -//        LISTENER.preEvent = null;
  -//        LISTENER.postEvent = null;
  -//        coll.add(SIX);
  -//        assertTrue(LISTENER.preEvent != null);
  -//        assertTrue(LISTENER.postEvent == null);
  -//    }
  +//      coll = ObservedCollection.decorate(new ArrayList(), LISTENER, ModificationEventType.ADD, ModificationEventType.ADD_ALL);
  +//      LISTENER.preEvent = null;
  +//      LISTENER.postEvent = null;
  +//      coll.add(SIX);
  +//      assertTrue(LISTENER.preEvent != null);
  +//      assertTrue(LISTENER.postEvent == null);
  +//  }
   //    
   }
  
  
  
  1.6       +10 -2     jakarta-commons/collections/src/test/org/apache/commons/collections/decorators/TestAll.java
  
  Index: TestAll.java
  ===================================================================
  RCS file: /home/cvs/jakarta-commons/collections/src/test/org/apache/commons/collections/decorators/TestAll.java,v
  retrieving revision 1.5
  retrieving revision 1.6
  diff -u -r1.5 -r1.6
  --- TestAll.java	31 Aug 2003 17:28:42 -0000	1.5
  +++ TestAll.java	3 Sep 2003 00:11:28 -0000	1.6
  @@ -82,10 +82,17 @@
       
       public static Test suite() {
           TestSuite suite = new TestSuite();
  +        
           suite.addTest(TestFixedSizeList.suite());
           suite.addTest(TestFixedSizeMap.suite());
           suite.addTest(TestFixedSizeSortedMap.suite());
  +        
  +        suite.addTest(TestObservedCollection.suite());
  +        suite.addTest(TestObservedList.suite());
  +        suite.addTest(TestObservedSet.suite());
  +        
           suite.addTest(TestSequencedSet.suite());
  +        
           suite.addTest(TestTransformedBag.suite());
           suite.addTest(TestTransformedBuffer.suite());
           suite.addTest(TestTransformedCollection.suite());
  @@ -95,6 +102,7 @@
           suite.addTest(TestTransformedSortedBag.suite());
           suite.addTest(TestTransformedSortedMap.suite());
           suite.addTest(TestTransformedSortedSet.suite());
  +        
           return suite;
       }
           
  
  
  
  1.4       +16 -99    jakarta-commons/collections/src/test/org/apache/commons/collections/decorators/TestObservedSet.java
  
  Index: TestObservedSet.java
  ===================================================================
  RCS file: /home/cvs/jakarta-commons/collections/src/test/org/apache/commons/collections/decorators/TestObservedSet.java,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- TestObservedSet.java	31 Aug 2003 22:44:54 -0000	1.3
  +++ TestObservedSet.java	3 Sep 2003 00:11:28 -0000	1.4
  @@ -65,7 +65,6 @@
   import junit.framework.TestSuite;
   
   import org.apache.commons.collections.TestSet;
  -import org.apache.commons.collections.event.StandardModificationHandler;
   
   /**
    * Extension of {@link TestSet} for exercising the
  @@ -76,14 +75,7 @@
    * 
    * @author Stephen Colebourne
    */
  -public class TestObservedSet extends TestSet {
  -    
  -    private static Integer SIX = new Integer(6);
  -    private static Integer SEVEN = new Integer(7);
  -    private static Integer EIGHT = new Integer(8);
  -    private static final ObservedTestHelper.Listener LISTENER = ObservedTestHelper.LISTENER;
  -    private static final ObservedTestHelper.PreListener PRE_LISTENER = ObservedTestHelper.PRE_LISTENER;
  -    private static final ObservedTestHelper.PostListener POST_LISTENER = ObservedTestHelper.POST_LISTENER;
  +public class TestObservedSet extends TestSet implements ObservedTestHelper.ObservedFactory {
       
       public TestObservedSet(String testName) {
           super(testName);
  @@ -100,102 +92,27 @@
   
       //-----------------------------------------------------------------------
       public Set makeEmptySet() {
  -        return ObservedSet.decorate(new HashSet(), LISTENER);
  +        return ObservedSet.decorate(new HashSet(), ObservedTestHelper.LISTENER);
       }
   
       protected Set makeFullSet() {
           Set set = new HashSet();
           set.addAll(Arrays.asList(getFullElements()));
  -        return ObservedSet.decorate(set, LISTENER);
  +        return ObservedSet.decorate(set, ObservedTestHelper.LISTENER);
       }
       
       //-----------------------------------------------------------------------
       public void testObservedSet() {
  -        ObservedSet coll = ObservedSet.decorate(new HashSet());
  -        ObservedTestHelper.doTestFactoryPlain(coll);
  -        
  -        coll = ObservedSet.decorate(new HashSet(), LISTENER);
  -        ObservedTestHelper.doTestFactoryWithListener(coll);
  -        
  -        coll = ObservedSet.decorate(new HashSet(), PRE_LISTENER);
  -        ObservedTestHelper.doTestFactoryWithPreListener(coll);
  -        
  -        coll = ObservedSet.decorate(new HashSet(), POST_LISTENER);
  -        ObservedTestHelper.doTestFactoryWithPostListener(coll);
  -        
  -        coll = ObservedSet.decorate(new HashSet());
  -        ObservedTestHelper.doTestAddRemoveGetPreListeners(coll);
  -        
  -        coll = ObservedSet.decorate(new HashSet());
  -        ObservedTestHelper.doTestAddRemoveGetPostListeners(coll);
  -        
  -        coll = ObservedSet.decorate(new HashSet(), LISTENER);
  -        ObservedTestHelper.doTestAdd(coll);
  -        
  -        coll = ObservedSet.decorate(new HashSet(), LISTENER);
  -        ObservedTestHelper.doTestAddAll(coll);
  -        
  -        coll = ObservedSet.decorate(new HashSet(), LISTENER);
  -        ObservedTestHelper.doTestClear(coll);
  -        
  -        coll = ObservedSet.decorate(new HashSet(), LISTENER);
  -        ObservedTestHelper.doTestRemove(coll);
  -        
  -        coll = ObservedSet.decorate(new HashSet(), LISTENER);
  -        ObservedTestHelper.doTestRemoveAll(coll);
  -        
  -        coll = ObservedSet.decorate(new HashSet(), LISTENER);
  -        ObservedTestHelper.doTestRetainAll(coll);
  -        
  -        coll = ObservedSet.decorate(new HashSet(), LISTENER);
  -        ObservedTestHelper.doTestIteratorRemove(coll);
  -    }
  -
  -    //-----------------------------------------------------------------------    
  -    public void testFactoryWithHandler() {
  -        StandardModificationHandler handler = new StandardModificationHandler();
  -        ObservedSet coll = ObservedSet.decorate(new HashSet(), handler);
  -        
  -        assertSame(handler, coll.getHandler());
  -        assertEquals(0, coll.getHandler().getPreModificationListeners().length);
  -        assertEquals(0, coll.getHandler().getPostModificationListeners().length);
  +        ObservedTestHelper.bulkTestObservedSet(this);
       }
  -    
  -//    public void testFactoryWithMasks() {
  -//        ObservedSet coll = ObservedSet.decorate(new HashSet(), LISTENER, -1, 0);
  -//        LISTENER.preEvent = null;
  -//        LISTENER.postEvent = null;
  -//        coll.add(SIX);
  -//        assertTrue(LISTENER.preEvent != null);
  -//        assertTrue(LISTENER.postEvent == null);
  -//        
  -//        coll = ObservedSet.decorate(new HashSet(), LISTENER, 0, -1);
  -//        LISTENER.preEvent = null;
  -//        LISTENER.postEvent = null;
  -//        coll.add(SIX);
  -//        assertTrue(LISTENER.preEvent == null);
  -//        assertTrue(LISTENER.postEvent != null);
  -//        
  -//        coll = ObservedSet.decorate(new HashSet(), LISTENER, -1, -1);
  -//        LISTENER.preEvent = null;
  -//        LISTENER.postEvent = null;
  -//        coll.add(SIX);
  -//        assertTrue(LISTENER.preEvent != null);
  -//        assertTrue(LISTENER.postEvent != null);
  -//        
  -//        coll = ObservedSet.decorate(new HashSet(), LISTENER, 0, 0);
  -//        LISTENER.preEvent = null;
  -//        LISTENER.postEvent = null;
  -//        coll.add(SIX);
  -//        assertTrue(LISTENER.preEvent == null);
  -//        assertTrue(LISTENER.postEvent == null);
  -//        
  -//        coll = ObservedSet.decorate(new HashSet(), LISTENER, ModificationEventType.ADD, ModificationEventType.ADD_ALL);
  -//        LISTENER.preEvent = null;
  -//        LISTENER.postEvent = null;
  -//        coll.add(SIX);
  -//        assertTrue(LISTENER.preEvent != null);
  -//        assertTrue(LISTENER.postEvent == null);
  -//    }
  -//    
  +
  +    //-----------------------------------------------------------------------
  +    public ObservedCollection createObservedCollection() {
  +        return ObservedSet.decorate(new HashSet());
  +    }
  +
  +    public ObservedCollection createObservedCollection(Object listener) {
  +        return ObservedSet.decorate(new HashSet(), listener);
  +    }
  +
   }