开发者社区> 技术小美> 正文
阿里云
为了无法计算的价值
打开APP
阿里云APP内打开

proxool配置文件中用户和密码加密

简介:
+关注继续查看

Proxool是一种Java数据库连接池技术。sourceforge下的一个开源项目,这个项目提供一个健壮、易用的连接池,最为关键的是这个连接池提供监控的功能,方便易用,便于发现连接泄漏的情况。

Proxool是一种Java数据库连接池技术。sourceforge下的一个开源项目,这个项目提供一个健壮、易用的连接池,最为关键的是这个连接池提供监控的功能,方便易用,便于发现连接泄漏的情况。

目前是和DBCP以及C3P0一起,最为常见的三种JDBC连接池技术

日前,Hibernate官方宣布由于Bug太多不再支持DBCP,而推荐使用 Proxool或C3P0。

proxool是个很好的开源连接池。但配置文件中的用户和密码却是明文存储的,如果对系统安全有较高的要求,使用时就麻烦了。昨天下了Proxool 0.9.1的源码,研究了下,做了些小小的改动,现在proxool配置文件中用户和密码可以使用密文存储了,同时明文的也可以正常使用。解密功能部分做成了接口,可以用自己的算法来实现,很方便。

 

先上配置文件proxool.xml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
<?xml version="1.0" encoding="gb2312"?>       
   
<!-- the proxool configuration can be embedded within your own application's. Anything outside the "proxool" tag is ignored. -->       
   
<something-else-entirely>     
    <proxool>     
        <!--连接池的别名-->     
        <alias>hdqt</alias>  
        <!--实现解密的工具类-->    
        <encrypt>cn.bq.tools.DecUtil</encrypt>  
        <!--proxool只能管理由自己产生的连接-->     
        <driver-url>jdbc:microsoft:sqlserver://127.0.0.1:1433;databaseName=xxxx</driver-url>     
        <!--JDBC驱动程序-->     
        <driver-class>com.microsoft.jdbc.sqlserver.SQLServerDriver</driver-class>     
        <driver-properties>     
            <!--加密后的用户名和密码-->  
            <property name="user" value="da33e8657877280c32683ae317ef78e1"/>     
            <property name="password" value="3defde98af47835a74537600eebe78f2"/>     
        </driver-properties>     
        <!-- proxool自动侦察各个连接状态的时间间隔(毫秒),侦察到空闲的连接就马上回收,超时的销毁-->     
        <house-keeping-sleep-time>90000</house-keeping-sleep-time>   
        <house-keeping-test-sql>select getdate()</house-keeping-test-sql>  
        <!-- 指因未有空闲连接可以分配而在队列中等候的最大请求数,超过这个请求数的用户连接就不会被接受-->       
        <!--maximum-new-connections>150</maximum-new-connections-->     
    <simultaneous-build-throttle>5</simultaneous-build-throttle>  
        <!-- 最少保持的空闲连接数-->       
        <prototype-count>3</prototype-count>     
        <!-- 允许最大连接数,超过了这个连接,再有请求时,就排在队列中等候,最大的等待请求数由maximum-new-connections决定-->       
        <maximum-connection-count>100</maximum-connection-count>     
        <!-- 最小连接数-->     
        <minimum-connection-count>3</minimum-connection-count>     
    </proxool>  
   
</something-else-entirely>

proxool.properties配置文件:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
jdbc-0.proxool.alias=property-test  
jdbc-0.encrypt=cn.bq.tools.DecUtil  
jdbc-0.proxool.driver-url=jdbc:sqlserver://127.0.0.1:1433;databaseName=xxxx  
jdbc-0.proxool.driver-class=com.microsoft.jdbc.sqlserver.SQLServerDriver  
jdbc-0.user=da33e8657877280c32683ae317ef78e1  
jdbc-0.password=3defde98af47835a74537600eebe78f2  
jdbc-0.proxool.house-keeping-sleep-time=40000  
jdbc-0.proxool.house-keeping-test-sql=select getdate()  
jdbc-0.proxool.maximum-connection-count=10  
jdbc-0.proxool.minimum-connection-count=3  
jdbc-0.proxool.maximum-connection-lifetime=18000000  
jdbc-0.proxool.simultaneous-build-throttle=5  
jdbc-0.proxool.recently-started-threshold=40000  
jdbc-0.proxool.overload-without-refusal-lifetime=50000  
jdbc-0.proxool.maximum-active-time=60000  
jdbc-0.proxool.verbose=true  
jdbc-0.proxool.trace=true  
jdbc-0.proxool.fatal-sql-exception=Fatal error  
jdbc-0.proxool.prototype-count=2

 

 下面是修改的类:

ProxoolConstants.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
/* 
 * This software is released under a licence similar to the Apache Software Licence. 
 * See org.logicalcobwebs.proxool.package.html for details. 
 * The latest version is available at http://proxool.sourceforge.net 
 */  
package org.logicalcobwebs.proxool;  
   
/** 
 * All constants here please. 
 
 * @version $Revision: 1.21 $, $Date: 2004/06/02 20:39:17 $ 
 * @author billhorsman 
 * @author $Author: billhorsman $ (current maintainer) 
 */  
public interface ProxoolConstants {  
   
    public final String PROXOOL = "proxool";  
   
    /** 
     * The namespace uri associated with namepace aware Proxool xml configurations.<br> 
     * Value: The latest version is available at http://proxool.sourceforge.net/xml-namespace 
     */  
    public final String PROXOOL_XML_NAMESPACE_URI = "The latest version is available at http://proxool.sourceforge.net/xml-namespace";  
   
    public final String ALIAS_DELIMITER = ".";  
   
    public final String PROPERTY_PREFIX = PROXOOL + ".";  
   
    public final String URL_DELIMITER = ":";  
       
    /** 用户名和密码是否加密,对应值为解密的class*/  
    public final String USER_PASSWORD_ENCRYPT = "encrypt";  
   
