1 /***
2 * Copyright 2009 ATG DUST Project Licensed under the Apache License, Version
3 * 2.0 (the "License"); you may not use this file except in compliance with the
4 * License. You may obtain a copy of the License at
5 * http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law
6 * or agreed to in writing, software distributed under the License is
7 * distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
8 * KIND, either express or implied. See the License for the specific language
9 * governing permissions and limitations under the License.
10 */
11
12 package atg.service.jdbc;
13
14 import java.sql.DriverManager;
15 import java.sql.SQLException;
16
17 import org.apache.log4j.Logger;
18
19 import atg.nucleus.ServiceException;
20
21 /***
22 * <b>Experimental since Apache Derby is not supported by ATG 9.0.</b>
23 *
24 * This datasource is used for testing. It starts up a Derby in memory instance
25 * on localhost automatically. The database will be named "testdb" by default.
26 * If you need to name it something else set the "databaseName" property on this
27 * component. You may want to change the name if your test requires running two
28 * databases at the same time.
29 *
30 * @author adamb
31 * @version $Id:$
32 */
33
34 public class DerbyDataSource extends InitializingDataSourceBase {
35
36 static Logger sLog = Logger.getLogger(DerbyDataSource.class);
37
38 private String framework = "embedded";
39 private String driver = "org.apache.derby.jdbc.EmbeddedDriver";
40 private String protocol = "jdbc:derby:";
41 private boolean mAddedShutdownHook = false;
42
43 /***
44 * Sets Derby JDBC properties to be used when the first client asks for a
45 * connection.
46 */
47 @Override
48 public void doStartService() throws ServiceException {
49 logInfo("Starting DerbyDataSource.");
50 loadDriver();
51 this.setURL(protocol + getDatabaseName() + ";create=true");
52 this.setDriver(driver);
53 this.setUser("user1");
54 this.setPassword("user1");
55 }
56
57 /***
58 * Cleans up for dynamo shutdown
59 */
60 @Override
61 public void doStopService() throws ServiceException {
62
63
64
65
66 if (!mAddedShutdownHook)
67 addShutdownHook(getDatabaseName());
68 }
69
70 /***
71 * Adds a shutdown hook to shutdown Derby when the JVM exits.
72 *
73 * @param pDBName
74 *
75 */
76 private void addShutdownHook(String pDBName) {
77 final String name = pDBName;
78 Runtime.getRuntime().addShutdownHook(new Thread() {
79 public void run() {
80 DerbyDataSource.shutdown(name);
81 }
82 });
83 }
84
85 /***
86 * Shuts down derby
87 *
88 * @param name
89 */
90 private static void shutdown(String name) {
91 try {
92
93 DriverManager.getConnection("jdbc:derby:" + name + ";shutdown=true");
94
95
96
97
98
99
100 } catch (SQLException se) {
101
102 if (((se.getErrorCode() == 50000) && ("XJ015".equals(se.getSQLState())))) {
103
104 sLog.info("Derby shut down normally");
105
106
107 } else if ((se.getErrorCode() == 45000)
108 && ("08006".equals(se.getSQLState()))) {
109
110 } else {
111
112
113 sLog.error("Derby did not shut down normally", se);
114 printSQLException(se);
115 }
116 }
117
118 }
119
120 /***
121 * Prints details of an SQLException chain to <code>System.err</code>. Details
122 * included are SQL State, Error code, Exception message.
123 *
124 * @param e
125 * the SQLException from which to print details.
126 */
127 public static void printSQLException(SQLException e) {
128
129
130 while (e != null) {
131 System.err.println("\n----- SQLException -----");
132 System.err.println(" SQL State: " + e.getSQLState());
133 System.err.println(" Error Code: " + e.getErrorCode());
134 System.err.println(" Message: " + e.getMessage());
135
136
137 e = e.getNextException();
138 }
139 }
140
141 /***
142 * Loads the appropriate JDBC driver for this environment/framework. For
143 * example, if we are in an embedded environment, we load Derby's embedded
144 * Driver, <code>org.apache.derby.jdbc.EmbeddedDriver</code>.
145 */
146 private void loadDriver() {
147
148
149
150
151
152
153
154
155
156
157
158
159
160 try {
161 Class.forName(driver).newInstance();
162 } catch (ClassNotFoundException cnfe) {
163 sLog.error("\nUnable to load the JDBC driver " + driver);
164 sLog.error("Please check your CLASSPATH.");
165 cnfe.printStackTrace(System.err);
166 } catch (InstantiationException ie) {
167 sLog.error("\nUnable to instantiate the JDBC driver " + driver);
168 ie.printStackTrace(System.err);
169 } catch (IllegalAccessException iae) {
170 sLog.error("\nNot allowed to access the JDBC driver " + driver);
171 iae.printStackTrace(System.err);
172 }
173 }
174
175 }