001 /**
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements. See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License. You may obtain a copy of the License at
008 *
009 * http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017
018 package org.apache.geronimo.console.internaldb;
019
020 import java.sql.Connection;
021 import java.sql.DriverManager;
022 import java.sql.SQLException;
023 import java.util.HashMap;
024 import java.util.Iterator;
025
026 import javax.sql.DataSource;
027
028 import org.apache.commons.logging.Log;
029 import org.apache.commons.logging.LogFactory;
030 import org.apache.geronimo.gbean.AbstractName;
031 import org.apache.geronimo.gbean.AbstractNameQuery;
032 import org.apache.geronimo.kernel.KernelRegistry;
033 import org.apache.geronimo.kernel.repository.Artifact;
034 import org.apache.geronimo.kernel.repository.Version;
035
036 import org.apache.geronimo.derby.DerbySystemGBean;
037
038 /**
039 * A static class to handle retreiving connections. This class is built to
040 * handle lookups to the SystemDatabase as a special case. If a connection is
041 * requested for the SystemDatabase this class gets a DataSource from an admin
042 * object registered in the geronimo kernel otherwise the DataSource is looked
043 * up via JNDI.
044 *
045 * @version $Rev: 497248 $ $Date: 2007-01-17 18:42:34 -0500 (Wed, 17 Jan 2007) $
046 */
047 public class DerbyConnectionUtil {
048
049 private final static Log log = LogFactory.getLog(DerbyConnectionUtil.class);
050
051 public static final String CREATE_DB_PROP = ";create=true";
052
053 public static final String SHUTDOWN_DB_PROP = ";shutdown=true";
054
055 private static final int RDBMS_DERBY = 1;
056
057 private static final int RDBMS_MSSQL = 2;
058
059 private static final String SYSTEM_DB = "SYSTEMDATABASE";
060
061 private static final String DERBY_DRIVER = "org.apache.derby.jdbc.EmbeddedDriver";
062
063 private static final String PROTOCOL = "jdbc:derby:";
064
065 private static final String EMPTY_PROPS = "";
066
067 private static AbstractName SYSTEM_DATASOURCE_NAME = null;
068
069 static {
070 try {
071 log.debug("Looking up system datasource name...");
072
073 // look up the system data source name without using the version number
074 HashMap props = new HashMap();
075 props.put("name","SystemDatasource");
076 props.put("j2eeType","JCAManagedConnectionFactory");
077 Artifact systemDB = new Artifact("org.apache.geronimo.configs", "system-database", (Version)null, "car");
078 AbstractNameQuery query = new AbstractNameQuery(systemDB,props);
079 Iterator iter = KernelRegistry.getSingleKernel().listGBeans(query).iterator();
080
081 if (iter.hasNext()) {
082 SYSTEM_DATASOURCE_NAME = (AbstractName)iter.next();
083 log.debug("Using system datasource name: " + SYSTEM_DATASOURCE_NAME);
084 }
085 else {
086 log.warn("Failed to lookup system datasource name");
087 }
088 }
089 catch (Throwable t) {
090 //
091 // HACK: Log any errors which occur when this is loading...
092 // the system is not logging the full detail, which it should
093 // but for now lets show the details here
094 //
095 log.error("Failed to initialize", t);
096 throw new Error(t);
097 }
098 }
099
100 private static String derbyHome = null;
101
102 /**
103 * Get the Derby home directory path.
104 */
105 public static String getDerbyHome() {
106 if (derbyHome == null) {
107 try {
108 derbyHome = (String)KernelRegistry.getSingleKernel().getAttribute(DerbySystemGBean.class, "derbyHome");
109 }
110 catch (Exception e) {
111 throw new RuntimeException("Failed to query derbyHome", e);
112 }
113 }
114 return derbyHome;
115 }
116
117 /**
118 * Get database connection.
119 *
120 * @param dbName
121 * @return
122 * @throws SQLException
123 */
124 private static Connection getConnection(String dbName, String properties,
125 String protocol, String driver) throws SQLException {
126 try {
127 Class.forName(driver).newInstance();
128 } catch (Exception e) {
129 log.error("Problem loading driver class", e);
130 }
131 // If we are looking for the SystemDatabase get it from the kernel
132 // because it is not binded to our JNDI Context.
133 if (SYSTEM_DB.equalsIgnoreCase(dbName)) {
134 return getSystemDBConnection();
135 } else {
136 return DriverManager.getConnection(protocol + dbName + properties);
137 }
138 }
139
140 /**
141 * Get a connection to derby.
142 *
143 * @param dbName
144 * the name of the database to connect to.
145 * @param properties
146 * the properties to pass to the connection string.
147 * @return connection
148 */
149 public static Connection getDerbyConnection(String dbName, String properties)
150 throws SQLException {
151 return getConnection(dbName, properties, PROTOCOL, DERBY_DRIVER);
152 }
153
154 public static Connection getDerbyConnection(String dbName)
155 throws SQLException {
156 return getDerbyConnection(dbName, EMPTY_PROPS);
157 }
158
159 /**
160 * Get a connection to the SystemDatabase.
161 *
162 * @return
163 * @throws SQLException
164 */
165 public static Connection getSystemDBConnection() throws SQLException {
166 DataSource ds = null;
167 try {
168 ds = getDataSource(SYSTEM_DB);
169 return ds.getConnection();
170 } catch (Exception e) {
171 throw new SQLException(e.getMessage());
172 }
173 }
174
175 /**
176 * Get the datasource if dbName is == SYSTEM_DB, otherwise returns null.
177 *
178 * @param dbName
179 * @return datasource
180 */
181 public static DataSource getDataSource(String dbName) {
182 try {
183 if (SYSTEM_DATASOURCE_NAME!=null && SYSTEM_DB.equalsIgnoreCase(dbName)) {
184 return (DataSource) KernelRegistry.getSingleKernel().invoke(
185 SYSTEM_DATASOURCE_NAME, "$getResource");
186 }
187 } catch (Exception e) {
188 log.error("Problem getting datasource " + dbName, e);
189 }
190 return null;
191 }
192
193 }