001: /*
002: * Copyright 2003-2004 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.io.IOException;
019: import java.io.ObjectInputStream;
020: import java.io.ObjectOutputStream;
021: import java.io.Serializable;
022: import java.util.Collection;
023: import java.util.Iterator;
024: import java.util.Map;
025: import java.util.Set;
026: import java.util.SortedMap;
027:
028: import org.apache.commons.collections.BoundedMap;
029: import org.apache.commons.collections.collection.UnmodifiableCollection;
030: import org.apache.commons.collections.set.UnmodifiableSet;
031:
032: /**
033: * Decorates another <code>SortedMap</code> to fix the size blocking add/remove.
034: * <p>
035: * Any action that would change the size of the map is disallowed.
036: * The put method is allowed to change the value associated with an existing
037: * key however.
038: * <p>
039: * If trying to remove or clear the map, an UnsupportedOperationException is
040: * thrown. If trying to put a new mapping into the map, an
041: * IllegalArgumentException is thrown. This is because the put method can
042: * succeed if the mapping's key already exists in the map, so the put method
043: * is not always unsupported.
044: * <p>
045: * <strong>Note that FixedSizeSortedMap is not synchronized and is not thread-safe.</strong>
046: * If you wish to use this map from multiple threads concurrently, you must use
047: * appropriate synchronization. The simplest approach is to wrap this map
048: * using {@link java.util.Collections#synchronizedSortedMap}. This class may throw
049: * exceptions when accessed by concurrent threads without synchronization.
050: * <p>
051: * This class is Serializable from Commons Collections 3.1.
052: *
053: * @since Commons Collections 3.0
054: * @version $Revision: 348007 $ $Date: 2005-11-21 22:52:57 +0000 (Mon, 21 Nov 2005) $
055: *
056: * @author Stephen Colebourne
057: * @author Paul Jack
058: */
059: public class FixedSizeSortedMap extends AbstractSortedMapDecorator
060: implements SortedMap, BoundedMap, Serializable {
061:
062: /** Serialization version */
063: private static final long serialVersionUID = 3126019624511683653L;
064:
065: /**
066: * Factory method to create a fixed size sorted map.
067: *
068: * @param map the map to decorate, must not be null
069: * @throws IllegalArgumentException if map is null
070: */
071: public static SortedMap decorate(SortedMap map) {
072: return new FixedSizeSortedMap(map);
073: }
074:
075: //-----------------------------------------------------------------------
076: /**
077: * Constructor that wraps (not copies).
078: *
079: * @param map the map to decorate, must not be null
080: * @throws IllegalArgumentException if map is null
081: */
082: protected FixedSizeSortedMap(SortedMap map) {
083: super (map);
084: }
085:
086: /**
087: * Gets the map being decorated.
088: *
089: * @return the decorated map
090: */
091: protected SortedMap getSortedMap() {
092: return (SortedMap) map;
093: }
094:
095: //-----------------------------------------------------------------------
096: /**
097: * Write the map out using a custom routine.
098: */
099: private void writeObject(ObjectOutputStream out) throws IOException {
100: out.defaultWriteObject();
101: out.writeObject(map);
102: }
103:
104: /**
105: * Read the map in using a custom routine.
106: */
107: private void readObject(ObjectInputStream in) throws IOException,
108: ClassNotFoundException {
109: in.defaultReadObject();
110: map = (Map) in.readObject();
111: }
112:
113: //-----------------------------------------------------------------------
114: public Object put(Object key, Object value) {
115: if (map.containsKey(key) == false) {
116: throw new IllegalArgumentException(
117: "Cannot put new key/value pair - Map is fixed size");
118: }
119: return map.put(key, value);
120: }
121:
122: public void putAll(Map mapToCopy) {
123: for (Iterator it = mapToCopy.keySet().iterator(); it.hasNext();) {
124: if (mapToCopy.containsKey(it.next()) == false) {
125: throw new IllegalArgumentException(
126: "Cannot put new key/value pair - Map is fixed size");
127: }
128: }
129: map.putAll(mapToCopy);
130: }
131:
132: public void clear() {
133: throw new UnsupportedOperationException("Map is fixed size");
134: }
135:
136: public Object remove(Object key) {
137: throw new UnsupportedOperationException("Map is fixed size");
138: }
139:
140: public Set entrySet() {
141: Set set = map.entrySet();
142: return UnmodifiableSet.decorate(set);
143: }
144:
145: public Set keySet() {
146: Set set = map.keySet();
147: return UnmodifiableSet.decorate(set);
148: }
149:
150: public Collection values() {
151: Collection coll = map.values();
152: return UnmodifiableCollection.decorate(coll);
153: }
154:
155: //-----------------------------------------------------------------------
156: public SortedMap subMap(Object fromKey, Object toKey) {
157: SortedMap map = getSortedMap().subMap(fromKey, toKey);
158: return new FixedSizeSortedMap(map);
159: }
160:
161: public SortedMap headMap(Object toKey) {
162: SortedMap map = getSortedMap().headMap(toKey);
163: return new FixedSizeSortedMap(map);
164: }
165:
166: public SortedMap tailMap(Object fromKey) {
167: SortedMap map = getSortedMap().tailMap(fromKey);
168: return new FixedSizeSortedMap(map);
169: }
170:
171: public boolean isFull() {
172: return true;
173: }
174:
175: public int maxSize() {
176: return size();
177: }
178:
179: }
|