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 leftPane.setMinimumSize(
new java.awt.Dimension(150, 23));
214 leftPane.setOpaque(
false);
216 listsTable.setBackground(
new java.awt.Color(240, 240, 240));
217 listsTable.setModel(listsTableModel);
218 listsTable.setShowHorizontalLines(
false);
219 listsTable.setShowVerticalLines(
false);
220 listsTable.getTableHeader().setReorderingAllowed(
false);
221 leftPane.setViewportView(listsTable);
223 jSplitPane1.setLeftComponent(leftPane);
225 rightPane.setOpaque(
false);
227 keywordsTable.setBackground(
new java.awt.Color(240, 240, 240));
228 keywordsTable.setModel(keywordsTableModel);
229 keywordsTable.setGridColor(
new java.awt.Color(153, 153, 153));
230 rightPane.setViewportView(keywordsTable);
232 jSplitPane1.setRightComponent(rightPane);
234 manageListsButton.setText(
org.openide.util.NbBundle.getMessage(DropdownListSearchPanel.class,
"KeywordSearchListsViewerPanel.manageListsButton.text"));
235 manageListsButton.setToolTipText(
org.openide.util.NbBundle.getMessage(DropdownListSearchPanel.class,
"KeywordSearchListsViewerPanel.manageListsButton.toolTipText"));
236 manageListsButton.addActionListener(
new java.awt.event.ActionListener() {
237 public void actionPerformed(java.awt.event.ActionEvent evt) {
238 manageListsButtonActionPerformed(evt);
242 searchAddButton.setIcon(
new javax.swing.ImageIcon(getClass().getResource(
"/org/sleuthkit/autopsy/keywordsearch/search-icon.png")));
243 searchAddButton.setText(
org.openide.util.NbBundle.getMessage(DropdownListSearchPanel.class,
"KeywordSearchListsViewerPanel.searchAddButton.text"));
244 searchAddButton.addActionListener(
new java.awt.event.ActionListener() {
245 public void actionPerformed(java.awt.event.ActionEvent evt) {
246 searchAddButtonActionPerformed(evt);
250 ingestIndexLabel.setFont(ingestIndexLabel.getFont().deriveFont(ingestIndexLabel.getFont().getSize()-1f));
251 ingestIndexLabel.setText(
org.openide.util.NbBundle.getMessage(DropdownListSearchPanel.class,
"KeywordSearchListsViewerPanel.ingestIndexLabel.text"));
253 dataSourceCheckBox.setText(
org.openide.util.NbBundle.getMessage(DropdownListSearchPanel.class,
"DropdownListSearchPanel.dataSourceCheckBox.text"));
254 dataSourceCheckBox.addActionListener(
new java.awt.event.ActionListener() {
255 public void actionPerformed(java.awt.event.ActionEvent evt) {
256 dataSourceCheckBoxActionPerformed(evt);
260 dataSourceList.setMinimumSize(
new java.awt.Dimension(0, 200));
261 jScrollPane1.setViewportView(dataSourceList);
263 jSaveSearchResults.setText(
org.openide.util.NbBundle.getMessage(DropdownListSearchPanel.class,
"DropdownListSearchPanel.jSaveSearchResults.text"));
264 jSaveSearchResults.setToolTipText(
org.openide.util.NbBundle.getMessage(DropdownListSearchPanel.class,
"DropdownListSearchPanel.jSaveSearchResults.toolTipText"));
266 javax.swing.GroupLayout layout =
new javax.swing.GroupLayout(
this);
267 this.setLayout(layout);
268 layout.setHorizontalGroup(
269 layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
270 .addComponent(jSplitPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 0, Short.MAX_VALUE)
271 .addComponent(jScrollPane1)
272 .addGroup(layout.createSequentialGroup()
273 .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
274 .addComponent(dataSourceCheckBox)
275 .addComponent(jSaveSearchResults)
276 .addGroup(layout.createSequentialGroup()
277 .addComponent(searchAddButton)
278 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
279 .addComponent(manageListsButton)
280 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
281 .addComponent(ingestIndexLabel)))
282 .addGap(0, 120, Short.MAX_VALUE))
285 layout.linkSize(javax.swing.SwingConstants.HORIZONTAL,
new java.awt.Component[] {manageListsButton, searchAddButton});
287 layout.setVerticalGroup(
288 layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
289 .addGroup(layout.createSequentialGroup()
290 .addComponent(jSplitPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 183, javax.swing.GroupLayout.PREFERRED_SIZE)
291 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
292 .addComponent(dataSourceCheckBox)
293 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
294 .addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 65, javax.swing.GroupLayout.PREFERRED_SIZE)
295 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
296 .addComponent(jSaveSearchResults)
297 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
298 .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
299 .addComponent(manageListsButton)
300 .addComponent(searchAddButton)
301 .addComponent(ingestIndexLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 13, javax.swing.GroupLayout.PREFERRED_SIZE))
306 private void manageListsButtonActionPerformed(java.awt.event.ActionEvent evt) {
307 SystemAction.get(KeywordSearchConfigurationAction.class).performAction();
310 private void dataSourceCheckBoxActionPerformed(java.awt.event.ActionEvent evt) {
311 updateDataSourceListModel();
314 private void searchAddButtonActionPerformed(java.awt.event.ActionEvent evt) {
319 private javax.swing.JCheckBox dataSourceCheckBox;
320 private javax.swing.JList<String> dataSourceList;
321 private javax.swing.JLabel ingestIndexLabel;
322 private javax.swing.JCheckBox jSaveSearchResults;
323 private javax.swing.JScrollPane jScrollPane1;
324 private javax.swing.JSplitPane jSplitPane1;
325 private javax.swing.JTable keywordsTable;
326 private javax.swing.JScrollPane leftPane;
327 private javax.swing.JTable listsTable;
328 private javax.swing.JButton manageListsButton;
329 private javax.swing.JScrollPane rightPane;
330 private javax.swing.JButton searchAddButton;
333 private void searchAction(ActionEvent e) {
334 setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
337 search(jSaveSearchResults.isSelected());
344 List<KeywordList> getKeywordLists() {
345 return listsTableModel.getSelectedListsL();
348 void addSearchButtonActionListener(ActionListener al) {
349 searchAddButton.addActionListener(al);
357 Set<Long> getDataSourcesSelected() {
358 Set<Long> dataSourceObjIdSet =
new HashSet<>();
359 for (Long key : getDataSourceMap().keySet()) {
360 String value = getDataSourceMap().get(key);
361 for (String dataSource : this.dataSourceList.getSelectedValuesList()) {
362 if (value.equals(dataSource)) {
363 dataSourceObjIdSet.add(key);
367 return dataSourceObjIdSet;
373 private final XmlKeywordSearchList listsHandle = XmlKeywordSearchList.getCurrent();
374 private final List<ListTableEntry> listData =
new ArrayList<>();
383 return listData.size();
391 ret = NbBundle.getMessage(this.getClass(),
"KeywordSearch.selectedColLbl");
394 ret = NbBundle.getMessage(this.getClass(),
"KeywordSearch.nameColLbl");
407 Iterator<ListTableEntry> it = listData.iterator();
408 for (
int i = 0; i <= rowIndex; ++i) {
412 switch (columnIndex) {
414 ret = (Object) entry.selected;
417 ret = (Object) entry.name;
428 return (columnIndex == 0 && !ingestRunning);
432 public void setValueAt(Object aValue,
int rowIndex,
int columnIndex) {
433 if (columnIndex == 0) {
435 Iterator<ListTableEntry> it = listData.iterator();
436 for (
int i = 0; i <= rowIndex; i++) {
440 entry.selected = (Boolean) aValue;
451 return getValueAt(0, c).getClass();
454 List<String> getAllLists() {
455 List<String> ret =
new ArrayList<>();
456 for (ListTableEntry e : listData) {
462 KeywordList getListAt(
int rowIndex) {
463 return listsHandle.getList((String) getValueAt(rowIndex, 1));
466 List<String> getSelectedLists() {
467 List<String> ret =
new ArrayList<>();
468 for (ListTableEntry e : listData) {
476 List<KeywordList> getSelectedListsL() {
477 List<KeywordList> ret =
new ArrayList<>();
478 for (String s : getSelectedLists()) {
479 ret.add(listsHandle.getList(s));
484 boolean listExists(String list) {
485 List<String> all = getAllLists();
486 return all.contains(list);
492 addLists(listsHandle.getListsL());
493 fireTableDataChanged();
499 if (!listExists(list.getName())) {
512 this.name = list.getName();
514 this.selected = list.getUseForIngest();
516 this.selected =
false;
522 return this.name.compareTo(e.name);
529 List<KeywordTableEntry> listData =
new ArrayList<>();
533 return listData.size();
546 ret = NbBundle.getMessage(this.getClass(),
"KeywordSearch.nameColLbl");
549 ret = NbBundle.getMessage(this.getClass(),
"KeywordSearch.typeColLbl");
562 Iterator<KeywordTableEntry> it = listData.iterator();
563 for (
int i = 0; i <= rowIndex; ++i) {
567 switch (columnIndex) {
569 ret = (Object) entry.name;
572 ret = (Object) entry.keywordType;
587 public void setValueAt(Object aValue,
int rowIndex,
int columnIndex) {
592 return getValueAt(0, c).getClass();
598 listData.add(
new KeywordTableEntry(k));
600 fireTableDataChanged();
605 fireTableDataChanged();
616 this.keywordType = keyword.getSearchTermType();
621 return this.name.compareTo(e.name);
630 JTable table, Object value,
631 boolean isSelected,
boolean hasFocus,
632 int row,
int column) {
634 this.setHorizontalAlignment(JCheckBox.CENTER);
635 this.setVerticalAlignment(JCheckBox.CENTER);
637 setEnabled(!ingestRunning);
639 boolean selected = (Boolean) table.getModel().getValueAt(row, 0);
640 setSelected(selected);
643 setBackground(listsTable.getSelectionBackground());
645 setBackground(listsTable.getBackground());
655 @NbBundle.Messages({
"DropdownListSearchPanel.selected=Ad Hoc Search data source filter is selected"})
656 void updateDataSourceListModel() {
657 getDataSourceListModel().removeAllElements();
658 for (String dsName : getDataSourceArray()) {
659 getDataSourceListModel().addElement(dsName);
661 setComponentsEnabled();
662 firePropertyChange(Bundle.DropdownListSearchPanel_selected(), null, null);
669 private void setComponentsEnabled() {
671 if (getDataSourceListModel().size() > 1) {
672 this.dataSourceCheckBox.setEnabled(
true);
674 boolean enabled = this.dataSourceCheckBox.isSelected();
675 this.dataSourceList.setEnabled(enabled);
677 this.dataSourceList.setSelectionInterval(0, this.dataSourceList.getModel().getSize()-1);
679 this.dataSourceList.setSelectedIndices(
new int[0]);
682 this.dataSourceCheckBox.setEnabled(
false);
683 this.dataSourceCheckBox.setSelected(
false);
684 this.dataSourceList.setEnabled(
false);
685 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)
List< Keyword > getKeywords()
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)