src/test/TestFlatFileParser.java

Code
Comments
Other
Rev Date Author Line
4925 08 May 09 nicklas 1 import java.io.IOException;
1106 23 Aug 05 enell 2 import java.io.InputStream;
2409 21 Jun 06 enell 3 import java.util.Arrays;
2494 08 Aug 06 nicklas 4 import java.util.HashSet;
4925 08 May 09 nicklas 5 import java.util.List;
2494 08 Aug 06 nicklas 6 import java.util.Set;
4925 08 May 09 nicklas 7 import java.util.regex.Matcher;
1106 23 Aug 05 enell 8 import java.util.regex.Pattern;
1106 23 Aug 05 enell 9
4925 08 May 09 nicklas 10 import net.sf.basedb.core.BaseException;
1106 23 Aug 05 enell 11 import net.sf.basedb.util.FileUtil;
2203 28 Apr 06 nicklas 12 import net.sf.basedb.util.parser.FlatFileParser;
2203 28 Apr 06 nicklas 13 import net.sf.basedb.util.parser.Mapper;
4925 08 May 09 nicklas 14 import net.sf.basedb.util.parser.FlatFileParser.Data;
3554 12 Jul 07 enell 15 import net.sf.basedb.util.parser.FlatFileParser.Line;
1106 23 Aug 05 enell 16
1106 23 Aug 05 enell 17 /*
1106 23 Aug 05 enell 18  $Id$
1106 23 Aug 05 enell 19
3675 16 Aug 07 jari 20  Copyright (C) 2005 Johan Enell, Nicklas Nordborg
4889 06 Apr 09 nicklas 21  Copyright (C) 2006 Johan Enell, Jari Häkkinen, Nicklas Nordborg
3675 16 Aug 07 jari 22  Copyright (C) 2007 Johan Enell
1106 23 Aug 05 enell 23  
2409 21 Jun 06 enell 24  This file is part of BASE - BioArray Software Environment.
2409 21 Jun 06 enell 25  Available at http://base.thep.lu.se/
1106 23 Aug 05 enell 26
1106 23 Aug 05 enell 27  BASE is free software; you can redistribute it and/or
1106 23 Aug 05 enell 28  modify it under the terms of the GNU General Public License
4480 05 Sep 08 jari 29  as published by the Free Software Foundation; either version 3
1106 23 Aug 05 enell 30  of the License, or (at your option) any later version.
1106 23 Aug 05 enell 31
1106 23 Aug 05 enell 32  BASE is distributed in the hope that it will be useful,
1106 23 Aug 05 enell 33  but WITHOUT ANY WARRANTY; without even the implied warranty of
1106 23 Aug 05 enell 34  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
1106 23 Aug 05 enell 35  GNU General Public License for more details.
1106 23 Aug 05 enell 36
1106 23 Aug 05 enell 37  You should have received a copy of the GNU General Public License
4514 11 Sep 08 jari 38  along with BASE. If not, see <http://www.gnu.org/licenses/>.
1106 23 Aug 05 enell 39  */
1106 23 Aug 05 enell 40
1106 23 Aug 05 enell 41 /**
1106 23 Aug 05 enell 42  
1106 23 Aug 05 enell 43  @base.modified $Date$
1106 23 Aug 05 enell 44  @author Enell
1106 23 Aug 05 enell 45  @version 2.0
1106 23 Aug 05 enell 46  */
1106 23 Aug 05 enell 47 public class TestFlatFileParser
1106 23 Aug 05 enell 48 {
1106 23 Aug 05 enell 49   static boolean ok = true;
2409 21 Jun 06 enell 50
1106 23 Aug 05 enell 51   public static void main(String[] args)
1106 23 Aug 05 enell 52   {
1106 23 Aug 05 enell 53     TestUtil.checkArgs(args);
1106 23 Aug 05 enell 54     TestUtil.begin();
1106 23 Aug 05 enell 55     ok = test_all();
1106 23 Aug 05 enell 56     TestUtil.stop();
1106 23 Aug 05 enell 57   }
1106 23 Aug 05 enell 58
1106 23 Aug 05 enell 59   static boolean test_all()
1106 23 Aug 05 enell 60   {
1106 23 Aug 05 enell 61     write("++Testing flat file parser");
1106 23 Aug 05 enell 62
2409 21 Jun 06 enell 63     FlatFileParser ffp = test_create("\"(.*)=(.*)\"", "\"?(.*?)\"?(\\t\"?(.*?)\"?){10,}", null, "\\t", null, null, 20, 10, 0);
1106 23 Aug 05 enell 64
2959 27 Nov 06 nicklas 65     test_parse(ffp, "data/test.parse.hskg.plates.txt", "\\3\\", "\\cluster_id\\", "Row:\\1\\, Col:\\2\\");
2959 27 Nov 06 nicklas 66     test_parse(ffp, "data/test.parse.genepix.result.gpr", "\\3\\", "\\Name\\", "B\\Block\\R\\Row\\C\\Column\\", "=col('Dia.')",
2409 21 Jun 06 enell 67       "=col('Dia.') / 2", "=\\Name\\+':'+\\ID\\");
2409 21 Jun 06 enell 68
2409 21 Jun 06 enell 69     ffp = test_create("(.*)=,(.*)", null, null, ",", null, "\\[(.*)\\]", 20, 10, 0);
2959 27 Nov 06 nicklas 70     test_parse_section(ffp, "data/test.parse.printmap.mwbr");
1106 23 Aug 05 enell 71
7670 21 Mar 19 nicklas 72     ffp = test_create(null, "Name\\t.*", null, "\\t", "#.*", null, 20, 0, 10);
7670 21 Mar 19 nicklas 73     test_parse(ffp, "data/test.annotation.import.xlsx", "\\Name\\", "\\Time (hours)\\", "\\Age (years)\\", "\\Timestamp\\", "\\Comment #1\\", "\\Comment #2\\");
7670 21 Mar 19 nicklas 74     
2409 21 Jun 06 enell 75     write("++Testing file parser " + (ok ? "OK" : "Failed") + "\n");
1106 23 Aug 05 enell 76     return ok;
1106 23 Aug 05 enell 77   }
1106 23 Aug 05 enell 78
2409 21 Jun 06 enell 79   public static FlatFileParser test_create(String header, String data_header, String data_footer, String data, String ignore, String section, int max_unknown_lines, int min_data_columns, int max_data_columns)
1106 23 Aug 05 enell 80   {
1106 23 Aug 05 enell 81     FlatFileParser ffp = new FlatFileParser();
1106 23 Aug 05 enell 82     if (header != null) ffp.setHeaderRegexp(Pattern.compile(header));
1106 23 Aug 05 enell 83     if (data_header != null) ffp.setDataHeaderRegexp(Pattern.compile(data_header));
1616 15 Nov 05 enell 84     if (data_footer != null) ffp.setDataFooterRegexp(Pattern.compile(data_footer));
1106 23 Aug 05 enell 85     if (data != null) ffp.setDataSplitterRegexp(Pattern.compile(data));
2203 28 Apr 06 nicklas 86     ffp.setTrimQuotes(true);
1106 23 Aug 05 enell 87     if (ignore != null) ffp.setIgnoreRegexp(Pattern.compile(ignore));
1616 15 Nov 05 enell 88     if (section != null) ffp.setSectionRegexp(Pattern.compile(section));
1106 23 Aug 05 enell 89     ffp.setMaxUnknownLines(max_unknown_lines);
1106 23 Aug 05 enell 90     ffp.setMinDataColumns(min_data_columns);
1106 23 Aug 05 enell 91     ffp.setMaxDataColumns(max_data_columns);
1106 23 Aug 05 enell 92     return ffp;
1106 23 Aug 05 enell 93   }
1106 23 Aug 05 enell 94
2203 28 Apr 06 nicklas 95   public static void test_parse(FlatFileParser ffp, String file, String... mappings)
1106 23 Aug 05 enell 96   {
1106 23 Aug 05 enell 97     try
1106 23 Aug 05 enell 98     {
2038 21 Feb 06 nicklas 99       InputStream in = FileUtil.getInputStream(new java.io.File(file));
5759 26 Sep 11 nicklas 100       test_parse(ffp, file, in, mappings);
5759 26 Sep 11 nicklas 101     }
5759 26 Sep 11 nicklas 102     catch (Throwable ex)
5759 26 Sep 11 nicklas 103     {
5759 26 Sep 11 nicklas 104       write("--Parse FAILED (" + file + ")");
5759 26 Sep 11 nicklas 105       ex.printStackTrace();
5759 26 Sep 11 nicklas 106       ok = false;
5759 26 Sep 11 nicklas 107     }
5759 26 Sep 11 nicklas 108   }
5759 26 Sep 11 nicklas 109
5759 26 Sep 11 nicklas 110
5759 26 Sep 11 nicklas 111   public static void test_parse(FlatFileParser ffp, String file, InputStream in, String... mappings)
5759 26 Sep 11 nicklas 112   {
5759 26 Sep 11 nicklas 113     try
5759 26 Sep 11 nicklas 114     {
2992 01 Dec 06 enell 115       ffp.setInputStream(in, "ISO-8859-1");
1273 07 Sep 05 nicklas 116       FlatFileParser.LineType last_line_type = ffp.parseHeaders();
2203 28 Apr 06 nicklas 117       int i = 0;
2203 28 Apr 06 nicklas 118       int headers = ffp.getLineCount();
2203 28 Apr 06 nicklas 119       while (i < headers)
1106 23 Aug 05 enell 120       {
1106 23 Aug 05 enell 121         write(i, ffp.getLine(i));
2203 28 Apr 06 nicklas 122         i++;
1106 23 Aug 05 enell 123       }
2203 28 Apr 06 nicklas 124       if (!TestUtil.getSilent()) write("--Column headers: " + ffp.getColumnHeaders());
2409 21 Jun 06 enell 125       if ((last_line_type == FlatFileParser.LineType.DATA_HEADER) || (last_line_type == FlatFileParser.LineType.DATA))
1106 23 Aug 05 enell 126       {
2203 28 Apr 06 nicklas 127         Mapper[] mappers = new Mapper[mappings.length];
2203 28 Apr 06 nicklas 128         for (int j = 0; j < mappings.length; ++j)
1106 23 Aug 05 enell 129         {
2203 28 Apr 06 nicklas 130           mappers[j] = ffp.getMapper(mappings[j]);
1106 23 Aug 05 enell 131         }
2203 28 Apr 06 nicklas 132         while (ffp.hasMoreData() && i < 20 + headers)
2203 28 Apr 06 nicklas 133         {
2203 28 Apr 06 nicklas 134           write(i++, ffp.nextData(), mappers);
2203 28 Apr 06 nicklas 135         }
1106 23 Aug 05 enell 136       }
1106 23 Aug 05 enell 137       in.close();
2409 21 Jun 06 enell 138       write("--Parse OK (" + file + ")");
1106 23 Aug 05 enell 139     }
2494 08 Aug 06 nicklas 140     catch (Throwable ex)
1106 23 Aug 05 enell 141     {
2409 21 Jun 06 enell 142       write("--Parse FAILED (" + file + ")");
1106 23 Aug 05 enell 143       ex.printStackTrace();
1106 23 Aug 05 enell 144       ok = false;
1106 23 Aug 05 enell 145     }
1106 23 Aug 05 enell 146   }
1106 23 Aug 05 enell 147
1616 15 Nov 05 enell 148   public static void test_parse_section(FlatFileParser ffp, String file)
1616 15 Nov 05 enell 149   {
1616 15 Nov 05 enell 150     try
1616 15 Nov 05 enell 151     {
2494 08 Aug 06 nicklas 152       Set<String> sections = new HashSet<String>(Arrays.asList("FileInformation", "Block1", "Block2", "Block3", "Block4", "mapping")); 
2038 21 Feb 06 nicklas 153       InputStream in = FileUtil.getInputStream(new java.io.File(file));
2992 01 Dec 06 enell 154       ffp.setInputStream(in, "ISO-8859-1");
2409 21 Jun 06 enell 155       FlatFileParser.Line section;
2409 21 Jun 06 enell 156       while (ffp.hasMoreSections())
1616 15 Nov 05 enell 157       {
1616 15 Nov 05 enell 158         section = ffp.nextSection();
2494 08 Aug 06 nicklas 159         sections.remove(section.name());
2409 21 Jun 06 enell 160         ffp.parseHeaders();
2409 21 Jun 06 enell 161         ffp.nextData();
1616 15 Nov 05 enell 162       }
1616 15 Nov 05 enell 163       in.close();
2409 21 Jun 06 enell 164       if (!sections.isEmpty())
2409 21 Jun 06 enell 165       {
2494 08 Aug 06 nicklas 166         throw new Exception("Didn't find all sections in (" + file + "), missed: " + sections);
2409 21 Jun 06 enell 167       }
2409 21 Jun 06 enell 168       write("--Parse sections OK (" + file + ")");
1616 15 Nov 05 enell 169     }
2494 08 Aug 06 nicklas 170     catch (Throwable ex)
1616 15 Nov 05 enell 171     {
2409 21 Jun 06 enell 172       write("--Parse sections FAILED (" + file + ")");
1616 15 Nov 05 enell 173       ex.printStackTrace();
1616 15 Nov 05 enell 174       ok = false;
1616 15 Nov 05 enell 175     }
1616 15 Nov 05 enell 176   }
1616 15 Nov 05 enell 177
1106 23 Aug 05 enell 178   static void write(String message)
1106 23 Aug 05 enell 179   {
1106 23 Aug 05 enell 180     System.out.println(message);
1106 23 Aug 05 enell 181   }
1106 23 Aug 05 enell 182
1106 23 Aug 05 enell 183   static void write(int i, FlatFileParser.Line line)
1106 23 Aug 05 enell 184   {
1106 23 Aug 05 enell 185     if (!TestUtil.getSilent())
1106 23 Aug 05 enell 186     {
1273 07 Sep 05 nicklas 187       if (line.type() == FlatFileParser.LineType.HEADER)
1106 23 Aug 05 enell 188       {
2409 21 Jun 06 enell 189         write("Line " + i + ": \t" + line.type() + "\t{" + line.name() + "} -> {" + line.value() + "}");
1106 23 Aug 05 enell 190       }
1106 23 Aug 05 enell 191       else
1106 23 Aug 05 enell 192       {
1106 23 Aug 05 enell 193         String s = line.line();
1106 23 Aug 05 enell 194         if (s.length() > 30) s = s.substring(0, 30);
2409 21 Jun 06 enell 195         write("Line " + i + ": \t" + line.type() + "\t" + s);
1106 23 Aug 05 enell 196       }
1106 23 Aug 05 enell 197     }
1106 23 Aug 05 enell 198   }
1106 23 Aug 05 enell 199
2203 28 Apr 06 nicklas 200   static void write(int i, FlatFileParser.Data data, Mapper[] mappings)
1106 23 Aug 05 enell 201   {
1106 23 Aug 05 enell 202     if (!TestUtil.getSilent())
1106 23 Aug 05 enell 203     {
1106 23 Aug 05 enell 204       StringBuffer sb = new StringBuffer();
2409 21 Jun 06 enell 205       sb.append("Line " + i + ": \tDATA(" + data.columns() + ")\t");
1106 23 Aug 05 enell 206       int max = data.columns();
1106 23 Aug 05 enell 207       if (max > 5) max = 5;
1106 23 Aug 05 enell 208       for (int j = 0; j < max; j++)
1106 23 Aug 05 enell 209       {
7665 20 Mar 19 nicklas 210         sb.append(j + "={" + data.getString(j) + "}\t");
1106 23 Aug 05 enell 211       }
5759 26 Sep 11 nicklas 212       if (max < data.columns()) sb.append((data.columns() - max) + " more...");
2203 28 Apr 06 nicklas 213       if (mappings != null)
2203 28 Apr 06 nicklas 214       {
5759 26 Sep 11 nicklas 215         sb.append("\n");
2203 28 Apr 06 nicklas 216         for (Mapper m : mappings)
2203 28 Apr 06 nicklas 217         {
7666 20 Mar 19 nicklas 218           sb.append(m+"={" + m.getString(data) + "}\t");
2203 28 Apr 06 nicklas 219         }
2203 28 Apr 06 nicklas 220       }
1106 23 Aug 05 enell 221       write(sb.toString());
1106 23 Aug 05 enell 222     }
1106 23 Aug 05 enell 223   }
3554 12 Jul 07 enell 224
4925 08 May 09 nicklas 225   public static void testHeaderLine(Line line, String name, String value)
3554 12 Jul 07 enell 226   {
3554 12 Jul 07 enell 227     if (!line.type().equals(FlatFileParser.LineType.HEADER))
4925 08 May 09 nicklas 228     {
4925 08 May 09 nicklas 229       throw new BaseException("Line is no header: "+line);
4925 08 May 09 nicklas 230     }
3554 12 Jul 07 enell 231     if (!line.name().equals(name))
4925 08 May 09 nicklas 232     {
4925 08 May 09 nicklas 233       throw new BaseException("Expected header name '"+name+"' on line '"+line+"'");
4925 08 May 09 nicklas 234     }
3554 12 Jul 07 enell 235     if (!line.value().equals(value))
4925 08 May 09 nicklas 236     {
4925 08 May 09 nicklas 237       throw new BaseException("Expected header value '"+value+"' on line '"+line+"'");
4925 08 May 09 nicklas 238     }
3554 12 Jul 07 enell 239   }
3554 12 Jul 07 enell 240
4925 08 May 09 nicklas 241   public static void testHeaderLine(Line line, String name, String splitter, String... expected)
3554 12 Jul 07 enell 242   {
4925 08 May 09 nicklas 243     testHeaderLine(line, name, splitter, Arrays.asList(expected));
4925 08 May 09 nicklas 244   }
4925 08 May 09 nicklas 245   
4925 08 May 09 nicklas 246   public static void testHeaderLine(Line line, String name, String splitter, List<String> expected)
4925 08 May 09 nicklas 247   {
4925 08 May 09 nicklas 248     if (!line.type().equals(FlatFileParser.LineType.HEADER))
4925 08 May 09 nicklas 249     {
4925 08 May 09 nicklas 250       throw new BaseException("Line is no header: "+line);
4925 08 May 09 nicklas 251     }
4925 08 May 09 nicklas 252     if (!line.name().equals(name))
4925 08 May 09 nicklas 253     {
4925 08 May 09 nicklas 254       throw new BaseException("Expected header name '"+name+"' on line '"+line+"'");
4925 08 May 09 nicklas 255     }
4925 08 May 09 nicklas 256     String[] lineValues = line.value().split(splitter);
4925 08 May 09 nicklas 257     for (int i = 0; i < lineValues.length; ++i)
4925 08 May 09 nicklas 258     {
4925 08 May 09 nicklas 259       String fnd = lineValues[i];
4925 08 May 09 nicklas 260       String exp = expected.get(i);
4925 08 May 09 nicklas 261       if (!fnd.equals(exp))
4925 08 May 09 nicklas 262       {
4925 08 May 09 nicklas 263         throw new BaseException("Expected header value '" + exp + "' at index " + i + " on line '" + line + "'" );
4925 08 May 09 nicklas 264       }
4925 08 May 09 nicklas 265     }
4925 08 May 09 nicklas 266   }
4925 08 May 09 nicklas 267
4925 08 May 09 nicklas 268   
4925 08 May 09 nicklas 269   public static void testLine(Line line, String name)
4925 08 May 09 nicklas 270   {
3554 12 Jul 07 enell 271     if (!line.line().equals(name))
4925 08 May 09 nicklas 272     {
4925 08 May 09 nicklas 273       throw new BaseException("Line '"+line+"' doesn't match '"+name+"'");
4925 08 May 09 nicklas 274     }
3554 12 Jul 07 enell 275   }
3554 12 Jul 07 enell 276
4925 08 May 09 nicklas 277   public static void testSection(Line line, String name)
3554 12 Jul 07 enell 278   {
3554 12 Jul 07 enell 279     if (!line.type().equals(FlatFileParser.LineType.SECTION))
4925 08 May 09 nicklas 280     {
4925 08 May 09 nicklas 281       throw new BaseException("Line is no section: "+line);
4925 08 May 09 nicklas 282     }
3554 12 Jul 07 enell 283     if (!line.name().equals(name))
4925 08 May 09 nicklas 284     {
4925 08 May 09 nicklas 285       throw new BaseException("Expected section name '"+name+"' on line '"+line+"'");
4925 08 May 09 nicklas 286     }
3554 12 Jul 07 enell 287   }
4925 08 May 09 nicklas 288   
4925 08 May 09 nicklas 289   public static void testDataSection(FlatFileParser ffp, List<Pattern[]> patterns, Line section)
4925 08 May 09 nicklas 290     throws IOException
4925 08 May 09 nicklas 291   {
4925 08 May 09 nicklas 292     int index = 0;
4925 08 May 09 nicklas 293     while (ffp.hasMoreData())
4925 08 May 09 nicklas 294     {
4925 08 May 09 nicklas 295       Data data = ffp.nextData();
4925 08 May 09 nicklas 296       if (index < patterns.size()) 
4925 08 May 09 nicklas 297       {
4925 08 May 09 nicklas 298         Pattern[] p = patterns.get(index);
4925 08 May 09 nicklas 299         if (p != null) testDataLine(data, p);
4925 08 May 09 nicklas 300       }
4925 08 May 09 nicklas 301       index++;
4925 08 May 09 nicklas 302     }
4925 08 May 09 nicklas 303     
4925 08 May 09 nicklas 304     if (index != patterns.size())
4925 08 May 09 nicklas 305     {
4925 08 May 09 nicklas 306       throw new BaseException("Unexpected number of data lines. Found "+index+
4925 08 May 09 nicklas 307           "; expected "+patterns.size() + " in section " + section);
4925 08 May 09 nicklas 308     }
4925 08 May 09 nicklas 309   }
4925 08 May 09 nicklas 310   
4925 08 May 09 nicklas 311   public static void testDataLine(Data data, Pattern[] regexp)
4925 08 May 09 nicklas 312   {
4925 08 May 09 nicklas 313     if (data.columns() != regexp.length)
4925 08 May 09 nicklas 314     {
4925 08 May 09 nicklas 315       throw new BaseException("Expected "+regexp.length+" columns on line "+data);
4925 08 May 09 nicklas 316     }
4925 08 May 09 nicklas 317     for (int i = 0; i < regexp.length; ++i)
4925 08 May 09 nicklas 318     {
4925 08 May 09 nicklas 319       Pattern p = regexp[i];
4925 08 May 09 nicklas 320       if (p != null)
4925 08 May 09 nicklas 321       {
7665 20 Mar 19 nicklas 322         String value = data.getString(i);
4925 08 May 09 nicklas 323         Matcher m = p.matcher(value);
4925 08 May 09 nicklas 324         if (!m.matches())
4925 08 May 09 nicklas 325         {
4925 08 May 09 nicklas 326           throw new BaseException("Value '"+value+"' at column " + i + " dosen't match the pattern '"+p+"' on line: " + data);
4925 08 May 09 nicklas 327         }
4925 08 May 09 nicklas 328       }
4925 08 May 09 nicklas 329     }
4925 08 May 09 nicklas 330   }
4925 08 May 09 nicklas 331   
1106 23 Aug 05 enell 332 }