All Downloads are FREE. Search and download functionalities are using the official Maven repository.

internal.sql.lhod.TabDataReader Maven / Gradle / Ivy

The newest version!
/*
 * Copyright 2016 National Bank of Belgium
 *
 * Licensed under the EUPL, Version 1.1 or - as soon they will be approved
 * by the European Commission - subsequent versions of the EUPL (the "Licence");
 * You may not use this work except in compliance with the Licence.
 * You may obtain a copy of the Licence at:
 *
 * http://ec.europa.eu/idabc/eupl
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the Licence is distributed on an "AS IS" basis,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the Licence for the specific language governing permissions and
 * limitations under the Licence.
 */
package internal.sql.lhod;

import internal.nbbrd.picocsv.Csv;
import lombok.AccessLevel;
import lombok.NonNull;
import nbbrd.design.StaticFactoryMethod;

import java.io.Closeable;
import java.io.IOException;
import java.io.Reader;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;

import static java.lang.String.format;

/**
 * @author Philippe Charles
 */
@lombok.RequiredArgsConstructor(access = AccessLevel.PRIVATE)
public final class TabDataReader implements Closeable {

    private static final Csv.Format FORMAT = Csv.Format.RFC4180.toBuilder().delimiter('\t').build();

    @StaticFactoryMethod
    public static @NonNull TabDataReader of(@NonNull Reader reader) throws IOException {
        Csv.Reader tsv = Csv.Reader.of(FORMAT, Csv.ReaderOptions.DEFAULT, reader);
        List columns = readColumnHeaders(tsv);
        return new TabDataReader(tsv, columns, new String[columns.size()]);
    }

    private final Csv.Reader reader;

    @lombok.Getter
    private final List columns;

    private final String[] currentRow;

    private boolean closed = false;

    public boolean isClosed() throws IOException {
        return closed;
    }

    public boolean readNextRow() throws IOException {
        if (reader.readLine()) {
            if (!reader.readField()) {
                throw parseError(reader);
            }
            int idx = 0;
            do {
                currentRow[idx++] = reader.toString();
            } while (reader.readField());
            return true;
        }
        return false;
    }

    public String get(int index) {
        return currentRow[index];
    }

    @Override
    public void close() throws IOException {
        closed = true;
        reader.close();
    }

    private static TabDataRemoteError parseError(Csv.Reader reader) throws IOException {
        if (!reader.readLine()) {
            throw new TabDataFormatError("Expected error on next row");
        }

        if (!reader.readField()) {
            throw new TabDataFormatError("Expected error code on next field");
        }
        String errorCode = reader.toString();

        if (!reader.readField()) {
            throw new TabDataFormatError("Expected error description on next field");
        }
        String errorMessage = reader.toString();

        try {
            return new TabDataRemoteError(errorMessage, Integer.parseInt(errorCode));
        } catch (NumberFormatException ex) {
            throw new TabDataFormatError("Cannot parse error code", ex);
        }
    }

    private static List readColumnHeaders(Csv.Reader reader) throws IOException {
        List names = readHeader(reader, "names");
        List types = readHeader(reader, "types");

        if (names.size() != types.size()) {
            throw new TabDataFormatError(format(Locale.ROOT, "Invalid data type length: expected '%s', found '%s'", names.size(), types.size()));
        }

        List result = new ArrayList<>();
        for (int i = 0; i < names.size(); i++) {
            try {
                result.add(new TabDataColumn(names.get(i), Integer.parseInt(types.get(i))));
            } catch (NumberFormatException ex) {
                throw new TabDataFormatError("Cannot parse type code", ex);
            }
        }
        return result;
    }

    private static List readHeader(Csv.Reader reader, String id) throws IOException {
        if (!reader.readLine()) {
            throw new TabDataFormatError(format(Locale.ROOT, "Expected header %s", id));
        }
        if (!reader.readField()) {
            throw parseError(reader);
        }
        List result = new ArrayList<>();
        result.add(reader.toString());
        while (reader.readField()) {
            result.add(reader.toString());
        }
        return result;
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy