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