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)