databasefilesystem.java

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

JAVA
1,559
字号
/* * 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.fs.db;import org.apache.jackrabbit.core.fs.FileSystem;import org.apache.jackrabbit.core.fs.FileSystemException;import org.apache.jackrabbit.core.fs.FileSystemPathUtil;import org.apache.jackrabbit.core.fs.RandomAccessOutputStream;import org.apache.jackrabbit.util.Text;import org.apache.jackrabbit.util.TransientFileFactory;import org.slf4j.Logger;import org.slf4j.LoggerFactory;import javax.jcr.RepositoryException;import java.io.BufferedReader;import java.io.File;import java.io.FileOutputStream;import java.io.FilterInputStream;import java.io.FilterOutputStream;import java.io.IOException;import java.io.InputStream;import java.io.InputStreamReader;import java.io.OutputStream;import java.io.FileInputStream;import java.io.RandomAccessFile;import java.sql.Connection;import java.sql.DatabaseMetaData;import java.sql.PreparedStatement;import java.sql.ResultSet;import java.sql.SQLException;import java.sql.Statement;import java.util.ArrayList;import java.util.Iterator;import java.util.HashMap;/** * Base class for database file systems. This class contains common * functionality for database file system subclasses that normally differ only * in the way the database connection is acquired. Subclasses should override * the {@link #getConnection()} method to return the configured database * connection. * <p> * See the {@link DbFileSystem} for a detailed description of the available * configuration options and database behaviour. */public class DatabaseFileSystem implements FileSystem {    /**     * Logger instance     */    private static Logger log = LoggerFactory.getLogger(DbFileSystem.class);    protected static final String SCHEMA_OBJECT_PREFIX_VARIABLE =            "${schemaObjectPrefix}";    protected boolean initialized;    protected String schema;    protected String schemaObjectPrefix;    // initial size of buffer used to serialize objects    protected static final int INITIAL_BUFFER_SIZE = 8192;    // jdbc connection    protected Connection con;    // time to sleep in ms before a reconnect is attempted    protected static final int SLEEP_BEFORE_RECONNECT = 10000;    // the map of prepared statements (key: sql stmt, value: prepared stmt)    private HashMap preparedStatements = new HashMap();    // SQL statements    protected String selectExistSQL;    protected String selectFileExistSQL;    protected String selectFolderExistSQL;    protected String selectChildCountSQL;    protected String selectDataSQL;    protected String selectLastModifiedSQL;    protected String selectLengthSQL;    protected String selectFileNamesSQL;    protected String selectFolderNamesSQL;    protected String selectFileAndFolderNamesSQL;    protected String deleteFileSQL;    protected String deleteFolderSQL;    protected String insertFileSQL;    protected String insertFolderSQL;    protected String updateDataSQL;    protected String updateLastModifiedSQL;    protected String copyFileSQL;    protected String copyFilesSQL;    /**     * Default constructor     */    public DatabaseFileSystem() {        schema = "default";        schemaObjectPrefix = "";        initialized = false;    }    //----------------------------------------------------< setters & getters >    public String getSchemaObjectPrefix() {        return schemaObjectPrefix;    }    public void setSchemaObjectPrefix(String schemaObjectPrefix) {        // make sure prefix is all uppercase        this.schemaObjectPrefix = schemaObjectPrefix.toUpperCase();    }    public String getSchema() {        return schema;    }    public void setSchema(String schema) {        this.schema = schema;    }    //-------------------------------------------< java.lang.Object overrides >    /**     * {@inheritDoc}     */    public boolean equals(Object obj) {        if (this == obj) {            return true;        }        if (obj instanceof DatabaseFileSystem) {            DatabaseFileSystem other = (DatabaseFileSystem) obj;            if (((schema != null) ? schema.equals(other.schema) : other.schema == null)                    && ((schemaObjectPrefix != null) ? schemaObjectPrefix.equals(other.schemaObjectPrefix) : other.schemaObjectPrefix == null)) {                return true;            }        }        return false;    }    /**     * Returns zero to satisfy the Object equals/hashCode contract.     * This class is mutable and not meant to be used as a hash key.     *     * @return always zero     * @see Object#hashCode()     */    public int hashCode() {        return 0;    }    //-----------------------------------------------------------< FileSystem >    /**     * {@inheritDoc}     */    public void init() throws FileSystemException {        if (initialized) {            throw new IllegalStateException("already initialized");        }        try {            // setup jdbc connection            initConnection();            // make sure schemaObjectPrefix consists of legal name characters only            prepareSchemaObjectPrefix();            // check if schema objects exist and create them if necessary            checkSchema();            // build sql statements            buildSQLStatements();            // prepare statements            initPreparedStatements();            // finally verify that there's a file system root entry            verifyRootExists();            initialized = true;        } catch (Exception e) {            String msg = "failed to initialize file system";            log.error(msg, e);            throw new FileSystemException(msg, e);        }    }    /**     * {@inheritDoc}     */    public void close() throws FileSystemException {        if (!initialized) {            throw new IllegalStateException("not initialized");        }        try {            // close shared prepared statements            for (Iterator it = preparedStatements.values().iterator(); it.hasNext(); ) {                closeStatement((PreparedStatement) it.next());            }            preparedStatements.clear();            // close jdbc connection            closeConnection(con);        } catch (SQLException e) {            String msg = "error closing file system";            log.error(msg, e);            throw new FileSystemException(msg, e);        } finally {            initialized = false;        }    }    /**     * {@inheritDoc}     */    public void createFolder(String folderPath) throws FileSystemException {        if (!initialized) {            throw new IllegalStateException("not initialized");        }        FileSystemPathUtil.checkFormat(folderPath);        if (!exists(folderPath)) {            createDeepFolder(folderPath);        } else {            throw new FileSystemException("file system entry already exists: " + folderPath);        }    }    /**     * {@inheritDoc}     */    public void deleteFile(String filePath) throws FileSystemException {        if (!initialized) {            throw new IllegalStateException("not initialized");        }        FileSystemPathUtil.checkFormat(filePath);        String parentDir = FileSystemPathUtil.getParentDir(filePath);        String name = FileSystemPathUtil.getName(filePath);        int count = 0;        synchronized (deleteFileSQL) {            try {                Statement stmt = executeStmt(                        deleteFileSQL, new Object[]{parentDir, name});                count = stmt.getUpdateCount();            } catch (SQLException e) {                String msg = "failed to delete file: " + filePath;                log.error(msg, e);                throw new FileSystemException(msg, e);            }        }        if (count == 0) {            throw new FileSystemException("no such file: " + filePath);        }    }    /**     * {@inheritDoc}     */    public void deleteFolder(String folderPath) throws FileSystemException {        if (!initialized) {            throw new IllegalStateException("not initialized");        }        FileSystemPathUtil.checkFormat(folderPath);        if (folderPath.equals(FileSystem.SEPARATOR)) {            throw new FileSystemException("cannot delete root");        }        String parentDir = FileSystemPathUtil.getParentDir(folderPath);        String name = FileSystemPathUtil.getName(folderPath);        int count = 0;        synchronized (deleteFolderSQL) {            try {                Statement stmt = executeStmt(deleteFolderSQL, new Object[]{                        parentDir,                        name,                        folderPath,                        folderPath + FileSystem.SEPARATOR + "%"});                count = stmt.getUpdateCount();            } catch (SQLException e) {                String msg = "failed to delete folder: " + folderPath;                log.error(msg, e);                throw new FileSystemException(msg, e);            }        }        if (count == 0) {            throw new FileSystemException("no such folder: " + folderPath);        }    }    /**     * {@inheritDoc}     */    public boolean exists(String path) throws FileSystemException {        if (!initialized) {            throw new IllegalStateException("not initialized");        }        FileSystemPathUtil.checkFormat(path);        String parentDir = FileSystemPathUtil.getParentDir(path);        String name = FileSystemPathUtil.getName(path);        synchronized (selectExistSQL) {            ResultSet rs = null;            try {                Statement stmt = executeStmt(                        selectExistSQL, new Object[]{parentDir, name});                rs = stmt.getResultSet();                // a file system entry exists if the result set                // has at least one entry                return rs.next();            } catch (SQLException e) {                String msg = "failed to check existence of file system entry: " + path;                log.error(msg, e);                throw new FileSystemException(msg, e);            } finally {                closeResultSet(rs);            }        }    }    /**     * {@inheritDoc}     */    public boolean isFile(String path) throws FileSystemException {        if (!initialized) {            throw new IllegalStateException("not initialized");        }        FileSystemPathUtil.checkFormat(path);        String parentDir = FileSystemPathUtil.getParentDir(path);        String name = FileSystemPathUtil.getName(path);        synchronized (selectFileExistSQL) {            ResultSet rs = null;            try {                Statement stmt = executeStmt(                        selectFileExistSQL, new Object[]{parentDir, name});                rs = stmt.getResultSet();                // a file exists if the result set has at least one entry                return rs.next();            } catch (SQLException e) {                String msg = "failed to check existence of file: " + path;                log.error(msg, e);                throw new FileSystemException(msg, e);            } finally {                closeResultSet(rs);            }        }    }    /**     * {@inheritDoc}     */    public boolean isFolder(String path) throws FileSystemException {        if (!initialized) {            throw new IllegalStateException("not initialized");        }        FileSystemPathUtil.checkFormat(path);        String parentDir = FileSystemPathUtil.getParentDir(path);        String name = FileSystemPathUtil.getName(path);        synchronized (selectFolderExistSQL) {

⌨️ 快捷键说明

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