    /** Standard JDBC property */  
    public final String USER_PROPERTY = "user";  
   
    /** Standard JDBC property */  
    public final String PASSWORD_PROPERTY = "password";  
   
    /** Used to build up URL */  
    public final String ALIAS_PROPERTY = PROPERTY_PREFIX + "alias";  
   
    /** Instead of defining the driver in the url you can also use this property */  
    public final String DELEGATE_DRIVER = "driver";  
   
    /** @see ProxoolDriver#getPropertyInfo */  
     public final String DELEGATE_DRIVER_PROPERTY = PROPERTY_PREFIX + DELEGATE_DRIVER;  
   
    /** @see #HOUSE_KEEPING_SLEEP_TIME_PROPERTY */  
    public final String DELEGATE_URL = "url";  
   
    /** @see ProxoolDriver#getPropertyInfo */  
     public final String DELEGATE_URL_PROPERTY = PROPERTY_PREFIX + DELEGATE_URL;  
   
    /** @see #HOUSE_KEEPING_SLEEP_TIME_PROPERTY */  
    public final String HOUSE_KEEPING_SLEEP_TIME = "house-keeping-sleep-time";  
   
    /** @see ProxoolDriver#getPropertyInfo */  
     public final String HOUSE_KEEPING_SLEEP_TIME_PROPERTY = PROPERTY_PREFIX + HOUSE_KEEPING_SLEEP_TIME;  
   
    /** @see #HOUSE_KEEPING_TEST_SQL_PROPERTY */  
    public final String HOUSE_KEEPING_TEST_SQL = "house-keeping-test-sql";  
   
    /** @see ProxoolDriver#getPropertyInfo */  
    public final String HOUSE_KEEPING_TEST_SQL_PROPERTY = PROPERTY_PREFIX + HOUSE_KEEPING_TEST_SQL;  
   
    /** @see #TEST_BEFORE_USE_PROPERTY */  
    public final String TEST_BEFORE_USE = "test-before-use";  
   
    /** @see ProxoolDriver#getPropertyInfo */  
    public final String TEST_BEFORE_USE_PROPERTY = PROPERTY_PREFIX + TEST_BEFORE_USE;  
   
    /** @see #TEST_AFTER_USE_PROPERTY */  
    public final String TEST_AFTER_USE = "test-after-use";  
   
    /** @see ProxoolDriver#getPropertyInfo */  
    public final String TEST_AFTER_USE_PROPERTY = PROPERTY_PREFIX + TEST_AFTER_USE;  
   
    /** @see #MAXIMUM_CONNECTION_COUNT_PROPERTY */  
    public final String MAXIMUM_CONNECTION_COUNT = "maximum-connection-count";  
   
    /** @see ProxoolDriver#getPropertyInfo */  
    public final String MAXIMUM_CONNECTION_COUNT_PROPERTY = PROPERTY_PREFIX + MAXIMUM_CONNECTION_COUNT;  
   
    /** @see #MAXIMUM_CONNECTION_LIFETIME_PROPERTY */  
    public final String MAXIMUM_CONNECTION_LIFETIME = "maximum-connection-lifetime";  
   
    /** @see ProxoolDriver#getPropertyInfo */  
    public final String MAXIMUM_CONNECTION_LIFETIME_PROPERTY = PROPERTY_PREFIX + MAXIMUM_CONNECTION_LIFETIME;  
   
    /** 
     * @deprecated use {@link #SIMULTANEOUS_BUILD_THROTTLE} instead 
     */  
    public final String MAXIMUM_NEW_CONNECTIONS = "maximum-new-connections";  
   
    /** 
     * @deprecated use {@link #SIMULTANEOUS_BUILD_THROTTLE_PROPERTY} instead 
     */  
    public final String MAXIMUM_NEW_CONNECTIONS_PROPERTY = PROPERTY_PREFIX + MAXIMUM_NEW_CONNECTIONS;  
   
    /** @see #SIMULTANEOUS_BUILD_THROTTLE_PROPERTY*/  
    public final String SIMULTANEOUS_BUILD_THROTTLE = "simultaneous-build-throttle";  
   
    /** @see ProxoolDriver#getPropertyInfo */  
    public final String SIMULTANEOUS_BUILD_THROTTLE_PROPERTY = PROPERTY_PREFIX + SIMULTANEOUS_BUILD_THROTTLE;  
   
    /** @see #MINIMUM_CONNECTION_COUNT_PROPERTY */  
    public final String MINIMUM_CONNECTION_COUNT = "minimum-connection-count";  
   
    /** @see ProxoolDriver#getPropertyInfo */  
    public final String MINIMUM_CONNECTION_COUNT_PROPERTY = PROPERTY_PREFIX + MINIMUM_CONNECTION_COUNT;  
   
    /** @see #PROTOTYPE_COUNT_PROPERTY */  
    public final String PROTOTYPE_COUNT = "prototype-count";  
   
    /** @see ProxoolDriver#getPropertyInfo */  
    public final String PROTOTYPE_COUNT_PROPERTY = PROPERTY_PREFIX + PROTOTYPE_COUNT;  
   
    /** @see #RECENTLY_STARTED_THRESHOLD_PROPERTY */  
    public final String RECENTLY_STARTED_THRESHOLD = "recently-started-threshold";  
   
    /** @see ProxoolDriver#getPropertyInfo */  
    public final String RECENTLY_STARTED_THRESHOLD_PROPERTY = PROPERTY_PREFIX + RECENTLY_STARTED_THRESHOLD;  
   
    /** @see #OVERLOAD_WITHOUT_REFUSAL_LIFETIME_PROPERTY */  
    public final String OVERLOAD_WITHOUT_REFUSAL_LIFETIME = "overload-without-refusal-lifetime";  
   
