1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21 package org.efaps.init;
22
23 import java.io.File;
24 import java.io.FileInputStream;
25 import java.io.FileNotFoundException;
26 import java.io.IOException;
27 import java.util.HashMap;
28 import java.util.Map;
29 import java.util.Map.Entry;
30 import java.util.Properties;
31 import java.util.regex.Matcher;
32 import java.util.regex.Pattern;
33
34 import javax.naming.Context;
35 import javax.naming.InitialContext;
36 import javax.naming.NamingException;
37 import javax.naming.Reference;
38 import javax.naming.StringRefAddr;
39 import javax.naming.spi.ObjectFactory;
40 import javax.sql.DataSource;
41 import javax.transaction.TransactionManager;
42 import javax.transaction.TransactionSynchronizationRegistry;
43
44 import org.efaps.db.databases.AbstractDatabase;
45 import org.efaps.db.transaction.DelegatingUserTransaction;
46 import org.slf4j.Logger;
47 import org.slf4j.LoggerFactory;
48
49
50
51
52
53
54
55 public final class StartupDatabaseConnection
56 implements INamingBinds
57 {
58
59
60
61
62 private static final Logger LOG = LoggerFactory.getLogger(StartupDatabaseConnection.class);
63
64
65
66
67 private static final String ENV_PATH = "EFAPS_BOOTSTRAP_PATH";
68
69
70
71
72 private static final String ENV_FILE = "EFAPS_BOOTSTRAP_FILE";
73
74
75
76
77 private static final String PROP_DBTYPE_CLASS = "org.efaps.db.type";
78
79
80
81
82 private static final String PROP_DBFACTORY_CLASS = "org.efaps.db.factory";
83
84
85
86
87 private static final String PROP_DBCONNECTION = "org.efaps.db.connection";
88
89
90
91
92 private static final String PROP_TM_CLASS = "org.efaps.transaction.manager";
93
94
95
96
97 private static final String PROP_CONFIGPROP = "org.efaps.configuration.properties";
98
99
100
101
102 private static final String DEFAULT_BOOTSTRAP_PATH = ".efaps/bootstrap";
103
104
105
106
107 private static final String DEFAULT_BOOTSTRAP_FILE = "default.efaps.xml";
108
109
110
111
112 private StartupDatabaseConnection()
113 {
114 }
115
116
117
118
119
120
121
122
123 public static void startup()
124 throws StartupException
125 {
126 StartupDatabaseConnection.startup(null, null);
127 }
128
129
130
131
132
133
134
135
136
137
138 public static void startup(final String _bootstrapFile)
139 throws StartupException
140 {
141 StartupDatabaseConnection.startup(null, _bootstrapFile);
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 public static void startup(final String _bootstrapPath,
182 final String _bootstrapFile)
183 throws StartupException
184 {
185
186 final File bsPath;
187 if (_bootstrapPath != null) {
188 bsPath = new File(_bootstrapPath);
189 } else {
190 final String envPath = System.getenv(StartupDatabaseConnection.ENV_PATH);
191 if (envPath != null) {
192 bsPath = new File(envPath);
193 } else {
194 bsPath = new File(System.getProperty("user.home"), StartupDatabaseConnection.DEFAULT_BOOTSTRAP_PATH);
195 }
196 }
197
198 final String bsFile;
199 File bootstrap = null;
200 if (_bootstrapFile != null) {
201 bsFile = _bootstrapFile;
202 } else {
203 final String envFile = System.getenv(StartupDatabaseConnection.ENV_FILE);
204 if (envFile != null) {
205 bsFile = envFile;
206 } else {
207 bsFile = StartupDatabaseConnection.DEFAULT_BOOTSTRAP_FILE;
208 }
209 }
210 bootstrap = new File(bsFile);
211 if (bootstrap == null || !bootstrap.exists()) {
212 bootstrap = new File(bsPath, bsFile);
213 }
214
215
216 final Properties props = new Properties();
217 try {
218 props.loadFromXML(new FileInputStream(bootstrap));
219 } catch (final FileNotFoundException e) {
220 throw new StartupException("bootstrap file " + bootstrap + " not found", e);
221 } catch (final IOException e) {
222 throw new StartupException("bootstrap file " + bootstrap + " could not be read", e);
223 }
224
225
226 final Map<String, String> eFapsProps;
227 if (props.containsKey(StartupDatabaseConnection.PROP_CONFIGPROP)) {
228 eFapsProps = StartupDatabaseConnection.convertToMap(props
229 .getProperty(StartupDatabaseConnection.PROP_CONFIGPROP));
230 } else {
231 eFapsProps = new HashMap<String, String>();
232 }
233 StartupDatabaseConnection.startup(props.getProperty(StartupDatabaseConnection.PROP_DBTYPE_CLASS),
234 props.getProperty(StartupDatabaseConnection.PROP_DBFACTORY_CLASS),
235 props.getProperty(StartupDatabaseConnection.PROP_DBCONNECTION),
236 props.getProperty(StartupDatabaseConnection.PROP_TM_CLASS),
237 null,
238 eFapsProps);
239 }
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254 public static void startup(final String _classDBType,
255 final String _classDSFactory,
256 final String _propConnection,
257 final String _classTM,
258 final String _classTSR,
259 final String _eFapsProps)
260 throws StartupException
261 {
262 StartupDatabaseConnection.startup(_classDBType,
263 _classDSFactory,
264 StartupDatabaseConnection.convertToMap(_propConnection),
265 _classTM,
266 _classTSR,
267 StartupDatabaseConnection.convertToMap(_eFapsProps));
268 }
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283 public static void startup(final String _classDBType,
284 final String _classDSFactory,
285 final String _propConnection,
286 final String _classTM,
287 final String _classTSR,
288 final Map<String, String> _eFapsProps)
289 throws StartupException
290 {
291 StartupDatabaseConnection.startup(_classDBType,
292 _classDSFactory,
293 StartupDatabaseConnection.convertToMap(_propConnection),
294 _classTM,
295 _classTSR,
296 _eFapsProps);
297 }
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318 public static void startup(final String _classDBType,
319 final String _classDSFactory,
320 final Map<String, String> _propConnection,
321 final String _classTM,
322 final String _classTSR,
323 final Map<String, String> _eFapsProps)
324 throws StartupException
325 {
326 if (StartupDatabaseConnection.LOG.isInfoEnabled()) {
327 StartupDatabaseConnection.LOG.info("Initialise Database Connection");
328 }
329
330 final Context compCtx;
331 try {
332 final InitialContext context = new InitialContext();
333 compCtx = (javax.naming.Context) context.lookup("java:/comp");
334
335 StartupDatabaseConnection.configureEFapsProperties(compCtx, _eFapsProps);
336 StartupDatabaseConnection.configureDBType(compCtx, _classDBType);
337 StartupDatabaseConnection.configureDataSource(compCtx, _classDSFactory, _propConnection);
338 StartupDatabaseConnection.configureTransactionManager(compCtx, _classTM);
339 StartupDatabaseConnection.configureTransactionSynchronizationRegistry(compCtx, _classTSR);
340 } catch (final NamingException e) {
341 throw new StartupException("Could not initialize JNDI", e);
342 }
343
344 org.efaps.db.Context.reset();
345 }
346
347
348
349
350
351
352
353 protected static void configureEFapsProperties(final Context _compCtx,
354 final Map<String, String> _eFapsProps)
355 throws StartupException
356 {
357 try {
358 Util.bind(_compCtx, "env/" + INamingBinds.RESOURCE_CONFIGPROPERTIES, _eFapsProps);
359 } catch (final NamingException e) {
360 throw new StartupException("could not bind eFaps Properties '" + _eFapsProps + "'", e);
361
362 } catch (final Exception e) {
363
364 throw new StartupException("could not bind eFaps Properties '" + _eFapsProps + "'", e);
365 }
366 }
367
368
369
370
371
372
373
374
375
376
377
378 protected static void configureDataSource(final Context _compCtx,
379 final String _classDSFactory,
380 final Map<String, String> _propConnection)
381 throws StartupException
382 {
383 final Reference ref = new Reference(DataSource.class.getName(), _classDSFactory, null);
384 for (final Entry<String, String> entry : _propConnection.entrySet()) {
385 ref.add(new StringRefAddr(entry.getKey(), entry.getValue()));
386 }
387 try {
388 Util.bind(_compCtx, "env/" + INamingBinds.RESOURCE_DATASOURCE, ref);
389 Util.bind(_compCtx, "test", ref);
390 } catch (final NamingException e) {
391 throw new StartupException("could not bind JDBC pooling class '" + _classDSFactory + "'", e);
392
393 } catch (final Exception e) {
394
395 throw new StartupException("coud not get object instance of factory '" + _classDSFactory + "'", e);
396 }
397 }
398
399
400
401
402
403
404
405
406
407
408 protected static void configureDBType(final Context _compCtx,
409 final String _classDBType)
410 throws StartupException
411 {
412 try {
413 final AbstractDatabase<?> dbType = (AbstractDatabase<?>) (Class.forName(_classDBType)).newInstance();
414 if (dbType == null) {
415 throw new StartupException("could not initaliase database type '" + _classDBType + "'");
416 } else {
417 Util.bind(_compCtx, "env/" + INamingBinds.RESOURCE_DBTYPE, dbType);
418 }
419 } catch (final ClassNotFoundException e) {
420 throw new StartupException("could not found database description class '" + _classDBType + "'", e);
421 } catch (final InstantiationException e) {
422 throw new StartupException("could not initialise database description class '" + _classDBType + "'", e);
423 } catch (final IllegalAccessException e) {
424 throw new StartupException("could not access database description class '" + _classDBType + "'", e);
425 } catch (final NamingException e) {
426 throw new StartupException("could not bind database description class '" + _classDBType + "'", e);
427 }
428 }
429
430
431
432
433
434
435
436
437
438
439 protected static void configureTransactionManager(final Context _compCtx,
440 final String _classTM)
441 throws StartupException
442 {
443 try {
444 final Object tm = (Class.forName(_classTM)).newInstance();
445 if (tm == null) {
446 throw new StartupException("could not initialise TransactionManager ");
447 } else {
448 if (tm instanceof TransactionManager) {
449 Util.bind(_compCtx, "env/" + INamingBinds.RESOURCE_TRANSMANAG, tm);
450 Util.bind(_compCtx, "env/" + INamingBinds.RESOURCE_USERTRANSACTION,
451 new DelegatingUserTransaction((TransactionManager) tm));
452 } else {
453 throw new StartupException("could not initialise TransactionManager with object:" + tm);
454 }
455 }
456 } catch (final ClassNotFoundException e) {
457 throw new StartupException("could not find transaction manager class '" + _classTM + "'", e);
458 } catch (final InstantiationException e) {
459 throw new StartupException("could not initialise transaction manager class '" + _classTM + "'", e);
460 } catch (final IllegalAccessException e) {
461 throw new StartupException("could not access transaction manager class '" + _classTM + "'", e);
462 } catch (final NamingException e) {
463 throw new StartupException("could not bind transaction manager class '" + _classTM + "'", e);
464 }
465 }
466
467
468
469
470
471
472
473
474
475
476
477 protected static void configureTransactionSynchronizationRegistry(final Context _compCtx,
478 final String _classTSR)
479 throws StartupException
480 {
481 try {
482
483 final Object clzz = (Class.forName(_classTSR)).newInstance();
484 if (clzz == null) {
485 throw new StartupException("could not initaliase database type");
486 } else {
487 if (clzz instanceof TransactionSynchronizationRegistry) {
488 Util.bind(_compCtx, "env/" + INamingBinds.RESOURCE_TRANSSYNREG, clzz);
489 Util.bind(_compCtx, "TransactionSynchronizationRegistry", clzz);
490 } else if (clzz instanceof ObjectFactory) {
491 final Reference ref = new Reference(TransactionSynchronizationRegistry.class.getName(), clzz
492 .getClass().getName(), null);
493 Util.bind(_compCtx, "env/" + INamingBinds.RESOURCE_TRANSSYNREG, ref);
494 Util.bind(_compCtx, "TransactionSynchronizationRegistry", ref);
495 }
496 }
497
498 } catch (final ClassNotFoundException e) {
499 throw new StartupException("could not found TransactionSynchronizationRegistry '" + _classTSR + "'", e);
500 } catch (final InstantiationException e) {
501 throw new StartupException("could not initialise TransactionSynchronizationRegistry class '" + _classTSR
502 + "'", e);
503 } catch (final IllegalAccessException e) {
504 throw new StartupException("could not access TransactionSynchronizationRegistry class '" + _classTSR + "'",
505 e);
506 } catch (final NamingException e) {
507 throw new StartupException("could not bind Transaction Synchronization Registry class '"
508 + _classTSR + "'", e);
509 }
510 }
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525 public static Map<String, String> convertToMap(final String _text)
526 {
527 final Map<String, String> properties = new HashMap<String, String>();
528
529
530 final Pattern pattern = Pattern.compile("(([^\\\\,])|(\\\\,)|(\\\\))*");
531 final Matcher matcher = pattern.matcher(_text);
532
533 while (matcher.find()) {
534 final String group = matcher.group().trim();
535 if (group.length() > 0) {
536
537 final int index = group.indexOf('=');
538 final String key = (index > 0)
539 ? group.substring(0, index).trim()
540 : group.trim();
541 final String value = (index > 0)
542 ? group.substring(index + 1).trim()
543 : "";
544 properties.put(key, value);
545 }
546 }
547 return properties;
548 }
549
550
551
552
553
554
555 public static void shutdown()
556 throws StartupException
557 {
558 final Context compCtx;
559 try {
560 final InitialContext context = new InitialContext();
561 compCtx = (javax.naming.Context) context.lookup("java:comp");
562 } catch (final NamingException e) {
563 throw new StartupException("Could not initialize JNDI", e);
564 }
565 try {
566 Util.unbind(compCtx, "env/" + INamingBinds.RESOURCE_DATASOURCE);
567 Util.unbind(compCtx, "env/" + INamingBinds.RESOURCE_DBTYPE);
568 Util.unbind(compCtx, "env/" + INamingBinds.RESOURCE_CONFIGPROPERTIES);
569 Util.unbind(compCtx, "env/" + INamingBinds.RESOURCE_TRANSMANAG);
570 } catch (final NamingException e) {
571 throw new StartupException("unbind of the database connection failed", e);
572 }
573 }
574 }