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