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

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