Skip to content

Commit

Permalink
fix(asciibox): ported the distortion bugfix from golang to java
Browse files Browse the repository at this point in the history
  • Loading branch information
sruehl committed Aug 19, 2022
1 parent 24edb1e commit b944ea1
Show file tree
Hide file tree
Showing 3 changed files with 120 additions and 32 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -34,15 +34,18 @@ public class AsciiBox {

private final String data;

// TODO: should be final but for the moment we mutate it in change box name... Maybe we find another solution
String compressedBoxSet;

protected AsciiBox(String data) {
Objects.requireNonNull(data);
asciiBoxWriter = AsciiBoxWriter.DEFAULT;
this.data = data;
this(AsciiBoxWriter.DEFAULT, data);
}

protected AsciiBox(AsciiBoxWriter asciiBoxWriter, String data) {
Objects.requireNonNull(data);
this.asciiBoxWriter = asciiBoxWriter;
this.data = data;
this.compressedBoxSet = asciiBoxWriter.boxSet.compressBoxSet();
}

/**
Expand Down Expand Up @@ -85,9 +88,11 @@ public AsciiBox changeBoxName(String newName) {
if (!asciiBoxWriter.hasBorders(this)) {
return asciiBoxWriter.boxString(newName, this.toString(), 0);
}
int minimumWidthWithNewName = (asciiBoxWriter.upperLeftCorner + asciiBoxWriter.horizontalLine + newName + asciiBoxWriter.upperRightCorner).length();
int minimumWidthWithNewName = (asciiBoxWriter.boxSet.upperLeftCorner + asciiBoxWriter.boxSet.horizontalLine + newName + asciiBoxWriter.boxSet.upperRightCorner).length();
int nameLengthDifference = minimumWidthWithNewName - (asciiBoxWriter.unwrap(this).width() + asciiBoxWriter.borderWidth + asciiBoxWriter.borderWidth);
return asciiBoxWriter.boxString(newName, asciiBoxWriter.unwrap(this).toString(), this.width() + nameLengthDifference);
AsciiBox asciiBox = asciiBoxWriter.boxString(newName, asciiBoxWriter.unwrap(this).toString(), this.width() + nameLengthDifference);
asciiBox.compressedBoxSet = asciiBoxWriter.boxSet.contributeToCompressedBoxSet(this);
return asciiBox;
}

public boolean isEmpty() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,21 +27,19 @@
import java.util.*;
import java.util.regex.Pattern;

import static org.apache.plc4x.java.spi.utils.ascii.BoxSet.combineCompressedBoxSets;

public class AsciiBoxWriter {

private final Logger LOGGER = LoggerFactory.getLogger(AsciiBoxWriter.class);

public static AsciiBoxWriter DEFAULT = new AsciiBoxWriter();

//public static AsciiBoxWriter LIGHT = new AsciiBoxWriter("┌","┐","┄","┆","└","┘");
public static AsciiBoxWriter LIGHT = new AsciiBoxWriter("╭","╮","┄","┆","╰","╯");
public static AsciiBoxWriter LIGHT = new AsciiBoxWriter("╭", "╮", "┄", "┆", "╰", "╯");

final BoxSet boxSet;

final String upperLeftCorner;
final String upperRightCorner;
final String horizontalLine;
final String verticalLine;
final String lowerLeftCorner;
final String lowerRightCorner;
final String newLine;
final String emptyPadding;
// the name gets prefixed with a extra symbol for indent
Expand All @@ -60,12 +58,7 @@ public AsciiBoxWriter(String upperLeftCorner,
String verticalLine,
String lowerLeftCorner,
String lowerRightCorner) {
this.upperLeftCorner = upperLeftCorner;
this.upperRightCorner = upperRightCorner;
this.horizontalLine = horizontalLine;
this.verticalLine = verticalLine;
this.lowerLeftCorner = lowerLeftCorner;
this.lowerRightCorner = lowerRightCorner;
this.boxSet = new BoxSet(upperLeftCorner, upperRightCorner, horizontalLine, verticalLine, lowerLeftCorner, lowerRightCorner);
this.newLine = "\n";
this.emptyPadding = " ";
// the name gets prefixed with a extra symbol for indent
Expand All @@ -85,7 +78,9 @@ public AsciiBoxWriter(String upperLeftCorner,
*/
public AsciiBox boxBox(String name, AsciiBox box, int charWidth) {
// TODO: if there is a box bigger then others in that this will get distorted
return boxString(name, box.toString(), charWidth);
AsciiBox asciiBox = boxString(name, box.toString(), charWidth);
asciiBox.compressedBoxSet = boxSet.contributeToCompressedBoxSet(box);
return asciiBox;
}

/**
Expand All @@ -100,15 +95,15 @@ public AsciiBox boxString(String name, String data, int charWidth) {
Objects.requireNonNull(data);
// Convert dos2unix as that messes with box rendering
data = data.replaceAll("\r\n", "\n");
AsciiBox rawBox = new AsciiBox(data);
AsciiBox rawBox = new AsciiBox(this, data);
int longestLine = rawBox.width();
if (charWidth < longestLine) {
LOGGER.trace("Overflow by {} chars", longestLine - charWidth);
charWidth = longestLine + borderWidth + borderWidth;
}
StringBuilder boxedString = new StringBuilder();
int namePadding = (Math.max(charWidth - name.length() - borderWidth - extraNameCharIndent - borderWidth, 0));
boxedString.append(upperLeftCorner).append(horizontalLine).append(name).append(StringUtils.repeat(horizontalLine, namePadding)).append(upperRightCorner).append(newLine);
boxedString.append(boxSet.upperLeftCorner).append(boxSet.horizontalLine).append(name).append(StringUtils.repeat(boxSet.horizontalLine, namePadding)).append(boxSet.upperRightCorner).append(newLine);
// Name of the header stretches the box so we align to that
charWidth = borderWidth + extraNameCharIndent + name.length() + namePadding + borderWidth;
for (String line : rawBox.lines()) {
Expand All @@ -118,11 +113,11 @@ public AsciiBox boxString(String name, String data, int charWidth) {
}
int frontPadding = (int) Math.floor(linePadding / 2.0);
int backPadding = (int) Math.ceil(linePadding / 2.0);
boxedString.append(verticalLine).append(StringUtils.repeat(emptyPadding, frontPadding)).append(line).append(StringUtils.repeat(emptyPadding, backPadding)).append(verticalLine).append(newLine);
boxedString.append(boxSet.verticalLine).append(StringUtils.repeat(emptyPadding, frontPadding)).append(line).append(StringUtils.repeat(emptyPadding, backPadding)).append(boxSet.verticalLine).append(newLine);
}
int bottomPadding = namePadding + name.length() + extraNameCharIndent;
boxedString.append(lowerLeftCorner).append(StringUtils.repeat(horizontalLine, bottomPadding)).append(lowerRightCorner);
return new AsciiBox(boxedString.toString());
boxedString.append(boxSet.lowerLeftCorner).append(StringUtils.repeat(boxSet.horizontalLine, bottomPadding)).append(boxSet.lowerRightCorner);
return new AsciiBox(this, boxedString.toString());
}

/**
Expand All @@ -134,7 +129,7 @@ public AsciiBox boxString(String name, String data, int charWidth) {
*/
public AsciiBox alignBoxes(Collection<AsciiBox> boxes, int desiredWidth) {
if (boxes.size() == 0) {
return new AsciiBox("");
return new AsciiBox(this, "");
}
int actualWidth = desiredWidth;
for (AsciiBox box : boxes) {
Expand All @@ -145,7 +140,7 @@ public AsciiBox alignBoxes(Collection<AsciiBox> boxes, int desiredWidth) {
}
}
LOGGER.trace("Working with {} chars", actualWidth);
AsciiBox bigBox = new AsciiBox("");
AsciiBox bigBox = new AsciiBox(this, "");
List<AsciiBox> currentBoxRow = new LinkedList<>();
int currentRowLength = 0;
for (AsciiBox box : boxes) {
Expand Down Expand Up @@ -213,7 +208,9 @@ public AsciiBox boxSideBySide(AsciiBox box1, AsciiBox box2) {
aggregateBox.append('\n');
}
}
return new AsciiBox(aggregateBox.toString());
AsciiBox asciiBox = new AsciiBox(aggregateBox.toString());
asciiBox.compressedBoxSet = combineCompressedBoxSets(box1, box2);
return asciiBox;
}

/**
Expand All @@ -231,7 +228,9 @@ public AsciiBox boxBelowBox(AsciiBox box1, AsciiBox box2) {
} else if (box2Width < box1Width) {
box2 = expandBox(box2, box1Width);
}
return new AsciiBox(box1.toString() + "\n" + box2.toString());
AsciiBox asciiBox = new AsciiBox(box1.toString() + "\n" + box2.toString());
asciiBox.compressedBoxSet = combineCompressedBoxSets(box1, box2);
return asciiBox;
}

AsciiBox mergeHorizontal(List<AsciiBox> boxes) {
Expand Down Expand Up @@ -264,7 +263,9 @@ AsciiBox expandBox(AsciiBox box, int desiredWidth) {
newBox.append(newLine);
}
}
return new AsciiBox(newBox.toString());
AsciiBox asciiBox = new AsciiBox(this, newBox.toString());
asciiBox.compressedBoxSet = boxSet.contributeToCompressedBoxSet(box);
return asciiBox;
}

/**
Expand All @@ -278,7 +279,7 @@ public boolean hasBorders(AsciiBox box) {
return false;
}
// Check if the first char is the upper left corner
return upperLeftCorner.equals(box.toString().substring(0, 1));
return boxSet.upperLeftCorner.equals(box.toString().substring(0, 1));
}

public AsciiBox unwrap(AsciiBox box) {
Expand All @@ -287,6 +288,7 @@ public AsciiBox unwrap(AsciiBox box) {
}
String[] originalLines = box.lines();
String[] newLines = new String[originalLines.length - 2];
String completeBoxSet = boxSet.contributeToCompressedBoxSet(box);
for (int i = 0; i < originalLines.length; i++) {
String line = originalLines[i];
if (i == 0) {
Expand All @@ -300,12 +302,15 @@ public AsciiBox unwrap(AsciiBox box) {
// Strip the vertical Lines and trim the padding
String unwrappedLine = line.substring(1, line.length() - 1);

if (!StringUtils.containsAny(unwrappedLine, verticalLine + horizontalLine)) {
if (!StringUtils.containsAny(unwrappedLine, completeBoxSet.replaceAll(",", ""))) {
// only trim boxes witch don't contain other boxes
unwrappedLine = StringUtils.trim(unwrappedLine);
}
newLines[i - 1] = unwrappedLine;
}
return new AsciiBox(StringUtils.join(newLines, newLine));
AsciiBox asciiBox = new AsciiBox(StringUtils.join(newLines, newLine));
asciiBox.compressedBoxSet = completeBoxSet;
return asciiBox;
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/

package org.apache.plc4x.java.spi.utils.ascii;

import org.apache.commons.lang3.StringUtils;

import java.util.Arrays;
import java.util.HashSet;
import java.util.Objects;
import java.util.Set;

class BoxSet {
final String upperLeftCorner;
final String upperRightCorner;
final String horizontalLine;
final String verticalLine;
final String lowerLeftCorner;
final String lowerRightCorner;

public BoxSet(String upperLeftCorner, String upperRightCorner, String horizontalLine, String verticalLine, String lowerLeftCorner, String lowerRightCorner) {
this.upperLeftCorner = upperLeftCorner;
this.upperRightCorner = upperRightCorner;
this.horizontalLine = horizontalLine;
this.verticalLine = verticalLine;
this.lowerLeftCorner = lowerLeftCorner;
this.lowerRightCorner = lowerRightCorner;
}

public String compressBoxSet() {
return upperLeftCorner + upperRightCorner + horizontalLine + verticalLine + lowerLeftCorner + lowerRightCorner;
}

String contributeToCompressedBoxSet(AsciiBox box) {
String actualSet = compressBoxSet();
if (box.compressedBoxSet.contains(actualSet)) {
// we have nothing to add
return box.compressedBoxSet;
}
return box.compressedBoxSet + "," + actualSet;
}

static String combineCompressedBoxSets(AsciiBox box1, AsciiBox box2) {
Set<String> allSets = new HashSet<>();
allSets.addAll(Arrays.asList(box1.compressedBoxSet.split(",")));
allSets.addAll(Arrays.asList(box2.compressedBoxSet.split(",")));
return StringUtils.join(allSets, ",");
}

@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
BoxSet boxSet = (BoxSet) o;
return upperLeftCorner.equals(boxSet.upperLeftCorner) && upperRightCorner.equals(boxSet.upperRightCorner) && horizontalLine.equals(boxSet.horizontalLine) && verticalLine.equals(boxSet.verticalLine) && lowerLeftCorner.equals(boxSet.lowerLeftCorner) && lowerRightCorner.equals(boxSet.lowerRightCorner);
}

@Override
public int hashCode() {
return Objects.hash(upperLeftCorner, upperRightCorner, horizontalLine, verticalLine, lowerLeftCorner, lowerRightCorner);
}
}

0 comments on commit b944ea1

Please sign in to comment.