diff --git a/src/main/java/io/jenkins/plugins/checks/api/ChecksOutput.java b/src/main/java/io/jenkins/plugins/checks/api/ChecksOutput.java index 4c6131e3..822e1716 100644 --- a/src/main/java/io/jenkins/plugins/checks/api/ChecksOutput.java +++ b/src/main/java/io/jenkins/plugins/checks/api/ChecksOutput.java @@ -15,12 +15,12 @@ */ public class ChecksOutput { private final String title; - private final List summary; - private final List text; + private final TruncatedString summary; + private final TruncatedString text; private final List annotations; private final List images; - private ChecksOutput(final String title, final List summary, final List text, + private ChecksOutput(final String title, final TruncatedString summary, final TruncatedString text, final List annotations, final List images) { this.title = title; this.summary = summary; @@ -37,8 +37,8 @@ private ChecksOutput(final String title, final List summary, final List< */ public ChecksOutput(final ChecksOutput that) { this(that.getTitle().orElse(null), - that.getSummary().map(Collections::singletonList).orElse(null), - that.getText().map(Collections::singletonList).orElse(null), + that.getSummary().map(TruncatedString::fromString).orElse(null), + that.getText().map(TruncatedString::fromString).orElse(null), that.getChecksAnnotations(), that.getChecksImages()); } @@ -60,19 +60,19 @@ private static String truncateText(List chunks, int maxLength, String tr } public Optional getSummary() { - return Optional.ofNullable(summary).map(StringUtils::join); + return Optional.ofNullable(summary).map(TruncatedString::build); } - public Optional getSummary(int maxLength, String truncateText) { - return Optional.ofNullable(summary).map(s -> truncateText(s, maxLength, truncateText)); + public Optional getSummary(TruncatedString.Truncator truncator) { + return Optional.ofNullable(summary).map(truncator::truncate); } public Optional getText() { - return Optional.ofNullable(text).map(StringUtils::join); + return Optional.ofNullable(text).map(TruncatedString::build); } - public Optional getText(int maxLength, String truncateText) { - return Optional.ofNullable(text).map(s -> truncateText(s, maxLength, truncateText)); + public Optional getText(TruncatedString.Truncator truncator) { + return Optional.ofNullable(text).map(truncator::truncate); } public List getChecksAnnotations() { @@ -99,8 +99,8 @@ public String toString() { */ public static class ChecksOutputBuilder { private String title; - private List summary; - private List text; + private TruncatedString summary; + private TruncatedString text; private List annotations; private List images; @@ -139,15 +139,11 @@ public ChecksOutputBuilder withTitle(final String title) { */ @SuppressWarnings("HiddenField") // builder pattern public ChecksOutputBuilder withSummary(final String summary) { - this.summary = new ArrayList<>(); - return appendSummary(summary); + return withSummary(new TruncatedString.Builder().addText(summary).build()); } - public ChecksOutputBuilder appendSummary(final String summary) { - if (this.summary == null) { - this.summary = new ArrayList<>(); - } - this.summary.add(requireNonNull(summary)); + public ChecksOutputBuilder withSummary(final TruncatedString summary) { + this.summary = requireNonNull(summary); return this; } @@ -164,15 +160,11 @@ public ChecksOutputBuilder appendSummary(final String summary) { */ @SuppressWarnings("HiddenField") // builder pattern public ChecksOutputBuilder withText(final String text) { - this.text = new ArrayList<>(); - return appendText(text); + return withText(new TruncatedString.Builder().addText(text).build()); } - public ChecksOutputBuilder appendText(final String text) { - if (this.text == null) { - this.text = new ArrayList<>(); - } - this.text.add(requireNonNull(text)); + public ChecksOutputBuilder withText(final TruncatedString text) { + this.text = requireNonNull(text); return this; } diff --git a/src/main/java/io/jenkins/plugins/checks/api/TruncatedString.java b/src/main/java/io/jenkins/plugins/checks/api/TruncatedString.java new file mode 100644 index 00000000..e1526cc3 --- /dev/null +++ b/src/main/java/io/jenkins/plugins/checks/api/TruncatedString.java @@ -0,0 +1,93 @@ +package io.jenkins.plugins.checks.api; + +import org.apache.commons.lang3.StringUtils; + +import java.util.ArrayList; +import java.util.List; + +public class TruncatedString { + + private final List chunks; + private final String readMoreLink; + + /** + * Create a {@link TruncatedString} with the provided limit and truncation message. + * + * @param truncatedMessage the message to be appended should maxSize be exceeded, e.g. + * "Some output is not shown here, see more on [Jenkins](url)." + */ + private TruncatedString(final String readMoreLink, final List chunks) { + this.readMoreLink = readMoreLink; + this.chunks = chunks; + } + + static TruncatedString fromString(String string) { + return new TruncatedString.Builder().addText(string).build(); + } + + public static class Builder { + private String readMoreLink; + private final List chunks = new ArrayList<>(); + + public TruncatedString build() { + return new TruncatedString(readMoreLink, chunks); + } + + public Builder withReadMoreLink(String readMoreLink) { + this.readMoreLink = readMoreLink; + return this; + } + + public Builder addText(CharSequence chunk) { + this.chunks.add(chunk); + return this; + } + + } + + public static abstract class Truncator { + + protected final int maxSize; + + public Truncator(int maxSize) { + this.maxSize = maxSize; + } + + public abstract String getReadMoreText(TruncatedString truncatedString); + + public String truncate(TruncatedString truncatedString) { + String readMoreText = getReadMoreText(truncatedString); + if (truncatedString.chunks.size() == 0) { + return null; + } + StringBuilder builder = new StringBuilder(); + for (CharSequence chunk: truncatedString.chunks) { + if (builder.length() + chunk.length() + readMoreText.length() < maxSize) { + builder.append(chunk); + } else { + builder.append(readMoreText); + break; + } + } + return builder.toString(); + } + } + + /* example implementation */ + public static class GitHubTruncator extends Truncator { + + public GitHubTruncator() { + super(65536); + } + + @Override + public String getReadMoreText(TruncatedString truncatedString) { + return String.format("%n%nOutput truncated - [more information](%s)", truncatedString.readMoreLink); + } + } + + public String build() { + return StringUtils.join(chunks); + } + +}