    /** @see ProxoolDriver#getPropertyInfo */  
    public final String OVERLOAD_WITHOUT_REFUSAL_LIFETIME_PROPERTY = PROPERTY_PREFIX + OVERLOAD_WITHOUT_REFUSAL_LIFETIME;  
   
    /** @see #MAXIMUM_ACTIVE_TIME_PROPERTY */  
    public final String MAXIMUM_ACTIVE_TIME = "maximum-active-time";  
   
    /** @see ProxoolDriver#getPropertyInfo */  
    public final String MAXIMUM_ACTIVE_TIME_PROPERTY = PROPERTY_PREFIX + MAXIMUM_ACTIVE_TIME;  
   
    /** @see #INJECTABLE_CONNECTION_INTERFACE_NAME_PROPERTY */  
    public final String INJECTABLE_CONNECTION_INTERFACE_NAME = "injectable-connection-interface";  
   
    /** @see ProxoolDriver#getPropertyInfo */  
    public final String INJECTABLE_CONNECTION_INTERFACE_NAME_PROPERTY = PROPERTY_PREFIX + INJECTABLE_CONNECTION_INTERFACE_NAME;  
   
    /** @see #INJECTABLE_STATEMENT_INTERFACE_NAME_PROPERTY */  
    public final String INJECTABLE_STATEMENT_INTERFACE_NAME = "injectable-statement-interface";  
   
    /** @see ProxoolDriver#getPropertyInfo */  
    public final String INJECTABLE_STATEMENT_INTERFACE_NAME_PROPERTY = PROPERTY_PREFIX + INJECTABLE_STATEMENT_INTERFACE_NAME;  
   
    /** @see #INJECTABLE_PREPARED_STATEMENT_INTERFACE_NAME_PROPERTY */  
    public final String INJECTABLE_PREPARED_STATEMENT_INTERFACE_NAME = "injectable-prepared-statement-interface";  
   
    /** @see ProxoolDriver#getPropertyInfo */  
    public final String INJECTABLE_PREPARED_STATEMENT_INTERFACE_NAME_PROPERTY = PROPERTY_PREFIX + INJECTABLE_PREPARED_STATEMENT_INTERFACE_NAME;  
   
    /** @see #INJECTABLE_CALLABLE_STATEMENT_INTERFACE_NAME_PROPERTY */  
    public final String INJECTABLE_CALLABLE_STATEMENT_INTERFACE_NAME = "injectable-callable-statement-interface";  
   
    /** @see ProxoolDriver#getPropertyInfo */  
    public final String INJECTABLE_CALLABLE_STATEMENT_INTERFACE_NAME_PROPERTY = PROPERTY_PREFIX + INJECTABLE_CALLABLE_STATEMENT_INTERFACE_NAME;  
   
    /** 
     * @deprecated use {@link #VERBOSE_PROPERTY verbose} instead. 
     */  
    public final String DEBUG_LEVEL_PROPERTY = PROPERTY_PREFIX + "debug-level";  
   
    /** @see #VERBOSE_PROPERTY */  
    public final String VERBOSE = "verbose";  
   
    /** @see ProxoolDriver#getPropertyInfo */  
    public final String VERBOSE_PROPERTY = PROPERTY_PREFIX + VERBOSE;  
   
    /** @see #TRACE_PROPERTY */  
    public final String TRACE = "trace";  
   
    /** @see ProxoolDriver#getPropertyInfo */  
    public final String TRACE_PROPERTY = PROPERTY_PREFIX + TRACE;  
   
    /** @see #FATAL_SQL_EXCEPTION_PROPERTY **/  
    public final String FATAL_SQL_EXCEPTION = "fatal-sql-exception";  
   
    /** @see ProxoolDriver#getPropertyInfo */  
    public final String FATAL_SQL_EXCEPTION_PROPERTY = PROPERTY_PREFIX + FATAL_SQL_EXCEPTION;  
   
    /** @see #FATAL_SQL_EXCEPTION_WRAPPER_CLASS_PROPERTY**/  
    public final String FATAL_SQL_EXCEPTION_WRAPPER_CLASS = "fatal-sql-exception-wrapper-class";  
   
    /** @see ProxoolDriver#getPropertyInfo */  
    public final String FATAL_SQL_EXCEPTION_WRAPPER_CLASS_PROPERTY = PROPERTY_PREFIX + FATAL_SQL_EXCEPTION_WRAPPER_CLASS;  
   
    public static final String STATISTICS = "statistics";  
   
    /** @see ProxoolDriver#getPropertyInfo */  
    public final String STATISTICS_PROPERTY = PROPERTY_PREFIX + STATISTICS;  
   
    public static final String STATISTICS_LOG_LEVEL = "statistics-log-level";  
   
    /** @see ProxoolDriver#getPropertyInfo */  
    public final String STATISTICS_LOG_LEVEL_PROPERTY = PROPERTY_PREFIX + STATISTICS_LOG_LEVEL;  
   
    public static final String JNDI_NAME = "jndi-name";  
       
    /** Prefix for generic JNDI properties. */  
    public static final String JNDI_PROPERTY_PREFIX = "jndi-";  
   
    /** @see ProxoolDriver#getPropertyInfo */  
    public final String JNDI_NAME_PROPERTY = PROPERTY_PREFIX + JNDI_NAME;  
   
// End JNDI  
   
    public static final String STATISTICS_LOG_LEVEL_TRACE = "TRACE";  
   
    public static final String STATISTICS_LOG_LEVEL_DEBUG = "DEBUG";  
   
    public static final String STATISTICS_LOG_LEVEL_INFO = "INFO";  
   
    /** 
     * Element name for the container of properties passed directlry to the delegate driver. 
     */  
    public static final String DRIVER_PROPERTIES = "driver-properties";  
   
   
    /** 
     * Configuration attribute used to indicate that a pool should be registered with JMX. 
     */  
    public static final String JMX = "jmx";  
   
    /** 
     * "proxool." prefixed version of {@link #JMX}. 
     */  
    public final String JMX_PROPERTY = PROPERTY_PREFIX + JMX;  
   
