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