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)