    /** 
     * Configuration attribute for a list of jmx agent ids to register a 
     * {@link org.logicalcobwebs.proxool.admin.jmx.ConnectionPoolMBean} to. 
     * The list is comma separated. 
     */  
    public static final String JMX_AGENT_ID = "jmx-agent-id";  
   
    /** 
     * "proxool." prefixed version of {@link #JMX_AGENT_ID}. 
     */  
    public final String JMX_AGENT_PROPERTY = PROPERTY_PREFIX + JMX_AGENT_ID;  
   
    /** 
     *  Un-prefixed propety name for the Proxool alias configuration property. Value: alias 
     */  
    public final String ALIAS = "alias";  
   
    /** 
     *  Un-prefixed propety name for the Proxool driver class  configuration property. Value: driver-class 
     */  
    public final String DRIVER_CLASS = "driver-class";  
    /** 
     *  Prefixed propety name for the Proxool driver class  configuration property. Value: proxool.driver-class 
     */  
    public final String DRIVER_CLASS_PROPERTY = PROPERTY_PREFIX + DRIVER_CLASS;;  
    /** 
     *  Un-prefixed propety name for the Proxool driver url configuration property. Value: driver-url 
     */  
    public final String DRIVER_URL = "driver-url";  
    /** 
     *  Prefixed propety name for the Proxool driver url configuration property. Value: proxool.driver-url 
     */  
    public final String DRIVER_URL_PROPERTY = PROPERTY_PREFIX + DRIVER_URL;  
}  
   
/* 
 Revision history: 
 $Log: ProxoolConstants.java,v $ 
 Revision 1.21  2004/06/02 20:39:17  billhorsman 
 New injectable interface constants 
  
 Revision 1.20  2004/03/15 02:43:47  chr32 
 Removed explicit JNDI properties. Going for a generic approach instead. 
 Added constant for JNDI properties prefix. 
  
 Revision 1.19  2003/09/30 18:39:08  billhorsman 
 New test-before-use, test-after-use and fatal-sql-exception-wrapper-class properties. 
  
 Revision 1.18  2003/09/29 17:48:21  billhorsman 
 New fatal-sql-exception-wrapper-class allows you to define what exception is used as a wrapper. This means that you 
 can make it a RuntimeException if you need to. 
  
 Revision 1.17  2003/09/05 17:00:42  billhorsman 
 New wrap-fatal-sql-exceptions property. 
  
 Revision 1.16  2003/07/23 06:54:48  billhorsman 
 draft JNDI changes (shouldn't effect normal operation) 
  
 Revision 1.15  2003/03/05 23:28:56  billhorsman 
 deprecated maximum-new-connections property in favour of 
 more descriptive simultaneous-build-throttle 
  
 Revision 1.14  2003/03/03 11:11:58  billhorsman 
 fixed licence 
  
 Revision 1.13  2003/02/26 16:05:52  billhorsman 
 widespread changes caused by refactoring the way we 
 update and redefine pool definitions. 
  
 Revision 1.12  2003/02/24 18:02:24  chr32 
 Added JMX related constants. 
  
 Revision 1.11  2003/02/24 01:16:15  chr32 
 Added constant for "driver-properties" property. 
  
 Revision 1.10  2003/02/06 15:41:17  billhorsman 
 add statistics-log-level 
  
 Revision 1.9  2003/01/30 17:22:03  billhorsman 
 new statistics property 
  
 Revision 1.8  2003/01/23 10:41:05  billhorsman 
 changed use of pool-name to alias for consistency 
  
 Revision 1.7  2002/12/26 11:32:22  billhorsman 
 Moved ALIAS, DRIVER_URL and DRIVER_CLASS constants 
 from XMLConfgiurator to ProxoolConstants. 
  
 Revision 1.6  2002/12/15 19:22:51  chr32 
 Added constant for proxool xml namespace. 
  
 Revision 1.5  2002/12/11 01:47:12  billhorsman 
 extracted property names without proxool. prefix for use 
 by XMLConfigurators. 
  
 Revision 1.4  2002/11/09 15:50:49  billhorsman 
 new trace constant 
  
 Revision 1.3  2002/10/27 13:29:38  billhorsman 
 deprecated debug-level in favour of verbose 
  
 Revision 1.2  2002/10/25 15:59:32  billhorsman 
 made non-public where possible 
  
 Revision 1.1.1.1  2002/09/13 08:13:06  billhorsman 
 new 
  
 Revision 1.3  2002/08/24 19:57:15  billhorsman 
 checkstyle changes 
  
 Revision 1.2  2002/07/12 23:03:22  billhorsman 
 added doc headers 
  
 Revision 1.7  2002/07/10 16:14:47  billhorsman 
 widespread layout changes and move constants into ProxoolConstants 
  
 Revision 1.6  2002/07/02 11:19:08  billhorsman 
 layout code and imports 
  
 Revision 1.5  2002/07/02 08:27:47  billhorsman 
 bug fix when settiong definition, displayStatistics now available to ProxoolFacade, prototyper no longer attempts to make connections when maximum is reached 
  
 Revision 1.4  2002/06/28 11:19:47  billhorsman 
 improved doc 
  
*/

解密接口类Decryptool.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
/* 
 * To change this template, choose Tools | Templates 
 * and open the template in the editor. 
 */  
package org.logicalcobwebs.proxool.util;  
   
/** 
 
 * @author zhappy 
 */  
public interface Decryptool {  
   
    /** 
     * 解密字符串 
     * @param content 密文 
     * @return 明文 
     */  
    public String decrypt(String content);  
       
}

PropertyConfigurator.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
/* 
 * This software is released under a licence similar to the Apache Software Licence. 
 * See org.logicalcobwebs.proxool.package.html for details. 
 * The latest version is available at http://proxool.sourceforge.net 
 */  
