src/core/net/sf/basedb/util/bfs/DataWriter.java

Code
Comments
Other
Rev Date Author Line
5194 04 Dec 09 nicklas 1 /**
5194 04 Dec 09 nicklas 2   $Id$
5194 04 Dec 09 nicklas 3
5194 04 Dec 09 nicklas 4   Copyright (C) 2009 Nicklas Nordborg
5194 04 Dec 09 nicklas 5
5194 04 Dec 09 nicklas 6   This file is part of BASE - BioArray Software Environment.
5194 04 Dec 09 nicklas 7   Available at http://base.thep.lu.se/
5194 04 Dec 09 nicklas 8
5194 04 Dec 09 nicklas 9   BASE is free software; you can redistribute it and/or
5194 04 Dec 09 nicklas 10   modify it under the terms of the GNU General Public License
5194 04 Dec 09 nicklas 11   as published by the Free Software Foundation; either version 3
5194 04 Dec 09 nicklas 12   of the License, or (at your option) any later version.
5194 04 Dec 09 nicklas 13
5194 04 Dec 09 nicklas 14   BASE is distributed in the hope that it will be useful,
5194 04 Dec 09 nicklas 15   but WITHOUT ANY WARRANTY; without even the implied warranty of
5194 04 Dec 09 nicklas 16   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
5194 04 Dec 09 nicklas 17   GNU General Public License for more details.
5194 04 Dec 09 nicklas 18
5194 04 Dec 09 nicklas 19   You should have received a copy of the GNU General Public License
5194 04 Dec 09 nicklas 20   along with BASE. If not, see <http://www.gnu.org/licenses/>.
5194 04 Dec 09 nicklas 21 */
5194 04 Dec 09 nicklas 22 package net.sf.basedb.util.bfs;
5194 04 Dec 09 nicklas 23
5384 13 Aug 10 nicklas 24 import java.io.FileNotFoundException;
5236 05 Feb 10 nicklas 25 import java.io.FileOutputStream;
5236 05 Feb 10 nicklas 26 import java.io.IOException;
5236 05 Feb 10 nicklas 27 import java.io.OutputStream;
5236 05 Feb 10 nicklas 28 import java.io.OutputStreamWriter;
5194 04 Dec 09 nicklas 29 import java.io.Writer;
7714 21 May 19 nicklas 30 import java.nio.charset.StandardCharsets;
5194 04 Dec 09 nicklas 31
5236 05 Feb 10 nicklas 32 import net.sf.basedb.core.File;
5194 04 Dec 09 nicklas 33 import net.sf.basedb.util.encode.TabCrLfEncoderDecoder;
5194 04 Dec 09 nicklas 34 import net.sf.basedb.util.export.TableWriter;
5194 04 Dec 09 nicklas 35
5194 04 Dec 09 nicklas 36 /**
5194 04 Dec 09 nicklas 37   Writer implementation for writing BFS data files. A data file is
5194 04 Dec 09 nicklas 38   a matrix of data. Columns are separated by tabs. Values are escaped
5194 04 Dec 09 nicklas 39   using the regular rules ({@link TabCrLfEncoderDecoder}). All
5194 04 Dec 09 nicklas 40   rows must have an equal number of columns. The number of columns is
5194 04 Dec 09 nicklas 41   defined by the first call to {@link #bfsPrintData(Object...)}
5194 04 Dec 09 nicklas 42   or by calling {@link #setColumnCount(int)}.
5194 04 Dec 09 nicklas 43
5194 04 Dec 09 nicklas 44   @author Nicklas
5194 04 Dec 09 nicklas 45   @version 2.15
5194 04 Dec 09 nicklas 46   @base.modified $Date$
5194 04 Dec 09 nicklas 47 */
5194 04 Dec 09 nicklas 48 public class DataWriter
5194 04 Dec 09 nicklas 49   extends TableWriter
5194 04 Dec 09 nicklas 50 {
5194 04 Dec 09 nicklas 51
5236 05 Feb 10 nicklas 52   /**
5236 05 Feb 10 nicklas 53     Utility method for creating a data writer when you have an
5236 05 Feb 10 nicklas 54     output stream.
5236 05 Feb 10 nicklas 55     @param out The output stream the writer should print to
5236 05 Feb 10 nicklas 56     @param filename Optional, the name of the file the output stream
5236 05 Feb 10 nicklas 57       is printing to
5236 05 Feb 10 nicklas 58   */
5236 05 Feb 10 nicklas 59   public static DataWriter create(OutputStream out, String filename)
5236 05 Feb 10 nicklas 60   {
5384 13 Aug 10 nicklas 61     if (out == null) throw new NullPointerException("out");
5236 05 Feb 10 nicklas 62     DataWriter writer = new DataWriter(
7714 21 May 19 nicklas 63         new OutputStreamWriter(out, StandardCharsets.UTF_8));
5236 05 Feb 10 nicklas 64     writer.setFilename(filename);
5236 05 Feb 10 nicklas 65     return writer;
5236 05 Feb 10 nicklas 66   }
5236 05 Feb 10 nicklas 67   
5236 05 Feb 10 nicklas 68   /**
5236 05 Feb 10 nicklas 69     Utility method for creating a data writer to a file in the BASE
5236 05 Feb 10 nicklas 70     file system. The character set and MIME type on the file are automatically 
5236 05 Feb 10 nicklas 71     updated.
5236 05 Feb 10 nicklas 72     @param file The file in the BASE file system
5236 05 Feb 10 nicklas 73   */
5236 05 Feb 10 nicklas 74   public static DataWriter create(File file)
5236 05 Feb 10 nicklas 75   {
5384 13 Aug 10 nicklas 76     if (file == null) throw new NullPointerException("file");
5236 05 Feb 10 nicklas 77     file.setCharacterSet("UTF-8");
5236 05 Feb 10 nicklas 78     file.setMimeType("text/plain");
5236 05 Feb 10 nicklas 79     return create(file.getUploadStream(false), file.getName());
5236 05 Feb 10 nicklas 80   }
5236 05 Feb 10 nicklas 81   
5236 05 Feb 10 nicklas 82   /**
5236 05 Feb 10 nicklas 83     Utility method for creating a data writer to a file in the native
5236 05 Feb 10 nicklas 84     file system. If the file doesn't exists, it is created.
5236 05 Feb 10 nicklas 85     @param file The file in the native file system
5236 05 Feb 10 nicklas 86   */
5236 05 Feb 10 nicklas 87   public static DataWriter create(java.io.File file)
5236 05 Feb 10 nicklas 88     throws IOException
5236 05 Feb 10 nicklas 89   {
5384 13 Aug 10 nicklas 90     if (file == null) throw new NullPointerException("file");
5384 13 Aug 10 nicklas 91     if (!file.createNewFile() && !file.exists()) 
5384 13 Aug 10 nicklas 92     {
5384 13 Aug 10 nicklas 93       throw new FileNotFoundException(file.toString());
5384 13 Aug 10 nicklas 94     }
5236 05 Feb 10 nicklas 95     return create(new FileOutputStream(file), file.getName());
5236 05 Feb 10 nicklas 96   }
5236 05 Feb 10 nicklas 97
5198 15 Dec 09 nicklas 98   private String filename;
5194 04 Dec 09 nicklas 99   private boolean lockedColumns;
5194 04 Dec 09 nicklas 100   private int columnCount = -1;
5194 04 Dec 09 nicklas 101   
5194 04 Dec 09 nicklas 102   /**
5194 04 Dec 09 nicklas 103     Create a new BFS data writer.
5194 04 Dec 09 nicklas 104     @param out The parent writer which this writer will print to
5194 04 Dec 09 nicklas 105   */
5194 04 Dec 09 nicklas 106   public DataWriter(Writer out)
5194 04 Dec 09 nicklas 107   {
5194 04 Dec 09 nicklas 108     super(out);
5194 04 Dec 09 nicklas 109     super.setDataSeparator("\t");
5194 04 Dec 09 nicklas 110     super.setNullValue("");
5194 04 Dec 09 nicklas 111     super.setEncoder(new TabCrLfEncoderDecoder(false));
5194 04 Dec 09 nicklas 112   }
5194 04 Dec 09 nicklas 113
5194 04 Dec 09 nicklas 114   /**
5198 15 Dec 09 nicklas 115     Get the file name that this writer is printing to.
5198 15 Dec 09 nicklas 116     @return The file name or null if not known
5198 15 Dec 09 nicklas 117   */
5198 15 Dec 09 nicklas 118   public String getFilename()
5198 15 Dec 09 nicklas 119   {
5198 15 Dec 09 nicklas 120     return filename;
5198 15 Dec 09 nicklas 121   }
5198 15 Dec 09 nicklas 122
5198 15 Dec 09 nicklas 123   /**
5198 15 Dec 09 nicklas 124     Set the file name that this writer is printing to.
5198 15 Dec 09 nicklas 125   */
5198 15 Dec 09 nicklas 126   public void setFilename(String filename)
5198 15 Dec 09 nicklas 127   {
5198 15 Dec 09 nicklas 128     this.filename = filename;
5198 15 Dec 09 nicklas 129   }
5198 15 Dec 09 nicklas 130   
5198 15 Dec 09 nicklas 131   /**
5194 04 Dec 09 nicklas 132     Get the number of data columns. This information is only
5194 04 Dec 09 nicklas 133     available after the first line of data has been printed
5194 04 Dec 09 nicklas 134     or if a specific number of columns has been set.
5194 04 Dec 09 nicklas 135     
5194 04 Dec 09 nicklas 136     @return The number of columns, or -1 if this information
5194 04 Dec 09 nicklas 137       is not yet known
5194 04 Dec 09 nicklas 138   */
5194 04 Dec 09 nicklas 139   public int getColumnCount()
5194 04 Dec 09 nicklas 140   {
5194 04 Dec 09 nicklas 141     return columnCount;
5194 04 Dec 09 nicklas 142   }
5194 04 Dec 09 nicklas 143   
5194 04 Dec 09 nicklas 144   /**
5194 04 Dec 09 nicklas 145     Set the number of data columns. This can only be changed
5194 04 Dec 09 nicklas 146     as long as no data has been written to the stream.
5194 04 Dec 09 nicklas 147     @param columns The number of data columns, if 0 or negative the
5194 04 Dec 09 nicklas 148       first call to {@link #bfsPrintData(Object...)} determines 
5194 04 Dec 09 nicklas 149       the number of columns
5194 04 Dec 09 nicklas 150   */
5194 04 Dec 09 nicklas 151   public void setColumnCount(int columns)
5194 04 Dec 09 nicklas 152   {
5194 04 Dec 09 nicklas 153     if (lockedColumns) 
5194 04 Dec 09 nicklas 154     {
5198 15 Dec 09 nicklas 155       throw new IllegalStateException("Can't change the number of columns since data " +
5198 15 Dec 09 nicklas 156         "has already been written in file: " + getFilename());
5194 04 Dec 09 nicklas 157     }
5194 04 Dec 09 nicklas 158     this.columnCount = columns;
5194 04 Dec 09 nicklas 159   }
5194 04 Dec 09 nicklas 160   
5194 04 Dec 09 nicklas 161   /**
5194 04 Dec 09 nicklas 162     Checks if the number of columns has been locked or not. The number
5194 04 Dec 09 nicklas 163     of required columns are locked the first time a call to
5194 04 Dec 09 nicklas 164     {@link #bfsPrintData(Object...)}  is made.
5194 04 Dec 09 nicklas 165   */
5194 04 Dec 09 nicklas 166   public boolean isLockedColumns()
5194 04 Dec 09 nicklas 167   {
5194 04 Dec 09 nicklas 168     return lockedColumns;
5194 04 Dec 09 nicklas 169   }
5194 04 Dec 09 nicklas 170   
5194 04 Dec 09 nicklas 171   /**
5194 04 Dec 09 nicklas 172     Print a data line. The number of columns must be the same for all calls
5194 04 Dec 09 nicklas 173     to this method. Normally, the first call determines the required number
5194 04 Dec 09 nicklas 174     of columns, but this can also be set with {@link #setColumnCount(int)}.
5194 04 Dec 09 nicklas 175     
5194 04 Dec 09 nicklas 176     @param data The data to print
5194 04 Dec 09 nicklas 177     @throws IllegalStateException If headers has not been printed
5194 04 Dec 09 nicklas 178     @throws IllegalArgumentException If the data array doesn't match the
5194 04 Dec 09 nicklas 179       required number of columns
5194 04 Dec 09 nicklas 180     @throws NullPointerException If the data array is null
5194 04 Dec 09 nicklas 181   */
5194 04 Dec 09 nicklas 182   public void bfsPrintData(Object... data)
5194 04 Dec 09 nicklas 183   {
5194 04 Dec 09 nicklas 184
5198 15 Dec 09 nicklas 185     if (data == null) throw new NullPointerException("'data' in file: " + getFilename());
5194 04 Dec 09 nicklas 186     if (columnCount <= 0) columnCount = data.length;
5194 04 Dec 09 nicklas 187     if (data.length != columnCount)
5194 04 Dec 09 nicklas 188     {
5194 04 Dec 09 nicklas 189       throw new IllegalArgumentException("Data array has " + data.length + " columns; " +
5198 15 Dec 09 nicklas 190           "; expected " + columnCount + " in file: " + getFilename());
5194 04 Dec 09 nicklas 191     }
5194 04 Dec 09 nicklas 192     lockedColumns = true;
5194 04 Dec 09 nicklas 193     if (data.length > 0)
5194 04 Dec 09 nicklas 194     {
5194 04 Dec 09 nicklas 195       tablePrintData(data);
5194 04 Dec 09 nicklas 196     }
5194 04 Dec 09 nicklas 197     else
5194 04 Dec 09 nicklas 198     {
5194 04 Dec 09 nicklas 199       print("\n");
5194 04 Dec 09 nicklas 200     }
5194 04 Dec 09 nicklas 201   }
5194 04 Dec 09 nicklas 202   
5194 04 Dec 09 nicklas 203 }