001package com.hfg.util.io; 002 003import com.hfg.util.StringBuilderPlus; 004import com.hfg.util.StringUtil; 005import com.hfg.util.collection.DataColumn; 006import com.hfg.util.collection.DataTable; 007 008import java.io.IOException; 009import java.io.Reader; 010import java.util.List; 011import java.util.Map; 012 013//------------------------------------------------------------------------------ 014/** 015 Utility to help in parsing CSV (comma-separated value) files. 016 <div> 017 @author J. Alex Taylor, hairyfatguy.com 018 </div> 019 */ 020//------------------------------------------------------------------------------ 021// com.hfg Library 022// 023// This library is free software; you can redistribute it and/or 024// modify it under the terms of the GNU Lesser General Public 025// License as published by the Free Software Foundation; either 026// version 2.1 of the License, or (at your option) any later version. 027// 028// This library is distributed in the hope that it will be useful, 029// but WITHOUT ANY WARRANTY; without even the implied warranty of 030// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 031// Lesser General Public License for more details. 032// 033// You should have received a copy of the GNU Lesser General Public 034// License along with this library; if not, write to the Free Software 035// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 036// 037// J. Alex Taylor, President, Founder, CEO, COO, CFO, OOPS hairyfatguy.com 038// jataylor@hairyfatguy.com 039//------------------------------------------------------------------------------ 040 041public class CSV 042{ 043 private static DelimitedTextParser sParser = new DelimitedTextParser(','); 044 045 //########################################################################### 046 // PUBLIC FUNCTIONS 047 //########################################################################### 048 049 //--------------------------------------------------------------------------- 050 public static String write(DataTable inDataTable) 051 { 052 StringBuilderPlus buffer = new StringBuilderPlus(); 053 if (inDataTable != null) 054 { 055 // Header line 056 boolean firstCol = true; 057 for (DataColumn col : inDataTable.getDataColumns()) 058 { 059 if (firstCol) 060 { 061 firstCol = false; 062 } 063 else 064 { 065 buffer.append(", "); 066 } 067 068 buffer.append(writeField(col.getTitle())); 069 } 070 buffer.appendln(); 071 072 // Rows 073 for (String rowKey : inDataTable.rowKeySet()) 074 { 075 Map<DataColumn, Comparable> rowData = inDataTable.getRowData(rowKey); 076 077 firstCol = true; 078 for (DataColumn col : inDataTable.getDataColumns()) 079 { 080 if (firstCol) 081 { 082 firstCol = false; 083 } 084 else 085 { 086 buffer.append(", "); 087 } 088 089 buffer.append(writeField(rowData.get(col))); 090 } 091 buffer.appendln(); 092 } 093 } 094 095 return buffer.toString(); 096 } 097 098 //--------------------------------------------------------------------------- 099 public static String writeField(String inField) 100 { 101 return StringUtil.isSet(inField) ? escapeField(inField) : ""; 102 } 103 104 //--------------------------------------------------------------------------- 105 public static String writeField(Number inField) 106 { 107 return inField != null ? inField.toString() : ""; 108 } 109 110 //--------------------------------------------------------------------------- 111 public static String writeField(Number inField, String inFormatString) 112 { 113 return inField != null ? String.format(inFormatString, inField) : ""; 114 } 115 116 //--------------------------------------------------------------------------- 117 public static String writeField(Boolean inField) 118 { 119 return inField != null ? inField.toString() : ""; 120 } 121 122 //--------------------------------------------------------------------------- 123 // When this method was public it was causing issues with signature conflicts. 124 private static String writeField(Comparable inField) 125 { 126 String fieldValue = ""; 127 if (inField != null) 128 { 129 if (inField instanceof String) 130 { 131 fieldValue = writeField((String) inField); 132 } 133 else if (inField instanceof Number) 134 { 135 fieldValue = writeField((Number) inField); 136 } 137 else if (inField instanceof Boolean) 138 { 139 fieldValue = writeField((Boolean) inField); 140 } 141 else 142 { 143 fieldValue = writeField(inField.toString()); 144 } 145 } 146 147 return fieldValue; 148 } 149 150 //--------------------------------------------------------------------------- 151 public static String escapeField(String inField) 152 { 153 return sParser.escapeField(inField); 154 } 155 156 //--------------------------------------------------------------------------- 157 public static List<String[]> parse(Reader inReader) 158 throws IOException 159 { 160 return sParser.parse(inReader); 161 } 162 163 //--------------------------------------------------------------------------- 164 public static DataTable parseToDataTable(Reader inReader) 165 throws IOException 166 { 167 return sParser.parseToDataTable(inReader); 168 } 169 170 //--------------------------------------------------------------------------- 171 public static String[] parseLine(String inLine) 172 throws IOException 173 { 174 return sParser.parseLine(inLine); 175 } 176}