// $HeadURL: // http://forge.abcd.harvard.edu/svn/screensaver/branches/iccbl/library-mgmt-rework/src/edu/harvard/med/screensaver/io/libraries/rnai/RNAiLibraryContentsParser.java // $ // $Id$ // Copyright © 2006, 2010, 2011, 2012 by the President and Fellows of Harvard College. // Screensaver is an open-source project developed by the ICCB-L and NSRB labs // at Harvard Medical School. This software is distributed under the terms of // the GNU General Public License. package edu.harvard.med.screensaver.io.libraries.rnai; import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.File; import java.io.FileReader; import java.io.FileWriter; import java.io.IOException; import java.io.InputStream; import java.util.Iterator; import java.util.Map; import edu.harvard.med.screensaver.db.GenericEntityDAO; import edu.harvard.med.screensaver.io.ParseError; import edu.harvard.med.screensaver.io.ParseException; import edu.harvard.med.screensaver.io.libraries.LibraryContentsParser; import edu.harvard.med.screensaver.io.workbook2.Cell; import edu.harvard.med.screensaver.io.workbook2.Row; import edu.harvard.med.screensaver.io.workbook2.Workbook; import edu.harvard.med.screensaver.io.workbook2.Worksheet; import edu.harvard.med.screensaver.model.libraries.Library; import edu.harvard.med.screensaver.model.libraries.Reagent; import edu.harvard.med.screensaver.model.libraries.Well; import edu.harvard.med.screensaver.util.AlphabeticCounter; import edu.harvard.med.screensaver.util.CSVPrintWriter; import edu.harvard.med.screensaver.util.Pair; import edu.harvard.med.screensaver.util.StringUtils; import org.apache.commons.lang.math.IntRange; import org.apache.log4j.Logger; import com.google.common.collect.Maps; /** * This class accomplishes both: * <ul> * <li>Parsing of the library input file, and * <li>Loading of the data into Library and related domain model objects on the * database. */ abstract public class WorkbookLibraryContentsParser<R extends Reagent> extends LibraryContentsParser<R> { private static final Logger log = Logger.getLogger(WorkbookLibraryContentsParser.class); private static final String FIELD_DELIMITER = "~~"; public static final int FIRST_DATA_ROW = 1; protected final Pair<Well,R> EMPTY_PARSE_RESULT = new Pair<Well,R>(null, null); private BufferedReader _reader; private int _lineNumber; private Map<IntRange,String> _worksheetRecordRanges; public WorkbookLibraryContentsParser(GenericEntityDAO dao, InputStream stream, Library library) { super(dao, stream, library); } public void convert() throws IOException { Workbook _workbook = new Workbook("Library Contents Input Stream", getStream()); File tmpFile = File.createTempFile("workbook", ".csv"); tmpFile.deleteOnExit(); log.debug("converting workbook into csv file: " + tmpFile.getAbsolutePath()); CSVPrintWriter writer = new CSVPrintWriter(new BufferedWriter(new FileWriter(tmpFile)), "\n", FIELD_DELIMITER); Iterator<Worksheet> worksheetsIterator = _workbook.iterator(); int prevSheetLastRecord = 0; int record = 0; _worksheetRecordRanges = Maps.newHashMap(); while (worksheetsIterator.hasNext()) { Worksheet worksheet = worksheetsIterator.next().forOrigin(0, FIRST_DATA_ROW); Iterator<Row> rowsIterator = worksheet.iterator(); while (rowsIterator.hasNext()) { for (Cell cell : rowsIterator.next()) { writer.print(cell.getAsString()); } writer.println(); ++record; } IntRange worksheetRecordRange = new IntRange(prevSheetLastRecord, record); _worksheetRecordRanges.put(worksheetRecordRange, worksheet.getName()); prevSheetLastRecord = record; } writer.close(); _reader = new BufferedReader(new FileReader(tmpFile)); log.debug("done converting workbook into csv file"); } public Pair<Well,R> parseNext() throws ParseException, IOException { if (_reader == null) { convert(); } String line = _reader.readLine(); ++_lineNumber; if (StringUtils.isEmpty(line)) { return null; } String[] values = line.split(FIELD_DELIMITER); try { return parse(values); } catch (ParseException e) { throw new ParseException(new ParseError(e.getError().getErrorMessage(), makeWorkbookCellLocation(_lineNumber, e.getError().getErrorLocation()))); } catch (RuntimeException e) { // in case subclass throws a RuntimeException, instead of a ParseException throw new ParseException(new ParseError(e.toString(), _lineNumber)); } } private String makeWorkbookCellLocation(int recordIndex, Object errorLocation) { try { for (Map.Entry<IntRange,String> worksheetRecordRangeEntry : _worksheetRecordRanges.entrySet()) { if (worksheetRecordRangeEntry.getKey().containsInteger(recordIndex)) { String cellColumn = AlphabeticCounter.toLabel(Integer.parseInt(errorLocation.toString()) - 1); int cellRow = recordIndex - worksheetRecordRangeEntry.getKey().getMinimumInteger() + 1; return worksheetRecordRangeEntry.getValue() + ":(" + cellColumn + "," + cellRow + ")"; } } } catch (Exception e) {} return "<workbook>"; } abstract protected Pair<Well,R> parse(String[] values) throws ParseException; }