package org.logicalcobwebs.proxool.configuration;  
   
import java.io.FileInputStream;  
import java.io.IOException;  
import java.util.HashMap;  
import java.util.Iterator;  
import java.util.Map;  
import java.util.Properties;  
import org.apache.commons.logging.Log;  
import org.apache.commons.logging.LogFactory;  
import org.logicalcobwebs.proxool.ProxoolConstants;  
import org.logicalcobwebs.proxool.ProxoolException;  
import org.logicalcobwebs.proxool.ProxoolFacade;  
import org.logicalcobwebs.proxool.util.Decryptool;  
   
/** 
 * Uses a standard Java properties file to configure Proxool. For example: 
 
 * <pre> 
 * jdbc-0.proxool.alias=property-test 
 * jdbc-0.proxool.driver-url=jdbc:hsqldb:. 
 * jdbc-0.proxool.driver-class=org.hsqldb.jdbcDriver 
 * jdbc-0.encrypt=org.logicalcobwebs.proxool.util.Decryptool 
 * jdbc-0.user=foo 
 * jdbc-0.password=bar 
 * jdbc-0.proxool.house-keeping-sleep-time=40000 
 * jdbc-0.proxool.house-keeping-test-sql=select CURRENT_DATE 
 * jdbc-0.proxool.maximum-connection-count=10 
 * jdbc-0.proxool.minimum-connection-count=3 
 * jdbc-0.proxool.maximum-connection-lifetime=18000000 
 * jdbc-0.proxool.simultaneous-build-throttle=5 
 * jdbc-0.proxool.recently-started-threshold=40000 
 * jdbc-0.proxool.overload-without-refusal-lifetime=50000 
 * jdbc-0.proxool.maximum-active-time=60000 
 * jdbc-0.proxool.verbose=true 
 * jdbc-0.proxool.trace=true 
 * jdbc-0.proxool.fatal-sql-exception=Fatal error 
 * jdbc-0.proxool.prototype-count=2 
 
 * jdbc-1.proxool.alias=property-test-2 
 * jdbc-1.proxool.driver-url=jdbc:hsqldb:. 
 * jdbc-1.proxool.driver-class=org.hsqldb.jdbcDriver 
 * jdbc-1.user=scott 
 * jdbc-1.password=tiger 
 * jdbc-1.proxool.house-keeping-sleep-time=40000 
 * jdbc-1.proxool.house-keeping-test-sql=select CURRENT_DATE 
 * jdbc-1.proxool.maximum-connection-count=10 
 * jdbc-1.proxool.minimum-connection-count=3 
 * jdbc-1.proxool.maximum-connection-lifetime=18000000 
 * jdbc-1.proxool.simultaneous-build-throttle=5 
 * jdbc-1.proxool.recently-started-threshold=40000 
 * jdbc-1.proxool.overload-without-refusal-lifetime=50000 
 * jdbc-1.proxool.maximum-active-time=60000 
 * jdbc-1.proxool.verbose=true 
 * jdbc-1.proxool.trace=true 
 * jdbc-1.proxool.fatal-sql-exception=Fatal error 
 * jdbc-1.proxool.prototype-count=2 
 * </pre> 
 
 * <p>The first word (up to the first dot) must start with "jdbc", but it can be 
 * anything you like. Use unique names to identify each pool. Any property not 
 * starting with "jdbc" will be ignored.</p> <p> The properties prefixed with 
 * "proxool." will be used by Proxool while the properties that are not prefixed 
 * will be passed on to the delegate JDBC driver. </p> 
 
 * @version $Revision: 1.11 $, $Date: 2006/01/18 14:39:58 $ 
 * @author Bill Horsman (bill@logicalcobwebs.co.uk) 
 * @author $Author: billhorsman $ (current maintainer) 
 * @since Proxool 0.5 
 */  
public class PropertyConfigurator {  
   
    private static final Log LOG = LogFactory.getLog(PropertyConfigurator.class);  
    protected static final String PREFIX = "jdbc";  
    private static final String DOT = ".";  
    private static final String EXAMPLE_FORMAT = PREFIX + "*" + DOT + "*";  
   
    /** 
     * Configure proxool with the given properties file. 
     
     * @param filename the filename of the properties file. 
     * @throws ProxoolException if the configuration fails. 
     */  
    public static void configure(String filename) throws ProxoolException {  
        Properties properties = new Properties();  
        try {  
            properties.load(new FileInputStream(filename));  
        } catch (IOException e) {  
            throw new ProxoolException("Couldn't load property file " + filename);  
        }  
        configure(properties);  
    }  
   
