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.map;
018    
019    import java.util.Comparator;
020    import java.util.SortedMap;
021    
022    import org.apache.commons.collections.Factory;
023    import org.apache.commons.collections.Transformer;
024    
025    /**
026     * Decorates another <code>SortedMap</code> to create objects in the map on demand.
027     * <p>
028     * When the {@link #get(Object)} method is called with a key that does not
029     * exist in the map, the factory is used to create the object. The created
030     * object will be added to the map using the requested key.
031     * <p>
032     * For instance:
033     * <pre>
034     * Factory factory = new Factory() {
035     *     public Object create() {
036     *         return new Date();
037     *     }
038     * }
039     * SortedMap lazy = Lazy.sortedMap(new HashMap(), factory);
040     * Object obj = lazy.get("NOW");
041     * </pre>
042     *
043     * After the above code is executed, <code>obj</code> will contain
044     * a new <code>Date</code> instance. Furthermore, that <code>Date</code>
045     * instance is mapped to the "NOW" key in the map.
046     * <p>
047     * <strong>Note that LazySortedMap is not synchronized and is not thread-safe.</strong>
048     * If you wish to use this map from multiple threads concurrently, you must use
049     * appropriate synchronization. The simplest approach is to wrap this map
050     * using {@link java.util.Collections#synchronizedSortedMap}. This class may throw 
051     * exceptions when accessed by concurrent threads without synchronization.
052     * <p>
053     * This class is Serializable from Commons Collections 3.1.
054     *
055     * @since Commons Collections 3.0
056     * @version $Revision: 646777 $ $Date: 2008-04-10 13:33:15 +0100 (Thu, 10 Apr 2008) $
057     * 
058     * @author Stephen Colebourne
059     * @author Paul Jack
060     */
061    public class LazySortedMap
062            extends LazyMap
063            implements SortedMap {
064    
065        /** Serialization version */
066        private static final long serialVersionUID = 2715322183617658933L;
067    
068        /**
069         * Factory method to create a lazily instantiated sorted map.
070         * 
071         * @param map  the map to decorate, must not be null
072         * @param factory  the factory to use, must not be null
073         * @throws IllegalArgumentException if map or factory is null
074         */
075        public static SortedMap decorate(SortedMap map, Factory factory) {
076            return new LazySortedMap(map, factory);
077        }
078    
079        /**
080         * Factory method to create a lazily instantiated sorted map.
081         * 
082         * @param map  the map to decorate, must not be null
083         * @param factory  the factory to use, must not be null
084         * @throws IllegalArgumentException if map or factory is null
085         */
086        public static SortedMap decorate(SortedMap map, Transformer factory) {
087            return new LazySortedMap(map, factory);
088        }
089    
090        //-----------------------------------------------------------------------
091        /**
092         * Constructor that wraps (not copies).
093         * 
094         * @param map  the map to decorate, must not be null
095         * @param factory  the factory to use, must not be null
096         * @throws IllegalArgumentException if map or factory is null
097         */
098        protected LazySortedMap(SortedMap map, Factory factory) {
099            super(map, factory);
100        }
101    
102        /**
103         * Constructor that wraps (not copies).
104         * 
105         * @param map  the map to decorate, must not be null
106         * @param factory  the factory to use, must not be null
107         * @throws IllegalArgumentException if map or factory is null
108         */
109        protected LazySortedMap(SortedMap map, Transformer factory) {
110            super(map, factory);
111        }
112    
113        //-----------------------------------------------------------------------
114        /**
115         * Gets the map being decorated.
116         * 
117         * @return the decorated map
118         */
119        protected SortedMap getSortedMap() {
120            return (SortedMap) map;
121        }
122    
123        //-----------------------------------------------------------------------
124        public Object firstKey() {
125            return getSortedMap().firstKey();
126        }
127    
128        public Object lastKey() {
129            return getSortedMap().lastKey();
130        }
131    
132        public Comparator comparator() {
133            return getSortedMap().comparator();
134        }
135    
136        public SortedMap subMap(Object fromKey, Object toKey) {
137            SortedMap map = getSortedMap().subMap(fromKey, toKey);
138            return new LazySortedMap(map, factory);
139        }
140    
141        public SortedMap headMap(Object toKey) {
142            SortedMap map = getSortedMap().headMap(toKey);
143            return new LazySortedMap(map, factory);
144        }
145    
146        public SortedMap tailMap(Object fromKey) {
147            SortedMap map = getSortedMap().tailMap(fromKey);
148            return new LazySortedMap(map, factory);
149        }
150    
151    }