Java tutorial
/* * Portions Copyright 2007-2008 Sun Microsystems, Inc. All rights reserved. */ /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. 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. For additional information regarding * copyright in this work, please see the NOTICE file in the top level * directory of this distribution. */ package com.sun.socialsite.business; import java.sql.Connection; import java.sql.DriverManager; import java.sql.SQLException; import java.util.ArrayList; import java.util.List; 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 com.sun.socialsite.business.startup.StartupException; import com.sun.socialsite.config.Config; /** * Encapsulates SocialSite database configuration via JDBC properties or JNDI. * * <p>To keep the logs from filling up with DB connection errors, will only * attempt to connect once.</p> * * <p>Keeps startup exception and log so we can present useful debugging * information to whomever is installing SocialSite.</p> * * * <p>Reads configuration properties from Config:</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/socialsitedb * * # 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); public enum ConfigurationType { JNDI_NAME, JDBC_PROPERTIES; } private ConfigurationType type = ConfigurationType.JNDI_NAME; private List<String> startupLog = new ArrayList<String>(); private DataSource dataSource = null; 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. */ public DatabaseProvider() throws StartupException { String connectionTypeString = Config.getProperty("database.configurationType"); if ("jdbc".equals(connectionTypeString)) { type = ConfigurationType.JDBC_PROPERTIES; } jndiName = Config.getProperty("database.jndi.name"); jdbcDriverClass = Config.getProperty("database.jdbc.driverClass"); jdbcConnectionURL = Config.getProperty("database.jdbc.connectionURL"); jdbcUsername = Config.getProperty("database.jdbc.username"); jdbcPassword = Config.getProperty("database.jdbc.password"); successMessage("SUCCESS: Got parameters. Using configuration type " + type); // If we're doing JDBC then attempt to load JDBC driver class if (getType() == ConfigurationType.JDBC_PROPERTIES) { successMessage("-- Using JDBC driver class: " + jdbcDriverClass); successMessage("-- Using JDBC connection URL: " + jdbcConnectionURL); successMessage("-- Using JDBC username: " + jdbcUsername); successMessage("-- Using JDBC password: [hidden]"); try { Class.forName(getJdbcDriverClass()); } catch (ClassNotFoundException ex) { String errorMsg = "ERROR: cannot load JDBC driver class [" + getJdbcDriverClass() + "]. " + "Likely problem: JDBC driver jar missing from server classpath."; errorMessage(errorMsg); throw new StartupException(errorMsg, ex, startupLog); } successMessage("SUCCESS: loaded JDBC driver class [" + getJdbcDriverClass() + "]"); if (getJdbcUsername() != null || getJdbcPassword() != null) { props = new Properties(); if (getJdbcUsername() != null) props.put("user", getJdbcUsername()); if (getJdbcPassword() != null) props.put("password", getJdbcPassword()); } // Else attempt to locate JNDI datasource } else { String name = "java:comp/env/" + getJndiName(); successMessage("-- Using JNDI datasource name: " + name); try { InitialContext ic = new InitialContext(); dataSource = (DataSource) ic.lookup(name); } catch (NamingException ex) { String errorMsg = "ERROR: cannot locate JNDI DataSource [" + name + "]. " + "Likely problem: no DataSource or datasource is misconfigured."; errorMessage(errorMsg); throw new StartupException(errorMsg, ex, startupLog); } successMessage("SUCCESS: located JNDI DataSource [" + name + "]"); } // So far so good. Now, can we get a connection? try { Connection testcon = getConnection(); testcon.close(); } catch (Throwable t) { String errorMsg = "ERROR: unable to obtain database connection. " + "Likely problem: bad connection parameters or database unavailable."; errorMessage(errorMsg); throw new StartupException(errorMsg, t, startupLog); } } private void successMessage(String msg) { startupLog.add(msg); log.info(msg); } private void errorMessage(String msg) { startupLog.add(msg); log.error(msg); } /** * List of success and error messages when class was first instantiated. **/ public List<String> getStartupLog() { return startupLog; } /** * Get database connection from data-source or driver manager, depending * on which is configured. */ public Connection getConnection() throws SQLException { if (getType() == ConfigurationType.JDBC_PROPERTIES) { return DriverManager.getConnection(getJdbcConnectionURL(), props); } else { return dataSource.getConnection(); } } public ConfigurationType getType() { return type; } public String getJndiName() { return jndiName; } public String getJdbcDriverClass() { return jdbcDriverClass; } public String getJdbcConnectionURL() { return jdbcConnectionURL; } public String getJdbcPassword() { return jdbcPassword; } public String getJdbcUsername() { return jdbcUsername; } }