001: package com.mockrunner.jdbc;
002:
003: import java.io.File;
004: import java.io.FileNotFoundException;
005: import java.util.Iterator;
006: import java.util.List;
007:
008: import org.jdom.Document;
009: import org.jdom.Element;
010: import org.jdom.input.SAXBuilder;
011:
012: import com.mockrunner.base.NestedApplicationException;
013: import com.mockrunner.mock.jdbc.MockResultSet;
014: import com.mockrunner.util.common.FileUtil;
015:
016: /**
017: * Can be used to create a <code>ResultSet</code> based on
018: * a an XML <code>Document</code> of the proper format. You can specify
019: * the dialect, for proper parsing of the document. Furthermore you can
020: * specify the dialect of the <code>ResultSet</code>, which determines
021: * the expected format of the XML <code>Document</code> and whether or not
022: * the column entries should be trimmed (default is <code>true</code>).
023: * The file can be specified directly or by its name. The class
024: * tries to find the file in the absolut or relative path and
025: * (if not found) by calling <code>getResource</code>. Note that the
026: * file must exist in the local file system and cannot be loaded from
027: * inside a jar archive.
028: */
029: public class XMLResultSetFactory implements ResultSetFactory {
030: public final static int SYBASE_DIALECT = 0;
031:
032: private File file = null;
033: private String fileName = null;
034: private boolean trim = true;
035: private int dialect = SYBASE_DIALECT;
036:
037: public XMLResultSetFactory(String fileName) {
038: this .file = new File(fileName);
039: this .fileName = fileName;
040: }
041:
042: public XMLResultSetFactory(File file) {
043: this .file = file;
044: this .fileName = file.getAbsolutePath();
045: }
046:
047: /**
048: * Makes and returns a MockResultSet created from
049: * an existing and valid XML <code>Document</code>.
050: *
051: * @return a new MockResultSet
052: */
053: public MockResultSet create(String id) {
054: MockResultSet resultSet;
055:
056: switch (dialect) {
057: case SYBASE_DIALECT:
058: resultSet = createSybaseResultSet(id);
059: break;
060: default:
061: resultSet = createSybaseResultSet(id);
062: break;
063: }
064:
065: return resultSet;
066: }
067:
068: /**
069: * Get the <code>File</code> being used to read in the
070: * <code>ResultSet</code>. Returns <code>null</code> if
071: * the file does not exist.
072: * @return the file
073: */
074: public File getXMLFile() {
075: if (file.exists() && file.isFile()) {
076: return file;
077: } else {
078: try {
079: file = FileUtil.findFile(file.getPath());
080: return file;
081: } catch (FileNotFoundException exc) {
082: throw new RuntimeException("Could not find: "
083: + file.getPath());
084: }
085: }
086: }
087:
088: /**
089: * Set if the column entries should be trimmed.
090: * Default is <code>true</code>.
091: *
092: * @param trim
093: */
094: public void setTrim(boolean trim) {
095: this .trim = trim;
096: }
097:
098: /**
099: * Get whether or not trim is true or false.
100: */
101: public boolean getTrim() {
102: return trim;
103: }
104:
105: /**
106: * Set the dialect of the XML <code>Document</code>. Can be
107: * different for different database systems.
108: * Will determine the expected XML format for
109: * the <code>ResultSet</code>. <code>SYBASE_DIALECT</code>
110: * is the <b>only</b> accepted dialect for now.
111: * @param dialect int specifying which createXXXResultSet
112: * method to call.
113: */
114: public void setDialect(int dialect) {
115: //this.dialect = dialect;
116: this .dialect = SYBASE_DIALECT;
117: }
118:
119: /**
120: * Get the dialect of the XML <code>Document</code.
121: *
122: * @return dialect
123: */
124: public int getDialect() {
125: return dialect;
126: }
127:
128: /**
129: * Return a MockResultSet with proper column names and
130: * rows based on the XML <code>Document</code>.
131: * @return MockResultSet Results read from XML
132: * <code>Document</code>.
133: */
134: public MockResultSet createSybaseResultSet(String id) {
135: MockResultSet resultSet = new MockResultSet(id);
136: SAXBuilder builder = new SAXBuilder();
137: Document doc = null;
138: File fileToParse = getXMLFile();
139: if (null == fileToParse) {
140: throw new RuntimeException("File " + fileName
141: + " not found.");
142: }
143: try {
144: doc = builder.build(fileToParse);
145: Element root = doc.getRootElement();
146: List rows = root.getChildren("row");
147: Iterator ri = rows.iterator();
148: boolean firstIteration = true;
149: int colNum = 0;
150: while (ri.hasNext()) {
151: Element cRow = (Element) ri.next();
152: List cRowChildren = cRow.getChildren();
153: Iterator cri = cRowChildren.iterator();
154: if (firstIteration) {
155: List columns = cRowChildren;
156: Iterator ci = columns.iterator();
157:
158: while (ci.hasNext()) {
159: Element ccRow = (Element) ci.next();
160: resultSet.addColumn(ccRow.getName());
161: colNum++;
162: }
163: firstIteration = false;
164: }
165: String[] cRowValues = new String[colNum];
166: int curCol = 0;
167: while (cri.hasNext()) {
168: Element crValue = (Element) cri.next();
169: String value = trim ? crValue.getTextTrim()
170: : crValue.getText();
171: cRowValues[curCol] = value;
172: curCol++;
173: }
174: resultSet.addRow(cRowValues);
175: }
176: } catch (Exception exc) {
177: throw new NestedApplicationException(
178: "Failure while reading from XML file", exc);
179: }
180: return resultSet;
181: }
182: }
|