001: /*
002: * Primitive Collections for Java.
003: * Copyright (C) 2003 Søren Bak
004: *
005: * This library is free software; you can redistribute it and/or
006: * modify it under the terms of the GNU Lesser General Public
007: * License as published by the Free Software Foundation; either
008: * version 2.1 of the License, or (at your option) any later version.
009: *
010: * This library is distributed in the hope that it will be useful,
011: * but WITHOUT ANY WARRANTY; without even the implied warranty of
012: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
013: * Lesser General Public License for more details.
014: *
015: * You should have received a copy of the GNU Lesser General Public
016: * License along with this library; if not, write to the Free Software
017: * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
018: */
019: package bak.pcj.adapter;
020:
021: import bak.pcj.Adapter;
022: import bak.pcj.FloatIterator;
023: import bak.pcj.map.FloatKeyMap;
024: import bak.pcj.map.AbstractFloatKeyMap;
025: import bak.pcj.map.FloatKeyMapIterator;
026: import bak.pcj.set.FloatSet;
027: import bak.pcj.util.Exceptions;
028:
029: import java.util.Map;
030: import java.util.Iterator;
031: import java.util.Collection;
032:
033: /**
034: * This class represents adaptions of Java Collections Framework
035: * maps to primitive maps from float values to objects.
036: * The adapter is implemented as a wrapper around the map.
037: * Thus, changes to the underlying map are reflected by this
038: * map and vice versa.
039: *
040: * <p>
041: * Adapters from JCF maps to primitive map will
042: * fail if the JCF collection contains <tt>null</tt> keys or
043: * keys of the wrong class. However, adapters are not fast
044: * failing in the case that the underlying map should
045: * contain illegal keys. To implement fast failure would require
046: * every operation to check every key of the underlying
047: * map before doing anything. Instead validation methods
048: * are provided. They can be called using the assertion facility
049: * in the client code:
050: * <pre>
051: * MapToFloatKeyMapAdapter s;
052: * ...
053: * <b>assert</b> s.validate();
054: * </pre>
055: * or by letting the adapter throw an exception on illegal values:
056: * <pre>
057: * MapToFloatKeyMapAdapter s;
058: * ...
059: * s.evalidate(); // Throws an exception on illegal values
060: * </pre>
061: * Either way, validation must be invoked directly by the client
062: * code.
063: *
064: * @author Søren Bak
065: * @version 1.2 21-08-2003 19:10
066: * @since 1.0
067: */
068: public class MapToFloatKeyMapAdapter extends AbstractFloatKeyMap
069: implements FloatKeyMap {
070:
071: /** The underlying map. */
072: protected Map map;
073:
074: /**
075: * Creates a new adaption to a map from float
076: * values to objects.
077: *
078: * @param map
079: * the underlying map. This map must
080: * consist of keys of class
081: * {@link Float Float}. Otherwise a
082: * {@link ClassCastException ClassCastException}
083: * will be thrown by some methods.
084: *
085: * @throws NullPointerException
086: * if <tt>map</tt> is <tt>null</tt>.
087: */
088: public MapToFloatKeyMapAdapter(Map map) {
089: this (map, false);
090: }
091:
092: /**
093: * Creates a new adaption to a map from float
094: * values to objects. The map to adapt is optionally validated.
095: *
096: * @param map
097: * the underlying map. This map must
098: * consist of keys of class
099: * {@link Float Float}. Otherwise a
100: * {@link ClassCastException ClassCastException}
101: * will be thrown by some methods.
102: *
103: * @param validate
104: * indicates whether <tt>map</tt> should
105: * be checked for illegal keys.
106: *
107: * @throws NullPointerException
108: * if <tt>map</tt> is <tt>null</tt>.
109: *
110: * @throws IllegalStateException
111: * if <tt>validate</tt> is <tt>true</tt> and
112: * <tt>map</tt> contains a <tt>null</tt> key
113: * or a key that is not of class
114: * {@link Float Float}.
115: */
116: public MapToFloatKeyMapAdapter(Map map, boolean validate) {
117: if (map == null)
118: Exceptions.nullArgument("map");
119: this .map = map;
120: if (validate)
121: evalidate();
122: }
123:
124: public void clear() {
125: map.clear();
126: }
127:
128: public boolean containsKey(float key) {
129: return map.get(new Float(key)) != null;
130: }
131:
132: public boolean containsValue(Object value) {
133: return map.containsValue(value);
134: }
135:
136: public FloatKeyMapIterator entries() {
137: return new FloatKeyMapIterator() {
138: Iterator i = map.entrySet().iterator();
139: Map.Entry lastEntry = null;
140:
141: public boolean hasNext() {
142: return i.hasNext();
143: }
144:
145: public void next() {
146: lastEntry = (Map.Entry) i.next();
147: }
148:
149: public float getKey() {
150: if (lastEntry == null)
151: Exceptions.noElementToGet();
152: return ((Float) lastEntry.getKey()).floatValue();
153: }
154:
155: public Object getValue() {
156: if (lastEntry == null)
157: Exceptions.noElementToGet();
158: return lastEntry.getValue();
159: }
160:
161: public void remove() {
162: i.remove();
163: lastEntry = null;
164: }
165: };
166: }
167:
168: public Object get(float key) {
169: return map.get(new Float(key));
170: }
171:
172: public FloatSet keySet() {
173: return new SetToFloatSetAdapter(map.keySet());
174: }
175:
176: public Object put(float key, Object value) {
177: return map.put(new Float(key), value);
178: }
179:
180: public Object remove(float key) {
181: return map.remove(new Float(key));
182: }
183:
184: public int size() {
185: return map.size();
186: }
187:
188: public Collection values() {
189: return map.values();
190: }
191:
192: /**
193: * Indicates whether the underlying map is valid for
194: * this adapter. For the underlying map to be valid, it
195: * can only contain {@link Float Float} keys and no <tt>null</tt>
196: * keys.
197: *
198: * @return <tt>true</tt> if the underlying map is
199: * valid; returns <tt>false</tt> otherwise.
200: */
201: public boolean validate() {
202: return Adapter.isFloatKeyAdaptable(map);
203: }
204:
205: /**
206: * Validates the map underlying this adapter and throws
207: * an exception if it is invalid. For the underlying map
208: * to be valid, it can only contain {@link Float Float}
209: * keys and no <tt>null</tt> keys.
210: *
211: * @throws IllegalStateException
212: * if the underlying map is invalid.
213: */
214: public void evalidate() {
215: if (!validate())
216: Exceptions.cannotAdapt("map");
217: }
218:
219: }
|