File Source: DatabaseProvider.java
1 /*
2 * Licensed to the Apache Software Foundation (ASF) under one or more
3 * contributor license agreements. The ASF licenses this file to You
4 * under the Apache License, Version 2.0 (the "License"); you may not
5 * use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License. For additional information regarding
15 * copyright in this work, please see the NOTICE file in the top level
16 * directory of this distribution.
17 */
18
19 package org.apache.roller.weblogger.business;
20
21 import java.sql.Connection;
22 import java.sql.DriverManager;
23 import java.sql.SQLException;
24 import java.util.ArrayList;
25 import java.util.List;
26 import java.util.Properties;
27 import javax.naming.InitialContext;
28 import javax.naming.NamingException;
29 import javax.sql.DataSource;
30 import org.apache.commons.logging.Log;
31 import org.apache.commons.logging.LogFactory;
32 import org.apache.roller.weblogger.WebloggerException;
33 import org.apache.roller.weblogger.business.startup.StartupException;
34 import org.apache.roller.weblogger.config.WebloggerConfig;
35
36
37 /**
38 * Encapsulates Roller database configuration via JDBC properties or JNDI.
39 *
40 * <p>To keep the logs from filling up with DB connection errors, will only
41 * attempt to connect once.</p>
42 *
43 * <p>Keeps startup exception and log so we can present useful debugging
44 * information to whoever is installing Roller.</p>
45 *
46 *
47 * <p>Reads configuration properties from WebloggerConfig:</p>
48 * <pre>
49 * # Specify database configuration type of 'jndi' or 'jdbc'
50 * database.configurationType=jndi
51 *
52 * # For database configuration type 'jndi',this will be used
53 * database.jndi.name=jdbc/rollerdb
54 *
55 * # For database configuration type of 'jdbc', you MUST override these
56 * database.jdbc.driverClass=
57 * database.jdbc.connectionURL=
58 * database.jdbc.username=
59 * database.jdbc.password=
60 * </pre>
61 */
62 public class DatabaseProvider {
63
/*
P/P * Method: org.apache.roller.weblogger.business.DatabaseProvider__static_init
*
* Postconditions:
* init'ed(log)
*/
64 private static Log log = LogFactory.getLog(DatabaseProvider.class);
65
/*
P/P * Method: org.apache.roller.weblogger.business.DatabaseProvider$ConfigurationType__static_init
*
* Postconditions:
* $VALUES == &new DatabaseProvider$ConfigurationType[](DatabaseProvider$ConfigurationType__static_init#3)
* JDBC_PROPERTIES == &new DatabaseProvider$ConfigurationType(DatabaseProvider$ConfigurationType__static_init#2)
* $VALUES[1] == &new DatabaseProvider$ConfigurationType(DatabaseProvider$ConfigurationType__static_init#2)
* JNDI_NAME == &new DatabaseProvider$ConfigurationType(DatabaseProvider$ConfigurationType__static_init#1)
* $VALUES[0] == &new DatabaseProvider$ConfigurationType(DatabaseProvider$ConfigurationType__static_init#1)
* new DatabaseProvider$ConfigurationType(DatabaseProvider$ConfigurationType__static_init#1) num objects == 1
* new DatabaseProvider$ConfigurationType(DatabaseProvider$ConfigurationType__static_init#2) num objects == 1
* new DatabaseProvider$ConfigurationType[](DatabaseProvider$ConfigurationType__static_init#3) num objects == 1
* $VALUES.length == 2
*/
66 public enum ConfigurationType {JNDI_NAME, JDBC_PROPERTIES;}
67 private ConfigurationType type = ConfigurationType.JNDI_NAME;
68 private List<String> startupLog = new ArrayList<String>();
69
70 private DataSource dataSource = null;
71 private String jndiName = null;
72
73 private String jdbcDriverClass = null;
74 private String jdbcConnectionURL = null;
75 private String jdbcPassword = null;
76 private String jdbcUsername = null;
77 private Properties props = null;
78
79
80 /**
81 * Reads configuraiton, loads driver or locates data-source and attempts
82 * to get test connecton so that we can fail early.
83 */
/*
P/P * Method: void org.apache.roller.weblogger.business.DatabaseProvider()
*
* Preconditions:
* log != null
* org/apache/roller/weblogger/config/WebloggerConfig.config != null
* org/apache/roller/weblogger/config/WebloggerConfig.log != null
*
* Presumptions:
* javax.naming.InitialContext:lookup(...)@128 != null
* this.dataSource != null
* this.props != null
*
* Postconditions:
* (soft) this.dataSource != null
* init'ed(this.jdbcConnectionURL)
* init'ed(this.jdbcDriverClass)
* init'ed(this.jdbcPassword)
* init'ed(this.jdbcUsername)
* init'ed(this.jndiName)
* (soft) this.props != null
* this.startupLog == &new ArrayList(DatabaseProvider#1)
* this.type in Addr_Set{&org.apache.roller.weblogger.business.DatabaseProvider$ConfigurationType__static_init.new DatabaseProvider$ConfigurationType(DatabaseProvider$ConfigurationType__static_init#1),&org.apache.roller.weblogger.business.DatabaseProvider$ConfigurationType__static_init.new DatabaseProvider$ConfigurationType(DatabaseProvider$ConfigurationType__static_init#2)}
* new ArrayList(DatabaseProvider#1) num objects == 1
* ...
*
* Test Vectors:
* java.lang.String:equals(...)@88: {0}, {1}
*/
84 public DatabaseProvider() throws StartupException {
85
86 String connectionTypeString =
87 WebloggerConfig.getProperty("database.configurationType");
88 if ("jdbc".equals(connectionTypeString)) {
89 type = ConfigurationType.JDBC_PROPERTIES;
90 }
91 jndiName = WebloggerConfig.getProperty("database.jndi.name");
92 jdbcDriverClass = WebloggerConfig.getProperty("database.jdbc.driverClass");
93 jdbcConnectionURL = WebloggerConfig.getProperty("database.jdbc.connectionURL");
94 jdbcUsername = WebloggerConfig.getProperty("database.jdbc.username");
95 jdbcPassword = WebloggerConfig.getProperty("database.jdbc.password");
96
97 successMessage("SUCCESS: Got parameters. Using configuration type " + type);
98
99 // If we're doing JDBC then attempt to load JDBC driver class
100 if (getType() == ConfigurationType.JDBC_PROPERTIES) {
101 successMessage("-- Using JDBC driver class: " + jdbcDriverClass);
102 successMessage("-- Using JDBC connection URL: " + jdbcConnectionURL);
103 successMessage("-- Using JDBC username: " + jdbcUsername);
104 successMessage("-- Using JDBC password: [hidden]");
105 try {
106 Class.forName(getJdbcDriverClass());
107 } catch (ClassNotFoundException ex) {
108 String errorMsg =
109 "ERROR: cannot load JDBC driver class [" + getJdbcDriverClass()+ "]. "
110 +"Likely problem: JDBC driver jar missing from server classpath.";
111 errorMessage(errorMsg);
112 throw new StartupException(errorMsg, ex, startupLog);
113 }
114 successMessage("SUCCESS: loaded JDBC driver class [" +getJdbcDriverClass()+ "]");
115
116 if (getJdbcUsername() != null || getJdbcPassword() != null) {
117 props = new Properties();
118 if (getJdbcUsername() != null) props.put("user", getJdbcUsername());
119 if (getJdbcPassword() != null) props.put("password", getJdbcPassword());
120 }
121
122 // Else attempt to locate JNDI datasource
123 } else {
124 String name = "java:comp/env/" + getJndiName();
125 successMessage("-- Using JNDI datasource name: " + name);
126 try {
127 InitialContext ic = new InitialContext();
128 dataSource = (DataSource)ic.lookup(name);
129 } catch (NamingException ex) {
130 String errorMsg =
131 "ERROR: cannot locate JNDI DataSource [" +name+ "]. "
132 +"Likely problem: no DataSource or datasource is misconfigured.";
133 errorMessage(errorMsg);
134 throw new StartupException(errorMsg, ex, startupLog);
135 }
136 successMessage("SUCCESS: located JNDI DataSource [" +name+ "]");
137 }
138
139 // So far so good. Now, can we get a connection?
140 try {
141 Connection testcon = getConnection();
+ 142 testcon.close();
143 } catch (Throwable t) {
144 String errorMsg =
145 "ERROR: unable to obtain database connection. "
146 +"Likely problem: bad connection parameters or database unavailable.";
147 errorMessage(errorMsg);
148 throw new StartupException(errorMsg, t, startupLog);
149 }
150 }
151
152
153 private void successMessage(String msg) {
/*
P/P * Method: void successMessage(String)
*
* Preconditions:
* log != null
* this.startupLog != null
*/
154 startupLog.add(msg);
155 log.info(msg);
156 }
157
158 private void errorMessage(String msg) {
/*
P/P * Method: void errorMessage(String)
*
* Preconditions:
* log != null
* this.startupLog != null
*/
159 startupLog.add(msg);
160 log.error(msg);
161 }
162
163
164 /**
165 * List of success and error messages when class was first instantiated.
166 **/
167 public List<String> getStartupLog() {
/*
P/P * Method: List getStartupLog()
*
* Preconditions:
* init'ed(this.startupLog)
*
* Postconditions:
* return_value == this.startupLog
* init'ed(return_value)
*/
168 return startupLog;
169 }
170
171 /**
172 * Get database connection from data-source or driver manager, depending
173 * on which is configured.
174 */
175 public Connection getConnection() throws SQLException {
/*
P/P * Method: Connection getConnection()
*
* Preconditions:
* init'ed(this.type)
* (soft) this.dataSource != null
* (soft) init'ed(this.jdbcConnectionURL)
* (soft) this.props != null
* (soft) this.props._tainted == 0
*
* Postconditions:
* init'ed(return_value)
*/
176 if (getType() == ConfigurationType.JDBC_PROPERTIES) {
177 return DriverManager.getConnection(getJdbcConnectionURL(), props);
178 } else {
179 return dataSource.getConnection();
180 }
181 }
182
183 public ConfigurationType getType() {
/*
P/P * Method: DatabaseProvider$ConfigurationType getType()
*
* Preconditions:
* init'ed(this.type)
*
* Postconditions:
* return_value == this.type
* init'ed(return_value)
*/
184 return type;
185 }
186
187 public String getJndiName() {
/*
P/P * Method: String getJndiName()
*
* Preconditions:
* init'ed(this.jndiName)
*
* Postconditions:
* return_value == this.jndiName
* init'ed(return_value)
*/
188 return jndiName;
189 }
190
191 public String getJdbcDriverClass() {
/*
P/P * Method: String getJdbcDriverClass()
*
* Preconditions:
* init'ed(this.jdbcDriverClass)
*
* Postconditions:
* return_value == this.jdbcDriverClass
* init'ed(return_value)
*/
192 return jdbcDriverClass;
193 }
194
195 public String getJdbcConnectionURL() {
/*
P/P * Method: String getJdbcConnectionURL()
*
* Preconditions:
* init'ed(this.jdbcConnectionURL)
*
* Postconditions:
* return_value == this.jdbcConnectionURL
* init'ed(return_value)
*/
196 return jdbcConnectionURL;
197 }
198
199 public String getJdbcPassword() {
/*
P/P * Method: String getJdbcPassword()
*
* Preconditions:
* init'ed(this.jdbcPassword)
*
* Postconditions:
* return_value == this.jdbcPassword
* init'ed(return_value)
*/
200 return jdbcPassword;
201 }
202
203 public String getJdbcUsername() {
/*
P/P * Method: String getJdbcUsername()
*
* Preconditions:
* init'ed(this.jdbcUsername)
*
* Postconditions:
* return_value == this.jdbcUsername
* init'ed(return_value)
*/
204 return jdbcUsername;
205 }
206
207 }
SofCheck Inspector Build Version : 2.18479
| DatabaseProvider.java |
2009-Jan-02 14:24:54 |
| DatabaseProvider.class |
2009-Sep-04 03:12:30 |
| DatabaseProvider$ConfigurationType.class |
2009-Sep-04 03:12:30 |