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)