Author: snoopdave
Date: Tue May 22 11:25:36 2007
New Revision: 540679

URL: http://svn.apache.org/viewvc?view=rev&rev=540679
Log:
DatabaseProvider for JNDI and JDBC properties based config

Added:
    roller/trunk/src/org/apache/roller/business/DatabaseProvider.java
    
roller/trunk/src/org/apache/roller/business/hibernate/HibernateConnectionProvider.java
Modified:
    
roller/trunk/src/org/apache/roller/business/hibernate/HibernatePersistenceStrategy.java
    
roller/trunk/src/org/apache/roller/business/hibernate/HibernateRollerImpl.java
    roller/trunk/web/WEB-INF/classes/hibernate.cfg.xml
    roller/trunk/web/WEB-INF/classes/roller.properties
    roller/trunk/web/roller-ui/tools/dstest.jsp

Added: roller/trunk/src/org/apache/roller/business/DatabaseProvider.java
URL: 
http://svn.apache.org/viewvc/roller/trunk/src/org/apache/roller/business/DatabaseProvider.java?view=auto&rev=540679
==============================================================================
--- roller/trunk/src/org/apache/roller/business/DatabaseProvider.java (added)
+++ roller/trunk/src/org/apache/roller/business/DatabaseProvider.java Tue May 
22 11:25:36 2007
@@ -0,0 +1,121 @@
+package org.apache.roller.business;
+
+import java.sql.Connection;
+import java.sql.DriverManager;
+import java.sql.SQLException;
+import java.util.Properties;
+import javax.naming.InitialContext;
+import javax.naming.NamingException;
+import javax.sql.DataSource;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.roller.RollerException;
+import org.apache.roller.config.RollerConfig;
+
+/**
+ * Encapsulates Roller database configuration via JDBC properties or JNDI.
+ *
+ * <p>Reads configuration properties from RollerConfig:</p>
+ * <pre>
+ * # Specify database configuration type of 'jndi' or 'jdbc'
+ * database.configurationType=jndi
+ * 
+ * # For database configuration type 'jndi',this will be used
+ * database.jndi.name=jdbc/rollerdb
+ * 
+ * # For database configuration type of 'jdbc', you MUST override these
+ * database.jdbc.driverClass=
+ * database.jdbc.connectionURL=
+ * database.jdbc.username=
+ * database.jdbc.password=
+ * </pre>
+ */
+public class DatabaseProvider  {
+    private static Log log = LogFactory.getLog(DatabaseProvider.class);
+    private enum ConfigurationType {JNDI_NAME, JDBC_PROPERTIES;}
+    
+    private static DatabaseProvider singletonInstance = null;
+    
+    private DataSource dataSource = null;
+    
+    private ConfigurationType type = ConfigurationType.JNDI_NAME; 
+    
+    private String jndiName = null; 
+    
+    private String jdbcDriverClass = null;
+    private String jdbcConnectionURL = null;
+    private String jdbcPassword = null;
+    private String jdbcUsername = null;
+    private Properties props = null;
+   
+    /**
+     * Reads configuraiton, loads driver or locates data-source and attempts
+     * to get test connecton so that we can fail early.
+     */ 
+    private DatabaseProvider() throws RollerException {
+        String connectionTypeString = 
+                RollerConfig.getProperty("database.configurationType"); 
+        if ("jdbc".equals(connectionTypeString)) {
+            type = ConfigurationType.JDBC_PROPERTIES;
+        }
+        jndiName =          RollerConfig.getProperty("database.jndi.name");
+        jdbcDriverClass =   
RollerConfig.getProperty("database.jdbc.driverClass");
+        jdbcConnectionURL = 
RollerConfig.getProperty("database.jdbc.connectionURL");
+        jdbcUsername =      RollerConfig.getProperty("database.jdbc.username");
+        jdbcPassword =      RollerConfig.getProperty("database.jdbc.password");
+        
+        // init now so we fail early
+        if (type == ConfigurationType.JDBC_PROPERTIES) {
+            log.info("Using 'jdbc' properties based configuration");
+            try {
+                Class.forName(jdbcDriverClass);
+            } catch (ClassNotFoundException ex) {
+                throw new RollerException(
+                   "Cannot load specified JDBC driver class [" 
+jdbcDriverClass+ "]", ex);
+            }
+            if (jdbcUsername != null || jdbcPassword != null) {
+                props = new Properties();
+                if (jdbcUsername != null) props.put("user", jdbcUsername);
+                if (jdbcPassword != null) props.put("password", jdbcPassword);
+            }
+        } else {
+            log.info("Using 'jndi' based configuration");
+            String name = "java:comp/env/" + jndiName;
+            try {
+                InitialContext ic = new InitialContext();
+                dataSource = (DataSource)ic.lookup(name);
+            } catch (NamingException ex) {
+                throw new RollerException(
+                    "ERROR looking up data-source with JNDI name: " + name, 
ex);
+            }            
+        }
+        try { 
+            Connection testcon = getConnection();
+            testcon.close();
+        } catch (Throwable t) {
+            throw new RollerException("ERROR unable to obtain connection", t);
+        }
+    }
+    
+    /**
+     * Get global database provider singlton, instantiating if necessary.
+     */
+    public static DatabaseProvider getDatabaseProvider() throws 
RollerException {
+        if (singletonInstance == null) {
+            singletonInstance = new DatabaseProvider();
+        }
+        return singletonInstance;
+    }
+    
+    /**
+     * Get database connection from data-source or driver manager, depending 
+     * on which is configured.
+     */
+    public Connection getConnection() throws SQLException {
+        if (type == ConfigurationType.JDBC_PROPERTIES) {
+            return DriverManager.getConnection(jdbcConnectionURL, props);
+        } else {
+            return dataSource.getConnection();
+        }
+    } 
+}