    /** 
     * Configure proxool with the given properties. 
     
     * @param properties the properties instance to use. 
     * @throws ProxoolException if the configuration fails. 
     */  
    public static void configure(Properties properties) throws ProxoolException {  
        final Map propertiesMap = new HashMap();  
        final Iterator allPropertyKeysIterator = properties.keySet().iterator();  
        Properties proxoolProperties = null;  
   
        while (allPropertyKeysIterator.hasNext()) {  
            String key = (String) allPropertyKeysIterator.next();  
            String value = properties.getProperty(key);  
   
            if (key.startsWith(PREFIX)) {  
                int a = key.indexOf(DOT);  
                if (a == -1) {  
                    throw new ProxoolException("Property " + key + " must be of the format " + EXAMPLE_FORMAT);  
                }  
                final String tag = key.substring(0, a);  
                final String name = key.substring(a + 1);  
                proxoolProperties = (Properties) propertiesMap.get(tag);  
                if (proxoolProperties == null) {  
                    proxoolProperties = new Properties();  
                    propertiesMap.put(tag, proxoolProperties);  
                }  
                proxoolProperties.put(name, value);  
            }  
        }  
   
        final Iterator tags = propertiesMap.keySet().iterator();  
        while (tags.hasNext()) {  
            proxoolProperties = (Properties) propertiesMap.get(tags.next());  
   
            final String ec = proxoolProperties.getProperty(ProxoolConstants.USER_PASSWORD_ENCRYPT);  
            if (ec != null) {//如果在配置文件中存在解密项就先动态加载解密类,然后对用户名和密码进行解密  
                Decryptool dec = null;  
                try {  
                    Class c = Class.forName(ec);  
                    Object o = c.newInstance();  
                    dec = (Decryptool) o;  
                } catch (Exception e) {  
                    LOG.error("new Class [" + ec + "] fail!", e);  
                }  
                final String user = proxoolProperties.getProperty(ProxoolConstants.USER_PROPERTY);//取原值  
                proxoolProperties.setProperty(ProxoolConstants.USER_PROPERTY, dec.decrypt(user));//解密并设置  
                final String password = proxoolProperties.getProperty(ProxoolConstants.PASSWORD_PROPERTY);//取原值  
                proxoolProperties.setProperty(ProxoolConstants.PASSWORD_PROPERTY, dec.decrypt(password));//解密并设置  
            }  
            // make sure that required propeties are defined  
            // and build the url  
            // Check that we have defined the minimum information  
            final String driverClass = proxoolProperties.getProperty(ProxoolConstants.DRIVER_CLASS_PROPERTY);  
            final String driverUrl = proxoolProperties.getProperty(ProxoolConstants.DRIVER_URL_PROPERTY);  
            if (driverClass == null || driverUrl == null) {  
                throw new ProxoolException("You must define the " + ProxoolConstants.DRIVER_CLASS_PROPERTY + " and the "  
                        + ProxoolConstants.DRIVER_URL_PROPERTY + ".");  
            }  
            final String alias = proxoolProperties.getProperty(ProxoolConstants.ALIAS_PROPERTY);  
   
            // Build the URL; optionally defining a name  
            StringBuffer url = new StringBuffer();  
            url.append("proxool");  
            if (alias != null) {  
                url.append(ProxoolConstants.ALIAS_DELIMITER);  
                url.append(alias);  
                proxoolProperties.remove(ProxoolConstants.ALIAS_PROPERTY);  
            }  
            url.append(ProxoolConstants.URL_DELIMITER);  
            url.append(driverClass);  
            proxoolProperties.remove(ProxoolConstants.DRIVER_CLASS_PROPERTY);  
            url.append(ProxoolConstants.URL_DELIMITER);  
            url.append(driverUrl);  
            proxoolProperties.remove(ProxoolConstants.DRIVER_URL_PROPERTY);  
            if (LOG.isDebugEnabled()) {  
                LOG.debug("Created url: " + url);  
            }  
   
            ProxoolFacade.registerConnectionPool(url.toString(), proxoolProperties);  
        }  
    }  
}  
   
/* 
 * Revision history: $Log: PropertyConfigurator.java,v $ Revision 1.11 
 * 2006/01/18 14:39:58 billhorsman Unbundled Jakarta's Commons Logging. 
 
 * Revision 1.10 2003/03/05 23:28:56 billhorsman deprecated 
 * maximum-new-connections property in favour of more descriptive 
 * simultaneous-build-throttle 
 
 * Revision 1.9 2003/03/03 11:12:00 billhorsman fixed licence 
 
 * Revision 1.8 2003/02/06 17:41:05 billhorsman now uses imported logging 
 
 * Revision 1.7 2003/02/05 14:46:31 billhorsman fixed copyright and made PREFIX 
 * protected for use by ServletConfigurator 
 
 * Revision 1.6 2003/01/27 18:26:43 billhorsman refactoring of ProxyConnection 
 * and ProxyStatement to make it easier to write JDK 1.2 patch 
 
 * Revision 1.5 2003/01/23 10:41:05 billhorsman changed use of pool-name to 
 * alias for consistency 
 
 * Revision 1.4 2003/01/22 17:35:01 billhorsman checkstyle 
 
 * Revision 1.3 2003/01/18 15:13:12 billhorsman Signature changes (new 
 * ProxoolException thrown) on the ProxoolFacade API. 
 
 * Revision 1.2 2002/12/26 11:32:59 billhorsman Rewrote to support new format. 
 
 * Revision 1.1 2002/12/15 18:48:33 chr32 Movied in from 'ext' source tree. 
 
 * Revision 1.4 2002/11/09 15:57:57 billhorsman fix doc 
 
 * Revision 1.3 2002/11/02 14:22:16 billhorsman Documentation 
 
 * Revision 1.2 2002/10/27 13:05:01 billhorsman checkstyle 
 
 * Revision 1.1 2002/10/27 12:00:16 billhorsman moved classes from ext 
 * sub-package which is now obsolete - let's keep everything together in one 
 * place 
 
 * Revision 1.1 2002/10/25 10:40:27 billhorsman draft 
 
 */

XMLConfigurator.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
Java代码  
/* 
 * This software is released under a licence similar to the Apache Software Licence. 
 * See org.logicalcobwebs.proxool.package.html for details. 
 * The latest version is available at http://proxool.sourceforge.net 
 */  
package org.logicalcobwebs.proxool.configuration;  
   
import java.util.Iterator;  
import java.util.Properties;  
import org.apache.commons.logging.Log;  
import org.apache.commons.logging.LogFactory;  
import org.logicalcobwebs.proxool.ProxoolConstants;  
import org.logicalcobwebs.proxool.ProxoolException;  
import org.logicalcobwebs.proxool.ProxoolFacade;  
import org.logicalcobwebs.proxool.util.Decryptool;  
import org.xml.sax.Attributes;  
import org.xml.sax.SAXException;  
import org.xml.sax.SAXParseException;  
import org.xml.sax.helpers.DefaultHandler;  
   
