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();
608 listData.add(
new KeywordTableEntry(k));
610 fireTableDataChanged();
615 fireTableDataChanged();
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)
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)