KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > bak > pcj > adapter > MapToCharKeyByteMapAdapter


1 /*
2  * Primitive Collections for Java.
3  * Copyright (C) 2002, 2003 Søren Bak
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public
7  * License as published by the Free Software Foundation; either
8  * version 2.1 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13  * Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public
16  * License along with this library; if not, write to the Free Software
17  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18  */

19 package bak.pcj.adapter;
20
21 import bak.pcj.Adapter;
22 import bak.pcj.CharIterator;
23 import bak.pcj.ByteCollection;
24 import bak.pcj.map.CharKeyByteMap;
25 import bak.pcj.map.AbstractCharKeyByteMap;
26 import bak.pcj.map.CharKeyByteMapIterator;
27 import bak.pcj.map.MapDefaults;
28 import bak.pcj.map.NoSuchMappingException;
29 import bak.pcj.set.CharSet;
30 import bak.pcj.util.Exceptions;
31
32 import java.util.Map JavaDoc;
33 import java.util.Iterator JavaDoc;
34
35 /**
36  * This class represents adaptions of Java Collections Framework
37  * maps to primitive maps from char values to byte values.
38  * The adapter is implemented as a wrapper around the map.
39  * Thus, changes to the underlying map are reflected by this
40  * map and vice versa.
41  *
42  * <p>
43  * Adapters from JCF maps to primitive map will
44  * fail if the JCF collection contains <tt>null</tt> keys/values or
45  * keys/values of the wrong class. However, adapters are not fast
46  * failing in the case that the underlying map should
47  * contain illegal keys or values. To implement fast failure would require
48  * every operation to check every key and value of the underlying
49  * map before doing anything. Instead validation methods
50  * are provided. They can be called using the assertion facility
51  * in the client code:
52  * <pre>
53  * MapToCharKeyByteMapAdapter s;
54  * ...
55  * <b>assert</b> s.validate();
56  * </pre>
57  * or by letting the adapter throw an exception on illegal values:
58  * <pre>
59  * MapToCharKeyByteMapAdapter s;
60  * ...
61  * s.evalidate(); // Throws an exception on illegal values
62  * </pre>
63  * Either way, validation must be invoked directly by the client
64  * code.
65  *
66  * @author S&oslash;ren Bak
67  * @version 1.3 21-08-2003 19:09
68  * @since 1.0
69  */

