Coverage Report - au.com.bytecode.opencsv.CSVWriter
 
Classes in this File Line Coverage Branch Coverage Complexity
CSVWriter
0%
0/117
0%
0/82
4.125
 
 1  
 package au.com.bytecode.opencsv;
 2  
 
 3  
 /**
 4  
  Copyright 2005 Bytecode Pty Ltd.
 5  
 
 6  
  Licensed under the Apache License, Version 2.0 (the "License");
 7  
  you may not use this file except in compliance with the License.
 8  
  You may obtain a copy of the License at
 9  
 
 10  
  http://www.apache.org/licenses/LICENSE-2.0
 11  
 
 12  
  Unless required by applicable law or agreed to in writing, software
 13  
  distributed under the License is distributed on an "AS IS" BASIS,
 14  
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 15  
  See the License for the specific language governing permissions and
 16  
  limitations under the License.
 17  
  */
 18  
 
 19  
 import java.io.*;
 20  
 import java.math.BigDecimal;
 21  
 import java.sql.*;
 22  
 import java.text.SimpleDateFormat;
 23  
 import java.util.List;
 24  
 
 25  
 /**
 26  
  * A very simple CSV writer released under a commercial-friendly license.
 27  
  *
 28  
  * @author Glen Smith
 29  
  *
 30  
  */
 31  
 public class CSVWriter implements Closeable {
 32  
     
 33  
     public static final int INITIAL_STRING_SIZE = 128;
 34  
 
 35  
         private Writer rawWriter;
 36  
 
 37  
     private PrintWriter pw;
 38  
 
 39  
     private char separator;
 40  
 
 41  
     private char quotechar;
 42  
     
 43  
     private char escapechar;
 44  
     
 45  
     private String lineEnd;
 46  
 
 47  
     /** The character used for escaping quotes. */
 48  
     public static final char DEFAULT_ESCAPE_CHARACTER = '"';
 49  
 
 50  
     /** The default separator to use if none is supplied to the constructor. */
 51  
     public static final char DEFAULT_SEPARATOR = ',';
 52  
 
 53  
     /**
 54  
      * The default quote character to use if none is supplied to the
 55  
      * constructor.
 56  
      */
 57  
     public static final char DEFAULT_QUOTE_CHARACTER = '"';
 58  
     
 59  
     /** The quote constant to use when you wish to suppress all quoting. */
 60  
     public static final char NO_QUOTE_CHARACTER = '\u0000';
 61  
     
 62  
     /** The escape constant to use when you wish to suppress all escaping. */
 63  
     public static final char NO_ESCAPE_CHARACTER = '\u0000';
 64  
     
 65  
     /** Default line terminator uses platform encoding. */
 66  
     public static final String DEFAULT_LINE_END = "\n";
 67  
     
 68  
     /**
 69  
      * Constructs CSVWriter using a comma for the separator.
 70  
      *
 71  
      * @param writer
 72  
      *            the writer to an underlying CSV source.
 73  
      */
 74  
     public CSVWriter(Writer writer) {
 75  0
         this(writer, DEFAULT_SEPARATOR);
 76  0
     }
 77  
 
 78  
     /**
 79  
      * Constructs CSVWriter with supplied separator.
 80  
      *
 81  
      * @param writer
 82  
      *            the writer to an underlying CSV source.
 83  
      * @param separator
 84  
      *            the delimiter to use for separating entries.
 85  
      */
 86  
     public CSVWriter(Writer writer, char separator) {
 87  0
         this(writer, separator, DEFAULT_QUOTE_CHARACTER);
 88  0
     }
 89  
 
 90  
     /**
 91  
      * Constructs CSVWriter with supplied separator and quote char.
 92  
      *
 93  
      * @param writer
 94  
      *            the writer to an underlying CSV source.
 95  
      * @param separator
 96  
      *            the delimiter to use for separating entries
 97  
      * @param quotechar
 98  
      *            the character to use for quoted elements
 99  
      */
 100  
     public CSVWriter(Writer writer, char separator, char quotechar) {
 101  0
             this(writer, separator, quotechar, DEFAULT_ESCAPE_CHARACTER);
 102  0
     }
 103  
 
 104  
     /**
 105  
      * Constructs CSVWriter with supplied separator and quote char.
 106  
      *
 107  
      * @param writer
 108  
      *            the writer to an underlying CSV source.
 109  
      * @param separator
 110  
      *            the delimiter to use for separating entries
 111  
      * @param quotechar
 112  
      *            the character to use for quoted elements
 113  
      * @param escapechar
 114  
      *            the character to use for escaping quotechars or escapechars
 115  
      */
 116  
     public CSVWriter(Writer writer, char separator, char quotechar, char escapechar) {
 117  0
         this(writer, separator, quotechar, escapechar, DEFAULT_LINE_END);
 118  0
     }
 119  
     
 120  
     
 121  
     /**
 122  
      * Constructs CSVWriter with supplied separator and quote char.
 123  
      *
 124  
      * @param writer
 125  
      *            the writer to an underlying CSV source.
 126  
      * @param separator
 127  
      *            the delimiter to use for separating entries
 128  
      * @param quotechar
 129  
      *            the character to use for quoted elements
 130  
      * @param lineEnd
 131  
      *                           the line feed terminator to use
 132  
      */
 133  
     public CSVWriter(Writer writer, char separator, char quotechar, String lineEnd) {
 134  0
         this(writer, separator, quotechar, DEFAULT_ESCAPE_CHARACTER, lineEnd);
 135  0
     }   
 136  
     
 137  
     
 138  
     
 139  
     /**
 140  
      * Constructs CSVWriter with supplied separator, quote char, escape char and line ending.
 141  
      *
 142  
      * @param writer
 143  
      *            the writer to an underlying CSV source.
 144  
      * @param separator
 145  
      *            the delimiter to use for separating entries
 146  
      * @param quotechar
 147  
      *            the character to use for quoted elements
 148  
      * @param escapechar
 149  
      *            the character to use for escaping quotechars or escapechars
 150  
      * @param lineEnd
 151  
      *                           the line feed terminator to use
 152  
      */
 153  0
     public CSVWriter(Writer writer, char separator, char quotechar, char escapechar, String lineEnd) {
 154  0
         this.rawWriter = writer;
 155  0
         this.pw = new PrintWriter(writer);
 156  0
         this.separator = separator;
 157  0
         this.quotechar = quotechar;
 158  0
         this.escapechar = escapechar;
 159  0
         this.lineEnd = lineEnd;
 160  0
     }
 161  
     
 162  
     /**
 163  
      * Writes the entire list to a CSV file. The list is assumed to be a
 164  
      * String[]
 165  
      *
 166  
      * @param allLines
 167  
      *            a List of String[], with each String[] representing a line of
 168  
      *            the file.
 169  
      */
 170  
     public void writeAll(List<String[]> allLines)  {
 171  0
             for (String[] line : allLines) {
 172  0
                         writeNext(line);
 173  
                 }
 174  0
     }
 175  
 
 176  
     protected void writeColumnNames(ResultSetMetaData metadata)
 177  
             throws SQLException {
 178  
             
 179  0
             int columnCount =  metadata.getColumnCount();
 180  
             
 181  0
             String[] nextLine = new String[columnCount];
 182  0
                 for (int i = 0; i < columnCount; i++) {
 183  0
                         nextLine[i] = metadata.getColumnName(i + 1);
 184  
                 }
 185  0
             writeNext(nextLine);
 186  0
     }
 187  
     
 188  
     /**
 189  
      * Writes the entire ResultSet to a CSV file.
 190  
      *
 191  
      * The caller is responsible for closing the ResultSet.
 192  
      *
 193  
      * @param rs the recordset to write
 194  
      * @param includeColumnNames true if you want column names in the output, false otherwise
 195  
      *
 196  
      * @throws java.io.IOException thrown by getColumnValue
 197  
      * @throws java.sql.SQLException thrown by getColumnValue
 198  
      */
 199  
     public void writeAll(java.sql.ResultSet rs, boolean includeColumnNames)  throws SQLException, IOException {
 200  
             
 201  0
             ResultSetMetaData metadata = rs.getMetaData();
 202  
             
 203  
             
 204  0
             if (includeColumnNames) {
 205  0
                         writeColumnNames(metadata);
 206  
                 }
 207  
 
 208  0
             int columnCount =  metadata.getColumnCount();
 209  
             
 210  0
             while (rs.next())
 211  
             {
 212  0
                 String[] nextLine = new String[columnCount];
 213  
                 
 214  0
                 for (int i = 0; i < columnCount; i++) {
 215  0
                                 nextLine[i] = getColumnValue(rs, metadata.getColumnType(i + 1), i + 1);
 216  
                         }
 217  
                 
 218  0
                     writeNext(nextLine);
 219  0
             }
 220  0
     }
 221  
     
 222  
     private static String getColumnValue(ResultSet rs, int colType, int colIndex)
 223  
                     throws SQLException, IOException {
 224  
 
 225  0
             String value = "";
 226  
             
 227  0
                 switch (colType)
 228  
                 {
 229  
                         case Types.BIT:
 230  
             case Types.JAVA_OBJECT:
 231  0
                                 Object obj = rs.getObject(colIndex);
 232  0
                                 if (obj != null) {
 233  0
                                         value = String.valueOf(obj);
 234  
                                 }
 235  
                         break;
 236  
                         case Types.BOOLEAN:
 237  0
                                 boolean b = rs.getBoolean(colIndex);
 238  0
                                 if (!rs.wasNull()) {
 239  0
                                         value = Boolean.valueOf(b).toString();
 240  
                                 }
 241  
                         break;
 242  
                         case Types.CLOB:
 243  0
                                 Clob c = rs.getClob(colIndex);
 244  0
                                 if (c != null) {
 245  0
                                         value = read(c);
 246  
                                 }
 247  
                         break;
 248  
                         case Types.BIGINT:
 249  0
                                 long lv = rs.getLong(colIndex);
 250  0
                                 if (!rs.wasNull()) {
 251  0
                                         value = Long.toString(lv);
 252  
                                 }
 253  
                                 break;
 254  
                         case Types.DECIMAL:
 255  
                         case Types.DOUBLE:
 256  
                         case Types.FLOAT:
 257  
                         case Types.REAL:
 258  
                         case Types.NUMERIC:
 259  0
                                 BigDecimal bd = rs.getBigDecimal(colIndex);
 260  0
                                 if (bd != null) {
 261  0
                                         value = bd.toString();
 262  
                                 }
 263  
                         break;
 264  
                         case Types.INTEGER:
 265  
                         case Types.TINYINT:
 266  
                         case Types.SMALLINT:
 267  0
                                 int intValue = rs.getInt(colIndex);
 268  0
                                 if (!rs.wasNull()) {
 269  0
                                         value = Integer.toString(intValue);
 270  
                                 }
 271  
                         break;
 272  
                         case Types.DATE:
 273  0
                                 java.sql.Date date = rs.getDate(colIndex);
 274  0
                                 if (date != null) {
 275  0
                                     SimpleDateFormat dateFormat = new SimpleDateFormat("dd-MMM-yyyy");
 276  0
                                         value = dateFormat.format(date);
 277  0
                                 }
 278  
                         break;
 279  
                         case Types.TIME:
 280  0
                                 Time t = rs.getTime(colIndex);
 281  0
                                 if (t != null) {
 282  0
                                         value = t.toString();
 283  
                                 }
 284  
                         break;
 285  
                         case Types.TIMESTAMP:
 286  0
                                 Timestamp tstamp = rs.getTimestamp(colIndex);
 287  0
                                 if (tstamp != null) {
 288  0
                                         SimpleDateFormat timeFormat = new SimpleDateFormat("dd-MMM-yyyy HH:mm:ss");
 289  0
                                         value = timeFormat.format(tstamp);
 290  0
                                 }
 291  
                         break;
 292  
                         case Types.LONGVARCHAR:
 293  
                         case Types.VARCHAR:
 294  
                         case Types.CHAR:
 295  0
                                 value = rs.getString(colIndex);
 296  0
                         break;
 297  
                         default:
 298  0
                                 value = "";
 299  
                 }
 300  
 
 301  
                 
 302  0
                 if (value == null)
 303  
                 {
 304  0
                         value = "";
 305  
                 }
 306  
                 
 307  0
                 return value;
 308  
             
 309  
     }
 310  
 
 311  
         private static String read(Clob c) throws SQLException, IOException
 312  
         {
 313  0
                 StringBuilder sb = new StringBuilder( (int) c.length());
 314  0
                 Reader r = c.getCharacterStream();
 315  0
                 char[] cbuf = new char[2048];
 316  
                 int n;
 317  0
                 while ((n = r.read(cbuf, 0, cbuf.length)) != -1) {
 318  0
                         if (n > 0) {
 319  0
                                 sb.append(cbuf, 0, n);
 320  
                         }
 321  
                 }
 322  0
                 return sb.toString();
 323  
         }
 324  
     
 325  
     /**
 326  
      * Writes the next line to the file.
 327  
      *
 328  
      * @param nextLine
 329  
      *            a string array with each comma-separated element as a separate
 330  
      *            entry.
 331  
      */
 332  
     public void writeNext(String[] nextLine) {
 333  
             
 334  0
             if (nextLine == null)
 335  0
                     return;
 336  
             
 337  0
         StringBuilder sb = new StringBuilder(INITIAL_STRING_SIZE);
 338  0
         for (int i = 0; i < nextLine.length; i++) {
 339  
 
 340  0
             if (i != 0) {
 341  0
                 sb.append(separator);
 342  
             }
 343  
 
 344  0
             String nextElement = nextLine[i];
 345  0
             if (nextElement == null)
 346  0
                 continue;
 347  0
             if (quotechar !=  NO_QUOTE_CHARACTER)
 348  0
                     sb.append(quotechar);
 349  
             
 350  0
             sb.append(stringContainsSpecialCharacters(nextElement) ? processLine(nextElement) : nextElement);
 351  
 
 352  0
             if (quotechar != NO_QUOTE_CHARACTER)
 353  0
                     sb.append(quotechar);
 354  
         }
 355  
         
 356  0
         sb.append(lineEnd);
 357  0
         pw.write(sb.toString());
 358  
 
 359  0
     }
 360  
 
 361  
         private boolean stringContainsSpecialCharacters(String line) {
 362  0
             return line.indexOf(quotechar) != -1 || line.indexOf(escapechar) != -1;
 363  
     }
 364  
 
 365  
         protected StringBuilder processLine(String nextElement)
 366  
     {
 367  0
                 StringBuilder sb = new StringBuilder(INITIAL_STRING_SIZE);
 368  0
             for (int j = 0; j < nextElement.length(); j++) {
 369  0
                 char nextChar = nextElement.charAt(j);
 370  0
                 if (escapechar != NO_ESCAPE_CHARACTER && nextChar == quotechar) {
 371  0
                         sb.append(escapechar).append(nextChar);
 372  0
                 } else if (escapechar != NO_ESCAPE_CHARACTER && nextChar == escapechar) {
 373  0
                         sb.append(escapechar).append(nextChar);
 374  
                 } else {
 375  0
                     sb.append(nextChar);
 376  
                 }
 377  
             }
 378  
             
 379  0
             return sb;
 380  
     }
 381  
 
 382  
     /**
 383  
      * Flush underlying stream to writer.
 384  
      * 
 385  
      * @throws IOException if bad things happen
 386  
      */
 387  
     public void flush() throws IOException {
 388  
 
 389  0
         pw.flush();
 390  
 
 391  0
     } 
 392  
 
 393  
     /**
 394  
      * Close the underlying stream writer flushing any buffered content.
 395  
      *
 396  
      * @throws IOException if bad things happen
 397  
      *
 398  
      */
 399  
     public void close() throws IOException {
 400  0
         flush();
 401  0
         pw.close();
 402  0
         rawWriter.close();
 403  0
     }
 404  
 
 405  
 }