001: /*-
002: * See the file LICENSE for redistribution information.
003: *
004: * Copyright (c) 2000,2008 Oracle. All rights reserved.
005: *
006: * $Id: SerialInput.java,v 1.18.2.2 2008/01/07 15:14:05 cwl Exp $
007: */
008:
009: package com.sleepycat.bind.serial;
010:
011: import java.io.IOException;
012: import java.io.InputStream;
013: import java.io.ObjectInputStream;
014: import java.io.ObjectStreamClass;
015:
016: import com.sleepycat.je.DatabaseException;
017: import com.sleepycat.util.RuntimeExceptionWrapper;
018:
019: /**
020: * A specialized <code>ObjectInputStream</code> that gets class description
021: * information from a <code>ClassCatalog</code>. It is used by
022: * <code>SerialBinding</code>.
023: *
024: * <p>This class is used instead of an {@link ObjectInputStream}, which it
025: * extends, to read an object stream written by the {@link SerialOutput} class.
026: * For reading objects from a database normally one of the serial binding
027: * classes is used. {@link SerialInput} is used when an {@link
028: * ObjectInputStream} is needed along with compact storage. A {@link
029: * ClassCatalog} must be supplied, however, to stored shared class
030: * descriptions.</p>
031: *
032: * @author Mark Hayes
033: */
034: public class SerialInput extends ObjectInputStream {
035:
036: private ClassCatalog classCatalog;
037: private ClassLoader classLoader;
038:
039: /**
040: * Creates a serial input stream.
041: *
042: * @param in is the input stream from which compact serialized objects will
043: * be read.
044: *
045: * @param classCatalog is the catalog containing the class descriptions
046: * for the serialized objects.
047: */
048: public SerialInput(InputStream in, ClassCatalog classCatalog)
049: throws IOException {
050:
051: this (in, classCatalog, null);
052: }
053:
054: /**
055: * Creates a serial input stream.
056: *
057: * @param in is the input stream from which compact serialized objects will
058: * be read.
059: *
060: * @param classCatalog is the catalog containing the class descriptions
061: * for the serialized objects.
062: *
063: * @param classLoader is the class loader to use, or null if a default
064: * class loader should be used.
065: */
066: public SerialInput(InputStream in, ClassCatalog classCatalog,
067: ClassLoader classLoader) throws IOException {
068:
069: super (in);
070:
071: this .classCatalog = classCatalog;
072: this .classLoader = classLoader;
073: }
074:
075: // javadoc is specified elsewhere
076: protected ObjectStreamClass readClassDescriptor()
077: throws IOException, ClassNotFoundException {
078:
079: try {
080: byte len = readByte();
081: byte[] id = new byte[len];
082: readFully(id);
083:
084: return classCatalog.getClassFormat(id);
085: } catch (DatabaseException e) {
086: /*
087: * Do not throw IOException from here since ObjectOutputStream
088: * will write the exception to the stream, which causes another
089: * call here, etc.
090: */
091: throw new RuntimeExceptionWrapper(e);
092: }
093: }
094:
095: // javadoc is specified elsewhere
096: protected Class resolveClass(ObjectStreamClass desc)
097: throws IOException, ClassNotFoundException {
098:
099: if (classLoader != null) {
100: try {
101: return Class
102: .forName(desc.getName(), false, classLoader);
103: } catch (ClassNotFoundException e) {
104: return super.resolveClass(desc);
105: }
106: } else {
107: return super.resolveClass(desc);
108: }
109: }
110: }
|