/** 
 * <p>A SAX 2 ContentHandler that can configure Proxool from an XML source.</p> 
 
 * <p>This is just a <a 
 * href="http://www.saxproject.org/apidoc/org/xml/sax/ContentHandler.html" 
 * target="_new" >ContentHandler</a>, so you must associate it with a SAX parser 
 * for it to actually do anything. If you have JAXP available {@link JAXPConfigurator} 
 * will do this for you.</p> 
 
 * <p>Properties that you pass on to the delegate driver have to be treated 
 * specially. They must be contained within a &lt;driver-properties&gt; 
 * element.</p> 
 
 * <p>See the <a href="The latest version is available at 
 * http://proxool.sourceforge.net/properties.html" target="_new">Proxool 
 * properties</a> for documentation on the available configuration 
 * properties.</p> 
 
 * Example configuration: 
 * <pre> 
 * &lt;proxool&gt; 
 *     &lt;alias&gt;apple&lt;/alias&gt; 
 *     &lt;encrypt&gt;org.logicalcobwebs.proxool.util.Decryptool&lt;/alias&gt; 
 *     &lt;driver-url&gt;jdbc:hsqldb:.&lt;/driver-url&gt; 
 *     &lt;driver-class&gt;org.hsqldb.jdbcDriver&lt;/driver-class&gt; 
 *     &lt;driver-properties&gt; 
 *         &lt;property name="user" value="abc" /&gt; 
 *         &lt;property name="password" value="def" /&gt; 
 *     &lt;/driver-properties&gt; 
 *     &lt;house-keeping-sleep-time&gt;40000&lt;/house-keeping-sleep-time&gt; 
 *     &lt;house-keeping-test-sql&gt;select CURRENT_DATE&lt;/house-keeping-test-sql&gt; 
 *     &lt;maximum-connection-count&gt;10&lt;/maximum-connection-count&gt; 
 *     &lt;minimum-connection-count&gt;3&lt;/minimum-connection-count&gt; 
 *     &lt;maximum-connection-lifetime&gt;18000000&lt;/maximum-connection-lifetime&gt; &lt;!-- 5 hours --&gt; 
 *     &lt;simultaneous-build-throttle&gt;5&lt;/simultaneous-build-throttle&gt; 
 *     &lt;recently-started-threshold&gt;40000&lt;/recently-started-threshold&gt; 
 *     &lt;overload-without-refusal-lifetime&gt;50000&lt;/overload-without-refusal-lifetime&gt; 
 *     &lt;maximum-active-time&gt;60000&lt;/maximum-active-time&gt; 
 *     &lt;verbose&gt;true&lt;/verbose&gt; 
 *     &lt;trace&gt;true&lt;/trace&gt; 
 *     &lt;fatal-sql-exception&gt;ORA-1234&lt;/fatal-sql-exception&gt; 
 *     &lt;prototype-count&gt;2&lt;/prototype-count&gt; 
 * &lt;/proxool&gt; 
 * </pre> 
 
 * When the parser reaches the end of the &lt;proxool&gt; element the pool is 
 * automatically registered. You can contain the &lt;proxool&gt; element in any 
 * other elements as you wish. And the &lt;proxool&gt; element can occur as many 
 * times as you wish. This allows you to use an XML file that configures your 
 * whole application as the source. This configurator will ignore everything 
 * apart from the elements contained within the &lt;proxool&gt; element. <p><a 
 * name="#validation"> <b>Validation</b><br> A couple of additional steps are 
 * required if you want your SAX parser to validate your Proxool xml 
 * confguration: <ul> <li> Put your proxool configuration elements inside a root 
 * <code>proxool-config</code> element. The document must adhere to the <a 
 * href="proxool.dtd">Proxool dtd</a>. </li> <li> Add a 
 * <code>DOCTYPE</code> entry to your xml with a system id containing the 
 * <i>absolute url</i> to the Proxool dtd. The Proxool jar contains a copy of 
 * the Proxool dtd in the confguration package. You can reference that with a 
 * jar url like this:<br> 
 * <code><nobr>&lt;!DOCTYPE proxool-config SYSTEM "jar:file:///C:/Proxool/lib/proxool.jar!/org/logicalcobwebs/proxool/configuration/proxool.dtd"&gt;</nobr></code></li> 
 * <li> Configure your parser to be validating. In the {@link JAXPConfigurator} 
 * this is done by passing 
 * <code>true</code> as the second arghument to any of the 
 * <code>configure</code> methods. </li> </ul> </p> <p>This class is not thread 
 * safe.</p> 
 
 * @version $Revision: 1.18 $, $Date: 2006/01/18 14:39:58 $ 
 * @author billhorsman 
 * @author $Author: billhorsman $ (current maintainer) 
 */  
public class XMLConfigurator extends DefaultHandler {  
   
    private static final Log LOG = LogFactory.getLog(XMLConfigurator.class);  
    private StringBuffer content = new StringBuffer();  
    private String poolName;  
    private String driverClass;  
    private String driverUrl;  
    private Properties properties = new Properties();  
    private static final String PROXOOL = "proxool";  
    private static final String DRIVER_PROPERTIES = "driver-properties";  
    private static final String PROPERTY = "property";  
    private static final String NAME = "name";  
    private static final String VALUE = "value";  
    private boolean insideDelegateProperties;  
    private boolean insideProxool;  
   
    /** 
     * @see org.xml.sax.ContentHandler#startElement 
     */  
    @Override  
    public void startElement(String uri, String lname, String qname, Attributes attributes) throws SAXException {  
        content.setLength(0);  
   
        if (!namespaceOk(uri)) {  
            return;  
        }  
   
        final String elementName = getElementName(uri, lname, qname);  
   
        if (elementName.equals(PROXOOL)) {  
            if (insideProxool) {  
                throw new SAXException("A <" + PROXOOL + "> element can't contain another <" + PROXOOL + "> element.");  
            }  
            insideProxool = true;  
            properties.clear();  
            driverClass = null;  
            driverUrl = null;  
        }  
   
        if (insideProxool) {  
            if (elementName.equals(DRIVER_PROPERTIES)) {  
                insideDelegateProperties = true;  
            } else if (insideDelegateProperties) {  
                if (elementName.equals(PROPERTY)) {  
                    setDriverProperty(attributes);  
                }  
            }  
        }  
    }  
   