Added: 
roller/trunk/src/org/apache/roller/business/hibernate/HibernateConnectionProvider.java
URL: 
http://svn.apache.org/viewvc/roller/trunk/src/org/apache/roller/business/hibernate/HibernateConnectionProvider.java?view=auto&rev=540679
==============================================================================
--- 
roller/trunk/src/org/apache/roller/business/hibernate/HibernateConnectionProvider.java
 (added)
+++ 
roller/trunk/src/org/apache/roller/business/hibernate/HibernateConnectionProvider.java
 Tue May 22 11:25:36 2007
@@ -0,0 +1,54 @@
+package org.apache.roller.business.hibernate;
+
+import java.sql.Connection;
+import java.sql.SQLException;
+import java.util.Properties;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.roller.RollerException;
+import org.apache.roller.business.DatabaseProvider;
+import org.hibernate.HibernateException;
+import org.hibernate.connection.ConnectionProvider;
+
+/**
+ * Allows use to provide Hibernate with database connections via Roller's
+ * DatabaseProvider class. By default HibernatePersistenceStrategy adds this 
+ * class to Hibernate's configuration. If you'd like to provide your own
+ * ConnctionProvider implementation you can do so by overriding Roller's 
+ * 'hibernate.connectionProvider' property with the classname of your impl.
+ */
+public class HibernateConnectionProvider implements ConnectionProvider {
+    private static Log log = 
LogFactory.getLog(HibernateConnectionProvider.class);
+    
+    /** No-op: we get our configuration from Roller's DatabaseProvider */
+    public void configure(Properties properties) throws HibernateException {
+        // no-op
+    }
+
+    /** Get connecetion from Roller's Database provider */
+    public Connection getConnection() throws SQLException {
+        try {
+            return DatabaseProvider.getDatabaseProvider().getConnection();
+        } catch (RollerException ex) {
+            // The DatabaseProvider should have been constructed long before 
+            // we get to this point, so this should never ever happen
+            throw new RuntimeException("ERROR getting database provider", ex);
+        }
+    }
+
+    /** Close connection by calling connection.close() */
+    public void closeConnection(Connection connection) throws SQLException {
+        connection.close();
+    }
+
+    /** No-op: no need to close Roller's DatabaseProvider */
+    public void close() throws HibernateException {
+        // no-op
+    }
+
+    /** Returns false, we don't support aggressive release */
+    public boolean supportsAggressiveRelease() {
+        return false;
+    }
+    
+}

Modified: 
roller/trunk/src/org/apache/roller/business/hibernate/HibernatePersistenceStrategy.java
URL: 
http://svn.apache.org/viewvc/roller/trunk/src/org/apache/roller/business/hibernate/HibernatePersistenceStrategy.java?view=diff&rev=540679&r1=540678&r2=540679
==============================================================================
--- 
roller/trunk/src/org/apache/roller/business/hibernate/HibernatePersistenceStrategy.java
 (original)
+++ 
roller/trunk/src/org/apache/roller/business/hibernate/HibernatePersistenceStrategy.java
 Tue May 22 11:25:36 2007
@@ -19,9 +19,7 @@
 package org.apache.roller.business.hibernate;
 
 import java.io.StringBufferInputStream;
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.List;
+import java.util.Properties;
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 import org.hibernate.HibernateException;
@@ -30,11 +28,8 @@
 import org.hibernate.Transaction;
 import org.hibernate.cfg.Configuration;
 import org.apache.roller.RollerException;
