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

hansva pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/hop.git


The following commit(s) were added to refs/heads/main by this push:
     new a61ce273fb Issue #7935 : Add pretty-print JSON button to Content 
Editor toolbar (#7937)
a61ce273fb is described below

commit a61ce273fbd97ea9b9b46da1407fd1cbd1a04b3d
Author: Matt Casters <[email protected]>
AuthorDate: Thu Aug 13 15:51:16 2026 +0200

    Issue #7935 : Add pretty-print JSON button to Content Editor toolbar (#7937)
    
    Reuse TextCompositeToolbarJsonFormatButton to contribute the same format
    action to IContentEditorWidget toolbars (explorer JSON files), filtered
    by language == json.
---
 .../ui/TextCompositeToolbarJsonFormatButton.java   | 115 ++++++++++++++++++---
 1 file changed, 98 insertions(+), 17 deletions(-)

diff --git 
a/plugins/transforms/json/src/main/java/org/apache/hop/pipeline/transforms/ui/TextCompositeToolbarJsonFormatButton.java
 
b/plugins/transforms/json/src/main/java/org/apache/hop/pipeline/transforms/ui/TextCompositeToolbarJsonFormatButton.java
index 9ec5262fc1..498dc7ca76 100644
--- 
a/plugins/transforms/json/src/main/java/org/apache/hop/pipeline/transforms/ui/TextCompositeToolbarJsonFormatButton.java
+++ 
b/plugins/transforms/json/src/main/java/org/apache/hop/pipeline/transforms/ui/TextCompositeToolbarJsonFormatButton.java
@@ -28,17 +28,29 @@ import org.apache.hop.core.json.HopJson;
 import org.apache.hop.i18n.BaseMessages;
 import org.apache.hop.ui.core.dialog.ErrorDialog;
 import org.apache.hop.ui.core.widget.TextComposite;
+import org.apache.hop.ui.core.widget.editor.IContentEditorWidget;
+import org.eclipse.swt.widgets.Control;
 import org.eclipse.swt.widgets.Shell;
 
 /**
- * Sample TextComposite toolbar contribution: pretty-print JSON when the 
editor's {@link
- * TextComposite#getStyleType()} is {@link TextComposite#STYLE_TYPE_JSON}.
+ * Pretty-print JSON for:
+ *
+ * <ul>
+ *   <li>{@link TextComposite} toolbars when {@link 
TextComposite#getStyleType()} is {@link
+ *       TextComposite#STYLE_TYPE_JSON}
+ *   <li>Content editor toolbars ({@link 
IContentEditorWidget#GUI_PLUGIN_TOOLBAR_PARENT_ID}) when
+ *       {@link IContentEditorWidget#getLanguage()} is {@code json} (e.g. 
explorer JSON files)
+ * </ul>
  */
 @GuiPlugin
 public class TextCompositeToolbarJsonFormatButton {
   private static final Class<?> PKG = 
TextCompositeToolbarJsonFormatButton.class;
 
   private static final String ID_TOOLBAR_FORMAT_JSON = 
"textcomposite-toolbar-20010-format-json";
+  private static final String ID_CONTENT_EDITOR_FORMAT_JSON =
+      "ContentEditor-Toolbar-40000-format-json";
+
+  private static final String LANGUAGE_JSON = "json";
 
   /**
    * Only show this toolbar button when the content is JSON. Other toolbar 
item IDs always return
@@ -67,6 +79,25 @@ public class TextCompositeToolbarJsonFormatButton {
     return 
TextComposite.STYLE_TYPE_JSON.equalsIgnoreCase(textComposite.getStyleType());
   }
 
+  /**
+   * Only show the Content Editor format button when the editor language is 
JSON. Other toolbar item
+   * IDs always return {@code true} so built-in buttons are not hidden.
+   *
+   * @param buttonId the toolbar button id being evaluated
+   * @param guiPluginInstance the registered content editor instance
+   * @return whether the button should be shown
+   */
+  @GuiToolbarElementFilter(parentId = 
IContentEditorWidget.GUI_PLUGIN_TOOLBAR_PARENT_ID)
+  public static boolean isContentEditorButtonShown(String buttonId, Object 
guiPluginInstance) {
+    if (!ID_CONTENT_EDITOR_FORMAT_JSON.equals(buttonId)) {
+      return true;
+    }
+    if (!(guiPluginInstance instanceof IContentEditorWidget editor)) {
+      return false;
+    }
+    return LANGUAGE_JSON.equalsIgnoreCase(editor.getLanguage());
+  }
+
   @GuiToolbarElement(
       root = TextComposite.ID_TOOLBAR,
       id = ID_TOOLBAR_FORMAT_JSON,
@@ -86,16 +117,8 @@ public class TextCompositeToolbarJsonFormatButton {
     }
 
     try {
-      ObjectMapper mapper = HopJson.newMapper();
-      JsonNode tree = mapper.readTree(json);
-      String formatted = 
mapper.writerWithDefaultPrettyPrinter().writeValueAsString(tree);
-
-      // Jackson may leave a trailing newline; normalize so compare is stable
-      if (formatted.endsWith("\n") && !json.endsWith("\n")) {
-        formatted = formatted.substring(0, formatted.length() - 1);
-      }
-
-      if (formatted.equals(json)) {
+      String formatted = prettyPrintJson(json);
+      if (formatted == null || formatted.equals(json)) {
         return;
       }
 
@@ -105,11 +128,69 @@ public class TextCompositeToolbarJsonFormatButton {
       textComposite.setCaretPosition(0);
       textComposite.updateToolbar();
     } catch (Exception e) {
-      new ErrorDialog(
-          shell,
-          BaseMessages.getString(PKG, 
"TextCompositeToolbarJsonFormatButton.Error.Title"),
-          BaseMessages.getString(PKG, 
"TextCompositeToolbarJsonFormatButton.Error.Message"),
-          e);
+      showFormatError(shell, e);
+    }
+  }
+
+  @GuiToolbarElement(
+      root = IContentEditorWidget.GUI_PLUGIN_TOOLBAR_PARENT_ID,
+      id = ID_CONTENT_EDITOR_FORMAT_JSON,
+      toolTip = 
"i18n::TextCompositeToolbarJsonFormatButton.FormatJson.ToolTip",
+      separator = true,
+      image = "json-input.svg")
+  public static void formatJson(IContentEditorWidget editor) {
+    if (editor == null) {
+      return;
     }
+    Control control = editor.getControl();
+    if (control == null || control.isDisposed()) {
+      return;
+    }
+
+    Shell shell = control.getShell();
+    String json = editor.getText();
+    if (StringUtils.isBlank(json)) {
+      return;
+    }
+
+    try {
+      String formatted = prettyPrintJson(json);
+      if (formatted == null || formatted.equals(json)) {
+        return;
+      }
+      editor.setText(formatted);
+    } catch (Exception e) {
+      showFormatError(shell, e);
+    }
+  }
+
+  /**
+   * Pretty-print JSON text. Returns the formatted string, or {@code null} if 
input is blank.
+   *
+   * @param json raw JSON
+   * @return pretty-printed JSON (trailing newline normalized to match input 
when absent)
+   * @throws Exception if the text is not valid JSON
+   */
+  private static String prettyPrintJson(String json) throws Exception {
+    if (StringUtils.isBlank(json)) {
+      return null;
+    }
+    ObjectMapper mapper = HopJson.newMapper();
+    JsonNode tree = mapper.readTree(json);
+    String formatted = 
mapper.writerWithDefaultPrettyPrinter().writeValueAsString(tree);
+
+    // Jackson may leave a trailing newline; normalize so compare is stable
+    if (formatted.endsWith("\n") && !json.endsWith("\n")) {
+      formatted = formatted.substring(0, formatted.length() - 1);
+    }
+    return formatted;
+  }
+
+  private static void showFormatError(Shell shell, Exception e) {
+    new ErrorDialog(
+        shell,
+        BaseMessages.getString(PKG, 
"TextCompositeToolbarJsonFormatButton.Error.Title"),
+        BaseMessages.getString(PKG, 
"TextCompositeToolbarJsonFormatButton.Error.Message"),
+        e);
   }
 }

Reply via email to