001 /**
002 * ========================================
003 * JFreeReport : a free Java report library
004 * ========================================
005 *
006 * Project Info: http://reporting.pentaho.org/
007 *
008 * (C) Copyright 2000-2007, by Object Refinery Limited, Pentaho Corporation and Contributors.
009 *
010 * This library is free software; you can redistribute it and/or modify it under the terms
011 * of the GNU Lesser General Public License as published by the Free Software Foundation;
012 * either version 2.1 of the License, or (at your option) any later version.
013 *
014 * This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
015 * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
016 * See the GNU Lesser General Public License for more details.
017 *
018 * You should have received a copy of the GNU Lesser General Public License along with this
019 * library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
020 * Boston, MA 02111-1307, USA.
021 *
022 * [Java is a trademark or registered trademark of Sun Microsystems, Inc.
023 * in the United States and other countries.]
024 *
025 * ------------
026 * $Id: CSVTableModelProducer.java,v 1.5 2007/04/01 18:49:32 taqua Exp $
027 * ------------
028 * (C) Copyright 2000-2005, by Object Refinery Limited.
029 * (C) Copyright 2005-2007, by Pentaho Corporation.
030 */
031
032 package org.jfree.report.modules.misc.tablemodel;
033
034 import java.io.BufferedReader;
035 import java.io.FileNotFoundException;
036 import java.io.FileReader;
037 import java.io.IOException;
038 import java.io.InputStream;
039 import java.io.InputStreamReader;
040 import java.util.ArrayList;
041 import javax.swing.table.TableModel;
042
043 import org.jfree.report.util.CSVTokenizer;
044
045 /**
046 * Creates a <code>TableModel</code> using a file formated in CSV for input. The
047 * separation can be what ever you want (as it is an understandable regexp). The default
048 * separator is a <code>,</code>.
049 *
050 * @author Mimil
051 */
052 public class CSVTableModelProducer
053 {
054 private BufferedReader reader;
055 private String separator;
056 private CSVTableModel tableModel;
057 private boolean columnNameFirst;
058
059 public CSVTableModelProducer (final InputStream in)
060 {
061 this(new BufferedReader(new InputStreamReader(in)));
062 }
063
064 public CSVTableModelProducer (final String filename)
065 throws FileNotFoundException
066 {
067 this(new BufferedReader(new FileReader(filename)));
068 }
069
070 public CSVTableModelProducer (final BufferedReader r)
071 {
072 if (r == null)
073 {
074 throw new NullPointerException("The input stream must not be null");
075 }
076 this.reader = r;
077 this.separator = ",";
078 }
079
080 public void close ()
081 throws IOException
082 {
083 this.reader.close();
084 }
085
086 /**
087 * Parses the input and stores data in a TableModel.
088 *
089 * @see this.getTableModel()
090 */
091 public synchronized TableModel parse ()
092 throws IOException
093 {
094 if (tableModel != null)
095 {
096 return tableModel;
097 }
098
099
100 this.tableModel = new CSVTableModel();
101
102 if (this.columnNameFirst == true)
103 { //read the fisrt line
104 final String first = this.reader.readLine();
105
106 if (first == null)
107 {
108 // after the end of the file it makes no sense to read anything.
109 // so we can safely return ..
110 return tableModel;
111 }
112 this.tableModel.setColumnNames(splitLine(first));
113 }
114
115 final ArrayList data = new ArrayList();
116 String line;
117 int maxLength = 0;
118 while ((line = this.reader.readLine()) != null)
119 {
120 final String[] o = splitLine(line);
121 if (o.length > maxLength)
122 {
123 maxLength = o.length;
124 }
125 data.add(o);
126 }
127
128 close();
129
130 final Object[][] array = new Object[data.size()][];
131 data.toArray(array);
132 this.tableModel.setData(array);
133 return tableModel;
134 }
135
136 private String[] splitLine (final String line)
137 {
138 final ArrayList row = new ArrayList();
139 final CSVTokenizer tokenizer = new CSVTokenizer(line, getSeparator());
140 while (tokenizer.hasMoreElements())
141 {
142 row.add(tokenizer.nextElement());
143 }
144 return (String[]) row.toArray(new String[row.size()]);
145 }
146
147 /**
148 * Returns the current separator used to parse the input.
149 *
150 * @return a regexp
151 */
152 public String getSeparator ()
153 {
154 return separator;
155 }
156
157 /**
158 * Sets the separator for parsing the input. It can be a regexp as we use the function
159 * <code>String.split()</code>. The default separator is a <code>;</code>.
160 *
161 * @param separator a regexp
162 */
163 public void setSeparator (final String separator)
164 {
165 this.separator = separator;
166 }
167
168 /**
169 * Creates the corrspondant TableModel of the input.
170 *
171 * @return the new TableModel
172 */
173 public TableModel getTableModel ()
174 throws IOException
175 {
176 return this.parse();
177 }
178
179 /**
180 * Tells if the first line of the input was column names.
181 *
182 * @return boolean
183 */
184 public boolean isColumnNameFirstLine ()
185 {
186 return columnNameFirst;
187 }
188
189 /**
190 * Set if the first line of the input is column names or not.
191 *
192 * @param columnNameFirst boolean
193 */
194 public void setColumnNameFirstLine (final boolean columnNameFirst)
195 {
196 this.columnNameFirst = columnNameFirst;
197 }
198
199 }