001    /*
002     *  Licensed to the Apache Software Foundation (ASF) under one or more
003     *  contributor license agreements.  See the NOTICE file distributed with
004     *  this work for additional information regarding copyright ownership.
005     *  The ASF licenses this file to You under the Apache License, Version 2.0
006     *  (the "License"); you may not use this file except in compliance with
007     *  the License.  You may obtain a copy of the License at
008     *
009     *      http://www.apache.org/licenses/LICENSE-2.0
010     *
011     *  Unless required by applicable law or agreed to in writing, software
012     *  distributed under the License is distributed on an "AS IS" BASIS,
013     *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014     *  See the License for the specific language governing permissions and
015     *  limitations under the License.
016     */
017    package org.apache.commons.collections.set;
018    
019    import java.util.Comparator;
020    import java.util.SortedSet;
021    
022    import org.apache.commons.collections.collection.SynchronizedCollection;
023    
024    /**
025     * Decorates another <code>SortedSet</code> to synchronize its behaviour
026     * for a multi-threaded environment.
027     * <p>
028     * Methods are synchronized, then forwarded to the decorated set.
029     * <p>
030     * This class is Serializable from Commons Collections 3.1.
031     *
032     * @since Commons Collections 3.0
033     * @version $Revision: 646777 $ $Date: 2008-04-10 13:33:15 +0100 (Thu, 10 Apr 2008) $
034     * 
035     * @author Stephen Colebourne
036     */
037    public class SynchronizedSortedSet extends SynchronizedCollection implements SortedSet {
038    
039        /** Serialization version */
040        private static final long serialVersionUID = 2775582861954500111L;
041    
042        /**
043         * Factory method to create a synchronized set.
044         * 
045         * @param set  the set to decorate, must not be null
046         * @throws IllegalArgumentException if set is null
047         */
048        public static SortedSet decorate(SortedSet set) {
049            return new SynchronizedSortedSet(set);
050        }
051        
052        //-----------------------------------------------------------------------
053        /**
054         * Constructor that wraps (not copies).
055         * 
056         * @param set  the set to decorate, must not be null
057         * @throws IllegalArgumentException if set is null
058         */
059        protected SynchronizedSortedSet(SortedSet set) {
060            super(set);
061        }
062    
063        /**
064         * Constructor that wraps (not copies).
065         * 
066         * @param set  the set to decorate, must not be null
067         * @param lock  the lock object to use, must not be null
068         * @throws IllegalArgumentException if set is null
069         */
070        protected SynchronizedSortedSet(SortedSet set, Object lock) {
071            super(set, lock);
072        }
073    
074        /**
075         * Gets the decorated set.
076         * 
077         * @return the decorated set
078         */
079        protected SortedSet getSortedSet() {
080            return (SortedSet) collection;
081        }
082    
083        //-----------------------------------------------------------------------
084        public SortedSet subSet(Object fromElement, Object toElement) {
085            synchronized (lock) {
086                SortedSet set = getSortedSet().subSet(fromElement, toElement);
087                // the lock is passed into the constructor here to ensure that the
088                // subset is synchronized on the same lock as the parent
089                return new SynchronizedSortedSet(set, lock);
090            }
091        }
092    
093        public SortedSet headSet(Object toElement) {
094            synchronized (lock) {
095                SortedSet set = getSortedSet().headSet(toElement);
096                // the lock is passed into the constructor here to ensure that the
097                // headset is synchronized on the same lock as the parent
098                return new SynchronizedSortedSet(set, lock);
099            }
100        }
101    
102        public SortedSet tailSet(Object fromElement) {
103            synchronized (lock) {
104                SortedSet set = getSortedSet().tailSet(fromElement);
105                // the lock is passed into the constructor here to ensure that the
106                // tailset is synchronized on the same lock as the parent
107                return new SynchronizedSortedSet(set, lock);
108            }
109        }
110    
111        public Object first() {
112            synchronized (lock) {
113                return getSortedSet().first();
114            }
115        }
116    
117        public Object last() {
118            synchronized (lock) {
119                return getSortedSet().last();
120            }
121        }
122    
123        public Comparator comparator() {
124            synchronized (lock) {
125                return getSortedSet().comparator();
126            }
127        }
128    
129    }