70 public class MapToCharKeyByteMapAdapter extends AbstractCharKeyByteMap implements CharKeyByteMap {
71
72     /** The underlying map. */
73     protected Map map;
74
75     /** The value corresponding to the last key found by containsKey(). */
76     protected Byte JavaDoc lastValue;
77
78     /**
79      * Creates a new adaption to a map from char
80      * values to byte values.
81      *
82      * @param map
83      * the underlying map. This map must
84      * consist of keys of class
85      * {@link Character Character}.
86      * values of class
87      * {@link Byte Byte}. Otherwise a
88      * {@link ClassCastException ClassCastException}
89      * will be thrown by some methods.
90      *
91      * @throws NullPointerException
92      * if <tt>map</tt> is <tt>null</tt>.
93      */

94     public MapToCharKeyByteMapAdapter(Map map) {
95         if (map == null)
96             Exceptions.nullArgument("map");
97         this.map = map;
98         lastValue = null;
99     }
100
101     /**
102      * Creates a new adaption to a map from char
103      * values to byte values. The map to adapt is optionally validated.
104      *
105      * @param map
106      * the underlying map. This map must
107      * consist of keys of class
108      * {@link Character Character}.
109      * values of class
110      * {@link Byte Byte}. Otherwise a
111      * {@link ClassCastException ClassCastException}
112      * will be thrown by some methods.
113      *
114      * @param validate
115      * indicates whether <tt>map</tt> should
116      * be checked for illegal values.
117      *
118      * @throws NullPointerException
119      * if <tt>map</tt> is <tt>null</tt>.
120      *
121      * @throws IllegalStateException
122      * if <tt>validate</tt> is <tt>true</tt> and
123      * <tt>map</tt> contains a <tt>null</tt> key/value,
124      * a key that is not of class
125      * {@link Character Character},
126      * or a value that is not of class
127      * {@link Byte Byte}.
128      */

129     public MapToCharKeyByteMapAdapter(Map map, boolean validate) {
130         if (map == null)
131             Exceptions.nullArgument("map");
132         this.map = map;
133         lastValue = null;
134         if (validate)
135             evalidate();
136     }
137
138     public void clear()
139     { map.clear(); }
140
141     public boolean containsKey(char key) {
142         lastValue = (Byte JavaDoc)map.get(new Character JavaDoc(key));
143         return lastValue != null;
144     }
145
146     public boolean containsValue(byte value)
147     { return map.containsValue(new Byte JavaDoc(value)); }
148
149     public CharKeyByteMapIterator entries() {
150         return new CharKeyByteMapIterator() {
151             Iterator i = map.entrySet().iterator();
152             Map.Entry lastEntry = null;
153
154             public boolean hasNext()
155             { return i.hasNext(); }
156
157             public void next()
158             { lastEntry = (Map.Entry)i.next(); }
159
160             public char getKey() {
161                 if (lastEntry == null)
162                     Exceptions.noElementToGet();
163                 return ((Character JavaDoc)lastEntry.getKey()).charValue();
164             }
165
166             public byte getValue() {
167                 if (lastEntry == null)
168                     Exceptions.noElementToGet();
169                 return ((Byte JavaDoc)lastEntry.getValue()).byteValue();
170             }
171
172             public void remove() {
173                 i.remove();
174                 lastEntry = null;
175             }
176         };
177     }
178
179     public byte get(char key) {
180         Byte JavaDoc value = (Byte JavaDoc)map.get(new Character JavaDoc(key));
181         return value == null ? MapDefaults.defaultByte() : value.byteValue();
182     }
183
184     public CharSet keySet()
185     { return new SetToCharSetAdapter(map.keySet()); }
186
187     public byte lget() {
188         if (lastValue == null)
189             Exceptions.noLastElement();
190         return lastValue.byteValue();
191     }
192
193     public byte put(char key, byte value) {
194         Byte JavaDoc oldValue = (Byte JavaDoc)map.put(new Character JavaDoc(key), new Byte JavaDoc(value));
195         return oldValue == null ? MapDefaults.defaultByte() : oldValue.byteValue();
196     }
197
198     public byte remove(char key) {
199         Byte JavaDoc value = (Byte JavaDoc)map.remove(new Character JavaDoc(key));
200         return value == null ? MapDefaults.defaultByte() : value.byteValue();
201     }
202
203     public int size()
204     { return map.size(); }
205
206     public ByteCollection values()
207     { return new CollectionToByteCollectionAdapter(map.values()); }
208
209     public byte tget(char key) {
210         Byte JavaDoc value = (Byte JavaDoc)map.get(new Character JavaDoc(key));
211         if (value == null)
212             Exceptions.noSuchMapping(String.valueOf(key));
213         return value.byteValue();
214     }
215
216     /**
217      * Indicates whether the underlying map is valid for
218      * this adapter. For the underlying map to be valid, it
219      * can only contain {@link Character Character} keys, no <tt>null</tt>
220      * keys/values, and only {@link Byte Byte} values.
221      *
222      * @return <tt>true</tt> if the underlying map is
223      * valid; returns <tt>false</tt> otherwise.
224      */

225     public boolean validate()
226     { return Adapter.isCharKeyByteAdaptable(map); }
227
228     /**
229      * Validates the map underlying this adapter and throws
230      * an exception if it is invalid. For the underlying map
231      * to be valid, it
232      * can only contain {@link Character Character} keys, no <tt>null</tt>
233      * keys/values, and only {@link Byte Byte} values.
234      *
235      * @throws IllegalStateException
236      * if the underlying map is invalid.
237      */

238     public void evalidate() {
239         if (!validate())
240             Exceptions.cannotAdapt("map");
241     }
242
243 }
Popular Tags