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.io.IOException; 020 import java.io.ObjectInputStream; 021 import java.io.ObjectOutputStream; 022 import java.io.Serializable; 023 import java.util.Collection; 024 import java.util.Iterator; 025 import java.util.Map; 026 import java.util.Set; 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>Map</code> to fix the size, preventing 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 FixedSizeMap 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#synchronizedMap(Map)}. 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: 646777 $ $Date: 2008-04-10 13:33:15 +0100 (Thu, 10 Apr 2008) $ 055 * 056 * @author Stephen Colebourne 057 * @author Paul Jack 058 */ 059 public class FixedSizeMap 060 extends AbstractMapDecorator 061 implements Map, BoundedMap, Serializable { 062 063 /** Serialization version */ 064 private static final long serialVersionUID = 7450927208116179316L; 065 066 /** 067 * Factory method to create a fixed size map. 068 * 069 * @param map the map to decorate, must not be null 070 * @throws IllegalArgumentException if map is null 071 */ 072 public static Map decorate(Map map) { 073 return new FixedSizeMap(map); 074 } 075 076 //----------------------------------------------------------------------- 077 /** 078 * Constructor that wraps (not copies). 079 * 080 * @param map the map to decorate, must not be null 081 * @throws IllegalArgumentException if map is null 082 */ 083 protected FixedSizeMap(Map map) { 084 super(map); 085 } 086 087 //----------------------------------------------------------------------- 088 /** 089 * Write the map out using a custom routine. 090 * 091 * @param out the output stream 092 * @throws IOException 093 * @since Commons Collections 3.1 094 */ 095 private void writeObject(ObjectOutputStream out) throws IOException { 096 out.defaultWriteObject(); 097 out.writeObject(map); 098 } 099 100 /** 101 * Read the map in using a custom routine. 102 * 103 * @param in the input stream 104 * @throws IOException 105 * @throws ClassNotFoundException 106 * @since Commons Collections 3.1 107 */ 108 private void readObject(ObjectInputStream in) throws IOException, 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("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("Cannot put new key/value pair - Map is fixed size"); 125 } 126 } 127 map.putAll(mapToCopy); 128 } 129 130 public void clear() { 131 throw new UnsupportedOperationException("Map is fixed size"); 132 } 133 134 public Object remove(Object key) { 135 throw new UnsupportedOperationException("Map is fixed size"); 136 } 137 138 public Set entrySet() { 139 Set set = map.entrySet(); 140 // unmodifiable set will still allow modification via Map.Entry objects 141 return UnmodifiableSet.decorate(set); 142 } 143 144 public Set keySet() { 145 Set set = map.keySet(); 146 return UnmodifiableSet.decorate(set); 147 } 148 149 public Collection values() { 150 Collection coll = map.values(); 151 return UnmodifiableCollection.decorate(coll); 152 } 153 154 public boolean isFull() { 155 return true; 156 } 157 158 public int maxSize() { 159 return size(); 160 } 161 162 }