Autopsy  3.1
Graphical digital forensics platform for The Sleuth Kit and other tools.
DropdownListSearchPanel.java
Go to the documentation of this file.
1 /*
2  * Autopsy Forensic Browser
3  *
4  * Copyright 2011-2014 Basis Technology Corp.
5  * Contact: carrier <at> sleuthkit <dot> org
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  * http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  */
19 
20 package org.sleuthkit.autopsy.keywordsearch;
21 
22 import java.awt.*;
23 import java.awt.event.ActionEvent;
24 import java.awt.event.ActionListener;
25 import java.beans.PropertyChangeEvent;
26 import java.beans.PropertyChangeListener;
27 import java.util.ArrayList;
28 import java.util.Iterator;
29 import java.util.List;
30 import java.util.logging.Level;
31 import javax.swing.JCheckBox;
32 import javax.swing.JTable;
33 import javax.swing.ListSelectionModel;
34 import javax.swing.event.ListSelectionEvent;
35 import javax.swing.event.ListSelectionListener;
36 import javax.swing.table.AbstractTableModel;
37 import javax.swing.table.TableCellRenderer;
38 import javax.swing.table.TableColumn;
39 import org.openide.util.NbBundle;
40 import org.openide.util.actions.SystemAction;
44 
48 class DropdownListSearchPanel extends KeywordSearchPanel {
49 
50  private static final Logger logger = Logger.getLogger(DropdownListSearchPanel.class.getName());
51  private static DropdownListSearchPanel instance;
52  private XmlKeywordSearchList loader;
53  private KeywordListsTableModel listsTableModel;
54  private KeywordsTableModel keywordsTableModel;
55  private ActionListener searchAddListener;
56  private boolean ingestRunning;
57 
61  private DropdownListSearchPanel() {
62  listsTableModel = new KeywordListsTableModel();
63  keywordsTableModel = new KeywordsTableModel();
64  initComponents();
65  customizeComponents();
66  }
67 
68  static synchronized DropdownListSearchPanel getDefault() {
69  if (instance == null) {
70  instance = new DropdownListSearchPanel();
71  }
72  return instance;
73  }
74 
75  private void customizeComponents() {
76  listsTable.setTableHeader(null);
77  listsTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
78  //customize column witdhs
79  final int leftWidth = leftPane.getPreferredSize().width;
80  TableColumn column;
81  for (int i = 0; i < listsTable.getColumnCount(); i++) {
82  column = listsTable.getColumnModel().getColumn(i);
83  if (i == 0) {
84  column.setPreferredWidth(((int) (leftWidth * 0.10)));
85  column.setCellRenderer(new LeftCheckBoxRenderer());
86  } else {
87  column.setPreferredWidth(((int) (leftWidth * 0.89)));
88  }
89  }
90  final int rightWidth = rightPane.getPreferredSize().width;
91  for (int i = 0; i < keywordsTable.getColumnCount(); i++) {
92  column = keywordsTable.getColumnModel().getColumn(i);
93  if (i == 0) {
94  column.setPreferredWidth(((int) (rightWidth * 0.78)));
95  } else {
96  column.setPreferredWidth(((int) (rightWidth * 0.20)));
97  column.setCellRenderer(new RightCheckBoxRenderer());
98  }
99  }
100 
101  loader = XmlKeywordSearchList.getCurrent();
102  listsTable.getSelectionModel().addListSelectionListener(new ListSelectionListener() {
103  @Override
104  public void valueChanged(ListSelectionEvent e) {
105  ListSelectionModel listSelectionModel = (ListSelectionModel) e.getSource();
106  if (!listSelectionModel.isSelectionEmpty()) {
107  int index = listSelectionModel.getMinSelectionIndex();
108  KeywordList list = listsTableModel.getListAt(index);
109  keywordsTableModel.resync(list);
110  } else {
111  keywordsTableModel.deleteAll();
112  }
113  }
114  });
115 
116  ingestRunning = IngestManager.getInstance().isIngestRunning();
117  updateComponents();
118 
119  IngestManager.getInstance().addIngestJobEventListener(new PropertyChangeListener() {
120  @Override
121  public void propertyChange(PropertyChangeEvent evt) {
122  String changed = evt.getPropertyName();
123  if (changed.equals(IngestJobEvent.STARTED.toString())
124  || changed.equals(IngestJobEvent.COMPLETED.toString())
125  || changed.equals(IngestJobEvent.CANCELLED.toString())) {
126  EventQueue.invokeLater(new Runnable() {
127  @Override
128  public void run() {
129  ingestRunning = IngestManager.getInstance().isIngestRunning();
130  updateComponents();
131  }
132  });
133  }
134  }
135  });
136 
137  searchAddListener = new ActionListener() {
138  @Override
139  public void actionPerformed(ActionEvent e) {
140  if (ingestRunning) {
141  SearchRunner.getInstance().addKeywordListsToAllJobs(listsTableModel.getSelectedLists());
142  logger.log(Level.INFO, "Submitted enqueued lists to ingest"); //NON-NLS
143  } else {
144  searchAction(e);
145  }
146  }
147  };
148 
149  searchAddButton.addActionListener(searchAddListener);
150  }
151 
152  private void updateComponents() {
153  ingestRunning = IngestManager.getInstance().isIngestRunning();
154  if (ingestRunning) {
155  searchAddButton.setText(NbBundle.getMessage(this.getClass(), "KeywordSearchListsViewerPanel.initIngest.addIngestTitle"));
156  searchAddButton.setToolTipText(NbBundle.getMessage(this.getClass(), "KeywordSearchListsViewerPanel.initIngest.addIngestMsg" ));
157 
158  } else {
159  searchAddButton.setText(NbBundle.getMessage(this.getClass(), "KeywordSearchListsViewerPanel.initIngest.searchIngestTitle"));
160  searchAddButton.setToolTipText(NbBundle.getMessage(this.getClass(), "KeywordSearchListsViewerPanel.initIngest.addIdxSearchMsg"));
161  }
162  listsTableModel.resync();
163  updateIngestIndexLabel();
164  }
165 
166  private void updateIngestIndexLabel() {
167  if (ingestRunning) {
168  ingestIndexLabel.setText(NbBundle.getMessage(this.getClass(), "KeywordSearchListsViewerPanel.initIngest.ongoingIngestMsg", filesIndexed));
169  }
170  else {
171  ingestIndexLabel.setText(NbBundle.getMessage(this.getClass(), "KeywordSearchListsViewerPanel.initIngest.fileIndexCtMsg", filesIndexed));
172  }
173  }
174 
175  @Override
176  protected void postFilesIndexedChange() {
177  updateIngestIndexLabel();
178  }
179 
183  void resync() {
184  listsTableModel.resync();
185  }
186 
192  @SuppressWarnings("unchecked")
193  // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
194  private void initComponents() {
195 
196  jSplitPane1 = new javax.swing.JSplitPane();
197  leftPane = new javax.swing.JScrollPane();
198  listsTable = new javax.swing.JTable();
199  rightPane = new javax.swing.JScrollPane();
200  keywordsTable = new javax.swing.JTable();
201  manageListsButton = new javax.swing.JButton();
202  searchAddButton = new javax.swing.JButton();
203  ingestIndexLabel = new javax.swing.JLabel();
204 
205  leftPane.setMinimumSize(new java.awt.Dimension(150, 23));
206 
207  listsTable.setBackground(new java.awt.Color(240, 240, 240));
208  listsTable.setModel(listsTableModel);
209  listsTable.setShowHorizontalLines(false);
210  listsTable.setShowVerticalLines(false);
211  listsTable.getTableHeader().setReorderingAllowed(false);
212  leftPane.setViewportView(listsTable);
213 
214  jSplitPane1.setLeftComponent(leftPane);
215 
216  keywordsTable.setBackground(new java.awt.Color(240, 240, 240));
217  keywordsTable.setModel(keywordsTableModel);
218  keywordsTable.setShowHorizontalLines(false);
219  keywordsTable.setShowVerticalLines(false);
220  rightPane.setViewportView(keywordsTable);
221 
222  jSplitPane1.setRightComponent(rightPane);
223 
224  manageListsButton.setText(org.openide.util.NbBundle.getMessage(DropdownListSearchPanel.class, "KeywordSearchListsViewerPanel.manageListsButton.text")); // NOI18N
225  manageListsButton.setToolTipText(org.openide.util.NbBundle.getMessage(DropdownListSearchPanel.class, "KeywordSearchListsViewerPanel.manageListsButton.toolTipText")); // NOI18N
226  manageListsButton.addActionListener(new java.awt.event.ActionListener() {
227  public void actionPerformed(java.awt.event.ActionEvent evt) {
228  manageListsButtonActionPerformed(evt);
229  }
230  });
231 
232  searchAddButton.setText(org.openide.util.NbBundle.getMessage(DropdownListSearchPanel.class, "KeywordSearchListsViewerPanel.searchAddButton.text")); // NOI18N
233  searchAddButton.addActionListener(new java.awt.event.ActionListener() {
234  public void actionPerformed(java.awt.event.ActionEvent evt) {
235  searchAddButtonActionPerformed(evt);
236  }
237  });
238 
239  ingestIndexLabel.setFont(ingestIndexLabel.getFont().deriveFont(Font.PLAIN, 10));
240  ingestIndexLabel.setText(org.openide.util.NbBundle.getMessage(DropdownListSearchPanel.class, "KeywordSearchListsViewerPanel.ingestIndexLabel.text")); // NOI18N
241 
242  javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
243  this.setLayout(layout);
244  layout.setHorizontalGroup(
245  layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
246  .addComponent(jSplitPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 400, Short.MAX_VALUE)
247  .addGroup(layout.createSequentialGroup()
248  .addContainerGap()
249  .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
250  .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
251  .addComponent(searchAddButton)
252  .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 220, Short.MAX_VALUE)
253  .addComponent(manageListsButton))
254  .addGroup(layout.createSequentialGroup()
255  .addComponent(ingestIndexLabel)
256  .addGap(0, 317, Short.MAX_VALUE)))
257  .addContainerGap())
258  );
259  layout.setVerticalGroup(
260  layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
261  .addGroup(layout.createSequentialGroup()
262  .addComponent(jSplitPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 268, javax.swing.GroupLayout.PREFERRED_SIZE)
263  .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 7, Short.MAX_VALUE)
264  .addComponent(ingestIndexLabel)
265  .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
266  .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
267  .addComponent(manageListsButton)
268  .addComponent(searchAddButton))
269  .addContainerGap())
270  );
271  }// </editor-fold>//GEN-END:initComponents
272 
273  private void manageListsButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_manageListsButtonActionPerformed
274  SystemAction.get(KeywordSearchConfigurationAction.class).performAction();
275  }//GEN-LAST:event_manageListsButtonActionPerformed
276 
277  private void searchAddButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_searchAddButtonActionPerformed
278  // TODO add your handling code here:
279  }//GEN-LAST:event_searchAddButtonActionPerformed
280 
281  // Variables declaration - do not modify//GEN-BEGIN:variables
282  private javax.swing.JLabel ingestIndexLabel;
283  private javax.swing.JSplitPane jSplitPane1;
284  private javax.swing.JTable keywordsTable;
285  private javax.swing.JScrollPane leftPane;
286  private javax.swing.JTable listsTable;
287  private javax.swing.JButton manageListsButton;
288  private javax.swing.JScrollPane rightPane;
289  private javax.swing.JButton searchAddButton;
290  // End of variables declaration//GEN-END:variables
291 
292  private void searchAction(ActionEvent e) {
293  setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
294 
295  try {
296  search();
297  } finally {
298  setCursor(null);
299  }
300  }
301 
302  @Override
303  List<KeywordList> getKeywordLists() {
304  return listsTableModel.getSelectedListsL();
305  }
306 
307 
308  void addSearchButtonActionListener(ActionListener al) {
309  searchAddButton.addActionListener(al);
310  }
311 
312  private class KeywordListsTableModel extends AbstractTableModel {
313  //data
314 
315  private XmlKeywordSearchList listsHandle = XmlKeywordSearchList.getCurrent();
316  private List<ListTableEntry> listData = new ArrayList<>();
317 
318  @Override
319  public int getColumnCount() {
320  return 2;
321  }
322 
323  @Override
324  public int getRowCount() {
325  return listData.size();
326  }
327 
328  @Override
329  public String getColumnName(int column) {
330  String ret = null;
331  switch (column) {
332  case 0:
333  ret = NbBundle.getMessage(this.getClass(), "KeywordSearch.selectedColLbl");
334  break;
335  case 1:
336  ret = NbBundle.getMessage(this.getClass(), "KeywordSearch.nameColLbl");
337  break;
338  default:
339  break;
340  }
341  return ret;
342  }
343 
344  @Override
345  public Object getValueAt(int rowIndex, int columnIndex) {
346  Object ret = null;
347  ListTableEntry entry = null;
348  //iterate until row
349  Iterator<ListTableEntry> it = listData.iterator();
350  for (int i = 0; i <= rowIndex; ++i) {
351  entry = it.next();
352  }
353  if (null != entry) {
354  switch (columnIndex) {
355  case 0:
356  ret = (Object) entry.selected;
357  break;
358  case 1:
359  ret = (Object) entry.name;
360  break;
361  default:
362  break;
363  }
364  }
365  return ret;
366  }
367 
368  @Override
369  public boolean isCellEditable(int rowIndex, int columnIndex) {
370  return (columnIndex == 0 && !ingestRunning);
371  }
372 
373  @Override
374  public void setValueAt(Object aValue, int rowIndex, int columnIndex) {
375  if (columnIndex == 0) {
376  ListTableEntry entry = null;
377  Iterator<ListTableEntry> it = listData.iterator();
378  for (int i = 0; i <= rowIndex; i++) {
379  entry = it.next();
380  }
381  if (entry != null) {
382  entry.selected = (Boolean) aValue;
383  if (ingestRunning) {
384  //updateUseForIngest(getListAt(rowIndex), (Boolean) aValue);
385  }
386  }
387 
388  }
389  }
390 
391  @Override
392  public Class<?> getColumnClass(int c) {
393  return getValueAt(0, c).getClass();
394  }
395 
396  List<String> getAllLists() {
397  List<String> ret = new ArrayList<>();
398  for (ListTableEntry e : listData) {
399  ret.add(e.name);
400  }
401  return ret;
402  }
403 
404  KeywordList getListAt(int rowIndex) {
405  return listsHandle.getList((String) getValueAt(rowIndex, 1));
406  }
407 
408  List<String> getSelectedLists() {
409  List<String> ret = new ArrayList<>();
410  for (ListTableEntry e : listData) {
411  if (e.selected) {
412  ret.add(e.name);
413  }
414  }
415  return ret;
416  }
417 
418  List<KeywordList> getSelectedListsL() {
419  List<KeywordList> ret = new ArrayList<>();
420  for (String s : getSelectedLists()) {
421  ret.add(listsHandle.getList(s));
422  }
423  return ret;
424  }
425 
426  boolean listExists(String list) {
427  List<String> all = getAllLists();
428  return all.contains(list);
429  }
430 
431  //resync model from handle, then update table
432  void resync() {
433  listData.clear();
434  addLists(listsHandle.getListsL());
435  fireTableDataChanged();
436  }
437 
438  //add lists to the model
439  private void addLists(List<KeywordList> lists) {
440  for (KeywordList list : lists) {
441  if (!listExists(list.getName())) {
442  listData.add(new ListTableEntry(list, ingestRunning));
443  }
444  }
445  }
446 
447  //single model entry
448  private class ListTableEntry implements Comparable<ListTableEntry> {
449 
450  String name;
451  Boolean selected;
452 
453  ListTableEntry(KeywordList list, boolean ingestRunning) {
454  this.name = list.getName();
455  if (ingestRunning) {
456  this.selected = list.getUseForIngest();
457  } else {
458  this.selected = false;
459  }
460  }
461 
462  @Override
463  public int compareTo(ListTableEntry e) {
464  return this.name.compareTo(e.name);
465  }
466  }
467  }
468 
469  private class KeywordsTableModel extends AbstractTableModel {
470 
471  List<KeywordTableEntry> listData = new ArrayList<>();
472 
473  @Override
474  public int getRowCount() {
475  return listData.size();
476  }
477 
478  @Override
479  public int getColumnCount() {
480  return 2;
481  }
482 
483  @Override
484  public String getColumnName(int column) {
485  String ret = null;
486  switch (column) {
487  case 0:
488  ret = NbBundle.getMessage(this.getClass(), "KeywordSearch.nameColLbl");
489  break;
490  case 1:
491  ret = NbBundle.getMessage(this.getClass(), "KeywordSearch.regExColLbl");
492  break;
493  default:
494  break;
495  }
496  return ret;
497  }
498 
499  @Override
500  public Object getValueAt(int rowIndex, int columnIndex) {
501  Object ret = null;
502  KeywordTableEntry entry = null;
503  //iterate until row
504  Iterator<KeywordTableEntry> it = listData.iterator();
505  for (int i = 0; i <= rowIndex; ++i) {
506  entry = it.next();
507  }
508  if (null != entry) {
509  switch (columnIndex) {
510  case 0:
511  ret = (Object) entry.name;
512  break;
513  case 1:
514  ret = (Object) entry.regex;
515  break;
516  default:
517  break;
518  }
519  }
520  return ret;
521  }
522 
523  @Override
524  public boolean isCellEditable(int rowIndex, int columnIndex) {
525  return false;
526  }
527 
528  @Override
529  public void setValueAt(Object aValue, int rowIndex, int columnIndex) {
530  }
531 
532  @Override
533  public Class<?> getColumnClass(int c) {
534  return getValueAt(0, c).getClass();
535  }
536 
537  void resync(KeywordList list) {
538  listData.clear();
539  for (Keyword k : list.getKeywords()) {
540  listData.add(new KeywordTableEntry(k));
541  }
542  fireTableDataChanged();
543  }
544 
545  void deleteAll() {
546  listData.clear();
547  fireTableDataChanged();
548  }
549 
550  //single model entry
551  private class KeywordTableEntry implements Comparable<KeywordTableEntry> {
552 
553  String name;
554  Boolean regex;
555 
556  KeywordTableEntry(Keyword keyword) {
557  this.name = keyword.getQuery();
558  this.regex = !keyword.isLiteral();
559  }
560 
561  @Override
562  public int compareTo(KeywordTableEntry e) {
563  return this.name.compareTo(e.name);
564  }
565  }
566  }
567 
568  private class LeftCheckBoxRenderer extends JCheckBox implements TableCellRenderer {
569 
570  @Override
572  JTable table, Object value,
573  boolean isSelected, boolean hasFocus,
574  int row, int column) {
575 
576  this.setHorizontalAlignment(JCheckBox.CENTER);
577  this.setVerticalAlignment(JCheckBox.CENTER);
578 
579  setEnabled(!ingestRunning);
580 
581  boolean selected = (Boolean) table.getModel().getValueAt(row, 0);
582  setSelected(selected);
583 
584  if (isSelected) {
585  setBackground(listsTable.getSelectionBackground());
586  } else {
587  setBackground(listsTable.getBackground());
588  }
589 
590  return this;
591  }
592  }
593 
594  private class RightCheckBoxRenderer extends JCheckBox implements TableCellRenderer {
595 
596  @Override
598  JTable table, Object value,
599  boolean isSelected, boolean hasFocus,
600  int row, int column) {
601 
602  this.setHorizontalAlignment(JCheckBox.CENTER);
603  this.setVerticalAlignment(JCheckBox.CENTER);
604 
605  Boolean selected = (Boolean) table.getModel().getValueAt(row, 1);
606  setSelected(selected);
607  if (isSelected) {
608  setBackground(keywordsTable.getSelectionBackground());
609  } else {
610  setBackground(keywordsTable.getBackground());
611  }
612  setEnabled(false);
613 
614  return this;
615  }
616  }
617 }
Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column)
Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column)

Copyright © 2012-2015 Basis Technology. Generated on: Mon Oct 19 2015
This work is licensed under a Creative Commons Attribution-Share Alike 3.0 United States License.