001: //$Id: DbDataRestorer.java 282 2007-07-19 22:46:27Z jg_hamburg $
002: /********************************************************************************
003: * DDTUnit, a Datadriven Approach to Unit- and Moduletesting
004: * Copyright (c) 2004, Joerg and Kai Gellien
005: * All rights reserved.
006: *
007: * The Software is provided under the terms of the Common Public License 1.0
008: * as provided with the distribution of DDTUnit in the file cpl-v10.html.
009: * Redistribution and use in source and binary forms, with or without
010: * modification, are permitted provided that the following conditions
011: * are met:
012: *
013: * + Redistributions of source code must retain the above copyright
014: * notice, this list of conditions and the following disclaimer.
015: *
016: * + Redistributions in binary form must reproduce the above
017: * copyright notice, this list of conditions and the following
018: * disclaimer in the documentation and/or other materials provided
019: * with the distribution.
020: *
021: * + Neither the name of the authors or DDTUnit, nor the
022: * names of its contributors may be used to endorse or promote
023: * products derived from this software without specific prior
024: * written permission.
025: *
026: * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
027: * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
028: * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
029: * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR
030: * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
031: * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
032: * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
033: * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
034: * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
035: * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
036: * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
037: ********************************************************************************/package junitx.ddtunit.data.db;
038:
039: import java.sql.Connection;
040: import java.sql.DriverManager;
041: import java.sql.PreparedStatement;
042: import java.sql.ResultSet;
043: import java.sql.SQLException;
044: import java.util.Properties;
045: import java.util.regex.Matcher;
046: import java.util.regex.Pattern;
047:
048: import junitx.ddtunit.data.DDTTestDataException;
049: import junitx.ddtunit.data.ExceptionAsserter;
050: import junitx.ddtunit.data.IDataSetSerializer;
051: import junitx.ddtunit.data.ObjectAsserter;
052: import junitx.ddtunit.data.TestClusterDataSet;
053: import junitx.ddtunit.data.TestDataSet;
054: import junitx.ddtunit.data.TestGroupDataSet;
055: import junitx.ddtunit.data.TypedObject;
056: import junitx.ddtunit.data.processing.IParser;
057: import junitx.ddtunit.data.processing.parser.ParserImpl;
058:
059: public class DbDataRestorer implements IDataSetSerializer {
060: private static final String LF = System
061: .getProperty("line.separator");
062:
063: private IParser parser;
064:
065: public DbDataRestorer() {
066: this .parser = new ParserImpl();
067: }
068:
069: public TestClusterDataSet restore(String resource, String clusterId) {
070: TestClusterDataSet clusterDataSet = null;
071: Connection connect = createConnection();
072: try {
073: String selectData = "select clusterid, groupid, testid, ogroup"
074: + ", otype, id, class_type, action, xml from TESTDATA_VIEW "
075: + "where clusterid=? ";
076: PreparedStatement dbData = connect
077: .prepareStatement(selectData);
078: dbData.setString(1, clusterId);
079: ResultSet resultSet = dbData.executeQuery();
080: clusterDataSet = new TestClusterDataSet(clusterId, null);
081: String oldGroupId = "<<<OldGroupId>>>";
082: String oldTestId = "<<<OldTestId>>>";
083: TestGroupDataSet groupDataSet = null;
084: TestDataSet testDataSet = null;
085: while (resultSet.next()) {
086: String groupId = resultSet.getString("groupid");
087: String testId = resultSet.getString("testid");
088: String oType = resultSet.getString("otype");
089:
090: String id = resultSet.getString("id");
091: String type = resultSet.getString("class_type");
092: String action = resultSet.getString("action");
093: String xml = resultSet.getString("xml");
094: if (!oldGroupId.equals(groupId)) {
095: // on groupid change store old structure and create new
096: if (groupDataSet != null) {
097: // every group change adds up in a test change as well
098: if (testDataSet != null) {
099: groupDataSet.put(oldTestId, testDataSet);
100: }
101: clusterDataSet.put(oldGroupId, groupDataSet);
102: }
103: oldGroupId = groupId;
104: groupDataSet = new TestGroupDataSet(groupId,
105: clusterDataSet);
106: oldTestId = testId;
107: testDataSet = new TestDataSet(testId, groupDataSet);
108: addParsedObject(testDataSet, oType, id, type,
109: action, xml);
110: } else {
111: if (!oldTestId.equals(testId)) {
112: // on testid change store dataset in groupDataSet and
113: // create new
114: if (testDataSet != null) {
115: groupDataSet.put(oldTestId, testDataSet);
116: }
117: oldTestId = testId;
118: testDataSet = new TestDataSet(testId,
119: groupDataSet);
120: }
121: addParsedObject(testDataSet, oType, id, type,
122: action, xml);
123: }
124: }
125: // do not forget the last open entry in the dataset
126: if (testDataSet != null) {
127: groupDataSet.put(oldTestId, testDataSet);
128: clusterDataSet.put(oldGroupId, groupDataSet);
129: }
130: } catch (SQLException ex) {
131: throw new DDTTestDataException(
132: "Could not access db test data", ex);
133: } finally {
134: if (connect != null) {
135: try {
136: connect.close();
137: } catch (SQLException ex) {
138: // ignore exception
139: }
140: }
141: }
142: return clusterDataSet;
143: }
144:
145: /**
146: * Create xml testdata resource for specified clusterId.
147: *
148: * @param clusterId to create xml resource for
149: * @return StringBuffer representation of xml resource
150: */
151: public StringBuffer createXml(String clusterId) {
152: StringBuffer sb = new StringBuffer();
153: sb
154: .append("<?xml version=\"1.0\" ?>" + LF)
155: .append(
156: "<ddtunit xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\""
157: + LF)
158: .append(
159: " xsi:noNamespaceSchemaLocation=\"http://ddtunit.sourceforge.net/ddtunit.xsd\">"
160: + LF).append(" <cluster id=\"")
161: .append(clusterId).append("\">" + LF);
162:
163: Connection connect = createConnection();
164: try {
165: String selectData = "select clusterid, groupid, testid, ogroup"
166: + ", otype, id, class_type, action, xml from TESTDATA_VIEW "
167: + "where clusterid=? ";
168: PreparedStatement dbData = connect
169: .prepareStatement(selectData);
170: dbData.setString(1, clusterId);
171: ResultSet resultSet = dbData.executeQuery();
172: String oldGroupId = "<<<OldGroupId>>>";
173: String oldTestId = "<<<OldTestId>>>";
174: String oldOGroup = "<<<OldOGroup>>>";
175: boolean startGroups = true;
176: boolean startTests = true;
177: boolean startOGroups = true;
178: while (resultSet.next()) {
179: String groupId = resultSet.getString("groupid");
180: String testId = resultSet.getString("testid");
181: String oType = resultSet.getString("otype");
182: String oGroup = resultSet.getString("ogroup");
183:
184: String id = resultSet.getString("id");
185: String type = resultSet.getString("class_type");
186: String action = resultSet.getString("action");
187: String xml = resultSet.getString("xml");
188: // ----------------------------------------------------
189: Pattern idPattern = Pattern.compile("id=\"\\w*\"");
190: Matcher idMatcher = idPattern.matcher(xml);
191: String replacement = idMatcher.replaceFirst("id=\""
192: + id + "\"");
193: if ("noaction".equals(action)) {
194: replacement = replacement.replaceFirst("<obj", "<"
195: + oType);
196: } else {
197: replacement = replacement.replaceFirst("<obj", "<"
198: + oType + " action=\"" + action + "\"");
199: }
200: // ----------------------------------------------------
201: replacement = replacement.replaceFirst("obj>", oType
202: + ">");
203: if (!oldGroupId.equals(groupId)) {
204: // on groupid change close old structure and open new
205: if (!startGroups) {
206: startGroups = false;
207: sb.append(" </").append(oldOGroup)
208: .append(">" + LF);
209: sb.append(" </test>" + LF);
210: sb.append(" </group>" + LF);
211: }
212: sb.append(" <group id=\"").append(groupId)
213: .append("\">" + LF);
214: startGroups = false;
215: oldGroupId = groupId;
216: }
217: if (!oldTestId.equals(testId)) {
218: // on testid change store dataset in groupDataSet and
219: // create new
220: if (!startTests) {
221: startTests = false;
222: sb.append(" </").append(oldOGroup)
223: .append(">" + LF);
224: sb.append(" </test>" + LF);
225: }
226: oldTestId = testId;
227: sb.append(" <test id=\"").append(testId)
228: .append("\">" + LF);
229: startTests = false;
230: startOGroups = true;
231: }
232: if (!oldOGroup.equals(oGroup)) {
233: if (!startOGroups) {
234: sb.append(" </").append(oldOGroup)
235: .append(">" + LF);
236: startOGroups = false;
237: }
238: sb.append(" <").append(oGroup).append(
239: ">" + LF);
240: startOGroups = false;
241: oldOGroup = oGroup;
242: }
243: sb.append(" " + replacement + LF);
244: }
245: sb.append(" </").append(oldOGroup).append(">" + LF);
246: sb.append(" </test>" + LF);
247: sb.append(" </group>" + LF);
248: sb.append(" </cluster>" + LF);
249: } catch (SQLException ex) {
250: throw new DDTTestDataException(
251: "Could not access db test data", ex);
252: } finally {
253: if (connect != null) {
254: try {
255: connect.close();
256: } catch (SQLException ex) {
257: // ignore exception
258: }
259: }
260: }
261: return sb;
262: }
263:
264: private Connection createConnection() {
265: Properties dbProp = new Properties();
266: dbProp.put("userid", "sa");
267: dbProp.put("password", "");
268:
269: try {
270: Class.forName("org.hsqldb.jdbcDriver");
271: Connection connect = DriverManager.getConnection(
272: "jdbc:hsqldb:hsql://localhost/ddt", dbProp);
273: return connect;
274: } catch (ClassNotFoundException ex) {
275: throw new DDTTestDataException(
276: "Could not create connection to db repository", ex);
277: } catch (SQLException ex) {
278: throw new DDTTestDataException(
279: "Could not create connection to db repository", ex);
280: }
281: }
282:
283: /**
284: * Retrieve single object instance from database.
285: *
286: * @param id used to identify object
287: * @param type of object to retrieve
288: * @return TypedObject created by repository
289: */
290: public TypedObject getObject(String id, String type) {
291: TypedObject tObj = null;
292: Connection connect = createConnection();
293: try {
294: String selectData = "select id, class_type, xml from objects_tab"
295: + " where id=? and class_type=?";
296: PreparedStatement dbData = connect
297: .prepareStatement(selectData);
298: dbData.setString(1, id);
299: dbData.setString(2, type);
300: ResultSet resultSet = dbData.executeQuery();
301: resultSet.next();
302: String xml = resultSet.getString("xml");
303: tObj = this .parser.parseElement(xml, true);
304: } catch (SQLException ex) {
305: throw new DDTTestDataException(
306: "Error during access on db testdata", ex);
307: } finally {
308: if (connect != null) {
309: try {
310: connect.close();
311: } catch (SQLException ex) {
312: // ignore exception
313: }
314: }
315: }
316: return tObj;
317: }
318:
319: /**
320: * @param testDataSet
321: * @param oType specifies tag type: obj, assert, exception
322: * @param id of object for reference usage
323: * @param type of object used as additional reference attribute
324: * @param xml
325: */
326: private void addParsedObject(TestDataSet testDataSet, String oType,
327: String id, String type, String action, String xml) {
328: TypedObject tObj = this .parser.parseElement(xml, true);
329: tObj.setId(id);
330: tObj.setType(type);
331: if ("obj".equals(oType)) {
332: testDataSet.putObject(id, tObj);
333: } else if ("assert".equals(oType)) {
334: ObjectAsserter asserter = new ObjectAsserter(id, type,
335: action);
336: asserter.setValue(tObj.getValue());
337: testDataSet.putAssert(id, asserter);
338: } else if ("exception".equals(oType)) {
339: ExceptionAsserter asserter = new ExceptionAsserter(id,
340: type, action);
341: asserter.setValue(tObj.getValue());
342: testDataSet.putAssert(id, asserter);
343: } else {
344: throw new DDTTestDataException("Wrong tag type " + oType);
345: }
346: }
347:
348: }
|