View Issue Details
ID | Project | Category | View Status | Date Submitted | Last Update |
---|---|---|---|---|---|
0000017 | KafkaEsque | Improvement | public | 2018-12-14 08:26 | 2018-12-16 12:23 |
Reporter | Emin | Assigned To | patschuh | ||
Priority | normal | Severity | feature | Reproducibility | N/A |
Status | resolved | Resolution | fixed | ||
Product Version | 0.12.0 | ||||
Target Version | Fixed in Version | ||||
Summary | 0000017: Json Tree View Patch | ||||
Description | Patch for Json Tree View when using Format as Json. Needs work to deal with nested ArrayLists/Maps and to clean up unsafe casts. | ||||
Tags | No tags attached. | ||||
jsontree.patch (4,129 bytes)
Index: src/main/java/com/modulo/kafkaesque/Controller.java IDEA additional info: Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP <+>UTF-8 =================================================================== --- src/main/java/com/modulo/kafkaesque/Controller.java (revision dbc9c10b8a607e7ff939f603db97dae122bcc29b) +++ src/main/java/com/modulo/kafkaesque/Controller.java (date 1544743259000) @@ -1,6 +1,7 @@ package com.modulo.kafkaesque; import com.fasterxml.jackson.core.type.TypeReference; +import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.dataformat.yaml.YAMLMapper; import com.google.inject.Inject; @@ -99,6 +100,8 @@ private TextArea keyTextArea; @FXML private TextArea valueTextArea; + @FXML + public TreeView<String> jsonTreeView; @FXML private TableView<Header> headerTableView; @FXML @@ -252,12 +255,48 @@ if (formatJson) { keyTextArea.setText(formatJson(selectedMessage.getKey())); valueTextArea.setText(formatJson(selectedMessage.getValue())); + try { + Map<String, Object> json = objectMapper.readValue(selectedMessage.getValue(), Map.class); + TreeItem<String> root = new TreeItem<>("root"); + recursivelyAddElements(json, root); + jsonTreeView.setRoot(root); + } catch (IOException e) { + e.printStackTrace(); + } } else { keyTextArea.setText(selectedMessage.getKey()); valueTextArea.setText(selectedMessage.getValue()); } } + private void recursivelyAddElements(Map<String, Object> jsonNode, TreeItem<String> treeItem) { + Set<Map.Entry<String, Object>> entries = jsonNode.entrySet(); + + if (!entries.isEmpty()) { + for (Map.Entry<String, Object> entry : entries) { + TreeItem<String> newItem = new TreeItem<>(entry.getKey()); + treeItem.getChildren().add(newItem); + if (entry.getValue() instanceof String) { + recursivelyAddElements((String) entry.getValue(), newItem); + } else if (entry.getValue() instanceof ArrayList) { + recursivelyAddElements((ArrayList) entry.getValue(), newItem); + } else { + recursivelyAddElements((Map<String, Object>) entry.getValue(), newItem); + } + } + } + } + + private void recursivelyAddElements(ArrayList values, TreeItem<String> treeItem) { + for (Object val : values){ + treeItem.getChildren().add(new TreeItem<>((String) val)); + } + } + + private void recursivelyAddElements(String string, TreeItem<String> treeItem) { + treeItem.getChildren().add(new TreeItem<>(string)); + } + /* TODO can be extracted to a JsonUtil */ private String formatJson(String string) { try { Index: src/main/resources/fxml/mainScene.fxml IDEA additional info: Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP <+>UTF-8 =================================================================== --- src/main/resources/fxml/mainScene.fxml (revision dbc9c10b8a607e7ff939f603db97dae122bcc29b) +++ src/main/resources/fxml/mainScene.fxml (date 1544743450000) @@ -223,7 +223,11 @@ </Tab> <Tab text="Value"> <content> - <TextArea fx:id="valueTextArea" editable="false" prefHeight="200.0" prefWidth="200.0"/> + <HBox> + <TreeView fx:id="jsonTreeView" editable="false" prefHeight="200.0"/> + <TextArea fx:id="valueTextArea" editable="false" prefHeight="200.0" + prefWidth="200.0" HBox.hgrow="ALWAYS"/> + </HBox> </content> </Tab> <Tab text="Header"> |
|
New Patch with infinitely recursive search and support for non-string types
jsontree-new.patch (4,432 bytes)
Index: src/main/resources/fxml/mainScene.fxml IDEA additional info: Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP <+>UTF-8 =================================================================== --- src/main/resources/fxml/mainScene.fxml (revision dbc9c10b8a607e7ff939f603db97dae122bcc29b) +++ src/main/resources/fxml/mainScene.fxml (date 1544774332456) @@ -223,7 +223,11 @@ </Tab> <Tab text="Value"> <content> - <TextArea fx:id="valueTextArea" editable="false" prefHeight="200.0" prefWidth="200.0"/> + <HBox> + <TreeView fx:id="jsonTreeView" editable="false" prefHeight="200.0"/> + <TextArea fx:id="valueTextArea" editable="false" prefHeight="200.0" + prefWidth="200.0" HBox.hgrow="ALWAYS"/> + </HBox> </content> </Tab> <Tab text="Header"> Index: src/main/java/com/modulo/kafkaesque/Controller.java IDEA additional info: Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP <+>UTF-8 =================================================================== --- src/main/java/com/modulo/kafkaesque/Controller.java (revision dbc9c10b8a607e7ff939f603db97dae122bcc29b) +++ src/main/java/com/modulo/kafkaesque/Controller.java (date 1544785811155) @@ -100,6 +100,8 @@ @FXML private TextArea valueTextArea; @FXML + public TreeView<String> jsonTreeView; + @FXML private TableView<Header> headerTableView; @FXML private TableColumn<Header, String> headerKeyColumn; @@ -252,12 +254,57 @@ if (formatJson) { keyTextArea.setText(formatJson(selectedMessage.getKey())); valueTextArea.setText(formatJson(selectedMessage.getValue())); + try { + Map<String, Object> json = objectMapper.readValue(selectedMessage.getValue(), Map.class); + TreeItem<String> root = new TreeItem<>("root"); + recursivelyAddElements(json, root); + jsonTreeView.setRoot(root); + } catch (IOException e) { + e.printStackTrace(); + } } else { keyTextArea.setText(selectedMessage.getKey()); valueTextArea.setText(selectedMessage.getValue()); } } + private void recursivelyAddElements(Map<String, Object> jsonNode, TreeItem<String> treeItem) { + Set<Map.Entry<String, Object>> entries = jsonNode.entrySet(); + + if (!entries.isEmpty()) { + for (Map.Entry<String, Object> entry : entries) { + TreeItem<String> newItem = new TreeItem<>(entry.getKey()); + treeItem.getChildren().add(newItem); + applyCorrectAdder(entry.getValue(), newItem); + } + } + } + + private void recursivelyAddElements(ArrayList values, TreeItem<String> treeItem) { + int i = 1; + for (Object val : values) { + TreeItem<String> newItem = new TreeItem<>(i + ""); + treeItem.getChildren().add(newItem); + applyCorrectAdder(val, newItem); + i++; + } + } + + private void recursivelyAddElements(String val, TreeItem<String> treeItem) { + treeItem.getChildren().add(new TreeItem<>(val)); + } + + private void applyCorrectAdder(Object value, TreeItem<String> treeItem) { + if (value instanceof Map) { + recursivelyAddElements((Map) value, treeItem); + }else if (value instanceof ArrayList) { + recursivelyAddElements((ArrayList) value, treeItem); + } else { + recursivelyAddElements((String.valueOf(value)), treeItem); + } + } + + /* TODO can be extracted to a JsonUtil */ private String formatJson(String string) { try { @@ -952,7 +999,7 @@ String identifier = matcher.group("identifier"); String type = matcher.group("type"); - Object replacement; + Serializable replacement; switch (type) { case "UUID": replacement = UUID.randomUUID(); |
|
Final Patch with code cleanup and auto expansion of lists and top level map
jsontree-final.patch (7,510 bytes)
Index: src/main/resources/fxml/mainScene.fxml IDEA additional info: Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP <+>UTF-8 =================================================================== --- src/main/resources/fxml/mainScene.fxml (revision dbc9c10b8a607e7ff939f603db97dae122bcc29b) +++ src/main/resources/fxml/mainScene.fxml (date 1544789099034) @@ -223,7 +223,11 @@ </Tab> <Tab text="Value"> <content> - <TextArea fx:id="valueTextArea" editable="false" prefHeight="200.0" prefWidth="200.0"/> + <HBox> + <TreeView fx:id="jsonTreeView" prefHeight="200.0" prefWidth="400.0"/> + <TextArea fx:id="valueTextArea" editable="false" prefHeight="200.0" + prefWidth="200.0" HBox.hgrow="ALWAYS"/> + </HBox> </content> </Tab> <Tab text="Header"> Index: src/main/java/com/modulo/kafkaesque/Controller.java IDEA additional info: Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP <+>UTF-8 =================================================================== --- src/main/java/com/modulo/kafkaesque/Controller.java (revision dbc9c10b8a607e7ff939f603db97dae122bcc29b) +++ src/main/java/com/modulo/kafkaesque/Controller.java (date 1544789994257) @@ -100,6 +100,8 @@ @FXML private TextArea valueTextArea; @FXML + public TreeView<String> jsonTreeView; + @FXML private TableView<Header> headerTableView; @FXML private TableColumn<Header, String> headerKeyColumn; @@ -250,24 +252,20 @@ } headerTableView.setItems(selectedMessage.getHeaders()); if (formatJson) { - keyTextArea.setText(formatJson(selectedMessage.getKey())); - valueTextArea.setText(formatJson(selectedMessage.getValue())); + keyTextArea.setText(JsonUtils.formatJson(selectedMessage.getKey())); + valueTextArea.setText(JsonUtils.formatJson(selectedMessage.getValue())); + try { + TreeItem<String> root = JsonUtils.buildTreeFromJson(selectedMessage.getValue()); + jsonTreeView.setRoot(root); + } catch (IOException e) { + e.printStackTrace(); + } } else { keyTextArea.setText(selectedMessage.getKey()); valueTextArea.setText(selectedMessage.getValue()); } } - /* TODO can be extracted to a JsonUtil */ - private String formatJson(String string) { - try { - Object jsonObject = string == null ? null : objectMapper.readValue(string, Object.class); - return objectMapper.writerWithDefaultPrettyPrinter().writeValueAsString(jsonObject); - } catch (Exception e) { - return String.format("%s%s[Formatting Error: %s]", string, System.lineSeparator(), e.getMessage()); - } - } - private void setupClusterCombobox() { ListCell<ClusterConfig> buttonCell = new ListCell<ClusterConfig>() { @Override @@ -952,7 +950,7 @@ String identifier = matcher.group("identifier"); String type = matcher.group("type"); - Object replacement; + Serializable replacement; switch (type) { case "UUID": replacement = UUID.randomUUID(); Index: src/main/java/com/modulo/kafkaesque/JsonUtils.java IDEA additional info: Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP <+>UTF-8 =================================================================== --- src/main/java/com/modulo/kafkaesque/JsonUtils.java (revision dbc9c10b8a607e7ff939f603db97dae122bcc29b) +++ src/main/java/com/modulo/kafkaesque/JsonUtils.java (date 1544789963178) @@ -1,24 +1,89 @@ package com.modulo.kafkaesque; +import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.databind.ObjectMapper; +import javafx.scene.control.TreeItem; import java.io.IOException; +import java.util.ArrayList; +import java.util.Map; +import java.util.Set; -public final class JsonUtils { +final class JsonUtils { private JsonUtils() { } - public static ValidationResult validate(String jsonInString) { + private static final ObjectMapper objectMapper; + + static { + objectMapper = new ObjectMapper(); + } + + static String formatJson(String string) { + try { + Object jsonObject = string == null ? null : objectMapper.readValue(string, Object.class); + return objectMapper.writerWithDefaultPrettyPrinter().writeValueAsString(jsonObject); + } catch (Exception e) { + return String.format("%s%s[Formatting Error: %s]", string, System.lineSeparator(), e.getMessage()); + } + } + + static ValidationResult validate(String jsonInString) { if (jsonInString == null) { return new ValidationResult(true); } try { - final ObjectMapper mapper = new ObjectMapper(); - mapper.readTree(jsonInString); + objectMapper.readTree(jsonInString); return new ValidationResult(true); } catch (IOException e) { return new ValidationResult(false, e.getMessage()); } } + + static TreeItem<String> buildTreeFromJson(String value) throws IOException { + Map<String, Object> json = objectMapper.readValue(value, new TypeReference<Map<String, Object>>() { + }); + TreeItem<String> root = new TreeItem<>("root"); + root.setExpanded(true); + recursivelyAddElements(json, root); + return root; + } + + private static void recursivelyAddElements(Map<String, Object> jsonNode, TreeItem<String> treeItem) { + Set<Map.Entry<String, Object>> entries = jsonNode.entrySet(); + + if (!entries.isEmpty()) { + for (Map.Entry<String, Object> entry : entries) { + TreeItem<String> newItem = new TreeItem<>(entry.getKey()); + treeItem.getChildren().add(newItem); + applyCorrectAdder(entry.getValue(), newItem); + } + } + } + + private static void recursivelyAddElements(ArrayList values, TreeItem<String> treeItem) { + int i = 1; + for (Object val : values) { + TreeItem<String> newItem = new TreeItem<>(i + ""); + treeItem.getChildren().add(newItem); + treeItem.setExpanded(true); + applyCorrectAdder(val, newItem); + i++; + } + } + + private static void recursivelyAddElements(String val, TreeItem<String> treeItem) { + treeItem.setValue(treeItem.getValue() + ": " + val); + } + + private static void applyCorrectAdder(Object value, TreeItem<String> treeItem) { + if (value instanceof Map) { + recursivelyAddElements((Map<String, Object>) value, treeItem); + } else if (value instanceof ArrayList) { + recursivelyAddElements((ArrayList) value, treeItem); + } else { + recursivelyAddElements((String.valueOf(value)), treeItem); + } + } } |
|
Implemented the JsonTreeView as its own control based on the patch |
|
Date Modified | Username | Field | Change |
---|---|---|---|
2018-12-14 08:26 | Emin | New Issue | |
2018-12-14 08:26 | Emin | File Added: jsontree.patch | |
2018-12-14 11:49 | Emin | File Added: jsontree-new.patch | |
2018-12-14 11:49 | Emin | Note Added: 0000018 | |
2018-12-14 12:21 | Emin | File Added: jsontree-final.patch | |
2018-12-14 12:21 | Emin | Note Added: 0000019 | |
2018-12-16 12:20 | patschuh | Changeset attached | => KafkaEsque master 0303f2f6 |
2018-12-16 12:23 | patschuh | Assigned To | => patschuh |
2018-12-16 12:23 | patschuh | Status | new => resolved |
2018-12-16 12:23 | patschuh | Resolution | open => fixed |
2018-12-16 12:23 | patschuh | Note Added: 0000020 |