Autopsy  4.6.0
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-2015 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 package org.sleuthkit.autopsy.keywordsearch;
20 
21 import java.awt.*;
22 import java.awt.event.ActionEvent;
23 import java.awt.event.ActionListener;
24 import java.beans.PropertyChangeEvent;
25 import java.beans.PropertyChangeListener;
26 import java.util.ArrayList;
27 import java.util.Iterator;
28 import java.util.List;
29 import java.util.logging.Level;
30 import javax.swing.JCheckBox;
31 import javax.swing.JTable;
32 import javax.swing.ListSelectionModel;
33 import javax.swing.event.ListSelectionEvent;
34 import javax.swing.event.ListSelectionListener;
35 import javax.swing.table.AbstractTableModel;
36 import javax.swing.table.TableCellRenderer;
37 import javax.swing.table.TableColumn;
38 import org.openide.util.NbBundle;
39 import org.openide.util.actions.SystemAction;
42 
47 @SuppressWarnings("PMD.SingularField") // UI widgets cause lots of false positives
48 class DropdownListSearchPanel extends AdHocSearchPanel {
49 
50  private static final Logger logger = Logger.getLogger(DropdownListSearchPanel.class.getName());
51  private static DropdownListSearchPanel instance;
52  private XmlKeywordSearchList loader;
53  private final KeywordListsTableModel listsTableModel;
54  private final 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.60)));
95  } else {
96  column.setPreferredWidth(((int) (rightWidth * 0.38)));
97  }
98  }
99 
100  loader = XmlKeywordSearchList.getCurrent();
101  listsTable.getSelectionModel().addListSelectionListener(new ListSelectionListener() {
102  @Override
103  public void valueChanged(ListSelectionEvent e) {
104  ListSelectionModel listSelectionModel = (ListSelectionModel) e.getSource();
105  if (!listSelectionModel.isSelectionEmpty()) {
106  int index = listSelectionModel.getMinSelectionIndex();
107  KeywordList list = listsTableModel.getListAt(index);
108  keywordsTableModel.resync(list);
109  } else {
110  keywordsTableModel.deleteAll();
111  }
112  }
113  });
114 
115  ingestRunning = IngestManager.getInstance().isIngestRunning();
116  updateComponents();
117 
118  IngestManager.getInstance().addIngestJobEventListener(new PropertyChangeListener() {
119  @Override
120  public void propertyChange(PropertyChangeEvent evt) {
121  Object source = evt.getSource();
122  if (source instanceof String && ((String) source).equals("LOCAL")) { //NON-NLS
123  EventQueue.invokeLater(() -> {
124  ingestRunning = IngestManager.getInstance().isIngestRunning();
125  updateComponents();
126  });
127  }
128  }
129  });
130 
131  searchAddListener = new ActionListener() {
132  @Override
133  public void actionPerformed(ActionEvent e) {
134  if (ingestRunning) {
135  IngestSearchRunner.getInstance().addKeywordListsToAllJobs(listsTableModel.getSelectedLists());
136  logger.log(Level.INFO, "Submitted enqueued lists to ingest"); //NON-NLS
137  } else {
138  searchAction(e);
139  }
140  }
141  };
142 
143  searchAddButton.addActionListener(searchAddListener);
144  }
145 
146  private void updateComponents() {
147  ingestRunning = IngestManager.getInstance().isIngestRunning();
148  if (ingestRunning) {
149  searchAddButton.setText(NbBundle.getMessage(this.getClass(), "KeywordSearchListsViewerPanel.initIngest.addIngestTitle"));
150  searchAddButton.setToolTipText(NbBundle.getMessage(this.getClass(), "KeywordSearchListsViewerPanel.initIngest.addIngestMsg"));
151 
152  } else {
153  searchAddButton.setText(NbBundle.getMessage(this.getClass(), "KeywordSearchListsViewerPanel.initIngest.searchIngestTitle"));
154  searchAddButton.setToolTipText(NbBundle.getMessage(this.getClass(), "KeywordSearchListsViewerPanel.initIngest.addIdxSearchMsg"));
155  }
156  listsTableModel.resync();
157  updateIngestIndexLabel();
158  }
159 
160  private void updateIngestIndexLabel() {
161  if (ingestRunning) {
162  ingestIndexLabel.setText(NbBundle.getMessage(this.getClass(), "KeywordSearchListsViewerPanel.initIngest.ongoingIngestMsg", filesIndexed));
163  } else {
164  ingestIndexLabel.setText(NbBundle.getMessage(this.getClass(), "KeywordSearchListsViewerPanel.initIngest.fileIndexCtMsg", filesIndexed));
165  }
166  }
167 
168  @Override
169  protected void postFilesIndexedChange() {
170  updateIngestIndexLabel();
171  }
172 
176  void resync() {
177  listsTableModel.resync();
178  }
179 
185  @SuppressWarnings("unchecked")
186  // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
187  private void initComponents() {
188 
189  jSplitPane1 = new javax.swing.JSplitPane();
190  leftPane = new javax.swing.JScrollPane();
191  listsTable = new javax.swing.JTable();
192  rightPane = new javax.swing.JScrollPane();
193  keywordsTable = new javax.swing.JTable();
194  manageListsButton = new javax.swing.JButton();
195  searchAddButton = new javax.swing.JButton();
196  ingestIndexLabel = new javax.swing.JLabel();
197 
198  setFont(getFont().deriveFont(getFont().getStyle() & ~java.awt.Font.BOLD, 11));
199 
200  jSplitPane1.setFont(leftPane.getFont());
201 
202  leftPane.setFont(leftPane.getFont().deriveFont(leftPane.getFont().getStyle() & ~java.awt.Font.BOLD, 11));
203  leftPane.setMinimumSize(new java.awt.Dimension(150, 23));
204 
205  listsTable.setBackground(new java.awt.Color(240, 240, 240));
206  listsTable.setFont(listsTable.getFont().deriveFont(listsTable.getFont().getStyle() & ~java.awt.Font.BOLD, 11));
207  listsTable.setModel(listsTableModel);
208  listsTable.setShowHorizontalLines(false);
209  listsTable.setShowVerticalLines(false);
210  listsTable.getTableHeader().setReorderingAllowed(false);
211  leftPane.setViewportView(listsTable);
212 
213  jSplitPane1.setLeftComponent(leftPane);
214 
215  rightPane.setFont(rightPane.getFont().deriveFont(rightPane.getFont().getStyle() & ~java.awt.Font.BOLD, 11));
216 
217  keywordsTable.setBackground(new java.awt.Color(240, 240, 240));
218  keywordsTable.setFont(keywordsTable.getFont().deriveFont(keywordsTable.getFont().getStyle() & ~java.awt.Font.BOLD, 11));
219  keywordsTable.setModel(keywordsTableModel);
220  keywordsTable.setGridColor(new java.awt.Color(153, 153, 153));
221  rightPane.setViewportView(keywordsTable);
222 
223  jSplitPane1.setRightComponent(rightPane);
224 
225  manageListsButton.setFont(manageListsButton.getFont().deriveFont(manageListsButton.getFont().getStyle() & ~java.awt.Font.BOLD, 11));
226  manageListsButton.setText(org.openide.util.NbBundle.getMessage(DropdownListSearchPanel.class, "KeywordSearchListsViewerPanel.manageListsButton.text")); // NOI18N
227  manageListsButton.setToolTipText(org.openide.util.NbBundle.getMessage(DropdownListSearchPanel.class, "KeywordSearchListsViewerPanel.manageListsButton.toolTipText")); // NOI18N
228  manageListsButton.addActionListener(new java.awt.event.ActionListener() {
229  public void actionPerformed(java.awt.event.ActionEvent evt) {
230  manageListsButtonActionPerformed(evt);
231  }
232  });
233 
234  searchAddButton.setFont(searchAddButton.getFont().deriveFont(searchAddButton.getFont().getStyle() & ~java.awt.Font.BOLD, 11));
235  searchAddButton.setText(org.openide.util.NbBundle.getMessage(DropdownListSearchPanel.class, "KeywordSearchListsViewerPanel.searchAddButton.text")); // NOI18N
236  searchAddButton.addActionListener(new java.awt.event.ActionListener() {
237  public void actionPerformed(java.awt.event.ActionEvent evt) {
238  searchAddButtonActionPerformed(evt);
239  }
240  });
241 
242  ingestIndexLabel.setFont(ingestIndexLabel.getFont().deriveFont(ingestIndexLabel.getFont().getStyle() & ~java.awt.Font.BOLD, 10));
243  ingestIndexLabel.setText(org.openide.util.NbBundle.getMessage(DropdownListSearchPanel.class, "KeywordSearchListsViewerPanel.ingestIndexLabel.text")); // NOI18N
244 
245  javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
246  this.setLayout(layout);
247  layout.setHorizontalGroup(
248  layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
249  .addComponent(jSplitPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 400, Short.MAX_VALUE)
250  .addGroup(layout.createSequentialGroup()
251  .addContainerGap()
252  .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
253  .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
254  .addComponent(searchAddButton)
255  .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 220, Short.MAX_VALUE)
256  .addComponent(manageListsButton))
257  .addGroup(layout.createSequentialGroup()
258  .addComponent(ingestIndexLabel)
259  .addGap(0, 317, Short.MAX_VALUE)))
260  .addContainerGap())
261  );
262  layout.setVerticalGroup(
263  layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
264  .addGroup(layout.createSequentialGroup()
265  .addComponent(jSplitPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 268, javax.swing.GroupLayout.PREFERRED_SIZE)
266  .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 7, Short.MAX_VALUE)
267  .addComponent(ingestIndexLabel)
268  .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
269  .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
270  .addComponent(manageListsButton)
271  .addComponent(searchAddButton))
272  .addContainerGap())
273  );
274  }// </editor-fold>//GEN-END:initComponents
275 
276  private void manageListsButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_manageListsButtonActionPerformed
277  SystemAction.get(KeywordSearchConfigurationAction.class).performAction();
278  }//GEN-LAST:event_manageListsButtonActionPerformed
279 
280  private void searchAddButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_searchAddButtonActionPerformed
281  // TODO add your handling code here:
282  }//GEN-LAST:event_searchAddButtonActionPerformed
283 
284  // Variables declaration - do not modify//GEN-BEGIN:variables
285  private javax.swing.JLabel ingestIndexLabel;
286  private javax.swing.JSplitPane jSplitPane1;
287  private javax.swing.JTable keywordsTable;
288  private javax.swing.JScrollPane leftPane;
289  private javax.swing.JTable listsTable;
290  private javax.swing.JButton manageListsButton;
291  private javax.swing.JScrollPane rightPane;
292  private javax.swing.JButton searchAddButton;
293  // End of variables declaration//GEN-END:variables
294 
295  private void searchAction(ActionEvent e) {
296  setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
297 
298  try {
299  search();
300  } finally {
301  setCursor(null);
302  }
303  }
304 
305  @Override
306  List<KeywordList> getKeywordLists() {
307  return listsTableModel.getSelectedListsL();
308  }
309 
310  void addSearchButtonActionListener(ActionListener al) {
311  searchAddButton.addActionListener(al);
312  }
313 
314  private class KeywordListsTableModel extends AbstractTableModel {
315  //data
316 
317  private final XmlKeywordSearchList listsHandle = XmlKeywordSearchList.getCurrent();
318  private final List<ListTableEntry> listData = new ArrayList<>();
319 
320  @Override
321  public int getColumnCount() {
322  return 2;
323  }
324 
325  @Override
326  public int getRowCount() {
327  return listData.size();
328  }
329 
330  @Override
331  public String getColumnName(int column) {
332  String ret = null;
333  switch (column) {
334  case 0:
335  ret = NbBundle.getMessage(this.getClass(), "KeywordSearch.selectedColLbl");
336  break;
337  case 1:
338  ret = NbBundle.getMessage(this.getClass(), "KeywordSearch.nameColLbl");
339  break;
340  default:
341  break;
342  }
343  return ret;
344  }
345 
346  @Override
347  public Object getValueAt(int rowIndex, int columnIndex) {
348  Object ret = null;
349  ListTableEntry entry = null;
350  //iterate until row
351  Iterator<ListTableEntry> it = listData.iterator();
352  for (int i = 0; i <= rowIndex; ++i) {
353  entry = it.next();
354  }
355  if (null != entry) {
356  switch (columnIndex) {
357  case 0:
358  ret = (Object) entry.selected;
359  break;
360  case 1:
361  ret = (Object) entry.name;
362  break;
363  default:
364  break;
365  }
366  }
367  return ret;
368  }
369 
370  @Override
371  public boolean isCellEditable(int rowIndex, int columnIndex) {
372  return (columnIndex == 0 && !ingestRunning);
373  }
374 
375  @Override
376  public void setValueAt(Object aValue, int rowIndex, int columnIndex) {
377  if (columnIndex == 0) {
378  ListTableEntry entry = null;
379  Iterator<ListTableEntry> it = listData.iterator();
380  for (int i = 0; i <= rowIndex; i++) {
381  entry = it.next();
382  }
383  if (entry != null) {
384  entry.selected = (Boolean) aValue;
385  if (ingestRunning) {
386  //updateUseForIngest(getListAt(rowIndex), (Boolean) aValue);
387  }
388  }
389 
390  }
391  }
392 
393  @Override
394  public Class<?> getColumnClass(int c) {
395  return getValueAt(0, c).getClass();
396  }
397 
398  List<String> getAllLists() {
399  List<String> ret = new ArrayList<>();
400  for (ListTableEntry e : listData) {
401  ret.add(e.name);
402  }
403  return ret;
404  }
405 
406  KeywordList getListAt(int rowIndex) {
407  return listsHandle.getList((String) getValueAt(rowIndex, 1));
408  }
409 
410  List<String> getSelectedLists() {
411  List<String> ret = new ArrayList<>();
412  for (ListTableEntry e : listData) {
413  if (e.selected) {
414  ret.add(e.name);
415  }
416  }
417  return ret;
418  }
419 
420  List<KeywordList> getSelectedListsL() {
421  List<KeywordList> ret = new ArrayList<>();
422  for (String s : getSelectedLists()) {
423  ret.add(listsHandle.getList(s));
424  }
425  return ret;
426  }
427 
428  boolean listExists(String list) {
429  List<String> all = getAllLists();
430  return all.contains(list);
431  }
432 
433  //resync model from handle, then update table
434  void resync() {
435  listData.clear();
436  addLists(listsHandle.getListsL());
437  fireTableDataChanged();
438  }
439 
440  //add lists to the model
441  private void addLists(List<KeywordList> lists) {
442  for (KeywordList list : lists) {
443  if (!listExists(list.getName())) {
444  listData.add(new ListTableEntry(list, ingestRunning));
445  }
446  }
447  }
448 
449  //single model entry
450  private class ListTableEntry implements Comparable<ListTableEntry> {
451 
452  String name;
453  Boolean selected;
454 
455  ListTableEntry(KeywordList list, boolean ingestRunning) {
456  this.name = list.getName();
457  if (ingestRunning) {
458  this.selected = list.getUseForIngest();
459  } else {
460  this.selected = false;
461  }
462  }
463 
464  @Override
465  public int compareTo(ListTableEntry e) {
466  return this.name.compareTo(e.name);
467  }
468  }
469  }
470 
471  private class KeywordsTableModel extends AbstractTableModel {
472 
473  List<KeywordTableEntry> listData = new ArrayList<>();
474 
475  @Override
476  public int getRowCount() {
477  return listData.size();
478  }
479 
480  @Override
481  public int getColumnCount() {
482  return 2;
483  }
484 
485  @Override
486  public String getColumnName(int column) {
487  String ret = null;
488  switch (column) {
489  case 0:
490  ret = NbBundle.getMessage(this.getClass(), "KeywordSearch.nameColLbl");
491  break;
492  case 1:
493  ret = NbBundle.getMessage(this.getClass(), "KeywordSearch.typeColLbl");
494  break;
495  default:
496  break;
497  }
498  return ret;
499  }
500 
501  @Override
502  public Object getValueAt(int rowIndex, int columnIndex) {
503  Object ret = null;
504  KeywordTableEntry entry = null;
505  //iterate until row
506  Iterator<KeywordTableEntry> it = listData.iterator();
507  for (int i = 0; i <= rowIndex; ++i) {
508  entry = it.next();
509  }
510  if (null != entry) {
511  switch (columnIndex) {
512  case 0:
513  ret = (Object) entry.name;
514  break;
515  case 1:
516  ret = (Object) entry.keywordType;
517  break;
518  default:
519  break;
520  }
521  }
522  return ret;
523  }
524 
525  @Override
526  public boolean isCellEditable(int rowIndex, int columnIndex) {
527  return false;
528  }
529 
530  @Override
531  public void setValueAt(Object aValue, int rowIndex, int columnIndex) {
532  }
533 
534  @Override
535  public Class<?> getColumnClass(int c) {
536  return getValueAt(0, c).getClass();
537  }
538 
539  void resync(KeywordList list) {
540  listData.clear();
541  for (Keyword k : list.getKeywords()) {
542  listData.add(new KeywordTableEntry(k));
543  }
544  fireTableDataChanged();
545  }
546 
547  void deleteAll() {
548  listData.clear();
549  fireTableDataChanged();
550  }
551 
552  //single model entry
553  private class KeywordTableEntry implements Comparable<KeywordTableEntry> {
554 
555  String name;
556  String keywordType;
557 
558  KeywordTableEntry(Keyword keyword) {
559  this.name = keyword.getSearchTerm();
560  this.keywordType = keyword.getSearchTermType();
561  }
562 
563  @Override
564  public int compareTo(KeywordTableEntry e) {
565  return this.name.compareTo(e.name);
566  }
567  }
568  }
569 
570  private class LeftCheckBoxRenderer extends JCheckBox implements TableCellRenderer {
571 
572  @Override
574  JTable table, Object value,
575  boolean isSelected, boolean hasFocus,
576  int row, int column) {
577 
578  this.setHorizontalAlignment(JCheckBox.CENTER);
579  this.setVerticalAlignment(JCheckBox.CENTER);
580 
581  setEnabled(!ingestRunning);
582 
583  boolean selected = (Boolean) table.getModel().getValueAt(row, 0);
584  setSelected(selected);
585 
586  if (isSelected) {
587  setBackground(listsTable.getSelectionBackground());
588  } else {
589  setBackground(listsTable.getBackground());
590  }
591 
592  return this;
593  }
594  }
595 }
Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column)

Copyright © 2012-2016 Basis Technology. Generated on: Mon May 7 2018
This work is licensed under a Creative Commons Attribution-Share Alike 3.0 United States License.