001: /*
002: * Copyright 2007 The Kuali Foundation
003: *
004: * Licensed under the Educational Community License, Version 1.0 (the "License");
005: * you may not use this file except in compliance with the License.
006: * You may obtain a copy of the License at
007: *
008: * http://www.opensource.org/licenses/ecl1.php
009: *
010: * Unless required by applicable law or agreed to in writing, software
011: * distributed under the License is distributed on an "AS IS" BASIS,
012: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013: * See the License for the specific language governing permissions and
014: * limitations under the License.
015: */
016: package org.kuali.rice.test;
017:
018: import java.sql.Connection;
019: import java.sql.ResultSet;
020: import java.sql.SQLException;
021: import java.sql.Statement;
022: import java.util.ArrayList;
023: import java.util.List;
024:
025: import javax.sql.DataSource;
026:
027: import junit.framework.Assert;
028:
029: import org.apache.log4j.Logger;
030: import org.kuali.rice.core.Core;
031: import org.kuali.rice.database.XAPoolDataSource;
032: import org.kuali.rice.lifecycle.BaseLifecycle;
033: import org.springframework.jdbc.core.ConnectionCallback;
034: import org.springframework.jdbc.core.JdbcTemplate;
035: import org.springframework.jdbc.core.StatementCallback;
036: import org.springframework.transaction.PlatformTransactionManager;
037: import org.springframework.transaction.TransactionStatus;
038: import org.springframework.transaction.support.TransactionCallback;
039: import org.springframework.transaction.support.TransactionTemplate;
040:
041: /**
042: * Lifecycle class to clean up the database for use in testing.
043: *
044: * @author Kuali Rice Team (kuali-rice@googlegroups.com)
045: * @version $Revision: 1.2.16.1.6.3 $ $Date: 2007/12/10 16:19:55 $
046: * @since 0.9
047: *
048: */
049: public class ClearDatabaseLifecycle extends BaseLifecycle {
050:
051: protected static final Logger LOG = Logger
052: .getLogger(ClearDatabaseLifecycle.class);
053:
054: private List<String> tablesToClear = new ArrayList<String>();
055: private List<String> tablesNotToClear = new ArrayList<String>();
056:
057: public ClearDatabaseLifecycle() {
058: addStandardTables();
059: }
060:
061: public ClearDatabaseLifecycle(
062: TestHarnessServiceLocator testHarnessServiceLocator,
063: List<String> tablesToClear) {
064: this .tablesToClear = tablesToClear;
065: }
066:
067: public ClearDatabaseLifecycle(List<String> tablesToClear,
068: List<String> tablesNotToClear) {
069: this .tablesToClear = tablesToClear;
070: this .tablesNotToClear = tablesNotToClear;
071: addStandardTables();
072: }
073:
074: protected void addStandardTables() {
075: tablesNotToClear.add("BIN.*");
076: }
077:
078: public static final String TEST_TABLE_NAME = "EN_UNITTEST_T";
079:
080: public void start() throws Exception {
081: if (new Boolean(Core.getCurrentContextConfig().getProperty(
082: "use.clearDatabaseLifecycle"))) {
083: final XAPoolDataSource dataSource = TestHarnessServiceLocator
084: .getDataSource();
085: final String schemaName = dataSource.getUser()
086: .toUpperCase();
087: clearTables(
088: (PlatformTransactionManager) TestHarnessServiceLocator
089: .getJtaTransactionManager(), dataSource,
090: schemaName);
091: super .start();
092: }
093: }
094:
095: protected Boolean isTestTableInSchema(final DataSource dataSource) {
096: Assert.assertNotNull("DataSource could not be located.",
097: dataSource);
098: return (Boolean) new JdbcTemplate(dataSource)
099: .execute(new ConnectionCallback() {
100: public Object doInConnection(
101: final Connection connection)
102: throws SQLException {
103: final ResultSet resultSet = connection
104: .getMetaData().getTables(null, null,
105: TEST_TABLE_NAME, null);
106: return new Boolean(resultSet.next());
107: }
108: });
109: }
110:
111: protected void verifyTestEnvironment(final DataSource dataSource) {
112: Assert
113: .assertTrue(
114: "No table named '"
115: + TEST_TABLE_NAME
116: + "' was found in the configured database. "
117: + "You are attempting to run tests against a non-test database!!!",
118: isTestTableInSchema(dataSource));
119: }
120:
121: protected void clearTables(
122: final PlatformTransactionManager transactionManager,
123: final DataSource dataSource, final String schemaName) {
124: LOG.info("Clearing tables for schema " + schemaName);
125: Assert.assertNotNull("DataSource could not be located.",
126: dataSource);
127:
128: if (schemaName == null || schemaName.equals("")) {
129: Assert.fail("Empty schema name given");
130: }
131: new TransactionTemplate(transactionManager)
132: .execute(new TransactionCallback() {
133: public Object doInTransaction(
134: final TransactionStatus status) {
135: verifyTestEnvironment(dataSource);
136: return new JdbcTemplate(dataSource)
137: .execute(new StatementCallback() {
138: public Object doInStatement(
139: Statement statement)
140: throws SQLException {
141: final List<String> reEnableConstraints = new ArrayList<String>();
142: final ResultSet resultSet = statement
143: .getConnection()
144: .getMetaData()
145: .getTables(
146: null,
147: schemaName,
148: null,
149: new String[] { "TABLE" });
150: while (resultSet.next()) {
151: String tableName = resultSet
152: .getString("TABLE_NAME");
153: // if (tableName.startsWith("EN_")) {
154: if (shouldTableBeCleared(tableName)) {
155: // if (getTablesToClear() != null && (!getTablesToClear().isEmpty()) && !getTablesToClear().contains(tableName)) {
156: // continue;
157: // }
158: // if (tableName.startsWith("BIN$")) {
159: // continue;
160: // }
161: if (!isUsingDerby()) {
162: ResultSet keyResultSet = statement
163: .getConnection()
164: .getMetaData()
165: .getExportedKeys(
166: null,
167: schemaName,
168: tableName);
169: while (keyResultSet
170: .next()) {
171: final String fkName = keyResultSet
172: .getString("FK_NAME");
173: final String fkTableName = keyResultSet
174: .getString("FKTABLE_NAME");
175: final String disableConstraint = "ALTER TABLE "
176: + fkTableName
177: + " DISABLE CONSTRAINT "
178: + fkName;
179: LOG
180: .info("Disabling constraints using statement ->"
181: + disableConstraint
182: + "<-");
183: statement
184: .addBatch(disableConstraint);
185: reEnableConstraints
186: .add("ALTER TABLE "
187: + fkTableName
188: + " ENABLE CONSTRAINT "
189: + fkName);
190: }
191: keyResultSet
192: .close();
193: }
194: String deleteStatement = "DELETE FROM "
195: + tableName;
196: LOG
197: .info("Clearing contents using statement ->"
198: + deleteStatement
199: + "<-");
200: statement
201: .addBatch(deleteStatement);
202: }
203:
204: }
205: for (final String constraint : reEnableConstraints) {
206: LOG
207: .info("Enabling constraints using statement ->"
208: + constraint
209: + "<-");
210: statement
211: .addBatch(constraint);
212: }
213: statement.executeBatch();
214: resultSet.close();
215: return null;
216: }
217: });
218: }
219: });
220: LOG
221: .info("Tables successfully cleared for schema "
222: + schemaName);
223: }
224:
225: private boolean shouldTableBeCleared(String tableName) {
226: if (getTablesToClear() != null && !getTablesToClear().isEmpty()) {
227: for (String tableToClear : getTablesToClear()) {
228: if (tableName.matches(tableToClear)) {
229: return true;
230: }
231: }
232: return false;
233: }
234: if (getTablesNotToClear() != null
235: && !getTablesNotToClear().isEmpty()) {
236: for (String tableNotToClear : getTablesNotToClear()) {
237: if (tableName.matches(tableNotToClear)) {
238: return false;
239: }
240: }
241: }
242: return true;
243: }
244:
245: private boolean isUsingDerby() throws SQLException {
246: return TestHarnessServiceLocator.getDataSource()
247: .getDriverClassName().toLowerCase().indexOf("derby") > -1;
248: }
249:
250: public List<String> getTablesToClear() {
251: return this .tablesToClear;
252: }
253:
254: public List<String> getTablesNotToClear() {
255: return this.tablesNotToClear;
256: }
257:
258: }
|