    /** 
     * @see org.xml.sax.ContentHandler#characters 
     */  
    @Override  
    public void characters(char[] chars, int start, int length) throws SAXException {  
        if (insideProxool) {  
            content.append(chars, start, length);  
        }  
    }  
   
    /** 
     * @see org.xml.sax.ContentHandler#endElement 
     */  
    @Override  
    public void endElement(String uri, String lname, String qname) throws SAXException {  
        if (!namespaceOk(uri)) {  
            return;  
        }  
   
        final String elementName = getElementName(uri, lname, qname);  
   
        // Are we ending a proxool configuration section?  
        if (elementName.equals(PROXOOL)) {  
   
            // Check that we have defined the minimum information  
            if (driverClass == null || driverUrl == null) {  
                throw new SAXException("You must define the "   
                        + ProxoolConstants.DRIVER_CLASS + " and the " + ProxoolConstants.DRIVER_URL + ".");  
            }  
   
            // Build the URL; optinally defining a name  
            StringBuffer url = new StringBuffer();  
            url.append("proxool");  
            if (poolName != null) {  
                url.append(ProxoolConstants.ALIAS_DELIMITER);  
                url.append(poolName);  
            }  
            url.append(ProxoolConstants.URL_DELIMITER);  
            url.append(driverClass);  
            url.append(ProxoolConstants.URL_DELIMITER);  
            url.append(driverUrl);  
            if (LOG.isDebugEnabled()) {  
                LOG.debug("Created url: " + url);  
            }  
   
            // Register the pool  
            try {  
                final String ec = properties.getProperty(ProxoolConstants.PROPERTY_PREFIX   
                        + ProxoolConstants.USER_PASSWORD_ENCRYPT);  
                if (ec != null) {//判断配置文件中是否有解密class的配置,如果有则动态加载  
                    Decryptool dec = null;  
                    try {  
                        Class c = Class.forName(ec);  
                        Object o = c.newInstance();  
                        dec = (Decryptool) o;  
                    } catch (Exception e) {  
                        LOG.error("new Class [" + ec + "] fail!", e);  
                    }  
                    final String user = properties.getProperty(ProxoolConstants.USER_PROPERTY);//取原值  
                    properties.setProperty(ProxoolConstants.USER_PROPERTY, dec.decrypt(user));//解密并设置  
                    final String password = properties.getProperty(ProxoolConstants.PASSWORD_PROPERTY);//取原值  
                    properties.setProperty(ProxoolConstants.PASSWORD_PROPERTY, dec.decrypt(password));//解密并设置  
                }  
                ProxoolFacade.registerConnectionPool(url.toString(), properties);  
            } catch (ProxoolException e) {  
                throw new SAXException(e);  
            }  
   
            // This ensures we ignore remaining XML until we come across another  
            // <proxool> element.  
            insideProxool = false;  
        }  
   
        if (insideProxool && !elementName.equals(PROXOOL)) {  
            if (elementName.equals(DRIVER_PROPERTIES)) {  
                insideDelegateProperties = false;  
            } else if (!insideDelegateProperties) {  
                setProxoolProperty(elementName, content.toString().trim());  
            }  
        }  
    }  
   
    private void setProxoolProperty(String localName, String value) {  
        if (localName.equals(ProxoolConstants.ALIAS)) {  
            poolName = value;  
        } else if (localName.equals(ProxoolConstants.DRIVER_CLASS)) {  
            driverClass = value;  
        } else if (localName.equals(ProxoolConstants.DRIVER_URL)) {  
            driverUrl = value;  
        } else {  
            if (LOG.isDebugEnabled()) {  
                LOG.debug("Setting property '" + ProxoolConstants.PROPERTY_PREFIX + localName + "' to value '" + value + "'.");  
            }  
            properties.put(ProxoolConstants.PROPERTY_PREFIX + localName, value);  
        }  
    }  
   
    private void setDriverProperty(Attributes attributes) throws SAXException {  
        final String name = attributes.getValue(NAME);  
        final String value = attributes.getValue(VALUE);  
        if (name == null || name.length() < 1 || value == null) {  
            throw new SAXException("Name or value attribute missing from property element."  
                    + "Name: '" + name + "' Value: '" + value + "'.");  
        }  
        if (LOG.isDebugEnabled()) {  
            if (name.toLowerCase().indexOf("password") > -1) {  
                LOG.debug("Adding driver property: " + name + "=" + "*******");  
            } else {  
                LOG.debug("Adding driver property: " + name + "=" + value);  
            }  
        }  
        properties.put(name, value);  
    }  
   
    /** 
     * @see org.xml.sax.ErrorHandler#warning(SAXParseException) 
     */  
    @Override  
    public void warning(SAXParseException e) throws SAXException {  
        // Just debug-log the warning. We'll probably survive.  
        LOG.debug("The saxparser reported a warning.", e);  
    }  
   
    /** 
     * @see org.xml.sax.ErrorHandler#error(SAXParseException) 
     */  
    @Override  
    public void error(SAXParseException e) throws SAXException {  
        // On error we rethrow the exception.  
        // This should cause the parser stop and an exeption be thrown back to the client.  
        throw e;  
    }  
   
    /** 
     * @see org.xml.sax.ErrorHandler#fatalError(SAXParseException) 
     */  
    @Override  
    public void fatalError(SAXParseException e) throws SAXException {  
        // On fatal error we rethrow the exception.  
        // This should cause the parser stop and an exeption be thrown back to the client.  
        throw e;  
    }  
   
    // If no namespace use qname, else use lname.  
    private String getElementName(String uri, String lname, String qname) {  
        if (uri == null || "".equals(uri)) {  
            return qname;  
        else {