KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > springframework > test > AbstractTransactionalDataSourceSpringContextTests


1 /*
2  * Copyright 2002-2007 the original author or authors.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */

16
17 package org.springframework.test;
18
19 import java.io.IOException JavaDoc;
20 import java.io.InputStreamReader JavaDoc;
21 import java.io.LineNumberReader JavaDoc;
22 import java.util.Iterator JavaDoc;
23 import java.util.LinkedList JavaDoc;
24 import java.util.List JavaDoc;
25
26 import javax.sql.DataSource JavaDoc;
27
28 import org.springframework.core.io.Resource;
29 import org.springframework.dao.DataAccessException;
30 import org.springframework.dao.DataAccessResourceFailureException;
31 import org.springframework.jdbc.core.JdbcTemplate;
32 import org.springframework.util.StringUtils;
33
34 /**
35  * Subclass of AbstractTransactionalSpringContextTests that adds some convenience
36  * functionality for JDBC access. Expects a {@link javax.sql.DataSource} bean
37  * to be defined in the Spring application context.
38  *
39  * <p>This class exposes a {@link org.springframework.jdbc.core.JdbcTemplate}
40  * and provides an easy way to delete from the database in a new transaction.
41  *
42  * @author Rod Johnson
43  * @author Juergen Hoeller
44  * @since 1.1.1
45  * @see #setDataSource(javax.sql.DataSource)
46  * @see #getJdbcTemplate()
47  */

48 public abstract class AbstractTransactionalDataSourceSpringContextTests
49     extends AbstractTransactionalSpringContextTests {
50
51     protected JdbcTemplate jdbcTemplate;
52
53     /**
54      * Did this test delete any tables? If so, we forbid transaction completion,
55      * and only allow rollback.
56      */

57     private boolean zappedTables;
58
59
60     /**
61      * Default constructor for AbstractTransactionalDataSourceSpringContextTests.
62      */

63     public AbstractTransactionalDataSourceSpringContextTests() {
64     }
65
66     /**
67      * Constructor for AbstractTransactionalDataSourceSpringContextTests with a JUnit name.
68      */

69     public AbstractTransactionalDataSourceSpringContextTests(String JavaDoc name) {
70         super(name);
71     }
72
73
74     /**
75      * Setter: DataSource is provided by Dependency Injection.
76      */

77     public void setDataSource(DataSource JavaDoc dataSource) {
78         this.jdbcTemplate = new JdbcTemplate(dataSource);
79     }
80
81     /**
82      * Return the JdbcTemplate that this base class manages.
83      */

84     public final JdbcTemplate getJdbcTemplate() {
85         return this.jdbcTemplate;
86     }
87
88
89     /**
90      * Convenient method to delete all rows from these tables.
91      * Calling this method will make avoidance of rollback by calling
92      * <code>setComplete()</code> impossible.
93      * @see #setComplete
94      */

95     protected void deleteFromTables(String JavaDoc[] names) {
96         for (int i = 0; i < names.length; i++) {
97             int rowCount = this.jdbcTemplate.update("DELETE FROM " + names[i]);
98             if (logger.isInfoEnabled()) {
99                 logger.info("Deleted " + rowCount + " rows from table " + names[i]);
100             }
101         }
102         this.zappedTables = true;
103     }
104
105     /**
106      * Overridden to prevent the transaction committing if a number of tables have been
107      * cleared, as a defensive measure against accidental <i>permanent</i> wiping of a database.
108      * @see org.springframework.test.AbstractTransactionalSpringContextTests#setComplete()
109      */

110     protected final void setComplete() {
111         if (this.zappedTables) {
112             throw new IllegalStateException JavaDoc("Cannot set complete after deleting tables");
113         }
114         super.setComplete();
115     }
116     
117     /**
118      * Count the rows in the given table
119      * @param tableName table name to count rows in
120      * @return the number of rows in the table
121      */

122     protected int countRowsInTable(String JavaDoc tableName) {
123         return this.jdbcTemplate.queryForInt("SELECT COUNT(0) FROM " + tableName);
124     }
125     
126     
127     /**
128      * Execute the given SQL script. Will be rolled back by default,
129      * according to the fate of the current transaction.
130      * @param sqlResourcePath Spring resource path for the SQL script.
131      * Should normally be loaded by classpath. There should be one statement
132      * per line. Any semicolons will be removed.
133      * <b>Do not use this method to execute DDL if you expect rollback.</b>
134      * @param continueOnError whether or not to continue without throwing
135      * an exception in the event of an error
136      * @throws DataAccessException if there is an error executing a statement
137      * and continueOnError was false
138      */

139     protected void executeSqlScript(String JavaDoc sqlResourcePath, boolean continueOnError) throws DataAccessException {
140         if (logger.isInfoEnabled()) {
141             logger.info("Executing SQL script '" + sqlResourcePath + "'");
142         }
143
144         long startTime = System.currentTimeMillis();
145         List JavaDoc statements = new LinkedList JavaDoc();
146         Resource res = getApplicationContext().getResource(sqlResourcePath);
147         try {
148             LineNumberReader JavaDoc lnr = new LineNumberReader JavaDoc(new InputStreamReader JavaDoc(res.getInputStream()));
149             String JavaDoc currentStatement = lnr.readLine();
150             while (currentStatement != null) {
151                 currentStatement = StringUtils.replace(currentStatement, ";", "");
152                 statements.add(currentStatement);
153                 currentStatement = lnr.readLine();
154             }
155             
156             for (Iterator JavaDoc itr = statements.iterator(); itr.hasNext(); ) {
157                 String JavaDoc statement = (String JavaDoc) itr.next();
158                 try {
159                     int rowsAffected = this.jdbcTemplate.update(statement);
160                     if (logger.isDebugEnabled()) {
161                         logger.debug(rowsAffected + " rows affected by SQL: " + statement);
162                     }
163                 }
164                 catch (DataAccessException ex) {
165                     if (continueOnError) {
166                         if (logger.isWarnEnabled()) {
167                             logger.warn("SQL: " + statement + " failed", ex);
168                         }
169                     }
170                     else {
171                         throw ex;
172                     }
173                 }
174             }
175             long elapsedTime = System.currentTimeMillis() - startTime;
176             logger.info("Done executing SQL script '" + sqlResourcePath + "' in " + elapsedTime + " ms");
177         }
178         catch (IOException JavaDoc ex) {
179             throw new DataAccessResourceFailureException("Failed to open SQL script '" + sqlResourcePath + "'", ex);
180         }
181     }
182
183 }
184
Popular Tags