001    package org.expasy.jpl.commons.base.io;
002    
003    
004    import java.io.FileWriter;
005    import java.io.IOException;
006    import java.util.ArrayList;
007    import java.util.List;
008    
009    
010    /**
011     * Class to write tabular files
012     * 
013     * @author mueller
014     * 
015     */
016    public final class TabFileWriter {
017            
018            /** Column separator */
019            private String separator;
020            /** Number of decimal digits */
021            private int nrFractDecDigits;
022            /** Names of columns (can be empty) */
023            private List<String> colomnNames;
024            /** Array of arrays containing values */
025            private List<List<Double>> values;
026            
027            public TabFileWriter() {
028                    colomnNames = null;
029                    values = null;
030                    separator = ",";
031                    nrFractDecDigits = 4;
032            }
033            
034            public static TabFileWriter newInstance() {
035                    return new TabFileWriter();
036            }
037            
038            /**
039             * Write data to tabular file
040             * 
041             * @param fileName file name
042             * @param append if true, append to file
043             * @throws IOException
044             * @throws IllegalArgumentException
045             */
046            public void write(String fileName, boolean append) throws IOException,
047                IllegalArgumentException {
048                    
049                    FileWriter file = new FileWriter(fileName, append);
050                    
051                    if (colomnNames != null && colomnNames.size() > 0
052                        && values.size() != colomnNames.size()) {
053                            throw new IllegalArgumentException(
054                                "Incomaptible lengths of values and columnNames");
055                    }
056                    
057                    for (int i = 1; i < values.size(); i++) {
058                            if (values.get(i).size() != values.get(0).size()) {
059                                    throw new IllegalArgumentException(
060                                        "Incomaptible lengths of values");
061                            }
062                    }
063                    
064                    if (!append && colomnNames != null) {
065                            for (int i = 0; i < colomnNames.size(); i++) {
066                                    file.write(colomnNames.get(i));
067                                    if (i < colomnNames.size() - 1) {
068                                            file.write(separator);
069                                    } else {
070                                            file.write("\n");
071                                    }
072                            }
073                    }
074                    
075                    for (int j = 0; j < values.get(0).size(); j++) {
076                            for (int i = 0; i < values.size(); i++) {
077                                    file.write(String.format("%." + nrFractDecDigits + "f", values
078                                        .get(i).get(j)));
079                                    if (i < values.size() - 1) {
080                                            file.write(separator);
081                                    } else {
082                                            file.write("\n");
083                                    }
084                            }
085                    }
086                    
087                    file.close();
088            }
089            
090            /**
091             * Set separator
092             * 
093             * @param separator separator
094             */
095            public void setSeparator(String separator) {
096                    this.separator = separator;
097            }
098            
099            /**
100             * Get separator
101             * 
102             * @return column separator
103             */
104            public String getSeparator() {
105                    return separator;
106            }
107            
108            /**
109             * Set number of fractional decimal digits
110             * 
111             * @param nrFractDecDigits Number of fractional decimal digits
112             */
113            public void setNrFractDecDigits(int nrFractDecDigits) {
114                    this.nrFractDecDigits = nrFractDecDigits;
115            }
116            
117            /**
118             * Get number of fractional decimal digits
119             * 
120             * @return number of fractional decimal digits
121             */
122            public int getNrFractDecDigits() {
123                    return nrFractDecDigits;
124            }
125            
126            /**
127             * Add a column name
128             * 
129             * @param name of the column
130             */
131            public void addColumnName(String name) {
132                    if (colomnNames == null)
133                            colomnNames = new ArrayList<String>();
134                    this.colomnNames.add(name);
135            }
136            
137            /**
138             * Add a column names
139             * 
140             * @param names of the columns
141             */
142            public void setColumnNames(List<String> names) {
143                    colomnNames = names;
144            }
145            
146            /**
147             * Add a value array
148             * 
149             * @param values array
150             */
151            public void addValueColumn(List<Double> values) {
152                    if (this.values == null)
153                            this.values = new ArrayList<List<Double>>();
154                    
155                    for (int i = 0; i < this.values.size(); i++) {
156                            if (values.size() != this.values.get(i).size()) {
157                                    throw new IllegalArgumentException(
158                                        "Incomaptible lengths of values");
159                            }
160                    }
161                    
162                    if (values == null) {
163                            throw new IllegalArgumentException("Incompatible lengths of values");
164                    }
165                    
166                    this.values.add(values);
167            }
168            
169            public void addValueRow(List<Double> values)
170                throws IllegalArgumentException {
171                    
172                    if (this.values == null && values != null) {
173                            this.values = new ArrayList<List<Double>>();
174                            for (int i = 0; i < values.size(); i++) {
175                                    this.values.add(new ArrayList<Double>());
176                            }
177                    }
178                    
179                    if (values == null || this.values == null
180                        || values.size() != this.values.size()) {
181                            throw new IllegalArgumentException("Incomaptible lengths of values");
182                    }
183                    
184                    for (int i = 0; i < values.size(); i++) {
185                            this.values.get(i).add(values.get(i));
186                    }
187            }
188            
189            /**
190             * Set all values
191             * 
192             * @param values
193             */
194            public void setValues(List<List<Double>> values) {
195                    this.values = values;
196            }
197            
198            /**
199             * Clears column names and values and resets parameters to default
200             */
201            public void reset() {
202                    colomnNames = null;
203                    values = null;
204                    separator = ",";
205                    nrFractDecDigits = 4;
206            }
207    }