// $HeadURL: http://seanderickson1@forge.abcd.harvard.edu/svn/screensaver/branches/serickson/3411/core/src/main/java/edu/harvard/med/screensaver/io/parseutil/CsvSetColumn.java $ // $Id: CsvSetColumn.java 6946 2012-01-13 18:24:30Z seanderickson1 $ // // 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.parseutil; import java.util.List; import com.google.common.collect.Lists; import edu.harvard.med.screensaver.io.DataExporter; import edu.harvard.med.screensaver.io.ParseError; import edu.harvard.med.screensaver.io.ParseException; /** * CsvSubListColumn extends the concept of CsvListColumn to support a nested level in a list * field, used in hairpin (shRNA) reagent libraries to code for multiple genes. * * The code does not extend CsvListColumn from an implementation perspective as this would * mean splitting on the usual list delimiter (;) first. For backward compatibility, the * outer list of lists actually uses colon (:) as a delimiter, so that the interpretation * of an existing list column is that it describes the first nested list. * * For example, "123;456;789" is parsed as [ [ 123, 456, 789 ] ], not [ [123], [456], [789] ]. * * @author William Rose * @param <E> the type of the sublist elements */ public abstract class CsvSubListColumn<E> extends CsvColumn<List<List<E>>> { public CsvSubListColumn(String name, int col, boolean isRequired) { super(name, col, isRequired); } @Override protected List<List<E>> parseField(String value) throws ParseException { List<List<E>> list = Lists.newArrayList(); if (value != null) { String[] values = value.split(DataExporter.SUBLIST_DELIMITER, -1); for (String v : values) { // Don't check duplicates here: they are not unexpected list.add(parseElement(v.trim())); } } return list; } protected List<E> parseElement(String value) throws ParseException { List<E> list = Lists.newArrayList(); if (value != null) { String[] values = value.split(DataExporter.LIST_DELIMITER, -1); for (String v : values) { v = v.trim(); E val = parseSubElement(v); if(v.length() > 0 && list.contains(val)) { throw new ParseException(new ParseError(getName() + " cannot contain duplicates: " + val)); } list.add(val); } } return list; } abstract protected E parseSubElement(String value); }