/*-
* See the file LICENSE for redistribution information.
*
* Copyright (c) 2000, 2010 Oracle and/or its affiliates. All rights reserved.
*
*/
package com.sleepycat.bind.serial;
import java.io.IOException;
import com.sleepycat.bind.EntryBinding;
import com.sleepycat.db.DatabaseEntry;
import com.sleepycat.util.FastInputStream;
import com.sleepycat.util.FastOutputStream;
import com.sleepycat.util.RuntimeExceptionWrapper;
/**
* A concrete EntryBinding
that treats a key or data entry as
* a serialized object.
*
*
This binding stores objects in serialized object format. The
* deserialized objects are returned by the binding, and their
* Class
must implement the Serializable
* interface.
For key bindings, a tuple binding is usually a better choice than a * serial binding. A tuple binding gives a reasonable sort order, and works * with comparators in all cases -- see below.
* *WARNING: SerialBinding should not be used with Berkeley DB Java * Edition for key bindings, when a custom comparator is used. In JE, * comparators are instantiated and called internally at times when databases * are not accessible. Because serial bindings depend on the class catalog * database, a serial binding cannot be used during these times. An attempt * to use a serial binding with a custom comparator will result in a * NullPointerException during environment open or close.
* * * *{@code SerialBinding} and other classes in this package use standard Java * serialization and all rules of Java serialization apply. This includes the * rules for class evolution. Once an instance of a class is stored, the class * must maintain its {@code serialVersionUID} and follow the rules defined in * the Java specification. To use a new incompatible version of a class, a * different {@link ClassCatalog} must be used or the class catalog database * must be truncated.
* *If more advanced class evolution features are required, consider using * the {@link com.sleepycat.persist.evolve Direct Persistence Layer}.
* * @author Mark Hayes */ public class SerialBindingThread.currentThread().getContextClassLoader()
to use the
* context class loader for the current thread.
*
* This method may be overridden to return a dynamically determined class
* loader. For example, getBaseClass().getClassLoader()
could
* be called to use the class loader for the base class, assuming that a
* base class has been specified.
If this method returns null, a default class loader will be used as
* determined by the java.io.ObjectInputStream.resolveClass
* method.
Note that this method sets the DatabaseEntry offset property to a * non-zero value and the size property to a value less than the length of * the byte array.
* * @param object is the input deserialized object. * * @param entry is the output serialized entry. * * @throws IllegalArgumentException if the object is not an instance of the * base class for this binding. */ public void objectToEntry(E object, DatabaseEntry entry) { if (baseClass != null && !baseClass.isInstance(object)) { throw new IllegalArgumentException ("Data object class (" + object.getClass() + ") not an instance of binding's base class (" + baseClass + ')'); } FastOutputStream fo = getSerialOutput(object); try { SerialOutput jos = new SerialOutput(fo, classCatalog); jos.writeObject(object); } catch (IOException e) { throw RuntimeExceptionWrapper.wrapIfNeeded(e); } byte[] hdr = SerialOutput.getStreamHeader(); entry.setData(fo.getBufferBytes(), hdr.length, fo.getBufferLength() - hdr.length); } }