Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

OakRun Explorer GUI improvements #1867

Open
wants to merge 2 commits into
base: trunk
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions oak-run/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -399,6 +399,17 @@
<artifactId>joda-time</artifactId>
<version>2.8.1</version>
</dependency>
<dependency>
<groupId>com.formdev</groupId>
<artifactId>flatlaf</artifactId>
<version>3.5.2</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>com.j2html</groupId>
<artifactId>j2html</artifactId>
<version>1.6.0</version>
</dependency>

<!-- RDB support -->
<dependency>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
package org.apache.jackrabbit.oak.explorer;

import org.apache.jackrabbit.oak.spi.state.NodeState;

import static org.apache.jackrabbit.oak.commons.PathUtils.elements;
import static org.apache.jackrabbit.oak.commons.json.JsopBuilder.prettyPrint;
import static org.apache.jackrabbit.oak.json.JsopDiff.diffToJsop;

class DiffReport {

private DiffReport() {
}

static String createPlainTextReport(String input, ExplorerBackend backend) {
StringBuilder sb = new StringBuilder();
if (input == null || input.trim().isEmpty()) {
return "Usage <recordId> <recordId> [<path>]";
}

String[] tokens = input.trim().split(" ");
if (tokens.length != 2 && tokens.length != 3) {
return "Usage <recordId> <recordId> [<path>]";
}
NodeState node1;
NodeState node2;
try {
node1 = backend.readNodeState(tokens[0]);
node2 = backend.readNodeState(tokens[1]);
} catch (IllegalArgumentException ex) {
sb.append("Unknown argument: ");
sb.append(input);
sb.append(ReportUtils.newline);
sb.append("Error: ");
sb.append(ex.getMessage());
sb.append(ReportUtils.newline);
return sb.toString();
}
String path = "/";
if (tokens.length == 3) {
path = tokens[2];
}

for (String name : elements(path)) {
node1 = node1.getChildNode(name);
node2 = node2.getChildNode(name);
}

sb.append("SegmentNodeState diff ");
sb.append(tokens[0]);
sb.append(" vs ");
sb.append(tokens[1]);
sb.append(" at ");
sb.append(path);
sb.append(ReportUtils.newline);
sb.append("--------");
sb.append(ReportUtils.newline);
sb.append(prettyPrint(diffToJsop(node1, node2)));
return sb.toString();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@
import org.apache.commons.io.IOUtils;

import javax.swing.*;
import javax.swing.UIManager.LookAndFeelInfo;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
Expand All @@ -41,15 +40,9 @@ public class Explorer {

private static void initLF() {
try {
for (LookAndFeelInfo info : UIManager.getInstalledLookAndFeels()) {
if ("Nimbus".equals(info.getName())) {
UIManager.setLookAndFeel(info.getClassName());
break;
}
}
} catch (Exception e) {
// If Nimbus is not available, you can set the GUI to another look
// and feel.
UIManager.setLookAndFeel("com.formdev.flatlaf.FlatLightLaf");
} catch (Exception ex) {
System.err.println("Failed to initialize LaF");
}
}

Expand Down Expand Up @@ -93,12 +86,9 @@ public void run() {
}

private void createAndShowGUI(final String path, boolean skipSizeCheck) throws IOException {
JTextArea log = new JTextArea(5, 20);
log.setMargin(new Insets(5, 5, 5, 5));
log.setLineWrap(true);
log.setEditable(false);

final NodeStoreTree treePanel = new NodeStoreTree(backend, log, skipSizeCheck);
final LogPanel logPanel = new LogPanel();
final NodeStoreTree treePanel = new NodeStoreTree(backend, logPanel, skipSizeCheck);
logPanel.addTarSelectedListener(treePanel::printTarInfo);

final JFrame frame = new JFrame("Explore " + path + " @head");
frame.addWindowListener(new java.awt.event.WindowAdapter() {
Expand All @@ -109,18 +99,13 @@ public void windowClosing(java.awt.event.WindowEvent windowEvent) {
}
});

JPanel content = new JPanel(new GridBagLayout());
treePanel.getComponent().setBorder(BorderFactory.createEmptyBorder(20, 20, 20, 10));
logPanel.getComponent().setBorder(BorderFactory.createEmptyBorder(20, 10, 20, 20));

GridBagConstraints c = new GridBagConstraints();
c.fill = GridBagConstraints.BOTH;
c.weightx = 1;
c.weighty = 1;

JSplitPane splitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT,
new JScrollPane(treePanel), new JScrollPane(log));
JSplitPane splitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, treePanel.getComponent(), logPanel.getComponent());
splitPane.setDividerLocation(0.3);
content.add(new JScrollPane(splitPane), c);
frame.getContentPane().add(content);

frame.getContentPane().add(splitPane);

JMenuBar menuBar = new JMenuBar();
menuBar.setMargin(new Insets(2, 2, 2, 2));
Expand Down
109 changes: 109 additions & 0 deletions oak-run/src/main/java/org/apache/jackrabbit/oak/explorer/LogPanel.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
package org.apache.jackrabbit.oak.explorer;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.swing.*;
import javax.swing.event.HyperlinkEvent;
import javax.swing.text.BadLocationException;
import javax.swing.text.DefaultHighlighter;
import javax.swing.text.Document;
import javax.swing.text.Highlighter;
import java.awt.*;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

class LogPanel {

private static final Logger LOG = LoggerFactory.getLogger(LogPanel.class);

private final JTextPane textPane = new JTextPane();
private final List<LogPanelListener> listeners = new ArrayList<>();

private JPanel panel;
private String searchKeyword = "";

public void addTarSelectedListener(LogPanelListener listener) {
listeners.add(listener);
}

public void setHtmlContent(String text) {
textPane.setContentType("text/html");
textPane.setText(text);
setHighlightOnTextPane();
textPane.setCaretPosition(0);
}

public void setPlainContent(String text) {
textPane.setContentType("text/plain");
textPane.setText(text);
setHighlightOnTextPane();
textPane.setCaretPosition(0);
}

public JComponent getComponent() {
if (panel == null) {
createPanel();
}
return panel;
}

private void createPanel() {
panel = new JPanel(new BorderLayout());
panel.add(new JScrollPane(textPane), BorderLayout.CENTER);

textPane.addHyperlinkListener(e -> {
if (e.getEventType() == HyperlinkEvent.EventType.ACTIVATED) {
onHyperLinkClickEvent(e);
}
});

SearchPanel searchPanel = new SearchPanel();
searchPanel.addSearchListener(this::onSearchKeywordChanged);

panel.add(searchPanel.getComponent(), BorderLayout.SOUTH);
textPane.setMargin(new Insets(5, 5, 5, 5));
textPane.setEditable(false);
}

private void onHyperLinkClickEvent(HyperlinkEvent e) {
try {
if (e.getDescription().startsWith("tar://")) {
String fileName = e.getDescription().replace("tar://", "");
listeners.forEach(logPanelListener -> logPanelListener.onTarFileClicked(fileName));
}
} catch (Exception ex) {
LOG.warn("Unable to open tar file", ex);
}
}

private void onSearchKeywordChanged(String searchKeyword) {
this.searchKeyword = searchKeyword;
setHighlightOnTextPane();
}

private void setHighlightOnTextPane() {
Highlighter highlighter = textPane.getHighlighter();
highlighter.removeAllHighlights();
Document document = textPane.getDocument();

try {
String renderedText = document.getText(0, document.getLength());
if (searchKeyword != null && !searchKeyword.isEmpty()) {
Pattern pattern = Pattern.compile(Pattern.quote(searchKeyword), Pattern.CASE_INSENSITIVE);
Matcher matcher = pattern.matcher(renderedText);
while (matcher.find()) {
highlighter.addHighlight(matcher.start(), matcher.end(), DefaultHighlighter.DefaultPainter);
}
}
} catch (BadLocationException e) {
LOG.warn("Unable to highlight text", e);
}
}

interface LogPanelListener {
void onTarFileClicked(String tarFileName);
}
}
Loading