001: /*
002: * Copyright 2003-2005 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.collections.map;
017:
018: import java.util.Comparator;
019: import java.util.Map;
020: import java.util.SortedMap;
021:
022: import org.apache.commons.collections.Transformer;
023:
024: /**
025: * Decorates another <code>SortedMap </code> to transform objects that are added.
026: * <p>
027: * The Map put methods and Map.Entry setValue method are affected by this class.
028: * Thus objects must be removed or searched for using their transformed form.
029: * For example, if the transformation converts Strings to Integers, you must
030: * use the Integer form to remove objects.
031: * <p>
032: * <strong>Note that TransformedSortedMap is not synchronized and is not thread-safe.</strong>
033: * If you wish to use this map from multiple threads concurrently, you must use
034: * appropriate synchronization. The simplest approach is to wrap this map
035: * using {@link java.util.Collections#synchronizedSortedMap}. This class may throw
036: * exceptions when accessed by concurrent threads without synchronization.
037: * <p>
038: * This class is Serializable from Commons Collections 3.1.
039: *
040: * @since Commons Collections 3.0
041: * @version $Revision: 348013 $ $Date: 2005-11-21 23:24:45 +0000 (Mon, 21 Nov 2005) $
042: *
043: * @author Stephen Colebourne
044: */
045: public class TransformedSortedMap extends TransformedMap implements
046: SortedMap {
047:
048: /** Serialization version */
049: private static final long serialVersionUID = -8751771676410385778L;
050:
051: /**
052: * Factory method to create a transforming sorted map.
053: * <p>
054: * If there are any elements already in the map being decorated, they
055: * are NOT transformed.
056: * Constrast this with {@link #decorateTransform}.
057: *
058: * @param map the map to decorate, must not be null
059: * @param keyTransformer the predicate to validate the keys, null means no transformation
060: * @param valueTransformer the predicate to validate to values, null means no transformation
061: * @throws IllegalArgumentException if the map is null
062: */
063: public static SortedMap decorate(SortedMap map,
064: Transformer keyTransformer, Transformer valueTransformer) {
065: return new TransformedSortedMap(map, keyTransformer,
066: valueTransformer);
067: }
068:
069: /**
070: * Factory method to create a transforming sorted map that will transform
071: * existing contents of the specified map.
072: * <p>
073: * If there are any elements already in the map being decorated, they
074: * will be transformed by this method.
075: * Constrast this with {@link #decorate}.
076: *
077: * @param map the map to decorate, must not be null
078: * @param keyTransformer the transformer to use for key conversion, null means no transformation
079: * @param valueTransformer the transformer to use for value conversion, null means no transformation
080: * @throws IllegalArgumentException if map is null
081: * @since Commons Collections 3.2
082: */
083: public static SortedMap decorateTransform(SortedMap map,
084: Transformer keyTransformer, Transformer valueTransformer) {
085: TransformedSortedMap decorated = new TransformedSortedMap(map,
086: keyTransformer, valueTransformer);
087: if (map.size() > 0) {
088: Map transformed = decorated.transformMap(map);
089: decorated.clear();
090: decorated.getMap().putAll(transformed); // avoids double transformation
091: }
092: return decorated;
093: }
094:
095: //-----------------------------------------------------------------------
096: /**
097: * Constructor that wraps (not copies).
098: * <p>
099: * If there are any elements already in the collection being decorated, they
100: * are NOT transformed.</p>
101: *
102: * @param map the map to decorate, must not be null
103: * @param keyTransformer the predicate to validate the keys, null means no transformation
104: * @param valueTransformer the predicate to validate to values, null means no transformation
105: * @throws IllegalArgumentException if the map is null
106: */
107: protected TransformedSortedMap(SortedMap map,
108: Transformer keyTransformer, Transformer valueTransformer) {
109: super (map, keyTransformer, valueTransformer);
110: }
111:
112: //-----------------------------------------------------------------------
113: /**
114: * Gets the map being decorated.
115: *
116: * @return the decorated map
117: */
118: protected SortedMap getSortedMap() {
119: return (SortedMap) map;
120: }
121:
122: //-----------------------------------------------------------------------
123: public Object firstKey() {
124: return getSortedMap().firstKey();
125: }
126:
127: public Object lastKey() {
128: return getSortedMap().lastKey();
129: }
130:
131: public Comparator comparator() {
132: return getSortedMap().comparator();
133: }
134:
135: public SortedMap subMap(Object fromKey, Object toKey) {
136: SortedMap map = getSortedMap().subMap(fromKey, toKey);
137: return new TransformedSortedMap(map, keyTransformer,
138: valueTransformer);
139: }
140:
141: public SortedMap headMap(Object toKey) {
142: SortedMap map = getSortedMap().headMap(toKey);
143: return new TransformedSortedMap(map, keyTransformer,
144: valueTransformer);
145: }
146:
147: public SortedMap tailMap(Object fromKey) {
148: SortedMap map = getSortedMap().tailMap(fromKey);
149: return new TransformedSortedMap(map, keyTransformer,
150: valueTransformer);
151: }
152:
153: }
|