mirror of
https://github.com/overcuriousity/autopsy-flatpak.git
synced 2025-07-13 00:16:16 +00:00
- started code refactor to make search result node presentation common
between single and multi search - changed regex bullet to single checkbox in Simple
This commit is contained in:
parent
b197088de8
commit
ee588d2018
@ -1,6 +1,9 @@
|
|||||||
|
CTL_KeywordSearchListAction=List
|
||||||
|
CTL_KeywordSearchListTopComponent=List
|
||||||
CTL_KeywordSearchTabsTopComponentAction=Keyword Search
|
CTL_KeywordSearchTabsTopComponentAction=Keyword Search
|
||||||
CTL_KeywordSearchTabsTopComponentTopComponent=Keyword Search
|
CTL_KeywordSearchTabsTopComponentTopComponent=Keyword Search
|
||||||
HINT_KeywordSearchTabsTopComponentTopComponent=This is a Keyword Search window
|
HINT_KeywordSearchListTopComponent=Keyword Search List
|
||||||
|
HINT_KeywordSearchTabsTopComponentTopComponent=Keyword Search window
|
||||||
OpenIDE-Module-Name=KeywordSearch
|
OpenIDE-Module-Name=KeywordSearch
|
||||||
IndexProgressPanel.statusText.text=Status text
|
IndexProgressPanel.statusText.text=Status text
|
||||||
IndexProgressPanel.cancelButton.text=Cancel
|
IndexProgressPanel.cancelButton.text=Cancel
|
||||||
@ -17,5 +20,17 @@ KeywordSearchSimpleTopComponent.filesIndexedValLabel.text=-
|
|||||||
KeywordSearchSimpleTopComponent.filesIndexedNameLabel.text=Files indexed:
|
KeywordSearchSimpleTopComponent.filesIndexedNameLabel.text=Files indexed:
|
||||||
KeywordSearchSimpleTopComponent.queryLabel.text=Query:
|
KeywordSearchSimpleTopComponent.queryLabel.text=Query:
|
||||||
KeywordSearchSimpleTopComponent.searchButton.text=Search
|
KeywordSearchSimpleTopComponent.searchButton.text=Search
|
||||||
KeywordSearchSimpleTopComponent.regexQRadioButton.text=RegEx
|
KeywordSearchListTopComponent.searchButton.text=Search
|
||||||
KeywordSearchSimpleTopComponent.luceneQRadioButton.text=Lucene
|
KeywordSearchListTopComponent.filesIndexedNameLabel.text=Files indexed:
|
||||||
|
KeywordSearchListTopComponent.filesIndexedValLabel.text=-
|
||||||
|
KeywordSearchListTopComponent.titleLabel.text=Search for or load a saved list of keywords
|
||||||
|
KeywordSearchListTopComponent.listLabel.text=Current list of keywords:
|
||||||
|
KeywordSearchListTopComponent.addWordButton.text=Add
|
||||||
|
KeywordSearchListTopComponent.loadListButton.text=Load
|
||||||
|
KeywordSearchListTopComponent.addWordField.text=
|
||||||
|
KeywordSearchListTopComponent.saveListButton.text=Save
|
||||||
|
KeywordSearchListTopComponent.chLiteralWord.text=Literal
|
||||||
|
KeywordSearchListTopComponent.addWordLabel.text=Add a new word:
|
||||||
|
KeywordSearchListTopComponent.deleteWordButton.text=Delete
|
||||||
|
KeywordSearchListTopComponent.deleteAllWordsButton.text=Delete All
|
||||||
|
KeywordSearchSimpleTopComponent.chRegex.text=RegEx
|
||||||
|
@ -95,7 +95,7 @@ public class KeywordSearchDataExplorer implements DataExplorer {
|
|||||||
* @param solrQuery
|
* @param solrQuery
|
||||||
*/
|
*/
|
||||||
private void searchRegexQuery(String regexQuery) {
|
private void searchRegexQuery(String regexQuery) {
|
||||||
RegexQuery rq = new RegexQuery(regexQuery);
|
TermComponentQuery rq = new TermComponentQuery(regexQuery);
|
||||||
if (rq.validate()) {
|
if (rq.validate()) {
|
||||||
rq.execute();
|
rq.execute();
|
||||||
} else {
|
} else {
|
||||||
|
@ -0,0 +1,229 @@
|
|||||||
|
<?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="32767" attributes="0"/>
|
||||||
|
<Group type="103" groupAlignment="0" attributes="0">
|
||||||
|
<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" max="-2" attributes="0"/>
|
||||||
|
</Group>
|
||||||
|
<Component id="searchButton" alignment="0" min="-2" max="-2" attributes="0"/>
|
||||||
|
<Group type="102" alignment="0" attributes="1">
|
||||||
|
<Group type="103" groupAlignment="0" attributes="0">
|
||||||
|
<Component id="titleLabel" alignment="0" min="-2" max="-2" attributes="0"/>
|
||||||
|
<Group type="102" alignment="0" attributes="0">
|
||||||
|
<Group type="103" groupAlignment="0" max="-2" attributes="0">
|
||||||
|
<Group type="102" alignment="0" attributes="0">
|
||||||
|
<Component id="loadListButton" min="-2" max="-2" attributes="0"/>
|
||||||
|
<EmptySpace max="32767" attributes="0"/>
|
||||||
|
<Component id="saveListButton" min="-2" max="-2" attributes="0"/>
|
||||||
|
</Group>
|
||||||
|
<Component id="chLiteralWord" alignment="0" min="-2" max="-2" attributes="0"/>
|
||||||
|
<Component id="addWordField" alignment="0" min="-2" pref="152" max="-2" attributes="0"/>
|
||||||
|
</Group>
|
||||||
|
<EmptySpace type="unrelated" max="-2" attributes="0"/>
|
||||||
|
<Component id="addWordButton" min="-2" max="-2" attributes="0"/>
|
||||||
|
</Group>
|
||||||
|
</Group>
|
||||||
|
<EmptySpace min="-2" pref="66" max="-2" attributes="0"/>
|
||||||
|
</Group>
|
||||||
|
<Component id="listLabel" alignment="0" min="-2" max="-2" attributes="0"/>
|
||||||
|
<Component id="addWordLabel" alignment="0" min="-2" max="-2" attributes="0"/>
|
||||||
|
<Group type="103" alignment="0" groupAlignment="1" max="-2" attributes="0">
|
||||||
|
<Group type="102" alignment="0" attributes="1">
|
||||||
|
<Component id="deleteWordButton" min="-2" max="-2" attributes="0"/>
|
||||||
|
<EmptySpace max="32767" attributes="0"/>
|
||||||
|
<Component id="deleteAllWordsButton" min="-2" max="-2" attributes="0"/>
|
||||||
|
</Group>
|
||||||
|
<Component id="jScrollPane1" alignment="0" min="-2" pref="217" max="-2" attributes="0"/>
|
||||||
|
</Group>
|
||||||
|
</Group>
|
||||||
|
</Group>
|
||||||
|
</Group>
|
||||||
|
</DimensionLayout>
|
||||||
|
<DimensionLayout dim="1">
|
||||||
|
<Group type="103" groupAlignment="0" attributes="0">
|
||||||
|
<Group type="102" alignment="1" attributes="0">
|
||||||
|
<EmptySpace max="-2" attributes="0"/>
|
||||||
|
<Component id="titleLabel" min="-2" max="-2" attributes="0"/>
|
||||||
|
<EmptySpace type="separate" max="-2" attributes="0"/>
|
||||||
|
<Group type="103" groupAlignment="3" attributes="0">
|
||||||
|
<Component id="loadListButton" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||||
|
<Component id="saveListButton" 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"/>
|
||||||
|
<Group type="103" groupAlignment="1" attributes="0">
|
||||||
|
<Group type="102" attributes="0">
|
||||||
|
<Group type="103" groupAlignment="3" attributes="0">
|
||||||
|
<Component id="addWordButton" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||||
|
<Component id="addWordField" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||||
|
</Group>
|
||||||
|
<EmptySpace min="-2" pref="27" max="-2" attributes="0"/>
|
||||||
|
</Group>
|
||||||
|
<Group type="102" alignment="1" attributes="0">
|
||||||
|
<Component id="chLiteralWord" min="-2" max="-2" attributes="0"/>
|
||||||
|
<EmptySpace type="unrelated" max="-2" attributes="0"/>
|
||||||
|
</Group>
|
||||||
|
</Group>
|
||||||
|
<EmptySpace min="-2" pref="12" max="-2" attributes="0"/>
|
||||||
|
<Component id="listLabel" min="-2" max="-2" attributes="0"/>
|
||||||
|
<EmptySpace type="unrelated" max="-2" attributes="0"/>
|
||||||
|
<Component id="jScrollPane1" min="-2" max="-2" attributes="0"/>
|
||||||
|
<EmptySpace type="unrelated" max="-2" attributes="0"/>
|
||||||
|
<Group type="103" groupAlignment="3" attributes="0">
|
||||||
|
<Component id="deleteWordButton" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||||
|
<Component id="deleteAllWordsButton" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||||
|
</Group>
|
||||||
|
<EmptySpace min="-2" pref="30" max="-2" attributes="0"/>
|
||||||
|
<Component id="searchButton" min="-2" max="-2" attributes="0"/>
|
||||||
|
<EmptySpace type="unrelated" 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 min="-2" pref="42" max="-2" attributes="0"/>
|
||||||
|
</Group>
|
||||||
|
</Group>
|
||||||
|
</DimensionLayout>
|
||||||
|
</Layout>
|
||||||
|
<SubComponents>
|
||||||
|
<Component class="javax.swing.JButton" name="searchButton">
|
||||||
|
<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.searchButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||||
|
</Property>
|
||||||
|
</Properties>
|
||||||
|
<Events>
|
||||||
|
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="searchButtonActionPerformed"/>
|
||||||
|
</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="KeywordSearchListTopComponent.filesIndexedNameLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||||
|
</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="KeywordSearchListTopComponent.filesIndexedValLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||||
|
</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.JList" name="jList1">
|
||||||
|
<Properties>
|
||||||
|
<Property name="model" type="javax.swing.ListModel" editor="org.netbeans.modules.form.editors2.ListModelEditor">
|
||||||
|
<StringArray count="0"/>
|
||||||
|
</Property>
|
||||||
|
</Properties>
|
||||||
|
</Component>
|
||||||
|
</SubComponents>
|
||||||
|
</Container>
|
||||||
|
<Component class="javax.swing.JLabel" name="titleLabel">
|
||||||
|
<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.titleLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||||
|
</Property>
|
||||||
|
</Properties>
|
||||||
|
</Component>
|
||||||
|
<Component class="javax.swing.JLabel" name="listLabel">
|
||||||
|
<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.listLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||||
|
</Property>
|
||||||
|
</Properties>
|
||||||
|
</Component>
|
||||||
|
<Component class="javax.swing.JTextField" name="addWordField">
|
||||||
|
<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.addWordField.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||||
|
</Property>
|
||||||
|
</Properties>
|
||||||
|
</Component>
|
||||||
|
<Component class="javax.swing.JLabel" name="addWordLabel">
|
||||||
|
<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.addWordLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||||
|
</Property>
|
||||||
|
</Properties>
|
||||||
|
</Component>
|
||||||
|
<Component class="javax.swing.JButton" name="addWordButton">
|
||||||
|
<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.addWordButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||||
|
</Property>
|
||||||
|
</Properties>
|
||||||
|
<Events>
|
||||||
|
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="addWordButtonActionPerformed"/>
|
||||||
|
</Events>
|
||||||
|
</Component>
|
||||||
|
<Component class="javax.swing.JButton" name="loadListButton">
|
||||||
|
<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.loadListButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||||
|
</Property>
|
||||||
|
</Properties>
|
||||||
|
</Component>
|
||||||
|
<Component class="javax.swing.JButton" name="deleteWordButton">
|
||||||
|
<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.deleteWordButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||||
|
</Property>
|
||||||
|
</Properties>
|
||||||
|
</Component>
|
||||||
|
<Component class="javax.swing.JButton" name="deleteAllWordsButton">
|
||||||
|
<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.deleteAllWordsButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||||
|
</Property>
|
||||||
|
</Properties>
|
||||||
|
</Component>
|
||||||
|
<Component class="javax.swing.JButton" name="saveListButton">
|
||||||
|
<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.saveListButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||||
|
</Property>
|
||||||
|
</Properties>
|
||||||
|
<Events>
|
||||||
|
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="saveListButtonActionPerformed"/>
|
||||||
|
</Events>
|
||||||
|
</Component>
|
||||||
|
<Component class="javax.swing.JCheckBox" name="chLiteralWord">
|
||||||
|
<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.chLiteralWord.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||||
|
</Property>
|
||||||
|
</Properties>
|
||||||
|
<Events>
|
||||||
|
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="chLiteralWordActionPerformed"/>
|
||||||
|
</Events>
|
||||||
|
</Component>
|
||||||
|
</SubComponents>
|
||||||
|
</Form>
|
@ -0,0 +1,305 @@
|
|||||||
|
/*
|
||||||
|
* 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.event.ActionListener;
|
||||||
|
import java.util.logging.Logger;
|
||||||
|
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//KeywordSearchList//EN",
|
||||||
|
autostore = false)
|
||||||
|
@TopComponent.Description(preferredID = "KeywordSearchListTopComponent",
|
||||||
|
//iconBase="SET/PATH/TO/ICON/HERE",
|
||||||
|
persistenceType = TopComponent.PERSISTENCE_NEVER)
|
||||||
|
@TopComponent.Registration(mode = "output", openAtStartup = false)
|
||||||
|
@ActionID(category = "Window", id = "org.sleuthkit.autopsy.keywordsearch.KeywordSearchListTopComponent")
|
||||||
|
@ActionReference(path = "Menu/Window" /*, position = 333 */)
|
||||||
|
@TopComponent.OpenActionRegistration(displayName = "#CTL_KeywordSearchListAction",
|
||||||
|
preferredID = "KeywordSearchListTopComponent")
|
||||||
|
public final class KeywordSearchListTopComponent extends TopComponent implements KeywordSearchTopComponentInterface {
|
||||||
|
|
||||||
|
private Logger logger = Logger.getLogger(KeywordSearchListTopComponent.class.getName());
|
||||||
|
|
||||||
|
public KeywordSearchListTopComponent() {
|
||||||
|
initComponents();
|
||||||
|
customizeComponents();
|
||||||
|
setName(NbBundle.getMessage(KeywordSearchListTopComponent.class, "CTL_KeywordSearchListTopComponent"));
|
||||||
|
setToolTipText(NbBundle.getMessage(KeywordSearchListTopComponent.class, "HINT_KeywordSearchListTopComponent"));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private void customizeComponents() {
|
||||||
|
chLiteralWord.setToolTipText("Literal word (auto-escape special regex characters)");
|
||||||
|
addWordButton.setToolTipText(("Add a new word to the keyword search list"));
|
||||||
|
addWordField.setToolTipText("Enter a new word or regex to search");
|
||||||
|
|
||||||
|
loadListButton.setToolTipText("Load a new keyword list from 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 word(s) from the list");
|
||||||
|
deleteAllWordsButton.setToolTipText("Delete all words from the list (clear it)");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 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() {
|
||||||
|
|
||||||
|
searchButton = new javax.swing.JButton();
|
||||||
|
filesIndexedNameLabel = new javax.swing.JLabel();
|
||||||
|
filesIndexedValLabel = new javax.swing.JLabel();
|
||||||
|
jScrollPane1 = new javax.swing.JScrollPane();
|
||||||
|
jList1 = new javax.swing.JList();
|
||||||
|
titleLabel = new javax.swing.JLabel();
|
||||||
|
listLabel = new javax.swing.JLabel();
|
||||||
|
addWordField = new javax.swing.JTextField();
|
||||||
|
addWordLabel = new javax.swing.JLabel();
|
||||||
|
addWordButton = new javax.swing.JButton();
|
||||||
|
loadListButton = new javax.swing.JButton();
|
||||||
|
deleteWordButton = new javax.swing.JButton();
|
||||||
|
deleteAllWordsButton = new javax.swing.JButton();
|
||||||
|
saveListButton = new javax.swing.JButton();
|
||||||
|
chLiteralWord = new javax.swing.JCheckBox();
|
||||||
|
|
||||||
|
org.openide.awt.Mnemonics.setLocalizedText(searchButton, org.openide.util.NbBundle.getMessage(KeywordSearchListTopComponent.class, "KeywordSearchListTopComponent.searchButton.text")); // NOI18N
|
||||||
|
searchButton.addActionListener(new java.awt.event.ActionListener() {
|
||||||
|
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||||
|
searchButtonActionPerformed(evt);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
org.openide.awt.Mnemonics.setLocalizedText(filesIndexedNameLabel, org.openide.util.NbBundle.getMessage(KeywordSearchListTopComponent.class, "KeywordSearchListTopComponent.filesIndexedNameLabel.text")); // NOI18N
|
||||||
|
|
||||||
|
org.openide.awt.Mnemonics.setLocalizedText(filesIndexedValLabel, org.openide.util.NbBundle.getMessage(KeywordSearchListTopComponent.class, "KeywordSearchListTopComponent.filesIndexedValLabel.text")); // NOI18N
|
||||||
|
|
||||||
|
jScrollPane1.setViewportView(jList1);
|
||||||
|
|
||||||
|
org.openide.awt.Mnemonics.setLocalizedText(titleLabel, org.openide.util.NbBundle.getMessage(KeywordSearchListTopComponent.class, "KeywordSearchListTopComponent.titleLabel.text")); // NOI18N
|
||||||
|
|
||||||
|
org.openide.awt.Mnemonics.setLocalizedText(listLabel, org.openide.util.NbBundle.getMessage(KeywordSearchListTopComponent.class, "KeywordSearchListTopComponent.listLabel.text")); // NOI18N
|
||||||
|
|
||||||
|
addWordField.setText(org.openide.util.NbBundle.getMessage(KeywordSearchListTopComponent.class, "KeywordSearchListTopComponent.addWordField.text")); // NOI18N
|
||||||
|
|
||||||
|
org.openide.awt.Mnemonics.setLocalizedText(addWordLabel, org.openide.util.NbBundle.getMessage(KeywordSearchListTopComponent.class, "KeywordSearchListTopComponent.addWordLabel.text")); // NOI18N
|
||||||
|
|
||||||
|
org.openide.awt.Mnemonics.setLocalizedText(addWordButton, org.openide.util.NbBundle.getMessage(KeywordSearchListTopComponent.class, "KeywordSearchListTopComponent.addWordButton.text")); // NOI18N
|
||||||
|
addWordButton.addActionListener(new java.awt.event.ActionListener() {
|
||||||
|
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||||
|
addWordButtonActionPerformed(evt);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
org.openide.awt.Mnemonics.setLocalizedText(loadListButton, org.openide.util.NbBundle.getMessage(KeywordSearchListTopComponent.class, "KeywordSearchListTopComponent.loadListButton.text")); // NOI18N
|
||||||
|
|
||||||
|
org.openide.awt.Mnemonics.setLocalizedText(deleteWordButton, org.openide.util.NbBundle.getMessage(KeywordSearchListTopComponent.class, "KeywordSearchListTopComponent.deleteWordButton.text")); // NOI18N
|
||||||
|
|
||||||
|
org.openide.awt.Mnemonics.setLocalizedText(deleteAllWordsButton, org.openide.util.NbBundle.getMessage(KeywordSearchListTopComponent.class, "KeywordSearchListTopComponent.deleteAllWordsButton.text")); // NOI18N
|
||||||
|
|
||||||
|
org.openide.awt.Mnemonics.setLocalizedText(saveListButton, org.openide.util.NbBundle.getMessage(KeywordSearchListTopComponent.class, "KeywordSearchListTopComponent.saveListButton.text")); // NOI18N
|
||||||
|
saveListButton.addActionListener(new java.awt.event.ActionListener() {
|
||||||
|
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||||
|
saveListButtonActionPerformed(evt);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
org.openide.awt.Mnemonics.setLocalizedText(chLiteralWord, org.openide.util.NbBundle.getMessage(KeywordSearchListTopComponent.class, "KeywordSearchListTopComponent.chLiteralWord.text")); // NOI18N
|
||||||
|
chLiteralWord.addActionListener(new java.awt.event.ActionListener() {
|
||||||
|
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||||
|
chLiteralWordActionPerformed(evt);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
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(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
||||||
|
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||||
|
.addGroup(layout.createSequentialGroup()
|
||||||
|
.addComponent(filesIndexedNameLabel)
|
||||||
|
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||||
|
.addComponent(filesIndexedValLabel))
|
||||||
|
.addComponent(searchButton)
|
||||||
|
.addGroup(layout.createSequentialGroup()
|
||||||
|
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||||
|
.addComponent(titleLabel)
|
||||||
|
.addGroup(layout.createSequentialGroup()
|
||||||
|
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
|
||||||
|
.addGroup(layout.createSequentialGroup()
|
||||||
|
.addComponent(loadListButton)
|
||||||
|
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
||||||
|
.addComponent(saveListButton))
|
||||||
|
.addComponent(chLiteralWord)
|
||||||
|
.addComponent(addWordField, javax.swing.GroupLayout.PREFERRED_SIZE, 152, javax.swing.GroupLayout.PREFERRED_SIZE))
|
||||||
|
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
|
||||||
|
.addComponent(addWordButton)))
|
||||||
|
.addGap(66, 66, 66))
|
||||||
|
.addComponent(listLabel)
|
||||||
|
.addComponent(addWordLabel)
|
||||||
|
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING, false)
|
||||||
|
.addGroup(javax.swing.GroupLayout.Alignment.LEADING, layout.createSequentialGroup()
|
||||||
|
.addComponent(deleteWordButton)
|
||||||
|
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
||||||
|
.addComponent(deleteAllWordsButton))
|
||||||
|
.addComponent(jScrollPane1, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.PREFERRED_SIZE, 217, javax.swing.GroupLayout.PREFERRED_SIZE))))
|
||||||
|
);
|
||||||
|
layout.setVerticalGroup(
|
||||||
|
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||||
|
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
|
||||||
|
.addContainerGap()
|
||||||
|
.addComponent(titleLabel)
|
||||||
|
.addGap(18, 18, 18)
|
||||||
|
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
|
||||||
|
.addComponent(loadListButton)
|
||||||
|
.addComponent(saveListButton))
|
||||||
|
.addGap(19, 19, 19)
|
||||||
|
.addComponent(addWordLabel)
|
||||||
|
.addGap(18, 18, 18)
|
||||||
|
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
|
||||||
|
.addGroup(layout.createSequentialGroup()
|
||||||
|
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
|
||||||
|
.addComponent(addWordButton)
|
||||||
|
.addComponent(addWordField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
|
||||||
|
.addGap(27, 27, 27))
|
||||||
|
.addGroup(layout.createSequentialGroup()
|
||||||
|
.addComponent(chLiteralWord)
|
||||||
|
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)))
|
||||||
|
.addGap(12, 12, 12)
|
||||||
|
.addComponent(listLabel)
|
||||||
|
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
|
||||||
|
.addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||||
|
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
|
||||||
|
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
|
||||||
|
.addComponent(deleteWordButton)
|
||||||
|
.addComponent(deleteAllWordsButton))
|
||||||
|
.addGap(30, 30, 30)
|
||||||
|
.addComponent(searchButton)
|
||||||
|
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
|
||||||
|
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
|
||||||
|
.addComponent(filesIndexedNameLabel)
|
||||||
|
.addComponent(filesIndexedValLabel))
|
||||||
|
.addGap(42, 42, 42))
|
||||||
|
);
|
||||||
|
}// </editor-fold>//GEN-END:initComponents
|
||||||
|
|
||||||
|
private void searchButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_searchButtonActionPerformed
|
||||||
|
// TODO add your handling code here:
|
||||||
|
}//GEN-LAST:event_searchButtonActionPerformed
|
||||||
|
|
||||||
|
private void addWordButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_addWordButtonActionPerformed
|
||||||
|
// TODO add your handling code here:
|
||||||
|
}//GEN-LAST:event_addWordButtonActionPerformed
|
||||||
|
|
||||||
|
private void saveListButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_saveListButtonActionPerformed
|
||||||
|
// TODO add your handling code here:
|
||||||
|
}//GEN-LAST:event_saveListButtonActionPerformed
|
||||||
|
|
||||||
|
private void chLiteralWordActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_chLiteralWordActionPerformed
|
||||||
|
// TODO add your handling code here:
|
||||||
|
}//GEN-LAST:event_chLiteralWordActionPerformed
|
||||||
|
|
||||||
|
// 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.JButton deleteAllWordsButton;
|
||||||
|
private javax.swing.JButton deleteWordButton;
|
||||||
|
private javax.swing.JLabel filesIndexedNameLabel;
|
||||||
|
private javax.swing.JLabel filesIndexedValLabel;
|
||||||
|
private javax.swing.JList jList1;
|
||||||
|
private javax.swing.JScrollPane jScrollPane1;
|
||||||
|
private javax.swing.JLabel listLabel;
|
||||||
|
private javax.swing.JButton loadListButton;
|
||||||
|
private javax.swing.JButton saveListButton;
|
||||||
|
private javax.swing.JButton searchButton;
|
||||||
|
private javax.swing.JLabel titleLabel;
|
||||||
|
// End of variables declaration//GEN-END:variables
|
||||||
|
@Override
|
||||||
|
public void componentOpened() {
|
||||||
|
// TODO add custom code on component opening
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void componentClosed() {
|
||||||
|
// TODO add custom code on component closing
|
||||||
|
}
|
||||||
|
|
||||||
|
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");
|
||||||
|
// TODO store your settings
|
||||||
|
}
|
||||||
|
|
||||||
|
void readProperties(java.util.Properties p) {
|
||||||
|
String version = p.getProperty("version");
|
||||||
|
// TODO read your settings according to their version
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isMultiwordQuery() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void addSearchButtonListener(ActionListener l) {
|
||||||
|
searchButton.addActionListener(l);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getQueryText() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isLuceneQuerySelected() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isRegexQuerySelected() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setFilesIndexed(int filesIndexed) {
|
||||||
|
filesIndexedValLabel.setText(Integer.toString(filesIndexed));
|
||||||
|
if (filesIndexed == 0) {
|
||||||
|
searchButton.setEnabled(false);
|
||||||
|
} else {
|
||||||
|
searchButton.setEnabled(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
@ -18,6 +18,9 @@
|
|||||||
*/
|
*/
|
||||||
package org.sleuthkit.autopsy.keywordsearch;
|
package org.sleuthkit.autopsy.keywordsearch;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import org.sleuthkit.datamodel.FsContent;
|
||||||
|
|
||||||
public interface KeywordSearchQuery {
|
public interface KeywordSearchQuery {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -26,8 +29,23 @@ public interface KeywordSearchQuery {
|
|||||||
*/
|
*/
|
||||||
public boolean validate();
|
public boolean validate();
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* execute the query
|
* execute query and return results without publishing them
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public List<FsContent> performQuery();
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* execute the query and publish results
|
||||||
*/
|
*/
|
||||||
public void execute();
|
public void execute();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* escape the query string and use the escaped string in the query
|
||||||
|
*/
|
||||||
|
public void escape();
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -21,31 +21,20 @@ package org.sleuthkit.autopsy.keywordsearch;
|
|||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.Comparator;
|
import java.util.Comparator;
|
||||||
import java.util.Iterator;
|
|
||||||
import java.util.LinkedHashMap;
|
import java.util.LinkedHashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.TreeSet;
|
import java.util.TreeSet;
|
||||||
import java.util.concurrent.ExecutionException;
|
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
import java.util.regex.Matcher;
|
import java.util.regex.Matcher;
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
import java.util.regex.PatternSyntaxException;
|
|
||||||
import javax.swing.SwingWorker;
|
|
||||||
import org.apache.solr.client.solrj.SolrQuery;
|
import org.apache.solr.client.solrj.SolrQuery;
|
||||||
import org.apache.solr.client.solrj.SolrServerException;
|
import org.apache.solr.client.solrj.SolrServerException;
|
||||||
import org.apache.solr.client.solrj.response.TermsResponse;
|
|
||||||
import org.apache.solr.client.solrj.response.TermsResponse.Term;
|
|
||||||
import org.netbeans.api.progress.ProgressHandle;
|
|
||||||
import org.netbeans.api.progress.ProgressHandleFactory;
|
|
||||||
import org.openide.nodes.AbstractNode;
|
|
||||||
import org.openide.nodes.ChildFactory;
|
import org.openide.nodes.ChildFactory;
|
||||||
import org.openide.nodes.Children;
|
import org.openide.nodes.Children;
|
||||||
import org.openide.nodes.Node;
|
import org.openide.nodes.Node;
|
||||||
import org.openide.windows.TopComponent;
|
|
||||||
import org.sleuthkit.autopsy.corecomponents.DataResultTopComponent;
|
|
||||||
import org.sleuthkit.autopsy.datamodel.AbstractFsContentNode;
|
import org.sleuthkit.autopsy.datamodel.AbstractFsContentNode;
|
||||||
import org.sleuthkit.autopsy.datamodel.AbstractFsContentNode.FsContentPropertyType;
|
import org.sleuthkit.autopsy.datamodel.AbstractFsContentNode.FsContentPropertyType;
|
||||||
import org.sleuthkit.autopsy.datamodel.KeyValueNode;
|
import org.sleuthkit.autopsy.datamodel.KeyValueNode;
|
||||||
@ -54,182 +43,97 @@ import org.sleuthkit.datamodel.Content;
|
|||||||
import org.sleuthkit.datamodel.File;
|
import org.sleuthkit.datamodel.File;
|
||||||
import org.sleuthkit.datamodel.FsContent;
|
import org.sleuthkit.datamodel.FsContent;
|
||||||
|
|
||||||
public class RegexQuery implements KeywordSearchQuery {
|
/**
|
||||||
|
*
|
||||||
|
* factory responsible for assembling nodes in the right way
|
||||||
|
* and performing lazy queries as needed
|
||||||
|
*/
|
||||||
|
public class KeywordSearchResultFactory extends ChildFactory<KeyValueThing> {
|
||||||
|
|
||||||
|
public enum Presentation {
|
||||||
|
|
||||||
|
COLLAPSE, STRUCTURE
|
||||||
|
};
|
||||||
|
|
||||||
private static final int TERMS_UNLIMITED = -1;
|
|
||||||
//corresponds to field in Solr schema, analyzed with white-space tokenizer only
|
|
||||||
private static final String TERMS_SEARCH_FIELD = "content_ws";
|
|
||||||
private static final String TERMS_HANDLER = "/terms";
|
|
||||||
private static final int TERMS_TIMEOUT = 90 * 1000; //in ms
|
|
||||||
private String regexQuery;
|
|
||||||
private static Logger logger = Logger.getLogger(RegexQuery.class.getName());
|
|
||||||
|
|
||||||
//common properties (superset of all Node properties) to be displayed as columns
|
//common properties (superset of all Node properties) to be displayed as columns
|
||||||
//these are merged with FsContentPropertyType defined properties
|
//these are merged with FsContentPropertyType defined properties
|
||||||
private static enum CommonPropertyTypes {
|
public static enum CommonPropertyTypes {
|
||||||
|
|
||||||
QUERY {
|
QUERY {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return "Query";
|
return "Query";
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
MATCH {
|
MATCH {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return "Match";
|
return "Match";
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
/* MATCH_RANK {
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return "Match Rank";
|
|
||||||
}
|
|
||||||
},*/
|
|
||||||
}
|
}
|
||||||
|
private Presentation presentation;
|
||||||
|
private Collection<String> queries;
|
||||||
|
private Collection<KeyValueThing> things;
|
||||||
|
private static final Logger logger = Logger.getLogger(KeywordSearchResultFactory.class.getName());
|
||||||
|
|
||||||
public RegexQuery(String query) {
|
KeywordSearchResultFactory(Collection<String> queries, Collection<KeyValueThing> things, Presentation presentation) {
|
||||||
this.regexQuery = query;
|
this.queries = queries;
|
||||||
|
this.things = things;
|
||||||
|
this.presentation = presentation;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
KeywordSearchResultFactory(String query, Collection<KeyValueThing> things, Presentation presentation) {
|
||||||
public boolean validate() {
|
queries = new ArrayList<String>();
|
||||||
boolean valid = true;
|
queries.add(query);
|
||||||
try {
|
this.presentation = presentation;
|
||||||
Pattern.compile(regexQuery);
|
this.things = things;
|
||||||
} catch (PatternSyntaxException ex1) {
|
|
||||||
valid = false;
|
|
||||||
} catch (IllegalArgumentException ex2) {
|
|
||||||
valid = false;
|
|
||||||
}
|
|
||||||
return valid;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void execute() {
|
|
||||||
|
|
||||||
final SolrQuery q = new SolrQuery();
|
|
||||||
q.setQueryType(TERMS_HANDLER);
|
|
||||||
q.setTerms(true);
|
|
||||||
q.setTermsLimit(TERMS_UNLIMITED);
|
|
||||||
q.setTermsRegexFlag("case_insensitive");
|
|
||||||
//q.setTermsLimit(200);
|
|
||||||
//q.setTermsRegexFlag(regexFlag);
|
|
||||||
//q.setTermsRaw(true);
|
|
||||||
q.setTermsRegex(regexQuery);
|
|
||||||
q.addTermsField(TERMS_SEARCH_FIELD);
|
|
||||||
q.setTimeAllowed(TERMS_TIMEOUT);
|
|
||||||
|
|
||||||
logger.log(Level.INFO, "Executing TermsComponent query: " + q.toString());
|
|
||||||
|
|
||||||
final SwingWorker worker = new RegexQueryWorker(q);
|
|
||||||
worker.execute();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* map Terms to generic Nodes with key/value pairs properties
|
|
||||||
* @param terms
|
|
||||||
*/
|
|
||||||
private void publishNodes(List<Term> terms) {
|
|
||||||
|
|
||||||
Collection<KeyValueThing> things = new ArrayList<KeyValueThing>();
|
|
||||||
|
|
||||||
Iterator<Term> it = terms.iterator();
|
|
||||||
int termID = 0;
|
|
||||||
//long totalMatches = 0;
|
|
||||||
while (it.hasNext()) {
|
|
||||||
Term term = it.next();
|
|
||||||
Map<String, Object> kvs = new LinkedHashMap<String, Object>();
|
|
||||||
long matches = term.getFrequency();
|
|
||||||
final String match = term.getTerm();
|
|
||||||
setCommonProperty(kvs, CommonPropertyTypes.MATCH, match);
|
|
||||||
//setCommonProperty(kvs, CommonPropertyTypes.MATCH_RANK, Long.toString(matches));
|
|
||||||
things.add(new KeyValueThing(match, kvs, ++termID));
|
|
||||||
//totalMatches += matches;
|
|
||||||
}
|
|
||||||
|
|
||||||
Node rootNode = null;
|
|
||||||
if (things.size() > 0) {
|
|
||||||
Children childThingNodes =
|
|
||||||
Children.create(new RegexResultQueryChildFactory(regexQuery, things), true);
|
|
||||||
|
|
||||||
rootNode = new AbstractNode(childThingNodes);
|
|
||||||
} else {
|
|
||||||
rootNode = Node.EMPTY;
|
|
||||||
}
|
|
||||||
|
|
||||||
final String pathText = "RegEx query";
|
|
||||||
// String pathText = "RegEx query: " + regexQuery
|
|
||||||
//+ " Files with exact matches: " + Long.toString(totalMatches) + " (also listing approximate matches)";
|
|
||||||
|
|
||||||
TopComponent searchResultWin = DataResultTopComponent.createInstance("Keyword search", pathText, rootNode, things.size());
|
|
||||||
searchResultWin.requestActive(); // make it the active top component
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* call this at least for the parent Node, to make sure all common
|
* call this at least for the parent Node, to make sure all common
|
||||||
* properties are displayed as columns (since we are doing lazy child Node load
|
* properties are displayed as columns (since we are doing lazy child Node load
|
||||||
* we need to preinitialize properties when sending parent Node)
|
* we need to preinitialize properties when sending parent Node)
|
||||||
* @param toSet property set map for a Node
|
* @param toSet property set map for a Node
|
||||||
*/
|
*/
|
||||||
private static void initCommonProperties(Map<String, Object> toSet) {
|
public static void initCommonProperties(Map<String, Object> toSet) {
|
||||||
CommonPropertyTypes [] commonTypes = CommonPropertyTypes.values();
|
CommonPropertyTypes[] commonTypes = CommonPropertyTypes.values();
|
||||||
final int COMMON_PROPS_LEN = commonTypes.length;
|
final int COMMON_PROPS_LEN = commonTypes.length;
|
||||||
for (int i = 0; i< COMMON_PROPS_LEN; ++i) {
|
for (int i = 0; i < COMMON_PROPS_LEN; ++i) {
|
||||||
toSet.put(commonTypes[i].toString(), "");
|
toSet.put(commonTypes[i].toString(), "");
|
||||||
}
|
}
|
||||||
|
|
||||||
FsContentPropertyType [] fsTypes = FsContentPropertyType.values();
|
FsContentPropertyType[] fsTypes = FsContentPropertyType.values();
|
||||||
final int FS_PROPS_LEN = fsTypes.length;
|
final int FS_PROPS_LEN = fsTypes.length;
|
||||||
for (int i = 0; i< FS_PROPS_LEN; ++i) {
|
for (int i = 0; i < FS_PROPS_LEN; ++i) {
|
||||||
toSet.put(fsTypes[i].toString(), "");
|
toSet.put(fsTypes[i].toString(), "");
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void setCommonProperty(Map<String, Object> toSet, CommonPropertyTypes type, String value) {
|
public static void setCommonProperty(Map<String, Object> toSet, CommonPropertyTypes type, String value) {
|
||||||
final String typeStr = type.toString();
|
final String typeStr = type.toString();
|
||||||
toSet.put(typeStr, value);
|
toSet.put(typeStr, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* factory produces top level result nodes showing query used
|
|
||||||
*/
|
|
||||||
class RegexResultQueryChildFactory extends ChildFactory<KeyValueThing> {
|
|
||||||
|
|
||||||
Collection<String> queries;
|
@Override
|
||||||
Collection<KeyValueThing> things;
|
protected boolean createKeys(List<KeyValueThing> toPopulate) {
|
||||||
|
int id = 0;
|
||||||
|
for (String query : queries) {
|
||||||
RegexResultQueryChildFactory(Collection<String>queries, Collection<KeyValueThing> things) {
|
Map<String, Object> map = new LinkedHashMap<String, Object>();
|
||||||
this.queries = queries;
|
initCommonProperties(map);
|
||||||
this.things = things;
|
setCommonProperty(map, CommonPropertyTypes.QUERY, query);
|
||||||
}
|
toPopulate.add(new KeyValueThing(query, map, ++id));
|
||||||
|
|
||||||
RegexResultQueryChildFactory(String query, Collection<KeyValueThing> things) {
|
|
||||||
queries = new ArrayList<String>();
|
|
||||||
queries.add(query);
|
|
||||||
this.things = things;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
return true;
|
||||||
protected boolean createKeys(List<KeyValueThing> toPopulate) {
|
}
|
||||||
int id = 0;
|
|
||||||
for (String query : queries) {
|
|
||||||
Map<String, Object> map = new LinkedHashMap<String, Object>();
|
|
||||||
initCommonProperties(map);
|
|
||||||
setCommonProperty(map, CommonPropertyTypes.QUERY, query);
|
|
||||||
toPopulate.add(new KeyValueThing(query, map, ++id));
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected Node createNodeForKey(KeyValueThing thing) {
|
protected Node createNodeForKey(KeyValueThing thing) {
|
||||||
return new KeyValueNode(thing, Children.create(new RegexResultChildFactory(things), true));
|
return new KeyValueNode(thing, Children.create(new RegexResultChildFactory(things), true));
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -273,7 +177,7 @@ public class RegexQuery implements KeywordSearchQuery {
|
|||||||
//use Lucene query to get files with regular expression match result
|
//use Lucene query to get files with regular expression match result
|
||||||
final String keywordQuery = thing.getName();
|
final String keywordQuery = thing.getName();
|
||||||
LuceneQuery filesQuery = new LuceneQuery(keywordQuery);
|
LuceneQuery filesQuery = new LuceneQuery(keywordQuery);
|
||||||
List<FsContent> matches = filesQuery.doQuery();
|
List<FsContent> matches = filesQuery.performQuery();
|
||||||
|
|
||||||
//get unique match result files
|
//get unique match result files
|
||||||
Set<FsContent> uniqueMatches = new TreeSet<FsContent>(new Comparator<FsContent>() {
|
Set<FsContent> uniqueMatches = new TreeSet<FsContent>(new Comparator<FsContent>() {
|
||||||
@ -287,15 +191,14 @@ public class RegexQuery implements KeywordSearchQuery {
|
|||||||
uniqueMatches.addAll(matches);
|
uniqueMatches.addAll(matches);
|
||||||
|
|
||||||
int resID = 0;
|
int resID = 0;
|
||||||
for (FsContent f : uniqueMatches) {
|
for (FsContent f : uniqueMatches) {
|
||||||
Map<String, Object> resMap = new LinkedHashMap<String, Object>();
|
Map<String, Object> resMap = new LinkedHashMap<String, Object>();
|
||||||
AbstractFsContentNode.fillPropertyMap(resMap, (File)f);
|
AbstractFsContentNode.fillPropertyMap(resMap, (File) f);
|
||||||
toPopulate.add(new KeyValueThingContent(f.getName(), resMap, ++resID, f, keywordQuery));
|
toPopulate.add(new KeyValueThingContent(f.getName(), resMap, ++resID, f, keywordQuery));
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected Node createNodeForKey(KeyValueThing thing) {
|
protected Node createNodeForKey(KeyValueThing thing) {
|
||||||
@ -309,7 +212,8 @@ public class RegexQuery implements KeywordSearchQuery {
|
|||||||
//TODO option in GUI to include approximate matches (faster)
|
//TODO option in GUI to include approximate matches (faster)
|
||||||
boolean matchFound = false;
|
boolean matchFound = false;
|
||||||
if (contentStr != null) {//if not null, some error getting from Solr, handle it by not filtering out
|
if (contentStr != null) {//if not null, some error getting from Solr, handle it by not filtering out
|
||||||
Pattern p = Pattern.compile(regexQuery, Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);
|
final String keywordQuery = thing.getName();
|
||||||
|
Pattern p = Pattern.compile(keywordQuery, Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);
|
||||||
Matcher m = p.matcher(contentStr);
|
Matcher m = p.matcher(contentStr);
|
||||||
matchFound = m.find();
|
matchFound = m.find();
|
||||||
}
|
}
|
||||||
@ -362,64 +266,4 @@ public class RegexQuery implements KeywordSearchQuery {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class RegexQueryWorker extends SwingWorker<List<Term>, Void> {
|
|
||||||
|
|
||||||
private SolrQuery q;
|
|
||||||
private ProgressHandle progress;
|
|
||||||
|
|
||||||
RegexQueryWorker(SolrQuery q) {
|
|
||||||
this.q = q;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected List<Term> doInBackground() throws Exception {
|
|
||||||
progress = ProgressHandleFactory.createHandle("RegEx query task");
|
|
||||||
progress.start();
|
|
||||||
progress.progress("Running RegEx query.");
|
|
||||||
|
|
||||||
Server.Core solrCore = KeywordSearch.getServer().getCore();
|
|
||||||
|
|
||||||
|
|
||||||
List<Term> terms = null;
|
|
||||||
try {
|
|
||||||
TermsResponse tr = solrCore.queryTerms(q);
|
|
||||||
terms = tr.getTerms(TERMS_SEARCH_FIELD);
|
|
||||||
} catch (SolrServerException ex) {
|
|
||||||
logger.log(Level.SEVERE, "Error executing the regex terms query: " + regexQuery, ex);
|
|
||||||
return null; //no need to create result view, just display error dialog
|
|
||||||
}
|
|
||||||
|
|
||||||
progress.progress("RegEx query completed.");
|
|
||||||
|
|
||||||
//debug query
|
|
||||||
//StringBuilder sb = new StringBuilder();
|
|
||||||
//for (Term t : terms) {
|
|
||||||
// sb.append(t.getTerm() + " : " + t.getFrequency() + "\n");
|
|
||||||
//}
|
|
||||||
//logger.log(Level.INFO, "TermsComponent query result: " + sb.toString());
|
|
||||||
//end debug query
|
|
||||||
|
|
||||||
return terms;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void done() {
|
|
||||||
if (!this.isCancelled()) {
|
|
||||||
try {
|
|
||||||
List<Term> terms = get();
|
|
||||||
publishNodes(terms);
|
|
||||||
} catch (InterruptedException e) {
|
|
||||||
logger.log(Level.INFO, "Exception while executing regex query,", e);
|
|
||||||
|
|
||||||
} catch (ExecutionException e) {
|
|
||||||
logger.log(Level.INFO, "Exception while executing regex query,", e);
|
|
||||||
} finally {
|
|
||||||
progress.finish();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
@ -25,10 +25,8 @@
|
|||||||
<Group type="103" groupAlignment="0" attributes="0">
|
<Group type="103" groupAlignment="0" attributes="0">
|
||||||
<Group type="102" attributes="0">
|
<Group type="102" attributes="0">
|
||||||
<Component id="queryLabel" min="-2" max="-2" attributes="0"/>
|
<Component id="queryLabel" min="-2" max="-2" attributes="0"/>
|
||||||
<EmptySpace type="unrelated" max="-2" attributes="0"/>
|
<EmptySpace min="-2" pref="62" max="-2" attributes="0"/>
|
||||||
<Component id="luceneQRadioButton" min="-2" max="-2" attributes="0"/>
|
<Component id="chRegex" min="-2" max="-2" attributes="0"/>
|
||||||
<EmptySpace type="unrelated" max="-2" attributes="0"/>
|
|
||||||
<Component id="regexQRadioButton" min="-2" max="-2" attributes="0"/>
|
|
||||||
</Group>
|
</Group>
|
||||||
<Component id="jScrollPane1" alignment="0" pref="599" max="32767" attributes="0"/>
|
<Component id="jScrollPane1" alignment="0" pref="599" max="32767" attributes="0"/>
|
||||||
<Component id="searchButton" alignment="0" min="-2" max="-2" attributes="0"/>
|
<Component id="searchButton" alignment="0" min="-2" max="-2" attributes="0"/>
|
||||||
@ -48,8 +46,7 @@
|
|||||||
<EmptySpace max="-2" attributes="0"/>
|
<EmptySpace max="-2" attributes="0"/>
|
||||||
<Group type="103" groupAlignment="3" attributes="0">
|
<Group type="103" groupAlignment="3" attributes="0">
|
||||||
<Component id="queryLabel" alignment="3" min="-2" max="-2" attributes="0"/>
|
<Component id="queryLabel" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||||
<Component id="luceneQRadioButton" alignment="3" min="-2" max="-2" attributes="0"/>
|
<Component id="chRegex" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||||
<Component id="regexQRadioButton" alignment="3" min="-2" max="-2" attributes="0"/>
|
|
||||||
</Group>
|
</Group>
|
||||||
<EmptySpace max="-2" attributes="0"/>
|
<EmptySpace max="-2" attributes="0"/>
|
||||||
<Component id="jScrollPane1" min="-2" max="-2" attributes="0"/>
|
<Component id="jScrollPane1" min="-2" max="-2" attributes="0"/>
|
||||||
@ -119,20 +116,15 @@
|
|||||||
</Property>
|
</Property>
|
||||||
</AccessibilityProperties>
|
</AccessibilityProperties>
|
||||||
</Component>
|
</Component>
|
||||||
<Component class="javax.swing.JRadioButton" name="luceneQRadioButton">
|
<Component class="javax.swing.JCheckBox" name="chRegex">
|
||||||
<Properties>
|
|
||||||
<Property name="selected" type="boolean" value="true"/>
|
|
||||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
|
||||||
<ResourceString bundle="org/sleuthkit/autopsy/keywordsearch/Bundle.properties" key="KeywordSearchSimpleTopComponent.luceneQRadioButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
|
||||||
</Property>
|
|
||||||
</Properties>
|
|
||||||
</Component>
|
|
||||||
<Component class="javax.swing.JRadioButton" name="regexQRadioButton">
|
|
||||||
<Properties>
|
<Properties>
|
||||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||||
<ResourceString bundle="org/sleuthkit/autopsy/keywordsearch/Bundle.properties" key="KeywordSearchSimpleTopComponent.regexQRadioButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
<ResourceString bundle="org/sleuthkit/autopsy/keywordsearch/Bundle.properties" key="KeywordSearchSimpleTopComponent.chRegex.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||||
</Property>
|
</Property>
|
||||||
</Properties>
|
</Properties>
|
||||||
|
<Events>
|
||||||
|
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="chRegexActionPerformed"/>
|
||||||
|
</Events>
|
||||||
</Component>
|
</Component>
|
||||||
</SubComponents>
|
</SubComponents>
|
||||||
</Form>
|
</Form>
|
||||||
|
@ -30,8 +30,7 @@ public class KeywordSearchSimpleTopComponent extends TopComponent implements Key
|
|||||||
public KeywordSearchSimpleTopComponent() {
|
public KeywordSearchSimpleTopComponent() {
|
||||||
initComponents();
|
initComponents();
|
||||||
setName("Simple");
|
setName("Simple");
|
||||||
buttonGroup1.add(luceneQRadioButton);
|
buttonGroup1.add(chRegex);
|
||||||
buttonGroup1.add(regexQRadioButton);
|
|
||||||
searchButton.setEnabled(false);
|
searchButton.setEnabled(false);
|
||||||
|
|
||||||
putClientProperty(TopComponent.PROP_CLOSING_DISABLED, Boolean.TRUE);
|
putClientProperty(TopComponent.PROP_CLOSING_DISABLED, Boolean.TRUE);
|
||||||
@ -53,8 +52,7 @@ public class KeywordSearchSimpleTopComponent extends TopComponent implements Key
|
|||||||
queryLabel = new javax.swing.JLabel();
|
queryLabel = new javax.swing.JLabel();
|
||||||
filesIndexedNameLabel = new javax.swing.JLabel();
|
filesIndexedNameLabel = new javax.swing.JLabel();
|
||||||
filesIndexedValLabel = new javax.swing.JLabel();
|
filesIndexedValLabel = new javax.swing.JLabel();
|
||||||
luceneQRadioButton = new javax.swing.JRadioButton();
|
chRegex = new javax.swing.JCheckBox();
|
||||||
regexQRadioButton = new javax.swing.JRadioButton();
|
|
||||||
|
|
||||||
queryTextArea.setColumns(20);
|
queryTextArea.setColumns(20);
|
||||||
queryTextArea.setRows(5);
|
queryTextArea.setRows(5);
|
||||||
@ -68,10 +66,12 @@ public class KeywordSearchSimpleTopComponent extends TopComponent implements Key
|
|||||||
|
|
||||||
filesIndexedValLabel.setText(org.openide.util.NbBundle.getMessage(KeywordSearchSimpleTopComponent.class, "KeywordSearchSimpleTopComponent.filesIndexedValLabel.text")); // NOI18N
|
filesIndexedValLabel.setText(org.openide.util.NbBundle.getMessage(KeywordSearchSimpleTopComponent.class, "KeywordSearchSimpleTopComponent.filesIndexedValLabel.text")); // NOI18N
|
||||||
|
|
||||||
luceneQRadioButton.setSelected(true);
|
chRegex.setText(org.openide.util.NbBundle.getMessage(KeywordSearchSimpleTopComponent.class, "KeywordSearchSimpleTopComponent.chRegex.text")); // NOI18N
|
||||||
luceneQRadioButton.setText(org.openide.util.NbBundle.getMessage(KeywordSearchSimpleTopComponent.class, "KeywordSearchSimpleTopComponent.luceneQRadioButton.text")); // NOI18N
|
chRegex.addActionListener(new java.awt.event.ActionListener() {
|
||||||
|
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||||
regexQRadioButton.setText(org.openide.util.NbBundle.getMessage(KeywordSearchSimpleTopComponent.class, "KeywordSearchSimpleTopComponent.regexQRadioButton.text")); // NOI18N
|
chRegexActionPerformed(evt);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
|
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
|
||||||
this.setLayout(layout);
|
this.setLayout(layout);
|
||||||
@ -82,10 +82,8 @@ public class KeywordSearchSimpleTopComponent extends TopComponent implements Key
|
|||||||
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||||
.addGroup(layout.createSequentialGroup()
|
.addGroup(layout.createSequentialGroup()
|
||||||
.addComponent(queryLabel)
|
.addComponent(queryLabel)
|
||||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
|
.addGap(62, 62, 62)
|
||||||
.addComponent(luceneQRadioButton)
|
.addComponent(chRegex))
|
||||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
|
|
||||||
.addComponent(regexQRadioButton))
|
|
||||||
.addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 599, Short.MAX_VALUE)
|
.addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 599, Short.MAX_VALUE)
|
||||||
.addComponent(searchButton)
|
.addComponent(searchButton)
|
||||||
.addGroup(layout.createSequentialGroup()
|
.addGroup(layout.createSequentialGroup()
|
||||||
@ -100,8 +98,7 @@ public class KeywordSearchSimpleTopComponent extends TopComponent implements Key
|
|||||||
.addContainerGap()
|
.addContainerGap()
|
||||||
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
|
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
|
||||||
.addComponent(queryLabel)
|
.addComponent(queryLabel)
|
||||||
.addComponent(luceneQRadioButton)
|
.addComponent(chRegex))
|
||||||
.addComponent(regexQRadioButton))
|
|
||||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||||
.addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
|
.addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||||
.addGap(18, 18, 18)
|
.addGap(18, 18, 18)
|
||||||
@ -116,15 +113,19 @@ public class KeywordSearchSimpleTopComponent extends TopComponent implements Key
|
|||||||
filesIndexedNameLabel.getAccessibleContext().setAccessibleName(org.openide.util.NbBundle.getMessage(KeywordSearchSimpleTopComponent.class, "KeywordSearchTopComponent.filesIndexedNameLabel.AccessibleContext.accessibleName")); // NOI18N
|
filesIndexedNameLabel.getAccessibleContext().setAccessibleName(org.openide.util.NbBundle.getMessage(KeywordSearchSimpleTopComponent.class, "KeywordSearchTopComponent.filesIndexedNameLabel.AccessibleContext.accessibleName")); // NOI18N
|
||||||
filesIndexedValLabel.getAccessibleContext().setAccessibleName(org.openide.util.NbBundle.getMessage(KeywordSearchSimpleTopComponent.class, "KeywordSearchTopComponent.filesIndexedValLabel.AccessibleContext.accessibleName")); // NOI18N
|
filesIndexedValLabel.getAccessibleContext().setAccessibleName(org.openide.util.NbBundle.getMessage(KeywordSearchSimpleTopComponent.class, "KeywordSearchTopComponent.filesIndexedValLabel.AccessibleContext.accessibleName")); // NOI18N
|
||||||
}// </editor-fold>//GEN-END:initComponents
|
}// </editor-fold>//GEN-END:initComponents
|
||||||
|
|
||||||
|
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
|
// Variables declaration - do not modify//GEN-BEGIN:variables
|
||||||
private javax.swing.ButtonGroup buttonGroup1;
|
private javax.swing.ButtonGroup buttonGroup1;
|
||||||
|
private javax.swing.JCheckBox chRegex;
|
||||||
private javax.swing.JLabel filesIndexedNameLabel;
|
private javax.swing.JLabel filesIndexedNameLabel;
|
||||||
private javax.swing.JLabel filesIndexedValLabel;
|
private javax.swing.JLabel filesIndexedValLabel;
|
||||||
private javax.swing.JScrollPane jScrollPane1;
|
private javax.swing.JScrollPane jScrollPane1;
|
||||||
private javax.swing.JRadioButton luceneQRadioButton;
|
|
||||||
private javax.swing.JLabel queryLabel;
|
private javax.swing.JLabel queryLabel;
|
||||||
private javax.swing.JTextArea queryTextArea;
|
private javax.swing.JTextArea queryTextArea;
|
||||||
private javax.swing.JRadioButton regexQRadioButton;
|
|
||||||
private javax.swing.JButton searchButton;
|
private javax.swing.JButton searchButton;
|
||||||
// End of variables declaration//GEN-END:variables
|
// End of variables declaration//GEN-END:variables
|
||||||
|
|
||||||
@ -135,6 +136,11 @@ public class KeywordSearchSimpleTopComponent extends TopComponent implements Key
|
|||||||
queryTextArea.setText("");
|
queryTextArea.setText("");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isMultiwordQuery() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void addSearchButtonListener(ActionListener l) {
|
public void addSearchButtonListener(ActionListener l) {
|
||||||
searchButton.addActionListener(l);
|
searchButton.addActionListener(l);
|
||||||
@ -147,12 +153,12 @@ public class KeywordSearchSimpleTopComponent extends TopComponent implements Key
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isLuceneQuerySelected() {
|
public boolean isLuceneQuerySelected() {
|
||||||
return luceneQRadioButton.isSelected();
|
return !chRegex.isSelected();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isRegexQuerySelected() {
|
public boolean isRegexQuerySelected() {
|
||||||
return regexQRadioButton.isSelected();
|
return chRegex.isSelected();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
<?xml version="1.1" encoding="UTF-8" ?>
|
<?xml version="1.1" encoding="UTF-8" ?>
|
||||||
|
|
||||||
<Form version="1.3" maxVersion="1.7" type="org.netbeans.modules.form.forminfo.JPanelFormInfo">
|
<Form version="1.4" maxVersion="1.7" type="org.netbeans.modules.form.forminfo.JPanelFormInfo">
|
||||||
<AuxValues>
|
<AuxValues>
|
||||||
<AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="1"/>
|
<AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="1"/>
|
||||||
<AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/>
|
<AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/>
|
||||||
|
@ -89,6 +89,7 @@ public final class KeywordSearchTabsTopComponent extends TopComponent implements
|
|||||||
|
|
||||||
private void initTabs() {
|
private void initTabs() {
|
||||||
tabs.addTab("Simple", null, new KeywordSearchSimpleTopComponent(), "Single keyword or regex search");
|
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.");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -97,7 +98,6 @@ public final class KeywordSearchTabsTopComponent extends TopComponent implements
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void componentClosed() {
|
public void componentClosed() {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void writeProperties(java.util.Properties p) {
|
void writeProperties(java.util.Properties p) {
|
||||||
@ -112,6 +112,15 @@ public final class KeywordSearchTabsTopComponent extends TopComponent implements
|
|||||||
// read your settings according to their version
|
// read your settings according to their version
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isMultiwordQuery() {
|
||||||
|
KeywordSearchTopComponentInterface selected = (KeywordSearchTopComponentInterface) tabs.getSelectedComponent();
|
||||||
|
if (selected == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return selected.isMultiwordQuery();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void addSearchButtonListener(ActionListener l) {
|
public void addSearchButtonListener(ActionListener l) {
|
||||||
final int tabsCount = tabs.getTabCount();
|
final int tabsCount = tabs.getTabCount();
|
||||||
@ -159,6 +168,7 @@ public final class KeywordSearchTabsTopComponent extends TopComponent implements
|
|||||||
}
|
}
|
||||||
|
|
||||||
class KeywordSearchServerListener implements PropertyChangeListener {
|
class KeywordSearchServerListener implements PropertyChangeListener {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void propertyChange(PropertyChangeEvent evt) {
|
public void propertyChange(PropertyChangeEvent evt) {
|
||||||
String eventType = evt.getPropertyName();
|
String eventType = evt.getPropertyName();
|
||||||
|
@ -27,6 +27,7 @@ import java.awt.event.ActionListener;
|
|||||||
*/
|
*/
|
||||||
public interface KeywordSearchTopComponentInterface {
|
public interface KeywordSearchTopComponentInterface {
|
||||||
|
|
||||||
|
boolean isMultiwordQuery();
|
||||||
boolean isLuceneQuerySelected();
|
boolean isLuceneQuerySelected();
|
||||||
boolean isRegexQuerySelected();
|
boolean isRegexQuerySelected();
|
||||||
String getQueryText();
|
String getQueryText();
|
||||||
|
@ -43,11 +43,22 @@ public class LuceneQuery implements KeywordSearchQuery {
|
|||||||
|
|
||||||
private static final Logger logger = Logger.getLogger(LuceneQuery.class.getName());
|
private static final Logger logger = Logger.getLogger(LuceneQuery.class.getName());
|
||||||
|
|
||||||
private String query;
|
private String query; //original unescaped query
|
||||||
|
private String queryEscaped;
|
||||||
|
private boolean isEscaped;
|
||||||
|
|
||||||
public LuceneQuery(String query) {
|
public LuceneQuery(String query) {
|
||||||
this.query = query;
|
this.query = query;
|
||||||
|
this.queryEscaped = query;
|
||||||
|
isEscaped = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void escape() {
|
||||||
|
queryEscaped = KeywordSearchUtil.escapeLuceneQuery(query);
|
||||||
|
isEscaped = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Just perform the query and return result without updating the GUI
|
* Just perform the query and return result without updating the GUI
|
||||||
@ -55,7 +66,7 @@ public class LuceneQuery implements KeywordSearchQuery {
|
|||||||
* @param query
|
* @param query
|
||||||
* @return matches List
|
* @return matches List
|
||||||
*/
|
*/
|
||||||
public List<FsContent> doQuery() throws RuntimeException {
|
public List<FsContent> performQuery() throws RuntimeException {
|
||||||
List<FsContent> matches = new ArrayList<FsContent>();
|
List<FsContent> matches = new ArrayList<FsContent>();
|
||||||
|
|
||||||
boolean allMatchesFetched = false;
|
boolean allMatchesFetched = false;
|
||||||
@ -65,7 +76,6 @@ public class LuceneQuery implements KeywordSearchQuery {
|
|||||||
|
|
||||||
SolrQuery q = new SolrQuery();
|
SolrQuery q = new SolrQuery();
|
||||||
|
|
||||||
final String queryEscaped = KeywordSearchUtil.escapeLuceneQuery(query);
|
|
||||||
q.setQuery(queryEscaped);
|
q.setQuery(queryEscaped);
|
||||||
q.setRows(ROWS_PER_FETCH);
|
q.setRows(ROWS_PER_FETCH);
|
||||||
q.setFields("id");
|
q.setFields("id");
|
||||||
@ -107,7 +117,8 @@ public class LuceneQuery implements KeywordSearchQuery {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void execute() {
|
public void execute() {
|
||||||
List<FsContent> matches = doQuery();
|
escape();
|
||||||
|
List<FsContent> matches = performQuery();
|
||||||
|
|
||||||
String pathText = "Lucene query: " + query;
|
String pathText = "Lucene query: " + query;
|
||||||
Node rootNode = new KeywordSearchNode(matches, query);
|
Node rootNode = new KeywordSearchNode(matches, query);
|
||||||
|
@ -0,0 +1,230 @@
|
|||||||
|
/*
|
||||||
|
* 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.util.ArrayList;
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.LinkedHashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.concurrent.ExecutionException;
|
||||||
|
import java.util.logging.Level;
|
||||||
|
import java.util.logging.Logger;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
import java.util.regex.PatternSyntaxException;
|
||||||
|
import javax.swing.SwingWorker;
|
||||||
|
import org.apache.solr.client.solrj.SolrQuery;
|
||||||
|
import org.apache.solr.client.solrj.SolrServerException;
|
||||||
|
import org.apache.solr.client.solrj.response.TermsResponse;
|
||||||
|
import org.apache.solr.client.solrj.response.TermsResponse.Term;
|
||||||
|
import org.netbeans.api.progress.ProgressHandle;
|
||||||
|
import org.netbeans.api.progress.ProgressHandleFactory;
|
||||||
|
import org.openide.nodes.AbstractNode;
|
||||||
|
import org.openide.nodes.Children;
|
||||||
|
import org.openide.nodes.Node;
|
||||||
|
import org.openide.windows.TopComponent;
|
||||||
|
import org.sleuthkit.autopsy.corecomponents.DataResultTopComponent;
|
||||||
|
import org.sleuthkit.autopsy.datamodel.KeyValueThing;
|
||||||
|
import org.sleuthkit.datamodel.FsContent;
|
||||||
|
|
||||||
|
public class TermComponentQuery implements KeywordSearchQuery {
|
||||||
|
|
||||||
|
private static final int TERMS_UNLIMITED = -1;
|
||||||
|
//corresponds to field in Solr schema, analyzed with white-space tokenizer only
|
||||||
|
private static final String TERMS_SEARCH_FIELD = "content_ws";
|
||||||
|
private static final String TERMS_HANDLER = "/terms";
|
||||||
|
private static final int TERMS_TIMEOUT = 90 * 1000; //in ms
|
||||||
|
|
||||||
|
private static Logger logger = Logger.getLogger(TermComponentQuery.class.getName());
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
private String termsQuery;
|
||||||
|
private String queryEscaped;
|
||||||
|
private boolean isEscaped;
|
||||||
|
|
||||||
|
|
||||||
|
public TermComponentQuery(String query) {
|
||||||
|
this.termsQuery = query;
|
||||||
|
this.queryEscaped = query;
|
||||||
|
isEscaped = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void escape() {
|
||||||
|
isEscaped = true;
|
||||||
|
//will use prefix terms component query instead of regex
|
||||||
|
//to treat the query as a word
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean validate() {
|
||||||
|
boolean valid = true;
|
||||||
|
try {
|
||||||
|
Pattern.compile(termsQuery);
|
||||||
|
} catch (PatternSyntaxException ex1) {
|
||||||
|
valid = false;
|
||||||
|
} catch (IllegalArgumentException ex2) {
|
||||||
|
valid = false;
|
||||||
|
}
|
||||||
|
return valid;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
protected void executeQuery() {
|
||||||
|
final SolrQuery q = new SolrQuery();
|
||||||
|
q.setQueryType(TERMS_HANDLER);
|
||||||
|
q.setTerms(true);
|
||||||
|
q.setTermsLimit(TERMS_UNLIMITED);
|
||||||
|
q.setTermsRegexFlag("case_insensitive");
|
||||||
|
//q.setTermsLimit(200);
|
||||||
|
//q.setTermsRegexFlag(regexFlag);
|
||||||
|
//q.setTermsRaw(true);
|
||||||
|
q.setTermsRegex(termsQuery);
|
||||||
|
q.addTermsField(TERMS_SEARCH_FIELD);
|
||||||
|
q.setTimeAllowed(TERMS_TIMEOUT);
|
||||||
|
|
||||||
|
logger.log(Level.INFO, "Executing TermsComponent query: " + q.toString());
|
||||||
|
|
||||||
|
final SwingWorker worker = new TermsQueryWorker(q);
|
||||||
|
worker.execute();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<FsContent> performQuery() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void execute() {
|
||||||
|
executeQuery();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* map Terms to generic Nodes with key/value pairs properties
|
||||||
|
* @param terms
|
||||||
|
*/
|
||||||
|
private void publishNodes(List<Term> terms) {
|
||||||
|
|
||||||
|
Collection<KeyValueThing> things = new ArrayList<KeyValueThing>();
|
||||||
|
|
||||||
|
Iterator<Term> it = terms.iterator();
|
||||||
|
int termID = 0;
|
||||||
|
//long totalMatches = 0;
|
||||||
|
while (it.hasNext()) {
|
||||||
|
Term term = it.next();
|
||||||
|
Map<String, Object> kvs = new LinkedHashMap<String, Object>();
|
||||||
|
//long matches = term.getFrequency();
|
||||||
|
final String match = term.getTerm();
|
||||||
|
KeywordSearchResultFactory.setCommonProperty(kvs, KeywordSearchResultFactory.CommonPropertyTypes.MATCH, match);
|
||||||
|
//setCommonProperty(kvs, CommonPropertyTypes.MATCH_RANK, Long.toString(matches));
|
||||||
|
things.add(new KeyValueThing(match, kvs, ++termID));
|
||||||
|
//totalMatches += matches;
|
||||||
|
}
|
||||||
|
|
||||||
|
Node rootNode = null;
|
||||||
|
if (things.size() > 0) {
|
||||||
|
Children childThingNodes =
|
||||||
|
Children.create(new KeywordSearchResultFactory(termsQuery, things, KeywordSearchResultFactory.Presentation.COLLAPSE), true);
|
||||||
|
|
||||||
|
rootNode = new AbstractNode(childThingNodes);
|
||||||
|
} else {
|
||||||
|
rootNode = Node.EMPTY;
|
||||||
|
}
|
||||||
|
|
||||||
|
final String pathText = "RegEx query";
|
||||||
|
// String pathText = "RegEx query: " + termsQuery
|
||||||
|
//+ " Files with exact matches: " + Long.toString(totalMatches) + " (also listing approximate matches)";
|
||||||
|
|
||||||
|
TopComponent searchResultWin = DataResultTopComponent.createInstance("Keyword search", pathText, rootNode, things.size());
|
||||||
|
searchResultWin.requestActive(); // make it the active top component
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
class TermsQueryWorker extends SwingWorker<List<Term>, Void> {
|
||||||
|
|
||||||
|
private SolrQuery q;
|
||||||
|
private ProgressHandle progress;
|
||||||
|
|
||||||
|
TermsQueryWorker(SolrQuery q) {
|
||||||
|
this.q = q;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected List<Term> doInBackground() throws Exception {
|
||||||
|
progress = ProgressHandleFactory.createHandle("Terms query task");
|
||||||
|
progress.start();
|
||||||
|
progress.progress("Running Terms query.");
|
||||||
|
|
||||||
|
Server.Core solrCore = KeywordSearch.getServer().getCore();
|
||||||
|
|
||||||
|
|
||||||
|
List<Term> terms = null;
|
||||||
|
try {
|
||||||
|
TermsResponse tr = solrCore.queryTerms(q);
|
||||||
|
terms = tr.getTerms(TERMS_SEARCH_FIELD);
|
||||||
|
} catch (SolrServerException ex) {
|
||||||
|
logger.log(Level.SEVERE, "Error executing the regex terms query: " + termsQuery, ex);
|
||||||
|
return null; //no need to create result view, just display error dialog
|
||||||
|
}
|
||||||
|
|
||||||
|
progress.progress("Terms query completed.");
|
||||||
|
|
||||||
|
//debug query
|
||||||
|
//StringBuilder sb = new StringBuilder();
|
||||||
|
//for (Term t : terms) {
|
||||||
|
// sb.append(t.getTerm() + " : " + t.getFrequency() + "\n");
|
||||||
|
//}
|
||||||
|
//logger.log(Level.INFO, "TermsComponent query result: " + sb.toString());
|
||||||
|
//end debug query
|
||||||
|
|
||||||
|
return terms;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void done() {
|
||||||
|
if (!this.isCancelled()) {
|
||||||
|
try {
|
||||||
|
List<Term> terms = get();
|
||||||
|
publishNodes(terms);
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
logger.log(Level.INFO, "Exception while executing regex query,", e);
|
||||||
|
|
||||||
|
} catch (ExecutionException e) {
|
||||||
|
logger.log(Level.INFO, "Exception while executing regex query,", e);
|
||||||
|
} finally {
|
||||||
|
progress.finish();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user