You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@karaf.apache.org by gn...@apache.org on 2016/11/29 16:58:57 UTC
karaf git commit: [KARAF-4868] Fix encoding problems with shell table
formatting
Repository: karaf
Updated Branches:
refs/heads/master 5f87ec263 -> d3e170bda
[KARAF-4868] Fix encoding problems with shell table formatting
Project: http://git-wip-us.apache.org/repos/asf/karaf/repo
Commit: http://git-wip-us.apache.org/repos/asf/karaf/commit/d3e170bd
Tree: http://git-wip-us.apache.org/repos/asf/karaf/tree/d3e170bd
Diff: http://git-wip-us.apache.org/repos/asf/karaf/diff/d3e170bd
Branch: refs/heads/master
Commit: d3e170bdab9b6d502c9a9f5c83c35bce9dd2d41d
Parents: 5f87ec2
Author: Guillaume Nodet <gn...@apache.org>
Authored: Tue Nov 29 17:58:35 2016 +0100
Committer: Guillaume Nodet <gn...@apache.org>
Committed: Tue Nov 29 17:58:35 2016 +0100
----------------------------------------------------------------------
.../karaf/shell/support/table/ShellTable.java | 66 ++++++++++++++++----
.../shell/support/table/ShellTableTest.java | 41 ++++++++++++
2 files changed, 96 insertions(+), 11 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/karaf/blob/d3e170bd/shell/core/src/main/java/org/apache/karaf/shell/support/table/ShellTable.java
----------------------------------------------------------------------
diff --git a/shell/core/src/main/java/org/apache/karaf/shell/support/table/ShellTable.java b/shell/core/src/main/java/org/apache/karaf/shell/support/table/ShellTable.java
index 8f3f245..476ba7c 100644
--- a/shell/core/src/main/java/org/apache/karaf/shell/support/table/ShellTable.java
+++ b/shell/core/src/main/java/org/apache/karaf/shell/support/table/ShellTable.java
@@ -16,17 +16,33 @@
*/
package org.apache.karaf.shell.support.table;
+import java.io.OutputStreamWriter;
import java.io.PrintStream;
+import java.lang.reflect.Field;
+import java.nio.charset.Charset;
+import java.nio.charset.CharsetEncoder;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class ShellTable {
- private List<Col> cols = new ArrayList<Col>();
- private List<Row> rows = new ArrayList<Row>();
- boolean showHeaders = true;
- private String separator = " \u2502 ";
+ private static final char SEP_HORIZONTAL = '\u2500';
+ private static final char SEP_VERTICAL = '|';
+ private static final char SEP_CROSS = '\u253c';
+
+ private static final char SEP_HORIZONTAL_ASCII = '-';
+ private static final char SEP_VERTICAL_ASCII = '|';
+ private static final char SEP_CROSS_ASCII = '+';
+
+ private static final String DEFAULT_SEPARATOR = " " + SEP_VERTICAL + " ";
+ private static final String DEFAULT_SEPARATOR_ASCII = " " + SEP_VERTICAL_ASCII + " ";
+ private static final String DEFAULT_SEPARATOR_NO_FORMAT = "\t";
+
+ private List<Col> cols = new ArrayList<>();
+ private List<Row> rows = new ArrayList<>();
+ private boolean showHeaders = true;
+ private String separator = DEFAULT_SEPARATOR;
private int size;
private String emptyTableText;
@@ -82,6 +98,15 @@ public class ShellTable {
}
public void print(PrintStream out, boolean format) {
+ boolean supported = false;
+ String encoding = getEncoding(out);
+ if (encoding != null) {
+ CharsetEncoder encoder = Charset.forName(encoding).newEncoder();
+ supported = encoder.canEncode(separator)
+ && encoder.canEncode(SEP_HORIZONTAL)
+ && encoder.canEncode(SEP_CROSS);
+ }
+ String separator = supported ? this.separator : DEFAULT_SEPARATOR_ASCII;
// "normal" table rendering, with borders
Row headerRow = new Row(cols);
@@ -100,9 +125,9 @@ public class ShellTable {
int iCol = 0;
for (Col col : cols) {
if (iCol++ == 0) {
- out.print(underline(col.getSize(), false));
+ out.print(underline(col.getSize(), false, supported));
} else {
- out.print(underline(col.getSize() + 3, true));
+ out.print(underline(col.getSize() + 3, true, supported));
}
iCol++;
}
@@ -111,8 +136,8 @@ public class ShellTable {
for (Row row : rows) {
if (!format) {
- if (separator == null || separator.equals(" \u2502 "))
- out.println(row.getContent(cols, "\t"));
+ if (separator == null || separator.equals(DEFAULT_SEPARATOR))
+ out.println(row.getContent(cols, DEFAULT_SEPARATOR_NO_FORMAT));
else out.println(row.getContent(cols, separator));
} else {
out.println(row.getContent(cols, separator));
@@ -124,6 +149,25 @@ public class ShellTable {
}
}
+ private String getEncoding(PrintStream ps) {
+ if (ps.getClass().getName().equals("org.apache.felix.gogo.runtime.threadio.ThreadPrintStream")) {
+ try {
+ ps = (PrintStream) ps.getClass().getMethod("getCurrent").invoke(ps);
+ } catch (Throwable t) {
+ // ignore
+ }
+ }
+ try {
+ Field f = ps.getClass().getDeclaredField("charOut");
+ f.setAccessible(true);
+ OutputStreamWriter osw = (OutputStreamWriter) f.get(ps);
+ return osw.getEncoding();
+ } catch (Throwable t) {
+ // ignore
+ }
+ return null;
+ }
+
private void adjustSize() {
int currentSize = 0;
for (Col col : cols) {
@@ -142,11 +186,11 @@ public class ShellTable {
}
- private String underline(int length, boolean crossAtBeg) {
+ private String underline(int length, boolean crossAtBeg, boolean supported) {
char[] exmarks = new char[length];
- Arrays.fill(exmarks, '\u2500');
+ Arrays.fill(exmarks, supported ? SEP_HORIZONTAL : SEP_HORIZONTAL_ASCII);
if (crossAtBeg) {
- exmarks[1] = '\u253c';
+ exmarks[1] = supported ? SEP_CROSS : SEP_CROSS_ASCII;
}
return new String(exmarks);
}
http://git-wip-us.apache.org/repos/asf/karaf/blob/d3e170bd/shell/core/src/test/java/org/apache/karaf/shell/support/table/ShellTableTest.java
----------------------------------------------------------------------
diff --git a/shell/core/src/test/java/org/apache/karaf/shell/support/table/ShellTableTest.java b/shell/core/src/test/java/org/apache/karaf/shell/support/table/ShellTableTest.java
index 575493d..0826e88 100644
--- a/shell/core/src/test/java/org/apache/karaf/shell/support/table/ShellTableTest.java
+++ b/shell/core/src/test/java/org/apache/karaf/shell/support/table/ShellTableTest.java
@@ -19,8 +19,12 @@
package org.apache.karaf.shell.support.table;
import java.io.ByteArrayOutputStream;
+import java.io.FileDescriptor;
+import java.io.FileInputStream;
import java.io.PrintStream;
+import org.apache.felix.gogo.runtime.threadio.ThreadIOImpl;
+import org.apache.felix.service.threadio.ThreadIO;
import org.junit.Test;
import static org.junit.Assert.assertEquals;
@@ -66,4 +70,41 @@ public class ShellTableTest {
" |quite long"), baos.toString());
}
+ @Test
+ public void testCP1252() throws Exception {
+ testNonUtf8("cp1252");
+ }
+
+ @Test
+ public void testANSI() throws Exception {
+ testNonUtf8("ANSI_X3.4-1968");
+ }
+
+ private void testNonUtf8(String encoding) throws Exception {
+ ShellTable table = new ShellTable();
+ table.column("col1");
+ table.column("col2").maxSize(-1).wrap();
+ table.addRow().addContent("my first column value", "my second column value is quite long");
+ table.size(50);
+
+ ThreadIO tio = new ThreadIOImpl();
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ PrintStream ps = new PrintStream(baos, false, encoding);
+ table.print(ps, true);
+ tio.setStreams(new FileInputStream(FileDescriptor.in), ps, ps);
+
+ table.print(System.out);
+
+ assertEquals(
+ "col1 | col2\n" +
+ "----------------------+---------------------------\n" +
+ "my first column value | my second column value is\n" +
+ " | quite long\n" +
+ "col1 | col2\n" +
+ "----------------------+---------------------------\n" +
+ "my first column value | my second column value is\n" +
+ " | quite long\n",
+ baos.toString());
+
+ }
}