Files
HaE/src/main/java/burp/ui/board/Databoard.java

338 lines
13 KiB
Java
Raw Normal View History

2023-10-12 21:38:27 +08:00
package burp.ui.board;
import burp.config.ConfigEntry;
import burp.core.utils.StringHelper;
import burp.ui.board.MessagePanel.Table;
2023-10-18 00:44:50 +08:00
import java.util.*;
2023-11-27 14:55:28 +08:00
import java.util.concurrent.ConcurrentHashMap;
import javax.swing.event.*;
2023-10-12 21:38:27 +08:00
import javax.swing.table.TableColumn;
import javax.swing.table.TableColumnModel;
import javax.swing.table.TableModel;
import javax.swing.table.TableRowSorter;
import java.awt.*;
import java.awt.event.*;
2023-10-18 00:44:50 +08:00
import java.util.List;
2023-10-12 21:38:27 +08:00
import javax.swing.*;
/**
* @author LinChen && EvilChen
*/
public class Databoard extends JPanel {
private static Boolean isMatchHost = false;
private JLabel hostLabel;
private JTextField hostTextField;
2023-11-07 11:15:20 +08:00
private JTabbedPane dataTabbedPane;
2023-10-12 21:38:27 +08:00
private JButton clearButton;
private JSplitPane splitPane;
private MessagePanel messagePanel;
private Table table;
2023-11-07 11:15:20 +08:00
private SwingWorker<Object, Void> currentWorker;
private DefaultComboBoxModel comboBoxModel = new DefaultComboBoxModel();
private JComboBox hostComboBox = new JComboBox(comboBoxModel);
private ChangeListener changeListenerInstance = new ChangeListener() {
@Override
public void stateChanged(ChangeEvent e) {
int selectedIndex = dataTabbedPane.getSelectedIndex();
String selectedTitle = "";
if (selectedIndex != -1) {
selectedTitle = dataTabbedPane.getTitleAt(selectedIndex);
}
applyHostFilter(selectedTitle);
}
};
2023-10-12 21:38:27 +08:00
public Databoard(MessagePanel messagePanel) {
this.messagePanel = messagePanel;
initComponents();
}
private void cleanUI() {
2023-11-07 11:15:20 +08:00
dataTabbedPane.removeAll();
2023-10-12 21:38:27 +08:00
splitPane.setVisible(false);
}
private void clearActionPerformed(ActionEvent e) {
2023-10-18 00:44:50 +08:00
int retCode = JOptionPane.showConfirmDialog(null, "Do you want to clear data?", "Info",
JOptionPane.YES_NO_OPTION);
if (retCode == JOptionPane.YES_OPTION) {
cleanUI();
String host = hostTextField.getText();
String cleanedHost = StringHelper.replaceFirstOccurrence(host, "*.", "");
if (host.contains("*")) {
2023-11-13 08:28:44 +08:00
ConfigEntry.globalDataMap.keySet().removeIf(i -> i.contains(cleanedHost) || cleanedHost.contains("*"));
2023-10-18 00:44:50 +08:00
} else {
ConfigEntry.globalDataMap.remove(host);
}
2023-10-12 21:38:27 +08:00
2023-10-18 00:44:50 +08:00
messagePanel.deleteByHost(cleanedHost);
2023-10-12 21:38:27 +08:00
}
}
private void initComponents() {
// JFormDesigner - Component initialization - DO NOT MODIFY //GEN-BEGIN:initComponents
hostLabel = new JLabel();
hostTextField = new JTextField();
2023-11-07 11:15:20 +08:00
dataTabbedPane = new JTabbedPane(JTabbedPane.TOP);
2023-10-12 21:38:27 +08:00
clearButton = new JButton();
//======== this ========
setLayout(new GridBagLayout());
((GridBagLayout)getLayout()).columnWidths = new int[] {25, 0, 0, 0, 20, 0};
((GridBagLayout)getLayout()).rowHeights = new int[] {0, 65, 20, 0};
((GridBagLayout)getLayout()).columnWeights = new double[] {0.0, 0.0, 1.0, 0.0, 0.0, 1.0E-4};
((GridBagLayout)getLayout()).rowWeights = new double[] {0.0, 1.0, 0.0, 1.0E-4};
//---- hostLabel ----
hostLabel.setText("Host:");
2023-11-27 14:55:28 +08:00
add(hostLabel, new GridBagConstraints(1, 0, 1, 1, 0.0, 0.0, GridBagConstraints.CENTER, GridBagConstraints.BOTH,
2023-10-12 21:38:27 +08:00
new Insets(8, 0, 5, 5), 0, 0));
2023-11-27 14:55:28 +08:00
add(hostTextField, new GridBagConstraints(2, 0, 1, 1, 0.0, 0.0, GridBagConstraints.CENTER, GridBagConstraints.BOTH,
2023-10-12 21:38:27 +08:00
new Insets(8, 0, 5, 5), 0, 0));
clearButton.setText("Clear");
clearButton.addActionListener(this::clearActionPerformed);
2023-11-27 14:55:28 +08:00
add(clearButton, new GridBagConstraints(3, 0, 1, 1, 0.0, 0.0, GridBagConstraints.CENTER, GridBagConstraints.BOTH,
new Insets(8, 0, 5, 5), 0, 0));
hostComboBox.setMaximumRowCount(5);
add(hostComboBox, new GridBagConstraints(2, 0, 1, 1, 0.0, 0.0, GridBagConstraints.CENTER, GridBagConstraints.BOTH,
2023-10-12 21:38:27 +08:00
new Insets(8, 0, 5, 5), 0, 0));
splitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT);
splitPane.setVisible(false);
2023-11-27 14:55:28 +08:00
add(splitPane, new GridBagConstraints(1, 1, 3, 3, 0.0, 0.0,
2023-10-12 21:38:27 +08:00
GridBagConstraints.CENTER, GridBagConstraints.BOTH,
new Insets(8, 0, 5, 5), 0, 0));
setAutoMatch();
}
private static List<String> getHostByList() {
return new ArrayList<>(ConfigEntry.globalDataMap.keySet());
}
/**
* 设置输入自动匹配
*/
private void setAutoMatch() {
2023-11-07 11:15:20 +08:00
populateComboBoxModel();
2023-10-12 21:38:27 +08:00
hostComboBox.setSelectedItem(null);
2023-11-07 11:15:20 +08:00
hostComboBox.addActionListener(this::handleComboBoxAction);
2023-10-12 21:38:27 +08:00
hostTextField.addKeyListener(new KeyAdapter() {
@Override
public void keyPressed(KeyEvent e) {
2023-11-07 11:15:20 +08:00
handleKeyEvents(e);
2023-10-12 21:38:27 +08:00
}
});
hostTextField.getDocument().addDocumentListener(new DocumentListener() {
@Override
public void insertUpdate(DocumentEvent e) {
2023-11-27 14:55:28 +08:00
filterComboBoxList();
2023-10-12 21:38:27 +08:00
}
@Override
public void removeUpdate(DocumentEvent e) {
2023-11-27 14:55:28 +08:00
filterComboBoxList();
2023-10-12 21:38:27 +08:00
}
@Override
public void changedUpdate(DocumentEvent e) {
2023-11-07 11:15:20 +08:00
filterComboBoxList();
}
2023-11-27 14:55:28 +08:00
2023-11-07 11:15:20 +08:00
});
}
private void populateComboBoxModel() {
for (String host : getHostByList()) {
comboBoxModel.addElement(host);
}
}
private void handleComboBoxAction(ActionEvent e) {
if (!isMatchHost && hostComboBox.getSelectedItem() != null) {
String selectedHost = hostComboBox.getSelectedItem().toString();
hostTextField.setText(selectedHost);
populateTabbedPaneByHost(selectedHost);
}
}
private void handleKeyEvents(KeyEvent e) {
isMatchHost = true;
int keyCode = e.getKeyCode();
if (keyCode == KeyEvent.VK_SPACE && hostComboBox.isPopupVisible()) {
e.setKeyCode(KeyEvent.VK_ENTER);
}
2023-11-27 14:55:28 +08:00
if (Arrays.asList(KeyEvent.VK_DOWN, KeyEvent.VK_UP).contains(keyCode)) {
2023-11-07 11:15:20 +08:00
hostComboBox.dispatchEvent(e);
2023-11-27 14:55:28 +08:00
}
if (keyCode == KeyEvent.VK_ENTER) {
isMatchHost = false;
handleComboBoxAction(null);
hostComboBox.setPopupVisible(false);
2023-11-07 11:15:20 +08:00
}
if (keyCode == KeyEvent.VK_ESCAPE) {
hostComboBox.setPopupVisible(false);
}
isMatchHost = false;
}
private void filterComboBoxList() {
isMatchHost = true;
comboBoxModel.removeAllElements();
String input = hostTextField.getText().toLowerCase();
if (!input.isEmpty()) {
for (String host : getHostByList()) {
String lowerCaseHost = host.toLowerCase();
if (lowerCaseHost.contains(input)) {
if (lowerCaseHost.equals(input)) {
comboBoxModel.insertElementAt(lowerCaseHost, 0);
comboBoxModel.setSelectedItem(lowerCaseHost);
} else {
comboBoxModel.addElement(host);
2023-10-12 21:38:27 +08:00
}
}
}
2023-11-07 11:15:20 +08:00
}
hostComboBox.setPopupVisible(comboBoxModel.getSize() > 0);
isMatchHost = false;
2023-10-12 21:38:27 +08:00
}
private void applyHostFilter(String filterText) {
TableRowSorter<TableModel> sorter = (TableRowSorter<TableModel>) table.getRowSorter();
2023-11-07 11:15:20 +08:00
2023-11-27 14:55:28 +08:00
String cleanedText = StringHelper.replaceFirstOccurrence(filterText, "*.", "");
if (cleanedText.contains("*")) {
cleanedText = "";
2023-10-12 21:38:27 +08:00
}
2023-11-07 11:15:20 +08:00
2023-11-27 14:55:28 +08:00
RowFilter<TableModel, Integer> filter = RowFilter.regexFilter(cleanedText, 1);
2023-10-12 21:38:27 +08:00
sorter.setRowFilter(filter);
messagePanel.applyHostFilter(filterText);
}
2023-10-18 00:44:50 +08:00
private void populateTabbedPaneByHost(String selectedHost) {
if (!Objects.equals(selectedHost, "")) {
2023-11-27 14:55:28 +08:00
ConcurrentHashMap<String, Map<String, List<String>>> dataMap = ConfigEntry.globalDataMap;
2023-10-12 21:38:27 +08:00
Map<String, List<String>> selectedDataMap;
2023-11-27 14:55:28 +08:00
dataTabbedPane.removeAll();
dataTabbedPane.setPreferredSize(new Dimension(500,0));
dataTabbedPane.setTabLayoutPolicy(JTabbedPane.SCROLL_TAB_LAYOUT);
splitPane.setLeftComponent(dataTabbedPane);
2023-10-12 21:38:27 +08:00
if (selectedHost.contains("*")) {
// 通配符数据
selectedDataMap = new HashMap<>();
String hostPattern = StringHelper.replaceFirstOccurrence(selectedHost, "*.", "");
for (String key : dataMap.keySet()) {
if (key.contains(hostPattern) || selectedHost.equals("*")) {
Map<String, List<String>> ruleMap = dataMap.get(key);
for (String ruleKey : ruleMap.keySet()) {
List<String> dataList = ruleMap.get(ruleKey);
if (selectedDataMap.containsKey(ruleKey)) {
List<String> mergedList = new ArrayList<>(selectedDataMap.get(ruleKey));
mergedList.addAll(dataList);
HashSet<String> uniqueSet = new HashSet<>(mergedList);
selectedDataMap.put(ruleKey, new ArrayList<>(uniqueSet));
} else {
selectedDataMap.put(ruleKey, dataList);
}
}
}
}
} else {
selectedDataMap = dataMap.get(selectedHost);
}
if (selectedHost.equals("**")) {
2023-11-27 14:55:28 +08:00
for (ConcurrentHashMap.Entry<String, Map<String, List<String>>> entry : dataMap.entrySet()) {
2023-10-12 21:38:27 +08:00
JTabbedPane newTabbedPane = new JTabbedPane();
newTabbedPane.setTabLayoutPolicy(JTabbedPane.SCROLL_TAB_LAYOUT);
2023-11-07 11:15:20 +08:00
2023-10-12 21:38:27 +08:00
for (Map.Entry<String, List<String>> entrySet : entry.getValue().entrySet()) {
2023-11-07 11:15:20 +08:00
currentWorker = new SwingWorker<Object, Void>() {
@Override
protected Object[] doInBackground() throws Exception {
String tabTitle = String.format("%s (%s)", entrySet.getKey(),
entrySet.getValue().size());
DatatablePanel datatablePanel = new DatatablePanel(entrySet.getKey(),
entrySet.getValue());
datatablePanel.setTableListener(messagePanel);
return new Object[] {tabTitle, datatablePanel};
}
@Override
protected void done() {
if (!isCancelled()) {
try {
Object[] result = (Object[]) get();
2023-11-16 19:33:38 +08:00
SwingUtilities.invokeLater(() -> {
newTabbedPane.addTab(result[0].toString(), (DatatablePanel) result[1]);
dataTabbedPane.addTab(entry.getKey(), newTabbedPane);
});
2023-11-07 11:15:20 +08:00
} catch (Exception e) {
e.printStackTrace();
}
}
}
};
currentWorker.execute();
2023-10-12 21:38:27 +08:00
}
}
2023-11-07 11:15:20 +08:00
dataTabbedPane.addChangeListener(changeListenerInstance);
2023-10-12 21:38:27 +08:00
} else {
2023-11-07 11:15:20 +08:00
dataTabbedPane.removeChangeListener(changeListenerInstance);
2023-10-12 21:38:27 +08:00
for (Map.Entry<String, List<String>> entry : selectedDataMap.entrySet()) {
String tabTitle = String.format("%s (%s)", entry.getKey(), entry.getValue().size());
2023-11-07 11:15:20 +08:00
DatatablePanel datatablePanel = new DatatablePanel(entry.getKey(), entry.getValue());
datatablePanel.setTableListener(messagePanel);
dataTabbedPane.addTab(tabTitle, datatablePanel);
2023-10-12 21:38:27 +08:00
}
}
// 展示请求消息表单
JSplitPane messageSplitPane = this.messagePanel.getPanel();
this.splitPane.setRightComponent(messageSplitPane);
// 获取字段
table = this.messagePanel.getTable();
// 设置对应字段宽度
TableColumnModel columnModel = table.getColumnModel();
TableColumn column = columnModel.getColumn(1);
column.setPreferredWidth(300);
column = columnModel.getColumn(2);
column.setPreferredWidth(300);
splitPane.setVisible(true);
applyHostFilter(selectedHost);
// 主动调用一次stateChanged使得dataTabbedPane可以精准展示内容
if (selectedHost.equals("**")) {
changeListenerInstance.stateChanged(null);
}
hostTextField.setText(selectedHost);
2023-10-23 21:51:12 +08:00
2023-10-12 21:38:27 +08:00
}
}
2023-11-27 14:55:28 +08:00
}