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.Comparator;
019 import java.util.SortedSet;
020
021 /**
022 * Decorates a <code>SortedSet</code> implementation to observe modifications.
023 * <p>
024 * Each modifying method call made on this <code>SortedSet</code> is forwarded to a
025 * {@link ModificationHandler}.
026 * The handler manages the event, notifying listeners and optionally vetoing changes.
027 * The default handler is
028 * {@link org.apache.commons.events.observable.standard.StandardModificationHandler StandardModificationHandler}.
029 * See this class for details of configuration available.
030 *
031 * @since Commons Events 1.0
032 * @version $Revision: 155443 $ $Date: 2005-02-26 13:19:51 +0000 (Sat, 26 Feb 2005) $
033 *
034 * @author Stephen Colebourne
035 */
036 public class ObservableSortedSet extends ObservableSet implements SortedSet {
037
038 // Factories
039 //-----------------------------------------------------------------------
040 /**
041 * Factory method to create an observable set.
042 * <p>
043 * A {@link org.apache.commons.events.observable.standard.StandardModificationHandler} will be created.
044 * This can be accessed by {@link #getHandler()} to add listeners.
045 *
046 * @param set the set to decorate, must not be null
047 * @return the observed Set
048 * @throws IllegalArgumentException if the collection is null
049 */
050 public static ObservableSortedSet decorate(final SortedSet set) {
051 return new ObservableSortedSet(set, null);
052 }
053
054 /**
055 * Factory method to create an observable set using a listener or a handler.
056 * <p>
057 * A lot of functionality is available through this method.
058 * If you don't need the extra functionality, simply implement the
059 * {@link org.apache.commons.events.observable.standard.StandardModificationListener}
060 * interface and pass it in as the second parameter.
061 * <p>
062 * Internally, an <code>ObservableSortedSet</code> relies on a {@link ModificationHandler}.
063 * The handler receives all the events and processes them, typically by
064 * calling listeners. Different handler implementations can be plugged in
065 * to provide a flexible event system.
066 * <p>
067 * The handler implementation is determined by the listener parameter via
068 * the registered factories. The listener may be a manually configured
069 * <code>ModificationHandler</code> instance.
070 * <p>
071 * The listener is defined as an Object for maximum flexibility.
072 * It does not have to be a listener in the classic JavaBean sense.
073 * It is entirely up to the factory and handler as to how the parameter
074 * is interpretted. An IllegalArgumentException is thrown if no suitable
075 * handler can be found for this listener.
076 * <p>
077 * A <code>null</code> listener will create a
078 * {@link org.apache.commons.events.observable.standard.StandardModificationHandler}.
079 *
080 * @param set the set to decorate, must not be null
081 * @param listener set listener, may be null
082 * @return the observed set
083 * @throws IllegalArgumentException if the set is null
084 * @throws IllegalArgumentException if there is no valid handler for the listener
085 */
086 public static ObservableSortedSet decorate(
087 final SortedSet set,
088 final Object listener) {
089
090 if (set == null) {
091 throw new IllegalArgumentException("SortedSet must not be null");
092 }
093 return new ObservableSortedSet(set, listener);
094 }
095
096 // Constructors
097 //-----------------------------------------------------------------------
098 /**
099 * Constructor that wraps (not copies) and takes a handler.
100 * <p>
101 * The handler implementation is determined by the listener parameter via
102 * the registered factories. The listener may be a manually configured
103 * <code>ModificationHandler</code> instance.
104 *
105 * @param set the set to decorate, must not be null
106 * @param listener the listener, may be null
107 * @throws IllegalArgumentException if the set is null
108 */
109 protected ObservableSortedSet(
110 final SortedSet set,
111 final Object listener) {
112 super(set, listener);
113 }
114
115 /**
116 * Typecast the collection to a SortedSet.
117 *
118 * @return the wrapped collection as a SortedSet
119 */
120 private SortedSet getSortedSet() {
121 return (SortedSet) getCollection();
122 }
123
124 // SortedSet API
125 //-----------------------------------------------------------------------
126 public Comparator comparator() {
127 return getSortedSet().comparator();
128 }
129
130 public Object first() {
131 return getSortedSet().first();
132 }
133
134 public Object last() {
135 return getSortedSet().last();
136 }
137
138 //-----------------------------------------------------------------------
139 public SortedSet subSet(Object fromElement, Object toElement) {
140 SortedSet subSet = getSortedSet().subSet(fromElement, toElement);
141 return new ObservableSortedSet(subSet, getHandler().createSubSetHandler(fromElement, toElement));
142 }
143
144 public SortedSet headSet(Object toElement) {
145 SortedSet headSet = getSortedSet().headSet(toElement);
146 return new ObservableSortedSet(headSet, getHandler().createHeadSetHandler(toElement));
147 }
148
149 public SortedSet tailSet(Object fromElement) {
150 SortedSet tailSet = getSortedSet().tailSet(fromElement);
151 return new ObservableSortedSet(tailSet, getHandler().createTailSetHandler(fromElement));
152 }
153
154 }