001: /*
002: * TextRowDataConverter.java
003: *
004: * This file is part of SQL Workbench/J, http://www.sql-workbench.net
005: *
006: * Copyright 2002-2008, Thomas Kellerer
007: * No part of this code maybe reused without the permission of the author
008: *
009: * To contact the author please send an email to: support@sql-workbench.net
010: *
011: */
012: package workbench.db.exporter;
013:
014: import java.io.File;
015: import workbench.log.LogMgr;
016: import workbench.storage.RowData;
017: import workbench.util.CharacterRange;
018: import workbench.util.QuoteEscapeType;
019: import workbench.util.SqlUtil;
020: import workbench.util.StrBuffer;
021: import workbench.util.StringUtil;
022:
023: /**
024: *
025: * @author support@sql-workbench.net
026: */
027: public class TextRowDataConverter extends RowDataConverter {
028: private String delimiter = "\t";
029: private String quoteCharacter = null;
030: private boolean quoteAlways = false;
031: private CharacterRange escapeRange = null;
032: private String additionalEncodeCharacters = null;
033: private String delimiterAndQuote = null;
034: private String lineEnding = StringUtil.LINE_TERMINATOR;
035: private boolean writeBlobFiles = true;
036: private boolean writeClobFiles = false;
037: private QuoteEscapeType quoteEscape = QuoteEscapeType.none;
038:
039: public TextRowDataConverter() {
040: super ();
041: }
042:
043: public void setWriteClobToFile(boolean flag) {
044: this .writeClobFiles = flag;
045: }
046:
047: public void setWriteBlobToFile(boolean flag) {
048: writeBlobFiles = flag;
049: }
050:
051: public StrBuffer getEnd(long totalRows) {
052: return null;
053: }
054:
055: public void setQuoteEscaping(QuoteEscapeType type) {
056: this .quoteEscape = type;
057: }
058:
059: public QuoteEscapeType getQuoteEscaping() {
060: return this .quoteEscape;
061: }
062:
063: public StrBuffer convertRowData(RowData row, long rowIndex) {
064: int count = this .metaData.getColumnCount();
065: StrBuffer result = new StrBuffer(count * 30);
066: boolean canQuote = this .quoteCharacter != null;
067: int currentColIndex = 0;
068:
069: for (int c = 0; c < count; c++) {
070: if (!this .includeColumnInExport(c))
071: continue;
072: if (currentColIndex > 0) {
073: result.append(this .delimiter);
074: }
075: int colType = this .metaData.getColumnType(c);
076: String value = null;
077:
078: boolean addQuote = quoteAlways;
079:
080: if (writeBlobFiles && SqlUtil.isBlobType(colType)) {
081: File blobFile = createBlobFile(row, c, rowIndex);
082:
083: value = blobFile.getName();
084: try {
085: writeBlobFile(row.getValue(c), blobFile);
086: } catch (Exception e) {
087: LogMgr.logError(
088: "TextRowDataConverter.convertRowData",
089: "Error writing BLOB file", e);
090: throw new RuntimeException(
091: "Error writing BLOB file", e);
092: }
093:
094: } else if (writeClobFiles
095: && SqlUtil.isClobType(colType,
096: this .originalConnection.getDbSettings())) {
097: Object clobData = row.getValue(c);
098: if (clobData != null) {
099: File clobFile = createBlobFile(row, c, rowIndex);
100: value = clobFile.getName();
101: try {
102: String s = clobData.toString();
103: writeClobFile(s, clobFile, this .encoding);
104: } catch (Exception e) {
105: throw new RuntimeException(
106: "Error writing CLOB file", e);
107: }
108: }
109: } else {
110: value = this .getValueAsFormattedString(row, c);
111: }
112:
113: if (value == null)
114: value = "";
115:
116: if (SqlUtil.isCharacterType(colType)) {
117: boolean containsDelimiter = value
118: .indexOf(this .delimiter) > -1;
119: addQuote = (this .quoteAlways || (canQuote && containsDelimiter));
120:
121: if (this .escapeRange != null
122: && this .escapeRange != CharacterRange.RANGE_NONE) {
123: if (addQuote) {
124: value = StringUtil.escapeUnicode(value,
125: this .quoteCharacter, this .escapeRange);
126: } else {
127: value = StringUtil.escapeUnicode(value,
128: this .delimiterAndQuote,
129: this .escapeRange);
130: }
131: }
132: if (this .quoteCharacter != null
133: && this .quoteEscape != QuoteEscapeType.none
134: && value.indexOf(this .quoteCharacter) > -1) {
135: if (this .quoteEscape == QuoteEscapeType.escape) {
136: value = StringUtil.replace(value,
137: this .quoteCharacter, "\\"
138: + this .quoteCharacter);
139: } else {
140: value = StringUtil.replace(value,
141: this .quoteCharacter,
142: this .quoteCharacter
143: + this .quoteCharacter);
144: }
145: }
146: }
147:
148: if (addQuote)
149: result.append(this .quoteCharacter);
150:
151: result.append(value);
152:
153: if (addQuote)
154: result.append(this .quoteCharacter);
155:
156: currentColIndex++;
157: }
158: result.append(lineEnding);
159: return result;
160: }
161:
162: public void setLineEnding(String ending) {
163: if (ending != null)
164: this .lineEnding = ending;
165: }
166:
167: public StrBuffer getStart() {
168: this .setAdditionalEncodeCharacters();
169:
170: if (!this .writeHeader)
171: return null;
172:
173: StrBuffer result = new StrBuffer();
174: int colCount = this .metaData.getColumnCount();
175: boolean first = true;
176: for (int c = 0; c < colCount; c++) {
177: if (!this .includeColumnInExport(c))
178: continue;
179: String name = this .metaData.getColumnName(c);
180: if (first) {
181: first = false;
182: } else {
183: result.append(this .delimiter);
184: }
185: result.append(name);
186: }
187: result.append(lineEnding);
188: return result;
189: }
190:
191: public void setDelimiter(String delimit) {
192: if (delimit == null || delimit.trim().length() == 0)
193: return;
194:
195: if (delimit.equals("\\t")) {
196: this .delimiter = "\t";
197: } else {
198: this .delimiter = delimit;
199: }
200: setAdditionalEncodeCharacters();
201: }
202:
203: private void setAdditionalEncodeCharacters() {
204: if (this .escapeRange == null)
205: return;
206: if (this .quoteCharacter == null && this .delimiter == null)
207: return;
208:
209: this .delimiterAndQuote = this .delimiter;
210: // If values should always be quoted, then we need to
211: // escape the quote character in values
212: if (this .quoteCharacter != null) {
213: this .additionalEncodeCharacters = this .quoteCharacter;
214: this .delimiterAndQuote += this .quoteCharacter;
215: }
216:
217: }
218:
219: public void setQuoteCharacter(String quote) {
220: if (quote != null && quote.trim().length() > 0) {
221: this .quoteCharacter = quote;
222: setAdditionalEncodeCharacters();
223: }
224: }
225:
226: public void setQuoteAlways(boolean flag) {
227: this .quoteAlways = flag;
228: }
229:
230: /**
231: * Define the range of characters to be escaped
232: * @see workbench.util.StringUtil
233: */
234: public void setEscapeRange(CharacterRange range) {
235: this.escapeRange = range;
236: }
237:
238: }
|