Skip to content

Commit 58d233a

Browse files
committed
DefaultPrinter: improve table columns selection
1 parent 513e6fd commit 58d233a

1 file changed

Lines changed: 43 additions & 38 deletions

File tree

console/src/main/java/org/jline/console/impl/DefaultPrinter.java

Lines changed: 43 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -439,10 +439,6 @@ private boolean doValueHighlight(Map<String,Object> options, String value) {
439439
}
440440
}
441441

442-
private void highlightAndPrint(int width, String style, String object, boolean doValueHighlight) {
443-
highlightAndPrint(width, valueHighlighter(style), object, doValueHighlight);
444-
}
445-
446442
private void highlightAndPrint(int width, SyntaxHighlighter highlighter, String object, boolean doValueHighlight) {
447443
for (String s: object.split("\\r?\\n")) {
448444
AttributedStringBuilder asb = new AttributedStringBuilder();
@@ -671,17 +667,17 @@ private List<Object> objectToList(Object obj) {
671667
return out;
672668
}
673669

674-
private boolean similarSets(Set<String> ref, Set<String> c2, double threshold) {
675-
boolean out = c2.containsAll(ref);
676-
if (!out) {
677-
int matches = 0;
678-
for (String s : ref) {
679-
if (c2.contains(s)) {
680-
matches += 1;
670+
private boolean similarSets(final Set<String> ref, final Set<String> c2, final int matchLimit) {
671+
boolean out = false;
672+
int limit = matchLimit;
673+
for (String s : ref) {
674+
if (c2.contains(s)) {
675+
limit--;
676+
if (limit == 0) {
677+
out = true;
678+
break;
681679
}
682680
}
683-
double r = (1.0*matches)/ref.size();
684-
out = r > threshold;
685681
}
686682
return out;
687683
}
@@ -766,8 +762,14 @@ private void highlightAndPrint(Map<String, Object> options, Object obj) {
766762
Object elem = collection.iterator().next();
767763
boolean convert = canConvert(elem);
768764
if ((elem instanceof Map || convert) && !options.containsKey(Printer.TO_STRING)) {
769-
Map<String, Object> map = convert ? objectToMap(options, elem)
770-
: keysToString((Map<Object, Object>) elem);
765+
List<Map<String,Object>> convertedCollection = new ArrayList<>();
766+
Set<String> keys = new HashSet<>();
767+
for (Object o : collection) {
768+
Map<String, Object> m = convert ? objectToMap(options, o)
769+
: keysToString((Map<Object, Object>) o);
770+
convertedCollection.add(m);
771+
keys.addAll(m.keySet());
772+
}
771773
List<String> _header;
772774
List<String> columnsIn = optionList(Printer.COLUMNS_IN, options);
773775
List<String> columnsOut = !options.containsKey("all") ? optionList(Printer.COLUMNS_OUT, options)
@@ -776,30 +778,38 @@ private void highlightAndPrint(Map<String, Object> options, Object obj) {
776778
_header = (List<String>) options.get(Printer.COLUMNS);
777779
} else {
778780
_header = columnsIn;
779-
_header.addAll(map.keySet().stream()
781+
_header.addAll(keys.stream()
780782
.filter(k -> !columnsIn.contains(k) && !hasMatch(columnsOut, k))
781783
.collect(Collectors.toList()));
782784
}
783785
List<String> header = new ArrayList<>();
784786
List<Integer> columns = new ArrayList<>();
785787
int headerWidth = 0;
786788
Set<String> refKeys = new HashSet<>();
787-
for (String value : _header) {
788-
if (!map.containsKey(value.split("\\.")[0]) && !map.containsKey(value)) {
789+
for (String v : _header) {
790+
String value = v.split("\\.")[0];
791+
if (!keys.contains(value)) {
789792
continue;
790793
}
791-
if (options.containsKey(Printer.COLUMNS)) {
792-
// do nothing
793-
} else if (!options.containsKey(Printer.STRUCT_ON_TABLE)) {
794-
Object val = mapValue(options, value, map);
795-
if (!simpleObject(val)) {
794+
if (!options.containsKey(Printer.COLUMNS) &&
795+
!options.containsKey(Printer.STRUCT_ON_TABLE)) {
796+
boolean simple = true;
797+
for (Map<String,Object> m : convertedCollection) {
798+
if (m.containsKey(value)) {
799+
Object val = mapValue(options, v, m);
800+
if (!simpleObject(val)) {
801+
simple = false;
802+
}
803+
break;
804+
}
805+
}
806+
if (!simple) {
796807
continue;
797808
}
798809
}
799-
String rk = map.containsKey(value) ? value : value.split("\\.")[0];
800-
refKeys.add(rk);
801-
header.add(value);
802-
String cn = columnName(value, options.containsKey(Printer.SHORT_NAMES));
810+
refKeys.add(value);
811+
header.add(v);
812+
String cn = columnName(v, options.containsKey(Printer.SHORT_NAMES));
803813
columns.add(cn.length() + 1);
804814
headerWidth += cn.length() + 1;
805815
if (headerWidth > width) {
@@ -809,14 +819,11 @@ private void highlightAndPrint(Map<String, Object> options, Object obj) {
809819
if (header.size() == 0) {
810820
throw new Exception("No columns for table!");
811821
}
812-
double mapSimilarity = 0.8;
813-
if (options.containsKey(Printer.MAP_SIMILARITY)) {
814-
mapSimilarity = ((BigDecimal)options.get(Printer.MAP_SIMILARITY)).doubleValue();
815-
}
816-
for (Object o : collection) {
817-
Map<String, Object> m = convert ? objectToMap(options, o)
818-
: keysToString((Map<Object, Object>) o);
819-
if (o instanceof Map && !similarSets(refKeys, m.keySet(), mapSimilarity)) {
822+
double mapSimilarity = ((BigDecimal)options.getOrDefault(Printer.MAP_SIMILARITY
823+
, new BigDecimal("0.8"))).doubleValue();
824+
int matchLimit = (int)Math.ceil(header.size() * mapSimilarity);
825+
for (Map<String, Object> m : convertedCollection) {
826+
if (!similarSets(refKeys, m.keySet(), matchLimit)) {
820827
throw new Exception("Not homogenous list!");
821828
}
822829
for (int i = 0; i < header.size(); i++) {
@@ -847,7 +854,7 @@ private void highlightAndPrint(Map<String, Object> options, Object obj) {
847854
}
848855
asb.columnSubSequence(0, width).println(terminal());
849856
int row = 0;
850-
for (Object o : collection) {
857+
for (Map<String, Object> m : convertedCollection) {
851858
AttributedStringBuilder asb2 = new AttributedStringBuilder().tabs(columns);
852859
if (doRowHighlight(row, tableRows)) {
853860
asb2.style(prntStyle.resolve(".rs"));
@@ -859,8 +866,6 @@ private void highlightAndPrint(Map<String, Object> options, Object obj) {
859866
asb2.append("\t");
860867
}
861868
row++;
862-
Map<String, Object> m = convert ? objectToMap(options, o)
863-
: keysToString((Map<Object, Object>) o);
864869
for (int i = 0; i < header.size(); i++) {
865870
if (i > 0) {
866871
asb2.append(columnSep);

0 commit comments

Comments
 (0)