KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > slide > store > impl > rdbms > JDBCStore


1 /*
2  * $Header: /home/cvs/jakarta-slide/src/stores/org/apache/slide/store/impl/rdbms/JDBCStore.java,v 1.22.2.1 2004/10/01 15:20:07 unico Exp $
3  * $Revision: 1.22.2.1 $
4  * $Date: 2004/10/01 15:20:07 $
5  *
6  * ====================================================================
7  *
8  * Copyright 1999-2002 The Apache Software Foundation
9  *
10  * Licensed under the Apache License, Version 2.0 (the "License");
11  * you may not use this file except in compliance with the License.
12  * You may obtain a copy of the License at
13  *
14  * http://www.apache.org/licenses/LICENSE-2.0
15  *
16  * Unless required by applicable law or agreed to in writing, software
17  * distributed under the License is distributed on an "AS IS" BASIS,
18  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
19  * See the License for the specific language governing permissions and
20  * limitations under the License.
21  *
22  */

23
24 package org.apache.slide.store.impl.rdbms;
25
26 import java.sql.Connection JavaDoc;
27 import java.sql.Driver JavaDoc;
28 import java.sql.DriverManager JavaDoc;
29 import java.sql.SQLException JavaDoc;
30 import java.util.Hashtable JavaDoc;
31
32 import org.apache.commons.dbcp.DriverManagerConnectionFactory;
33 import org.apache.commons.dbcp.PoolableConnectionFactory;
34 import org.apache.commons.dbcp.PoolingDriver;
35 import org.apache.commons.pool.impl.GenericObjectPool;
36 import org.apache.slide.common.NamespaceAccessToken;
37 import org.apache.slide.common.ServiceInitializationFailedException;
38 import org.apache.slide.common.ServiceParameterErrorException;
39 import org.apache.slide.common.ServiceParameterMissingException;
40 import org.apache.slide.store.ContentStore;
41 import org.apache.slide.store.LockStore;
42 import org.apache.slide.store.NodeStore;
43 import org.apache.slide.store.RevisionDescriptorStore;
44 import org.apache.slide.store.RevisionDescriptorsStore;
45 import org.apache.slide.store.SecurityStore;
46 import org.apache.slide.util.logger.Logger;
47
48 /**
49  * Store implementation that is able to store all information (like structure,
50  * locks and content) in a JDBC-aware relational database system. As this
51  * implementation only uses a single connection to the database, it does not
52  * work properly in production environments that require simultaneous access by
53  * multiple clients.
54  *
55  * @version $Revision: 1.22.2.1 $
56  */

