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;
52 @SuppressWarnings(
"PMD.SingularField")
53 class DropdownListSearchPanel extends AdHocSearchPanel {
55 private static final Logger logger = Logger.getLogger(DropdownListSearchPanel.class.getName());
56 private static DropdownListSearchPanel instance;
57 private XmlKeywordSearchList loader;
58 private final KeywordListsTableModel listsTableModel;
59 private final KeywordsTableModel keywordsTableModel;
60 private ActionListener searchAddListener;
61 private boolean ingestRunning;
66 private DropdownListSearchPanel() {
67 listsTableModel =
new KeywordListsTableModel();
68 keywordsTableModel =
new KeywordsTableModel();
70 customizeComponents();
71 dataSourceList.setModel(getDataSourceListModel());
73 dataSourceList.addListSelectionListener((ListSelectionEvent evt) -> {
74 firePropertyChange(Bundle.DropdownSingleTermSearchPanel_selected(), null, null);
78 static synchronized DropdownListSearchPanel getDefault() {
79 if (instance == null) {
80 instance =
new DropdownListSearchPanel();
85 private void customizeComponents() {
86 listsTable.setTableHeader(null);
87 listsTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
89 final int leftWidth = leftPane.getPreferredSize().width;
91 for (
int i = 0; i < listsTable.getColumnCount(); i++) {
92 column = listsTable.getColumnModel().getColumn(i);
94 column.setPreferredWidth(((
int) (leftWidth * 0.10)));
95 column.setCellRenderer(
new LeftCheckBoxRenderer());
97 column.setPreferredWidth(((
int) (leftWidth * 0.89)));
98 column.setCellRenderer(
new SimpleTableCellRenderer());
101 final int rightWidth = rightPane.getPreferredSize().width;
102 for (
int i = 0; i < keywordsTable.getColumnCount(); i++) {
103 column = keywordsTable.getColumnModel().getColumn(i);
105 column.setPreferredWidth(((
int) (rightWidth * 0.60)));
107 column.setPreferredWidth(((
int) (rightWidth * 0.38)));
110 keywordsTable.setDefaultRenderer(String.class,
new SimpleTableCellRenderer());
112 loader = XmlKeywordSearchList.getCurrent();
113 listsTable.getSelectionModel().addListSelectionListener(
new ListSelectionListener() {
115 public void valueChanged(ListSelectionEvent e) {
116 ListSelectionModel listSelectionModel = (ListSelectionModel) e.getSource();
117 if (!listSelectionModel.isSelectionEmpty()) {
118 int index = listSelectionModel.getMinSelectionIndex();
119 KeywordList list = listsTableModel.getListAt(index);
120 keywordsTableModel.resync(list);
122 keywordsTableModel.deleteAll();
127 ingestRunning = IngestManager.getInstance().isIngestRunning();
130 IngestManager.getInstance().addIngestJobEventListener(
new PropertyChangeListener() {
132 public void propertyChange(PropertyChangeEvent evt) {
133 Object source = evt.getSource();
134 if (source instanceof String && ((String) source).equals(
"LOCAL")) {
135 EventQueue.invokeLater(() -> {
136 ingestRunning = IngestManager.getInstance().isIngestRunning();
143 searchAddListener =
new ActionListener() {
145 public void actionPerformed(ActionEvent e) {
147 IngestSearchRunner.getInstance().addKeywordListsToAllJobs(listsTableModel.getSelectedLists());
148 logger.log(Level.INFO,
"Submitted enqueued lists to ingest");
155 searchAddButton.addActionListener(searchAddListener);
158 private void updateComponents() {
159 ingestRunning = IngestManager.getInstance().isIngestRunning();
161 searchAddButton.setText(NbBundle.getMessage(
this.getClass(),
"KeywordSearchListsViewerPanel.initIngest.addIngestTitle"));
162 searchAddButton.setToolTipText(NbBundle.getMessage(
this.getClass(),
"KeywordSearchListsViewerPanel.initIngest.addIngestMsg"));
165 searchAddButton.setText(NbBundle.getMessage(
this.getClass(),
"KeywordSearchListsViewerPanel.initIngest.searchIngestTitle"));
166 searchAddButton.setToolTipText(NbBundle.getMessage(
this.getClass(),
"KeywordSearchListsViewerPanel.initIngest.addIdxSearchMsg"));
168 listsTableModel.resync();
169 updateIngestIndexLabel();
171 jSaveSearchResults.setSelected(
true);
174 private void updateIngestIndexLabel() {
176 ingestIndexLabel.setText(NbBundle.getMessage(
this.getClass(),
"KeywordSearchListsViewerPanel.initIngest.ongoingIngestMsg", filesIndexed));
178 ingestIndexLabel.setText(NbBundle.getMessage(
this.getClass(),
"KeywordSearchListsViewerPanel.initIngest.fileIndexCtMsg", filesIndexed));
183 protected void postFilesIndexedChange() {
184 updateIngestIndexLabel();
191 listsTableModel.resync();
199 @SuppressWarnings(
"unchecked")
201 private
void initComponents() {
203 jSplitPane1 =
new javax.swing.JSplitPane();
204 leftPane =
new javax.swing.JScrollPane();
205 listsTable =
new javax.swing.JTable();
206 rightPane =
new javax.swing.JScrollPane();
207 keywordsTable =
new javax.swing.JTable();
208 manageListsButton =
new javax.swing.JButton();
209 searchAddButton =
new javax.swing.JButton();
210 ingestIndexLabel =
new javax.swing.JLabel();
211 dataSourceCheckBox =
new javax.swing.JCheckBox();
212 jScrollPane1 =
new javax.swing.JScrollPane();
213 dataSourceList =
new javax.swing.JList<>();
214 jSaveSearchResults =
new javax.swing.JCheckBox();
216 leftPane.setMinimumSize(
new java.awt.Dimension(150, 23));
217 leftPane.setOpaque(
false);
219 listsTable.setBackground(
new java.awt.Color(240, 240, 240));
220 listsTable.setModel(listsTableModel);
221 listsTable.setShowHorizontalLines(
false);
222 listsTable.setShowVerticalLines(
false);
223 listsTable.getTableHeader().setReorderingAllowed(
false);
224 leftPane.setViewportView(listsTable);
226 jSplitPane1.setLeftComponent(leftPane);
228 rightPane.setOpaque(
false);
230 keywordsTable.setBackground(
new java.awt.Color(240, 240, 240));
231 keywordsTable.setModel(keywordsTableModel);
232 keywordsTable.setGridColor(
new java.awt.Color(153, 153, 153));
233 rightPane.setViewportView(keywordsTable);
235 jSplitPane1.setRightComponent(rightPane);
237 manageListsButton.setText(
org.openide.util.NbBundle.getMessage(DropdownListSearchPanel.class,
"KeywordSearchListsViewerPanel.manageListsButton.text"));
238 manageListsButton.setToolTipText(
org.openide.util.NbBundle.getMessage(DropdownListSearchPanel.class,
"KeywordSearchListsViewerPanel.manageListsButton.toolTipText"));
239 manageListsButton.addActionListener(
new java.awt.event.ActionListener() {
240 public void actionPerformed(java.awt.event.ActionEvent evt) {
241 manageListsButtonActionPerformed(evt);
245 searchAddButton.setIcon(
new javax.swing.ImageIcon(getClass().getResource(
"/org/sleuthkit/autopsy/keywordsearch/search-icon.png")));
246 searchAddButton.setText(
org.openide.util.NbBundle.getMessage(DropdownListSearchPanel.class,
"KeywordSearchListsViewerPanel.searchAddButton.text"));
247 searchAddButton.addActionListener(
new java.awt.event.ActionListener() {
248 public void actionPerformed(java.awt.event.ActionEvent evt) {
249 searchAddButtonActionPerformed(evt);
253 ingestIndexLabel.setFont(ingestIndexLabel.getFont().deriveFont(ingestIndexLabel.getFont().getSize()-1f));
254 ingestIndexLabel.setText(
org.openide.util.NbBundle.getMessage(DropdownListSearchPanel.class,
"KeywordSearchListsViewerPanel.ingestIndexLabel.text"));
256 dataSourceCheckBox.setText(
org.openide.util.NbBundle.getMessage(DropdownListSearchPanel.class,
"DropdownListSearchPanel.dataSourceCheckBox.text"));
257 dataSourceCheckBox.addActionListener(
new java.awt.event.ActionListener() {
258 public void actionPerformed(java.awt.event.ActionEvent evt) {
259 dataSourceCheckBoxActionPerformed(evt);
263 dataSourceList.setMinimumSize(
new java.awt.Dimension(0, 200));
264 jScrollPane1.setViewportView(dataSourceList);
266 jSaveSearchResults.setText(
org.openide.util.NbBundle.getMessage(DropdownListSearchPanel.class,
"DropdownListSearchPanel.jSaveSearchResults.text"));
267 jSaveSearchResults.setToolTipText(
org.openide.util.NbBundle.getMessage(DropdownListSearchPanel.class,
"DropdownListSearchPanel.jSaveSearchResults.toolTipText"));
269 javax.swing.GroupLayout layout =
new javax.swing.GroupLayout(
this);
270 this.setLayout(layout);
271 layout.setHorizontalGroup(
272 layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
273 .addComponent(jSplitPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 0, Short.MAX_VALUE)
274 .addComponent(jScrollPane1)
275 .addGroup(layout.createSequentialGroup()
276 .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
277 .addComponent(dataSourceCheckBox)
278 .addComponent(jSaveSearchResults)
279 .addGroup(layout.createSequentialGroup()
280 .addComponent(searchAddButton)
281 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
282 .addComponent(manageListsButton)
283 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
284 .addComponent(ingestIndexLabel)))
285 .addGap(0, 120, Short.MAX_VALUE))
288 layout.linkSize(javax.swing.SwingConstants.HORIZONTAL,
new java.awt.Component[] {manageListsButton, searchAddButton});
290 layout.setVerticalGroup(
291 layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
292 .addGroup(layout.createSequentialGroup()
293 .addComponent(jSplitPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 183, javax.swing.GroupLayout.PREFERRED_SIZE)
294 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
295 .addComponent(dataSourceCheckBox)
296 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
297 .addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 65, javax.swing.GroupLayout.PREFERRED_SIZE)
298 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
299 .addComponent(jSaveSearchResults)
300 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
301 .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
302 .addComponent(manageListsButton)
303 .addComponent(searchAddButton)
304 .addComponent(ingestIndexLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 13, javax.swing.GroupLayout.PREFERRED_SIZE))
309 private void manageListsButtonActionPerformed(java.awt.event.ActionEvent evt) {
310 SystemAction.get(KeywordSearchConfigurationAction.class).performAction();
313 private void dataSourceCheckBoxActionPerformed(java.awt.event.ActionEvent evt) {
314 updateDataSourceListModel();
317 private void searchAddButtonActionPerformed(java.awt.event.ActionEvent evt) {
322 private javax.swing.JCheckBox dataSourceCheckBox;
323 private javax.swing.JList<String> dataSourceList;
324 private javax.swing.JLabel ingestIndexLabel;
325 private javax.swing.JCheckBox jSaveSearchResults;
326 private javax.swing.JScrollPane jScrollPane1;
327 private javax.swing.JSplitPane jSplitPane1;
328 private javax.swing.JTable keywordsTable;
329 private javax.swing.JScrollPane leftPane;
330 private javax.swing.JTable listsTable;
331 private javax.swing.JButton manageListsButton;
332 private javax.swing.JScrollPane rightPane;
333 private javax.swing.JButton searchAddButton;
336 private void searchAction(ActionEvent e) {
337 setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
340 search(jSaveSearchResults.isSelected());
347 List<KeywordList> getKeywordLists() {
348 return listsTableModel.getSelectedListsL();
351 void addSearchButtonActionListener(ActionListener al) {
352 searchAddButton.addActionListener(al);
360 Set<Long> getDataSourcesSelected() {
361 Set<Long> dataSourceObjIdSet =
new HashSet<>();
362 for (Long key : getDataSourceMap().keySet()) {
363 String value = getDataSourceMap().get(key);
364 for (String dataSource : this.dataSourceList.getSelectedValuesList()) {
365 if (value.equals(dataSource)) {
366 dataSourceObjIdSet.add(key);
370 return dataSourceObjIdSet;
376 private final XmlKeywordSearchList listsHandle = XmlKeywordSearchList.getCurrent();
377 private final List<ListTableEntry> listData =
new ArrayList<>();
386 return listData.size();
394 ret = NbBundle.getMessage(this.getClass(),
"KeywordSearch.selectedColLbl");
397 ret = NbBundle.getMessage(this.getClass(),
"KeywordSearch.nameColLbl");
410 Iterator<ListTableEntry> it = listData.iterator();
411 for (
int i = 0; i <= rowIndex; ++i) {
415 switch (columnIndex) {
417 ret = (Object) entry.selected;
420 ret = (Object) entry.name;
431 return (columnIndex == 0 && !ingestRunning);
435 public void setValueAt(Object aValue,
int rowIndex,
int columnIndex) {
436 if (columnIndex == 0) {
438 Iterator<ListTableEntry> it = listData.iterator();
439 for (
int i = 0; i <= rowIndex; i++) {
443 entry.selected = (Boolean) aValue;
454 return getValueAt(0, c).getClass();
457 List<String> getAllLists() {
458 List<String> ret =
new ArrayList<>();
459 for (ListTableEntry e : listData) {
465 KeywordList getListAt(
int rowIndex) {
466 return listsHandle.getList((String) getValueAt(rowIndex, 1));
469 List<String> getSelectedLists() {
470 List<String> ret =
new ArrayList<>();
471 for (ListTableEntry e : listData) {
479 List<KeywordList> getSelectedListsL() {
480 List<KeywordList> ret =
new ArrayList<>();
481 for (String s : getSelectedLists()) {
482 ret.add(listsHandle.getList(s));
487 boolean listExists(String list) {
488 List<String> all = getAllLists();
489 return all.contains(list);
495 addLists(listsHandle.getListsL());
496 fireTableDataChanged();
502 if (!listExists(list.getName())) {
515 this.name = list.getName();
517 this.selected = list.getUseForIngest();
519 this.selected =
false;
525 return this.name.compareTo(e.name);
532 List<KeywordTableEntry> listData =
new ArrayList<>();
536 return listData.size();
549 ret = NbBundle.getMessage(this.getClass(),
"KeywordSearch.nameColLbl");
552 ret = NbBundle.getMessage(this.getClass(),
"KeywordSearch.typeColLbl");
565 Iterator<KeywordTableEntry> it = listData.iterator();
566 for (
int i = 0; i <= rowIndex; ++i) {
570 switch (columnIndex) {
572 ret = (Object) entry.name;
575 ret = (Object) entry.keywordType;
590 public void setValueAt(Object aValue,
int rowIndex,
int columnIndex) {
595 return getValueAt(0, c).getClass();
601 listData.add(
new KeywordTableEntry(k));
603 fireTableDataChanged();
608 fireTableDataChanged();
619 this.keywordType = keyword.getSearchTermType();
624 return this.name.compareTo(e.name);
633 JTable table, Object value,
634 boolean isSelected,
boolean hasFocus,
635 int row,
int column) {
637 this.setHorizontalAlignment(JCheckBox.CENTER);
638 this.setVerticalAlignment(JCheckBox.CENTER);
640 setEnabled(!ingestRunning);
642 boolean selected = (Boolean) table.getModel().getValueAt(row, 0);
643 setSelected(selected);
646 setBackground(listsTable.getSelectionBackground());
648 setBackground(listsTable.getBackground());
658 @NbBundle.Messages({
"DropdownListSearchPanel.selected=Ad Hoc Search data source filter is selected"})
659 void updateDataSourceListModel() {
660 getDataSourceListModel().removeAllElements();
661 for (String dsName : getDataSourceArray()) {
662 getDataSourceListModel().addElement(dsName);
664 setComponentsEnabled();
665 firePropertyChange(Bundle.DropdownListSearchPanel_selected(), null, null);
672 private void setComponentsEnabled() {
674 if (getDataSourceListModel().size() > 1) {
675 this.dataSourceCheckBox.setEnabled(
true);
677 boolean enabled = this.dataSourceCheckBox.isSelected();
678 this.dataSourceList.setEnabled(enabled);
680 this.dataSourceList.setSelectionInterval(0, this.dataSourceList.getModel().getSize()-1);
682 this.dataSourceList.setSelectedIndices(
new int[0]);
685 this.dataSourceCheckBox.setEnabled(
false);
686 this.dataSourceCheckBox.setSelected(
false);
687 this.dataSourceList.setEnabled(
false);
688 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)