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));
219 leftPane.setOpaque(
false);
221 listsTable.setBackground(
new java.awt.Color(240, 240, 240));
222 listsTable.setFont(listsTable.getFont().deriveFont(listsTable.getFont().getStyle() & ~java.awt.Font.BOLD, 11));
223 listsTable.setModel(listsTableModel);
224 listsTable.setShowHorizontalLines(
false);
225 listsTable.setShowVerticalLines(
false);
226 listsTable.getTableHeader().setReorderingAllowed(
false);
227 leftPane.setViewportView(listsTable);
229 jSplitPane1.setLeftComponent(leftPane);
231 rightPane.setFont(rightPane.getFont().deriveFont(rightPane.getFont().getStyle() & ~java.awt.Font.BOLD, 11));
232 rightPane.setOpaque(
false);
234 keywordsTable.setBackground(
new java.awt.Color(240, 240, 240));
235 keywordsTable.setFont(keywordsTable.getFont().deriveFont(keywordsTable.getFont().getStyle() & ~java.awt.Font.BOLD, 11));
236 keywordsTable.setModel(keywordsTableModel);
237 keywordsTable.setGridColor(
new java.awt.Color(153, 153, 153));
238 rightPane.setViewportView(keywordsTable);
240 jSplitPane1.setRightComponent(rightPane);
242 manageListsButton.setFont(manageListsButton.getFont().deriveFont(manageListsButton.getFont().getStyle() & ~java.awt.Font.BOLD, 11));
243 manageListsButton.setText(
org.openide.util.NbBundle.getMessage(DropdownListSearchPanel.class,
"KeywordSearchListsViewerPanel.manageListsButton.text"));
244 manageListsButton.setToolTipText(
org.openide.util.NbBundle.getMessage(DropdownListSearchPanel.class,
"KeywordSearchListsViewerPanel.manageListsButton.toolTipText"));
245 manageListsButton.addActionListener(
new java.awt.event.ActionListener() {
246 public void actionPerformed(java.awt.event.ActionEvent evt) {
247 manageListsButtonActionPerformed(evt);
251 searchAddButton.setFont(searchAddButton.getFont().deriveFont(searchAddButton.getFont().getStyle() & ~java.awt.Font.BOLD, 11));
252 searchAddButton.setIcon(
new javax.swing.ImageIcon(getClass().getResource(
"/org/sleuthkit/autopsy/keywordsearch/search-icon.png")));
253 searchAddButton.setText(
org.openide.util.NbBundle.getMessage(DropdownListSearchPanel.class,
"KeywordSearchListsViewerPanel.searchAddButton.text"));
254 searchAddButton.addActionListener(
new java.awt.event.ActionListener() {
255 public void actionPerformed(java.awt.event.ActionEvent evt) {
256 searchAddButtonActionPerformed(evt);
260 ingestIndexLabel.setFont(ingestIndexLabel.getFont().deriveFont(ingestIndexLabel.getFont().getStyle() & ~java.awt.Font.BOLD, 10));
261 ingestIndexLabel.setText(
org.openide.util.NbBundle.getMessage(DropdownListSearchPanel.class,
"KeywordSearchListsViewerPanel.ingestIndexLabel.text"));
263 dataSourceCheckBox.setText(
org.openide.util.NbBundle.getMessage(DropdownListSearchPanel.class,
"DropdownListSearchPanel.dataSourceCheckBox.text"));
264 dataSourceCheckBox.addActionListener(
new java.awt.event.ActionListener() {
265 public void actionPerformed(java.awt.event.ActionEvent evt) {
266 dataSourceCheckBoxActionPerformed(evt);
270 dataSourceList.setMinimumSize(
new java.awt.Dimension(0, 200));
271 jScrollPane1.setViewportView(dataSourceList);
273 jSaveSearchResults.setText(
org.openide.util.NbBundle.getMessage(DropdownListSearchPanel.class,
"DropdownListSearchPanel.jSaveSearchResults.text"));
274 jSaveSearchResults.setToolTipText(
org.openide.util.NbBundle.getMessage(DropdownListSearchPanel.class,
"DropdownListSearchPanel.jSaveSearchResults.toolTipText"));
276 javax.swing.GroupLayout layout =
new javax.swing.GroupLayout(
this);
277 this.setLayout(layout);
278 layout.setHorizontalGroup(
279 layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
280 .addComponent(jSplitPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 0, Short.MAX_VALUE)
281 .addComponent(jScrollPane1)
282 .addGroup(layout.createSequentialGroup()
283 .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
284 .addComponent(dataSourceCheckBox)
285 .addComponent(jSaveSearchResults)
286 .addGroup(layout.createSequentialGroup()
287 .addComponent(searchAddButton)
288 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
289 .addComponent(manageListsButton)
290 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
291 .addComponent(ingestIndexLabel)))
292 .addGap(0, 120, Short.MAX_VALUE))
295 layout.linkSize(javax.swing.SwingConstants.HORIZONTAL,
new java.awt.Component[] {manageListsButton, searchAddButton});
297 layout.setVerticalGroup(
298 layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
299 .addGroup(layout.createSequentialGroup()
300 .addComponent(jSplitPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 183, javax.swing.GroupLayout.PREFERRED_SIZE)
301 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
302 .addComponent(dataSourceCheckBox)
303 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
304 .addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 65, javax.swing.GroupLayout.PREFERRED_SIZE)
305 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
306 .addComponent(jSaveSearchResults)
307 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
308 .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
309 .addComponent(manageListsButton)
310 .addComponent(searchAddButton)
311 .addComponent(ingestIndexLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 13, javax.swing.GroupLayout.PREFERRED_SIZE))
316 private void manageListsButtonActionPerformed(java.awt.event.ActionEvent evt) {
317 SystemAction.get(KeywordSearchConfigurationAction.class).performAction();
320 private void dataSourceCheckBoxActionPerformed(java.awt.event.ActionEvent evt) {
321 updateDataSourceListModel();
324 private void searchAddButtonActionPerformed(java.awt.event.ActionEvent evt) {
329 private javax.swing.JCheckBox dataSourceCheckBox;
330 private javax.swing.JList<String> dataSourceList;
331 private javax.swing.JLabel ingestIndexLabel;
332 private javax.swing.JCheckBox jSaveSearchResults;
333 private javax.swing.JScrollPane jScrollPane1;
334 private javax.swing.JSplitPane jSplitPane1;
335 private javax.swing.JTable keywordsTable;
336 private javax.swing.JScrollPane leftPane;
337 private javax.swing.JTable listsTable;
338 private javax.swing.JButton manageListsButton;
339 private javax.swing.JScrollPane rightPane;
340 private javax.swing.JButton searchAddButton;
343 private void searchAction(ActionEvent e) {
344 setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
347 search(jSaveSearchResults.isSelected());
354 List<KeywordList> getKeywordLists() {
355 return listsTableModel.getSelectedListsL();
358 void addSearchButtonActionListener(ActionListener al) {
359 searchAddButton.addActionListener(al);
367 Set<Long> getDataSourcesSelected() {
368 Set<Long> dataSourceObjIdSet =
new HashSet<>();
369 for (Long key : getDataSourceMap().keySet()) {
370 String value = getDataSourceMap().get(key);
371 for (String dataSource : this.dataSourceList.getSelectedValuesList()) {
372 if (value.equals(dataSource)) {
373 dataSourceObjIdSet.add(key);
377 return dataSourceObjIdSet;
383 private final XmlKeywordSearchList listsHandle = XmlKeywordSearchList.getCurrent();
384 private final List<ListTableEntry> listData =
new ArrayList<>();
393 return listData.size();
401 ret = NbBundle.getMessage(this.getClass(),
"KeywordSearch.selectedColLbl");
404 ret = NbBundle.getMessage(this.getClass(),
"KeywordSearch.nameColLbl");
417 Iterator<ListTableEntry> it = listData.iterator();
418 for (
int i = 0; i <= rowIndex; ++i) {
422 switch (columnIndex) {
424 ret = (Object) entry.selected;
427 ret = (Object) entry.name;
438 return (columnIndex == 0 && !ingestRunning);
442 public void setValueAt(Object aValue,
int rowIndex,
int columnIndex) {
443 if (columnIndex == 0) {
445 Iterator<ListTableEntry> it = listData.iterator();
446 for (
int i = 0; i <= rowIndex; i++) {
450 entry.selected = (Boolean) aValue;
461 return getValueAt(0, c).getClass();
464 List<String> getAllLists() {
465 List<String> ret =
new ArrayList<>();
466 for (ListTableEntry e : listData) {
472 KeywordList getListAt(
int rowIndex) {
473 return listsHandle.getList((String) getValueAt(rowIndex, 1));
476 List<String> getSelectedLists() {
477 List<String> ret =
new ArrayList<>();
478 for (ListTableEntry e : listData) {
486 List<KeywordList> getSelectedListsL() {
487 List<KeywordList> ret =
new ArrayList<>();
488 for (String s : getSelectedLists()) {
489 ret.add(listsHandle.getList(s));
494 boolean listExists(String list) {
495 List<String> all = getAllLists();
496 return all.contains(list);
502 addLists(listsHandle.getListsL());
503 fireTableDataChanged();
509 if (!listExists(list.getName())) {
522 this.name = list.getName();
524 this.selected = list.getUseForIngest();
526 this.selected =
false;
532 return this.name.compareTo(e.name);
539 List<KeywordTableEntry> listData =
new ArrayList<>();
543 return listData.size();
556 ret = NbBundle.getMessage(this.getClass(),
"KeywordSearch.nameColLbl");
559 ret = NbBundle.getMessage(this.getClass(),
"KeywordSearch.typeColLbl");
572 Iterator<KeywordTableEntry> it = listData.iterator();
573 for (
int i = 0; i <= rowIndex; ++i) {
577 switch (columnIndex) {
579 ret = (Object) entry.name;
582 ret = (Object) entry.keywordType;
597 public void setValueAt(Object aValue,
int rowIndex,
int columnIndex) {
602 return getValueAt(0, c).getClass();
607 for (Keyword k : list.getKeywords()) {
608 listData.add(
new KeywordTableEntry(k));
610 fireTableDataChanged();
615 fireTableDataChanged();
625 this.name = keyword.getSearchTerm();
626 this.keywordType = keyword.getSearchTermType();
631 return this.name.compareTo(e.name);
640 JTable table, Object value,
641 boolean isSelected,
boolean hasFocus,
642 int row,
int column) {
644 this.setHorizontalAlignment(JCheckBox.CENTER);
645 this.setVerticalAlignment(JCheckBox.CENTER);
647 setEnabled(!ingestRunning);
649 boolean selected = (Boolean) table.getModel().getValueAt(row, 0);
650 setSelected(selected);
653 setBackground(listsTable.getSelectionBackground());
655 setBackground(listsTable.getBackground());
665 @NbBundle.Messages({
"DropdownListSearchPanel.selected=Ad Hoc Search data source filter is selected"})
666 void updateDataSourceListModel() {
667 getDataSourceListModel().removeAllElements();
668 for (String dsName : getDataSourceArray()) {
669 getDataSourceListModel().addElement(dsName);
671 setComponentsEnabled();
672 firePropertyChange(Bundle.DropdownListSearchPanel_selected(), null, null);
679 private void setComponentsEnabled() {
681 if (getDataSourceListModel().size() > 1) {
682 this.dataSourceCheckBox.setEnabled(
true);
684 boolean enabled = this.dataSourceCheckBox.isSelected();
685 this.dataSourceList.setEnabled(enabled);
687 this.dataSourceList.setSelectionInterval(0, this.dataSourceList.getModel().getSize()-1);
689 this.dataSourceList.setSelectedIndices(
new int[0]);
692 this.dataSourceCheckBox.setEnabled(
false);
693 this.dataSourceCheckBox.setSelected(
false);
694 this.dataSourceList.setEnabled(
false);
695 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)