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 }