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}