19 package org.sleuthkit.autopsy.keywordsearch;
21 import java.awt.Component;
22 import java.awt.Cursor;
23 import java.awt.EventQueue;
24 import java.awt.event.ActionEvent;
25 import java.awt.event.ActionListener;
26 import java.beans.PropertyChangeEvent;
27 import java.beans.PropertyChangeListener;
28 import java.util.ArrayList;
29 import java.util.HashSet;
30 import java.util.Iterator;
31 import java.util.List;
33 import java.util.logging.Level;
34 import javax.swing.JCheckBox;
35 import javax.swing.JTable;
36 import javax.swing.ListSelectionModel;
37 import javax.swing.event.ListSelectionEvent;
38 import javax.swing.event.ListSelectionListener;
39 import javax.swing.table.AbstractTableModel;
40 import javax.swing.table.TableCellRenderer;
41 import javax.swing.table.TableColumn;
42 import org.openide.util.NbBundle;
43 import org.openide.util.actions.SystemAction;
51 @SuppressWarnings(
"PMD.SingularField")
52 class DropdownListSearchPanel extends AdHocSearchPanel {
54 private static final Logger logger = Logger.getLogger(DropdownListSearchPanel.class.getName());
55 private static DropdownListSearchPanel instance;
56 private XmlKeywordSearchList loader;
57 private final KeywordListsTableModel listsTableModel;
58 private final KeywordsTableModel keywordsTableModel;
59 private ActionListener searchAddListener;
60 private boolean ingestRunning;
65 private DropdownListSearchPanel() {
66 listsTableModel =
new KeywordListsTableModel();
67 keywordsTableModel =
new KeywordsTableModel();
69 customizeComponents();
70 dataSourceList.setModel(getDataSourceListModel());
72 dataSourceList.addListSelectionListener((ListSelectionEvent evt) -> {
73 firePropertyChange(Bundle.DropdownSingleTermSearchPanel_selected(), null, null);
77 static synchronized DropdownListSearchPanel getDefault() {
78 if (instance == null) {
79 instance =
new DropdownListSearchPanel();
84 private void customizeComponents() {
85 listsTable.setTableHeader(null);
86 listsTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
88 final int leftWidth = leftPane.getPreferredSize().width;
90 for (
int i = 0; i < listsTable.getColumnCount(); i++) {
91 column = listsTable.getColumnModel().getColumn(i);
93 column.setPreferredWidth(((
int) (leftWidth * 0.10)));
94 column.setCellRenderer(
new LeftCheckBoxRenderer());
96 column.setPreferredWidth(((
int) (leftWidth * 0.89)));
99 final int rightWidth = rightPane.getPreferredSize().width;
100 for (
int i = 0; i < keywordsTable.getColumnCount(); i++) {
101 column = keywordsTable.getColumnModel().getColumn(i);
103 column.setPreferredWidth(((
int) (rightWidth * 0.60)));
105 column.setPreferredWidth(((
int) (rightWidth * 0.38)));
109 loader = XmlKeywordSearchList.getCurrent();
110 listsTable.getSelectionModel().addListSelectionListener(
new ListSelectionListener() {
112 public void valueChanged(ListSelectionEvent e) {
113 ListSelectionModel listSelectionModel = (ListSelectionModel) e.getSource();
114 if (!listSelectionModel.isSelectionEmpty()) {
115 int index = listSelectionModel.getMinSelectionIndex();
116 KeywordList list = listsTableModel.getListAt(index);
117 keywordsTableModel.resync(list);
119 keywordsTableModel.deleteAll();
124 ingestRunning = IngestManager.getInstance().isIngestRunning();
127 IngestManager.getInstance().addIngestJobEventListener(
new PropertyChangeListener() {
129 public void propertyChange(PropertyChangeEvent evt) {
130 Object source = evt.getSource();
131 if (source instanceof String && ((String) source).equals(
"LOCAL")) {
132 EventQueue.invokeLater(() -> {
133 ingestRunning = IngestManager.getInstance().isIngestRunning();
140 searchAddListener =
new ActionListener() {
142 public void actionPerformed(ActionEvent e) {
144 IngestSearchRunner.getInstance().addKeywordListsToAllJobs(listsTableModel.getSelectedLists());
145 logger.log(Level.INFO,
"Submitted enqueued lists to ingest");
152 searchAddButton.addActionListener(searchAddListener);
155 private void updateComponents() {
156 ingestRunning = IngestManager.getInstance().isIngestRunning();
158 searchAddButton.setText(NbBundle.getMessage(
this.getClass(),
"KeywordSearchListsViewerPanel.initIngest.addIngestTitle"));
159 searchAddButton.setToolTipText(NbBundle.getMessage(
this.getClass(),
"KeywordSearchListsViewerPanel.initIngest.addIngestMsg"));
162 searchAddButton.setText(NbBundle.getMessage(
this.getClass(),
"KeywordSearchListsViewerPanel.initIngest.searchIngestTitle"));
163 searchAddButton.setToolTipText(NbBundle.getMessage(
this.getClass(),
"KeywordSearchListsViewerPanel.initIngest.addIdxSearchMsg"));
165 listsTableModel.resync();
166 updateIngestIndexLabel();
168 jSaveSearchResults.setSelected(
true);
171 private void updateIngestIndexLabel() {
173 ingestIndexLabel.setText(NbBundle.getMessage(
this.getClass(),
"KeywordSearchListsViewerPanel.initIngest.ongoingIngestMsg", filesIndexed));
175 ingestIndexLabel.setText(NbBundle.getMessage(
this.getClass(),
"KeywordSearchListsViewerPanel.initIngest.fileIndexCtMsg", filesIndexed));
180 protected void postFilesIndexedChange() {
181 updateIngestIndexLabel();
188 listsTableModel.resync();
196 @SuppressWarnings(
"unchecked")
198 private
void initComponents() {
200 jSplitPane1 =
new javax.swing.JSplitPane();
201 leftPane =
new javax.swing.JScrollPane();
202 listsTable =
new javax.swing.JTable();
203 rightPane =
new javax.swing.JScrollPane();
204 keywordsTable =
new javax.swing.JTable();
205 manageListsButton =
new javax.swing.JButton();
206 searchAddButton =
new javax.swing.JButton();
207 ingestIndexLabel =
new javax.swing.JLabel();
208 dataSourceCheckBox =
new javax.swing.JCheckBox();
209 jScrollPane1 =
new javax.swing.JScrollPane();
210 dataSourceList =
new javax.swing.JList<>();
211 jSaveSearchResults =
new javax.swing.JCheckBox();
213 setFont(getFont().deriveFont(getFont().getStyle() & ~java.awt.Font.BOLD, 11));
215 jSplitPane1.setFont(leftPane.getFont());
217 leftPane.setFont(leftPane.getFont().deriveFont(leftPane.getFont().getStyle() & ~java.awt.Font.BOLD, 11));
218 leftPane.setMinimumSize(
new java.awt.Dimension(150, 23));
220 listsTable.setBackground(
new java.awt.Color(240, 240, 240));
221 listsTable.setFont(listsTable.getFont().deriveFont(listsTable.getFont().getStyle() & ~java.awt.Font.BOLD, 11));
222 listsTable.setModel(listsTableModel);
223 listsTable.setShowHorizontalLines(
false);
224 listsTable.setShowVerticalLines(
false);
225 listsTable.getTableHeader().setReorderingAllowed(
false);
226 leftPane.setViewportView(listsTable);
228 jSplitPane1.setLeftComponent(leftPane);
230 rightPane.setFont(rightPane.getFont().deriveFont(rightPane.getFont().getStyle() & ~java.awt.Font.BOLD, 11));
232 keywordsTable.setBackground(
new java.awt.Color(240, 240, 240));
233 keywordsTable.setFont(keywordsTable.getFont().deriveFont(keywordsTable.getFont().getStyle() & ~java.awt.Font.BOLD, 11));
234 keywordsTable.setModel(keywordsTableModel);
235 keywordsTable.setGridColor(
new java.awt.Color(153, 153, 153));
236 rightPane.setViewportView(keywordsTable);
238 jSplitPane1.setRightComponent(rightPane);
240 manageListsButton.setFont(manageListsButton.getFont().deriveFont(manageListsButton.getFont().getStyle() & ~java.awt.Font.BOLD, 11));
241 manageListsButton.setText(
org.openide.util.NbBundle.getMessage(DropdownListSearchPanel.class,
"KeywordSearchListsViewerPanel.manageListsButton.text"));
242 manageListsButton.setToolTipText(
org.openide.util.NbBundle.getMessage(DropdownListSearchPanel.class,
"KeywordSearchListsViewerPanel.manageListsButton.toolTipText"));
243 manageListsButton.addActionListener(
new java.awt.event.ActionListener() {
244 public void actionPerformed(java.awt.event.ActionEvent evt) {
245 manageListsButtonActionPerformed(evt);
249 searchAddButton.setFont(searchAddButton.getFont().deriveFont(searchAddButton.getFont().getStyle() & ~java.awt.Font.BOLD, 11));
250 searchAddButton.setIcon(
new javax.swing.ImageIcon(getClass().getResource(
"/org/sleuthkit/autopsy/keywordsearch/search-icon.png")));
251 searchAddButton.setText(
org.openide.util.NbBundle.getMessage(DropdownListSearchPanel.class,
"KeywordSearchListsViewerPanel.searchAddButton.text"));
252 searchAddButton.addActionListener(
new java.awt.event.ActionListener() {
253 public void actionPerformed(java.awt.event.ActionEvent evt) {
254 searchAddButtonActionPerformed(evt);
258 ingestIndexLabel.setFont(ingestIndexLabel.getFont().deriveFont(ingestIndexLabel.getFont().getStyle() & ~java.awt.Font.BOLD, 10));
259 ingestIndexLabel.setText(
org.openide.util.NbBundle.getMessage(DropdownListSearchPanel.class,
"KeywordSearchListsViewerPanel.ingestIndexLabel.text"));
261 dataSourceCheckBox.setText(
org.openide.util.NbBundle.getMessage(DropdownListSearchPanel.class,
"DropdownListSearchPanel.dataSourceCheckBox.text"));
262 dataSourceCheckBox.addActionListener(
new java.awt.event.ActionListener() {
263 public void actionPerformed(java.awt.event.ActionEvent evt) {
264 dataSourceCheckBoxActionPerformed(evt);
268 dataSourceList.setMinimumSize(
new java.awt.Dimension(0, 200));
269 jScrollPane1.setViewportView(dataSourceList);
271 jSaveSearchResults.setText(
org.openide.util.NbBundle.getMessage(DropdownListSearchPanel.class,
"DropdownListSearchPanel.jSaveSearchResults.text"));
272 jSaveSearchResults.setToolTipText(
org.openide.util.NbBundle.getMessage(DropdownListSearchPanel.class,
"DropdownListSearchPanel.jSaveSearchResults.toolTipText"));
274 javax.swing.GroupLayout layout =
new javax.swing.GroupLayout(
this);
275 this.setLayout(layout);
276 layout.setHorizontalGroup(
277 layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
278 .addComponent(jSplitPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 0, Short.MAX_VALUE)
279 .addComponent(jScrollPane1)
280 .addGroup(layout.createSequentialGroup()
281 .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
282 .addComponent(dataSourceCheckBox)
283 .addComponent(jSaveSearchResults)
284 .addGroup(layout.createSequentialGroup()
285 .addComponent(searchAddButton)
286 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
287 .addComponent(manageListsButton)
288 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
289 .addComponent(ingestIndexLabel)))
290 .addGap(0, 120, Short.MAX_VALUE))
293 layout.linkSize(javax.swing.SwingConstants.HORIZONTAL,
new java.awt.Component[] {manageListsButton, searchAddButton});
295 layout.setVerticalGroup(
296 layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
297 .addGroup(layout.createSequentialGroup()
298 .addComponent(jSplitPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 183, javax.swing.GroupLayout.PREFERRED_SIZE)
299 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
300 .addComponent(dataSourceCheckBox)
301 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
302 .addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 65, javax.swing.GroupLayout.PREFERRED_SIZE)
303 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
304 .addComponent(jSaveSearchResults)
305 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
306 .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
307 .addComponent(manageListsButton)
308 .addComponent(searchAddButton)
309 .addComponent(ingestIndexLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 13, javax.swing.GroupLayout.PREFERRED_SIZE))
314 private void manageListsButtonActionPerformed(java.awt.event.ActionEvent evt) {
315 SystemAction.get(KeywordSearchConfigurationAction.class).performAction();
318 private void dataSourceCheckBoxActionPerformed(java.awt.event.ActionEvent evt) {
319 updateDataSourceListModel();
322 private void searchAddButtonActionPerformed(java.awt.event.ActionEvent evt) {
327 private javax.swing.JCheckBox dataSourceCheckBox;
328 private javax.swing.JList<String> dataSourceList;
329 private javax.swing.JLabel ingestIndexLabel;
330 private javax.swing.JCheckBox jSaveSearchResults;
331 private javax.swing.JScrollPane jScrollPane1;
332 private javax.swing.JSplitPane jSplitPane1;
333 private javax.swing.JTable keywordsTable;
334 private javax.swing.JScrollPane leftPane;
335 private javax.swing.JTable listsTable;
336 private javax.swing.JButton manageListsButton;
337 private javax.swing.JScrollPane rightPane;
338 private javax.swing.JButton searchAddButton;
341 private void searchAction(ActionEvent e) {
342 setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
345 search(jSaveSearchResults.isSelected());
352 List<KeywordList> getKeywordLists() {
353 return listsTableModel.getSelectedListsL();
356 void addSearchButtonActionListener(ActionListener al) {
357 searchAddButton.addActionListener(al);
365 Set<Long> getDataSourcesSelected() {
366 Set<Long> dataSourceObjIdSet =
new HashSet<>();
367 for (Long key : getDataSourceMap().keySet()) {
368 String value = getDataSourceMap().get(key);
369 for (String dataSource : this.dataSourceList.getSelectedValuesList()) {
370 if (value.equals(dataSource)) {
371 dataSourceObjIdSet.add(key);
375 return dataSourceObjIdSet;
381 private final XmlKeywordSearchList listsHandle = XmlKeywordSearchList.getCurrent();
382 private final List<ListTableEntry> listData =
new ArrayList<>();
391 return listData.size();
399 ret = NbBundle.getMessage(this.getClass(),
"KeywordSearch.selectedColLbl");
402 ret = NbBundle.getMessage(this.getClass(),
"KeywordSearch.nameColLbl");
415 Iterator<ListTableEntry> it = listData.iterator();
416 for (
int i = 0; i <= rowIndex; ++i) {
420 switch (columnIndex) {
422 ret = (Object) entry.selected;
425 ret = (Object) entry.name;
436 return (columnIndex == 0 && !ingestRunning);
440 public void setValueAt(Object aValue,
int rowIndex,
int columnIndex) {
441 if (columnIndex == 0) {
443 Iterator<ListTableEntry> it = listData.iterator();
444 for (
int i = 0; i <= rowIndex; i++) {
448 entry.selected = (Boolean) aValue;
459 return getValueAt(0, c).getClass();
462 List<String> getAllLists() {
463 List<String> ret =
new ArrayList<>();
464 for (ListTableEntry e : listData) {
470 KeywordList getListAt(
int rowIndex) {
471 return listsHandle.getList((String) getValueAt(rowIndex, 1));
474 List<String> getSelectedLists() {
475 List<String> ret =
new ArrayList<>();
476 for (ListTableEntry e : listData) {
484 List<KeywordList> getSelectedListsL() {
485 List<KeywordList> ret =
new ArrayList<>();
486 for (String s : getSelectedLists()) {
487 ret.add(listsHandle.getList(s));
492 boolean listExists(String list) {
493 List<String> all = getAllLists();
494 return all.contains(list);
500 addLists(listsHandle.getListsL());
501 fireTableDataChanged();
507 if (!listExists(list.getName())) {
520 this.name = list.getName();
522 this.selected = list.getUseForIngest();
524 this.selected =
false;
530 return this.name.compareTo(e.name);
537 List<KeywordTableEntry> listData =
new ArrayList<>();
541 return listData.size();
554 ret = NbBundle.getMessage(this.getClass(),
"KeywordSearch.nameColLbl");
557 ret = NbBundle.getMessage(this.getClass(),
"KeywordSearch.typeColLbl");
570 Iterator<KeywordTableEntry> it = listData.iterator();
571 for (
int i = 0; i <= rowIndex; ++i) {
575 switch (columnIndex) {
577 ret = (Object) entry.name;
580 ret = (Object) entry.keywordType;
595 public void setValueAt(Object aValue,
int rowIndex,
int columnIndex) {
600 return getValueAt(0, c).getClass();
605 for (Keyword k : list.getKeywords()) {
606 listData.add(
new KeywordTableEntry(k));
608 fireTableDataChanged();
613 fireTableDataChanged();
623 this.name = keyword.getSearchTerm();
624 this.keywordType = keyword.getSearchTermType();
629 return this.name.compareTo(e.name);
638 JTable table, Object value,
639 boolean isSelected,
boolean hasFocus,
640 int row,
int column) {
642 this.setHorizontalAlignment(JCheckBox.CENTER);
643 this.setVerticalAlignment(JCheckBox.CENTER);
645 setEnabled(!ingestRunning);
647 boolean selected = (Boolean) table.getModel().getValueAt(row, 0);
648 setSelected(selected);
651 setBackground(listsTable.getSelectionBackground());
653 setBackground(listsTable.getBackground());
663 @NbBundle.Messages({
"DropdownListSearchPanel.selected=Ad Hoc Search data source filter is selected"})
664 void updateDataSourceListModel() {
665 getDataSourceListModel().removeAllElements();
666 for (String dsName : getDataSourceArray()) {
667 getDataSourceListModel().addElement(dsName);
669 setComponentsEnabled();
670 firePropertyChange(Bundle.DropdownListSearchPanel_selected(), null, null);
677 private void setComponentsEnabled() {
679 if (getDataSourceListModel().size() > 1) {
680 this.dataSourceCheckBox.setEnabled(
true);
682 boolean enabled = this.dataSourceCheckBox.isSelected();
683 this.dataSourceList.setEnabled(enabled);
685 this.dataSourceList.setSelectionInterval(0, this.dataSourceList.getModel().getSize()-1);
687 this.dataSourceList.setSelectedIndices(
new int[0]);
690 this.dataSourceCheckBox.setEnabled(
false);
691 this.dataSourceCheckBox.setSelected(
false);
692 this.dataSourceList.setEnabled(
false);
693 this.dataSourceList.setSelectedIndices(
new int[0]);
void setValueAt(Object aValue, int rowIndex, int columnIndex)
String getColumnName(int column)
int compareTo(ListTableEntry e)
boolean isCellEditable(int rowIndex, int columnIndex)
Class<?> getColumnClass(int c)
void addLists(List< KeywordList > lists)
boolean isCellEditable(int rowIndex, int columnIndex)
Class<?> getColumnClass(int c)
Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column)
int compareTo(KeywordTableEntry e)
String getColumnName(int column)
Object getValueAt(int rowIndex, int columnIndex)
void setValueAt(Object aValue, int rowIndex, int columnIndex)
Object getValueAt(int rowIndex, int columnIndex)