package org.intermine.util;

/*
 * Copyright (C) 2002-2009 FlyMine
 *
 * This code may be freely distributed and modified under the
 * terms of the GNU Lesser General Public Licence.  This should
 * be distributed with the code.  See the LICENSE file for more
 * information or http://www.gnu.org/copyleft/lesser.html.
 *
 */


import java.io.BufferedReader;
import java.io.IOException;
import java.io.Reader;
import java.util.Iterator;
import java.util.NoSuchElementException;

import org.apache.commons.lang.text.StrMatcher;
import org.apache.commons.lang.text.StrTokenizer;

/**
 * Class for methods and util methods for parsing csv files and others.
 * @author Kim Rutherford
 * @author Jakub Kulaviak
 **/
public class FormattedTextParser
{

    /**
     * Return an Iterator over a tab delimited file.  Iterator.next() splits the current line at the
     * tabs and returns a String[] of the bits.  No attempt is made to deal with quoted tabs.
     * Lines beginning with # are ignored.
     * @param reader the Reader to read from
     * @return an Iterator over the lines of the Reader
     * @throws IOException if there is an error while reading from the Reader
     */
    public static Iterator parseTabDelimitedReader(final Reader reader) throws IOException {
        return parseDelimitedReader(reader, false, "\t");
    }

    /**
     * Return an Iterator over a comma delimited file.  Iterator.next() splits the current line at
     * the commas and returns a String[] of the bits, stripped of all quotes.
     * Lines beginning with # are ignored.
     * @param reader the Reader to read from
     * @return an Iterator over the lines of the Reader
     * @throws IOException if there is an error while reading from the Reader
     */
    public static Iterator<String[]> parseCsvDelimitedReader(final Reader reader)
    throws IOException {
        return parseDelimitedReader(reader, true, ",");
    }

    private static Iterator parseDelimitedReader(final Reader reader, final boolean stripQuotes,
                                                 final String delim)
    throws IOException {
        final BufferedReader bufferedReader = new BufferedReader(reader);

        return new Iterator() {
            String currentLine = null;

            {
                currentLine = getNextNonCommentLine();
            }

            public boolean hasNext() {
                return currentLine != null;
            }

            public Object next() {
                if (currentLine == null) {
                    throw new NoSuchElementException();
                }
                String lastLine = currentLine;

                try {
                    currentLine = getNextNonCommentLine();
                } catch (IOException e) {
                    throw new RuntimeException("error while reading from " + reader, e);
                }

                if (stripQuotes) {
                    StrMatcher delimMatcher = null;

                    if (delim.equals(",")) {
                        delimMatcher = StrMatcher.commaMatcher();
                    } else {
                        delimMatcher = StrMatcher.tabMatcher();
                    }
                    StrTokenizer tokeniser
                    = new StrTokenizer(lastLine, delimMatcher, StrMatcher.doubleQuoteMatcher());
                    tokeniser.setEmptyTokenAsNull(false);
                    tokeniser.setIgnoreEmptyTokens(false);
                    return tokeniser.getTokenArray();
                }
                return StringUtil.split(lastLine, delim);
            }

            public void remove() {
                throw new UnsupportedOperationException();
            }

            private String getNextNonCommentLine() throws IOException {
                String line = null;

                while (true) {
                    line = bufferedReader.readLine();
                    if (line == null) {
                        break;
                    }
                    if (!line.startsWith("#")) {
                        break;
                    }
                }
                return line;
            }
        };
    }
}

@@ -1372,21 +1372,19 @@
  over a 
-comma
+tab
  delimit
@@ -1435,16 +1435,20 @@
  line at
+ the
 %0A     * 
@@ -1452,17 +1452,692 @@
  * t
-he commas
+abs and returns a String%5B%5D of the bits.  No attempt is made to deal with quoted tabs.%0A     * Lines beginning with # are ignored.%0A     * @param reader the Reader to read from%0A     * @param stripQuotes whether or not to remove double quotes%0A     * @return an Iterator over the lines of the Reader%0A     * @throws IOException if there is an error while reading from the Reader%0A     */%0A    public static Iterator parseTabDelimitedReader(final Reader reader, boolean stripQuotes)%0A    throws IOException %7B%0A        return parseDelimitedReader(reader, stripQuotes, %22%5Ct%22);%0A    %7D%0A%0A    /**%0A     * Return an Iterator over a comma/tab delimited file.  Iterator.next() splits the current line%0A     *
  and

remove double quotes from tabbed files