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 + -
显示快捷键?