Apache Jackrabbit : JNDI

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;