You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@plc4x.apache.org by sr...@apache.org on 2022/08/19 16:05:37 UTC

[plc4x] branch develop updated: fix(asciibox): ported the distortion bugfix from golang to java

This is an automated email from the ASF dual-hosted git repository.

sruehl pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/plc4x.git


The following commit(s) were added to refs/heads/develop by this push:
     new b944ea173 fix(asciibox): ported the distortion bugfix from golang to java
b944ea173 is described below

commit b944ea173252897cecf3a8767f7db2f96c14183d
Author: Sebastian Rühl <sr...@apache.org>
AuthorDate: Fri Aug 19 18:05:30 2022 +0200

    fix(asciibox): ported the distortion bugfix from golang to java
---
 .../plc4x/java/spi/utils/ascii/AsciiBox.java       | 15 +++--
 .../plc4x/java/spi/utils/ascii/AsciiBoxWriter.java | 59 ++++++++--------
 .../apache/plc4x/java/spi/utils/ascii/BoxSet.java  | 78 ++++++++++++++++++++++
 3 files changed, 120 insertions(+), 32 deletions(-)

diff --git a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/utils/ascii/AsciiBox.java b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/utils/ascii/AsciiBox.java
index 2251e046a..8303fb038 100644
--- a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/utils/ascii/AsciiBox.java
+++ b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/utils/ascii/AsciiBox.java
@@ -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();
     }
 
     /**
@@ -85,9 +88,11 @@ public class AsciiBox {
         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() {
diff --git a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/utils/ascii/AsciiBoxWriter.java b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/utils/ascii/AsciiBoxWriter.java
index 6ad510b4c..e1cdd2bd5 100644
--- a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/utils/ascii/AsciiBoxWriter.java
+++ b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/utils/ascii/AsciiBoxWriter.java
@@ -27,6 +27,8 @@ import org.slf4j.LoggerFactory;
 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);
@@ -34,14 +36,10 @@ public class AsciiBoxWriter {
     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
@@ -60,12 +58,7 @@ public class AsciiBoxWriter {
                           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
@@ -85,7 +78,9 @@ public class AsciiBoxWriter {
      */
     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;
     }
 
     /**
@@ -100,7 +95,7 @@ public class AsciiBoxWriter {
         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);
@@ -108,7 +103,7 @@ public class AsciiBoxWriter {
         }
         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()) {
@@ -118,11 +113,11 @@ public class AsciiBoxWriter {
             }
             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());
     }
 
     /**
@@ -134,7 +129,7 @@ public class AsciiBoxWriter {
      */
     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) {
@@ -145,7 +140,7 @@ public class AsciiBoxWriter {
             }
         }
         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) {
@@ -213,7 +208,9 @@ public class AsciiBoxWriter {
                 aggregateBox.append('\n');
             }
         }
-        return new AsciiBox(aggregateBox.toString());
+        AsciiBox asciiBox = new AsciiBox(aggregateBox.toString());
+        asciiBox.compressedBoxSet = combineCompressedBoxSets(box1, box2);
+        return asciiBox;
     }
 
     /**
@@ -231,7 +228,9 @@ public class AsciiBoxWriter {
         } 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) {
@@ -264,7 +263,9 @@ public class AsciiBoxWriter {
                 newBox.append(newLine);
             }
         }
-        return new AsciiBox(newBox.toString());
+        AsciiBox asciiBox = new AsciiBox(this, newBox.toString());
+        asciiBox.compressedBoxSet = boxSet.contributeToCompressedBoxSet(box);
+        return asciiBox;
     }
 
     /**
@@ -278,7 +279,7 @@ public class AsciiBoxWriter {
             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) {
@@ -287,6 +288,7 @@ public class AsciiBoxWriter {
         }
         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) {
@@ -300,12 +302,15 @@ public class AsciiBoxWriter {
             // 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;
     }
+
 }
diff --git a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/utils/ascii/BoxSet.java b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/utils/ascii/BoxSet.java
new file mode 100644
index 000000000..6b5383b51
--- /dev/null
+++ b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/utils/ascii/BoxSet.java
@@ -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);
+    }
+}