KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > sleepycat > bind > serial > SerialBinding


1 /*-
2  * See the file LICENSE for redistribution information.
3  *
4  * Copyright (c) 2000,2006 Oracle. All rights reserved.
5  *
6  * $Id: SerialBinding.java,v 1.28 2006/10/30 21:14:07 bostic Exp $
7  */

8
9 package com.sleepycat.bind.serial;
10
11 import java.io.IOException JavaDoc;
12
13 import com.sleepycat.bind.EntryBinding;
14 import com.sleepycat.je.DatabaseEntry;
15 import com.sleepycat.util.FastInputStream;
16 import com.sleepycat.util.FastOutputStream;
17 import com.sleepycat.util.RuntimeExceptionWrapper;
18
19 /**
20  * A concrete <code>EntryBinding</code> that treats a key or data entry as
21  * a serialized object.
22  *
23  * <p>This binding stores objects in serialized object format. The
24  * deserialized objects are returned by the binding, and their
25  * <code>Class</code> must implement the <code>Serializable</code>
26  * interface.</p>
27  *
28  * <p>For key bindings, a tuple binding is usually a better choice than a
29  * serial binding. A tuple binding gives a reasonable sort order, and works
30  * with comparators in all cases -- see below.</p>
31  *
32  * <p><em>WARNING:</em> SerialBinding should not be used with Berkeley DB Java
33  * Edition for key bindings, when a custom comparator is used. In JE,
34  * comparators are instantiated and called internally at times when databases
35  * are not accessible. Because serial bindings depend on the class catalog
36  * database, a serial binding cannot be used during these times. An attempt
37  * to use a serial binding with a custom comparator will result in a
38  * NullPointerException during environment open or close.</p>
39  *
40  * @author Mark Hayes
41  */

42 public class SerialBinding extends SerialBase implements EntryBinding {
43
44     private ClassCatalog classCatalog;
45     private Class JavaDoc baseClass;
46
47     /**
48      * Creates a serial binding.
49      *
50      * @param classCatalog is the catalog to hold shared class information and
51      * for a database should be a {@link StoredClassCatalog}.
52      *
53      * @param baseClass is the base class for serialized objects stored using
54      * this binding -- all objects using this binding must be an instance of
55      * this class.
56      */

57     public SerialBinding(ClassCatalog classCatalog, Class JavaDoc baseClass) {
58
59         if (classCatalog == null) {
60             throw new NullPointerException JavaDoc("classCatalog must be non-null");
61         }
62         this.classCatalog = classCatalog;
63         this.baseClass = baseClass;
64     }
65
66     /**
67      * Returns the base class for this binding.
68      *
69      * @return the base class for this binding.
70      */

71     public final Class JavaDoc getBaseClass() {
72
73         return baseClass;
74     }
75
76     /**
77      * Returns the class loader to be used during deserialization, or null if
78      * a default class loader should be used. The default implementation of
79      * this method returns null.
80      *
81      * <p>This method may be overriden to return a dynamically determined class
82      * loader. For example,
83      * <code>Thread.currentThread().getContextClassLoader()</code> could be
84      * called to use the context class loader for the curren thread. Or
85      * <code>getBaseClass().getClassLoader()</code> could be called to use the
86      * class loader for the base class, assuming that a base class has been
87      * specified.</p>
88      *
89      * <p>If this method returns null, a default class loader will be used as
90      * determined by the <code>java.io.ObjectInputStream.resolveClass</code>
91      * method.</p>
92      */

93     public ClassLoader JavaDoc getClassLoader() {
94
95         return null;
96     }
97
98     /**
99      * Deserialize an object from an entry buffer. May only be called for data
100      * that was serialized using {@link #objectToEntry}, since the fixed
101      * serialization header is assumed to not be included in the input data.
102      * {@link SerialInput} is used to deserialize the object.
103      *
104      * @param entry is the input serialized entry.
105      *
106      * @return the output deserialized object.
107      */

108     public Object JavaDoc entryToObject(DatabaseEntry entry) {
109
110         int length = entry.getSize();
111         byte[] hdr = SerialOutput.getStreamHeader();
112         byte[] bufWithHeader = new byte[length + hdr.length];
113
114         System.arraycopy(hdr, 0, bufWithHeader, 0, hdr.length);
115         System.arraycopy(entry.getData(), entry.getOffset(),
116                          bufWithHeader, hdr.length, length);
117
118         try {
119             SerialInput jin = new SerialInput(
120                 new FastInputStream(bufWithHeader, 0, bufWithHeader.length),
121                 classCatalog,
122                 getClassLoader());
123             return jin.readObject();
124         } catch (IOException JavaDoc e) {
125             throw new RuntimeExceptionWrapper(e);
126         } catch (ClassNotFoundException JavaDoc e) {
127             throw new RuntimeExceptionWrapper(e);
128         }
129     }
130
131     /**
132      * Serialize an object into an entry buffer. The fixed serialization
133      * header is not included in the output data to save space, and therefore
134      * to deserialize the data the complementary {@link #entryToObject} method
135      * must be used. {@link SerialOutput} is used to serialize the object.
136      *
137      * <p>Note that this method sets the DatabaseEntry offset property to a
138      * non-zero value and the size property to a value less than the length of
139      * the byte array.</p>
140      *
141      * @param object is the input deserialized object.
142      *
143      * @param entry is the output serialized entry.
144      *
145      * @throws IllegalArgumentException if the object is not an instance of the
146      * base class for this binding.
147      */

148     public void objectToEntry(Object JavaDoc object, DatabaseEntry entry) {
149
150         if (baseClass != null && !baseClass.isInstance(object)) {
151             throw new IllegalArgumentException JavaDoc(
152                         "Data object class (" + object.getClass() +
153                         ") not an instance of binding's base class (" +
154                         baseClass + ')');
155         }
156         FastOutputStream fo = getSerialOutput(object);
157         try {
158             SerialOutput jos = new SerialOutput(fo, classCatalog);
159             jos.writeObject(object);
160         } catch (IOException JavaDoc e) {
161             throw new RuntimeExceptionWrapper(e);
162         }
163
164         byte[] hdr = SerialOutput.getStreamHeader();
165         entry.setData(fo.getBufferBytes(), hdr.length,
166                      fo.getBufferLength() - hdr.length);
167     }
168 }
169
Popular Tags