1
0
mirror of https://github.com/elisspace/autopsy.git synced 2026-09-06 02:24:30 +00:00

Preliminary inbox message filtering / grouping, coloring, with no sort option

Remove auto scroll
This commit is contained in:
adam-m
2012-02-24 18:25:35 -05:00
parent 75d0786168
commit 8d65dadf4e
3 changed files with 322 additions and 90 deletions

View File

@@ -166,12 +166,6 @@ public class IngestMessage {
public static IngestMessage createMessage(long ID, MessageType messageType, IngestServiceAbstract source, String subject, String detailsHtml) {
if (messageType == null || source == null || subject == null) {
throw new IllegalArgumentException("message type, source and subject cannot be null");
}
//add html tags
if (detailsHtml != null) {
StringBuilder htmlB = new StringBuilder();
htmlB.append("<html>").append(detailsHtml).append("</html>");
detailsHtml = htmlB.toString();
}
return new IngestMessage(ID, messageType, source, subject, detailsHtml);
}
@@ -230,10 +224,6 @@ public class IngestMessage {
if (source == null || subject == null || detailsHtml == null || data == null) {
throw new IllegalArgumentException("source, subject, details and data cannot be null");
}
//add html tags
StringBuilder htmlB = new StringBuilder();
htmlB.append("<html>").append(detailsHtml).append("</html>");
detailsHtml = htmlB.toString();
IngestMessage im = new IngestMessage(ID, MessageType.DATA, source, subject, detailsHtml);
im.uniqueKey = uniqueKey;

View File

@@ -20,6 +20,7 @@ package org.sleuthkit.autopsy.ingest;
import org.openide.util.Lookup;
import org.sleuthkit.autopsy.corecomponentinterfaces.BlackboardResultViewer;
import org.sleuthkit.autopsy.ingest.IngestMessagePanel.IngestMessageGroup;
import org.sleuthkit.datamodel.BlackboardArtifact;
/**
@@ -143,9 +144,9 @@ class IngestMessageDetailsPanel extends javax.swing.JPanel {
private void viewArtifact(java.awt.event.ActionEvent evt) {
final IngestMessage message = mainPanel.getMessagePanel().getSelectedMessage();
if (message != null) {
BlackboardArtifact art = message.getData();
final IngestMessageGroup messageGroup = mainPanel.getMessagePanel().getSelectedMessage();
if (messageGroup != null) {
BlackboardArtifact art = messageGroup.getData();
if (art != null) {
BlackboardResultViewer v = Lookup.getDefault().lookup(BlackboardResultViewer.class);
v.viewArtifact(art);
@@ -156,9 +157,9 @@ class IngestMessageDetailsPanel extends javax.swing.JPanel {
private void viewContent(java.awt.event.ActionEvent evt) {
final IngestMessage message = mainPanel.getMessagePanel().getSelectedMessage();
if (message != null) {
BlackboardArtifact art = message.getData();
final IngestMessageGroup messageGroup = mainPanel.getMessagePanel().getSelectedMessage();
if (messageGroup != null) {
BlackboardArtifact art = messageGroup.getData();
if (art != null) {
BlackboardResultViewer v = Lookup.getDefault().lookup(BlackboardResultViewer.class);
v.viewArtifactContent(art);
@@ -168,15 +169,18 @@ class IngestMessageDetailsPanel extends javax.swing.JPanel {
void showDetails(int rowNumber) {
final IngestMessage message = mainPanel.getMessagePanel().getMessage(rowNumber);
if (message != null) {
String details = message.getDetails();
final IngestMessageGroup messageGroup = mainPanel.getMessagePanel().getMessageGroup(rowNumber);
if (messageGroup != null) {
String details = messageGroup.getDetails();
if (details != null) {
this.messageDetailsPane.setText(details);
StringBuilder b = new StringBuilder();
b.append("<html>").append(details).append("</html>");
this.messageDetailsPane.setText(b.toString());
} else {
this.messageDetailsPane.setText("");
}
if (message.getData() != null) {
//show artifact/content only for a message group with a single message
if (messageGroup.getData() != null && messageGroup.getCount() == 1) {
viewArtifactButton.setEnabled(true);
viewContentButton.setEnabled(true);
} else {

View File

@@ -22,7 +22,10 @@ import java.awt.Color;
import java.awt.Component;
import java.awt.Font;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.DefaultListSelectionModel;
@@ -33,18 +36,19 @@ import javax.swing.table.AbstractTableModel;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.TableColumn;
import org.sleuthkit.autopsy.ingest.IngestMessage.*;
import org.sleuthkit.datamodel.BlackboardArtifact;
/**
* Notification window showing messages from services to user
*
*/
class IngestMessagePanel extends javax.swing.JPanel {
private MessageTableModel tableModel;
private IngestMessageMainPanel mainPanel;
private static Font visitedFont = new Font("Arial", Font.PLAIN, 11);
private static Font notVisitedFont = new Font("Arial", Font.BOLD, 11);
private static Color ERROR_COLOR = new Color (255, 90, 90);
private static Color ERROR_COLOR = new Color(255, 90, 90);
private int lastRowSelected = -1;
/** Creates new form IngestMessagePanel */
@@ -54,21 +58,21 @@ class IngestMessagePanel extends javax.swing.JPanel {
initComponents();
customizeComponents();
}
int getLastRowSelected() {
return this.lastRowSelected;
}
IngestMessage getSelectedMessage() {
IngestMessageGroup getSelectedMessage() {
if (lastRowSelected < 0) {
return null;
}
return tableModel.getMessage(lastRowSelected);
return tableModel.getMessageGroup(lastRowSelected);
}
IngestMessage getMessage(int rowNumber) {
return tableModel.getMessage(rowNumber);
IngestMessageGroup getMessageGroup(int rowNumber) {
return tableModel.getMessageGroup(rowNumber);
}
/** This method is called from within the constructor to
@@ -122,14 +126,14 @@ class IngestMessagePanel extends javax.swing.JPanel {
mainPanel.setOpaque(true);
jScrollPane1.setOpaque(true);
messageTable.setOpaque(false);
jScrollPane1.setWheelScrollingEnabled(true);
messageTable.setAutoscrolls(true);
//messageTable.setTableHeader(null);
messageTable.setShowHorizontalLines(false);
messageTable.setShowVerticalLines(false);
messageTable.getParent().setBackground(messageTable.getBackground());
//customize column witdhs
@@ -141,10 +145,14 @@ class IngestMessagePanel extends javax.swing.JPanel {
column = messageTable.getColumnModel().getColumn(i);
if (i == 0) {
column.setCellRenderer(new MessageTableRenderer());
column.setPreferredWidth(((int) (width * 0.68)));
} else {
column.setPreferredWidth(((int) (width * 0.30)));
column.setPreferredWidth(((int) (width * 0.61)));
} else if (i == 1) {
column.setPreferredWidth(((int) (width * 0.15)));
column.setCellRenderer(new MessageTableRenderer());
} else {
column.setPreferredWidth(((int) (width * 0.23)));
column.setCellRenderer(new MessageTableRenderer());
}
}
messageTable.setCellSelectionEnabled(false);
@@ -152,72 +160,90 @@ class IngestMessagePanel extends javax.swing.JPanel {
messageTable.setRowSelectionAllowed(true);
messageTable.getSelectionModel().addListSelectionListener(new MessageVisitedSelection());
}
public void addMessage(IngestMessage m) {
tableModel.addMessage(m);
//autoscroll
messageTable.scrollRectToVisible(messageTable.getCellRect(messageTable.getRowCount() - 1, messageTable.getColumnCount(), true));
//messageTable.scrollRectToVisible(messageTable.getCellRect(messageTable.getRowCount() - 1, messageTable.getColumnCount(), true));
}
public void clearMessages() {
tableModel.clearMessages();
}
private void setVisited(int rowNumber) {
tableModel.setVisited(rowNumber);
lastRowSelected = rowNumber;
}
private class MessageTableModel extends AbstractTableModel {
//data
private Logger logger = Logger.getLogger(MessageTableModel.class.getName());
private List<TableEntry> messageData = new ArrayList<TableEntry>();
//for keeping track of messages to group, per service, by uniqness
private Map<IngestServiceAbstract, Map<String, List<IngestMessageGroup>>> groupings = new HashMap<IngestServiceAbstract, Map<String, List<IngestMessageGroup>>>();
private static final int MESSAGE_GROUP_THRESH = 3; //group messages after 3 messages per service with same uniqness
MessageTableModel() {
//initialize groupings map with services
for (IngestServiceAbstract service : IngestManager.enumerateFsContentServices()) {
groupings.put(service, new HashMap<String, List<IngestMessageGroup>>());
}
for (IngestServiceAbstract service : IngestManager.enumerateImageServices()) {
groupings.put(service, new HashMap<String, List<IngestMessageGroup>>());
}
}
@Override
public int getColumnCount() {
return 2;
return 3;
}
@Override
public int getRowCount() {
return messageData.size();
}
@Override
public String getColumnName(int column) {
String colName = null;
switch (column) {
case 0:
colName = "Subject";
break;
case 1:
colName = "Pri";
break;
case 2:
colName = "Module";
break;
default:
;
}
return colName;
}
@Override
public Object getValueAt(int rowIndex, int columnIndex) {
Object ret = null;
TableEntry entry = messageData.get(rowIndex);
switch (columnIndex) {
case 0:
ret = (Object) entry.message.getSubject();
ret = (Object) entry.messageGroup.getSubject();
break;
case 1:
Object service = entry.message.getSource();
ret = (Object) entry.messageGroup.getCount();
break;
case 2:
Object service = entry.messageGroup.getSource();
if (service == null) {
ret = "";
} else {
ret = (Object) entry.message.getSource().getName();
ret = (Object) entry.messageGroup.getSource().getName();
}
break;
default:
@@ -226,34 +252,113 @@ class IngestMessagePanel extends javax.swing.JPanel {
}
return ret;
}
@Override
public boolean isCellEditable(int rowIndex, int columnIndex) {
return false;
}
@Override
public Class getColumnClass(int c) {
return getValueAt(0, c).getClass();
}
private int getTableEntryIndex(IngestMessageGroup group) {
int ret = -1;
int i = 0;
for (TableEntry e : messageData) {
if (e.messageGroup.equals(group)) {
ret = i;
break;
}
++i;
}
return ret;
}
public void addMessage(IngestMessage m) {
messageData.add(new TableEntry(m));
//check how many messages per service with the same uniqness
//and add to existing group or create a new group
IngestServiceAbstract service = m.getSource();
IngestMessageGroup messageGroup = null;
if (service != null) {
//not a manager message, then group
final Map<String, List<IngestMessageGroup>> groups = groupings.get(service);
//groups for this uniqueness
final String uniqueness = m.getUniqueKey();
List<IngestMessageGroup> uniqGroups = groups.get(uniqueness);
if (uniqGroups == null) {
//first one with this uniqueness
uniqGroups = new ArrayList<IngestMessageGroup>();
messageGroup = new IngestMessageGroup(m);
uniqGroups.add(messageGroup);
groups.put(uniqueness, uniqGroups);
} else {
int uniqueGroupsCount = uniqGroups.size();
if (uniqueGroupsCount > MESSAGE_GROUP_THRESH) {
//merge them
messageGroup = uniqGroups.get(0);
for (int i = 1; i<uniqueGroupsCount; ++i) {
messageGroup.add(uniqGroups.get(i));
}
//remove merged groups
uniqGroups.clear();
uniqGroups.add(messageGroup);
//remove the row, will be added to the bottom
int toRemove = getTableEntryIndex(messageGroup);
messageData.remove(toRemove);
//remove the row, will be added to the bottom
this.fireTableRowsDeleted(toRemove, toRemove); //TODO check
} else if (uniqueGroupsCount == 1) {
IngestMessageGroup first = uniqGroups.get(0);
//one group with multiple messages
if (first.getCount() > 1) {
first.add(m);
messageGroup = first;
//TODO move to bottom of table
//remove from existing position
int toRemove = getTableEntryIndex(messageGroup);
messageData.remove(toRemove);
//remove the row, will be added to the bottom
this.fireTableRowsDeleted(toRemove, toRemove); //TODO check
} else {
//one group with one message
messageGroup = new IngestMessageGroup(m);
uniqGroups.add(messageGroup);
}
} else {
//multiple groups with 1 msg each
messageGroup = new IngestMessageGroup(m);
uniqGroups.add(messageGroup);
//add to bottom
}
}
} else {
//manager message
messageGroup = new IngestMessageGroup(m);
}
//add new or updated row to the bottom
messageData.add(new TableEntry(messageGroup));
int size = messageData.size();
this.fireTableRowsInserted(size - 1, size);
}
public void clearMessages() {
messageData.clear();
fireTableDataChanged();
}
public void setVisited(int rowNumber) {
messageData.get(rowNumber).visited = true;
//repaint the cell
fireTableCellUpdated(rowNumber, 0);
}
public void setVisitedAll() {
int row = 0;
for (TableEntry e : messageData) {
@@ -264,57 +369,188 @@ class IngestMessagePanel extends javax.swing.JPanel {
++row;
}
}
public boolean isVisited(int rowNumber) {
return messageData.get(rowNumber).visited;
}
public MessageType getMessageType(int rowNumber) {
return messageData.get(rowNumber).message.getMessageType();
return messageData.get(rowNumber).messageGroup.getMessageType();
}
public IngestMessage getMessage(int rowNumber) {
return messageData.get(rowNumber).message;
public IngestMessageGroup getMessageGroup(int rowNumber) {
return messageData.get(rowNumber).messageGroup;
}
class TableEntry implements Comparable {
IngestMessage message;
IngestMessageGroup messageGroup;
boolean visited;
TableEntry(IngestMessage message) {
this.message = message;
TableEntry(IngestMessageGroup messageGroup) {
this.messageGroup = messageGroup;
visited = false;
}
@Override
public int compareTo(Object o) {
return this.message.getDatePosted().compareTo(((TableEntry) o).message.getDatePosted());
return this.messageGroup.getDatePosted().compareTo(((TableEntry) o).messageGroup.getDatePosted());
}
}
}
//represents grouping of similar messages
//with the same uniqness
static class IngestMessageGroup {
static Color VERY_HIGH_PRI_COLOR = new Color(5, 131, 46); //for a single message in a group
static Color HIGH_PRI_COLOR = new Color(36, 166, 65);
static Color MED_PRI_COLOR = new Color(55, 213, 90);
static Color LOW_PRI_COLOR = new Color(160, 235, 177);
List<IngestMessage> messages;
int count;
IngestMessageGroup(IngestMessage message) {
messages = new ArrayList<IngestMessage>();
messages.add(message);
count = 1;
}
List<IngestMessage> getMessages() {
return messages;
}
void add(IngestMessage message) {
IngestMessage first = messages.get(0);
//make sure uniqness agrees
if (!message.getSource().equals(first.getSource())
|| !message.getUniqueKey().equals(first.getUniqueKey())) {
throw new IllegalArgumentException("Tried to add a message to a wrong message group.");
}
messages.add(message);
++count;
}
//add all messages from another group
void add(IngestMessageGroup group) {
IngestMessage first = messages.get(0);
IngestMessage firstG = group.messages.get(0);
//make sure uniqness agrees
if (!firstG.getSource().equals(first.getSource())
|| !firstG.getUniqueKey().equals(first.getUniqueKey())) {
throw new IllegalArgumentException("Tried to add a message to a wrong message group.");
}
for (IngestMessage m : group.getMessages()) {
messages.add(m);
++count;
}
}
int getCount() {
return count;
}
String getDetails() {
StringBuilder b = new StringBuilder();
for (IngestMessage m : messages) {
b.append(m.getDetails());
b.append("<hr />");
}
return b.toString();
}
/**
* return color corresp to priority
* @return
*/
Color getColor() {
if (count == 1) {
return VERY_HIGH_PRI_COLOR;
} else if (count < 5) {
return HIGH_PRI_COLOR;
} else if (count < 15) {
return MED_PRI_COLOR;
} else {
return LOW_PRI_COLOR;
}
}
/**
* return date of the last message of the group
* used for chrono sort
* @return
*/
Date getDatePosted() {
return messages.get(count - 1).getDatePosted();
}
/**
* get subject of the first message
* @return
*/
String getSubject() {
return messages.get(0).getSubject();
}
/*
* return unique key, should be the same for all msgs
*/
String getUniqueKey() {
return messages.get(0).getUniqueKey();
}
/*
* return source service, should be the same for all msgs
*/
IngestServiceAbstract getSource() {
return messages.get(0).getSource();
}
/*
* return data of the first message
*/
BlackboardArtifact getData() {
return messages.get(0).getData();
}
/*
* return message type, should be the same for all msgs
*/
IngestMessage.MessageType getMessageType() {
return messages.get(0).getMessageType();
}
}
/**
* bold font if not visited, colors for errors
* tooltips that show entire query string, disable selection borders
*/
private class MessageTableRenderer extends DefaultTableCellRenderer {
@Override
public Component getTableCellRendererComponent(
JTable table, Object value,
boolean isSelected, boolean hasFocus,
int row, int column) {
final Component cell = super.getTableCellRendererComponent(
table, value, false, false, row, column);
if (column < 2) {
if (column == 0 || column == 2) {
String val = (String) table.getModel().getValueAt(row, column);
setToolTipText(val);
setText(val);
//setText(val);
} else if (column == 1) {
//Integer val = (Integer) table.getModel().getValueAt(row, column);
//setToolTipText(Integer.toString(val));
}
if (column == 0) {
if (tableModel.isVisited(row)) {
cell.setFont(visitedFont);
@@ -322,20 +558,22 @@ class IngestMessagePanel extends javax.swing.JPanel {
cell.setFont(notVisitedFont);
}
if (!isSelected) {
MessageType mt = tableModel.getMessageType(row);
final IngestMessageGroup messageGroup = tableModel.getMessageGroup(row);
MessageType mt = messageGroup.getMessageType();
if (mt == MessageType.ERROR) {
cell.setBackground(ERROR_COLOR);
} else if (mt == MessageType.WARNING) {
cell.setBackground(Color.orange);
} else {
cell.setBackground(table.getBackground());
//cell.setBackground(table.getBackground());
cell.setBackground(messageGroup.getColor());
}
} else {
super.setForeground(table.getSelectionForeground());
super.setBackground(table.getSelectionBackground());
}
}
if (column == 1) {
if (isSelected) {
super.setForeground(table.getSelectionForeground());
@@ -344,10 +582,10 @@ class IngestMessagePanel extends javax.swing.JPanel {
cell.setBackground(table.getBackground());
}
}
return this;
}
@Override
protected void setValue(Object value) {
super.setValue(value);
@@ -358,9 +596,9 @@ class IngestMessagePanel extends javax.swing.JPanel {
* handle table selections / cell visitations
*/
private class MessageVisitedSelection implements ListSelectionListener {
private Logger logger = Logger.getLogger(MessageVisitedSelection.class.getName());
@Override
public void valueChanged(ListSelectionEvent e) {
DefaultListSelectionModel selModel = (DefaultListSelectionModel) e.getSource();
@@ -377,14 +615,14 @@ class IngestMessagePanel extends javax.swing.JPanel {
if (selected != -1) {
setVisited(selected);
//check if has details
IngestMessage m = getMessage(selected);
IngestMessageGroup m = getMessageGroup(selected);
String details = m.getDetails();
if (details != null && !details.equals("")) {
mainPanel.showDetails(selected);
}
}
}
}
}