4961 first pass at clean up of integrated rejview code

This commit is contained in:
William Schaefer 2019-05-10 11:40:33 -04:00
parent 7bd569b665
commit eda39d0bc0
12 changed files with 154 additions and 105 deletions

View File

@ -21,25 +21,41 @@
*/ */
package org.sleuthkit.autopsy.rejview; package org.sleuthkit.autopsy.rejview;
import javax.swing.*; import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import javax.swing.border.BevelBorder; import javax.swing.border.BevelBorder;
import javax.swing.event.CaretEvent; import javax.swing.event.CaretEvent;
import javax.swing.event.CaretListener; import javax.swing.event.CaretListener;
import javax.swing.text.BadLocationException; import javax.swing.text.BadLocationException;
import javax.swing.text.DefaultHighlighter; import javax.swing.text.DefaultHighlighter;
import javax.swing.text.JTextComponent; import javax.swing.text.JTextComponent;
import java.awt.*;
import java.nio.ByteBuffer; import java.nio.ByteBuffer;
import java.util.logging.Level;
import javax.swing.BoxLayout;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JSplitPane;
import javax.swing.JTextArea;
import javax.swing.SwingConstants;
import org.sleuthkit.autopsy.coreutils.Logger;
/** /**
* HexView is a standard three-paned hex editor widget that displays binary data. * HexView is a standard three-paned hex editor widget that displays binary
* data.
* *
* Note, this does not do any intelligent paging of the data. You should estimate it to load three strings * Note, this does not do any intelligent paging of the data. You should
* with length equal to the given ByteBuffer. So its probably not good to use this view with large files. * estimate it to load three strings with length equal to the given ByteBuffer.
* So its probably not good to use this view with large files.
*/ */
public class HexView extends JPanel implements CaretListener { public class HexView extends JPanel implements CaretListener {
private final static int DEFAULT_BYTES_PER_LINE = 0x10; private final static int DEFAULT_BYTES_PER_LINE = 0x10;
private final static char[] HEX_DIGITS = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' }; private final static char[] HEX_DIGITS = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};
private static final Logger logger = Logger.getLogger(HexView.class.getName());
private static final long serialVersionUID = 1L;
private final int _bytesPerLine; private final int _bytesPerLine;
private final ByteBuffer _buf; private final ByteBuffer _buf;
private final JTextComponent _offsetView; private final JTextComponent _offsetView;
@ -118,7 +134,7 @@ public class HexView extends JPanel implements CaretListener {
hexSB.append(hex); hexSB.append(hex);
if (b >= ' ' && b <= '~') { if (b >= ' ' && b <= '~') {
asciiSB.append((char)b); asciiSB.append((char) b);
} else { } else {
asciiSB.append('.'); asciiSB.append('.');
} }
@ -142,7 +158,6 @@ public class HexView extends JPanel implements CaretListener {
this._highlighterPainter = new DefaultHighlighter.DefaultHighlightPainter(this._highlightColor); this._highlighterPainter = new DefaultHighlighter.DefaultHighlightPainter(this._highlightColor);
} }
/** /**
* clearHighlight removes any colors applied to the text views. * clearHighlight removes any colors applied to the text views.
*/ */
@ -153,6 +168,7 @@ public class HexView extends JPanel implements CaretListener {
/** /**
* setHighlight colors the given byte range. * setHighlight colors the given byte range.
*
* @param startByte The starting byte index of the selection. * @param startByte The starting byte index of the selection.
* @param endByte The ending byte index of the selection. * @param endByte The ending byte index of the selection.
*/ */
@ -165,14 +181,15 @@ public class HexView extends JPanel implements CaretListener {
try { try {
this._asciiView.getHighlighter().addHighlight(startByte + startRows, endByte + endRows, this._highlighterPainter); this._asciiView.getHighlighter().addHighlight(startByte + startRows, endByte + endRows, this._highlighterPainter);
this._hexView.getHighlighter().addHighlight((startByte * 3) + startRows, (endByte * 3) + endRows, this._highlighterPainter); this._hexView.getHighlighter().addHighlight((startByte * 3) + startRows, (endByte * 3) + endRows, this._highlighterPainter);
} catch (BadLocationException e1) { } catch (BadLocationException ex) {
System.out.println("bad location"); logger.log(Level.WARNING, "bad location", ex);
} }
} }
/** /**
* setSelection sets the given byte range as "selected", which from a GUI perspective means the * setSelection sets the given byte range as "selected", which from a GUI
* bytes are highlighted, and the status bar updated. * perspective means the bytes are highlighted, and the status bar updated.
*
* @param startByte The starting byte index of the selection. * @param startByte The starting byte index of the selection.
* @param endByte The ending byte index of the selection. * @param endByte The ending byte index of the selection.
*/ */
@ -224,8 +241,8 @@ public class HexView extends JPanel implements CaretListener {
int endRows = (endByte - (endByte % this._bytesPerLine)) / this._bytesPerLine; int endRows = (endByte - (endByte % this._bytesPerLine)) / this._bytesPerLine;
// the byte index of the start,end points in the ASCII view // the byte index of the start,end points in the ASCII view
startByte = startByte - startRows; startByte -= startRows;
endByte = endByte - endRows; endByte -= endRows;
// avoid the loop // avoid the loop
if (_asciiLastSelectionStart == startByte && _asciiLastSelectionEnd == endByte) { if (_asciiLastSelectionStart == startByte && _asciiLastSelectionEnd == endByte) {
@ -250,10 +267,10 @@ public class HexView extends JPanel implements CaretListener {
int endRows = (endByte - (endByte % this._bytesPerLine)) / (3 * this._bytesPerLine); int endRows = (endByte - (endByte % this._bytesPerLine)) / (3 * this._bytesPerLine);
// the byte index of the start,end points in the ASCII view // the byte index of the start,end points in the ASCII view
startByte = startByte - startRows; startByte -= startRows;
startByte = startByte / 3; startByte /= 3;
endByte = endByte - endRows; endByte -= endRows;
endByte = endByte / 3; endByte /= 3;
if (_hexLastSelectionStart == startByte && _hexLastSelectionEnd == endByte) { if (_hexLastSelectionStart == startByte && _hexLastSelectionEnd == endByte) {
return; return;
@ -263,7 +280,7 @@ public class HexView extends JPanel implements CaretListener {
this.setSelection(startByte, endByte); this.setSelection(startByte, endByte);
} else { } else {
System.out.println("from unknown"); logger.log(Level.INFO, "from unknown");
} }
} }
} }

View File

@ -30,17 +30,18 @@ import java.nio.ByteBuffer;
import java.util.Iterator; import java.util.Iterator;
/** /**
* Formats a ValueData to a string similar to Regedit.exe on Windows. * Formats a ValueData to a string similar to Regedit.exe on Windows. For an
* For an example, see the nice sample here: * example, see the nice sample here:
* http://raja5.files.wordpress.com/2009/08/wincleanup_regedit.jpg * http://raja5.files.wordpress.com/2009/08/wincleanup_regedit.jpg
*/ */
public class RegeditExeValueFormatter { public class RegeditExeValueFormatter {
public static String format(ValueData val) throws UnsupportedEncodingException, RegistryParseException { public static String format(ValueData val) throws UnsupportedEncodingException, RegistryParseException {
StringBuilder sb = new StringBuilder(); StringBuilder sb = new StringBuilder();
switch(val.getValueType()) { switch (val.getValueType()) {
case REG_SZ: case REG_SZ:
case REG_EXPAND_SZ:{ case REG_EXPAND_SZ: {
String valString = val.getAsString(); String valString = val.getAsString();
if (valString.length() == 0) { if (valString.length() == 0) {
@ -94,4 +95,8 @@ public class RegeditExeValueFormatter {
} }
return sb.toString(); return sb.toString();
} }
private RegeditExeValueFormatter() {
//contrsuctor intentially left blank
}
} }

View File

@ -29,9 +29,12 @@ import java.io.UnsupportedEncodingException;
import java.util.Iterator; import java.util.Iterator;
import java.util.LinkedList; import java.util.LinkedList;
import java.util.List; import java.util.List;
import java.util.logging.Level;
import org.sleuthkit.autopsy.coreutils.Logger;
public class RejTreeKeyNode implements RejTreeNode { public class RejTreeKeyNode implements RejTreeNode {
private static final Logger logger = Logger.getLogger(RejTreeKeyNode.class.getName());
private final RegistryKey _key; private final RegistryKey _key;
public RejTreeKeyNode(RegistryKey key) { public RejTreeKeyNode(RegistryKey key) {
@ -42,8 +45,8 @@ public class RejTreeKeyNode implements RejTreeNode {
public String toString() { public String toString() {
try { try {
return this._key.getName(); return this._key.getName();
} catch (UnsupportedEncodingException e) { } catch (UnsupportedEncodingException ex) {
System.err.println("Failed to parse key name"); logger.log(Level.WARNING, "Failed to parse key name", ex);
return "PARSE FAILED."; return "PARSE FAILED.";
} }
} }
@ -52,15 +55,15 @@ public class RejTreeKeyNode implements RejTreeNode {
public boolean hasChildren() { public boolean hasChildren() {
try { try {
return this._key.getValueList().size() > 0 || this._key.getSubkeyList().size() > 0; return this._key.getValueList().size() > 0 || this._key.getSubkeyList().size() > 0;
} catch (RegistryParseException e) { } catch (RegistryParseException ex) {
System.err.println("Failed to parse key children."); logger.log(Level.WARNING, "Failed to parse key children.", ex);
return false; return false;
} }
} }
@Override @Override
public List<RejTreeNode> getChildren() { public List<RejTreeNode> getChildren() {
LinkedList<RejTreeNode> children = new LinkedList<RejTreeNode>(); LinkedList<RejTreeNode> children = new LinkedList<>();
try { try {
Iterator<RegistryKey> keyit = this._key.getSubkeyList().iterator(); Iterator<RegistryKey> keyit = this._key.getSubkeyList().iterator();
@ -72,8 +75,8 @@ public class RejTreeKeyNode implements RejTreeNode {
while (valueit.hasNext()) { while (valueit.hasNext()) {
children.add(new RejTreeValueNode(valueit.next())); children.add(new RejTreeValueNode(valueit.next()));
} }
} catch (RegistryParseException e) { } catch (RegistryParseException ex) {
System.err.println("Failed to parse key children."); logger.log(Level.WARNING, "Failed to parse key children.", ex);
} }
return children; return children;
} }
@ -85,10 +88,10 @@ public class RejTreeKeyNode implements RejTreeNode {
return this._key; return this._key;
} }
/** /**
* TODO(wb): this isn't exactly MVC... * TODO(wb): this isn't exactly MVC...
*/ */
@Override
public RejTreeNodeView getView() { public RejTreeNodeView getView() {
return new RejTreeKeyView(this); return new RejTreeKeyView(this);
} }

View File

@ -23,15 +23,22 @@ package org.sleuthkit.autopsy.rejview;
import com.williballenthin.rejistry.RegistryParseException; import com.williballenthin.rejistry.RegistryParseException;
import com.williballenthin.rejistry.RegistryValue; import com.williballenthin.rejistry.RegistryValue;
import java.awt.BorderLayout;
import java.awt.Dimension;
import javax.swing.*;
import javax.swing.table.TableColumn; import javax.swing.table.TableColumn;
import javax.swing.table.TableColumnModel; import javax.swing.table.TableColumnModel;
import java.awt.*;
import java.io.UnsupportedEncodingException; import java.io.UnsupportedEncodingException;
import java.util.Iterator; import java.util.Iterator;
import javax.swing.BorderFactory;
import javax.swing.JLabel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.SwingConstants;
public class RejTreeKeyView extends RejTreeNodeView { public class RejTreeKeyView extends RejTreeNodeView {
private static final long serialVersionUID = 1L;
private final RejTreeKeyNode _node; private final RejTreeKeyNode _node;
public RejTreeKeyView(RejTreeKeyNode node) { public RejTreeKeyView(RejTreeKeyNode node) {
@ -43,12 +50,12 @@ public class RejTreeKeyView extends RejTreeNodeView {
* @param 2 Number of subkeys * @param 2 Number of subkeys
* @param 3 Number of values * @param 3 Number of values
*/ */
String metadataTemplate = "" + String metadataTemplate = ""
"<html>" + + "<html>"
"<i>Name:</i> <b>%1$s</b><br/>" + + "<i>Name:</i> <b>%1$s</b><br/>"
"<i>Number of subkeys:</i> %2$d<br/>" + + "<i>Number of subkeys:</i> %2$d<br/>"
"<i>Number values:</i> %3$d<br/>" + + "<i>Number values:</i> %3$d<br/>"
"</html>"; + "</html>";
String keyName; String keyName;
int numSubkeys; int numSubkeys;
int numValues; int numValues;
@ -96,8 +103,7 @@ public class RejTreeKeyView extends RejTreeNodeView {
// TODO(wb): need to add some warning here... // TODO(wb): need to add some warning here...
// not sure how to do it, though, since some data may have already been added // not sure how to do it, though, since some data may have already been added
// but not necessarily all of it // but not necessarily all of it
} } catch (UnsupportedEncodingException e) {
catch (UnsupportedEncodingException e) {
// TODO(wb): need to add some warning here... // TODO(wb): need to add some warning here...
} }
@ -114,11 +120,11 @@ public class RejTreeKeyView extends RejTreeNodeView {
int total = 0; int total = 0;
for (int j = 0; j < width.length; j++) { for (int j = 0; j < width.length; j++) {
TableColumn column = table.getColumnModel().getColumn(j); TableColumn column = table.getColumnModel().getColumn(j);
int w = (int)table.getTableHeader().getDefaultRenderer().getTableCellRendererComponent(table, column.getIdentifier(), false, false, -1, j).getPreferredSize().getWidth(); int w = (int) table.getTableHeader().getDefaultRenderer().getTableCellRendererComponent(table, column.getIdentifier(), false, false, -1, j).getPreferredSize().getWidth();
if (table.getRowCount() > 0) { if (table.getRowCount() > 0) {
for (int i = 0; i < table.getRowCount(); i++) { for (int i = 0; i < table.getRowCount(); i++) {
int pw = (int)table.getCellRenderer(i, j).getTableCellRendererComponent(table, table.getValueAt(i, j), false, false, i, j).getPreferredSize().getWidth(); int pw = (int) table.getCellRenderer(i, j).getTableCellRendererComponent(table, table.getValueAt(i, j), false, false, i, j).getPreferredSize().getWidth();
w = Math.max(w, pw); w = Math.max(w, pw);
} }
} }

View File

@ -24,12 +24,18 @@ package org.sleuthkit.autopsy.rejview;
import java.util.List; import java.util.List;
/** /**
* RejTreeNode is the adaptor between the Registry structure model and the JTree model. * RejTreeNode is the adaptor between the Registry structure model and the JTree
* It may describe both the contents of the node, and how it should be displayed. * model. It may describe both the contents of the node, and how it should be
* displayed.
*/ */
public interface RejTreeNode { public interface RejTreeNode {
@Override
public abstract String toString(); public abstract String toString();
public abstract boolean hasChildren(); public abstract boolean hasChildren();
public abstract List<RejTreeNode> getChildren(); public abstract List<RejTreeNode> getChildren();
public abstract RejTreeNodeView getView(); public abstract RejTreeNodeView getView();
} }

View File

@ -22,7 +22,9 @@
package org.sleuthkit.autopsy.rejview; package org.sleuthkit.autopsy.rejview;
public class RejTreeNodeSelectionEvent { public class RejTreeNodeSelectionEvent {
private final RejTreeNode _node; private final RejTreeNode _node;
public RejTreeNodeSelectionEvent(RejTreeNode n) { public RejTreeNodeSelectionEvent(RejTreeNode n) {
this._node = n; this._node = n;
} }

View File

@ -22,5 +22,6 @@
package org.sleuthkit.autopsy.rejview; package org.sleuthkit.autopsy.rejview;
public interface RejTreeNodeSelectionListener { public interface RejTreeNodeSelectionListener {
public abstract void nodeSelected(RejTreeNodeSelectionEvent e); public abstract void nodeSelected(RejTreeNodeSelectionEvent e);
} }

View File

@ -21,10 +21,13 @@
*/ */
package org.sleuthkit.autopsy.rejview; package org.sleuthkit.autopsy.rejview;
import javax.swing.*; import java.awt.LayoutManager;
import java.awt.*; import javax.swing.JPanel;
public class RejTreeNodeView extends JPanel { public class RejTreeNodeView extends JPanel {
private static final long serialVersionUID = 1L;
public RejTreeNodeView() { public RejTreeNodeView() {
super(); super();
} }

View File

@ -26,26 +26,32 @@ import com.williballenthin.rejistry.RegistryValue;
import java.io.UnsupportedEncodingException; import java.io.UnsupportedEncodingException;
import java.util.LinkedList; import java.util.LinkedList;
import java.util.List; import java.util.List;
import org.openide.util.NbBundle.Messages;
import java.util.logging.Level;
import org.sleuthkit.autopsy.coreutils.Logger;
public class RejTreeValueNode implements RejTreeNode { public class RejTreeValueNode implements RejTreeNode {
private static final Logger logger = Logger.getLogger(RejTreeValueNode.class.getName());
private final RegistryValue _value; private final RegistryValue _value;
public RejTreeValueNode(RegistryValue value) { public RejTreeValueNode(RegistryValue value) {
this._value = value; this._value = value;
} }
@Messages({"RejTreeValueNode.defaultValueName.text=(Default)",
"RejTreeValueNode.failureValueName.text=PARSE FAILED"})
@Override @Override
public String toString() { public String toString() {
try { try {
String valueName = this._value.getName(); String valueName = this._value.getName();
if (valueName == "") { if (valueName.isEmpty()) {
return "(Default)"; return Bundle.RejTreeValueNode_defaultValueName_text();
} }
return valueName; return valueName;
} catch (UnsupportedEncodingException e) { } catch (UnsupportedEncodingException ex) {
System.err.println("Failed to parse _value name"); logger.log(Level.WARNING, "Failed to parse _value name", ex);
return "PARSE FAILED."; return Bundle.RejTreeValueNode_failureValueName_text();
} }
} }
@ -56,7 +62,7 @@ public class RejTreeValueNode implements RejTreeNode {
@Override @Override
public List<RejTreeNode> getChildren() { public List<RejTreeNode> getChildren() {
return new LinkedList<RejTreeNode>(); return new LinkedList<>();
} }
/** /**
@ -69,6 +75,7 @@ public class RejTreeValueNode implements RejTreeNode {
/** /**
* TODO(wb): this isn't exactly MVC... * TODO(wb): this isn't exactly MVC...
*/ */
@Override
public RejTreeNodeView getView() { public RejTreeNodeView getView() {
return new RejTreeValueView(this); return new RejTreeValueView(this);
} }

View File

@ -23,13 +23,17 @@ package org.sleuthkit.autopsy.rejview;
import com.williballenthin.rejistry.RegistryParseException; import com.williballenthin.rejistry.RegistryParseException;
import com.williballenthin.rejistry.ValueData; import com.williballenthin.rejistry.ValueData;
import java.awt.BorderLayout;
import javax.swing.*;
import java.awt.*;
import java.io.UnsupportedEncodingException; import java.io.UnsupportedEncodingException;
import java.util.Iterator; import javax.swing.BorderFactory;
import javax.swing.JComponent;
import javax.swing.JLabel;
import javax.swing.JScrollPane;
import javax.swing.SwingConstants;
public class RejTreeValueView extends RejTreeNodeView { public class RejTreeValueView extends RejTreeNodeView {
private static final long serialVersionUID = 1L;
private final RejTreeValueNode _node; private final RejTreeValueNode _node;
public RejTreeValueView(RejTreeValueNode node) { public RejTreeValueView(RejTreeValueNode node) {
@ -40,21 +44,21 @@ public class RejTreeValueView extends RejTreeNodeView {
* @param 1 Name * @param 1 Name
* @param 2 Type * @param 2 Type
*/ */
String metadataTemplate = "" + String metadataTemplate = ""
"<html>" + + "<html>"
"<i>Name:</i> <b>%1$s</b><br/>" + + "<i>Name:</i> <b>%1$s</b><br/>"
"<i>Type:</i> %2$s" + + "<i>Type:</i> %2$s"
"</html>"; + "</html>";
String valueName; String valueName;
String valueType; String valueType;
/** /**
* @param 1 Value * @param 1 Value
*/ */
String valueTemplate = "" + String valueTemplate = ""
"<html>" + + "<html>"
"%1$s" + + "%1$s"
"</html>"; + "</html>";
try { try {
valueName = this._node.getValue().getName(); valueName = this._node.getValue().getName();
} catch (UnsupportedEncodingException e) { } catch (UnsupportedEncodingException e) {
@ -63,7 +67,7 @@ public class RejTreeValueView extends RejTreeNodeView {
try { try {
valueType = this._node.getValue().getValueType().toString(); valueType = this._node.getValue().getValueType().toString();
} catch (RegistryParseException e ) { } catch (RegistryParseException e) {
valueType = "FAILED TO PARSE VALUE TYPE"; valueType = "FAILED TO PARSE VALUE TYPE";
} }
@ -77,7 +81,7 @@ public class RejTreeValueView extends RejTreeNodeView {
ValueData data = this._node.getValue().getValue(); ValueData data = this._node.getValue().getValue();
// the case statements are a bit repetitive, but i think make more sense than confusingly-nested if/elses // the case statements are a bit repetitive, but i think make more sense than confusingly-nested if/elses
switch(data.getValueType()) { switch (data.getValueType()) {
case REG_SZ: case REG_SZ:
case REG_EXPAND_SZ: { case REG_EXPAND_SZ: {
String valueValue = data.getAsString(); String valueValue = data.getAsString();
@ -117,12 +121,7 @@ public class RejTreeValueView extends RejTreeNodeView {
break; break;
} }
} }
} catch (RegistryParseException e) { } catch (RegistryParseException | UnsupportedEncodingException e) {
JLabel valueLabel = new JLabel(String.format(valueTemplate, "FAILED TO PARSE VALUE VALUE"), JLabel.LEFT);
valueLabel.setBorder(BorderFactory.createTitledBorder("Value"));
valueLabel.setVerticalAlignment(SwingConstants.TOP);
valueComponent = valueLabel;
} catch (UnsupportedEncodingException e) {
JLabel valueLabel = new JLabel(String.format(valueTemplate, "FAILED TO PARSE VALUE VALUE"), JLabel.LEFT); JLabel valueLabel = new JLabel(String.format(valueTemplate, "FAILED TO PARSE VALUE VALUE"), JLabel.LEFT);
valueLabel.setBorder(BorderFactory.createTitledBorder("Value")); valueLabel.setBorder(BorderFactory.createTitledBorder("Value"));
valueLabel.setVerticalAlignment(SwingConstants.TOP); valueLabel.setVerticalAlignment(SwingConstants.TOP);
@ -133,4 +132,3 @@ public class RejTreeValueView extends RejTreeNodeView {
this.add(new JScrollPane(valueComponent), BorderLayout.CENTER); this.add(new JScrollPane(valueComponent), BorderLayout.CENTER);
} }
} }

View File

@ -23,8 +23,7 @@ package org.sleuthkit.autopsy.rejview;
import com.williballenthin.rejistry.RegistryHive; import com.williballenthin.rejistry.RegistryHive;
import com.williballenthin.rejistry.RegistryParseException; import com.williballenthin.rejistry.RegistryParseException;
import java.awt.Dimension;
import javax.swing.*;
import javax.swing.event.TreeExpansionEvent; import javax.swing.event.TreeExpansionEvent;
import javax.swing.event.TreeExpansionListener; import javax.swing.event.TreeExpansionListener;
import javax.swing.event.TreeSelectionEvent; import javax.swing.event.TreeSelectionEvent;
@ -32,25 +31,30 @@ import javax.swing.event.TreeSelectionListener;
import javax.swing.tree.DefaultMutableTreeNode; import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeModel; import javax.swing.tree.DefaultTreeModel;
import javax.swing.tree.TreePath; import javax.swing.tree.TreePath;
import java.awt.*;
import java.util.concurrent.CopyOnWriteArrayList; import java.util.concurrent.CopyOnWriteArrayList;
import java.util.logging.Level;
import javax.swing.JScrollPane;
import javax.swing.JTree;
import org.sleuthkit.autopsy.coreutils.Logger;
public class RejTreeView extends JScrollPane implements TreeExpansionListener, TreeSelectionListener { public class RejTreeView extends JScrollPane implements TreeExpansionListener, TreeSelectionListener {
private static final Logger logger = Logger.getLogger(HexView.class.getName());
private static final long serialVersionUID = 1L;
private final DefaultTreeModel _tree_model; private final DefaultTreeModel _tree_model;
private JTree _tree;
private final RegistryHive _hive; private final RegistryHive _hive;
private final CopyOnWriteArrayList<RejTreeNodeSelectionListener> _nodeSelectionListeners; private final CopyOnWriteArrayList<RejTreeNodeSelectionListener> _nodeSelectionListeners;
private final JTree _tree;
public RejTreeView(RegistryHive hive) { public RejTreeView(RegistryHive hive) {
this._hive = hive; this._hive = hive;
DefaultMutableTreeNode rootNode; DefaultMutableTreeNode rootNode;
this._nodeSelectionListeners = new CopyOnWriteArrayList<RejTreeNodeSelectionListener>(); this._nodeSelectionListeners = new CopyOnWriteArrayList<>();
try { try {
rootNode = getTreeNode(new RejTreeKeyNode(this._hive.getRoot())); rootNode = getTreeNode(new RejTreeKeyNode(this._hive.getRoot()));
} catch (RegistryParseException e) { } catch (RegistryParseException ex) {
System.err.println("Failed to parse root key"); logger.log(Level.WARNING, "Failed to parse root key", ex);
rootNode = new DefaultMutableTreeNode("PARSE FAILED"); rootNode = new DefaultMutableTreeNode("PARSE FAILED");
} }
@ -70,7 +74,8 @@ public class RejTreeView extends JScrollPane implements TreeExpansionListener, T
} }
/** /**
* getTreeNode creates a TreeNode from a RejTreeNode, settings the appropriate fields. * getTreeNode creates a TreeNode from a RejTreeNode, settings the
* appropriate fields.
*/ */
private DefaultMutableTreeNode getTreeNode(RejTreeNode node) { private DefaultMutableTreeNode getTreeNode(RejTreeNode node) {
DefaultMutableTreeNode ret; DefaultMutableTreeNode ret;
@ -85,7 +90,7 @@ public class RejTreeView extends JScrollPane implements TreeExpansionListener, T
DefaultMutableTreeNode node = (DefaultMutableTreeNode) path.getLastPathComponent(); DefaultMutableTreeNode node = (DefaultMutableTreeNode) path.getLastPathComponent();
if (node.getChildCount() == 0) { if (node.getChildCount() == 0) {
RejTreeNode n = (RejTreeNode)node.getUserObject(); RejTreeNode n = (RejTreeNode) node.getUserObject();
for (RejTreeNode rejTreeNode : n.getChildren()) { for (RejTreeNode rejTreeNode : n.getChildren()) {
node.add(getTreeNode(rejTreeNode)); node.add(getTreeNode(rejTreeNode));
} }
@ -100,16 +105,15 @@ public class RejTreeView extends JScrollPane implements TreeExpansionListener, T
@Override @Override
public void valueChanged(TreeSelectionEvent e) { public void valueChanged(TreeSelectionEvent e) {
TreePath path = e.getPath(); TreePath path = e.getPath();
System.out.println("Selected: " + path);
DefaultMutableTreeNode node = (DefaultMutableTreeNode) path.getLastPathComponent(); DefaultMutableTreeNode node = (DefaultMutableTreeNode) path.getLastPathComponent();
this.triggerRejTreeNodeSelection((RejTreeNode)node.getUserObject()); this.triggerRejTreeNodeSelection((RejTreeNode) node.getUserObject());
} }
public void addRejTreeNodeSelectionListener(RejTreeNodeSelectionListener l) { public void addRejTreeNodeSelectionListener(RejTreeNodeSelectionListener l) {
this._nodeSelectionListeners.add(l); this._nodeSelectionListeners.add(l);
} }
public void removeRejTreeNodeSelectionListener(RejTreeNodeSelectionListener l ) { public void removeRejTreeNodeSelectionListener(RejTreeNodeSelectionListener l) {
this._nodeSelectionListeners.remove(l); this._nodeSelectionListeners.remove(l);
} }

View File

@ -23,13 +23,15 @@ package org.sleuthkit.autopsy.rejview;
import com.williballenthin.rejistry.RegistryHive; import com.williballenthin.rejistry.RegistryHive;
import com.williballenthin.rejistry.RegistryHiveBuffer; import com.williballenthin.rejistry.RegistryHiveBuffer;
import java.awt.BorderLayout;
import javax.swing.*; import java.awt.Dimension;
import java.awt.*;
import java.nio.ByteBuffer; import java.nio.ByteBuffer;
import javax.swing.JPanel;
import javax.swing.JSplitPane;
public class RejView extends JPanel implements RejTreeNodeSelectionListener { public class RejView extends JPanel implements RejTreeNodeSelectionListener {
private static final long serialVersionUID = 1L;
private final RegistryHive _hive; private final RegistryHive _hive;
private final RejTreeView _tree_view; private final RejTreeView _tree_view;
private final JSplitPane _splitPane; private final JSplitPane _splitPane;
@ -37,12 +39,10 @@ public class RejView extends JPanel implements RejTreeNodeSelectionListener {
public RejView(RegistryHive hive) { public RejView(RegistryHive hive) {
super(new BorderLayout()); super(new BorderLayout());
this._hive = hive; this._hive = hive;
// have to do these cause they're final // have to do these cause they're final
this._tree_view = new RejTreeView(this._hive); this._tree_view = new RejTreeView(this._hive);
this._splitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, this._splitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT,
this._tree_view, new JPanel()); this._tree_view, new JPanel());
this.setupUI(); this.setupUI();
} }
@ -54,7 +54,6 @@ public class RejView extends JPanel implements RejTreeNodeSelectionListener {
this._tree_view = new RejTreeView(this._hive); this._tree_view = new RejTreeView(this._hive);
this._splitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, this._splitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT,
this._tree_view, new JPanel()); this._tree_view, new JPanel());
this.setupUI(); this.setupUI();
} }
@ -62,10 +61,8 @@ public class RejView extends JPanel implements RejTreeNodeSelectionListener {
this._splitPane.setResizeWeight(0); this._splitPane.setResizeWeight(0);
this._splitPane.setOneTouchExpandable(true); this._splitPane.setOneTouchExpandable(true);
this._splitPane.setContinuousLayout(true); this._splitPane.setContinuousLayout(true);
this.add(this._splitPane, BorderLayout.CENTER); this.add(this._splitPane, BorderLayout.CENTER);
this.setPreferredSize(new Dimension(800, 600)); this.setPreferredSize(new Dimension(800, 600));
this._tree_view.addRejTreeNodeSelectionListener(this); this._tree_view.addRejTreeNodeSelectionListener(this);
} }