Merge github.com:sleuthkit/autopsy

This commit is contained in:
Dick Fickling 2012-01-18 10:47:58 -05:00
commit 7f19ba4723
10 changed files with 1641 additions and 150 deletions

View File

@ -1,7 +1,13 @@
CTL_KeywordSearchHistoryAction=Keyword Search History
CTL_KeywordSearchHistoryTopComponent=Keyword Search History Window
CTL_KeywordSearchListAction=List
CTL_KeywordSearchListImportExportAction=Keyword Search List Import Export
CTL_KeywordSearchListImportExportTopComponent=Keyword Search List Import Export Window
CTL_KeywordSearchListTopComponent=List
CTL_KeywordSearchTabsTopComponentAction=Keyword Search
CTL_KeywordSearchTabsTopComponentTopComponent=Keyword Search
HINT_KeywordSearchHistoryTopComponent=This is a Keyword Search History window
HINT_KeywordSearchListImportExportTopComponent=Keyword Search List Import Export window
HINT_KeywordSearchListTopComponent=Keyword Search List
HINT_KeywordSearchTabsTopComponentTopComponent=Keyword Search window
OpenIDE-Module-Name=KeywordSearch
@ -34,3 +40,18 @@ KeywordSearchListTopComponent.addWordLabel.text=Add a new keyword:
KeywordSearchListTopComponent.deleteWordButton.text=Delete
KeywordSearchListTopComponent.deleteAllWordsButton.text=Delete All
KeywordSearchSimpleTopComponent.chRegex.text=RegEx
KeywordSearchListImportExportTopComponent.topLabel.text=Manage (import, export, delete) lists of keywords
KeywordSearchListImportExportTopComponent.curKeywordsLabel.text=Current lists:
KeywordSearchListImportExportTopComponent.importButton.text=Import
KeywordSearchListImportExportTopComponent.exportButton.text=Export
KeywordSearchListImportExportTopComponent.deleteButton.text=Delete
KeywordSearchListImportExportTopComponent.filesIndexedNameLabel.text=Files indexed:
KeywordSearchListImportExportTopComponent.filesIndexedValLabel.text=-
KeywordSearchListTopComponent.curListNameLabel.text=Loaded list name:
KeywordSearchListTopComponent.curListValLabel.text=-
KeywordSearchListTopComponent.importButton.text=Import
KeywordSearchHistoryTopComponent.topLabel.text=Review keyword search history and saved results
KeywordSearchHistoryTopComponent.filesIndexedNameLabel.text=Files indexed:
KeywordSearchHistoryTopComponent.filesIndexedValLabel.text=-
KeywordSearchHistoryTopComponent.withHitsLabel.text=Keyword searches with hits:
KeywordSearchHistoryTopComponent.noHitsLabel.text=Keyword searches without hits:

View File

@ -0,0 +1,140 @@
<?xml version="1.1" encoding="UTF-8" ?>
<Form version="1.5" maxVersion="1.7" type="org.netbeans.modules.form.forminfo.JPanelFormInfo">
<AuxValues>
<AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="1"/>
<AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/>
<AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/>
<AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="true"/>
<AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="true"/>
<AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/>
<AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/>
<AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/>
<AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/>
</AuxValues>
<Layout>
<DimensionLayout dim="0">
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" attributes="0">
<EmptySpace max="-2" attributes="0"/>
<Group type="103" groupAlignment="0" attributes="0">
<Component id="jScrollPane2" alignment="0" min="-2" pref="275" max="-2" attributes="0"/>
<Component id="jScrollPane1" alignment="0" min="-2" pref="275" max="-2" attributes="0"/>
<Component id="topLabel" min="-2" max="-2" attributes="0"/>
<Component id="withHitsLabel" alignment="0" min="-2" max="-2" attributes="0"/>
<Component id="noHitsLabel" alignment="0" min="-2" max="-2" attributes="0"/>
<Group type="102" alignment="0" attributes="0">
<Component id="filesIndexedNameLabel" min="-2" max="-2" attributes="0"/>
<EmptySpace type="unrelated" max="-2" attributes="0"/>
<Component id="filesIndexedValLabel" min="-2" pref="72" max="-2" attributes="0"/>
</Group>
</Group>
<EmptySpace pref="15" max="32767" attributes="0"/>
</Group>
</Group>
</DimensionLayout>
<DimensionLayout dim="1">
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" alignment="0" attributes="0">
<EmptySpace min="-2" pref="23" max="-2" attributes="0"/>
<Component id="topLabel" min="-2" max="-2" attributes="0"/>
<EmptySpace min="-2" pref="27" max="-2" attributes="0"/>
<Component id="withHitsLabel" min="-2" max="-2" attributes="0"/>
<EmptySpace type="separate" max="-2" attributes="0"/>
<Component id="jScrollPane1" min="-2" pref="229" max="-2" attributes="0"/>
<EmptySpace min="-2" pref="30" max="-2" attributes="0"/>
<Component id="noHitsLabel" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="jScrollPane2" min="-2" pref="234" max="-2" attributes="0"/>
<EmptySpace min="-2" pref="35" max="-2" attributes="0"/>
<Group type="103" groupAlignment="3" attributes="0">
<Component id="filesIndexedNameLabel" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="filesIndexedValLabel" alignment="3" min="-2" max="-2" attributes="0"/>
</Group>
<EmptySpace pref="34" max="32767" attributes="0"/>
</Group>
</Group>
</DimensionLayout>
</Layout>
<SubComponents>
<Component class="javax.swing.JLabel" name="topLabel">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/keywordsearch/Bundle.properties" key="KeywordSearchHistoryTopComponent.topLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
</Component>
<Component class="javax.swing.JLabel" name="filesIndexedNameLabel">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/keywordsearch/Bundle.properties" key="KeywordSearchHistoryTopComponent.filesIndexedNameLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
</Component>
<Component class="javax.swing.JLabel" name="filesIndexedValLabel">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/keywordsearch/Bundle.properties" key="KeywordSearchHistoryTopComponent.filesIndexedValLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
</Component>
<Component class="javax.swing.JLabel" name="withHitsLabel">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/keywordsearch/Bundle.properties" key="KeywordSearchHistoryTopComponent.withHitsLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
</Component>
<Component class="javax.swing.JLabel" name="noHitsLabel">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/keywordsearch/Bundle.properties" key="KeywordSearchHistoryTopComponent.noHitsLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
</Component>
<Container class="javax.swing.JScrollPane" name="jScrollPane1">
<AuxValues>
<AuxValue name="autoScrollPane" type="java.lang.Boolean" value="true"/>
</AuxValues>
<Layout class="org.netbeans.modules.form.compat2.layouts.support.JScrollPaneSupportLayout"/>
<SubComponents>
<Component class="javax.swing.JTable" name="hitsTable">
<Properties>
<Property name="model" type="javax.swing.table.TableModel" editor="org.netbeans.modules.form.editors2.TableModelEditor">
<Table columnCount="2" rowCount="4">
<Column editable="false" title="Keyword" type="java.lang.String"/>
<Column editable="false" title="#Hits" type="java.lang.Integer"/>
</Table>
</Property>
<Property name="tableHeader" type="javax.swing.table.JTableHeader" editor="org.netbeans.modules.form.editors2.JTableHeaderEditor">
<TableHeader reorderingAllowed="false" resizingAllowed="true"/>
</Property>
</Properties>
</Component>
</SubComponents>
</Container>
<Container class="javax.swing.JScrollPane" name="jScrollPane2">
<AuxValues>
<AuxValue name="autoScrollPane" type="java.lang.Boolean" value="true"/>
</AuxValues>
<Layout class="org.netbeans.modules.form.compat2.layouts.support.JScrollPaneSupportLayout"/>
<SubComponents>
<Component class="javax.swing.JTable" name="nohitsTable">
<Properties>
<Property name="model" type="javax.swing.table.TableModel" editor="org.netbeans.modules.form.editors2.TableModelEditor">
<Table columnCount="1" rowCount="4">
<Column editable="false" title="Keyword" type="java.lang.String"/>
</Table>
</Property>
<Property name="tableHeader" type="javax.swing.table.JTableHeader" editor="org.netbeans.modules.form.editors2.JTableHeaderEditor">
<TableHeader reorderingAllowed="false" resizingAllowed="true"/>
</Property>
</Properties>
</Component>
</SubComponents>
</Container>
</SubComponents>
</Form>

View File

