/*
* Autopsy Forensic Browser
*
* Copyright 2011-2016 Basis Technology Corp.
* Contact: carrier <at> sleuthkit <dot> org
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.sleuthkit.autopsy.keywordsearch;
import java.awt.event.KeyEvent;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JFileChooser;
import javax.swing.JOptionPane;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import javax.swing.filechooser.FileNameExtensionFilter;
import javax.swing.table.AbstractTableModel;
import org.netbeans.spi.options.OptionsPanelController;
import org.openide.util.NbBundle;
import org.sleuthkit.autopsy.corecomponents.OptionsPanel;
import org.sleuthkit.autopsy.coreutils.Logger;
/**
* A panel to manage all keyword lists created/imported in Autopsy.
*/
class GlobalListsManagementPanel extends javax.swing.JPanel implements OptionsPanel {
private static final long serialVersionUID = 1L;
private final Logger logger = Logger.getLogger(GlobalListsManagementPanel.class.getName());
private final KeywordListTableModel tableModel;
private final org.sleuthkit.autopsy.keywordsearch.GlobalListSettingsPanel globalListSettingsPanel;
GlobalListsManagementPanel(org.sleuthkit.autopsy.keywordsearch.GlobalListSettingsPanel gsp) {
this.globalListSettingsPanel = gsp;
tableModel = new KeywordListTableModel();
initComponents();
customizeComponents();
}
private void customizeComponents() {
listsTable.setAutoscrolls(true);
listsTable.setTableHeader(null);
listsTable.setShowHorizontalLines(false);
listsTable.setShowVerticalLines(false);
listsTable.getParent().setBackground(listsTable.getBackground());
listsTable.setCellSelectionEnabled(false);
listsTable.setRowSelectionAllowed(true);
tableModel.resync();
listsTable.getSelectionModel().addListSelectionListener(new ListSelectionListener() {
@Override
public void valueChanged(ListSelectionEvent e) {
globalListSettingsPanel.setFocusOnKeywordTextBox();
}
});
/*
* XmlKeywordSearchList.getCurrent().addPropertyChangeListener(new
* PropertyChangeListener() {
*
* @Override public void propertyChange(PropertyChangeEvent evt) { if
* (evt.getPropertyName().equals(XmlKeywordSearchList.ListsEvt.LIST_ADDED.toString()))
* { tableModel.resync(); for(int i = 0; i<listsTable.getRowCount();
* i++) { String name = (String) listsTable.getValueAt(i, 0);
* if(((String) evt.getNewValue()).equals(name)) {
* listsTable.getSelectionModel().setSelectionInterval(i, i); } } } else
* if
* (evt.getPropertyName().equals(XmlKeywordSearchList.ListsEvt.LIST_DELETED.toString()))
* { tableModel.resync(); if(listsTable.getRowCount() > 0) {
* listsTable.getSelectionModel().setSelectionInterval(0, 0); } else {
* listsTable.getSelectionModel().clearSelection(); } } } });
*/
}
/**
* This method is called from within the constructor to initialize the form.
* WARNING: Do NOT modify this code. The content of this method is always
* regenerated by the Form Editor.
*/
@SuppressWarnings("unchecked")
// <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
private void initComponents() {
jScrollPane1 = new javax.swing.JScrollPane();
listsTable = new javax.swing.JTable();
newListButton = new javax.swing.JButton();
importButton = new javax.swing.JButton();
keywordListsLabel = new javax.swing.JLabel();
setMinimumSize(new java.awt.Dimension(250, 0));
listsTable.setModel(tableModel);
listsTable.setMaximumSize(new java.awt.Dimension(30000, 30000));
listsTable.setShowHorizontalLines(false);
listsTable.setShowVerticalLines(false);
listsTable.getTableHeader().setReorderingAllowed(false);
listsTable.addKeyListener(new java.awt.event.KeyAdapter() {
public void keyPressed(java.awt.event.KeyEvent evt) {
listsTableKeyPressed(evt);
}
});
jScrollPane1.setViewportView(listsTable);
newListButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/keywordsearch/new16.png"))); // NOI18N
newListButton.setText(org.openide.util.NbBundle.getMessage(GlobalListsManagementPanel.class, "GlobalListsManagementPanel.newListButton.text")); // NOI18N
newListButton.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
newListButtonActionPerformed(evt);
}
});
importButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/keywordsearch/import16.png"))); // NOI18N
importButton.setText(org.openide.util.NbBundle.getMessage(GlobalListsManagementPanel.class, "GlobalListsManagementPanel.importButton.text")); // NOI18N
importButton.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
importButtonActionPerformed(evt);
}
});
keywordListsLabel.setText(org.openide.util.NbBundle.getMessage(GlobalListsManagementPanel.class, "GlobalListsManagementPanel.keywordListsLabel.text")); // NOI18N
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
this.setLayout(layout);
layout.setHorizontalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addContainerGap()
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(jScrollPane1, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.PREFERRED_SIZE, 0, Short.MAX_VALUE)
.addGroup(layout.createSequentialGroup()
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(keywordListsLabel)
.addGroup(layout.createSequentialGroup()
.addComponent(newListButton, javax.swing.GroupLayout.PREFERRED_SIZE, 114, javax.swing.GroupLayout.PREFERRED_SIZE)
.addGap(18, 18, 18)
.addComponent(importButton, javax.swing.GroupLayout.PREFERRED_SIZE, 126, javax.swing.GroupLayout.PREFERRED_SIZE)))
.addGap(0, 0, Short.MAX_VALUE)))
.addContainerGap())
);
layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
.addContainerGap()
.addComponent(keywordListsLabel)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 355, Short.MAX_VALUE)
.addGap(5, 5, 5)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(newListButton)
.addComponent(importButton))
.addContainerGap())
);
}// </editor-fold>//GEN-END:initComponents
private void newListButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_newListButtonActionPerformed
XmlKeywordSearchList writer = XmlKeywordSearchList.getCurrent();
String listName = (String) JOptionPane.showInputDialog(null, NbBundle.getMessage(this.getClass(), "KeywordSearch.newKwListTitle"),
NbBundle.getMessage(this.getClass(), "KeywordSearch.newKeywordListMsg"), JOptionPane.PLAIN_MESSAGE, null, null, "");
if (listName == null || listName.trim().equals("")) {
return;
}
boolean shouldAdd = false;
if (writer.listExists(listName)) {
if (writer.getList(listName).isEditable()) {
boolean replace = KeywordSearchUtil.displayConfirmDialog(
NbBundle.getMessage(this.getClass(), "KeywordSearch.newKeywordListMsg"),
NbBundle.getMessage(this.getClass(), "KeywordSearchListsManagementPanel.newKeywordListDescription", listName),
KeywordSearchUtil.DIALOG_MESSAGE_TYPE.WARN);
if (replace) {
shouldAdd = true;
}
} else {
boolean replace = KeywordSearchUtil.displayConfirmDialog(
NbBundle.getMessage(this.getClass(), "KeywordSearch.newKeywordListMsg"),
NbBundle.getMessage(this.getClass(), "KeywordSearchListsManagementPanel.newKeywordListDescription2", listName),
KeywordSearchUtil.DIALOG_MESSAGE_TYPE.WARN);
if (replace) {
shouldAdd = true;
}
}
} else {
shouldAdd = true;
}
if (shouldAdd) {
writer.addList(listName, new ArrayList<Keyword>());
}
tableModel.resync();
//This loop selects the recently ADDED keywordslist in the JTable
for (int i = 0; i < listsTable.getRowCount(); i++) {
if (listsTable.getValueAt(i, 0).equals(listName)) {
listsTable.getSelectionModel().addSelectionInterval(i, i);
}
}
firePropertyChange(OptionsPanelController.PROP_CHANGED, null, null);
globalListSettingsPanel.setFocusOnKeywordTextBox();
}//GEN-LAST:event_newListButtonActionPerformed
private void importButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_importButtonActionPerformed
JFileChooser chooser = new JFileChooser();
final String[] AUTOPSY_EXTENSIONS = new String[]{"xml"}; //NON-NLS
final String[] ENCASE_EXTENSIONS = new String[]{"txt"}; //NON-NLS
FileNameExtensionFilter autopsyFilter = new FileNameExtensionFilter(
NbBundle.getMessage(this.getClass(), "KeywordSearchListsManagementPanel.fileExtensionFilterLbl"), AUTOPSY_EXTENSIONS);
FileNameExtensionFilter encaseFilter = new FileNameExtensionFilter(
NbBundle.getMessage(this.getClass(), "KeywordSearchListsManagementPanel.fileExtensionFilterLb2"), ENCASE_EXTENSIONS);
chooser.addChoosableFileFilter(autopsyFilter);
chooser.addChoosableFileFilter(encaseFilter);
chooser.setAcceptAllFileFilterUsed(false);
chooser.setFileSelectionMode(JFileChooser.FILES_ONLY);
String listName = null;
int returnVal = chooser.showOpenDialog(this);
if (returnVal == JFileChooser.APPROVE_OPTION) {
File selFile = chooser.getSelectedFile();
if (selFile == null) {
return;
}
//force append extension if not given
String fileAbs = selFile.getAbsolutePath();
final KeywordSearchList reader;
if (KeywordSearchUtil.isXMLList(fileAbs)) {
reader = new XmlKeywordSearchList(fileAbs);
} else {
reader = new EnCaseKeywordSearchList(fileAbs);
}
if (!reader.load()) {
KeywordSearchUtil.displayDialog(
NbBundle.getMessage(this.getClass(), "KeywordSearch.listImportFeatureTitle"), NbBundle.getMessage(this.getClass(), "KeywordSearch.importListFileDialogMsg", fileAbs), KeywordSearchUtil.DIALOG_MESSAGE_TYPE.ERROR);
return;
}
List<KeywordList> toImport = reader.getListsL();
List<KeywordList> toImportConfirmed = new ArrayList<KeywordList>();
final XmlKeywordSearchList writer = XmlKeywordSearchList.getCurrent();
for (KeywordList list : toImport) {
//check name collisions
listName = list.getName();
if (writer.listExists(listName)) {
Object[] options = {NbBundle.getMessage(this.getClass(), "KeywordSearch.yesOwMsg"),
NbBundle.getMessage(this.getClass(), "KeywordSearch.noSkipMsg"),
NbBundle.getMessage(this.getClass(), "KeywordSearch.cancelImportMsg")};
int choice = JOptionPane.showOptionDialog(this,
NbBundle.getMessage(this.getClass(), "KeywordSearch.overwriteListPrompt", listName),
NbBundle.getMessage(this.getClass(), "KeywordSearch.importOwConflict"),
JOptionPane.YES_NO_CANCEL_OPTION,
JOptionPane.QUESTION_MESSAGE,
null,
options,
options[0]);
if (choice == JOptionPane.OK_OPTION) {
toImportConfirmed.add(list);
} else if (choice == JOptionPane.CANCEL_OPTION) {
break;
}
} else {
//no conflict
toImportConfirmed.add(list);
}
}
if (toImportConfirmed.isEmpty()) {
return;
}
if (!writer.writeLists(toImportConfirmed)) {
KeywordSearchUtil.displayDialog(
NbBundle.getMessage(this.getClass(), "KeywordSearch.listImportFeatureTitle"), NbBundle.getMessage(this.getClass(), "KeywordSearch.kwListFailImportMsg"), KeywordSearchUtil.DIALOG_MESSAGE_TYPE.INFO);
}
}
tableModel.resync();
//This loop selects the recently IMPORTED keywordslist in the JTable
if (listName != null) {
for (int i = 0; i < listsTable.getRowCount(); i++) {
if (listsTable.getValueAt(i, 0).equals(listName)) {
listsTable.getSelectionModel().addSelectionInterval(i, i);
}
}
}
firePropertyChange(OptionsPanelController.PROP_CHANGED, null, null);
}//GEN-LAST:event_importButtonActionPerformed
private void listsTableKeyPressed(java.awt.event.KeyEvent evt) {//GEN-FIRST:event_listsTableKeyPressed
if (evt.getKeyCode() == KeyEvent.VK_DELETE) {
int[] selected = listsTable.getSelectedRows();
if (selected.length == 0) {
return;
} else if (KeywordSearchUtil.displayConfirmDialog(NbBundle.getMessage(this.getClass(), "KeywordSearchConfigurationPanel1.customizeComponents.title"), NbBundle.getMessage(this.getClass(), "KeywordSearchConfigurationPanel1.customizeComponents.body"), KeywordSearchUtil.DIALOG_MESSAGE_TYPE.WARN)) {
String listName = (String) listsTable.getModel().getValueAt(selected[0], 0);
XmlKeywordSearchList.getCurrent().deleteList(listName);
firePropertyChange(OptionsPanelController.PROP_CHANGED, null, null);
} else {
return;
}
}
tableModel.resync();
}//GEN-LAST:event_listsTableKeyPressed
// Variables declaration - do not modify//GEN-BEGIN:variables
private javax.swing.JButton importButton;
private javax.swing.JScrollPane jScrollPane1;
private javax.swing.JLabel keywordListsLabel;
private javax.swing.JTable listsTable;
private javax.swing.JButton newListButton;
// End of variables declaration//GEN-END:variables
@Override
public void store() {
// Implemented by parent panel
}
@Override
public void load() {
listsTable.clearSelection();
}
void resync() {
tableModel.resync();
}
private class KeywordListTableModel extends AbstractTableModel {
private final XmlKeywordSearchList listsHandle = XmlKeywordSearchList.getCurrent();
@Override
public int getColumnCount() {
return 1;
}
@Override
public int getRowCount() {
return listsHandle.getNumberLists(false);
}
@Override
public String getColumnName(int column) {
return NbBundle.getMessage(this.getClass(), "KeywordSearchListsManagementPanel.getColName.text");
}
@Override
public Object getValueAt(int rowIndex, int columnIndex) {
return listsHandle.getListNames(false).get(rowIndex);
}
@Override
public boolean isCellEditable(int rowIndex, int columnIndex) {
return false;
}
@Override
public void setValueAt(Object aValue, int rowIndex, int columnIndex) {
throw new UnsupportedOperationException(
NbBundle.getMessage(this.getClass(), "KeywordSearchListsManagementPanel.setValueAt.exception.msg"));
}
@Override
public Class<?> getColumnClass(int c) {
return getValueAt(0, c).getClass();
}
//delete selected from handle, events are fired from the handle
void deleteSelected(int[] selected) {
List<String> toDel = new ArrayList<>();
for (int i = 0; i < selected.length; i++) {
toDel.add((String) getValueAt(0, selected[i]));
}
for (String del : toDel) {
listsHandle.deleteList(del);
}
}
//resync model from handle, then update table
void resync() {
fireTableDataChanged();
}
}
void addListSelectionListener(ListSelectionListener l) {
listsTable.getSelectionModel().addListSelectionListener(l);
}
}