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);
}
}