@ -0,0 +1,320 @@
/*
* Autopsy Forensic Browser
*
* Copyright 2011 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.Component;
import java.awt.event.ActionListener;
import java.util.Map;
import java.util.logging.Logger;
import javax.swing.JTable;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.TableColumn;
import org.openide.util.NbBundle;
import org.openide.windows.TopComponent;
import org.netbeans.api.settings.ConvertAsProperties;
import org.openide.awt.ActionID;
import org.openide.awt.ActionReference;
/**
* Top component with saved searches viewer
*/
@ConvertAsProperties(dtd = "-//org.sleuthkit.autopsy.keywordsearch//KeywordSearchHistory//EN",
autostore = false)
@TopComponent.Description(preferredID = "KeywordSearchHistoryTopComponent",
//iconBase="SET/PATH/TO/ICON/HERE",
persistenceType = TopComponent.PERSISTENCE_NEVER)
@TopComponent.Registration(mode = "explorer", openAtStartup = false)
@ActionID(category = "Window", id = "org.sleuthkit.autopsy.keywordsearch.KeywordSearchHistoryTopComponent")
@ActionReference(path = "Menu/Window" /*, position = 333 */)
@TopComponent.OpenActionRegistration(displayName = "#CTL_KeywordSearchHistoryAction",
preferredID = "KeywordSearchHistoryTopComponent")
public final class KeywordSearchHistoryTopComponent extends TopComponent implements KeywordSearchTopComponentInterface {
private Logger logger = Logger.getLogger(KeywordSearchHistoryTopComponent.class.getName());
public KeywordSearchHistoryTopComponent() {
initComponents();
customizeComponents();
setName(NbBundle.getMessage(KeywordSearchHistoryTopComponent.class, "CTL_KeywordSearchHistoryTopComponent"));
setToolTipText(NbBundle.getMessage(KeywordSearchHistoryTopComponent.class, "HINT_KeywordSearchHistoryTopComponent"));
putClientProperty(TopComponent.PROP_UNDOCKING_DISABLED, Boolean.TRUE);
}
private void customizeComponents() {
hitsTable.setToolTipText("Saved searches with hits: click on the row to view search results.");
nohitsTable.setToolTipText("Saved searches without hits.");
hitsTable.setAutoscrolls(true);
hitsTable.setShowHorizontalLines(false);
hitsTable.setShowVerticalLines(false);
hitsTable.getParent().setBackground(hitsTable.getBackground());
//customize column witdhs
hitsTable.setSize(260, 200);
final int width = hitsTable.getSize().width;
TableColumn column = null;
for (int i = 0; i < 2; i++) {
column = hitsTable.getColumnModel().getColumn(i);
switch (i) {
case 0:
column.setCellRenderer(new CellTooltipRenderer());
column.setPreferredWidth(((int) (width * 0.80)));
column.setResizable(true);
break;
case 1:
column.setPreferredWidth(((int) (width * 0.15)));
column.setResizable(false);
break;
default:
break;
}
}
hitsTable.setCellSelectionEnabled(false);
nohitsTable.setAutoscrolls(true);
nohitsTable.setShowHorizontalLines(false);
nohitsTable.setShowVerticalLines(false);
nohitsTable.getParent().setBackground(nohitsTable.getBackground());
//customize column witdhs
nohitsTable.setSize(260, 200);
column = nohitsTable.getColumnModel().getColumn(0);
column.setCellRenderer(new CellTooltipRenderer());
nohitsTable.setCellSelectionEnabled(false);
}
/** 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.
*/
// <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
private void initComponents() {
topLabel = new javax.swing.JLabel();
filesIndexedNameLabel = new javax.swing.JLabel();
filesIndexedValLabel = new javax.swing.JLabel();
withHitsLabel = new javax.swing.JLabel();
noHitsLabel = new javax.swing.JLabel();
jScrollPane1 = new javax.swing.JScrollPane();
hitsTable = new javax.swing.JTable();
jScrollPane2 = new javax.swing.JScrollPane();
nohitsTable = new javax.swing.JTable();
org.openide.awt.Mnemonics.setLocalizedText(topLabel, org.openide.util.NbBundle.getMessage(KeywordSearchHistoryTopComponent.class, "KeywordSearchHistoryTopComponent.topLabel.text")); // NOI18N
org.openide.awt.Mnemonics.setLocalizedText(filesIndexedNameLabel, org.openide.util.NbBundle.getMessage(KeywordSearchHistoryTopComponent.class, "KeywordSearchHistoryTopComponent.filesIndexedNameLabel.text")); // NOI18N
org.openide.awt.Mnemonics.setLocalizedText(filesIndexedValLabel, org.openide.util.NbBundle.getMessage(KeywordSearchHistoryTopComponent.class, "KeywordSearchHistoryTopComponent.filesIndexedValLabel.text")); // NOI18N
org.openide.awt.Mnemonics.setLocalizedText(withHitsLabel, org.openide.util.NbBundle.getMessage(KeywordSearchHistoryTopComponent.class, "KeywordSearchHistoryTopComponent.withHitsLabel.text")); // NOI18N
org.openide.awt.Mnemonics.setLocalizedText(noHitsLabel, org.openide.util.NbBundle.getMessage(KeywordSearchHistoryTopComponent.class, "KeywordSearchHistoryTopComponent.noHitsLabel.text")); // NOI18N
hitsTable.setModel(new javax.swing.table.DefaultTableModel(
new Object [][] {
{null, null},
{null, null},
{null, null},
{null, null}
},
new String [] {
"Keyword", "#Hits"
}
) {
Class[] types = new Class [] {
java.lang.String.class, java.lang.Integer.class
};
boolean[] canEdit = new boolean [] {
false, false
};
public Class getColumnClass(int columnIndex) {
return types [columnIndex];
}
public boolean isCellEditable(int rowIndex, int columnIndex) {
return canEdit [columnIndex];
}
});
hitsTable.getTableHeader().setReorderingAllowed(false);
jScrollPane1.setViewportView(hitsTable);
nohitsTable.setModel(new javax.swing.table.DefaultTableModel(
new Object [][] {
{null},
{null},
{null},
{null}
},
new String [] {
"Keyword"
}
) {
Class[] types = new Class [] {
java.lang.String.class
};
boolean[] canEdit = new boolean [] {
false
};
public Class getColumnClass(int columnIndex) {
return types [columnIndex];
}
public boolean isCellEditable(int rowIndex, int columnIndex) {
return canEdit [columnIndex];
}
});
nohitsTable.getTableHeader().setReorderingAllowed(false);
jScrollPane2.setViewportView(nohitsTable);
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(jScrollPane2, javax.swing.GroupLayout.PREFERRED_SIZE, 275, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 275, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(topLabel)
.addComponent(withHitsLabel)
.addComponent(noHitsLabel)
.addGroup(layout.createSequentialGroup()
.addComponent(filesIndexedNameLabel)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
.addComponent(filesIndexedValLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 72, javax.swing.GroupLayout.PREFERRED_SIZE)))
.addContainerGap(15, Short.MAX_VALUE))
);
layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addGap(23, 23, 23)
.addComponent(topLabel)
.addGap(27, 27, 27)
.addComponent(withHitsLabel)
.addGap(18, 18, 18)
.addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 229, javax.swing.GroupLayout.PREFERRED_SIZE)
.addGap(30, 30, 30)
.addComponent(noHitsLabel)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(jScrollPane2, javax.swing.GroupLayout.PREFERRED_SIZE, 234, javax.swing.GroupLayout.PREFERRED_SIZE)
.addGap(35, 35, 35)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(filesIndexedNameLabel)
.addComponent(filesIndexedValLabel))
.addContainerGap(34, Short.MAX_VALUE))
);
}// </editor-fold>//GEN-END:initComponents
// Variables declaration - do not modify//GEN-BEGIN:variables
private javax.swing.JLabel filesIndexedNameLabel;
private javax.swing.JLabel filesIndexedValLabel;
private javax.swing.JTable hitsTable;
private javax.swing.JScrollPane jScrollPane1;
private javax.swing.JScrollPane jScrollPane2;
private javax.swing.JLabel noHitsLabel;
private javax.swing.JTable nohitsTable;
private javax.swing.JLabel topLabel;
private javax.swing.JLabel withHitsLabel;
// End of variables declaration//GEN-END:variables
@Override
public void componentOpened() {
}
@Override
public void componentClosed() {
}
void writeProperties(java.util.Properties p) {
// better to version settings since initial version as advocated at
// http://wiki.apidesign.org/wiki/PropertyFiles
p.setProperty("version", "1.0");
}
void readProperties(java.util.Properties p) {
}
@Override
public void addSearchButtonListener(ActionListener l) {
}
@Override
public Map<String, Boolean> getQueryList() {
return null;
}
@Override
public String getQueryText() {
throw new UnsupportedOperationException("Not supported yet.");
}
@Override
public boolean isLuceneQuerySelected() {
return false;
}
@Override
public boolean isMultiwordQuery() {
return false;
}
@Override
public boolean isRegexQuerySelected() {
return false;
}
@Override
public void setFilesIndexed(int filesIndexed) {
filesIndexedValLabel.setText(Integer.toString(filesIndexed));
}
/**
* tooltips that show text
*/
private static class CellTooltipRenderer extends DefaultTableCellRenderer {
@Override
public Component getTableCellRendererComponent(
JTable table, Object value,
boolean isSelected, boolean hasFocus,
int row, int column) {
if (column == 0) {
String val = (String) table.getModel().getValueAt(row, column);
setToolTipText(val);
setText(val);
} else if (column == 1) {
Integer ival = (Integer) table.getModel().getValueAt(row, column);
String val = Integer.toString(ival);
setToolTipText(val);
setText(val);
}
return this;
}
}
}

View File

@ -0,0 +1,148 @@
<?xml version="1.1" encoding="UTF-8" ?>
<Form version="1.5" maxVersion="1.7" type="org.netbeans.modules.form.forminfo.JPanelFormInfo">
<AuxValues>
<AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="1"/>
<AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/>
<AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/>
<AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="true"/>
<AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="true"/>
<AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/>
<AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/>
<AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/>
<AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/>
</AuxValues>
<Layout>
<DimensionLayout dim="0">
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" attributes="0">
<EmptySpace max="-2" attributes="0"/>
<Group type="103" groupAlignment="0" attributes="0">
<Component id="jScrollPane1" alignment="0" min="-2" pref="266" max="-2" attributes="1"/>
<Component id="topLabel" alignment="0" min="-2" max="-2" attributes="0"/>
<Component id="curKeywordsLabel" alignment="0" min="-2" max="-2" attributes="0"/>
<Group type="102" alignment="0" attributes="0">
<Component id="importButton" min="-2" max="-2" attributes="0"/>
<EmptySpace min="-2" pref="22" max="-2" attributes="0"/>
<Component id="exportButton" min="-2" max="-2" attributes="0"/>
<EmptySpace type="separate" max="-2" attributes="0"/>
<Component id="deleteButton" min="-2" max="-2" attributes="0"/>
</Group>
<Group type="102" alignment="0" attributes="0">
<Component id="filesIndexedNameLabel" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="filesIndexedValLabel" min="-2" pref="62" max="-2" attributes="0"/>
</Group>
</Group>
<EmptySpace pref="20" max="32767" attributes="0"/>
</Group>
</Group>
</DimensionLayout>
<DimensionLayout dim="1">
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" alignment="0" attributes="0">
<EmptySpace max="-2" attributes="0"/>
<Component id="topLabel" min="-2" max="-2" attributes="0"/>
<EmptySpace min="-2" pref="35" max="-2" attributes="0"/>
<Component id="curKeywordsLabel" min="-2" max="-2" attributes="0"/>
<EmptySpace type="unrelated" max="-2" attributes="0"/>
<Component id="jScrollPane1" min="-2" pref="227" max="-2" attributes="0"/>
<EmptySpace min="-2" pref="29" max="-2" attributes="0"/>
<Group type="103" groupAlignment="3" attributes="0">
<Component id="importButton" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="deleteButton" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="exportButton" alignment="3" min="-2" max="-2" attributes="0"/>
</Group>
<EmptySpace min="-2" pref="37" max="-2" attributes="0"/>
<Group type="103" groupAlignment="3" attributes="0">
<Component id="filesIndexedNameLabel" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="filesIndexedValLabel" alignment="3" min="-2" max="-2" attributes="0"/>
</Group>
<EmptySpace pref="62" max="32767" attributes="0"/>
</Group>
</Group>
</DimensionLayout>
</Layout>
<SubComponents>
<Container class="javax.swing.JScrollPane" name="jScrollPane1">
<AuxValues>
<AuxValue name="autoScrollPane" type="java.lang.Boolean" value="true"/>
</AuxValues>
<Layout class="org.netbeans.modules.form.compat2.layouts.support.JScrollPaneSupportLayout"/>
<SubComponents>
<Component class="javax.swing.JTable" name="listsTable">
<Properties>
<Property name="model" type="javax.swing.table.TableModel" editor="org.netbeans.modules.form.RADConnectionPropertyEditor">
<Connection code="tableModel" type="code"/>
</Property>
<Property name="showHorizontalLines" type="boolean" value="false"/>
<Property name="showVerticalLines" type="boolean" value="false"/>
<Property name="tableHeader" type="javax.swing.table.JTableHeader" editor="org.netbeans.modules.form.editors2.JTableHeaderEditor">
<TableHeader reorderingAllowed="false" resizingAllowed="true"/>
</Property>
</Properties>
</Component>
</SubComponents>
</Container>
<Component class="javax.swing.JLabel" name="topLabel">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/keywordsearch/Bundle.properties" key="KeywordSearchListImportExportTopComponent.topLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
</Component>
<Component class="javax.swing.JLabel" name="curKeywordsLabel">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/keywordsearch/Bundle.properties" key="KeywordSearchListImportExportTopComponent.curKeywordsLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
</Component>
<Component class="javax.swing.JButton" name="importButton">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/keywordsearch/Bundle.properties" key="KeywordSearchListImportExportTopComponent.importButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="importButtonActionPerformed"/>
</Events>
</Component>
<Component class="javax.swing.JButton" name="exportButton">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/keywordsearch/Bundle.properties" key="KeywordSearchListImportExportTopComponent.exportButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="exportButtonActionPerformed"/>
</Events>
</Component>
<Component class="javax.swing.JButton" name="deleteButton">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/keywordsearch/Bundle.properties" key="KeywordSearchListImportExportTopComponent.deleteButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="deleteButtonActionPerformed"/>
</Events>
</Component>
<Component class="javax.swing.JLabel" name="filesIndexedNameLabel">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/keywordsearch/Bundle.properties" key="KeywordSearchListImportExportTopComponent.filesIndexedNameLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
</Component>
<Component class="javax.swing.JLabel" name="filesIndexedValLabel">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/keywordsearch/Bundle.properties" key="KeywordSearchListImportExportTopComponent.filesIndexedValLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
</Component>
</SubComponents>
</Form>

View File

@ -0,0 +1,648 @@
/*
* Autopsy Forensic Browser
*
* Copyright 2011 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.Component;
import java.awt.event.ActionListener;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.io.File;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeSet;
import java.util.logging.Logger;
import javax.swing.JFileChooser;
import javax.swing.JOptionPane;
import javax.swing.JTable;
import javax.swing.filechooser.FileNameExtensionFilter;
import javax.swing.table.AbstractTableModel;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.TableColumn;
import org.openide.util.NbBundle;
import org.openide.windows.TopComponent;
import org.netbeans.api.settings.ConvertAsProperties;
import org.openide.awt.ActionID;
import org.openide.awt.ActionReference;
/**
* Top component which displays something.
*/
@ConvertAsProperties(dtd = "-//org.sleuthkit.autopsy.keywordsearch//KeywordSearchListImportExport//EN",
autostore = false)
@TopComponent.Description(preferredID = "KeywordSearchListImportExportTopComponent",
//iconBase="SET/PATH/TO/ICON/HERE",
persistenceType = TopComponent.PERSISTENCE_NEVER)
@TopComponent.Registration(mode = "explorer", openAtStartup = false)
@ActionID(category = "Window", id = "org.sleuthkit.autopsy.keywordsearch.KeywordSearchListImportExportTopComponent")
@ActionReference(path = "Menu/Window" /*, position = 333 */)
@TopComponent.OpenActionRegistration(displayName = "#CTL_KeywordSearchListImportExportAction",
preferredID = "KeywordSearchListImportExportTopComponent")
public final class KeywordSearchListImportExportTopComponent extends TopComponent implements KeywordSearchTopComponentInterface {
private Logger logger = Logger.getLogger(KeywordSearchListImportExportTopComponent.class.getName());
private KeywordListTableModel tableModel;
public KeywordSearchListImportExportTopComponent() {
tableModel = new KeywordListTableModel();
initComponents();
customizeComponents();
setName(NbBundle.getMessage(KeywordSearchListImportExportTopComponent.class, "CTL_KeywordSearchListImportExportTopComponent"));
setToolTipText(NbBundle.getMessage(KeywordSearchListImportExportTopComponent.class, "HINT_KeywordSearchListImportExportTopComponent"));
}
private void customizeComponents() {
importButton.setToolTipText("Import list(s) of keywords from an external file.");
exportButton.setToolTipText("Export selected list(s) of keywords to an external file.");
deleteButton.setToolTipText("Delete selected list(s) of keywords.");
listsTable.setAutoscrolls(true);
//listsTable.setTableHeader(null);
listsTable.setShowHorizontalLines(false);
listsTable.setShowVerticalLines(false);
listsTable.getParent().setBackground(listsTable.getBackground());
//customize column witdhs
listsTable.setSize(260, 200);
final int width = listsTable.getSize().width;
TableColumn column = null;
for (int i = 0; i < 4; i++) {
column = listsTable.getColumnModel().getColumn(i);
switch (i) {
case 0:
case 1:
case 2:
column.setCellRenderer(new CellTooltipRenderer());
column.setPreferredWidth(((int) (width * 0.28)));
column.setResizable(true);
break;
case 3:
column.setPreferredWidth(((int) (width * 0.15)));
column.setResizable(false);
break;
default:
break;
}
}
listsTable.setCellSelectionEnabled(false);
tableModel.resync();
if (KeywordSearchListsXML.getCurrent().getNumberLists() == 0) {
exportButton.setEnabled(false);
}
KeywordSearchListsXML.getCurrent().addPropertyChangeListener(new PropertyChangeListener() {
@Override
public void propertyChange(PropertyChangeEvent evt) {
if (evt.getPropertyName().equals(KeywordSearchListsXML.ListsEvt.LIST_ADDED.toString())
|| evt.getPropertyName().equals(KeywordSearchListsXML.ListsEvt.LIST_DELETED.toString())) {
tableModel.resync();
if (Integer.valueOf((Integer) evt.getNewValue()) == 0) {
exportButton.setEnabled(false);
} else if (Integer.valueOf((Integer) evt.getOldValue()) == 0) {
exportButton.setEnabled(true);
}
} else if (evt.getPropertyName().equals(KeywordSearchListsXML.ListsEvt.LIST_UPDATED.toString())) {
tableModel.resync((String) evt.getNewValue()); //changed list name
}
}
});
}
/** 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.
*/
// <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
private void initComponents() {
jScrollPane1 = new javax.swing.JScrollPane();
listsTable = new javax.swing.JTable();
topLabel = new javax.swing.JLabel();
curKeywordsLabel = new javax.swing.JLabel();
importButton = new javax.swing.JButton();
exportButton = new javax.swing.JButton();
deleteButton = new javax.swing.JButton();
filesIndexedNameLabel = new javax.swing.JLabel();
filesIndexedValLabel = new javax.swing.JLabel();
listsTable.setModel(tableModel);
listsTable.setShowHorizontalLines(false);
listsTable.setShowVerticalLines(false);
listsTable.getTableHeader().setReorderingAllowed(false);
jScrollPane1.setViewportView(listsTable);
org.openide.awt.Mnemonics.setLocalizedText(topLabel, org.openide.util.NbBundle.getMessage(KeywordSearchListImportExportTopComponent.class, "KeywordSearchListImportExportTopComponent.topLabel.text")); // NOI18N
org.openide.awt.Mnemonics.setLocalizedText(curKeywordsLabel, org.openide.util.NbBundle.getMessage(KeywordSearchListImportExportTopComponent.class, "KeywordSearchListImportExportTopComponent.curKeywordsLabel.text")); // NOI18N
org.openide.awt.Mnemonics.setLocalizedText(importButton, org.openide.util.NbBundle.getMessage(KeywordSearchListImportExportTopComponent.class, "KeywordSearchListImportExportTopComponent.importButton.text")); // NOI18N
importButton.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
importButtonActionPerformed(evt);
}
});
org.openide.awt.Mnemonics.setLocalizedText(exportButton, org.openide.util.NbBundle.getMessage(KeywordSearchListImportExportTopComponent.class, "KeywordSearchListImportExportTopComponent.exportButton.text")); // NOI18N
exportButton.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
exportButtonActionPerformed(evt);
}
});
org.openide.awt.Mnemonics.setLocalizedText(deleteButton, org.openide.util.NbBundle.getMessage(KeywordSearchListImportExportTopComponent.class, "KeywordSearchListImportExportTopComponent.deleteButton.text")); // NOI18N
deleteButton.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
deleteButtonActionPerformed(evt);
}
});
org.openide.awt.Mnemonics.setLocalizedText(filesIndexedNameLabel, org.openide.util.NbBundle.getMessage(KeywordSearchListImportExportTopComponent.class, "KeywordSearchListImportExportTopComponent.filesIndexedNameLabel.text")); // NOI18N
org.openide.awt.Mnemonics.setLocalizedText(filesIndexedValLabel, org.openide.util.NbBundle.getMessage(KeywordSearchListImportExportTopComponent.class, "KeywordSearchListImportExportTopComponent.filesIndexedValLabel.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.PREFERRED_SIZE, 266, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(topLabel)
.addComponent(curKeywordsLabel)
.addGroup(layout.createSequentialGroup()
.addComponent(importButton)
.addGap(22, 22, 22)
.addComponent(exportButton)
.addGap(18, 18, 18)
.addComponent(deleteButton))
.addGroup(layout.createSequentialGroup()
.addComponent(filesIndexedNameLabel)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(filesIndexedValLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 62, javax.swing.GroupLayout.PREFERRED_SIZE)))
.addContainerGap(20, Short.MAX_VALUE))
);
layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addContainerGap()
.addComponent(topLabel)
.addGap(35, 35, 35)
.addComponent(curKeywordsLabel)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
.addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 227, javax.swing.GroupLayout.PREFERRED_SIZE)
.addGap(29, 29, 29)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(importButton)
.addComponent(deleteButton)
.addComponent(exportButton))
.addGap(37, 37, 37)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(filesIndexedNameLabel)
.addComponent(filesIndexedValLabel))
.addContainerGap(62, Short.MAX_VALUE))
);
}// </editor-fold>//GEN-END:initComponents
public void importButtonAction(java.awt.event.ActionEvent evt) {
importButtonActionPerformed(evt);
}
private void importButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_importButtonActionPerformed
final String FEATURE_NAME = "Keyword List Import";
JFileChooser chooser = new JFileChooser();
final String EXTENSION = "xml";
FileNameExtensionFilter filter = new FileNameExtensionFilter(
"Keyword List XML file", EXTENSION);
chooser.setFileFilter(filter);
chooser.setFileSelectionMode(JFileChooser.FILES_ONLY);
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 KeywordSearchListsXML reader = new KeywordSearchListsXML(fileAbs);
if (!reader.load()) {
KeywordSearchUtil.displayDialog(FEATURE_NAME, "Error importing keyword list from file " + fileAbs, KeywordSearchUtil.DIALOG_MESSAGE_TYPE.ERROR);
return;
}
List<KeywordSearchList> toImport = reader.getListsL();
List<KeywordSearchList> toImportConfirmed = new ArrayList<KeywordSearchList>();
final KeywordSearchListsXML writer = KeywordSearchListsXML.getCurrent();
for (KeywordSearchList list : toImport) {
//check name collisions
if (writer.listExists(list.getName())) {
Object[] options = {"Yes, overwrite",
"No, skip",
"Cancel import"};
int choice = JOptionPane.showOptionDialog(this,
"Keyword list <" + list.getName() + "> already exists locally, overwrite?",
"Import list conflict",
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(FEATURE_NAME, "Keyword list imported", KeywordSearchUtil.DIALOG_MESSAGE_TYPE.INFO);
}
}
}//GEN-LAST:event_importButtonActionPerformed
private void exportButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_exportButtonActionPerformed
final String FEATURE_NAME = "Keyword List Export";
List<String> toExport = tableModel.getSelectedLists();
if (toExport.isEmpty()) {
KeywordSearchUtil.displayDialog(FEATURE_NAME, "Please select keyword lists to export", KeywordSearchUtil.DIALOG_MESSAGE_TYPE.ERROR);
return;
}
JFileChooser chooser = new JFileChooser();
final String EXTENSION = "xml";
FileNameExtensionFilter filter = new FileNameExtensionFilter(
"Keyword List XML file", EXTENSION);
chooser.setFileFilter(filter);
chooser.setFileSelectionMode(JFileChooser.FILES_ONLY);
int returnVal = chooser.showSaveDialog(this);
if (returnVal == JFileChooser.APPROVE_OPTION) {
File selFile = chooser.getSelectedFile();
if (selFile == null) {
return;
}
//force append extension if not given
String fileAbs = selFile.getAbsolutePath();
if (!fileAbs.endsWith("." + EXTENSION)) {
fileAbs = fileAbs + "." + EXTENSION;
selFile = new File(fileAbs);
}
boolean shouldWrite = true;
if (selFile.exists()) {
shouldWrite = KeywordSearchUtil.displayConfirmDialog(FEATURE_NAME, "File " + selFile.getName() + " exists, overwrite?", KeywordSearchUtil.DIALOG_MESSAGE_TYPE.WARN);
}
if (!shouldWrite) {
return;
}
final KeywordSearchListsXML reader = KeywordSearchListsXML.getCurrent();
List<KeywordSearchList> toWrite = new ArrayList<KeywordSearchList>();
for (String listName : toExport) {
toWrite.add(reader.getList(listName));
}
final KeywordSearchListsXML exporter = new KeywordSearchListsXML(fileAbs);
boolean written = exporter.writeLists(toWrite);
if (written) {
KeywordSearchUtil.displayDialog(FEATURE_NAME, "Keyword lists exported", KeywordSearchUtil.DIALOG_MESSAGE_TYPE.INFO);
return;
}
}
}//GEN-LAST:event_exportButtonActionPerformed
private void deleteButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_deleteButtonActionPerformed
tableModel.deleteSelected();
}//GEN-LAST:event_deleteButtonActionPerformed
// Variables declaration - do not modify//GEN-BEGIN:variables
private javax.swing.JLabel curKeywordsLabel;
private javax.swing.JButton deleteButton;
private javax.swing.JButton exportButton;
private javax.swing.JLabel filesIndexedNameLabel;
private javax.swing.JLabel filesIndexedValLabel;
private javax.swing.JButton importButton;
private javax.swing.JScrollPane jScrollPane1;
private javax.swing.JTable listsTable;
private javax.swing.JLabel topLabel;
// End of variables declaration//GEN-END:variables
@Override
public void componentOpened() {
}
@Override
public void componentClosed() {
}
void writeProperties(java.util.Properties p) {
p.setProperty("version", "1.0");
}
void readProperties(java.util.Properties p) {
}
@Override
public void addSearchButtonListener(ActionListener l) {
}
@Override
public Map<String, Boolean> getQueryList() {
return null;
}
@Override
public String getQueryText() {
return null;
}
@Override
public boolean isLuceneQuerySelected() {
return false;
}
@Override
public boolean isMultiwordQuery() {
return false;
}
@Override
public boolean isRegexQuerySelected() {
return false;
}
@Override
public void setFilesIndexed(int filesIndexed) {
filesIndexedValLabel.setText(Integer.toString(filesIndexed));
}
static class KeywordListTableModel extends AbstractTableModel {
//data
private KeywordSearchListsXML listsHandle = KeywordSearchListsXML.getCurrent();
private Set<TableEntry> listData = new TreeSet<TableEntry>();
@Override
public int getColumnCount() {
return 4;
}
@Override
public int getRowCount() {
return listData.size();
}
@Override
public String getColumnName(int column) {
String colName = null;
switch (column) {
case 0:
colName = "Name";
break;
case 1:
colName = "Created";
break;
case 2:
colName = "Modified";
break;
case 3:
colName = "Sel.";
break;
default:
;
}
return colName;
}
@Override
public Object getValueAt(int rowIndex, int columnIndex) {
Object ret = null;
TableEntry entry = null;
//iterate until row
Iterator<TableEntry> it = listData.iterator();
for (int i = 0; i <= rowIndex; ++i) {
entry = it.next();
}
switch (columnIndex) {
case 0:
ret = (Object) entry.name;
break;
case 1:
ret = (Object) entry.created;
break;
case 2:
ret = (Object) entry.modified;
break;
case 3:
ret = (Object) entry.isActive;
break;
default:
break;
}
return ret;
}
@Override
public boolean isCellEditable(int rowIndex, int columnIndex) {
return columnIndex == 3 ? true : false;
}
@Override
public void setValueAt(Object aValue, int rowIndex, int columnIndex) {
if (columnIndex == 3) {
TableEntry entry = null;
//iterate until row
Iterator<TableEntry> it = listData.iterator();
for (int i = 0; i <= rowIndex; ++i) {
entry = it.next();
}
entry.isActive = (Boolean) aValue;
}
}
@Override
public Class getColumnClass(int c) {
return getValueAt(0, c).getClass();
}
List<String> getAllLists() {
List<String> ret = new ArrayList<String>();
for (TableEntry e : listData) {
ret.add(e.name);
}
return ret;
}
List<String> getSelectedLists() {
List<String> ret = new ArrayList<String>();
for (TableEntry e : listData) {
if (e.isActive && !e.name.equals("")) {
ret.add(e.name);
}
}
return ret;
}
boolean listExists(String list) {
List<String> all = getAllLists();
return all.contains(list);
}
//delete selected from handle, events are fired from the handle
void deleteSelected() {
List<TableEntry> toDel = new ArrayList<TableEntry>();
for (TableEntry e : listData) {
if (e.isActive && !e.name.equals("")) {
toDel.add(e);
}
}
for (TableEntry del : toDel) {
listsHandle.deleteList(del.name);
}
}
//resync model from handle, then update table
void resync() {
listData.clear();
addLists(listsHandle.getListsL());
fireTableDataChanged();
}
//resync single model entry from handle, then update table
void resync(String listName) {
TableEntry found = null;
for (TableEntry e : listData) {
if (e.name.equals(listName)) {
found = e;
break;
}
}
if (found != null) {
listData.remove(found);
addList(listsHandle.getList(listName));
}
fireTableDataChanged();
}
//add list to the model
private void addList(KeywordSearchList list) {
if (!listExists(list.getName())) {
listData.add(new TableEntry(list));
}
}
//add lists to the model
private void addLists(List<KeywordSearchList> lists) {
for (KeywordSearchList list : lists) {
if (!listExists(list.getName())) {
listData.add(new TableEntry(list));
}
}
}
//single model entry
class TableEntry implements Comparable {
private DateFormat dateFormatter = new SimpleDateFormat("yyyy-MM-dd HH:mm");
String name;
String created;
String modified;
Boolean isActive;
TableEntry(KeywordSearchList list, Boolean isActive) {
this.name = list.getName();
this.created = dateFormatter.format(list.getDateCreated());
this.modified = dateFormatter.format(list.getDateModified());
this.isActive = isActive;
}
TableEntry(KeywordSearchList list) {
this.name = list.getName();
this.created = dateFormatter.format(list.getDateCreated());
this.modified = dateFormatter.format(list.getDateModified());
this.isActive = false;
}
@Override
public int compareTo(Object o) {
return this.name.compareTo(((TableEntry) o).name);
}
}
}
/**
* tooltips that show text
*/
private static class CellTooltipRenderer extends DefaultTableCellRenderer {
@Override
public Component getTableCellRendererComponent(
JTable table, Object value,
boolean isSelected, boolean hasFocus,
int row, int column) {
if (column < 3) {
String val = (String) table.getModel().getValueAt(row, column);
setToolTipText(val);
setText(val);
}
return this;
}
}
}

View File

@ -21,15 +21,12 @@
<Group type="103" groupAlignment="0" attributes="0">
<Component id="chLiteralWord" alignment="0" min="-2" max="-2" attributes="0"/>
<Component id="titleLabel" alignment="0" min="-2" max="-2" attributes="0"/>
<Component id="loadListButton" alignment="0" min="-2" max="-2" attributes="0"/>
<Component id="addWordLabel" alignment="0" min="-2" max="-2" attributes="0"/>
<Group type="102" alignment="0" attributes="1">
<Component id="deleteWordButton" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="deleteAllWordsButton" min="-2" max="-2" attributes="0"/>
<Group type="102" alignment="0" attributes="0">
<Component id="loadListButton" min="-2" max="-2" attributes="0"/>
<EmptySpace type="separate" max="-2" attributes="0"/>
<Component id="saveListButton" min="-2" max="-2" attributes="0"/>
<Component id="importButton" min="-2" max="-2" attributes="0"/>
</Group>
<Component id="addWordLabel" alignment="0" min="-2" max="-2" attributes="0"/>
<Group type="102" alignment="0" attributes="0">
<Component id="addWordField" min="-2" pref="152" max="-2" attributes="0"/>
<EmptySpace min="-2" pref="31" max="-2" attributes="0"/>
@ -43,6 +40,20 @@
<Component id="filesIndexedValLabel" min="-2" max="-2" attributes="0"/>
</Group>
<Component id="jScrollPane1" alignment="0" min="-2" pref="272" max="-2" attributes="0"/>
<Group type="103" alignment="0" groupAlignment="1" max="-2" attributes="0">
<Group type="102" alignment="0" attributes="1">
<Component id="curListNameLabel" min="-2" max="-2" attributes="0"/>
<EmptySpace type="separate" max="-2" attributes="0"/>
<Component id="curListValLabel" max="32767" attributes="0"/>
</Group>
<Group type="102" alignment="0" attributes="1">
<Component id="deleteWordButton" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="deleteAllWordsButton" min="-2" max="-2" attributes="0"/>
<EmptySpace type="separate" max="-2" attributes="0"/>
<Component id="saveListButton" min="-2" max="-2" attributes="0"/>
</Group>
</Group>
</Group>
<EmptySpace pref="15" max="32767" attributes="0"/>
</Group>
@ -54,7 +65,10 @@
<EmptySpace max="-2" attributes="0"/>
<Component id="titleLabel" min="-2" max="-2" attributes="0"/>
<EmptySpace type="separate" max="-2" attributes="0"/>
<Component id="loadListButton" min="-2" max="-2" attributes="0"/>
<Group type="103" groupAlignment="3" attributes="0">
<Component id="loadListButton" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="importButton" alignment="3" min="-2" max="-2" attributes="0"/>
</Group>
<EmptySpace min="-2" pref="19" max="-2" attributes="0"/>
<Component id="addWordLabel" min="-2" max="-2" attributes="0"/>
<EmptySpace type="separate" max="-2" attributes="0"/>
@ -76,7 +90,12 @@
</Group>
<EmptySpace min="-2" pref="29" max="-2" attributes="0"/>
<Component id="searchButton" min="-2" max="-2" attributes="0"/>
<EmptySpace min="-2" pref="38" max="-2" attributes="0"/>
<EmptySpace min="-2" pref="18" max="-2" attributes="0"/>
<Group type="103" groupAlignment="3" attributes="0">
<Component id="curListNameLabel" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="curListValLabel" alignment="3" min="-2" max="-2" attributes="0"/>
</Group>
<EmptySpace max="-2" attributes="0"/>
<Group type="103" groupAlignment="3" attributes="0">
<Component id="filesIndexedNameLabel" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="filesIndexedValLabel" alignment="3" min="-2" max="-2" attributes="0"/>
@ -218,5 +237,29 @@
</Component>
</SubComponents>
</Container>
<Component class="javax.swing.JLabel" name="curListNameLabel">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/keywordsearch/Bundle.properties" key="KeywordSearchListTopComponent.curListNameLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
</Component>
<Component class="javax.swing.JLabel" name="curListValLabel">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/keywordsearch/Bundle.properties" key="KeywordSearchListTopComponent.curListValLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
</Component>
<Component class="javax.swing.JButton" name="importButton">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/keywordsearch/Bundle.properties" key="KeywordSearchListTopComponent.importButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="importButtonActionPerformed"/>
</Events>
</Component>
</SubComponents>
</Form>

View File

@ -23,6 +23,8 @@ import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.LinkedHashMap;
@ -40,6 +42,7 @@ import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JPopupMenu;
import javax.swing.JTabbedPane;
import javax.swing.JTable;
import javax.swing.table.AbstractTableModel;
import javax.swing.table.DefaultTableCellRenderer;
@ -49,6 +52,7 @@ import org.openide.windows.TopComponent;
import org.netbeans.api.settings.ConvertAsProperties;
import org.openide.awt.ActionID;
import org.openide.awt.ActionReference;
import org.sleuthkit.autopsy.keywordsearch.KeywordSearchTabsTopComponent.TABS;
/**
* Top component which displays something.
@ -58,7 +62,7 @@ autostore = false)
@TopComponent.Description(preferredID = "KeywordSearchListTopComponent",
//iconBase="SET/PATH/TO/ICON/HERE",
persistenceType = TopComponent.PERSISTENCE_NEVER)
@TopComponent.Registration(mode = "output", openAtStartup = false)
@TopComponent.Registration(mode = "explorer", openAtStartup = false)
@ActionID(category = "Window", id = "org.sleuthkit.autopsy.keywordsearch.KeywordSearchListTopComponent")
@ActionReference(path = "Menu/Window" /*, position = 333 */)
@TopComponent.OpenActionRegistration(displayName = "#CTL_KeywordSearchListAction",
@ -84,6 +88,7 @@ public final class KeywordSearchListTopComponent extends TopComponent implements
addWordField.setToolTipText("Enter a new word or regex to search");
loadListButton.setToolTipText("Load a new keyword list from file or delete an existing list");
importButton.setToolTipText("Import list(s) of keywords from an external file.");
saveListButton.setToolTipText("Save the current keyword list to a file");
searchButton.setToolTipText("Execute the keyword list search using the current list");
deleteWordButton.setToolTipText("Delete selected keyword(s) from the list");
@ -114,7 +119,26 @@ public final class KeywordSearchListTopComponent extends TopComponent implements
loadDefaultKeywords();
if (KeywordSearchListsXML.getInstance().getNumberLists() == 0) {
KeywordSearchListsXML.getCurrent().addPropertyChangeListener(new PropertyChangeListener() {
@Override
public void propertyChange(PropertyChangeEvent evt) {
if (evt.getPropertyName().equals(KeywordSearchListsXML.ListsEvt.LIST_DELETED.toString())) {
//still keep keywords from deleted list in widgetm just disassociate the name
currentKeywordList = null;
curListValLabel.setText("-");
if (Integer.valueOf((Integer) evt.getNewValue()) == 0) {
loadListButton.setEnabled(false);
}
} else if (evt.getPropertyName().equals(KeywordSearchListsXML.ListsEvt.LIST_ADDED.toString())) {
if (Integer.valueOf((Integer) evt.getOldValue()) == 0) {
loadListButton.setEnabled(true);
}
}
}
});
if (KeywordSearchListsXML.getCurrent().getNumberLists() == 0) {
loadListButton.setEnabled(false);
}
}
@ -160,6 +184,9 @@ public final class KeywordSearchListTopComponent extends TopComponent implements
chLiteralWord = new javax.swing.JCheckBox();
jScrollPane1 = new javax.swing.JScrollPane();
keywordTable = new javax.swing.JTable();
curListNameLabel = new javax.swing.JLabel();
curListValLabel = new javax.swing.JLabel();
importButton = new javax.swing.JButton();
org.openide.awt.Mnemonics.setLocalizedText(searchButton, org.openide.util.NbBundle.getMessage(KeywordSearchListTopComponent.class, "KeywordSearchListTopComponent.searchButton.text")); // NOI18N
searchButton.addActionListener(new java.awt.event.ActionListener() {
@ -228,6 +255,17 @@ public final class KeywordSearchListTopComponent extends TopComponent implements
keywordTable.setShowVerticalLines(false);
jScrollPane1.setViewportView(keywordTable);
org.openide.awt.Mnemonics.setLocalizedText(curListNameLabel, org.openide.util.NbBundle.getMessage(KeywordSearchListTopComponent.class, "KeywordSearchListTopComponent.curListNameLabel.text")); // NOI18N
org.openide.awt.Mnemonics.setLocalizedText(curListValLabel, org.openide.util.NbBundle.getMessage(KeywordSearchListTopComponent.class, "KeywordSearchListTopComponent.curListValLabel.text")); // NOI18N
org.openide.awt.Mnemonics.setLocalizedText(importButton, org.openide.util.NbBundle.getMessage(KeywordSearchListTopComponent.class, "KeywordSearchListTopComponent.importButton.text")); // NOI18N
importButton.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
importButtonActionPerformed(evt);
}
});
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
this.setLayout(layout);
layout.setHorizontalGroup(
@ -237,14 +275,11 @@ public final class KeywordSearchListTopComponent extends TopComponent implements
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(chLiteralWord)
.addComponent(titleLabel)
.addComponent(loadListButton)
.addComponent(addWordLabel)
.addGroup(layout.createSequentialGroup()
.addComponent(deleteWordButton)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(deleteAllWordsButton)
.addComponent(loadListButton)
.addGap(18, 18, 18)
.addComponent(saveListButton))
.addComponent(importButton))
.addComponent(addWordLabel)
.addGroup(layout.createSequentialGroup()
.addComponent(addWordField, javax.swing.GroupLayout.PREFERRED_SIZE, 152, javax.swing.GroupLayout.PREFERRED_SIZE)
.addGap(31, 31, 31)
@ -255,7 +290,18 @@ public final class KeywordSearchListTopComponent extends TopComponent implements
.addComponent(filesIndexedNameLabel)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
.addComponent(filesIndexedValLabel))
.addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 272, javax.swing.GroupLayout.PREFERRED_SIZE))
.addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 272, javax.swing.GroupLayout.PREFERRED_SIZE)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING, false)
.addGroup(javax.swing.GroupLayout.Alignment.LEADING, layout.createSequentialGroup()
.addComponent(curListNameLabel)
.addGap(18, 18, 18)
.addComponent(curListValLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
.addGroup(javax.swing.GroupLayout.Alignment.LEADING, layout.createSequentialGroup()
.addComponent(deleteWordButton)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(deleteAllWordsButton)
.addGap(18, 18, 18)
.addComponent(saveListButton))))
.addContainerGap(15, Short.MAX_VALUE))
);
layout.setVerticalGroup(
@ -264,7 +310,9 @@ public final class KeywordSearchListTopComponent extends TopComponent implements
.addContainerGap()
.addComponent(titleLabel)
.addGap(18, 18, 18)
.addComponent(loadListButton)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(loadListButton)
.addComponent(importButton))
.addGap(19, 19, 19)
.addComponent(addWordLabel)
.addGap(18, 18, 18)
@ -284,7 +332,11 @@ public final class KeywordSearchListTopComponent extends TopComponent implements
.addComponent(saveListButton))
.addGap(29, 29, 29)
.addComponent(searchButton)
.addGap(38, 38, 38)
.addGap(18, 18, 18)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(curListNameLabel)
.addComponent(curListValLabel))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(filesIndexedNameLabel)
.addComponent(filesIndexedValLabel))
@ -337,7 +389,7 @@ public final class KeywordSearchListTopComponent extends TopComponent implements
private void saveListButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_saveListButtonActionPerformed
final String FEATURE_NAME = "Save Keyword List";
KeywordSearchListsXML writer = KeywordSearchListsXML.getInstance();
KeywordSearchListsXML writer = KeywordSearchListsXML.getCurrent();
String listName = (String) JOptionPane.showInputDialog(
null,
@ -352,32 +404,27 @@ public final class KeywordSearchListTopComponent extends TopComponent implements
}
List<String> keywords = tableModel.getAllKeywords();
boolean shouldWrite = false;
boolean written = false;
boolean shouldAdd = false;
if (writer.listExists(listName)) {
boolean replace = KeywordSearchUtil.displayConfirmDialog(FEATURE_NAME, "Keyword List <" + listName + "> already exists, do you want to replace it?",
KeywordSearchUtil.DIALOG_MESSAGE_TYPE.WARN);
if (replace) {
shouldWrite = true;
shouldAdd = true;
}
} else {
shouldWrite = true;
shouldAdd = true;
}
if (shouldWrite) {
if (shouldAdd) {
writer.addList(listName, keywords);
written = writer.save();
}
if (written) {
currentKeywordList = listName;
KeywordSearchUtil.displayDialog(FEATURE_NAME, "Keyword List <" + listName + "> saved", KeywordSearchUtil.DIALOG_MESSAGE_TYPE.INFO);
//enable load button if it was previously disabled, as lists now exist
if (loadListButton.isEnabled() == false) {
loadListButton.setEnabled(true);
}
}
currentKeywordList = listName;
curListValLabel.setText(listName);
KeywordSearchUtil.displayDialog(FEATURE_NAME, "Keyword List <" + listName + "> saved", KeywordSearchUtil.DIALOG_MESSAGE_TYPE.INFO);
}//GEN-LAST:event_saveListButtonActionPerformed
private void chLiteralWordActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_chLiteralWordActionPerformed
@ -395,35 +442,44 @@ public final class KeywordSearchListTopComponent extends TopComponent implements
final String FEATURE_NAME = "Load Keyword List";
KeywordSearchListsXML loader = KeywordSearchListsXML.getInstance();
KeywordSearchListsXML loader = KeywordSearchListsXML.getCurrent();
final String listName = showLoadDeleteListDialog(FEATURE_NAME, loader.getListNames().toArray(), currentKeywordList, true);
if (listName == null || listName.equals("")) {
return;
}
currentKeywordList = listName;
tableModel.resync(currentKeywordList);
curListValLabel.setText(listName);
KeywordSearchList list = loader.getList(listName);
if (list != null) {
List<String> keywords = list.getKeywords();
KeywordSearchUtil.displayDialog(FEATURE_NAME, "Keyword List <" + listName + "> loaded", KeywordSearchUtil.DIALOG_MESSAGE_TYPE.INFO);
//TODO clear/append option ?
tableModel.deleteAll();
tableModel.addKeywords(keywords);
currentKeywordList = listName;
KeywordSearchUtil.displayDialog(FEATURE_NAME, "Keyword List <" + listName + "> loaded", KeywordSearchUtil.DIALOG_MESSAGE_TYPE.INFO);
}
}//GEN-LAST:event_loadListButtonActionPerformed
private void importButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_importButtonActionPerformed
//delegate to lists component
JTabbedPane tabs = (JTabbedPane) this.getParent();
KeywordSearchListImportExportTopComponent lists = (KeywordSearchListImportExportTopComponent) tabs.getComponentAt(TABS.Lists.ordinal());
if (lists != null) {
lists.importButtonAction(evt);
}
}//GEN-LAST:event_importButtonActionPerformed
// Variables declaration - do not modify//GEN-BEGIN:variables
private javax.swing.JButton addWordButton;
private javax.swing.JTextField addWordField;
private javax.swing.JLabel addWordLabel;
private javax.swing.JCheckBox chLiteralWord;
private javax.swing.JLabel curListNameLabel;
private javax.swing.JLabel curListValLabel;
private javax.swing.JButton deleteAllWordsButton;
private javax.swing.JButton deleteWordButton;
private javax.swing.JLabel filesIndexedNameLabel;
private javax.swing.JLabel filesIndexedValLabel;
private javax.swing.JButton importButton;
private javax.swing.JScrollPane jScrollPane1;
private javax.swing.JTable keywordTable;
private javax.swing.JLabel listLabel;
@ -432,6 +488,23 @@ public final class KeywordSearchListTopComponent extends TopComponent implements
private javax.swing.JButton searchButton;
private javax.swing.JLabel titleLabel;
// End of variables declaration//GEN-END:variables
private JComboBox loadListCombo;
private JComboBox findDialogComponent(Component component) {
if (component instanceof JComboBox) {
loadListCombo = (JComboBox) component;
} else if (component instanceof JPanel) {
for (Component c : ((JPanel) component).getComponents()) {
findDialogComponent(c);
}
} else if (component instanceof JOptionPane) {
for (Component c : ((JOptionPane) component).getComponents()) {
findDialogComponent(c);
}
}
return loadListCombo;
}
private String showLoadDeleteListDialog(final String title, Object[] choices, Object initialChoice, boolean deleteOption) {
if (deleteOption) {
@ -444,64 +517,11 @@ public final class KeywordSearchListTopComponent extends TopComponent implements
loadPane.setWantsInput(true);
loadPane.setSelectionValues(choices);
loadPane.setInitialSelectionValue(initialChoice);
//loadPane.setValue(initialChoice);
final JDialog loadDialog = loadPane.createDialog(null, title);
final JPopupMenu rightClickMenu = new JPopupMenu();
JMenuItem delItem = new JMenuItem("Delete List");
delItem.addActionListener(new ActionListener() {
JComboBox combo;
//find the combo component
private JComboBox getDialogComponent(Component component) {
if (component instanceof JComboBox) {
combo = (JComboBox)component;
} else if (component instanceof JPanel) {
for (Component c : ((JPanel) component).getComponents()) {
getDialogComponent(c);
}
} else if (component instanceof JOptionPane) {
for (Component c : ((JOptionPane) component).getComponents()) {
getDialogComponent(c);
}
}
return combo;
}
@Override
public void actionPerformed(ActionEvent e) {
//there is no JOptionPane API to get current from combobox before OK is pressed
//workaround traversing the widgets
String selList = null;
combo = getDialogComponent(loadPane);
if (combo != null) {
selList = (String) combo.getSelectedItem();
}
if (selList != null && selList != JOptionPane.UNINITIALIZED_VALUE) {
KeywordSearchListsXML loader = KeywordSearchListsXML.getInstance();
boolean deleted = loader.deleteList(selList);
if (deleted) {
Object[] choices = loader.getListNames().toArray();
loadPane.setSelectionValues(choices);
if (choices.length > 0) {
loadPane.setInitialSelectionValue(choices[0]);
}
loadPane.selectInitialValue();
KeywordSearchUtil.displayDialog(title, "Keyword List <" + selList + "> deleted", KeywordSearchUtil.DIALOG_MESSAGE_TYPE.INFO);
}
}
rightClickMenu.setVisible(false);
}
});
rightClickMenu.add(delItem);
loadPane.addMouseListener(new MouseListener() {
final MouseListener rightClickListener = new MouseListener() {
@Override
public void mouseClicked(MouseEvent e) {
@ -526,15 +546,59 @@ public final class KeywordSearchListTopComponent extends TopComponent implements
public void mouseReleased(MouseEvent e) {
rightClickMenu.setVisible(false);
}
};
JMenuItem delItem = new JMenuItem("Delete List");
delItem.addActionListener(new ActionListener() {
JComboBox combo;
@Override
public void actionPerformed(ActionEvent e) {
String selList = null;
//there is no JOptionPane API to get current from combobox before OK is pressed
//workaround traversing the widgets
combo = findDialogComponent(loadPane);
if (combo != null) {
selList = (String) combo.getSelectedItem();
}
if (selList != null && selList != JOptionPane.UNINITIALIZED_VALUE) {
KeywordSearchListsXML loader = KeywordSearchListsXML.getCurrent();
boolean deleted = loader.deleteList(selList);
if (deleted) {
Object[] choices = loader.getListNames().toArray();
loadPane.setSelectionValues(choices);
if (choices.length > 0) {
loadPane.setInitialSelectionValue(choices[0]);
}
loadPane.selectInitialValue();
combo = findDialogComponent(loadPane);
combo.addMouseListener(rightClickListener);
KeywordSearchUtil.displayDialog(title, "Keyword List <" + selList + "> deleted", KeywordSearchUtil.DIALOG_MESSAGE_TYPE.INFO);
}
}
rightClickMenu.setVisible(false);
}
});
rightClickMenu.add(delItem);
JComboBox combo = findDialogComponent(loadPane);
combo.addMouseListener(rightClickListener);
loadPane.selectInitialValue();
loadDialog.setVisible(true);
loadDialog.dispose();
String retString = (String) loadPane.getInputValue();
if (retString == JOptionPane.UNINITIALIZED_VALUE) //no choice was made
{
retString = null;
}
return (String) loadPane.getInputValue();
return retString;
} else {
return (String) JOptionPane.showInputDialog(
null,
@ -629,9 +693,8 @@ public final class KeywordSearchListTopComponent extends TopComponent implements
}
static class KeywordTableModel extends AbstractTableModel {
private static Logger logger = Logger.getLogger(KeywordTableModel.class.getName());
//data
private Set<TableEntry> keywordData = new TreeSet<TableEntry>();
@Override
@ -729,6 +792,15 @@ public final class KeywordSearchListTopComponent extends TopComponent implements
fireTableDataChanged();
}
void resync(String listName) {
KeywordSearchListsXML loader = KeywordSearchListsXML.getCurrent();
KeywordSearchList list = loader.getList(listName);
List<String> keywords = list.getKeywords();
deleteAll();
addKeywords(keywords);
}
void deleteAll() {
keywordData.clear();
fireTableDataChanged();
@ -736,7 +808,7 @@ public final class KeywordSearchListTopComponent extends TopComponent implements
void deleteSelected() {
List<TableEntry> toDel = new ArrayList<TableEntry>();
int i = 0;
for (TableEntry e : keywordData) {
if (e.isActive && !e.keyword.equals("")) {
toDel.add(e);
@ -774,7 +846,7 @@ public final class KeywordSearchListTopComponent extends TopComponent implements
/**
* tooltips that show entire query string
*/
public static class CellTooltipRenderer extends DefaultTableCellRenderer {
private static class CellTooltipRenderer extends DefaultTableCellRenderer {
@Override
public Component getTableCellRendererComponent(

View File

@ -18,6 +18,8 @@
*/
package org.sleuthkit.autopsy.keywordsearch;
import java.beans.PropertyChangeListener;
import java.beans.PropertyChangeSupport;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
@ -54,6 +56,7 @@ import org.xml.sax.SAXException;
/**
* Manages reading and writing of keyword lists to user settings XML file keywords.xml
* or to any file provided in constructor
*/
public class KeywordSearchListsXML {
@ -63,25 +66,49 @@ public class KeywordSearchListsXML {
private static final String LIST_CREATE_ATTR = "created";
private static final String LIST_MOD_ATTR = "modified";
private static final String KEYWORD_EL = "keyword";
private static final String LISTS_FILE_NAME = "keywords.xml";
private static final String CUR_LISTS_FILE_NAME = "keywords.xml";
private static final String DATE_FORMAT = "yyyy-MM-dd HH:mm:ss";
private static final String ENCODING = "UTF-8";
private String LISTS_FILE = AutopsyPropFile.getUserDirPath() + File.separator + LISTS_FILE_NAME;
private static String CUR_LISTS_FILE = AutopsyPropFile.getUserDirPath() + File.separator + CUR_LISTS_FILE_NAME;
private static final Logger logger = Logger.getLogger(KeywordSearchListsXML.class.getName());
Map<String, KeywordSearchList> theLists; //the keyword data
static KeywordSearchListsXML theInstance = null;
static KeywordSearchListsXML currentInstance = null;
private String xmlFile;
private DateFormat dateFormatter;
private KeywordSearchListsXML() {
//property support
public enum ListsEvt {
LIST_ADDED, LIST_DELETED, LIST_UPDATED
};
private PropertyChangeSupport changeSupport;
/**
* Constructor to obtain handle on other that the current keyword list
* (such as for import or export)
* @param xmlFile xmlFile to obtain KeywordSearchListsXML handle on
*/
KeywordSearchListsXML(String xmlFile) {
theLists = new LinkedHashMap<String, KeywordSearchList>();
this.xmlFile = xmlFile;
changeSupport = new PropertyChangeSupport(this);
dateFormatter = new SimpleDateFormat(DATE_FORMAT);
}
static KeywordSearchListsXML getInstance() {
if (theInstance == null) {
theInstance = new KeywordSearchListsXML();
theInstance.reload();
/**
* get instance for managing the current keyword list of the application
*/
static KeywordSearchListsXML getCurrent() {
if (currentInstance == null) {
currentInstance = new KeywordSearchListsXML(CUR_LISTS_FILE);
currentInstance.reload();
}
return theInstance;
return currentInstance;
}
void addPropertyChangeListener(PropertyChangeListener l) {
changeSupport.addPropertyChangeListener(l);
}
/**
@ -89,36 +116,39 @@ public class KeywordSearchListsXML {
*/
public void reload() {
boolean created = false;
theLists = new LinkedHashMap<String, KeywordSearchList>();
theLists.clear();
if (!this.listFileExists()) {
//create new if it doesn't exist
save();
created = true;
}
//load, if fails to laod create new
if (!load() && !created) {
//create new if failed to load
save();
}
}
/**
* get all loaded keyword lists
* @return List of keyword list objects
*/
Map<String, KeywordSearchList> getLists() {
return theLists;
List<KeywordSearchList> getListsL() {
List<KeywordSearchList> ret = new ArrayList<KeywordSearchList>();
for (KeywordSearchList list : theLists.values()) {
ret.add(list);
}
return ret;
}
/**
* get list of all loaded keyword list names
* @return List of keyword list names
*/
List<String>getListNames() {
List<String> getListNames() {
return new ArrayList<String>(theLists.keySet());
}
/**
* get number of lists currently stored
* @return number of lists currently stored
@ -148,7 +178,6 @@ public class KeywordSearchListsXML {
/**
* adds the new word list using name id
* replacing old one if exists with the same name
* requires following call to save() to make permanent changes
* @param name the name of the new list or list to replace
* @param newList list of keywords
* @return true if old list was replaced
@ -157,15 +186,47 @@ public class KeywordSearchListsXML {
boolean replaced = false;
KeywordSearchList curList = getList(name);
final Date now = new Date();
final int oldSize = this.getNumberLists();
if (curList == null) {
theLists.put(name, new KeywordSearchList(name, now, now, newList));
save();
changeSupport.firePropertyChange(ListsEvt.LIST_ADDED.toString(), oldSize, this.getNumberLists());
} else {
theLists.put(name, new KeywordSearchList(name, curList.getDateCreated(), now, newList));
save();
replaced = true;
changeSupport.firePropertyChange(ListsEvt.LIST_UPDATED.toString(), null, name);
}
return replaced;
}
/**
* write out multiple lists
* @param lists
* @return
*/
boolean writeLists(List<KeywordSearchList> lists) {
int oldSize = this.getNumberLists();
List<KeywordSearchList> overwritten = new ArrayList<KeywordSearchList>();
for (KeywordSearchList list : lists) {
if (this.listExists(list.getName()))
overwritten.add(list);
theLists.put(list.getName(), list);
}
boolean saved = save();
if (saved) {
changeSupport.firePropertyChange(ListsEvt.LIST_ADDED.toString(), oldSize, this.getNumberLists());
for (KeywordSearchList over : overwritten) {
changeSupport.firePropertyChange(ListsEvt.LIST_UPDATED.toString(), null, over.getName());
}
}
return saved;
}
/**
* delete list if exists and save new list
* @param name of list to delete
@ -173,21 +234,23 @@ public class KeywordSearchListsXML {
*/
boolean deleteList(String name) {
boolean deleted = false;
final int oldSize = this.getNumberLists();
KeywordSearchList delList = getList(name);
if (delList != null) {
theLists.remove(name);
deleted = save();
}
changeSupport.firePropertyChange(ListsEvt.LIST_DELETED.toString(), oldSize, this.getNumberLists());
return deleted;
}
/**
* writes out current list replacing the last lists file
*/
boolean save() {
private boolean save() {
boolean success = false;
DateFormat dateFormatter = new SimpleDateFormat(DATE_FORMAT);
DocumentBuilderFactory dbfac = DocumentBuilderFactory.newInstance();
try {
@ -223,18 +286,14 @@ public class KeywordSearchListsXML {
return success;
}
/**
* load and parse XML, then dispose
*/
private boolean load() {
public boolean load() {
final Document doc = loadDoc();
if (doc == null) {
return false;
}
DateFormat dateFormatter = new SimpleDateFormat(DATE_FORMAT);
Element root = doc.getDocumentElement();
if (root == null) {
@ -273,7 +332,7 @@ public class KeywordSearchListsXML {
}
private boolean listFileExists() {
File f = new File(LISTS_FILE);
File f = new File(xmlFile);
return f.exists() && f.canRead() && f.canWrite();
}
@ -287,7 +346,7 @@ public class KeywordSearchListsXML {
try {
DocumentBuilder builder = builderFactory.newDocumentBuilder();
ret = builder.parse(
new FileInputStream(LISTS_FILE));
new FileInputStream(xmlFile));
} catch (ParserConfigurationException e) {
logger.log(Level.SEVERE, "Error loading keyword list: can't initialize parser.", e);
@ -314,9 +373,14 @@ public class KeywordSearchListsXML {
xformer.setOutputProperty(OutputKeys.ENCODING, ENCODING);
xformer.setOutputProperty(OutputKeys.STANDALONE, "yes");
xformer.setOutputProperty(OutputKeys.VERSION, "1.0");
Result out = new StreamResult(new OutputStreamWriter(new FileOutputStream(new File(LISTS_FILE)), ENCODING));
File file = new File(xmlFile);
FileOutputStream stream = new FileOutputStream(file);
Result out = new StreamResult(new OutputStreamWriter(stream, ENCODING));
xformer.transform(new DOMSource(doc), out);
stream.flush();
stream.close();
success = true;
} catch (UnsupportedEncodingException e) {
logger.log(Level.SEVERE, "Should not happen", e);
} catch (TransformerConfigurationException e) {
@ -324,7 +388,9 @@ public class KeywordSearchListsXML {
} catch (TransformerException e) {
logger.log(Level.SEVERE, "Error writing keyword lists XML", e);
} catch (FileNotFoundException e) {
logger.log(Level.SEVERE, "Error writing keyword lists XML: cannot write to file: " + LISTS_FILE, e);
logger.log(Level.SEVERE, "Error writing keyword lists XML: cannot write to file: " + xmlFile, e);
} catch (IOException e) {
logger.log(Level.SEVERE, "Error writing keyword lists XML: cannot write to file: " + xmlFile, e);
}
return success;
}
@ -348,6 +414,27 @@ class KeywordSearchList {
this.keywords = keywords;
}
@Override
public boolean equals(Object obj) {
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
final KeywordSearchList other = (KeywordSearchList) obj;
if ((this.name == null) ? (other.name != null) : !this.name.equals(other.name)) {
return false;
}
return true;
}
@Override
public int hashCode() {
int hash = 5;
return hash;
}
String getName() {
return name;
}

View File

@ -30,12 +30,22 @@ public class KeywordSearchSimpleTopComponent extends TopComponent implements Key
/** Creates new form KeywordSearchSimpleTopComponent */
public KeywordSearchSimpleTopComponent() {
initComponents();
customizeComponents();
setName("Simple");
searchButton.setEnabled(false);
putClientProperty(TopComponent.PROP_CLOSING_DISABLED, Boolean.TRUE);
}
private void customizeComponents() {
searchButton.setToolTipText("Execute a keyword search using the query specified.");
chRegex.setToolTipText("Select if query is a regular expression");
queryTextArea.setToolTipText("<html>For non-regex search enter one or more keywords separated by white-space.<br />"
+ "For a regex search, enter a Java-supported regular expression.<br />"
+ "Examples of regex (in double-quotes): \"\\d\\d\\d-\\d\\d\\d\" \\d{8,10} \"phone\" \"ftp|sftp|ssh|http|https|www\".<br />"
+ "Note: a word can be also searched using a regex search.<br />Regex containing whitespace [ \\s] matches are currently not supported.</html>");
}
/** This method is called from within the constructor to
* initialize the form.
* WARNING: Do NOT modify this code. The content of this method is
@ -119,7 +129,6 @@ public class KeywordSearchSimpleTopComponent extends TopComponent implements Key
private void chRegexActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_chRegexActionPerformed
// TODO add your handling code here:
}//GEN-LAST:event_chRegexActionPerformed
// Variables declaration - do not modify//GEN-BEGIN:variables
private javax.swing.ButtonGroup buttonGroup1;
private javax.swing.JCheckBox chRegex;
@ -131,18 +140,17 @@ public class KeywordSearchSimpleTopComponent extends TopComponent implements Key
private javax.swing.JButton searchButton;
// End of variables declaration//GEN-END:variables
@Override
protected void componentOpened() {
// clear old search
queryTextArea.setText("");
}
@Override
public boolean isMultiwordQuery() {
return false;
}
@Override
public void addSearchButtonListener(ActionListener l) {
searchButton.addActionListener(l);
@ -152,17 +160,17 @@ public class KeywordSearchSimpleTopComponent extends TopComponent implements Key
public String getQueryText() {
return queryTextArea.getText();
}
@Override
public Map<String,Boolean> getQueryList() {
public Map<String, Boolean> getQueryList() {
return null;
}
@Override
public boolean isLuceneQuerySelected() {
return !chRegex.isSelected();
}
@Override
public boolean isRegexQuerySelected() {
return chRegex.isSelected();
@ -188,5 +196,4 @@ public class KeywordSearchSimpleTopComponent extends TopComponent implements Key
searchButton.setEnabled(true);
}
}
}

View File

@ -18,6 +18,7 @@
*/
package org.sleuthkit.autopsy.keywordsearch;
import java.awt.Component;
import java.awt.event.ActionListener;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
@ -48,6 +49,8 @@ public final class KeywordSearchTabsTopComponent extends TopComponent implements
private Logger logger = Logger.getLogger(KeywordSearchTabsTopComponent.class.getName());
private PropertyChangeListener serverChangeListener;
public enum TABS{Simple, List, Lists, History};
public KeywordSearchTabsTopComponent() {
initComponents();
@ -89,8 +92,10 @@ public final class KeywordSearchTabsTopComponent extends TopComponent implements
// End of variables declaration//GEN-END:variables
private void initTabs() {
tabs.addTab("Simple", null, new KeywordSearchSimpleTopComponent(), "Single keyword or regex search");
tabs.addTab("List", null, new KeywordSearchListTopComponent(), "Search for or load a saved list of keywords.");
tabs.addTab(TABS.Simple.name(), null, new KeywordSearchSimpleTopComponent(), "Single keyword or regex search");
tabs.addTab(TABS.List.name(), null, new KeywordSearchListTopComponent(), "Search for or load a saved list of keywords.");
tabs.addTab(TABS.Lists.name(), null, new KeywordSearchListImportExportTopComponent(), "Manage (import, export, delete) lists of keywords.");
//tabs.addTab(TABS.History.name(), null, new KeywordSearchHistoryTopComponent(), "Review keyword search history and saved search results."); //TODO
}
@Override
@ -100,7 +105,7 @@ public final class KeywordSearchTabsTopComponent extends TopComponent implements
@Override
public void componentClosed() {
}
void writeProperties(java.util.Properties p) {
// better to version settings since initial version as advocated at
// http://wiki.apidesign.org/wiki/PropertyFiles