-import org.jdom.Attribute;
-import org.jdom.Document;
-import org.jdom.Element;
-import org.jdom.input.SAXBuilder;
-import org.jdom.output.DOMOutputter;
+import org.apache.roller.config.RollerConfig;
+import org.hibernate.cfg.Environment;
 import org.xml.sax.EntityResolver;
 import org.xml.sax.InputSource;
 
@@ -45,7 +40,6 @@
  * This class serves as a helper/util class for all of the Hibernate
  * manager implementations by providing a set of basic persistence methods
  * that can be easily reused.
- *
  */
 public class HibernatePersistenceStrategy {
     
@@ -62,133 +56,27 @@
         }
     };
     
-    
-    public HibernatePersistenceStrategy() {
-    }   
-
-    /** 
-     * Construct self using Hibernate config resource and optional dialect.
-     * @param configResouce Classpath-based path to Hibernate config file 
(e.g. "/hibernate.cgf.xml")
-     * @parma dialect Classname of Hibernate dialect to be used (overriding 
any specified in the configResource)
+    /**
+     * Persistence strategy configures itself by using Roller properties:
+     * 'hibernate.configResource' - the resource name of Roller's Hibernate 
XML configuration file, 
+     * 'hibernate.dialect' - the classname of the Hibernate dialect to be used,
+     * 'hibernate.connectionProvider - the classname of Roller's connnection 
provider impl.
      */
