Bug 574900: [Ltk-AST] Add SourceMessageUtil
Change-Id: I6f03847c102e7189120d723749be37ed8e3c9d06
diff --git a/ltk/org.eclipse.statet.ltk.core/src/org/eclipse/statet/ltk/core/util/SourceMessageUtil.java b/ltk/org.eclipse.statet.ltk.core/src/org/eclipse/statet/ltk/core/util/SourceMessageUtil.java
new file mode 100644
index 0000000..dff77b0
--- /dev/null
+++ b/ltk/org.eclipse.statet.ltk.core/src/org/eclipse/statet/ltk/core/util/SourceMessageUtil.java
@@ -0,0 +1,135 @@
+/*=============================================================================#
+ # Copyright (c) 2021 Stephan Wahlbrink and others.
+ #
+ # This program and the accompanying materials are made available under the
+ # terms of the Eclipse Public License 2.0 which is available at
+ # https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
+ # which is available at https://www.apache.org/licenses/LICENSE-2.0.
+ #
+ # SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
+ #
+ # Contributors:
+ # Stephan Wahlbrink <sw@wahlbrink.eu> - initial API and implementation
+ #=============================================================================*/
+
+package org.eclipse.statet.ltk.core.util;
+
+import static org.eclipse.statet.jcommons.lang.ObjectUtils.nonNullAssert;
+import static org.eclipse.statet.jcommons.lang.ObjectUtils.nonNullLateInit;
+
+import org.eclipse.jface.text.BadLocationException;
+
+import org.eclipse.statet.jcommons.lang.NonNullByDefault;
+
+import org.eclipse.statet.ltk.ast.core.AstNode;
+import org.eclipse.statet.ltk.ast.core.StatusDetail;
+import org.eclipse.statet.ltk.core.source.SourceContent;
+
+
+@NonNullByDefault
+public class SourceMessageUtil {
+
+
+ private static final int FULL_TEXT_LIMIT= 100;
+ private static final int START_TEXT_LIMIT= 25;
+
+
+ private final StringBuilder tmpBuilder= new StringBuilder();
+
+ private SourceContent sourceContent= nonNullLateInit();
+
+
+ public SourceMessageUtil(final SourceContent sourceContent) {
+ setSourceContent(sourceContent);
+ }
+
+ public SourceMessageUtil() {
+ }
+
+
+ public void setSourceContent(final SourceContent sourceContent) {
+ this.sourceContent= nonNullAssert(sourceContent);
+ }
+
+
+ protected final StringBuilder getStringBuilder() {
+ this.tmpBuilder.setLength(0);
+ return this.tmpBuilder;
+ }
+
+ public String getFullText(final AstNode node) throws BadLocationException {
+ final String text= node.getText();
+ if (text != null) {
+ if (text.length() > FULL_TEXT_LIMIT) {
+ final StringBuilder sb= getStringBuilder();
+ sb.append(text, 0, FULL_TEXT_LIMIT);
+ sb.append('…');
+ return sb.toString();
+ }
+ else {
+ return text;
+ }
+ }
+ else {
+ if (node.getLength() > FULL_TEXT_LIMIT) {
+ final StringBuilder sb= getStringBuilder();
+ this.sourceContent.appendStringTo(sb,
+ node.getStartOffset(),
+ node.getStartOffset() + FULL_TEXT_LIMIT );
+ sb.append('…');
+ return sb.toString();
+ }
+ else {
+ return this.sourceContent.getString(
+ node.getStartOffset(),
+ node.getEndOffset() );
+ }
+ }
+ }
+
+ public String getStartText(final AstNode node, final int offset)
+ throws BadLocationException {
+ final String text= node.getText();
+ if (text != null) {
+ if (text.length() > START_TEXT_LIMIT) {
+ final StringBuilder sb= getStringBuilder();
+ sb.append(text, 0, START_TEXT_LIMIT);
+ sb.append('…');
+ return sb.toString();
+ }
+ else {
+ return text;
+ }
+ }
+ else {
+ if (node.getLength() - offset > START_TEXT_LIMIT) {
+ final StringBuilder sb= getStringBuilder();
+ this.sourceContent.appendStringTo(sb,
+ node.getStartOffset() + offset,
+ node.getStartOffset() + offset + START_TEXT_LIMIT );
+ sb.append('…');
+ return sb.toString();
+ }
+ else {
+ return this.sourceContent.getString(
+ node.getStartOffset() + offset,
+ node.getEndOffset() );
+ }
+ }
+ }
+
+ public String getDetailText(final AstNode node, final int offset, final StatusDetail detail)
+ throws BadLocationException {
+ final String text= node.getText();
+ if (text != null) {
+ final int begin= detail.getStartOffset() - node.getStartOffset() - offset;
+ return text.substring(begin, begin + detail.getLength());
+ }
+ else {
+ return this.sourceContent.getString(
+ detail.getStartOffset(),
+ detail.getEndOffset() );
+ }
+ }
+
+}