Patching the OracleFileSystem and OraclePersistenceManager for use with JNDI
This patch was created by rkorbee at 2006-12-04 16:54:41:
- Use this pacth in Eclipse against jackrabbit-core-1.1.1
- This will fix jackrabbit-core to support an Oracle database over JNDI
Index: /home/nick/workspace/jackrabbit/jackrabbit/src/main/java/org/apache/jackrabbit/core/fs/db/DatabaseFileSystem.java =================================================================== --- /home/nick/workspace/jackrabbit/jackrabbit/src/main/java/org/apache/jackrabbit/core/fs/db/DatabaseFileSystem.java (revision 480910) +++ /home/nick/workspace/jackrabbit/jackrabbit/src/main/java/org/apache/jackrabbit/core/fs/db/DatabaseFileSystem.java (working copy) @@ -1251,6 +1251,9 @@ throws FileSystemException { String parentDir = FileSystemPathUtil.getParentDir(folderPath); String name = FileSystemPathUtil.getName(folderPath); + if ("".equals(name)) { + name = " "; + } if (!FileSystemPathUtil.denotesRoot(folderPath)) { if (!exists(parentDir)) { Index: /home/nick/workspace/jackrabbit/jackrabbit/src/main/java/org/apache/jackrabbit/core/fs/db/DbFileSystem.java =================================================================== --- /home/nick/workspace/jackrabbit/jackrabbit/src/main/java/org/apache/jackrabbit/core/fs/db/DbFileSystem.java (revision 480910) +++ /home/nick/workspace/jackrabbit/jackrabbit/src/main/java/org/apache/jackrabbit/core/fs/db/DbFileSystem.java (working copy) @@ -182,7 +182,7 @@ * * @throws SQLException if an error occurs */ - protected Connection getConnection() throws ClassNotFoundException, SQLException { + protected Connection getConnection() throws Exception { Class.forName(driver); return DriverManager.getConnection(url, user, password); } Index: /home/nick/workspace/jackrabbit/jackrabbit/src/main/java/org/apache/jackrabbit/core/fs/db/JNDIOracleDatabaseFileSystem.java =================================================================== --- /home/nick/workspace/jackrabbit/jackrabbit/src/main/java/org/apache/jackrabbit/core/fs/db/JNDIOracleDatabaseFileSystem.java (revision 0) +++ /home/nick/workspace/jackrabbit/jackrabbit/src/main/java/org/apache/jackrabbit/core/fs/db/JNDIOracleDatabaseFileSystem.java (revision 0) @@ -0,0 +1,97 @@ +/* + * 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 java.sql.Connection; +import java.sql.SQLException; + +import javax.naming.InitialContext; +import javax.naming.NamingException; +import javax.sql.DataSource; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import oracle.jdbc.driver.OracleConnection; +import oracle.jdbc.pool.OracleDataSource; + +/** + * Database file system that uses JNDI to acquire the database connection. + * The JNDI location of the {@link OracleDataSource} to be used in given as + * the <code>dataSourceLocation</code> configuration property. See the + * {@link DbFileSystem} for more configuration details. + * <p> + * <strong>WARNING:</strong> The acquired database connection is kept + * for the entire lifetime of the file system instance. The configured data + * source should be prepared for this. + */ +public class JNDIOracleDatabaseFileSystem extends OracleFileSystem { + + private static Logger log = LoggerFactory.getLogger(JNDIOracleDatabaseFileSystem.class); + + /** + * JNDI location of the data source used to acquire database connections. + */ + private String dataSourceLocation; + + //----------------------------------------------------< setters & getters > + + /** + * Returns the JNDI location of the data source. + * + * @return data source location + */ + public String getDataSourceLocation() { + return dataSourceLocation; + } + + /** + * Sets the JNDI location of the data source. + * + * @param dataSourceLocation data source location + */ + public void setDataSourceLocation(String dataSourceLocation) { + this.dataSourceLocation = dataSourceLocation; + } + + //--------------------------------------------------< DatabaseFileSystem > + + /** + * Returns a JDBC connection from a {@link OracleDataSource} acquired from JNDI + * with the configured data source location. + * + * @return new database connection + * @throws NamingException if the given data source location does not exist + * @throws SQLException if a database access error occurs + * @throws ClassNotFoundException + */ + protected Connection getConnection() throws NamingException, SQLException, ClassNotFoundException { + Class.forName(super.driver); + InitialContext ic = new InitialContext(); + + DataSource originalDS = (DataSource) ic.lookup(dataSourceLocation); + log.debug("Type of datasource is: " + originalDS.getClass()); + + Connection conn = originalDS.getConnection(); + log.debug("Type of Connection is: " + conn.getClass()); + if (conn instanceof OracleConnection) { + return conn; + } else { + throw new ClassNotFoundException("Wrong type for Connection, expected OracleConnection, got: " + conn.getClass()); + } + } +} Property changes on: /home/nick/workspace/jackrabbit/jackrabbit/src/main/java/org/apache/jackrabbit/core/fs/db/JNDIOracleDatabaseFileSystem.java ___________________________________________________________________ Name: svn:eol-style + native Name: svn:keywords + Id Index: /home/nick/workspace/jackrabbit/jackrabbit/src/main/java/org/apache/jackrabbit/core/fs/db/OracleFileSystem.java =================================================================== --- /home/nick/workspace/jackrabbit/jackrabbit/src/main/java/org/apache/jackrabbit/core/fs/db/OracleFileSystem.java (revision 480910) +++ /home/nick/workspace/jackrabbit/jackrabbit/src/main/java/org/apache/jackrabbit/core/fs/db/OracleFileSystem.java (working copy) @@ -16,36 +16,30 @@ */ package org.apache.jackrabbit.core.fs.db; -import org.apache.jackrabbit.util.Text; -import org.apache.jackrabbit.util.TransientFileFactory; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.FilterOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.io.RandomAccessFile; +import java.sql.Blob; +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.SQLException; +import java.util.LinkedList; +import java.util.List; + +import oracle.sql.BLOB; + 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.TransientFileFactory; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import javax.jcr.RepositoryException; -import java.sql.DatabaseMetaData; -import java.sql.ResultSet; -import java.sql.Statement; -import java.sql.SQLException; -import java.sql.Blob; -import java.sql.Connection; -import java.sql.PreparedStatement; -import java.io.InputStream; -import java.io.BufferedReader; -import java.io.InputStreamReader; -import java.io.OutputStream; -import java.io.IOException; -import java.io.File; -import java.io.FilterOutputStream; -import java.io.FileOutputStream; -import java.io.FileInputStream; -import java.io.RandomAccessFile; -import java.util.List; -import java.util.LinkedList; -import java.lang.reflect.Method; - /** * <code>OracleFileSystem</code> is a JDBC-based <code>FileSystem</code> * implementation for Jackrabbit that persists file system entries in an @@ -415,7 +409,9 @@ stmt.executeUpdate(); } - } catch (Exception e) { + } catch (SQLException e) { + throw new IOException(e.getMessage()); + } catch (FileSystemException e) { throw new IOException(e.getMessage()); } finally { if (stmt != null) { @@ -469,28 +465,14 @@ /** * Creates a temporary oracle.sql.BLOB instance via reflection and spools * the contents of the specified stream. + * @throws SQLException + * @throws IOException */ - protected Blob createTemporaryBlob(InputStream in) throws Exception { - /* + protected Blob createTemporaryBlob(InputStream in) throws SQLException, IOException { BLOB blob = BLOB.createTemporary(con, false, BLOB.DURATION_SESSION); blob.open(BLOB.MODE_READWRITE); OutputStream out = blob.getBinaryOutputStream(); - ... - out.flush(); - out.close(); - blob.close(); - return blob; - */ - Method createTemporary = blobClass.getMethod("createTemporary", - new Class[]{Connection.class, Boolean.TYPE, Integer.TYPE}); - Object blob = createTemporary.invoke(null, - new Object[]{con, Boolean.FALSE, DURATION_SESSION_CONSTANT}); - Method open = blobClass.getMethod("open", new Class[]{Integer.TYPE}); - open.invoke(blob, new Object[]{MODE_READWRITE_CONSTANT}); - Method getBinaryOutputStream = - blobClass.getMethod("getBinaryOutputStream", new Class[0]); - OutputStream out = (OutputStream) getBinaryOutputStream.invoke(blob, null); - try { + try { int read; byte[] buf = new byte[8192]; while ((read = in.read(buf, 0, buf.length)) > -1) { @@ -503,9 +485,34 @@ } out.close(); } - Method close = blobClass.getMethod("close", new Class[0]); - close.invoke(blob, null); - return (Blob) blob; + blob.close(); + return blob; + +// Method createTemporary = blobClass.getMethod("createTemporary", +// new Class[]{Connection.class, Boolean.TYPE, Integer.TYPE}); +// Object blob = createTemporary.invoke(null, +// new Object[]{con, Boolean.FALSE, DURATION_SESSION_CONSTANT}); +// Method open = blobClass.getMethod("open", new Class[]{Integer.TYPE}); +// open.invoke(blob, new Object[]{MODE_READWRITE_CONSTANT}); +// Method getBinaryOutputStream = +// blobClass.getMethod("getBinaryOutputStream", new Class[0]); +// OutputStream out = (OutputStream) getBinaryOutputStream.invoke(blob, null); +// try { +// int read; +// byte[] buf = new byte[8192]; +// while ((read = in.read(buf, 0, buf.length)) > -1) { +// out.write(buf, 0, read); +// } +// } finally { +// try { +// out.flush(); +// } catch (IOException ioe) { +// } +// out.close(); +// } +// Method close = blobClass.getMethod("close", new Class[0]); +// close.invoke(blob, null); +// return (Blob) blob; } /** @@ -511,9 +518,10 @@ /** * Frees a temporary oracle.sql.BLOB instance via reflection. */ - protected void freeTemporaryBlob(Object blob) throws Exception { - // blob.freeTemporary(); - Method freeTemporary = blobClass.getMethod("freeTemporary", new Class[0]); - freeTemporary.invoke(blob, null); + protected void freeTemporaryBlob(Blob blob) throws Exception { + BLOB obj = (BLOB) blob; + obj.freeTemporary(); + //Method freeTemporary = blobClass.getMethod("freeTemporary", new Class[0]); + //freeTemporary.invoke(blob, null); } } Index: /home/nick/workspace/jackrabbit/jackrabbit/src/main/java/org/apache/jackrabbit/core/state/db/JNDIOracleDatabasePersistenceManager.java =================================================================== --- /home/nick/workspace/jackrabbit/jackrabbit/src/main/java/org/apache/jackrabbit/core/state/db/JNDIOracleDatabasePersistenceManager.java (revision 0) +++ /home/nick/workspace/jackrabbit/jackrabbit/src/main/java/org/apache/jackrabbit/core/state/db/JNDIOracleDatabasePersistenceManager.java (revision 0) @@ -0,0 +1,83 @@ +/* + * 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.state.db; + +import java.sql.Connection; +import java.sql.SQLException; + +import javax.naming.InitialContext; +import javax.naming.NamingException; +import javax.sql.DataSource; + +/** + * Database persistence manager that uses JNDI to acquire the database + * connection. The JNDI location of the {@link DataSource} to be used in + * given as the <code>dataSourceLocation</code> configuration property. + * See the {@link SimpleDbPersistenceManager} for more configuration + * details. + * <p> + * <strong>WARNING:</strong> The acquired database connection is kept + * for the entire lifetime of the persistence manager instance. The + * configured data source should be prepared for this. + */ +public class JNDIOracleDatabasePersistenceManager extends OraclePersistenceManager{ + + /** + * JNDI location of the data source used to acquire database connections. + */ + private String dataSourceLocation; + + //----------------------------------------------------< setters & getters > + + /** + * Returns the JNDI location of the data source. + * + * @return data source location + */ + public String getDataSourceLocation() { + return dataSourceLocation; + } + + /** + * Sets the JNDI location of the data source. + * + * @param dataSourceLocation data source location + */ + public void setDataSourceLocation(String dataSourceLocation) { + this.dataSourceLocation = dataSourceLocation; + } + + //-------------------------------------------< DatabasePersistenceManager > + + /** + * Returns a JDBC connection from a {@link DataSource} acquired from JNDI + * with the configured data source location. + * + * @return new database connection + * @throws NamingException if the given data source location does not exist + * @throws SQLException if a database access error occurs + * @throws ClassNotFoundException + * @see DatabasePersistenceManager#getConnection() + */ + protected Connection getConnection() throws NamingException, SQLException, ClassNotFoundException { + Class.forName(super.driver); + InitialContext ic = new InitialContext(); + DataSource dataSource = (DataSource) ic.lookup(dataSourceLocation); + return dataSource.getConnection(); + } + +} Property changes on: /home/nick/workspace/jackrabbit/jackrabbit/src/main/java/org/apache/jackrabbit/core/state/db/JNDIOracleDatabasePersistenceManager.java ___________________________________________________________________ Name: svn:eol-style + native Name: svn:keywords + Id Index: /home/nick/workspace/jackrabbit/jackrabbit/src/main/java/org/apache/jackrabbit/core/state/db/SimpleDbPersistenceManager.java =================================================================== --- /home/nick/workspace/jackrabbit/jackrabbit/src/main/java/org/apache/jackrabbit/core/state/db/SimpleDbPersistenceManager.java (revision 480910) +++ /home/nick/workspace/jackrabbit/jackrabbit/src/main/java/org/apache/jackrabbit/core/state/db/SimpleDbPersistenceManager.java (working copy) @@ -158,7 +158,7 @@ * @throws SQLException if a database access error occurs * @see DatabasePersistenceManager#getConnection() */ - protected Connection getConnection() throws ClassNotFoundException, SQLException { + protected Connection getConnection() throws Exception { Class.forName(driver); Connection connection = DriverManager.getConnection(url, user, password); return connection;