001: package org.apache.commons.events.observable;
002:
003: import java.util.SortedSet;
004: import java.util.Comparator;
005:
006: /**
007: * <p>
008: * Decorates a <code>SortedSet</code> implementation with a <b>bound
009: * property</b> named "collection".
010: * </p>
011: * <p>
012: * Each modifying method call made on this <code>SortedSet</code> is
013: * handled as a change to the "collection" property. This
014: * facility serves to notify subscribers of a change to the collection
015: * but does not allow users the option of vetoing the change. To
016: * gain the ability to veto the change, use a {@link ConstrainedSortedSet}
017: * decorater.
018: * </p>
019: * <p>
020: * The SortedSet interface supports three methods which provide
021: * views into the data maintained by this object. These views are
022: * "backed by" this set, and therefore changes in the main object
023: * or in any view are reflected by any other view. This decorater
024: * ensures that changes made to any of the views are propagated to
025: * listeners registered in all of the views.
026: * </p>
027: * @since Commons Events 1.0
028: * @author Stephen Colebourne, Bryce Nordgren
029: */
030: public class BoundSortedSet extends BoundSet implements SortedSet {
031:
032: // Constructors
033: //-----------------------------------------------------------------------
034: protected BoundSortedSet(final SortedSet source,
035: final CollectionChangeEventFactory eventFactory) {
036:
037: super (source, eventFactory);
038: }
039:
040: protected BoundSortedSet(final SortedSet source) {
041: super (source);
042: }
043:
044: // Factory methods
045: //-----------------------------------------------------------------------
046: public static BoundSortedSet decorate(final SortedSet source,
047: final CollectionChangeEventFactory eventFactory) {
048: return new BoundSortedSet(source, eventFactory);
049: }
050:
051: public static BoundSortedSet decorate(final SortedSet source) {
052: return new BoundSortedSet(source);
053: }
054:
055: // Utility methods
056: //-----------------------------------------------------------------------
057: /**
058: * Typecasting method to get the sorted set functionality.
059: * @return the decorated collection as a SortedSet.
060: */
061: private SortedSet getSortedSet() {
062: return (SortedSet) (getCollection());
063: }
064:
065: private SortedSet bindSortedSet(SortedSet unbound) {
066: // clone the event factory
067: CollectionChangeEventFactory factoryCopy = (CollectionChangeEventFactory) (eventFactory
068: .clone());
069:
070: // bind the sortedset
071: BoundSortedSet boundSet = BoundSortedSet.decorate(unbound,
072: factoryCopy);
073:
074: // send "boundSet's" events to our listeners
075: boundSet.addPropertyChangeListener(createEventRepeater());
076:
077: // send our events to "boundSet's" listeners
078: addPropertyChangeListener(boundSet.createEventRepeater());
079:
080: return boundSet;
081: }
082:
083: // SortedSet API (methods which don't change the set.)
084: //-----------------------------------------------------------------------
085: public Comparator comparator() {
086: return getSortedSet().comparator();
087: }
088:
089: public Object first() {
090: return getSortedSet().first();
091: }
092:
093: public Object last() {
094: return getSortedSet().last();
095: }
096:
097: // Decorated methods
098: //-----------------------------------------------------------------------
099: public SortedSet subSet(Object from, Object to) {
100: SortedSet unbound = getSortedSet().subSet(from, to);
101: return bindSortedSet(unbound);
102: }
103:
104: public SortedSet headSet(Object to) {
105: SortedSet unbound = getSortedSet().headSet(to);
106: return bindSortedSet(unbound);
107: }
108:
109: public SortedSet tailSet(Object from) {
110: SortedSet unbound = getSortedSet().tailSet(from);
111: return bindSortedSet(unbound);
112: }
113: }
|