Skip to content

Commit

Permalink
Consumer Format
Browse files Browse the repository at this point in the history
- Add new consumer format properties for event key and value.
- Add XML format.
- Minor bug fixes.
  • Loading branch information
kumait committed Sep 18, 2022
1 parent f565b8a commit 9eebebe
Show file tree
Hide file tree
Showing 11 changed files with 184 additions and 81 deletions.
33 changes: 32 additions & 1 deletion src/main/java/kafkavisualizer/Utils.java
Original file line number Diff line number Diff line change
@@ -1,10 +1,20 @@
package kafkavisualizer;

import com.google.gson.GsonBuilder;
import org.xml.sax.InputSource;

import javax.swing.*;
import javax.xml.XMLConstants;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import java.awt.*;
import java.io.IOException;
import java.io.StringReader;
import java.io.StringWriter;
import java.util.Locale;
import java.util.Objects;

public class Utils {
Expand Down Expand Up @@ -39,7 +49,7 @@ public static Font getMonoFont() {

public static String beautifyJSON(String json) {
var prettyJSON = json;
var gson = new GsonBuilder().setPrettyPrinting().disableHtmlEscaping().create();
var gson = new GsonBuilder().setPrettyPrinting().disableHtmlEscaping().serializeNulls().create();
try {
var o = gson.fromJson(json, Object.class);
prettyJSON = gson.toJson(o);
Expand All @@ -48,4 +58,25 @@ public static String beautifyJSON(String json) {
}
return prettyJSON;
}

public static String beautifyXML(String xml) {
var prettyXML = xml;
try {
var document = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(new InputSource(new StringReader(xml)));
var transformerFactory = TransformerFactory.newInstance();
transformerFactory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true);
transformerFactory.setAttribute(XMLConstants.ACCESS_EXTERNAL_DTD, "");
transformerFactory.setAttribute(XMLConstants.ACCESS_EXTERNAL_STYLESHEET, "");
var transformer = transformerFactory.newTransformer();
var hasDeclaration = xml.trim().toLowerCase(Locale.ROOT).startsWith("<?xml");
transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, hasDeclaration ? "no": "yes");
transformer.setOutputProperty(OutputKeys.INDENT, "yes");
var writer = new StringWriter();
transformer.transform(new DOMSource(document), new StreamResult(writer));
prettyXML = writer.toString();
} catch (Exception ex) {
// do nothing
}
return prettyXML;
}
}
2 changes: 1 addition & 1 deletion src/main/java/kafkavisualizer/app/actions/AboutAction.java
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ public AboutAction() {

@Override
public void actionPerformed(ActionEvent e) {
var message = "Kafka Visualizer 1.0\n" +
var message = "Kafka Visualizer 1.1.0\n" +
"https://github.com/kumait/kafkavisualizer\n\n" +
"This software includes icons from IntelliJ IDEA Community Edition\n" +
"Copyright (C) JetBrains s.r.o.\n" +
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -130,8 +130,8 @@ public void keyTyped(KeyEvent e) {
pane.getConsumerEventPane().getValueTextArea().setWrapStyleWord(selected);
});

pane.getConsumerEventPane().getValueTextAreaFormatJSONCheckBox().addActionListener(e -> updateConsumerPane());
pane.getConsumerEventPane().getKeyTextAreaFormatJSONCheckBox().addActionListener(e -> updateConsumerPane());
pane.getConsumerEventPane().getValueTextAreaFormatCheckBox().addActionListener(e -> updateConsumerPane());
pane.getConsumerEventPane().getKeyTextAreaFormatCheckBox().addActionListener(e -> updateConsumerPane());

pane.getConsumerEventPane().getKeyTextAreaWordWrapCheckBox().addActionListener(e -> {
var selected = pane.getConsumerEventPane().getKeyTextAreaWordWrapCheckBox().isSelected();
Expand All @@ -148,16 +148,42 @@ public void updateConsumerPane() {
var selectedRow = pane.getTable().getSelectedRow();
var record = consumerTableModel.getSelectedRecord(selectedRow);

var formatValueJSON = pane.getConsumerEventPane().getValueTextAreaFormatJSONCheckBox().isSelected();
var value = formatValueJSON ? Utils.beautifyJSON(record.value()) : record.value();
String value = record.value();
if (pane.getConsumerEventPane().getValueTextAreaFormatCheckBox().isSelected()) {
switch (consumer.getValueFormat()) {
case JSON:
value = Utils.beautifyJSON(value);
break;
case XML:
value = Utils.beautifyXML(value);
break;
case PLAIN_TEXT:
default:
break;
}
}
pane.getConsumerEventPane().getValueTextArea().setText(value);

var formatKeyJSON = pane.getConsumerEventPane().getKeyTextAreaFormatJSONCheckBox().isSelected();
var key = formatKeyJSON ? Utils.beautifyJSON(record.key()) : record.key();
pane.getConsumerEventPane().getValueTextArea().setCaretPosition(0);

var key = record.key();
if (pane.getConsumerEventPane().getKeyTextAreaFormatCheckBox().isSelected()) {
switch (consumer.getKeyFormat()) {
case JSON:
key = Utils.beautifyJSON(key);
break;
case XML:
key = Utils.beautifyXML(key);
break;
case PLAIN_TEXT:
default:
break;
}
}
pane.getConsumerEventPane().getKeyTextArea().setText(key);
pane.getConsumerEventPane().getKeyTextArea().setCaretPosition(0);

headersTableModel.getHeaders().clear();
for (var header: record.headers()) {
for (var header : record.headers()) {
var v = header.value() == null ? null : new String(header.value(), StandardCharsets.UTF_8);
headersTableModel.getHeaders().add(new HeaderRow(header.key(), v));
}
Expand All @@ -181,7 +207,7 @@ public void start() {
if (selectedRow != -1) {
selectedRecord = consumerTableModel.getSelectedRecordIndex(selectedRow);
}
for (var record: records) {
for (var record : records) {
consumerTableModel.addRecord(record);
}
consumerTableModel.fireTableDataChanged();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,21 +12,21 @@ public class ConsumerEventPane extends JPanel {
private final JPanel headersPane;
private final JTextArea valueTextArea;
private final JCheckBox valueTextAreaWordWrapCheckBox;
private final JCheckBox valueTextAreaFormatJSONCheckBox;
private final JCheckBox valueTextAreaFormatCheckBox;
private final JTextArea keyTextArea;
private final JCheckBox keyTextAreaWordWrapCheckBox;
private final JCheckBox keyTextAreaFormatJSONCheckBox;
private final JCheckBox keyTextAreaFormatCheckBox;
private final JTable headersTable;

public ConsumerEventPane() {
valuePane = new JPanel();
valuePane.setLayout(new BorderLayout());
var valueToolbar = new JToolBar();
valueTextAreaWordWrapCheckBox = new JCheckBox("Word Wrap");
valueTextAreaFormatJSONCheckBox = new JCheckBox("Format JSON");
valueTextAreaFormatCheckBox = new JCheckBox("Format");
valueToolbar.setBorder(new EmptyBorder(8, 0, 8, 0));
valueToolbar.add(valueTextAreaWordWrapCheckBox);
valueToolbar.add(valueTextAreaFormatJSONCheckBox);
valueToolbar.add(valueTextAreaFormatCheckBox);
valuePane.add(valueToolbar, BorderLayout.NORTH);
valueTextArea = new JTextArea();
valueTextArea.setLineWrap(false);
Expand All @@ -38,10 +38,10 @@ public ConsumerEventPane() {
keyPane.setLayout(new BorderLayout());
var keyToolbar = new JToolBar();
keyTextAreaWordWrapCheckBox = new JCheckBox("Word Wrap");
keyTextAreaFormatJSONCheckBox = new JCheckBox("Format JSON");
keyTextAreaFormatCheckBox = new JCheckBox("Format");
keyToolbar.setBorder(new EmptyBorder(8, 0, 8, 0));
keyToolbar.add(keyTextAreaWordWrapCheckBox);
keyToolbar.add(keyTextAreaFormatJSONCheckBox);
keyToolbar.add(keyTextAreaFormatCheckBox);
keyPane.add(keyToolbar, BorderLayout.NORTH);
keyTextArea = new JTextArea();
keyTextArea.setLineWrap(false);
Expand Down Expand Up @@ -93,15 +93,15 @@ public JCheckBox getValueTextAreaWordWrapCheckBox() {
return valueTextAreaWordWrapCheckBox;
}

public JCheckBox getValueTextAreaFormatJSONCheckBox() {
return valueTextAreaFormatJSONCheckBox;
public JCheckBox getValueTextAreaFormatCheckBox() {
return valueTextAreaFormatCheckBox;
}

public JCheckBox getKeyTextAreaWordWrapCheckBox() {
return keyTextAreaWordWrapCheckBox;
}

public JCheckBox getKeyTextAreaFormatJSONCheckBox() {
return keyTextAreaFormatJSONCheckBox;
public JCheckBox getKeyTextAreaFormatCheckBox() {
return keyTextAreaFormatCheckBox;
}
}
41 changes: 0 additions & 41 deletions src/main/java/kafkavisualizer/mainframe/MainFrame.java

This file was deleted.

22 changes: 21 additions & 1 deletion src/main/java/kafkavisualizer/models/Consumer.java
Original file line number Diff line number Diff line change
Expand Up @@ -29,13 +29,17 @@ public String toString() {
private String name;
private List<String> topics;
private StartFrom startFrom;
private Format valueFormat;
private Format keyFormat;

public Consumer(String name, List<String> topics, StartFrom startFrom) {
public Consumer(String name, List<String> topics, StartFrom startFrom, Format valueFormat, Format keyFormat) {
Objects.requireNonNull(topics);
this.id = UUID.randomUUID().toString();
this.name = name;
this.topics = topics;
this.startFrom = startFrom;
this.valueFormat = valueFormat;
this.keyFormat = keyFormat;
}

public String getId() {
Expand Down Expand Up @@ -66,6 +70,22 @@ public void setStartFrom(StartFrom startFrom) {
this.startFrom = startFrom;
}

public Format getKeyFormat() {
return keyFormat;
}

public void setKeyFormat(Format keyFormat) {
this.keyFormat = keyFormat;
}

public void setValueFormat(Format valueFormat) {
this.valueFormat = valueFormat;
}

public Format getValueFormat() {
return valueFormat;
}

@Override
public String toString() {
if (name != null && name.trim().length() > 0) {
Expand Down
18 changes: 18 additions & 0 deletions src/main/java/kafkavisualizer/models/Format.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package kafkavisualizer.models;

public enum Format {
PLAIN_TEXT("Plain Text"),
JSON("JSON"),
XML("XML");

private final String stringValue;

Format(String stringValue) {
this.stringValue = stringValue;
}

@Override
public String toString() {
return stringValue;
}
}
19 changes: 19 additions & 0 deletions src/main/java/kafkavisualizer/navigator/ConsumerPane.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package kafkavisualizer.navigator;

import kafkavisualizer.models.Consumer;
import kafkavisualizer.models.Format;
import net.miginfocom.swing.MigLayout;

import javax.swing.*;
Expand All @@ -9,6 +10,8 @@ public class ConsumerPane extends JPanel {
private final JTextField nameTextField;
private final JComboBox<String> topicComboBox;
private final JComboBox<Consumer.StartFrom> startFromComboBox;
private final JComboBox<Format> keyFormatComboBox;
private final JComboBox<Format> valueFormatComboBox;

public ConsumerPane() {
var layout = new MigLayout(
Expand All @@ -29,6 +32,14 @@ public ConsumerPane() {
add(new JLabel("Start From"));
startFromComboBox = new JComboBox<>();
add(startFromComboBox);

add(new JLabel("Value Format"));
valueFormatComboBox = new JComboBox<>();
add(valueFormatComboBox);

add(new JLabel("Key Format"));
keyFormatComboBox = new JComboBox<>();
add(keyFormatComboBox);
}

public JTextField getNameTextField() {
Expand All @@ -42,4 +53,12 @@ public JComboBox<String> getTopicComboBox() {
public JComboBox<Consumer.StartFrom> getStartFromComboBox() {
return startFromComboBox;
}

public JComboBox<Format> getKeyFormatComboBox() {
return keyFormatComboBox;
}

public JComboBox<Format> getValueFormatComboBox() {
return valueFormatComboBox;
}
}
Loading

0 comments on commit 9eebebe

Please sign in to comment.