private static ImmutableMap<String, FxIndex> loadFromCsv() { List<ResourceLocator> resources = ResourceConfig.orderedResources("FxIndexData.csv"); Map<String, FxIndex> map = new HashMap<>(); for (ResourceLocator resource : resources) { try { CsvFile csv = CsvFile.of(resource.getCharSource(), true); for (CsvRow row : csv.rows()) { FxIndex parsed = parseFxIndex(row); map.put(parsed.getName(), parsed); map.putIfAbsent(parsed.getName().toUpperCase(Locale.ENGLISH), parsed); } } catch (RuntimeException ex) { log.log(Level.SEVERE, "Error processing resource as FX Index CSV file: " + resource, ex); return ImmutableMap.of(); } } return ImmutableMap.copyOf(map); }
private static CsvFile parseAll( List<String> lines, int lineIndex, char separator, ImmutableList<String> headers, ImmutableMap<String, Integer> searchHeaders) { ImmutableList.Builder<CsvRow> rows = ImmutableList.builder(); for (int i = lineIndex; i < lines.size(); i++) { ImmutableList<String> fields = parseLine(lines.get(i), i + 1, separator); if (!fields.isEmpty()) { rows.add(new CsvRow(headers, searchHeaders, i + 1, fields)); } } return new CsvFile(headers, searchHeaders, rows.build()); }
private static CsvFile create(List<String> lines, boolean headerRow, char separator) { if (headerRow) { for (int i = 0; i < lines.size(); i++) { ImmutableList<String> headers = parseLine(lines.get(i), i + 1, separator); if (!headers.isEmpty()) { ImmutableMap<String, Integer> searchHeaders = buildSearchHeaders(headers); return parseAll(lines, i + 1, separator, headers, searchHeaders); } } throw new IllegalArgumentException("Could not read header row from empty CSV file"); } return parseAll(lines, 0, separator, ImmutableList.of(), ImmutableMap.of()); }
public void test_of_empty_no_header() { CsvFile csvFile = CsvFile.of(CharSource.wrap(""), false); assertEquals(csvFile.headers().size(), 0); assertEquals(csvFile.rowCount(), 0); assertEquals(csvFile.containsHeader("Foo"), false); assertEquals(csvFile.containsHeader(Pattern.compile("Foo")), false); }
/** * Parses the specified source as a CSV file, using a comma as the separator. * <p> * CSV files sometimes contain a Unicode Byte Order Mark. * Callers are responsible for handling this, such as by using {@link UnicodeBom}. * * @param source the CSV file resource * @param headerRow whether the source has a header row, an empty source must still contain the header * @return the CSV file * @throws UncheckedIOException if an IO exception occurs * @throws IllegalArgumentException if the file cannot be parsed */ public static CsvFile of(CharSource source, boolean headerRow) { return of(source, headerRow, ','); }
public void test_of_blank_row() { CsvFile csvFile = CsvFile.of(CharSource.wrap(CSV3), false); assertEquals(csvFile.rowCount(), 2); assertEquals(csvFile.row(0).lineNumber(), 1); assertEquals(csvFile.row(1).lineNumber(), 3); assertEquals(csvFile.row(0).fieldCount(), 2); assertEquals(csvFile.row(0).field(0), "r11"); assertEquals(csvFile.row(0).field(1), "r12"); assertEquals(csvFile.row(1).fieldCount(), 2); assertEquals(csvFile.row(1).field(0), "r21"); assertEquals(csvFile.row(1).field(1), "r22"); }
public void test_equalsHashCodeToString() { CsvFile a1 = CsvFile.of(CharSource.wrap(CSV1), true); CsvFile a2 = CsvFile.of(CharSource.wrap(CSV1), true); CsvFile b = CsvFile.of(CharSource.wrap(CSV2), true); CsvFile c = CsvFile.of(CharSource.wrap(CSV3), false); // file assertEquals(a1.equals(a1), true); assertEquals(a1.equals(a2), true); assertEquals(a1.equals(b), false); assertEquals(a1.equals(c), false); assertEquals(a1.equals(null), false); assertEquals(a1.equals(ANOTHER_TYPE), false); assertEquals(a1.hashCode(), a2.hashCode()); assertNotNull(a1.toString()); // row assertEquals(a1.row(0).equals(a1.row(0)), true); assertEquals(a1.row(0).equals(a2.row(0)), true); assertEquals(a1.row(0).equals(b.row(0)), false); assertEquals(c.row(0).equals(c.row(1)), false); assertEquals(a1.row(0).equals(ANOTHER_TYPE), false); assertEquals(a1.row(0).equals(null), false); assertEquals(a1.row(0).hashCode(), a2.row(0).hashCode()); assertNotNull(a1.row(0).toString()); }
public void test_of_short_data_row() { CsvFile csvFile = CsvFile.of(CharSource.wrap(CSV6), true); assertEquals(csvFile.headers(), ImmutableList.of("a", "b", "c")); assertEquals(csvFile.row(0).getField("a"), "r11"); assertEquals(csvFile.row(0).getField("b"), ""); assertEquals(csvFile.row(0).getField("c"), ""); assertEquals(csvFile.row(0).field(0), "r11"); assertEquals(csvFile.row(0).field(1), ""); assertEquals(csvFile.row(0).field(2), ""); assertThrows(() -> csvFile.row(0).field(4), IndexOutOfBoundsException.class); assertEquals(csvFile.row(1).getField("a"), "r21"); assertEquals(csvFile.row(1).getField("b"), "r22"); assertEquals(csvFile.row(1).getField("c"), ""); }
/** * Obtains an instance from a list of headers and rows. * <p> * The headers may be an empty list. * All the rows must contain a list of the same size, matching the header if present. * * @param headers the headers, empty if no headers * @param rows the data rows * @return the CSV file * @throws IllegalArgumentException if the rows do not match the headers */ public static CsvFile of(List<String> headers, List<? extends List<String>> rows) { ArgChecker.notNull(headers, "headers"); ArgChecker.notNull(rows, "rows"); int size = (headers.size() == 0 && rows.size() > 0 ? rows.get(0).size() : headers.size()); if (rows.stream().filter(row -> row.size() != size).findAny().isPresent()) { throw new IllegalArgumentException("Invalid data rows, each row must have same columns as header row"); } ImmutableList<String> copiedHeaders = ImmutableList.copyOf(headers); ImmutableMap<String, Integer> searchHeaders = buildSearchHeaders(copiedHeaders); ImmutableList.Builder<CsvRow> csvRows = ImmutableList.builder(); int firstLine = copiedHeaders.isEmpty() ? 1 : 2; for (int i = 0; i < rows.size(); i++) { csvRows.add(new CsvRow(copiedHeaders, searchHeaders, i + firstLine, ImmutableList.copyOf(rows.get(i)))); } return new CsvFile(copiedHeaders, searchHeaders, csvRows.build()); }
int lineNumber = 1; while (line != null) { ImmutableList<String> headers = CsvFile.parseLine(line, lineNumber, separator); if (!headers.isEmpty()) { return new CsvIterator(breader, separator, headers, CsvFile.buildSearchHeaders(headers), lineNumber);
/** * Parses the specified source as a CSV file where the separator is specified and might not be a comma. * <p> * This overload allows the separator to be controlled. * For example, a tab-separated file is very similar to a CSV file, the only difference is the separator. * <p> * CSV files sometimes contain a Unicode Byte Order Mark. * Callers are responsible for handling this, such as by using {@link UnicodeBom}. * * @param source the file resource * @param headerRow whether the source has a header row, an empty source must still contain the header * @param separator the separator used to separate each field, typically a comma, but a tab is sometimes used * @return the CSV file * @throws UncheckedIOException if an IO exception occurs * @throws IllegalArgumentException if the file cannot be parsed */ public static CsvFile of(CharSource source, boolean headerRow, char separator) { ArgChecker.notNull(source, "source"); List<String> lines = Unchecked.wrap(() -> source.readLines()); return create(lines, headerRow, separator); }
public void test_of_lists_header() { List<String> headers = Arrays.asList("1", "2"); List<List<String>> rows = Arrays.asList(Arrays.asList("a", "x"), Arrays.asList("b", "y")); CsvFile csvFile = CsvFile.of(headers, rows); assertEquals(csvFile.headers(), headers); assertEquals(csvFile.rows().size(), 2); assertEquals(csvFile.row(0).fields(), Arrays.asList("a", "x")); assertEquals(csvFile.row(1).fields(), Arrays.asList("b", "y")); }
/** * Parses the specified reader as a CSV file, using a comma as the separator. * <p> * This factory method takes a {@link Reader}. * Callers are encouraged to use {@link CharSource} instead of {@code Reader} * as it allows the resource to be safely managed. * <p> * This factory method allows the separator to be controlled. * For example, a tab-separated file is very similar to a CSV file, the only difference is the separator. * <p> * CSV files sometimes contain a Unicode Byte Order Mark. * Callers are responsible for handling this, such as by using {@link UnicodeBom}. * * @param reader the file resource * @param headerRow whether the source has a header row, an empty source must still contain the header * @return the CSV file * @throws UncheckedIOException if an IO exception occurs * @throws IllegalArgumentException if the file cannot be parsed */ public static CsvFile of(Reader reader, boolean headerRow) { return of(reader, headerRow, ','); }
public void test_of_quoting() { CsvFile csvFile = CsvFile.of(CharSource.wrap(CSV4), false); assertEquals(csvFile.rowCount(), 3); assertEquals(csvFile.row(0).fieldCount(), 2); assertEquals(csvFile.row(0).field(0), "alpha"); assertEquals(csvFile.row(0).field(1), "be, \"at\", one"); assertEquals(csvFile.row(1).fieldCount(), 2); assertEquals(csvFile.row(1).field(0), "alpha\",\"be\""); assertEquals(csvFile.row(1).field(1), "\"at\", one"); assertEquals(csvFile.row(2).fieldCount(), 2); assertEquals(csvFile.row(2).field(0), "r21"); assertEquals(csvFile.row(2).field(1), " r22 "); }
/** * Parses the specified reader as a CSV file where the separator is specified and might not be a comma. * <p> * This factory method takes a {@link Reader}. * Callers are encouraged to use {@link CharSource} instead of {@code Reader} * as it allows the resource to be safely managed. * <p> * This factory method allows the separator to be controlled. * For example, a tab-separated file is very similar to a CSV file, the only difference is the separator. * <p> * CSV files sometimes contain a Unicode Byte Order Mark. * Callers are responsible for handling this, such as by using {@link UnicodeBom}. * * @param reader the file resource * @param headerRow whether the source has a header row, an empty source must still contain the header * @param separator the separator used to separate each field, typically a comma, but a tab is sometimes used * @return the CSV file * @throws UncheckedIOException if an IO exception occurs * @throws IllegalArgumentException if the file cannot be parsed */ public static CsvFile of(Reader reader, boolean headerRow, char separator) { ArgChecker.notNull(reader, "source"); List<String> lines = Unchecked.wrap(() -> CharStreams.readLines(reader)); return create(lines, headerRow, separator); }
private static ImmutableMap<String, SwapIndex> loadFromCsv() { List<ResourceLocator> resources = ResourceConfig.orderedResources("SwapIndexData.csv"); Map<String, SwapIndex> map = new HashMap<>(); for (ResourceLocator resource : resources) { try { CsvFile csv = CsvFile.of(resource.getCharSource(), true); for (CsvRow row : csv.rows()) { SwapIndex parsed = parseSwapIndex(row); map.put(parsed.getName(), parsed); map.putIfAbsent(parsed.getName().toUpperCase(Locale.ENGLISH), parsed); } } catch (RuntimeException ex) { log.log(Level.SEVERE, "Error processing resource as Swap Index CSV file: " + resource, ex); return ImmutableMap.of(); } } return ImmutableMap.copyOf(map); }