19 package org.sleuthkit.autopsy.modules.hashdatabase;
 
   21 import java.awt.Color;
 
   22 import java.awt.event.ActionEvent;
 
   23 import java.awt.event.ActionListener;
 
   24 import java.awt.event.KeyAdapter;
 
   25 import java.awt.event.KeyEvent;
 
   26 import java.util.ArrayList;
 
   28 import org.openide.util.NbBundle;
 
   30 import javax.swing.JOptionPane;
 
   31 import javax.swing.table.DefaultTableModel;
 
   32 import javax.swing.text.AttributeSet;
 
   33 import javax.swing.text.BadLocationException;
 
   34 import javax.swing.text.PlainDocument;
 
   40 class HashDbSearchPanel 
extends javax.swing.JPanel implements ActionListener {
 
   42     private static final Logger logger = Logger.getLogger(HashDbSearchPanel.class.getName());
 
   43     private static HashDbSearchPanel instance;
 
   48     public static HashDbSearchPanel getDefault() {
 
   49         if (instance == null) {
 
   50             instance = 
new HashDbSearchPanel();
 
   58     public void refresh() {
 
   59         boolean running = IngestManager.getInstance().isIngestRunning();
 
   61             titleLabel.setForeground(Color.red);
 
   62             titleLabel.setText(NbBundle.getMessage(
this.getClass(), 
"HashDbSearchPanel.titleText.ingestOngoing"));
 
   64             titleLabel.setForeground(Color.black);
 
   65             titleLabel.setText(NbBundle.getMessage(
this.getClass(), 
"HashDbSearchPanel.titleLabel.text"));
 
   67         hashField.setEditable(!running);
 
   68         searchButton.setEnabled(!running);
 
   69         addButton.setEnabled(!running);
 
   70         removeButton.setEnabled(!running);
 
   71         hashTable.setEnabled(!running);
 
   72         hashLabel.setEnabled(!running);
 
   73         saveBox.setEnabled(!running);
 
   79     private HashDbSearchPanel() {
 
   80         setName(HashDbPanelSearchAction.ACTION_NAME);
 
   85     final void customInit() {
 
   86         addButton.addActionListener(
this);
 
   87         removeButton.addActionListener(
this);
 
   88         errorField.setVisible(
false);
 
   89         hashField.requestFocus();
 
   91         hashField.setDocument(
new PlainDocument() {
 
   93             public void insertString(
int offset, String str, AttributeSet a) 
throws BadLocationException {
 
   94                 if ((this.getLength() + str.length()) <= 32) {
 
   95                     super.insertString(offset, str, a);
 
  100         hashField.addKeyListener(
new KeyAdapter() {
 
  102             public void keyPressed(KeyEvent e) {
 
  103                 if (e.getKeyChar() == KeyEvent.VK_ENTER) {
 
  109         hashTable.addKeyListener(
new KeyAdapter() {
 
  111             public void keyPressed(KeyEvent e) {
 
  112                 if (e.getKeyChar() == KeyEvent.VK_DELETE) {
 
  113                     removeButton.doClick();
 
  119     void addSearchActionListener(ActionListener l) {
 
  120         for (ActionListener al : searchButton.getActionListeners()) {
 
  121             searchButton.removeActionListener(al);
 
  123         searchButton.addActionListener(l);
 
  126     void addCancelActionListener(ActionListener l) {
 
  127         cancelButton.addActionListener(l);
 
  135     @SuppressWarnings(
"rawtypes")
 
  137     private 
void initComponents() {
 
  139         jScrollPane1 = 
new javax.swing.JScrollPane();
 
  140         hashTable = 
new javax.swing.JTable();
 
  141         hashField = 
new javax.swing.JTextField();
 
  142         addButton = 
new javax.swing.JButton();
 
  143         hashLabel = 
new javax.swing.JLabel();
 
  144         searchButton = 
new javax.swing.JButton();
 
  145         removeButton = 
new javax.swing.JButton();
 
  146         jSeparator1 = 
new javax.swing.JSeparator();
 
  147         titleLabel = 
new javax.swing.JLabel();
 
  148         errorField = 
new javax.swing.JLabel();
 
  149         saveBox = 
new javax.swing.JCheckBox();
 
  150         cancelButton = 
new javax.swing.JButton();
 
  152         hashTable.setModel(
new javax.swing.table.DefaultTableModel(
 
  157                     NbBundle.getMessage(this.getClass(), 
"HashDbSearchPanel.hashTable.defaultModel.title.text")
 
  160             Class[] types = 
new Class [] {
 
  161                 java.lang.String.class
 
  163             boolean[] canEdit = 
new boolean [] {
 
  167             public Class getColumnClass(
int columnIndex) {
 
  168                 return types [columnIndex];
 
  171             public boolean isCellEditable(
int rowIndex, 
int columnIndex) {
 
  172                 return canEdit [columnIndex];
 
  175         jScrollPane1.setViewportView(hashTable);
 
  176             hashTable.getColumnModel().getColumn(0).setHeaderValue(
org.openide.util.NbBundle.getMessage(HashDbSearchPanel.class, 
"HashDbSearchPanel.hashTable.columnModel.title0")); 
 
  178         hashField.setText(
org.openide.util.NbBundle.getMessage(HashDbSearchPanel.class, 
"HashDbSearchPanel.hashField.text")); 
 
  180         org.openide.awt.Mnemonics.setLocalizedText(addButton, 
org.openide.util.NbBundle.getMessage(HashDbSearchPanel.class, 
"HashDbSearchPanel.addButton.text")); 
 
  182         org.openide.awt.Mnemonics.setLocalizedText(hashLabel, 
org.openide.util.NbBundle.getMessage(HashDbSearchPanel.class, 
"HashDbSearchPanel.hashLabel.text")); 
 
  184         org.openide.awt.Mnemonics.setLocalizedText(searchButton, 
org.openide.util.NbBundle.getMessage(HashDbSearchPanel.class, 
"HashDbSearchPanel.searchButton.text")); 
 
  186         org.openide.awt.Mnemonics.setLocalizedText(removeButton, 
org.openide.util.NbBundle.getMessage(HashDbSearchPanel.class, 
"HashDbSearchPanel.removeButton.text")); 
 
  188         org.openide.awt.Mnemonics.setLocalizedText(titleLabel, 
org.openide.util.NbBundle.getMessage(HashDbSearchPanel.class, 
"HashDbSearchPanel.titleLabel.text")); 
 
  190         errorField.setForeground(
new java.awt.Color(255, 0, 0));
 
  191         org.openide.awt.Mnemonics.setLocalizedText(errorField, 
org.openide.util.NbBundle.getMessage(HashDbSearchPanel.class, 
"HashDbSearchPanel.errorField.text")); 
 
  193         org.openide.awt.Mnemonics.setLocalizedText(saveBox, 
org.openide.util.NbBundle.getMessage(HashDbSearchPanel.class, 
"HashDbSearchPanel.saveBox.text")); 
 
  194         saveBox.addActionListener(
new java.awt.event.ActionListener() {
 
  195             public void actionPerformed(java.awt.event.ActionEvent evt) {
 
  196                 saveBoxActionPerformed(evt);
 
  200         org.openide.awt.Mnemonics.setLocalizedText(cancelButton, 
org.openide.util.NbBundle.getMessage(HashDbSearchPanel.class, 
"HashDbSearchPanel.cancelButton.text")); 
 
  202         javax.swing.GroupLayout layout = 
new javax.swing.GroupLayout(
this);
 
  203         this.setLayout(layout);
 
  204         layout.setHorizontalGroup(
 
  205             layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
 
  206             .addGroup(layout.createSequentialGroup()
 
  208                 .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
 
  209                     .addComponent(jScrollPane1)
 
  210                     .addGroup(layout.createSequentialGroup()
 
  211                         .addComponent(hashLabel)
 
  212                         .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
 
  213                         .addComponent(hashField))
 
  214                     .addComponent(jSeparator1)
 
  215                     .addGroup(layout.createSequentialGroup()
 
  216                         .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
 
  217                             .addComponent(titleLabel)
 
  218                             .addGroup(layout.createSequentialGroup()
 
  220                                 .addComponent(addButton)
 
  221                                 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
 
  222                                 .addComponent(removeButton)
 
  223                                 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
 
  224                                 .addComponent(saveBox)))
 
  225                         .addGap(0, 0, Short.MAX_VALUE))
 
  226                     .addGroup(layout.createSequentialGroup()
 
  227                         .addComponent(errorField)
 
  228                         .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
 
  229                         .addComponent(searchButton)
 
  230                         .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
 
  231                         .addComponent(cancelButton)))
 
  234         layout.setVerticalGroup(
 
  235             layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
 
  236             .addGroup(layout.createSequentialGroup()
 
  238                 .addComponent(titleLabel)
 
  239                 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
 
  240                 .addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 171, javax.swing.GroupLayout.PREFERRED_SIZE)
 
  242                 .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
 
  243                     .addComponent(hashLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 20, javax.swing.GroupLayout.PREFERRED_SIZE)
 
  244                     .addComponent(hashField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
 
  245                 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
 
  246                 .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
 
  247                     .addComponent(addButton)
 
  248                     .addComponent(removeButton)
 
  249                     .addComponent(saveBox))
 
  251                 .addComponent(jSeparator1, javax.swing.GroupLayout.PREFERRED_SIZE, 10, javax.swing.GroupLayout.PREFERRED_SIZE)
 
  252                 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
 
  253                 .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
 
  254                     .addComponent(searchButton)
 
  255                     .addComponent(errorField)
 
  256                     .addComponent(cancelButton))
 
  257                 .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
 
  261     private void saveBoxActionPerformed(java.awt.event.ActionEvent evt) {
 
  266     private javax.swing.JButton addButton;
 
  267     private javax.swing.JButton cancelButton;
 
  268     private javax.swing.JLabel errorField;
 
  269     private javax.swing.JTextField hashField;
 
  270     private javax.swing.JLabel hashLabel;
 
  271     private javax.swing.JTable hashTable;
 
  272     private javax.swing.JScrollPane jScrollPane1;
 
  273     private javax.swing.JSeparator jSeparator1;
 
  274     private javax.swing.JButton removeButton;
 
  275     private javax.swing.JCheckBox saveBox;
 
  276     private javax.swing.JButton searchButton;
 
  277     private javax.swing.JLabel titleLabel;
 
  281     public void actionPerformed(ActionEvent e) {
 
  282         if (e.getSource().equals(addButton)) {
 
  284         } 
else if (e.getSource().equals(removeButton)) {
 
  295         if (hashTable.getRowCount() != 0) {
 
  297             if (HashDbSearcher.countFilesMd5Hashed() > 0) {
 
  300                 JOptionPane.showMessageDialog(null,
 
  301                         NbBundle.getMessage(
this.getClass(),
 
  302                                 "HashDbSearchPanel.noFilesHaveMD5HashMsg"),
 
  303                         NbBundle.getMessage(
this.getClass(), 
"HashDbSearchPanel.dlgMsg.title"),
 
  304                         JOptionPane.ERROR_MESSAGE);
 
  308             errorField.setText(NbBundle.getMessage(
this.getClass(), 
"HashDbSearchPanel.errorText.noHashesAddedMsg"));
 
  309             errorField.setVisible(
true);
 
  314     private boolean doSearch() {
 
  315         errorField.setVisible(
false);
 
  317         int numRows = hashTable.getRowCount();
 
  318         ArrayList<String> hashes = 
new ArrayList<String>();
 
  319         for (
int i = 0; i < numRows; i++) {
 
  320             hashes.add((String) hashTable.getValueAt(i, 0));
 
  323         HashDbSearchThread hashThread = 
new HashDbSearchThread(hashes);
 
  324         hashThread.execute();
 
  332         errorField.setVisible(
false);
 
  333         DefaultTableModel model = (DefaultTableModel) hashTable.getModel();
 
  334         String hash = hashField.getText();
 
  335         if (!hash.equals(
"")) {
 
  336             if (hash.matches(
"[a-fA-F0-9]{32}")) {
 
  337                 for (
int i = 0; i < model.getRowCount(); i++) {
 
  338                     if (model.getValueAt(i, 0).equals(hashField.getText())) {
 
  339                         hashField.setText(
"");
 
  341                                 NbBundle.getMessage(
this.getClass(), 
"HashDbSearchPanel.errorText.hashAlreadyAddedMsg"));
 
  342                         errorField.setVisible(
true);
 
  343                         errorField.setVisible(
true);
 
  347                 model.addRow(
new String[]{hash});
 
  348                 hashField.setText(
""); 
 
  350                 errorField.setText(NbBundle.getMessage(
this.getClass(), 
"HashDbSearchPanel.errorText.invalidMD5HashMsg"));
 
  351                 errorField.setVisible(
true);
 
  354         hashField.requestFocus(); 
 
  361         DefaultTableModel model = (DefaultTableModel) hashTable.getModel();
 
  362         int rows[] = hashTable.getSelectedRows();
 
  365         for (
int i = rows.length - 1; i >= 0; i--) {
 
  366             model.removeRow(rows[i]);
 
  374         if (!saveBox.isSelected()) {
 
  375             DefaultTableModel model = (DefaultTableModel) hashTable.getModel();
 
  376             int numRows = hashTable.getRowCount();
 
  377             for (
int i = numRows - 1; i >= 0; i--) {
 
  381         errorField.setVisible(
false);
 
  382         hashField.setText(
"");