plugins/base1/se.lu.onk.BaseFile/trunk/src/basefile/BASEFileReader.java

Code
Comments
Other
Rev Date Author Line
782 18 Sep 08 jari 1 /*
782 18 Sep 08 jari 2   $Id$
782 18 Sep 08 jari 3
782 18 Sep 08 jari 4   Copyright (C) 2006 Johan Enell
782 18 Sep 08 jari 5   Copyright (C) 2008 Jari Häkkinen
782 18 Sep 08 jari 6
782 18 Sep 08 jari 7   This file is part of the se.lu.onk.BaseFile package, a utility
782 18 Sep 08 jari 8   package for reading files generated by BASE. The package is
782 18 Sep 08 jari 9   available at http://baseplugins.thep.lu.se/ and BASE web site is
782 18 Sep 08 jari 10   http://base.thep.lu.se
782 18 Sep 08 jari 11
782 18 Sep 08 jari 12   This is free software; you can redistribute it and/or modify it
782 18 Sep 08 jari 13   under the terms of the GNU General Public License as published by
782 18 Sep 08 jari 14   the Free Software Foundation; either version 3 of the License, or
782 18 Sep 08 jari 15   (at your option) any later version.
782 18 Sep 08 jari 16
782 18 Sep 08 jari 17   The software is distributed in the hope that it will be useful, but
782 18 Sep 08 jari 18   WITHOUT ANY WARRANTY; without even the implied warranty of
782 18 Sep 08 jari 19   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
782 18 Sep 08 jari 20   General Public License for more details.
782 18 Sep 08 jari 21
782 18 Sep 08 jari 22   You should have received a copy of the GNU General Public License
782 18 Sep 08 jari 23   along with BASE. If not, see <http://www.gnu.org/licenses/>.
782 18 Sep 08 jari 24 */
6 10 Oct 05 enell 25 package basefile;
6 10 Oct 05 enell 26
15 14 Oct 05 enell 27 import java.io.File;
15 14 Oct 05 enell 28 import java.io.FileNotFoundException;
15 14 Oct 05 enell 29 import java.io.FileReader;
6 10 Oct 05 enell 30 import java.io.IOException;
6 10 Oct 05 enell 31 import java.io.LineNumberReader;
6 10 Oct 05 enell 32 import java.util.HashMap;
6 10 Oct 05 enell 33 import java.util.Vector;
6 10 Oct 05 enell 34
6 10 Oct 05 enell 35 /**
6 10 Oct 05 enell 36  * Read sections from a file created from the database BASE. This class is
6 10 Oct 05 enell 37  * designed to read from System.in and will read section wise.
6 10 Oct 05 enell 38  * 
6 10 Oct 05 enell 39  * @author Johan Enell
6 10 Oct 05 enell 40  */
6 10 Oct 05 enell 41 public class BASEFileReader
6 10 Oct 05 enell 42 {
6 10 Oct 05 enell 43
6 10 Oct 05 enell 44   /**
6 10 Oct 05 enell 45    * The active baseFile.BASEFileSection that the reader is reading from.
6 10 Oct 05 enell 46    */
6 10 Oct 05 enell 47   private BASEFileSection section = null;
6 10 Oct 05 enell 48
6 10 Oct 05 enell 49   private LineNumberReader str;
6 10 Oct 05 enell 50
6 10 Oct 05 enell 51   private boolean dataEnd;
6 10 Oct 05 enell 52
6 10 Oct 05 enell 53   private String buf;
6 10 Oct 05 enell 54
15 14 Oct 05 enell 55   private File inFile;
15 14 Oct 05 enell 56
6 10 Oct 05 enell 57   /**
6 10 Oct 05 enell 58    * Create a new baseFile reader.
6 10 Oct 05 enell 59    * 
6 10 Oct 05 enell 60    * @param in
6 10 Oct 05 enell 61    *            the stream from were the reader gets the data.
15 14 Oct 05 enell 62    * @throws FileNotFoundException If the infile cant be found
6 10 Oct 05 enell 63    */
248 28 Mar 07 enell 64   @Deprecated
15 14 Oct 05 enell 65   public BASEFileReader(File in) throws FileNotFoundException
6 10 Oct 05 enell 66   {
15 14 Oct 05 enell 67     inFile = in;
15 14 Oct 05 enell 68     str = new LineNumberReader(new FileReader(in));
6 10 Oct 05 enell 69     dataEnd = true;
6 10 Oct 05 enell 70   }
6 10 Oct 05 enell 71
6 10 Oct 05 enell 72   /**
6 10 Oct 05 enell 73    * Read the next baseFile section in the baseFile.
6 10 Oct 05 enell 74    * 
6 10 Oct 05 enell 75    * @return the section read.
6 10 Oct 05 enell 76    * @throws BadSectionException
6 10 Oct 05 enell 77    *             If the baseFile section is badly written
6 10 Oct 05 enell 78    * @throws BadFormatException
6 10 Oct 05 enell 79    *             If the baseFile is badly formatted (ie. first line is not
6 10 Oct 05 enell 80    *             BASEFil)
6 10 Oct 05 enell 81    * @throws IOException
6 10 Oct 05 enell 82    *             If an I/O error occurs.
6 10 Oct 05 enell 83    */
6 10 Oct 05 enell 84   public BASEFileSection readSection()
18 18 Oct 05 enell 85     throws BadSectionException, BadFormatException, IOException
6 10 Oct 05 enell 86   {
6 10 Oct 05 enell 87     return readSection(false);
6 10 Oct 05 enell 88   }
6 10 Oct 05 enell 89
6 10 Oct 05 enell 90   /**
6 10 Oct 05 enell 91    * Read the next baseFile section in the baseFile.
6 10 Oct 05 enell 92    * 
6 10 Oct 05 enell 93    * @param beginFile
6 10 Oct 05 enell 94    *            Is set true if it is the begining of the baseFile.
6 10 Oct 05 enell 95    * @return the section read or null if there is no more sections
6 10 Oct 05 enell 96    * @throws BadSectionException
6 10 Oct 05 enell 97    *             If the baseFile section is badly written
6 10 Oct 05 enell 98    * @throws BadFormatException
6 10 Oct 05 enell 99    *             If the baseFile is badly formatted (ie. first line is not
6 10 Oct 05 enell 100    *             BASEFil)
6 10 Oct 05 enell 101    * @throws IOException
6 10 Oct 05 enell 102    *             If an I/O error occurs.
6 10 Oct 05 enell 103    */
249 28 Mar 07 enell 104   @Deprecated
6 10 Oct 05 enell 105   public BASEFileSection readSection(boolean beginFile)
185 12 Oct 06 enell 106     throws BadFormatException, IOException
6 10 Oct 05 enell 107   {
103 01 Jun 06 enell 108     if (section == null)
103 01 Jun 06 enell 109     {
103 01 Jun 06 enell 110       section = new BASEFileSection();
103 01 Jun 06 enell 111     }
103 01 Jun 06 enell 112     else
103 01 Jun 06 enell 113     {
103 01 Jun 06 enell 114       section.clear();
103 01 Jun 06 enell 115     }
103 01 Jun 06 enell 116     
97 20 Apr 06 enell 117     section.setStartLine(str.getLineNumber() + 1);
6 10 Oct 05 enell 118     skipData();
97 20 Apr 06 enell 119     section.setStartLine(str.getLineNumber() + 1);
6 10 Oct 05 enell 120
18 18 Oct 05 enell 121     if (!section.setHeaders(readHeaders(beginFile)))
18 18 Oct 05 enell 122     {
18 18 Oct 05 enell 123       return null;
18 18 Oct 05 enell 124     }
6 10 Oct 05 enell 125
97 20 Apr 06 enell 126     section.setDataStartLine(str.getLineNumber() + 1);
6 10 Oct 05 enell 127
664 16 Apr 08 jari 128     if (section.getType()==null || section.getType().length()==0) return null;
6 10 Oct 05 enell 129     return section;
6 10 Oct 05 enell 130   }
103 01 Jun 06 enell 131   
103 01 Jun 06 enell 132   /**
103 01 Jun 06 enell 133    * TODO: Write javadoc for readSpotSection()
103 01 Jun 06 enell 134    * @param <R>
103 01 Jun 06 enell 135    * @param <S>
103 01 Jun 06 enell 136    * @return
103 01 Jun 06 enell 137    * @throws BadFormatException 
103 01 Jun 06 enell 138    * @throws IOException 
103 01 Jun 06 enell 139    */
247 27 Mar 07 enell 140   public <R, S> BASEFileSpotSection<R, S> readSpotSection()
248 28 Mar 07 enell 141     throws BASEFileException, IOException
103 01 Jun 06 enell 142   {
711 29 May 08 jari 143     section = readSection(false);
104 01 Jun 06 enell 144     while (section != null && !section.isType("spots"))
103 01 Jun 06 enell 145     {
103 01 Jun 06 enell 146       section = readSection(false);
103 01 Jun 06 enell 147     }
711 29 May 08 jari 148     return (section == null) ? null : new BASEFileSpotSection<R, S>(section);
103 01 Jun 06 enell 149   }
247 27 Mar 07 enell 150   
247 27 Mar 07 enell 151   /**
711 29 May 08 jari 152    * TODO: Write javadoc for readAssaySection()
247 27 Mar 07 enell 153    * @param <R>
247 27 Mar 07 enell 154    * @param <S>
247 27 Mar 07 enell 155    * @return
247 27 Mar 07 enell 156    * @throws IOException 
247 27 Mar 07 enell 157    * @throws BadSectionException 
247 27 Mar 07 enell 158    */
247 27 Mar 07 enell 159   public BASEFileAssaySection readAssaySection()
247 27 Mar 07 enell 160     throws BASEFileException, IOException
247 27 Mar 07 enell 161   {
248 28 Mar 07 enell 162     section = readSection(false); 
247 27 Mar 07 enell 163     while (section != null && !section.isType("assays"))
247 27 Mar 07 enell 164     {
247 27 Mar 07 enell 165       section = readSection(false);
247 27 Mar 07 enell 166     }
248 28 Mar 07 enell 167     if (section == null)
248 28 Mar 07 enell 168     {
248 28 Mar 07 enell 169       throw new BASEFileException("Couldn't find assays section in file "+this.inFile.getAbsolutePath());
248 28 Mar 07 enell 170     }
247 27 Mar 07 enell 171     return new BASEFileAssaySection(section);
247 27 Mar 07 enell 172   }
18 18 Oct 05 enell 173
15 14 Oct 05 enell 174   public void resetDataPosition(BASEFileSection section)
15 14 Oct 05 enell 175   {
15 14 Oct 05 enell 176     try
15 14 Oct 05 enell 177     {
15 14 Oct 05 enell 178       str.close();
15 14 Oct 05 enell 179       str = new LineNumberReader(new FileReader(inFile));
768 16 Sep 08 jari 180       while (str.getLineNumber()+1 < section.getDataStartLine())
15 14 Oct 05 enell 181       {
15 14 Oct 05 enell 182         str.readLine();
15 14 Oct 05 enell 183       }
18 18 Oct 05 enell 184       dataEnd = false;
15 14 Oct 05 enell 185     }
15 14 Oct 05 enell 186     catch (IOException e)
15 14 Oct 05 enell 187     {
15 14 Oct 05 enell 188       //Should not happend
15 14 Oct 05 enell 189       e.printStackTrace();
15 14 Oct 05 enell 190     }
15 14 Oct 05 enell 191   }
6 10 Oct 05 enell 192
6 10 Oct 05 enell 193   /**
6 10 Oct 05 enell 194    * This will read a singel line from the active section.
6 10 Oct 05 enell 195    * 
6 10 Oct 05 enell 196    * @return The data row as an String[]. Returns <code>null</code> if the
6 10 Oct 05 enell 197    *         section end or the file end is reached.
6 10 Oct 05 enell 198    * @throws IOException
6 10 Oct 05 enell 199    *             If an I/O error occurs.
6 10 Oct 05 enell 200    */
6 10 Oct 05 enell 201   public String[] readDataRow() throws IOException
6 10 Oct 05 enell 202   {
6 10 Oct 05 enell 203     Vector<String> vec = new Vector<String>();
6 10 Oct 05 enell 204
6 10 Oct 05 enell 205     if (!readLine() || dataEnd) return null;
6 10 Oct 05 enell 206
6 10 Oct 05 enell 207     int tok = buf.indexOf("\t"), otok = 0;
6 10 Oct 05 enell 208
6 10 Oct 05 enell 209     while (tok < buf.length())
6 10 Oct 05 enell 210     {
6 10 Oct 05 enell 211       tok = buf.indexOf("\t", otok);
6 10 Oct 05 enell 212       if (tok == -1)
6 10 Oct 05 enell 213       {
6 10 Oct 05 enell 214         tok = buf.length();
6 10 Oct 05 enell 215       }
6 10 Oct 05 enell 216       vec.add(buf.substring(otok, tok));
6 10 Oct 05 enell 217       otok = tok + 1;
6 10 Oct 05 enell 218     }
6 10 Oct 05 enell 219
31 08 Nov 05 enell 220     return vec.toArray(new String[vec.size()]);
6 10 Oct 05 enell 221   }
6 10 Oct 05 enell 222
6 10 Oct 05 enell 223   /**
6 10 Oct 05 enell 224    * This will read a singel line from the active section.
6 10 Oct 05 enell 225    * 
6 10 Oct 05 enell 226    * @param nbr
6 10 Oct 05 enell 227    *            The number of fields that the row consists of
6 10 Oct 05 enell 228    * @return The data row as an String[]. Returns <code>null</code> if the
6 10 Oct 05 enell 229    *         section end or the file end is reached.
6 10 Oct 05 enell 230    * @throws IOException
6 10 Oct 05 enell 231    *             If an I/O error occurs.
6 10 Oct 05 enell 232    * @throws TooFewFieldsException
6 10 Oct 05 enell 233    *             If <code>nbr</code> is less than the number of fields in
6 10 Oct 05 enell 234    *             the row.
6 10 Oct 05 enell 235    * @throws TooManyFieldsException
6 10 Oct 05 enell 236    *             If <code>nbr</code> is more than the number of fields in
6 10 Oct 05 enell 237    *             the row.
6 10 Oct 05 enell 238    */
6 10 Oct 05 enell 239   public String[] readDataRow(int nbr)
245 13 Mar 07 enell 240     throws BASEFileException, TooFewFieldsException, TooManyFieldsException
6 10 Oct 05 enell 241   {
6 10 Oct 05 enell 242     String[] vec = new String[nbr];
6 10 Oct 05 enell 243     dataEnd = false;
6 10 Oct 05 enell 244
18 18 Oct 05 enell 245     if (nbr < 0)
18 18 Oct 05 enell 246     {
18 18 Oct 05 enell 247       throw new TooFewFieldsException("Too few fields in " + section.getType() + ", line " + str.getLineNumber());
18 18 Oct 05 enell 248     }
245 13 Mar 07 enell 249     try
245 13 Mar 07 enell 250     {
245 13 Mar 07 enell 251       if (!readLine() || dataEnd) return null;
6 10 Oct 05 enell 252
245 13 Mar 07 enell 253       int tok = buf.indexOf("\t"), otok = 0;
6 10 Oct 05 enell 254
245 13 Mar 07 enell 255       while (tok < buf.length())
6 10 Oct 05 enell 256       {
245 13 Mar 07 enell 257         tok = buf.indexOf("\t", otok);
245 13 Mar 07 enell 258         if (tok == -1)
245 13 Mar 07 enell 259         {
245 13 Mar 07 enell 260           tok = buf.length();
245 13 Mar 07 enell 261         }
245 13 Mar 07 enell 262         vec[vec.length - nbr] = buf.substring(otok, tok);
245 13 Mar 07 enell 263         otok = tok + 1;
245 13 Mar 07 enell 264         nbr--;
6 10 Oct 05 enell 265       }
6 10 Oct 05 enell 266     }
245 13 Mar 07 enell 267     catch (Exception e)
245 13 Mar 07 enell 268     {
245 13 Mar 07 enell 269       throw new BASEFileException("At line " + str.getLineNumber(), e);
245 13 Mar 07 enell 270     }
6 10 Oct 05 enell 271
18 18 Oct 05 enell 272     if (nbr < 0)
18 18 Oct 05 enell 273     {
18 18 Oct 05 enell 274       throw new TooFewFieldsException("Too few fields in " + section.getType() + ", line " + str.getLineNumber());
18 18 Oct 05 enell 275     }
18 18 Oct 05 enell 276     if (nbr > 0)
18 18 Oct 05 enell 277     {
18 18 Oct 05 enell 278       throw new TooManyFieldsException("Too many fields in " + section.getType() + ", line " + str.getLineNumber());
18 18 Oct 05 enell 279     }
6 10 Oct 05 enell 280     return vec;
6 10 Oct 05 enell 281   }
6 10 Oct 05 enell 282
6 10 Oct 05 enell 283   /**
6 10 Oct 05 enell 284    * Read a line from the stream.
6 10 Oct 05 enell 285    * 
6 10 Oct 05 enell 286    * @return False if there is no more datarows in the section.
6 10 Oct 05 enell 287    * @throws IOException
6 10 Oct 05 enell 288    *             If an I/O error occurs.
6 10 Oct 05 enell 289    */
6 10 Oct 05 enell 290   private boolean readLine() throws IOException
6 10 Oct 05 enell 291   {
6 10 Oct 05 enell 292     buf = str.readLine();
6 10 Oct 05 enell 293     if (buf == null)
6 10 Oct 05 enell 294     {
6 10 Oct 05 enell 295       dataEnd = true;
185 12 Oct 06 enell 296       return false;
6 10 Oct 05 enell 297     }
6 10 Oct 05 enell 298     else if (buf.equals(""))
6 10 Oct 05 enell 299     {
6 10 Oct 05 enell 300       dataEnd = true;
185 12 Oct 06 enell 301       return false;
6 10 Oct 05 enell 302     }
6 10 Oct 05 enell 303     return true;
6 10 Oct 05 enell 304   }
6 10 Oct 05 enell 305
6 10 Oct 05 enell 306   /**
6 10 Oct 05 enell 307    * Skips all datarows so an new section can be read.
6 10 Oct 05 enell 308    * 
6 10 Oct 05 enell 309    * @return False if end of file is reached.
6 10 Oct 05 enell 310    * @throws IOException
6 10 Oct 05 enell 311    *             If an I/O error occurs.
6 10 Oct 05 enell 312    */
6 10 Oct 05 enell 313   private boolean skipData() throws IOException
6 10 Oct 05 enell 314   {
6 10 Oct 05 enell 315     if (!dataEnd)
6 10 Oct 05 enell 316     {
6 10 Oct 05 enell 317       if (!readLine()) return false;
6 10 Oct 05 enell 318       while (!dataEnd)
6 10 Oct 05 enell 319       {
6 10 Oct 05 enell 320         if (!readLine()) return false;
6 10 Oct 05 enell 321       }
6 10 Oct 05 enell 322     }
6 10 Oct 05 enell 323     return true;
6 10 Oct 05 enell 324   }
6 10 Oct 05 enell 325
6 10 Oct 05 enell 326   /**
6 10 Oct 05 enell 327    * Reads the headers in a section.
6 10 Oct 05 enell 328    * 
6 10 Oct 05 enell 329    * @param begin
6 10 Oct 05 enell 330    *            is true if it is the begining of the baseFile.
6 10 Oct 05 enell 331    * @return A HashMap with the fields as keys.
6 10 Oct 05 enell 332    * @throws IOException
6 10 Oct 05 enell 333    *             If an I/O error occurs.
6 10 Oct 05 enell 334    * @throws BadFormatException
6 10 Oct 05 enell 335    *             If the baseFile is badly formatted (ie. first line is not
6 10 Oct 05 enell 336    *             BASEFil)
6 10 Oct 05 enell 337    */
6 10 Oct 05 enell 338   private HashMap<String, String> readHeaders(boolean begin)
18 18 Oct 05 enell 339     throws IOException, BadFormatException
6 10 Oct 05 enell 340   {
6 10 Oct 05 enell 341     HashMap<String, String> nameValue = new HashMap<String, String>();
6 10 Oct 05 enell 342     if (begin)
6 10 Oct 05 enell 343     {
6 10 Oct 05 enell 344       if (!readLine()) return null;
18 18 Oct 05 enell 345       if (!buf.startsWith("BASEfile"))
18 18 Oct 05 enell 346       {
18 18 Oct 05 enell 347         throw new BadFormatException("The file must start with 'BASEfile'");
18 18 Oct 05 enell 348       }
6 10 Oct 05 enell 349     }
6 10 Oct 05 enell 350     if (!readLine()) return null;
6 10 Oct 05 enell 351     while (buf != null && buf.equals(""))
6 10 Oct 05 enell 352       if (!readLine()) return null;
6 10 Oct 05 enell 353     dataEnd = false;
6 10 Oct 05 enell 354     while (buf != null && !buf.equals("%"))
6 10 Oct 05 enell 355     {
6 10 Oct 05 enell 356       int tab = buf.indexOf("\t");
6 10 Oct 05 enell 357       if (tab != -1)
6 10 Oct 05 enell 358       {
6 10 Oct 05 enell 359         nameValue.put(buf.substring(0, tab), buf.substring(tab + 1));
6 10 Oct 05 enell 360       }
6 10 Oct 05 enell 361       else if (buf.length() > 0) nameValue.put(buf, "");
6 10 Oct 05 enell 362       if (!readLine()) return null;
6 10 Oct 05 enell 363     }
6 10 Oct 05 enell 364     return nameValue;
6 10 Oct 05 enell 365   }
6 10 Oct 05 enell 366
6 10 Oct 05 enell 367   /**
6 10 Oct 05 enell 368    * @return Returns the section.
6 10 Oct 05 enell 369    */
6 10 Oct 05 enell 370   public Object getSection()
6 10 Oct 05 enell 371   {
6 10 Oct 05 enell 372     return section;
6 10 Oct 05 enell 373   }
6 10 Oct 05 enell 374
768 16 Sep 08 jari 375 }