001    /*
002     * Copyright 2003-2004 The Apache Software Foundation
003     *
004     * Licensed under the Apache License, Version 2.0 (the "License");
005     * you may not use this file except in compliance with the License.
006     * You may obtain a copy of the License at
007     *
008     *     http://www.apache.org/licenses/LICENSE-2.0
009     *
010     * Unless required by applicable law or agreed to in writing, software
011     * distributed under the License is distributed on an "AS IS" BASIS,
012     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013     * See the License for the specific language governing permissions and
014     * limitations under the License.
015     */
016    package org.apache.commons.events.observable;
017    
018    import java.util.Set;
019    
020    /**
021     * Decorates a <code>Set</code> implementation to observe modifications.
022     * <p>
023     * Each modifying method call made on this <code>Set</code> is forwarded to a
024     * {@link ModificationHandler}.
025     * The handler manages the event, notifying listeners and optionally vetoing changes.
026     * The default handler is
027     * {@link org.apache.commons.events.observable.standard.StandardModificationHandler}.
028     * See this class for details of configuration available.
029     *
030     * @since Commons Events 1.0
031     * @version $Revision: 155443 $ $Date: 2005-02-26 13:19:51 +0000 (Sat, 26 Feb 2005) $
032     * 
033     * @author Stephen Colebourne
034     */
035    public class ObservableSet extends ObservableCollection implements Set {
036        
037        // Factories
038        //-----------------------------------------------------------------------
039        /**
040         * Factory method to create an observable set.
041         * <p>
042         * A {@link org.apache.commons.events.observable.standard.StandardModificationHandler} will be created.
043         * This can be accessed by {@link #getHandler()} to add listeners.
044         *
045         * @param set  the set to decorate, must not be null
046         * @return the observed Set
047         * @throws IllegalArgumentException if the collection is null
048         */
049        public static ObservableSet decorate(final Set set) {
050            return new ObservableSet(set, null);
051        }
052    
053        /**
054         * Factory method to create an observable set using a listener or a handler.
055         * <p>
056         * A lot of functionality is available through this method.
057         * If you don't need the extra functionality, simply implement the
058         * {@link org.apache.commons.events.observable.standard.StandardModificationListener}
059         * interface and pass it in as the second parameter.
060         * <p>
061         * Internally, an <code>ObservableSet</code> relies on a {@link ModificationHandler}.
062         * The handler receives all the events and processes them, typically by
063         * calling listeners. Different handler implementations can be plugged in
064         * to provide a flexible event system.
065         * <p>
066         * The handler implementation is determined by the listener parameter via
067         * the registered factories. The listener may be a manually configured 
068         * <code>ModificationHandler</code> instance.
069         * <p>
070         * The listener is defined as an Object for maximum flexibility.
071         * It does not have to be a listener in the classic JavaBean sense.
072         * It is entirely up to the factory and handler as to how the parameter
073         * is interpretted. An IllegalArgumentException is thrown if no suitable
074         * handler can be found for this listener.
075         * <p>
076         * A <code>null</code> listener will create a
077         * {@link org.apache.commons.events.observable.standard.StandardModificationHandler}.
078         *
079         * @param set  the set to decorate, must not be null
080         * @param listener  set listener, may be null
081         * @return the observed set
082         * @throws IllegalArgumentException if the set is null
083         * @throws IllegalArgumentException if there is no valid handler for the listener
084         */
085        public static ObservableSet decorate(
086                final Set set,
087                final Object listener) {
088            
089            if (set == null) {
090                throw new IllegalArgumentException("Set must not be null");
091            }
092            return new ObservableSet(set, listener);
093        }
094    
095        // Constructors
096        //-----------------------------------------------------------------------
097        /**
098         * Constructor that wraps (not copies) and takes a handler.
099         * <p>
100         * The handler implementation is determined by the listener parameter via
101         * the registered factories. The listener may be a manually configured 
102         * <code>ModificationHandler</code> instance.
103         * 
104         * @param set  the set to decorate, must not be null
105         * @param listener  the listener, may be null
106         * @throws IllegalArgumentException if the set is null
107         */
108        protected ObservableSet(
109                final Set set,
110                final Object listener) {
111            super(set, listener);
112        }
113    
114    }