java/sql-dk/src/main/java/info/globalcode/sql/dk/formatting/TabularWrappingFormatter.java
author František Kučera <franta-hg@frantovo.cz>
Thu, 24 Oct 2019 21:43:08 +0200
branchv_0
changeset 250 aae5009bd0af
parent 238 4a1864c3e867
permissions -rw-r--r--
fix license version: GNU GPLv3
     1 /**
     2  * SQL-DK
     3  * Copyright © 2014 František Kučera (frantovo.cz)
     4  *
     5  * This program is free software: you can redistribute it and/or modify
     6  * it under the terms of the GNU General Public License as published by
     7  * the Free Software Foundation, version 3 of the License.
     8  *
     9  * This program is distributed in the hope that it will be useful,
    10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
    11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    12  * GNU General Public License for more details.
    13  *
    14  * You should have received a copy of the GNU General Public License
    15  * along with this program. If not, see <http://www.gnu.org/licenses/>.
    16  */
    17 package info.globalcode.sql.dk.formatting;
    18 
    19 import info.globalcode.sql.dk.ColorfulPrintWriter.TerminalColor;
    20 import java.util.ArrayList;
    21 import java.util.List;
    22 import static info.globalcode.sql.dk.Functions.lpad;
    23 import static info.globalcode.sql.dk.Functions.rpad;
    24 import static info.globalcode.sql.dk.Functions.repeat;
    25 
    26 /**
    27  * Longer values are line-wrapped – the cell then contains multiple lines. Marks are added to
    28  * signalize forced line ends (not present in original data).
    29  *
    30  * @author Ing. František Kučera (frantovo.cz)
    31  */
    32 public class TabularWrappingFormatter extends TabularFormatter {
    33 
    34 	public static final String NAME = "tabular-wrapping"; // bash-completion:formatter
    35 	private List<String[]> currentRow;
    36 
    37 	public TabularWrappingFormatter(FormatterContext formatterContext) {
    38 		super(formatterContext);
    39 	}
    40 
    41 	@Override
    42 	public void writeStartResultSet(ColumnsHeader header) {
    43 		super.writeStartResultSet(header);
    44 		currentRow = new ArrayList<>(header.getColumnCount());
    45 	}
    46 
    47 	@Override
    48 	protected void writeColumnValueInternal(Object value) {
    49 		boolean rightAlign = value instanceof Number || value instanceof Boolean;
    50 		String valueString = String.valueOf(value);
    51 		int columnWidth = getColumnWidth(getCurrentColumnsCount()) - 1;  // -1 = space for new line symbol
    52 		currentRow.add(wrapLines(valueString, columnWidth, rightAlign));
    53 	}
    54 
    55 	@Override
    56 	public void writeEndRow() {
    57 		super.writeEndRow();
    58 
    59 		int wrappedLine = 0;
    60 		boolean hasMoreWrappedLines;
    61 
    62 		do {
    63 			hasMoreWrappedLines = false;
    64 			for (int i = 0; i < currentRow.size(); i++) {
    65 				if (i == 0) {
    66 					printTableIndent();
    67 					printTableBorder("│ ");
    68 				} else {
    69 					printTableBorder(" │ ");
    70 				}
    71 				String[] columnArray = currentRow.get(i);
    72 				if (wrappedLine < columnArray.length) {
    73 					printValueWithWhitespaceReplaced(columnArray[wrappedLine]);
    74 
    75 					if (wrappedLine < columnArray.length - 1) {
    76 						out.print(TerminalColor.Red, "↩");
    77 						hasMoreWrappedLines = true;
    78 					} else {
    79 						out.print(" ");
    80 					}
    81 
    82 				} else {
    83 					out.print(repeat(' ', getColumnWidth(i + 1)));
    84 				}
    85 
    86 				if (i == (currentRow.size() - 1)) {
    87 					printTableBorder(" │");
    88 				}
    89 			}
    90 			out.println();
    91 			out.flush();
    92 			wrappedLine++;
    93 		} while (hasMoreWrappedLines);
    94 
    95 		currentRow.clear();
    96 	}
    97 
    98 	@Override
    99 	public void writeEndRowInternal() {
   100 		// already done – wrapped row ends
   101 	}
   102 
   103 	private static String[] wrapLines(String s, int width, boolean rightAlign) {
   104 		String[] array = new String[(s.length() - 1) / width + 1];
   105 		for (int i = 0; i < array.length; i++) {
   106 			if (i == array.length - 1) {
   107 				String part = s.substring(i * width, s.length());
   108 				array[i] = rightAlign ? lpad(part, width) : rpad(part, width);
   109 			} else {
   110 				array[i] = s.substring(i * width, (i + 1) * width);
   111 			}
   112 		}
   113 		return array;
   114 	}
   115 }