57 public class JDBCStore
58     extends AbstractRDBMSStore
59     implements LockStore, NodeStore, RevisionDescriptorsStore, RevisionDescriptorStore, SecurityStore, ContentStore {
60
61     public static final String JavaDoc DBCP_URL = "jdbc:apache:commons:dbcp";
62
63     public static final String JavaDoc TRANSACTION_NONE = "NONE";
64     public static final String JavaDoc TRANSACTION_READ_UNCOMMITTED = "READ_UNCOMMITTED";
65     public static final String JavaDoc TRANSACTION_READ_COMMITTED = "READ_COMMITTED";
66     public static final String JavaDoc TRANSACTION_REPEATABLE_READ = "REPEATABLE_READ";
67     public static final String JavaDoc TRANSACTION_SERIALIZABLE = "SERIALIZABLE";
68
69     public static final int DEFAUT_ISOLATION_LEVEL = Connection.TRANSACTION_READ_COMMITTED;
70
71     protected static String JavaDoc isolationLevelToString(int isolationLevel) {
72         String JavaDoc levelString;
73         switch (isolationLevel) {
74             case Connection.TRANSACTION_NONE :
75                 levelString = TRANSACTION_NONE;
76                 break;
77             case Connection.TRANSACTION_READ_UNCOMMITTED :
78                 levelString = TRANSACTION_READ_UNCOMMITTED;
79                 break;
80             case Connection.TRANSACTION_READ_COMMITTED :
81                 levelString = TRANSACTION_READ_COMMITTED;
82                 break;
83             case Connection.TRANSACTION_REPEATABLE_READ :
84                 levelString = TRANSACTION_REPEATABLE_READ;
85                 break;
86             case Connection.TRANSACTION_SERIALIZABLE :
87                 levelString = TRANSACTION_SERIALIZABLE;
88                 break;
89             default :
90                 levelString = "UNKNOWN";
91                 break;
92         }
93         return levelString;
94
95     }
96
97     protected static int stringToIsolationLevelToString(String JavaDoc levelString) {
98         if (TRANSACTION_NONE.equals(levelString)) {
99             return Connection.TRANSACTION_NONE;
100         } else if (TRANSACTION_READ_UNCOMMITTED.equals(levelString)) {
101             return Connection.TRANSACTION_READ_UNCOMMITTED;
102         } else if (TRANSACTION_READ_COMMITTED.equals(levelString)) {
103             return Connection.TRANSACTION_READ_COMMITTED;
104         } else if (TRANSACTION_REPEATABLE_READ.equals(levelString)) {
105             return Connection.TRANSACTION_REPEATABLE_READ;
106         } else if (TRANSACTION_SERIALIZABLE.equals(levelString)) {
107             return Connection.TRANSACTION_SERIALIZABLE;
108         } else {
109             return -1;
110         }
111     }
112
113     // ----------------------------------------------------- Instance Variables
114

115     /**
116      * Driver class name.
117      */

118     protected String JavaDoc driver;
119
120     /**
121      * Connection URL.
122      */

123     protected String JavaDoc url;
124
125     /**
126      * User name.
127      */

128     protected String JavaDoc user = "";
129
130     /**
131      * Password.
132      */

133     protected String JavaDoc password = "";
134
135     protected boolean useDbcpPooling = false;
136
137     protected String JavaDoc dbcpPoolName = "dbcpPool" + System.identityHashCode(this);
138
139     protected int maxPooledConnections = -1;
140
141     protected int isolationLevel = DEFAUT_ISOLATION_LEVEL;
142
143     // -------------------------------------------------------- Service Methods
144

145     /**
146      * Initializes the data source with a set of parameters.
147      *
148      * @param parameters a Hashtable containing the parameters' name and
149      * associated value
150      * @exception ServiceParameterErrorException a service parameter holds an
151      * invalid value
152      * @exception ServiceParameterMissingException a required parameter is
153      * missing
154      */

155     public void setParameters(Hashtable JavaDoc parameters)
156         throws ServiceParameterErrorException, ServiceParameterMissingException {
157
158         String JavaDoc value;
159
160         // Driver classname
161
value = (String JavaDoc) parameters.get("driver");
162         if (value == null) {
163             throw new ServiceParameterMissingException(this, "driver");
164         } else {
165             driver = value;
166         }
167
168         // Connection url
169
value = (String JavaDoc) parameters.get("url");
170         if (value == null) {
171             throw new ServiceParameterMissingException(this, "url");
172         } else {
173             url = value;
174         }
175
176         // User name
177
value = (String JavaDoc) parameters.get("user");
178         if (value != null) {
179             user = value;
180         }
181
182         // Password
183
value = (String JavaDoc) parameters.get("password");
184         if (value != null) {
185             password = value;
186         }
187
188         value = (String JavaDoc) parameters.get("isolation");
189         if (value != null) {
190             isolationLevel = stringToIsolationLevelToString(value);
191             if (isolationLevel == -1) {
192                 getLogger().log(
193                     "Could not set isolation level '"
194                         + value
195                         + "', allowed levels are "
196                         + TRANSACTION_NONE
197                         + ", "
198                         + TRANSACTION_READ_UNCOMMITTED
199                         + ", "
200                         + TRANSACTION_READ_COMMITTED
201                         + ", "
202                         + TRANSACTION_REPEATABLE_READ
203                         + ", "
204                         + TRANSACTION_SERIALIZABLE,
205                     LOG_CHANNEL,
206                     Logger.WARNING);
207                 isolationLevel = DEFAUT_ISOLATION_LEVEL;
208             }
209         }
210
211         value = (String JavaDoc) parameters.get("dbcpPooling");
212         if (value != null) {
213             useDbcpPooling = "true".equals(value);
214         }
215
216         if (useDbcpPooling) {
217             value = (String JavaDoc) parameters.get("maxPooledConnections");
218             if (value != null) {
219                 try {
220                     maxPooledConnections = Integer.parseInt(value);
221                 } catch (NumberFormatException JavaDoc nfe) {
222                     getLogger().log(
223                         "Could not set maximum pooled connections, parameter must be integer",
224                         LOG_CHANNEL,
225                         Logger.WARNING);
226
227                 }
228             }
229         }
230
231         super.setParameters(parameters);
232     }
233
234     /**
235      * Initializes driver.
236      * <p/>
237      * Occurs in four steps :
238      * <li>Driver class is loaded</li>
239      * <li>Driver is instantiated</li>
240      * <li>Driver registration in the driver manager</li>
241      * <li>Creation of the basic tables, if they didn't exist before</li>
242      *
243      * @exception ServiceInitializationFailedException Throws an exception
244      * if the data source has already been initialized before
245      */

246     public synchronized void initialize(NamespaceAccessToken token) throws ServiceInitializationFailedException {
247
248         // XXX might be done already in setParameter
249
if (!alreadyInitialized) {
250             try {
251                 // Loading and registering driver
252
getLogger().log("Loading and registering driver '" + driver + "'", LOG_CHANNEL, Logger.INFO);
253                 Class JavaDoc driverClass = Class.forName(driver);
254                 Driver JavaDoc driverInstance = (Driver JavaDoc) driverClass.newInstance();
255
256                 String JavaDoc levelString = isolationLevelToString(isolationLevel);
257
258                 getLogger().log("Setting isolation level '" + levelString + "'", LOG_CHANNEL, Logger.INFO);
259
260                 // use DBCP pooling if enabled
261
if (useDbcpPooling) {
262                     getLogger().log("Using DBCP pooling", LOG_CHANNEL, Logger.INFO);
263                     GenericObjectPool connectionPool = new GenericObjectPool(null);
264                     if (maxPooledConnections != -1) {
265                         connectionPool.setMaxActive(maxPooledConnections);
266                     }
267                     getLogger().log(
268                         "Number of connections set to " + connectionPool.getMaxActive(),
269                         LOG_CHANNEL,
270                         Logger.INFO);
271
272                     DriverManagerConnectionFactory connectionFactory =
273                         new DriverManagerConnectionFactory(url, user, password);
274                     new PoolableConnectionFactory(
275                         connectionFactory,
276                         connectionPool,
277                         // TODO switching on pooling of prepared statements causes problems with closing of connections
278
// switched off for now
279
// new StackKeyedObjectPoolFactory(),
280
null,
281                         null,
282                         false,
283                         false,
284                         isolationLevel);
285                     PoolingDriver driver = new PoolingDriver();
286                     driver.registerPool(dbcpPoolName, connectionPool);
287                     // already done when loding PoolingDriver class
288
// DriverManager.registerDriver(driver);
289
} else {
290                     DriverManager.registerDriver(driverInstance);
291                     getLogger().log("Not using DBCP pooling", LOG_CHANNEL, Logger.WARNING);
292                 }
293             } catch (Exception JavaDoc e) {
294                 getLogger().log(
295                     "Loading and registering driver '" + driver + "' failed (" + e.getMessage() + ")",
296                     LOG_CHANNEL,
297                     Logger.ERROR);
298                 throw new ServiceInitializationFailedException(this, e);
299             } finally {
300                 alreadyInitialized = true;
301             }
302         }
303
304     }
305
306     protected Connection JavaDoc getNewConnection() throws SQLException JavaDoc {
307
308         Connection JavaDoc connection;
309         if (useDbcpPooling) {
310             try {
311                 connection = DriverManager.getConnection(DBCP_URL + ":" + dbcpPoolName);
312             } catch (SQLException JavaDoc e) {
313                 getLogger().log("Could not create connection. Reason: " + e, LOG_CHANNEL, Logger.EMERGENCY);
314                 throw e;
315             }
316         } else {
317             try {
318                 connection = DriverManager.getConnection(url, user, password);
319             } catch (SQLException JavaDoc e) {
320                 getLogger().log("Could not create connection. Reason: " + e, LOG_CHANNEL, Logger.EMERGENCY);
321                 throw e;
322             }
323
324             try {
325                 if (connection.getTransactionIsolation() != isolationLevel) {
326                     connection.setTransactionIsolation(isolationLevel);
327                 }
328             } catch (SQLException JavaDoc e) {
329                 getLogger().log(
330                     "Could not set isolation level '" + isolationLevelToString(isolationLevel) + "'. Reason: " + e,
331                     LOG_CHANNEL,
332                     Logger.WARNING);
333             }
334
335             if (connection.getAutoCommit()) {
336                 connection.setAutoCommit(false);
337             }
338
339         }
340
341         return connection;
342     }
343
344     protected boolean includeBranchInXid() {
345         return false;
346     }
347 }
348
Popular Tags