1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21 package org.dbunit.ant;
22
23 import org.slf4j.Logger;
24 import org.slf4j.LoggerFactory;
25
26 import org.apache.tools.ant.AntClassLoader;
27 import org.apache.tools.ant.BuildException;
28 import org.apache.tools.ant.Project;
29 import org.apache.tools.ant.Task;
30 import org.apache.tools.ant.types.Path;
31 import org.apache.tools.ant.types.Reference;
32 import org.dbunit.DatabaseUnitException;
33 import org.dbunit.database.DatabaseConfig;
34 import org.dbunit.database.DatabaseConnection;
35 import org.dbunit.database.ForwardOnlyResultSetTableFactory;
36 import org.dbunit.database.IDatabaseConnection;
37 import org.dbunit.dataset.datatype.IDataTypeFactory;
38
39 import java.sql.Connection;
40 import java.sql.Driver;
41 import java.sql.SQLException;
42 import java.util.ArrayList;
43 import java.util.Iterator;
44 import java.util.List;
45 import java.util.Properties;
46
47
48
49
50
51
52
53
54
55
56
57
58
59 public class DbUnitTask extends Task
60 {
61
62
63
64
65 private static final Logger logger = LoggerFactory.getLogger(DbUnitTask.class);
66
67
68
69
70 private Connection conn = null;
71
72
73
74
75 private String driver = null;
76
77
78
79
80 private String url = null;
81
82
83
84
85 private String userId = null;
86
87
88
89
90 private String password = null;
91
92
93
94
95 private String schema = null;
96
97
98
99
100 private List steps = new ArrayList();
101
102 private Path classpath;
103
104 private AntClassLoader loader;
105
106
107
108
109
110 private DbConfig dbConfig;
111
112
113
114
115
116 private Boolean useQualifiedTableNames = null;
117
118
119
120
121
122 private Boolean supportBatchStatement = null;
123
124
125
126
127
128 private Boolean datatypeWarning = null;
129
130
131
132
133 private String escapePattern = null;
134
135
136
137
138 private String dataTypeFactory = null;
139
140
141
142
143 private String batchSize = null;
144
145
146
147
148 private String fetchSize = null;
149
150
151
152
153 private Boolean skipOracleRecycleBinTables = null;
154
155
156
157
158 public void setDriver(String driver)
159 {
160 logger.trace("setDriver(driver={}) - start", driver);
161 this.driver = driver;
162 }
163
164
165
166
167 public void setUrl(String url)
168 {
169 logger.trace("setUrl(url={}) - start", url);
170 this.url = url;
171 }
172
173
174
175
176 public void setUserid(String userId)
177 {
178 logger.trace("setUserid(userId={}) - start", userId);
179 this.userId = userId;
180 }
181
182
183
184
185 public void setPassword(String password)
186 {
187 logger.trace("setPassword(password=*****) - start");
188 this.password = password;
189 }
190
191
192
193
194 public void setSchema(String schema)
195 {
196 logger.trace("setSchema(schema={}) - start", schema);
197 this.schema = schema;
198 }
199
200
201
202
203 public void setUseQualifiedTableNames(Boolean useQualifiedTableNames)
204 {
205 logger.trace("setUseQualifiedTableNames(useQualifiedTableNames={}) - start", String.valueOf(useQualifiedTableNames));
206 this.useQualifiedTableNames = useQualifiedTableNames;
207 }
208
209
210
211
212
213
214 public void setSupportBatchStatement(Boolean supportBatchStatement)
215 {
216 logger.trace("setSupportBatchStatement(supportBatchStatement={}) - start", String.valueOf(supportBatchStatement));
217 this.supportBatchStatement = supportBatchStatement;
218 }
219
220 public void setDatatypeWarning(Boolean datatypeWarning)
221 {
222 logger.trace("setDatatypeWarning(datatypeWarning={}) - start", String.valueOf(datatypeWarning));
223 this.datatypeWarning = datatypeWarning;
224 }
225
226 public void setDatatypeFactory(String datatypeFactory)
227 {
228 logger.trace("setDatatypeFactory(datatypeFactory={}) - start", datatypeFactory);
229 this.dataTypeFactory = datatypeFactory;
230 }
231
232 public void setEscapePattern(String escapePattern)
233 {
234 logger.trace("setEscapePattern(escapePattern={}) - start", escapePattern);
235 this.escapePattern = escapePattern;
236 }
237
238 public DbConfig getDbConfig()
239 {
240 return dbConfig;
241 }
242
243
244
245
246
247
248
249 public void addDbConfig(DbConfig dbConfig)
250 {
251 logger.trace("addDbConfig(dbConfig={}) - start", dbConfig);
252 this.dbConfig = dbConfig;
253 }
254
255
256
257
258 public void setClasspath(Path classpath)
259 {
260 logger.trace("setClasspath(classpath={}) - start", classpath);
261 if (this.classpath == null)
262 {
263 this.classpath = classpath;
264 }
265 else
266 {
267 this.classpath.append(classpath);
268 }
269 }
270
271
272
273
274 public Path createClasspath()
275 {
276 logger.trace("createClasspath() - start");
277
278 if (this.classpath == null)
279 {
280 this.classpath = new Path(getProject());
281 }
282 return this.classpath.createPath();
283 }
284
285
286
287
288 public void setClasspathRef(Reference r)
289 {
290 logger.trace("setClasspathRef(r={}) - start", r);
291
292 createClasspath().setRefid(r);
293 }
294
295
296
297
298 public List getSteps()
299 {
300 return steps;
301 }
302
303
304
305
306 public void addOperation(Operation operation)
307 {
308 logger.trace("addOperation({}) - start", operation);
309
310 steps.add(operation);
311 }
312
313
314
315
316 public void addCompare(Compare compare)
317 {
318 logger.trace("addCompare({}) - start", compare);
319
320 steps.add(compare);
321 }
322
323
324
325
326 public void addExport(Export export)
327 {
328 logger.trace("addExport(export={}) - start", export);
329
330 steps.add(export);
331 }
332
333
334 public String getBatchSize()
335 {
336 return batchSize;
337 }
338
339
340
341
342
343 public void setBatchSize(String batchSize)
344 {
345 this.batchSize = batchSize;
346 }
347
348
349 public String getFetchSize()
350 {
351 return fetchSize;
352 }
353
354 public void setFetchSize(String fetchSize)
355 {
356 this.fetchSize = fetchSize;
357 }
358
359 public void setSkipOracleRecycleBinTables(Boolean skipOracleRecycleBinTables)
360 {
361 this.skipOracleRecycleBinTables = skipOracleRecycleBinTables;
362 }
363
364
365
366
367 public void execute() throws BuildException
368 {
369 logger.trace("execute() - start");
370
371 try
372 {
373 IDatabaseConnection connection = createConnection();
374
375 Iterator stepIter = steps.listIterator();
376 while (stepIter.hasNext())
377 {
378 DbUnitTaskStep step = (DbUnitTaskStep)stepIter.next();
379 log(step.getLogMessage(), Project.MSG_INFO);
380 step.execute(connection);
381 }
382 }
383 catch (DatabaseUnitException e)
384 {
385 throw new BuildException(e, getLocation());
386 }
387 catch (SQLException e)
388 {
389 throw new BuildException(e, getLocation());
390 }
391 finally
392 {
393 try
394 {
395 if (conn != null)
396 {
397 conn.close();
398 }
399 }
400 catch (SQLException e)
401 {
402 logger.error("execute()", e);
403 }
404 }
405 }
406
407 protected IDatabaseConnection createConnection() throws SQLException
408 {
409 logger.trace("createConnection() - start");
410
411 if (driver == null)
412 {
413 throw new BuildException("Driver attribute must be set!", getLocation());
414 }
415 if (userId == null)
416 {
417 throw new BuildException("User Id attribute must be set!", getLocation());
418 }
419 if (password == null)
420 {
421 throw new BuildException("Password attribute must be set!", getLocation());
422 }
423 if (url == null)
424 {
425 throw new BuildException("Url attribute must be set!", getLocation());
426 }
427 if (steps.size() == 0)
428 {
429 throw new BuildException("Must declare at least one step in a <dbunit> task!", getLocation());
430 }
431
432
433 Driver driverInstance = null;
434 try
435 {
436 Class dc;
437 if (classpath != null)
438 {
439 log("Loading " + driver + " using AntClassLoader with classpath " + classpath,
440 Project.MSG_VERBOSE);
441
442 loader = new AntClassLoader(getProject(), classpath);
443 dc = loader.loadClass(driver);
444 }
445 else
446 {
447 log("Loading " + driver + " using system loader.", Project.MSG_VERBOSE);
448 dc = Class.forName(driver);
449 }
450 driverInstance = (Driver)dc.newInstance();
451 }
452 catch (ClassNotFoundException e)
453 {
454 throw new BuildException("Class Not Found: JDBC driver "
455 + driver + " could not be loaded", e, getLocation());
456 }
457 catch (IllegalAccessException e)
458 {
459 throw new BuildException("Illegal Access: JDBC driver "
460 + driver + " could not be loaded", e, getLocation());
461 }
462 catch (InstantiationException e)
463 {
464 throw new BuildException("Instantiation Exception: JDBC driver "
465 + driver + " could not be loaded", e, getLocation());
466 }
467
468 log("connecting to " + url, Project.MSG_VERBOSE);
469 Properties info = new Properties();
470 info.put("user", userId);
471 info.put("password", password);
472 conn = driverInstance.connect(url, info);
473
474 if (conn == null)
475 {
476
477 throw new SQLException("No suitable Driver for " + url);
478 }
479 conn.setAutoCommit(true);
480
481 IDatabaseConnection connection = createDatabaseConnection(conn, schema);
482 return connection;
483 }
484
485
486
487
488
489
490
491
492
493 protected IDatabaseConnection createDatabaseConnection(Connection jdbcConnection,
494 String dbSchema)
495 {
496 logger.trace("createDatabaseConnection(jdbcConnection={}, dbSchema={}) - start", jdbcConnection, dbSchema);
497
498 IDatabaseConnection connection = null;
499 try
500 {
501 connection = new DatabaseConnection(jdbcConnection, dbSchema);
502 }
503 catch(DatabaseUnitException e)
504 {
505 throw new BuildException("Could not create dbunit connection object", e);
506 }
507 DatabaseConfig config = connection.getConfig();
508
509
510 config.setProperty(DatabaseConfig.PROPERTY_RESULTSET_TABLE_FACTORY, new ForwardOnlyResultSetTableFactory());
511
512 if(this.dbConfig != null){
513 try {
514 this.dbConfig.copyTo(config);
515 }
516 catch(DatabaseUnitException e)
517 {
518 throw new BuildException("Could not populate dbunit config object", e, getLocation());
519 }
520 }
521
522
523 copyAttributes(config);
524
525 log("Created connection for schema '" + schema + "' with config: " + config, Project.MSG_VERBOSE);
526
527 return connection;
528 }
529
530
531
532
533
534 private void copyAttributes(DatabaseConfig config)
535 {
536 if(supportBatchStatement!=null)
537 config.setFeature(DatabaseConfig.FEATURE_BATCHED_STATEMENTS, supportBatchStatement.booleanValue());
538 if(useQualifiedTableNames!=null)
539 config.setFeature(DatabaseConfig.FEATURE_QUALIFIED_TABLE_NAMES, useQualifiedTableNames.booleanValue());
540 if(datatypeWarning!=null)
541 config.setFeature(DatabaseConfig.FEATURE_DATATYPE_WARNING, datatypeWarning.booleanValue());
542 if(skipOracleRecycleBinTables!=null)
543 config.setFeature(DatabaseConfig.FEATURE_SKIP_ORACLE_RECYCLEBIN_TABLES, skipOracleRecycleBinTables.booleanValue());
544
545 if(escapePattern!=null)
546 {
547 config.setProperty(DatabaseConfig.PROPERTY_ESCAPE_PATTERN, escapePattern);
548 }
549 if (batchSize != null)
550 {
551 Integer batchSizeInteger = new Integer(batchSize);
552 config.setProperty(DatabaseConfig.PROPERTY_BATCH_SIZE, batchSizeInteger);
553 }
554 if (fetchSize != null)
555 {
556 config.setProperty(DatabaseConfig.PROPERTY_FETCH_SIZE, new Integer(fetchSize));
557 }
558
559
560 if(this.dataTypeFactory!=null) {
561 try
562 {
563 IDataTypeFactory dataTypeFactory = (IDataTypeFactory)Class.forName(
564 this.dataTypeFactory).newInstance();
565 config.setProperty(DatabaseConfig.PROPERTY_DATATYPE_FACTORY, dataTypeFactory);
566 }
567 catch (ClassNotFoundException e)
568 {
569 throw new BuildException("Class Not Found: DataType factory "
570 + driver + " could not be loaded", e, getLocation());
571 }
572 catch (IllegalAccessException e)
573 {
574 throw new BuildException("Illegal Access: DataType factory "
575 + driver + " could not be loaded", e, getLocation());
576 }
577 catch (InstantiationException e)
578 {
579 throw new BuildException("Instantiation Exception: DataType factory "
580 + driver + " could not be loaded", e, getLocation());
581 }
582 }
583
584 }
585 }
586