View Javadoc

1   /*
2    * #%L
3    * ToPIA :: Persistence
4    * 
5    * $Id: TopiaConnectionProviderHardCoded.java 2706 2013-03-12 15:48:07Z echatellier $
6    * $HeadURL: http://svn.nuiton.org/svn/topia/tags/topia-2.8-rc-1/topia-persistence/src/test/java/org/nuiton/topia/framework/TopiaConnectionProviderHardCoded.java $
7    * %%
8    * Copyright (C) 2004 - 2011 CodeLutin
9    * %%
10   * This program is free software: you can redistribute it and/or modify
11   * it under the terms of the GNU Lesser General Public License as 
12   * published by the Free Software Foundation, either version 3 of the 
13   * License, or (at your option) any later version.
14   * 
15   * This program is distributed in the hope that it will be useful,
16   * but WITHOUT ANY WARRANTY; without even the implied warranty of
17   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18   * GNU General Lesser Public License for more details.
19   * 
20   * You should have received a copy of the GNU General Lesser Public 
21   * License along with this program.  If not, see
22   * <http://www.gnu.org/licenses/lgpl-3.0.html>.
23   * #L%
24   */
25  package org.nuiton.topia.framework;
26  
27  import java.sql.Connection;
28  import java.sql.DriverManager;
29  import java.sql.SQLException;
30  import java.util.ArrayList;
31  import java.util.Iterator;
32  import java.util.Map;
33  import java.util.Properties;
34  
35  import org.apache.commons.logging.Log;
36  import org.apache.commons.logging.LogFactory;
37  import org.hibernate.HibernateException;
38  import org.hibernate.cfg.Environment;
39  import org.hibernate.internal.util.ReflectHelper;
40  import org.hibernate.internal.util.config.ConfigurationHelper;
41  import org.hibernate.service.jdbc.connections.internal.ConnectionProviderInitiator;
42  import org.hibernate.service.jdbc.connections.internal.DriverManagerConnectionProviderImpl;
43  
44  /**
45   * Customized connection provider.
46   *
47   * @author tchemit <chemit@codelutin.com>
48   * @since 2.5.3
49   */
50  public class TopiaConnectionProviderHardCoded extends DriverManagerConnectionProviderImpl {
51  
52      private String url;
53  
54      private Properties connectionProps;
55  
56      private Integer isolation;
57  
58      private final ArrayList pool = new ArrayList();
59  
60      private int poolSize;
61  
62      private int checkedOut = 0;
63  
64      private boolean autocommit;
65  
66      /** Logger. */
67      private static final Log log =
68              LogFactory.getLog(TopiaConnectionProviderHardCoded.class);
69  
70      @Override
71      public void configure(Map configurationValues) throws HibernateException {
72          String driverClass = (String)configurationValues.get(Environment.DRIVER);
73  
74          poolSize = ConfigurationHelper.getInt(Environment.POOL_SIZE, configurationValues, 20); //default pool size 20
75          log.info("Using Hibernate built-in connection pool (not for production use!)");
76          log.info("Hibernate connection pool size: " + poolSize);
77  
78          autocommit = ConfigurationHelper.getBoolean(Environment.AUTOCOMMIT, configurationValues);
79          log.info("autocommit mode: " + autocommit);
80  
81          isolation = ConfigurationHelper.getInteger(Environment.ISOLATION, configurationValues);
82          if (isolation != null)
83              log.info("JDBC isolation level: " + Environment.isolationLevelToString(isolation));
84  
85          if (driverClass == null) {
86              log.warn("no JDBC Driver class was specified by property " + Environment.DRIVER);
87          } else {
88              try {
89                  // trying via forName() first to be as close to DriverManager's semantics
90                  Class.forName(driverClass);
91              } catch (ClassNotFoundException cnfe) {
92                  try {
93                      ReflectHelper.classForName(driverClass);
94                  } catch (ClassNotFoundException e) {
95                      String msg = "JDBC Driver class not found: " + driverClass;
96                      log.error(msg, e);
97                      throw new HibernateException(msg, e);
98                  }
99              }
100         }
101 
102         // use a dummy directory to make sure only the connection provider knows
103         // the real directory where db is and then make sure hibernate always
104         // use the connection provider...
105         String directory =
106                 (String)configurationValues.get(TopiaConnectionProviderTest.TEST_URL);
107 
108         url = directory;
109 //        url = props.getProperty(Environment.URL);
110 
111 //        if (url == null) {
112 //            String msg = "JDBC URL was not specified by property " + Environment.URL;
113 //            log.error(msg);
114 //            throw new HibernateException(msg);
115 //        }
116 
117         connectionProps = ConnectionProviderInitiator.getConnectionProperties(configurationValues);
118 
119         log.info("using driver: " + driverClass + " at URL: " + url);
120         // if debug level is enabled, then log the password, otherwise mask it
121         if (log.isDebugEnabled()) {
122             log.info("connection properties: " + connectionProps);
123         } else if (log.isInfoEnabled()) {
124             log.info("connection properties: " + ConfigurationHelper.maskOut(connectionProps, "password"));
125         }
126     }
127 
128     @Override
129     public Connection getConnection() throws SQLException {
130         if (log.isTraceEnabled())
131             log.trace("total checked-out connections: " + checkedOut);
132 
133         synchronized (pool) {
134             if (!pool.isEmpty()) {
135                 int last = pool.size() - 1;
136                 if (log.isTraceEnabled()) {
137                     log.trace("using pooled JDBC connection, pool size: " + last);
138                 }
139                 checkedOut++;
140                 Connection pooled = (Connection) pool.remove(last);
141                 if (isolation != null)
142                     pooled.setTransactionIsolation(isolation.intValue());
143                 if (pooled.getAutoCommit() != autocommit)
144                     pooled.setAutoCommit(autocommit);
145                 return pooled;
146             }
147         }
148 
149         log.debug("opening new JDBC connection");
150         Connection conn = DriverManager.getConnection(url, connectionProps);
151         if (isolation != null) conn.setTransactionIsolation(isolation);
152         if (conn.getAutoCommit() != autocommit) conn.setAutoCommit(autocommit);
153 
154         if (log.isDebugEnabled()) {
155             log.debug("created connection to: " + url + ", Isolation Level: " + conn.getTransactionIsolation());
156         }
157 //		if ( log.isTraceEnabled() )
158         checkedOut++;
159 
160         return conn;
161     }
162 
163     @Override
164     public void closeConnection(Connection conn) throws SQLException {
165 //        if ( log.isDebugEnabled() )
166         checkedOut--;
167 
168         synchronized (pool) {
169             int currentSize = pool.size();
170             if (currentSize < poolSize) {
171                 if (log.isTraceEnabled()) {
172                     log.trace("returning connection to pool, pool size: " + (currentSize + 1));
173                 }
174                 pool.add(conn);
175                 return;
176             }
177         }
178 
179         log.debug("closing JDBC connection");
180 
181         conn.close();
182     }
183 
184     @Override
185     protected void finalize() throws Throwable {
186         super.finalize();
187         close();
188     }
189 
190     public void close() {
191 
192         log.info("cleaning up connection pool: " + url);
193 
194         Iterator iter = pool.iterator();
195         while (iter.hasNext()) {
196             try {
197                 ((Connection) iter.next()).close();
198             } catch (SQLException sqle) {
199                 log.warn("problem closing pooled connection", sqle);
200             }
201         }
202         pool.clear();
203 
204     }
205 
206     @Override
207     public boolean supportsAggressiveRelease() {
208         return false;
209     }
210 }