private void writeTable()

in endorsed/src/org.apache.sis.util/main/org/apache/sis/io/TableAppender.java [704:844]


    private void writeTable() throws IOException {
        @SuppressWarnings("LocalVariableHidesMemberVariable")
        final String columnSeparator = this.columnSeparator;
        final Cell[] currentLine     = new Cell[maximalColumnWidths.length];
        final int    cellCount       = cells.size();
        for (int cellIndex=0; cellIndex<cellCount; cellIndex++) {
            /*
             * Copies in `currentLine` every cells to write in the current table row.
             * Those elements exclude the last null sentinel value. The `currentLine`
             * array initially contains no null element, but some element will be set
             * to null as we progress in the writing process.
             */
            Cell lineFill = null;
            int currentCount = 0;
            do {
                final Cell cell = cells.get(cellIndex);
                if (cell == null) {
                    break;
                }
                if (cell.text == null) {
                    lineFill = new Cell("", cell.alignment, cell.fill);
                    break;
                }
                currentLine[currentCount++] = cell;
            }
            while (++cellIndex < cellCount);
            Arrays.fill(currentLine, currentCount, currentLine.length, lineFill);
            /*
             * The loop below will be executed as long as we have some lines to write,
             * (i.e. as long as at least one element is non-null). If a cell contains
             * EOL characters, then we will need to format it as a multi-lines cell.
             */
            while (!isEmpty(currentLine)) {
                for (int j=0; j<currentLine.length; j++) {
                    final boolean isFirstColumn = (j   == 0);
                    final boolean isLastColumn  = (j+1 == currentLine.length);
                    final Cell    cell          = currentLine[j];
                    final int     cellWidth     = maximalColumnWidths[j];
                    final int     cellPadding   = isLastColumn && rightBorder.isEmpty() ? 0 : cellWidth;
                    if (cell == null) {
                        if (isFirstColumn) {
                            out.append(leftBorder);
                        }
                        repeat(out, SPACE, cellPadding);
                        out.append(isLastColumn ? rightBorder : columnSeparator);
                        continue;
                    }
                    String cellText = cell.text;
                    int textLength = cellText.length();
                    Cell remaining = null;
                    for (int endOfFirstLine=0; endOfFirstLine < textLength;) {
                        int c = cellText.codePointAt(endOfFirstLine);
                        int next = endOfFirstLine + Character.charCount(c);
                        if (isLineOrParagraphSeparator(c)) {
                            /*
                             * If a EOL character has been found, write only the first line in the cell.
                             * The `currentLine[j]` element will be modified in order to contain only
                             * the remaining lines, which will be written in next loop iterations.
                             */
                            if (c == '\r' && (next < textLength) && cellText.charAt(next) == '\n') {
                                next++;
                            }
                            /*
                             * Verify if the remaining contains only white spaces. If so, those spaces
                             * will be ignored. But if there is at least one non-white character, then
                             * we will not skip those spaces. We use Character.isWhitespace(…) instead
                             * of Character.isSpaceChar(…) in order to consider non-breaking spaces as
                             * non-white characters. This is similar to the use of &nbsp; in HTML tables,
                             * which can be used for forcing the insertion of anotherwise ignored space.
                             */
                            for (int i=next; i<textLength; i += Character.charCount(c)) {
                                c = cellText.codePointAt(i);
                                if (!Character.isWhitespace(c)) {
                                    remaining = cell.substring(next);
                                    break;
                                }
                            }
                            cellText = cellText.substring(0, endOfFirstLine);
                            break;
                        }
                        endOfFirstLine = next;
                    }
                    currentLine[j] = remaining;
                    textLength = X364.lengthOfPlain(cellText, 0, cellText.length());
                    /*
                     * If the cell to write is actually a border, do a special processing
                     * in order to use the characters defined in the BOX static constant.
                     */
                    if (currentCount == 0) {
                        assert textLength == 0;
                        final int verticalBorder;
                        if      (cellIndex == 0)           verticalBorder = -1;
                        else if (cellIndex >= cellCount-1) verticalBorder = +1;
                        else                               verticalBorder =  0;
                        if (isFirstColumn) {
                            writeBorder(-1, verticalBorder, cell.fill);
                        }
                        repeat(out, cell.fill, Character.isWhitespace(cell.fill) ? cellPadding : cellWidth);
                        writeBorder(isLastColumn ? +1 : 0, verticalBorder, cell.fill);
                        continue;
                    }
                    /*
                     * If the cell is not a border, it is a normal cell.
                     * Write a single line of this cell content.
                     */
                    if (isFirstColumn) {
                        out.append(leftBorder);
                    }
                    final Appendable tabExpander = (cellText.indexOf('\t') >= 0)
                            ? new LineAppender(out, Integer.MAX_VALUE, true) : out;
                    switch (cell.alignment) {
                        default: {
                            throw new AssertionError(cell.alignment);
                        }
                        case ALIGN_LEFT: {
                            tabExpander.append(cellText);
                            repeat(tabExpander, cell.fill, cellPadding - textLength);
                            break;
                        }
                        case ALIGN_RIGHT: {
                            repeat(tabExpander, cell.fill, cellWidth - textLength);
                            tabExpander.append(cellText);
                            break;
                        }
                        case ALIGN_CENTER: {
                            final int leftPadding = (cellWidth - textLength) / 2;
                            repeat(tabExpander, cell.fill, leftPadding);
                            tabExpander.append(cellText);
                            repeat(tabExpander, cell.fill, (cellPadding - leftPadding) - textLength);
                            break;
                        }
                    }
                    out.append(isLastColumn ? rightBorder : columnSeparator);
                }
                if (lineSeparator == null) {
                    lineSeparator = System.lineSeparator();
                }
                out.append(lineSeparator);
            }
        }
    }