001: package com.mockrunner.jdbc;
002:
003: import java.io.File;
004: import java.io.FileNotFoundException;
005: import java.util.HashMap;
006: import java.util.List;
007: import java.util.Map;
008:
009: import com.mockrunner.mock.jdbc.MockResultSet;
010: import com.mockrunner.util.common.FileUtil;
011: import com.mockrunner.util.common.StringUtil;
012:
013: /**
014: * Can be used to create a <code>ResultSet</code> based on
015: * a table specified in a CSV file. You can specify the delimiter
016: * of the columns (default is <code>;</code>). Furthermore you can specify if the first line
017: * contains the column names (default is <code>false</code>) and if
018: * the column entries should be trimmed (default is <code>true</code>).
019: * With {@link #setUseTemplates} you can enable template replacement in the
020: * files (default is <code>false</code>, i.e. templates are disabled).
021: * The file can be specified directly or by its name. The class
022: * tries to find the file in the absolut or relative path and
023: * (if not found) by calling <code>getResource</code>. Note that the
024: * file must exist in the local file system and cannot be loaded from
025: * inside a jar archive.
026: */
027: public class FileResultSetFactory implements ResultSetFactory {
028: private File file = null;
029: private String delimiter = ";";
030: private boolean firstLineContainsColumnNames = false;
031: private boolean trim = true;
032: private boolean useTemplates = false;
033: private String templateMarker = null;
034: private Map templates = null;
035:
036: public FileResultSetFactory(String fileName) {
037: this (new File(fileName));
038: }
039:
040: public FileResultSetFactory(File file) {
041: this .file = file;
042: setDefaultTemplateConfiguration();
043: }
044:
045: /**
046: * Get the <code>File</code> being used to read in the
047: * <code>ResultSet</code>. Throws a <code>RuntimeException</code>
048: * if the file does not exist.
049: * @return the file
050: */
051: public File getFile() {
052: if (file.exists() && file.isFile()) {
053: return file;
054: } else {
055: try {
056: file = FileUtil.findFile(file.getPath());
057: return file;
058: } catch (FileNotFoundException exc) {
059: throw new RuntimeException("Could not find: "
060: + file.getPath());
061: }
062: }
063: }
064:
065: /**
066: * Set the delimiter. Default is <i>";"</i>.
067: * @param delimiter the delimiter
068: */
069: public void setDelimiter(String delimiter) {
070: this .delimiter = delimiter;
071: }
072:
073: /**
074: * Set if the first line contains the column names.
075: * Default is <code>false</code>.
076: */
077: public void setFirstLineContainsColumnNames(
078: boolean firstLineContainsColumnNames) {
079: this .firstLineContainsColumnNames = firstLineContainsColumnNames;
080: }
081:
082: /**
083: * Set if the column entries should be trimmed.
084: * Default is <code>true</code>.
085: */
086: public void setTrim(boolean trim) {
087: this .trim = trim;
088: }
089:
090: /**
091: * Set this to <code>true</code> to allow the use of templates
092: * in data files. A template is identified by a marker followed
093: * by a label. The template is replaced by a predefined string in
094: * the corresponding data file. E.g. with the default configuration,
095: * <code>$defaultString</code> is replaced by an empty string
096: * in the file.
097: * The default configuration which is automatically set uses
098: * <code>$</code> as a marker. See {@link #setDefaultTemplateConfiguration}
099: * for details. You can also set a custom template configuration using
100: * {@link #setTemplateConfiguration(String, Map)}.
101: * Default is <code>false</code>, i.e. templates are disabled.
102: * @param useTemplates set <code>true</code> to enable templates.
103: */
104: public void setUseTemplates(boolean useTemplates) {
105: this .useTemplates = useTemplates;
106: }
107:
108: /**
109: * This method sets a custom template configuration. See
110: * {@link #setUseTemplates} for an explanation how templates work.
111: * <code>marker + map key</code> is replaced by the corresponding <code>map
112: * value</code> in the data files.
113: * Please use {@link #setDefaultTemplateConfiguration} to set a
114: * default configuration.
115: * @param marker the custom marker replacing the default <code>$</code>
116: * @param templates the custom template map
117: */
118: public void setTemplateConfiguration(String marker, Map templates) {
119: this .templates = templates;
120: this .templateMarker = marker;
121: }
122:
123: /**
124: * This method sets the default template configuration. See
125: * {@link #setUseTemplates} for an explanation how templates work.
126: * The default marker is <code>$</code> and the default templates are:<br><br>
127: * <code>$defaultString</code> is replaced by an empty string<br>
128: * <code>$defaultDate</code> is replaced by <code>1970-01-01</code><br>
129: * <code>$defaultInteger</code> is replaced by <code>0</code><br><br>
130: * Please use {@link #setTemplateConfiguration(String, Map)} to set a
131: * custom marker and custom templates.
132: */
133: public void setDefaultTemplateConfiguration() {
134: Map templates = new HashMap();
135: templates.put("defaultString", "");
136: templates.put("defaultDate", "1970-01-01");
137: templates.put("defaultInteger", "0");
138: setTemplateConfiguration("$", templates);
139: }
140:
141: public MockResultSet create(String id) {
142: MockResultSet resultSet = new MockResultSet(id);
143: File fileToRead = getFile();
144: List lines = FileUtil.getLinesFromFile(fileToRead);
145:
146: int firstLineNumber = 0;
147: if (firstLineContainsColumnNames) {
148: String firstLine = (String) lines.get(firstLineNumber);
149: firstLineNumber++;
150: String[] names = StringUtil.split(firstLine, delimiter,
151: trim);
152: for (int ii = 0; ii < names.length; ii++) {
153: resultSet.addColumn(names[ii]);
154: }
155: }
156: for (int ii = firstLineNumber; ii < lines.size(); ii++) {
157: String line = (String) lines.get(ii);
158: String[] values = StringUtil.split(line, delimiter, trim);
159: if (useTemplates) {
160: for (int yy = 0; yy < values.length; yy++) {
161: if (null != values[yy]) {
162: if (values[yy].startsWith(templateMarker)
163: && templates.containsKey(values[yy]
164: .substring(1))) {
165: values[yy] = (String) templates
166: .get(values[yy].substring(1));
167: }
168: }
169: }
170: }
171: resultSet.addRow(values);
172: }
173: return resultSet;
174: }
175: }
|