databasejournal.java

来自「jsr170接口的java实现。是个apache的开源项目。」· Java 代码 · 共 534 行 · 第 1/2 页

JAVA
534
字号
/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements.  See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License.  You may obtain a copy of the License at * *      http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */package org.apache.jackrabbit.core.journal;import org.apache.jackrabbit.name.NamespaceResolver;import org.apache.jackrabbit.util.Text;import org.slf4j.Logger;import org.slf4j.LoggerFactory;import java.io.IOException;import java.io.InputStream;import java.io.BufferedReader;import java.io.InputStreamReader;import java.sql.PreparedStatement;import java.sql.ResultSet;import java.sql.SQLException;import java.sql.Connection;import java.sql.DriverManager;import java.sql.DatabaseMetaData;import java.sql.Statement;/** * Database-based journal implementation. Stores records inside a database table named * <code>JOURNAL</code>, whereas the table <code>GLOBAL_REVISION</code> contains the * highest available revision number. These tables are located inside the schema specified * in <code>schemaObjectPrefix</code>. * <p/> * It is configured through the following properties: * <ul> * <li><code>revision</code>: the filename where the parent cluster node's revision * file should be written to; this is a required property with no default value</li> * <li><code>driver</code>: the JDBC driver class name to use; this is a required * property with no default value</li> * <li><code>url</code>: the JDBC connection url; this is a required property with * no default value </li> * <li><code>schema</code>: the schema to be used; if not specified, this is the * second field inside the JDBC connection url, delimeted by colons</li> * <li><code>schemaObjectPrefix</code>: the schema object prefix to be used; * defaults to an empty string</li> * <li><code>user</code>: username to specify when connecting</li> * <li><code>password</code>: password to specify when connecting</li> * </ul> */public class DatabaseJournal extends AbstractJournal {    /**     * Schema object prefix.     */    private static final String SCHEMA_OBJECT_PREFIX_VARIABLE =            "${schemaObjectPrefix}";    /**     * Default DDL script name.     */    private static final String DEFAULT_DDL_NAME = "default.ddl";    /**     * Logger.     */    private static Logger log = LoggerFactory.getLogger(DatabaseJournal.class);    /**     * Driver name, bean property.     */    private String driver;    /**     * Connection URL, bean property.     */    private String url;    /**     * Schema name, bean property.     */    private String schema;    /**     * Schema object prefix, bean property.     */    protected String schemaObjectPrefix;    /**     * User name, bean property.     */    private String user;    /**     * Password, bean property.     */    private String password;    /**     * JDBC Connection used.     */    private Connection con;    /**     * Statement returning all revisions within a range.     */    private PreparedStatement selectRevisionsStmt;    /**     * Statement updating the global revision.     */    private PreparedStatement updateGlobalStmt;    /**     * Statement returning the global revision.     */    private PreparedStatement selectGlobalStmt;    /**     * Statement appending a new record.     */    private PreparedStatement insertRevisionStmt;    /**     * Locked revision.     */    private long lockedRevision;    /**     * {@inheritDoc}     */    public void init(String id, NamespaceResolver resolver)            throws JournalException {        super.init(id, resolver);        if (driver == null) {            String msg = "Driver not specified.";            throw new JournalException(msg);        }        if (url == null) {            String msg = "Connection URL not specified.";            throw new JournalException(msg);        }        try {            if (schema == null) {                schema = getSchemaFromURL(url);            }            if (schemaObjectPrefix == null) {                schemaObjectPrefix = "";            }        } catch (IllegalArgumentException e) {            String msg = "Unable to derive schema from URL: " + e.getMessage();            throw new JournalException(msg);        }        try {            Class.forName(driver);            con = DriverManager.getConnection(url, user, password);            con.setAutoCommit(true);            checkSchema();            prepareStatements();        } catch (Exception e) {            String msg = "Unable to initialize connection.";            throw new JournalException(msg, e);        }        log.info("DatabaseJournal initialized at URL: " + url);    }    /**     * Derive a schema from a JDBC connection URL. This simply treats the given URL     * as delimeted by colons and takes the 2nd field.     *     * @param url JDBC connection URL     * @return schema     * @throws IllegalArgumentException if the JDBC connection URL is invalid     */    private String getSchemaFromURL(String url) throws IllegalArgumentException {        int start = url.indexOf(':');        if (start != -1) {            int end = url.indexOf(':', start + 1);            if (end != -1) {                return url.substring(start + 1, end);            }        }        throw new IllegalArgumentException(url);    }    /**     * {@inheritDoc}     */    protected RecordIterator getRecords(long startRevision)            throws JournalException {        try {            selectRevisionsStmt.clearParameters();            selectRevisionsStmt.clearWarnings();            selectRevisionsStmt.setLong(1, startRevision);            selectRevisionsStmt.execute();            return new DatabaseRecordIterator(                    selectRevisionsStmt.getResultSet(), getResolver());        } catch (SQLException e) {            String msg = "Unable to return record iterater.";            throw new JournalException(msg, e);        }    }    /**     * {@inheritDoc}     * <p/>     * This journal is locked by incrementing the current value in the table     * named <code>GLOBAL_REVISION</code>, which effectively write-locks this     * table. The updated value is then saved away and remembered in the     * appended record, because a save may entail multiple appends (JCR-884).     */    protected void doLock() throws JournalException {        ResultSet rs = null;        boolean succeeded = false;        try {            con.setAutoCommit(false);        } catch (SQLException e) {            String msg = "Unable to set autocommit to false.";            throw new JournalException(msg, e);        }        try {            updateGlobalStmt.clearParameters();            updateGlobalStmt.clearWarnings();            updateGlobalStmt.execute();            selectGlobalStmt.clearParameters();            selectGlobalStmt.clearWarnings();            selectGlobalStmt.execute();            rs = selectGlobalStmt.getResultSet();            if (!rs.next()) {                 throw new JournalException("No revision available.");            }            lockedRevision = rs.getLong(1);            succeeded = true;        } catch (SQLException e) {            String msg = "Unable to lock global revision table.";            throw new JournalException(msg, e);        } finally {            close(rs);            if (!succeeded) {                rollback(con);                try {                    con.setAutoCommit(true);                } catch (SQLException e) {                    String msg = "Unable to set autocommit to true.";                    log.warn(msg, e);                }            }        }    }

⌨️ 快捷键说明

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