package org.apache.commons.events.observable ; import java.util.SortedMap ; import java.util.Comparator ; /** *

* Decorates a SortedMap implementation with a bound * property named "collection". *

*

* Each modifying method call made on this SortedMap is * handled as a change to the "collection" property. This * facility serves to notify subscribers of a change to the collection * but does not allow users the option of vetoing the change. To * gain the ability to veto the change, use a {@link ConstrainedSortedMap} * decorater. *

*

* Due to the fact that a Map offers several "views" of the * same data, some confusion may arise as to what action caused a * particular event. For instance, entries in the map may be * deleted by Map.values().remove(object). There is no * known method, short of digging into the implementation of a Map, * to determine which key-value pair was deleted by this operation, * particularly if there is more than one occurence of a specific * value. (Conversely, there is also no means of controlling which * key-value pair is deleted by this method; therefore it's not a * terribly smart thing to do.) *

*

* This implementation of a bound map makes no attempt to interpret * events generated by these alternate views of the data. It merely * ensures that registered listeners receive all events generated * by any view of the Map's data. It is left to the client * to interpret the events generated by their map's usage. *

* * @see BoundMap * @since Commons Events 1.0 * @author Bryce Nordgren / USDA Forest Service */ public class BoundSortedMap extends BoundMap implements SortedMap { // Constructors //----------------------------------------------------------------------- protected BoundSortedMap( final SortedMap source, final CollectionChangeEventFactory eventFactory) { super(source, eventFactory) ; } protected BoundSortedMap(final SortedMap source) { super(source); } // Factory methods //----------------------------------------------------------------------- public static BoundSortedMap decorate( final SortedMap source, final CollectionChangeEventFactory eventFactory) { return new BoundSortedMap(source, eventFactory) ; } public static BoundSortedMap decorate(final SortedMap source) { return new BoundSortedMap(source) ; } // Utility methods //----------------------------------------------------------------------- /** * Typecast to the SortedMap interface... * @return a SortedMap */ private SortedMap getSortedMap() { return (SortedMap)(getMap()) ; } /** * Binds an unbound SortedMap returned by the decorated object. * Ensures that this map and the newly bound map get each other's * events. */ private SortedMap bindSortedMap(SortedMap unbound) { // make a copy of the event factory CollectionChangeEventFactory factoryCopy = (CollectionChangeEventFactory)(eventFactory.clone()) ; // bind the subMap view BoundSortedMap boundMap = BoundSortedMap.decorate( unbound, factoryCopy) ; // send "boundMap's" events to our listeners boundMap.addPropertyChangeListener(createEventRepeater()) ; // send our events to "boundMap's" listeners addPropertyChangeListener(boundMap.createEventRepeater()) ; return boundMap ; } // SortedMap API (methods which do not change map contents.) //----------------------------------------------------------------------- public Comparator comparator() { return getSortedMap().comparator() ; } public Object firstKey() { return getSortedMap().firstKey() ; } public Object lastKey() { return getSortedMap().lastKey() ; } // Decorator methods //----------------------------------------------------------------------- public SortedMap subMap(Object fromKey, Object toKey) { SortedMap subMap = getSortedMap().subMap(fromKey, toKey) ; return bindSortedMap(subMap) ; } public SortedMap headMap(Object toKey) { SortedMap subMap = getSortedMap().headMap(toKey) ; return bindSortedMap(subMap) ; } public SortedMap tailMap(Object fromKey) { SortedMap subMap = getSortedMap().tailMap(fromKey) ; return bindSortedMap(subMap) ; } }