-    public HibernatePersistenceStrategy(
-            String configResource,
-            String dialect) throws Exception {
-
-        log.info("configResource: " + configResource);
-        log.info("dialect:        " + dialect);
-        
-        // read configResource into DOM form
-        SAXBuilder builder = new SAXBuilder();
-        builder.setEntityResolver(noOpEntityResolver); 
-        Document configDoc = builder.build(
-            getClass().getResourceAsStream(configResource));
-        Element root = configDoc.getRootElement();
-        Element sessionFactoryElem = root.getChild("session-factory");
-        
-        // remove any existing connection.datasource and dialect properties
-        List propertyElems = sessionFactoryElem.getChildren("property");
-        List removeList = new ArrayList();
-        for (Iterator it = propertyElems.iterator(); it.hasNext();) {
-            Element elem = (Element) it.next();
-            if (elem.getAttribute("name") != null 
-                && elem.getAttribute("name").getValue().equals("dialect")) {
-                removeList.add(elem);           
-            }
-        }
-        for (Iterator it = removeList.iterator(); it.hasNext();) {
-            Element elem = (Element) it.next();
-            sessionFactoryElem.removeContent(elem); 
-        }
-        
-        // add Roller dialect property      
-        Element prop = new Element("property").setAttribute(
-            new Attribute("name","dialect"));
-        prop.addContent(dialect);
-        sessionFactoryElem.addContent(prop);
+    public HibernatePersistenceStrategy() {
         
+        // Read Hibernate config file specified by Roller config
         Configuration config = new Configuration();
-        DOMOutputter outputter = new DOMOutputter();
-        config.configure(outputter.output(configDoc));
-        this.sessionFactory = config.buildSessionFactory(); 
-    }
-    
-    /** 
-     * Construct self using Hibernate config resource and optional dialect.
-     * @param configResouce Classpath-based path to Hibernate config file 
(e.g. "/hibernate.cgf.xml")
-     * @parma dialect Classname of Hibernate dialect to be used (or null to 
use one specified in configResource)
-     */
-    public HibernatePersistenceStrategy(
-            String configResource,
-            String dialect,
-            String driverClass,
-            String connectionURL,
-            String username,
-            String password) throws Exception {
-        
-        log.info("configResource: " + configResource);
-        log.info("dialect:        " + dialect);
-        log.info("driverClass:    " + driverClass);
-        log.info("connectionURL:  " + connectionURL);
-        log.info("username:       " + username);
-
-        // read configResource into DOM form
-        SAXBuilder builder = new SAXBuilder();
-        builder.setEntityResolver(noOpEntityResolver); 
-        Document configDoc = builder.build(
-            getClass().getResourceAsStream(configResource));
-        Element root = configDoc.getRootElement();
-        Element sessionFactoryElem = root.getChild("session-factory");
-        
-        // remove any existing connection.datasource and dialect properties
-        List propertyElems = sessionFactoryElem.getChildren("property");
-        List removeList = new ArrayList();
-        for (Iterator it = propertyElems.iterator(); it.hasNext();) {
-            Element elem = (Element) it.next();
-            if (elem.getAttribute("name") != null 
-                && 
elem.getAttribute("name").getValue().equals("connection.datasource")) {
-                removeList.add(elem);
-            }
-            if (elem.getAttribute("name") != null 
-                && elem.getAttribute("name").getValue().equals("dialect")) {
-                removeList.add(elem);
-            }
-        }
-        for (Iterator it = removeList.iterator(); it.hasNext();) {
-            Element elem = (Element) it.next();
-            sessionFactoryElem.removeContent(elem); 
-        }
-                                       
-        // add JDBC connection params instead
-        Element prop = new Element("property").setAttribute(
-            new Attribute("name","hibernate.connection.driver_class"));
-        prop.addContent(driverClass);
-        sessionFactoryElem.addContent(prop);
+        config.configure(RollerConfig.getProperty("hibernate.configResource"));
 
-        prop = new Element("property").setAttribute(
-            new Attribute("name","hibernate.connection.url"));
-        prop.addContent(connectionURL);
-        sessionFactoryElem.addContent(prop);
-        
-        prop = new Element("property").setAttribute(
-            new Attribute("name","hibernate.connection.username"));
-        prop.addContent(username);
-        sessionFactoryElem.addContent(prop);
-        
-        prop = new Element("property").setAttribute(
-            new Attribute("name","hibernate.connection.password"));
-        prop.addContent(password);
-        sessionFactoryElem.addContent(prop);
+        // Add dialect specified by Roller config and our connection provider
+        Properties props = new Properties();
+        props.put(Environment.DIALECT, 
+                RollerConfig.getProperty("hibernate.dialect"));
+        props.put(Environment.CONNECTION_PROVIDER, 
+                RollerConfig.getProperty("hibernate.connectionProvider"));
+        config.mergeProperties(props);
         
-        prop = new Element("property").setAttribute(
-            new Attribute("name","dialect"));
-        prop.addContent(dialect);
-        sessionFactoryElem.addContent(prop);
-        
-        Configuration config = new Configuration();
-        DOMOutputter outputter = new DOMOutputter();
-        config.configure(outputter.output(configDoc));
-        this.sessionFactory = config.buildSessionFactory();
+        this.sessionFactory = config.buildSessionFactory(); 
     }
     
     

Modified: 
roller/trunk/src/org/apache/roller/business/hibernate/HibernateRollerImpl.java
URL: 
http://svn.apache.org/viewvc/roller/trunk/src/org/apache/roller/business/hibernate/HibernateRollerImpl.java?view=diff&rev=540679&r1=540678&r2=540679
==============================================================================
--- 
roller/trunk/src/org/apache/roller/business/hibernate/HibernateRollerImpl.java 
(original)
+++ 
roller/trunk/src/org/apache/roller/business/hibernate/HibernateRollerImpl.java 
Tue May 22 11:25:36 2007
@@ -65,21 +65,7 @@
     
     protected HibernateRollerImpl() throws RollerException {
         try {
-            if 
(StringUtils.isNotEmpty(RollerConfig.getProperty("jdbc.driverClass"))) {
-                // create and configure for JDBC access
-                strategy = new HibernatePersistenceStrategy(
-                    RollerConfig.getProperty("hibernate.configResource"),
-                    RollerConfig.getProperty("hibernate.dialect"),
-                    RollerConfig.getProperty("jdbc.driverClass"),
-                    RollerConfig.getProperty("jdbc.connectionURL"),
-                    RollerConfig.getProperty("jdbc.username"),
-                    RollerConfig.getProperty("jdbc.password"));
-            } else {
-                // create an configure via config resource only
-                strategy = new HibernatePersistenceStrategy(
-                    RollerConfig.getProperty("hibernate.configResource"),
-                    RollerConfig.getProperty("hibernate.dialect"));
-            }
+            strategy = new HibernatePersistenceStrategy();
         } catch(Throwable t) {
             // if this happens then we are screwed
             mLogger.fatal("Error initializing Hibernate", t);

Modified: roller/trunk/web/WEB-INF/classes/hibernate.cfg.xml
URL: 
http://svn.apache.org/viewvc/roller/trunk/web/WEB-INF/classes/hibernate.cfg.xml?view=diff&rev=540679&r1=540678&r2=540679
==============================================================================
--- roller/trunk/web/WEB-INF/classes/hibernate.cfg.xml (original)
+++ roller/trunk/web/WEB-INF/classes/hibernate.cfg.xml Tue May 22 11:25:36 2007
@@ -21,12 +21,11 @@
         "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd";>
 <hibernate-configuration>
     <session-factory>
-        
-        <!-- You can override this via the jdbc.XXX properties in 
roller-custom.properties -->
-        <property 
name="connection.datasource">java:comp/env/jdbc/rollerdb</property>
                         
-        <!-- You can override this via the hibernate.dialect property in 
roller-custom.properties -->
-        <property name="dialect">org.hibernate.dialect.MySQLDialect</property>
+        <!-- 
+            Specify your Roller database configuration parameters
+            in your roller-custom.properties override file, not here.
+         -->
                        
         <property name="show_sql">false</property>
 

Modified: roller/trunk/web/WEB-INF/classes/roller.properties
URL: 
http://svn.apache.org/viewvc/roller/trunk/web/WEB-INF/classes/roller.properties?view=diff&rev=540679&r1=540678&r2=540679
==============================================================================
--- roller/trunk/web/WEB-INF/classes/roller.properties (original)
+++ roller/trunk/web/WEB-INF/classes/roller.properties Tue May 22 11:25:36 2007
@@ -43,9 +43,40 @@
 #---------------------------------
 # Database configuration settings
 
+# Specify database configuration type of 'jndi' or 'jdbc'
+database.configurationType=jndi
+
+# For database configuration type 'jndi',this will be used
+database.jndi.name=jdbc/rollerdb
+
+# For database configuration type of 'jdbc', you MUST override these
+database.jdbc.driverClass=
+database.jdbc.connectionURL=
+database.jdbc.username=
+database.jdbc.password=
+
+#---------------------------------
+# Mail server connection parameters
+
+# Specify mail configuration type of 'jndi' or 'properties'
+mail.configurationType=jndi
+
+# For mail configuration type 'jndi', this will be used
+mail.jndi.name=mail/Session
+
+# For database configuration type of 'properties', you MUST override these
+mail.hostname=
+mail.username
+mail.password
+
+#---------------------------------
 # Hibernate dialect: You MUST override this to use a database other than MySQL4
 hibernate.dialect=org.hibernate.dialect.MySQLDialect
 
+# No need to touch these two settings unless you are customizing Roller
+hibernate.connectionProvider=org.apache.roller.business.hibernate.HibernateConnectionProvider
+hibernate.configResource=/hibernate.cfg.xml
+
 #---------------------------------
 # User management settings
 
@@ -572,20 +603,6 @@
 
 # editor theme to be used (corresponds to directory name under /theme)
 editor.theme=tan
-
-# Hibernate config resource (a classpath-based path)
-# NO NEED TO OVERRIDE this unless you are customizing Roller
-hibernate.configResource=/hibernate.cfg.xml
-
-# JDBC configuration parameters for standalone tasks
-# Don't override these in the roller-custom.properties file you use with the 
-# Roller webapp, but for the standalone tasks that you run outside of Roller 
-# (e.g. refresh entries) you'll need to override these properties. Do it in a 
-# separate roller-custom.properties file.
-jdbc.driverClass=
-jdbc.connectionURL=
-jdbc.username=
-jdbc.password=
 
 #---------------------------------
 # Experimental settings

Modified: roller/trunk/web/roller-ui/tools/dstest.jsp
URL: 
http://svn.apache.org/viewvc/roller/trunk/web/roller-ui/tools/dstest.jsp?view=diff&rev=540679&r1=540678&r2=540679
==============================================================================
--- roller/trunk/web/roller-ui/tools/dstest.jsp (original)
+++ roller/trunk/web/roller-ui/tools/dstest.jsp Tue May 22 11:25:36 2007
@@ -19,12 +19,11 @@
     "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd";>
     
 <%-- simple test page to test your Roller datasource setup --%>
-<%@ page import="javax.naming.InitialContext" %>
-<%@ page import="javax.sql.DataSource" %>
+<%@ page import="org.apache.roller.business.DatabaseProvider" %>
 <%@ page import="java.sql.Connection" %>
 <html>
 <head>
-<title>Roller DataSource test</title>
+<title>Roller database configuration check</title>
 </head>
 <body>
 <p>
@@ -33,10 +32,8 @@
 Connection con = null;
 try
 {
-    InitialContext ic = new InitialContext();
-    DataSource ds = (DataSource)ic.lookup("java:comp/env/jdbc/rollerdb");
-    con = ds.getConnection();
-    msg = "SUCCESS: Got datasource and connection, class is 
"+ds.getClass().getName();
+    con = DatabaseProvider.getDatabaseProvider().getConnection();
+    msg = "SUCCESS: Able to get database connection";
 }
 catch (Exception e)
 {
@@ -47,7 +44,6 @@
 {
     if (con != null) con.close();
 }
-
 %>
 <%= msg %>
 </p>


Reply via email to