Inspector | Message | Severity | Location |
---|---|---|---|
Java Inspector 048 | Copyrights information should be present in each file. | 1 | |
Java Inspector 045 | Too many exceptions (more than 3) listed in throws clause | 2 | 159:9 |
Java Inspector 083 | Do not use printStackTrace() for exception logging. | 2 | 88:66 |
Java Inspector 083 | Do not use printStackTrace() for exception logging. | 2 | 101:66 |
Java Inspector 089 | Undocumented method | 2 | 82:17 |
Java Inspector 089 | Undocumented method | 2 | 94:17 |
Java Inspector 089 | Undocumented method | 2 | 107:17 |
Java Inspector 089 | Undocumented method | 2 | 111:17 |
Java Inspector 089 | Undocumented method | 2 | 118:17 |
Java Inspector 089 | Constructor documentation is too short. It is only 1 words. Should be at least 3 words. | 2 | 134:9 |
Java Inspector 089 | Parameter driverClass is not documented | 2 | 134:9 |
Java Inspector 089 | Parameter dbURL is not documented | 2 | 134:9 |
Java Inspector 089 | Parameter user is not documented | 2 | 134:9 |
Java Inspector 089 | Parameter password is not documented | 2 | 134:9 |
Java Inspector 089 | Undocumented parameter initConnectionTransaction | 2 | 134:9 |
Java Inspector 089 | Constructor documentation is too short. It is only 1 words. Should be at least 3 words. | 2 | 159:9 |
Java Inspector 089 | Undocumented parameter classLoader | 2 | 159:9 |
Java Inspector 089 | Parameter driverClass is not documented | 2 | 159:9 |
Java Inspector 089 | Parameter dbURL is not documented | 2 | 159:9 |
Java Inspector 089 | Parameter user is not documented | 2 | 159:9 |
Java Inspector 089 | Parameter password is not documented | 2 | 159:9 |
Java Inspector 089 | Undocumented parameter initConnectionTransaction | 2 | 159:9 |
Java Inspector 089 | Undocumented method | 2 | 180:9 |
Java Inspector 089 | Undocumented method | 2 | 184:9 |
Java Inspector 089 | Undocumented method | 2 | 188:9 |
Java Inspector 089 | Undocumented method | 2 | 192:9 |
Java Inspector 089 | Undocumented method | 2 | 196:9 |
Java Inspector 089 | Undocumented method | 2 | 200:9 |
Java Inspector 089 | Undocumented method | 2 | 212:25 |
Java Inspector 089 | Javadoc contains tag for exception which method doesn't throw SQLException | 2 | 241:9 |
Java Inspector 089 | Undocumented method | 2 | 249:9 |
Java Inspector 089 | Method is not properly documented | 2 | 257:9 |
Java Inspector 089 | Undocumented method | 2 | 261:9 |
Java Inspector 089 | Undocumented method | 2 | 265:9 |
Java Inspector 089 | Undocumented method | 2 | 270:9 |
Java Inspector 016 | Sun coding standards - class modifiers should be in order (public protected private abstract static final strictfp) | 3 | 241:9 |
Java Inspector 026 | Avoid hardwired string literals. Allowed literals: [] | 3 | 167:56 |
Java Inspector 026 | Avoid hardwired string literals. Allowed literals: [] | 3 | 202:48 |
Java Inspector 026 | Avoid hardwired string literals. Allowed literals: [] | 3 | 214:45 |
Java Inspector 026 | Avoid hardwired string literals. Allowed literals: [] | 3 | 222:72 |
Java Inspector 040 | Parameter name user clashes with field name in ConnectionPerThreadDataSource | 3 | 200:41 |
Java Inspector 040 | Parameter name password clashes with field name in ConnectionPerThreadDataSource | 3 | 200:54 |
Java Inspector 051 | It is good practice to call in any case super() in a constructor. | 3 | 134:9 |
Java Inspector 051 | It is good practice to call in any case super() in a constructor. | 3 | 159:9 |
Java Inspector 090 | Unnecessary else part in if. The main part terminates control flow (return, break, throw, or continue). | 3 | 214:41 |
Java Inspector 090 | Unnecessary else part in if. The main part terminates control flow (return, break, throw, or continue). | 3 | 221:48 |
1/*
2 * hgcommons 9
3 * Hammurapi Group Common Library
4 * Copyright (C) 2003 Hammurapi Group
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 *
20 * URL: http://www.hammurapi.biz/hammurapi-biz/ef/xmenu/hammurapi-group/products/products/hgcommons/index.html
21 * e-Mail: support@hammurapi.biz
22*/
23
24package biz.hammurapi.sql;
25
26import java.io.PrintWriter;
27import java.lang.reflect.InvocationHandler;
28import java.lang.reflect.Method;
29import java.lang.reflect.Proxy;
30import java.sql.Connection;
31import java.sql.Driver;
32import java.sql.DriverManager;
33import java.sql.SQLException;
34import java.util.ArrayList;
35import java.util.Collection;
36import java.util.Iterator;
37
38import javax.sql.DataSource;
39
40import biz.hammurapi.config.Component;
41import biz.hammurapi.config.ConfigurationException;
42
43/**
44 * Maintains one connection per thread. Connection is allocated on first
45 * getConnection() call. Every next call increments use counter.
46 * Connection closes when it is not used (counter==0) and connectionCloseTimeout passed.
47 *
48 * @author Pavel Vlasov
49 * @version $Revision: 1.7 $
50 */
51public class ConnectionPerThreadDataSource implements DataSource, Component {
52
53 private String dbURL;
54 private String user;
55 private String password;
56
57 private boolean inShutdown;
58 private Collection connections=new ArrayList();
59
60 private class MasterEntry {
61
62 {
63 synchronized (ConnectionPerThreadDataSource.this) {
64 connections.add(this);
65 }
66 }
67
68 Connection master;
69 int counter;
70
71 synchronized Connection getMaster() throws SQLException {
72 if (master==null) {
73 master=DriverManager.getConnection(dbURL, user, password);
74 master.setAutoCommit(true);
75 if (initConnectionTransaction!=null) {
76 initConnectionTransaction.execute(new SQLProcessor(master, null));
77 }
78 }
79 return master;
80 }
81
82 public void shutdown() {
83 if (counter == 0) {
84 if (master!=null) {
85 try {
86 master.close();
87 } catch (SQLException e) {
88 e.printStackTrace();
89 }
90 }
91 }
92 }
93
94 public void release() {
95 counter--;
96 if (inShutdown && counter ==0) {
97 if (master!=null) {
98 try {
99 master.close();
100 } catch (SQLException e) {
101 e.printStackTrace();
102 }
103 }
104 }
105 }
106
107 public void use() {
108 counter++;
109 }
110
111 protected void finalize() throws Throwable {
112 shutdown();
113 super.finalize();
114 }
115 }
116
117 private ThreadLocal connectionTL=new ThreadLocal() {
118 protected Object initialValue() {
119 return new MasterEntry();
120 }
121 };
122
123 private Transaction initConnectionTransaction;
124 private ClassLoader classLoader = getClass().getClassLoader();
125
126 /**
127 * Constructor
128 * @param driverClass
129 * @param dbURL
130 * @param user
131 * @param password
132 * @throws ClassNotFoundException
133 */
134 public ConnectionPerThreadDataSource(
135 String driverClass,
136 String dbURL,
137 String user,
138 String password,
139 Transaction initConnectionTransaction) throws ClassNotFoundException {
140 //"org.hsqldb.jdbcDriver"
141 Class.forName(driverClass);
142 this.dbURL=dbURL;
143 this.user=user;
144 this.password=password;
145 this.initConnectionTransaction=initConnectionTransaction;
146 }
147
148 /**
149 * Constructor
150 * @param driverClass
151 * @param dbURL
152 * @param user
153 * @param password
154 * @throws SQLException
155 * @throws ClassNotFoundException
156 * @throws IllegalAccessException
157 * @throws InstantiationException
158 */
159 public ConnectionPerThreadDataSource(
160 ClassLoader classLoader,
161 String driverClass,
162 String dbURL,
163 String user,
164 String password,
165 Transaction initConnectionTransaction) throws SQLException, InstantiationException, IllegalAccessException, ClassNotFoundException {
166 if (classLoader==null) {
167 throw new NullPointerException("classLoader==null");
168 }
169 DriverManager.registerDriver((Driver) classLoader.loadClass(driverClass).newInstance());
170 this.dbURL=dbURL;
171 this.user=user;
172 this.password=password;
173 this.initConnectionTransaction=initConnectionTransaction;
174 this.classLoader=classLoader;
175 }
176
177 private int loginTimeout;
178 private PrintWriter logWriter;
179
180 public int getLoginTimeout() {
181 return loginTimeout;
182 }
183
184 public void setLoginTimeout(int seconds) {
185 loginTimeout=seconds;
186 }
187
188 public PrintWriter getLogWriter() throws SQLException {
189 return logWriter;
190 }
191
192 public void setLogWriter(PrintWriter out) throws SQLException {
193 logWriter=out;
194 }
195
196 public Connection getConnection() throws SQLException {
197 return getConnection(user,password);
198 }
199
200 public Connection getConnection(String user, final String password) throws SQLException {
201 if (inShutdown) {
202 throw new SQLException("Data source is shut down");
203 }
204
205 final MasterEntry me=(MasterEntry) connectionTL.get();
206 final Connection master=me.getMaster();
207 me.use();
208
209 InvocationHandler handler=new InvocationHandler() {
210 boolean closed = false;
211
212 public Object invoke(Object proxy, Method method, Object[] arguments) throws Throwable {
213 if (Connection.class.isAssignableFrom(method.getDeclaringClass())) {
214 if ("close".equals(method.getName()) && method.getParameterTypes().length==0) {
215 if (!closed) {
216 closed=true;
217 master.setAutoCommit(true);
218 me.release();
219 }
220 return null;
221 } else if (closed) {
222 throw new SQLException("Connection is closed");
223 } else {
224 return method.invoke(master, arguments);
225 }
226 }
227
228 return method.invoke(master, arguments);
229 }
230
231 };
232
233 return (Connection) Proxy.newProxyInstance(classLoader, new Class[] {Connection.class}, handler);
234 }
235
236 /**
237 * Closes all pooled (unused) connections and instructs connections being used
238 * to close immeidatly once they are released.
239 * @throws SQLException
240 */
241 synchronized public void shutdown() {
242 inShutdown=true;
243 Iterator it=connections.iterator();
244 while (it.hasNext()) {
245 ((MasterEntry) it.next()).shutdown();
246 }
247 }
248
249 protected void finalize() throws Throwable {
250 shutdown();
251 super.finalize();
252 }
253
254 /**
255 * @return connection initialization transaction
256 */
257 public Transaction getInitConnectionTransaction() {
258 return initConnectionTransaction;
259 }
260
261 public void setOwner(Object owner) {
262 // Nothing
263 }
264
265 public void start() throws ConfigurationException {
266 // Nothing
267
268 }
269
270 public void stop() throws ConfigurationException {
271 shutdown();
272 }
273}
274
275