root/trunk/LogicMail/src/org/logicprobe/LogicMail/util/SerializableHashtable.java

Revision 155, 7.1 kB (checked in by octorian, 14 months ago)
Line 
1/*-
2 * Copyright (c) 2007, Derek Konigsberg
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * 1. Redistributions of source code must retain the above copyright
10 *    notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 *    notice, this list of conditions and the following disclaimer in the
13 *    documentation and/or other materials provided with the distribution.
14 * 3. Neither the name of the project nor the names of its
15 *    contributors may be used to endorse or promote products derived
16 *    from this software without specific prior written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
21 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
22 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
23 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
24 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
25 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
27 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
29 * OF THE POSSIBILITY OF SUCH DAMAGE.
30 */
31
32package org.logicprobe.LogicMail.util;
33
34import java.io.DataInputStream;
35import java.io.DataOutputStream;
36import java.io.IOException;
37import java.util.Enumeration;
38import java.util.Hashtable;
39
40/**
41 * Provides an implementation of java.util.Hashtable that implements
42 * the LogicMail.util.Serializable interface.
43 * The maximum number of items that can be stored is 1000.
44 * This limit exists so that the deserialization code can quickly
45 * handle data corruption that could result in a bad size value.
46 */
47public class SerializableHashtable extends Hashtable implements Serializable {
48    final private static int TYPE_NULL    = 0;
49    final private static int TYPE_BOOLEAN = 1;
50    final private static int TYPE_BYTE    = 2;
51    final private static int TYPE_CHAR    = 3;
52    final private static int TYPE_STRING  = 4;
53    final private static int TYPE_DOUBLE  = 5;
54    final private static int TYPE_FLOAT   = 6;
55    final private static int TYPE_INT     = 7;
56    final private static int TYPE_LONG    = 8;
57    final private static int TYPE_SHORT   = 9;
58
59    final private static int MAX_ITEMS = 1000;
60   
61    private long uniqueId;
62   
63    /**
64     * Creates a new instance of SerializableHashtable.
65     * This class only supports hash tables containing objects which
66     * wrap the various primitive types supported by DataOutputStream
67     * and DataInputStream.
68     */
69    public SerializableHashtable() {
70        super();
71        uniqueId = UniqueIdGenerator.getInstance().getUniqueId();
72    }
73
74    /**
75     * Creates a new instance of SerializableHashtable.
76     * This class only supports hash tables containing objects which
77     * wrap the various primitive types supported by DataOutputStream
78     * and DataInputStream.
79     *
80     * @param initialCapacity Initial capacity of the hashtable.
81     */
82    public SerializableHashtable(int initialCapacity) {
83        super(initialCapacity);
84        uniqueId = UniqueIdGenerator.getInstance().getUniqueId();
85    }
86   
87    private static void writeObject(DataOutputStream output, Object item) throws IOException {
88        if(item instanceof Boolean) {
89            output.write(TYPE_BOOLEAN);
90            output.writeBoolean(((Boolean)item).booleanValue());
91        }
92        else if(item instanceof Byte) {
93            output.write(TYPE_BYTE);
94            output.writeByte(((Byte)item).byteValue());
95        }
96        else if(item instanceof Character) {
97            output.write(TYPE_CHAR);
98            output.writeChar(((Character)item).charValue());
99        }
100        else if(item instanceof String) {
101            output.write(TYPE_STRING);
102            output.writeUTF(((String)item));
103        }
104        else if(item instanceof Double) {
105            output.write(TYPE_DOUBLE);
106            output.writeDouble(((Double)item).doubleValue());
107        }
108        else if(item instanceof Float) {
109            output.write(TYPE_FLOAT);
110            output.writeFloat(((Float)item).floatValue());
111        }
112        else if(item instanceof Integer) {
113            output.write(TYPE_INT);
114            output.writeInt(((Integer)item).intValue());
115        }
116        else if(item instanceof Long) {
117            output.write(TYPE_LONG);
118            output.writeLong(((Long)item).longValue());
119        }
120        else if(item instanceof Short) {
121            output.write(TYPE_SHORT);
122            output.writeShort(((Short)item).shortValue());
123        }
124        else {
125            output.write(TYPE_NULL);
126            output.write(0);
127        }
128    }
129
130    private static Object readObject(DataInputStream input) throws IOException {
131        int type = input.read();
132        switch(type) {
133            case TYPE_BOOLEAN:
134                return new Boolean(input.readBoolean());
135            case TYPE_BYTE:
136                return new Byte(input.readByte());
137            case TYPE_CHAR:
138                return new Character(input.readChar());
139            case TYPE_STRING:
140                return input.readUTF();
141            case TYPE_DOUBLE:
142                return new Double(input.readDouble());
143            case TYPE_FLOAT:
144                return new Float(input.readFloat());
145            case TYPE_INT:
146                return new Integer(input.readInt());
147            case TYPE_LONG:
148                return new Long(input.readLong());
149            case TYPE_SHORT:
150                return new Short(input.readShort());
151            case TYPE_NULL:
152                return null;
153            default:
154                return null;
155        }
156    }
157   
158    public void serialize(DataOutputStream output) throws IOException {
159        output.writeLong(uniqueId);
160        output.writeInt(this.size());
161        Enumeration e = this.keys();
162        Object key;
163        while(e.hasMoreElements()) {
164            key = e.nextElement();
165            writeObject(output, key);
166            writeObject(output, this.get(key));
167        }
168    }
169
170    public void deserialize(DataInputStream input) throws IOException {
171        this.clear();
172        uniqueId = input.readLong();
173        int size = input.readInt();
174        if(size > MAX_ITEMS) {
175            throw new IOException();
176        }
177        Object key;
178        Object value;
179        for(int i=0; i<size; i++) {
180            key = readObject(input);
181            value = readObject(input);
182            if(key != null && value != null) {
183                this.put(key, value);
184            }
185        }
186    }   
187
188    public long getUniqueId() {
189        return uniqueId;
190    }
191}
Note: See TracBrowser for help on using the browser.