⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 storedclasscatalog.java

📁 嵌入式数据库Berkeley DB-4.5.20源代码
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
/*- * See the file LICENSE for redistribution information. * * Copyright (c) 2000-2006 *      Oracle Corporation.  All rights reserved. * * $Id: StoredClassCatalog.java,v 12.4 2006/08/31 18:14:05 bostic Exp $ */package com.sleepycat.bind.serial;import java.io.ByteArrayInputStream;import java.io.ByteArrayOutputStream;import java.io.IOException;import java.io.ObjectInputStream;import java.io.ObjectOutputStream;import java.io.ObjectStreamClass;import java.io.Serializable;import java.math.BigInteger;import java.util.HashMap;import com.sleepycat.compat.DbCompat;import com.sleepycat.db.Cursor;import com.sleepycat.db.CursorConfig;import com.sleepycat.db.Database;import com.sleepycat.db.DatabaseConfig;import com.sleepycat.db.DatabaseEntry;import com.sleepycat.db.DatabaseException;import com.sleepycat.db.EnvironmentConfig;import com.sleepycat.db.LockMode;import com.sleepycat.db.OperationStatus;import com.sleepycat.db.Transaction;import com.sleepycat.util.RuntimeExceptionWrapper;import com.sleepycat.util.UtfOps;/** * A <code>ClassCatalog</code> that is stored in a <code>Database</code>. * * <p>A single <code>StoredClassCatalog</code> object is normally used along * with a set of databases that stored serialized objects.</p> * * @author Mark Hayes */public class StoredClassCatalog implements ClassCatalog {    /*     * Record types ([key] [data]):     *     * [0] [next class ID]     * [1 / class ID] [ObjectStreamClass (class format)]     * [2 / class name] [ClassInfo (has 8 byte class ID)]     */    private static final byte REC_LAST_CLASS_ID = (byte) 0;    private static final byte REC_CLASS_FORMAT = (byte) 1;    private static final byte REC_CLASS_INFO = (byte) 2;    private static final byte[] LAST_CLASS_ID_KEY = {REC_LAST_CLASS_ID};    private Database db;    private HashMap classMap;    private HashMap formatMap;    private LockMode writeLockMode;    private boolean cdbMode;    private boolean txnMode;    /**     * Creates a catalog based on a given database. To save resources, only a     * single catalog object should be used for each unique catalog database.     *     * @param database an open database to use as the class catalog.  It must     * be a BTREE database and must not allow duplicates.     *     * @throws DatabaseException if an error occurs accessing the database.     *     * @throws IllegalArgumentException if the database is not a BTREE database     * or if it configured to allow duplicates.     */    public StoredClassCatalog(Database database)        throws DatabaseException, IllegalArgumentException {        db = database;        DatabaseConfig dbConfig = db.getConfig();        EnvironmentConfig envConfig = db.getEnvironment().getConfig();        writeLockMode = (DbCompat.getInitializeLocking(envConfig) ||                         envConfig.getTransactional()) ? LockMode.RMW                                                       : LockMode.DEFAULT;        cdbMode = DbCompat.getInitializeCDB(envConfig);        txnMode = dbConfig.getTransactional();        if (!DbCompat.isTypeBtree(dbConfig)) {            throw new IllegalArgumentException(                    "The class catalog must be a BTREE database.");        }        if (DbCompat.getSortedDuplicates(dbConfig) ||            DbCompat.getUnsortedDuplicates(dbConfig)) {            throw new IllegalArgumentException(                    "The class catalog database must not allow duplicates.");        }        /*         * Create the class format and class info maps. Note that these are not         * synchronized, and therefore the methods that use them are         * synchronized.         */        classMap = new HashMap();        formatMap = new HashMap();        DatabaseEntry key = new DatabaseEntry(LAST_CLASS_ID_KEY);        DatabaseEntry data = new DatabaseEntry();        if (dbConfig.getReadOnly()) {            /* Check that the class ID record exists. */            OperationStatus status = db.get(null, key, data, null);            if (status != OperationStatus.SUCCESS) {                throw new IllegalStateException                    ("A read-only catalog database may not be empty");            }        } else {            /* Add the initial class ID record if it doesn't exist.  */            data.setData(new byte[1]); // zero ID            /* Use putNoOverwrite to avoid phantoms. */            db.putNoOverwrite(null, key, data);        }    }    // javadoc is inherited    public synchronized void close()        throws DatabaseException {        if (db != null) {            db.close();        }        db = null;        formatMap = null;        classMap = null;    }    // javadoc is inherited    public synchronized byte[] getClassID(ObjectStreamClass classFormat)        throws DatabaseException, ClassNotFoundException {        ClassInfo classInfo = getClassInfo(classFormat);        return classInfo.getClassID();    }    // javadoc is inherited    public synchronized ObjectStreamClass getClassFormat(byte[] classID)        throws DatabaseException, ClassNotFoundException {        return getClassFormat(classID, new DatabaseEntry());    }    /**     * Internal function for getting the class format.  Allows passing the     * DatabaseEntry object for the data, so the bytes of the class format can     * be examined afterwards.     */    private ObjectStreamClass getClassFormat(byte[] classID,					     DatabaseEntry data)        throws DatabaseException, ClassNotFoundException {        /* First check the map and, if found, add class info to the map. */        BigInteger classIDObj = new BigInteger(classID);        ObjectStreamClass classFormat =            (ObjectStreamClass) formatMap.get(classIDObj);        if (classFormat == null) {            /* Make the class format key. */            byte[] keyBytes = new byte[classID.length + 1];            keyBytes[0] = REC_CLASS_FORMAT;            System.arraycopy(classID, 0, keyBytes, 1, classID.length);            DatabaseEntry key = new DatabaseEntry(keyBytes);            /* Read the class format. */            OperationStatus status = db.get(null, key, data, LockMode.DEFAULT);            if (status != OperationStatus.SUCCESS) {                throw new ClassNotFoundException("Catalog class ID not found");            }            try {                ObjectInputStream ois =                    new ObjectInputStream(                        new ByteArrayInputStream(data.getData(),                                                 data.getOffset(),                                                 data.getSize()));                classFormat = (ObjectStreamClass) ois.readObject();            } catch (IOException e) {                throw new RuntimeExceptionWrapper(e);            }            /* Update the class format map. */            formatMap.put(classIDObj, classFormat);        }        return classFormat;    }    /**     * Get the ClassInfo for a given class name, adding it and its     * ObjectStreamClass to the database if they are not already present, and     * caching both of them using the class info and class format maps.  When a     * class is first loaded from the database, the stored ObjectStreamClass is     * compared to the current ObjectStreamClass loaded by the Java class     * loader; if they are different, a new class ID is assigned for the     * current format.     */    private ClassInfo getClassInfo(ObjectStreamClass classFormat)        throws DatabaseException, ClassNotFoundException {        /*         * First check for a cached copy of the class info, which if         * present always contains the class format object         */        String className = classFormat.getName();        ClassInfo classInfo = (ClassInfo) classMap.get(className);        if (classInfo != null) {            return classInfo;        } else {            /* Make class info key.  */            char[] nameChars = className.toCharArray();            byte[] keyBytes = new byte[1 + UtfOps.getByteLength(nameChars)];            keyBytes[0] = REC_CLASS_INFO;            UtfOps.charsToBytes(nameChars, 0, keyBytes, 1, nameChars.length);            DatabaseEntry key = new DatabaseEntry(keyBytes);            /* Read class info.  */            DatabaseEntry data = new DatabaseEntry();            OperationStatus status = db.get(null, key, data, LockMode.DEFAULT);            if (status != OperationStatus.SUCCESS) {                /*

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -