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

io.linguarobot.aws.cdk.maven.text.table.TableWriter Maven / Gradle / Ivy

package io.linguarobot.aws.cdk.maven.text.table;

import com.google.common.collect.ImmutableList;
import io.linguarobot.aws.cdk.maven.text.Ansi;

import java.util.Arrays;
import java.util.List;
import java.util.function.Consumer;
import java.util.stream.Collectors;
import java.util.stream.IntStream;

public class TableWriter {

    private final List columns;
    private final Consumer writer;
    private int rowsPrinted;

    private TableWriter(Consumer writer, List columns) {
        this.columns = columns;
        this.writer = writer;
        this.rowsPrinted = 0;
    }

    public void print(Object[] row) {
        List cells = Arrays.stream(row)
                .map(String::valueOf)
                .map(value -> Cell.of(value))
                .collect(Collectors.toList());
        print(cells);
    }

    public void print(Cell... row) {
        print(Arrays.asList(row));
    }

    public void print(List row) {
        if (row.size() != columns.size()) {
            throw new IllegalArgumentException("The number of cells in the row is not the same as the number of " +
                    "columns defined for the table");
        }
        if (rowsPrinted == 0) {
            printHorizontalBorder();
            printRow(columns);
        }

        printRow(row);
        rowsPrinted++;
    }

    private void printRow(List row) {
        int height = IntStream.range(0, columns.size())
                .map(i -> ceilDiv(row.get(i).getValue().length(), columns.get(i).getWidth()))
                .max()
                .orElse(1);

        for (int i = 0; i < height; i++) {
            StringBuilder line = new StringBuilder();
            line.append('|');
            for (int j = 0; j < columns.size(); j++) {
                Column column = columns.get(j);
                Cell cell = row.get(j);
                int cellHeight = ceilDiv(cell.getValue().length(), column.getWidth());
                int topPadding = (height - cellHeight) / 2;
                int bottomPadding = ceilDiv(height - cellHeight, 2);
                line.append(' ');
                if (i < topPadding || i >= height - bottomPadding) {
                    append(line, ' ', column.getWidth());
                } else {
                    int start = (i - topPadding) * column.getWidth();
                    int end = Math.min(start + column.getWidth(), cell.getValue().length());
                    String textValue = cell.getValue().substring(start, end).trim();

                    int leftPadding;
                    int rightPadding;
                    Alignment alignment = cell.getAlignment()
                            .orElseGet(() -> column.getAlignment().orElse(Alignment.LEFT));
                    if (alignment == Alignment.LEFT) {
                        leftPadding = 0;
                        rightPadding = column.getWidth() - textValue.length();
                    } else if (alignment == Alignment.CENTER) {
                        leftPadding = ceilDiv(column.getWidth() - textValue.length(), 2);
                        rightPadding = (column.getWidth() - textValue.length()) / 2;
                    } else {
                        leftPadding = column.getWidth() - textValue.length();
                        rightPadding = 0;
                    }

                    append(line, ' ', leftPadding);
                    line.append(Ansi.format(cell.getAnsiParameters()));
                    line.append(textValue);
                    line.append(Ansi.clear());
                    append(line, ' ', rightPadding);
                }
                line.append(' ').append('|');
            }
            line.append('\n');
            writer.accept(line.toString());
        }

        printHorizontalBorder();
    }

    private void printHorizontalBorder() {
        StringBuilder line = new StringBuilder();
        appendHorizontalBorder(line);
        writer.accept(line.toString());
    }

    private void appendHorizontalBorder(StringBuilder out) {
        out.append('+');
        for (Column column : columns) {
            append(out, '-', column.getWidth() + 2);
            out.append('+');
        }
        out.append('\n');
    }

    private void append(StringBuilder out, char c, int n) {
        for (int i = 0; i < n; i++) {
            out.append(c);
        }
    }

    private int ceilDiv(int x, int y) {
        return (x + (x >= 0 ? 1 : -1) * (y - 1)) / y;
    }

    public static TableWriter of(Consumer lineWriter, Column... columns) {
        return of(lineWriter, Arrays.asList(columns));
    }

    public static TableWriter of(Consumer lineWriter, List columns) {
        if (columns.isEmpty()) {
            throw new IllegalArgumentException("At least one column must be defined");
        }
        return new TableWriter(lineWriter, ImmutableList.copyOf(columns));
    }

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy