mirror of
https://github.com/overcuriousity/autopsy-flatpak.git
synced 2025-07-06 21:00:22 +00:00
Merge branch 'keyword-search-prototype' of github.com:sleuthkit/autopsy into keyword-search-prototype
This commit is contained in:
commit
ef1e54509d
@ -25,7 +25,9 @@ import java.io.IOException;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import javax.swing.JTable;
|
||||
import javax.swing.ListSelectionModel;
|
||||
import org.openide.explorer.ExplorerManager;
|
||||
@ -135,6 +137,41 @@ public class DataResultViewerTable extends AbstractDataResultViewer {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets regular Bean property set properties from all first children and, recursively, subchildren of Node.
|
||||
* Note: won't work out the box for lazy load - you need to set all children props for the parent by hand
|
||||
* @param parent Node with at least one child to get properties from
|
||||
* @return Properties,
|
||||
*/
|
||||
private Node.Property[] getAllChildPropertyHeaders(Node parent) {
|
||||
Node firstChild = parent.getChildren().getNodeAt(0);
|
||||
|
||||
Property[] properties = null;
|
||||
|
||||
if (firstChild == null) {
|
||||
throw new IllegalArgumentException("Couldn't get a child Node from the given parent.");
|
||||
} else {
|
||||
Set<Property> allProperties = new LinkedHashSet<Property>();
|
||||
while (firstChild != null) {
|
||||
for (PropertySet ps : firstChild.getPropertySets()) {
|
||||
//if (ps.getName().equals(Sheet.PROPERTIES)) {
|
||||
//return ps.getProperties();
|
||||
final Property [] props = ps.getProperties();
|
||||
final int propsNum = props.length;
|
||||
for (int i = 0; i< propsNum; ++i)
|
||||
allProperties.add(props[i]);
|
||||
//}
|
||||
}
|
||||
firstChild = firstChild.getChildren().getNodeAt(0);
|
||||
}
|
||||
|
||||
properties = allProperties.toArray(new Property[0]);
|
||||
//throw new IllegalArgumentException("Child Node doesn't have the regular PropertySet.");
|
||||
}
|
||||
return properties;
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setNode(Node selectedNode) {
|
||||
// change the cursor to "waiting cursor" for this operation
|
||||
@ -163,7 +200,7 @@ public class DataResultViewerTable extends AbstractDataResultViewer {
|
||||
|
||||
OutlineView ov = ((OutlineView) this.tableScrollPanel);
|
||||
|
||||
List<Node.Property> tempProps = new ArrayList<Node.Property>(Arrays.asList(getChildPropertyHeaders(selectedNode)));
|
||||
List<Node.Property> tempProps = new ArrayList<Node.Property>(Arrays.asList(getAllChildPropertyHeaders(selectedNode)));
|
||||
|
||||
tempProps.remove(0);
|
||||
|
||||
@ -245,12 +282,11 @@ public class DataResultViewerTable extends AbstractDataResultViewer {
|
||||
this.setCursor(null);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
private static Object[][] getRowValues(Node node, int rows) {
|
||||
// how many rows are we returning
|
||||
int maxRows = Math.min(rows, node.getChildren().getNodesCount());
|
||||
|
||||
|
||||
Object[][] objs = new Object[maxRows][];
|
||||
|
||||
for (int i = 0; i < maxRows; i++) {
|
||||
@ -266,7 +302,7 @@ public class DataResultViewerTable extends AbstractDataResultViewer {
|
||||
objs[i][j] = "n/a";
|
||||
} catch (InvocationTargetException ignore) {
|
||||
objs[i][j] = "n/a";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return objs;
|
||||
|
@ -18,6 +18,8 @@
|
||||
*/
|
||||
package org.sleuthkit.autopsy.datamodel;
|
||||
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
import org.openide.nodes.Sheet;
|
||||
import org.sleuthkit.datamodel.FsContent;
|
||||
|
||||
@ -25,16 +27,139 @@ import org.sleuthkit.datamodel.FsContent;
|
||||
* Abstract class that implements the commonality between File and Directory
|
||||
* Nodes (same properties).
|
||||
*/
|
||||
abstract class AbstractFsContentNode<T extends FsContent> extends AbstractContentNode<T> {
|
||||
public abstract class AbstractFsContentNode<T extends FsContent> extends AbstractContentNode<T> {
|
||||
|
||||
/**
|
||||
* Name of the property that holds the name.
|
||||
*/
|
||||
public static final String PROPERTY_NAME = "Name";
|
||||
/**
|
||||
* Name of the property that holds the path.
|
||||
*/
|
||||
public static final String PROPERTY_LOCATION = "Location";
|
||||
// Note: this order matters for the search result, changed it if the order of property headers on the "KeywordSearchNode"changed
|
||||
|
||||
public static enum FsContentPropertyType {
|
||||
|
||||
NAME {
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Name";
|
||||
}
|
||||
},
|
||||
LOCATION {
|
||||
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Location";
|
||||
}
|
||||
},
|
||||
MOD_TIME {
|
||||
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Mod. Time";
|
||||
}
|
||||
},
|
||||
CHANGED_TIME {
|
||||
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Change Time";
|
||||
}
|
||||
},
|
||||
ACCESS_TIME {
|
||||
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Access Time";
|
||||
}
|
||||
},
|
||||
CREATED_TIME {
|
||||
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Created Time";
|
||||
}
|
||||
},
|
||||
SIZE {
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Size";
|
||||
}
|
||||
},
|
||||
FLAGS_DIR {
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Flags(Dir)";
|
||||
}
|
||||
},
|
||||
FLAGS_META {
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Flags(Meta)";
|
||||
}
|
||||
},
|
||||
MODE {
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Mode";
|
||||
}
|
||||
},
|
||||
USER_ID {
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "UserID";
|
||||
}
|
||||
},
|
||||
GROUP_ID {
|
||||
@Override
|
||||
public String toString() {
|
||||
return "GroupID";
|
||||
}
|
||||
},
|
||||
META_ADDR {
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Meta Addr.";
|
||||
}
|
||||
},
|
||||
ATTR_ADDR {
|
||||
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Attr. Addr.";
|
||||
}
|
||||
},
|
||||
TYPE_DIR {
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Type(Dir)";
|
||||
}
|
||||
},
|
||||
TYPE_META {
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Type(Meta)";
|
||||
}
|
||||
},
|
||||
KNOWN {
|
||||
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Known";
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
AbstractFsContentNode(T fsContent) {
|
||||
super(fsContent);
|
||||
@ -49,25 +174,43 @@ abstract class AbstractFsContentNode<T extends FsContent> extends AbstractConten
|
||||
s.put(ss);
|
||||
}
|
||||
|
||||
// Note: this order matters for the search result, changed it if the order of property headers on the "KeywordSearchNode"changed
|
||||
ss.put(new NodeProperty(PROPERTY_NAME, "Name", "no description", content.getName()));
|
||||
ss.put(new NodeProperty(PROPERTY_LOCATION, "Location", "no description", DataConversion.getformattedPath(ContentUtils.getDisplayPath(content), 0)));
|
||||
ss.put(new NodeProperty("Modified Time", "Modified Time", "no description", content.getMtimeAsDate()));
|
||||
ss.put(new NodeProperty("Changed Time", "Changed Time", "no description", content.getCtimeAsDate()));
|
||||
ss.put(new NodeProperty("Access Time", "Access Time", "no description", content.getAtimeAsDate()));
|
||||
ss.put(new NodeProperty("Created Time", "Created Time", "no description", content.getCrtimeAsDate()));
|
||||
ss.put(new NodeProperty("Size", "Size", "no description", content.getSize()));
|
||||
ss.put(new NodeProperty("Flags (Directory)", "Flags (Directory)", "no description", content.getDirFlagsAsString()));
|
||||
ss.put(new NodeProperty("Flags (Meta)", "Flags (Meta)", "no description", content.getMetaFlagsAsString()));
|
||||
ss.put(new NodeProperty("Mode ", "Mode", "no description", content.getModeAsString()));
|
||||
ss.put(new NodeProperty("User ID", "User ID", "no description", content.getUid()));
|
||||
ss.put(new NodeProperty("Group ID", "Group ID", "no description", content.getGid()));
|
||||
ss.put(new NodeProperty("Metadata Address", "Metadata Addr", "no description", content.getMeta_addr()));
|
||||
ss.put(new NodeProperty("Attribute Address", "Attribute Addr", "no description", Long.toString(content.getAttr_type()) + "-" + Long.toString(content.getAttr_id())));
|
||||
ss.put(new NodeProperty("Type (Directory)", "Type (Directory)", "no description", content.getDirTypeAsString()));
|
||||
ss.put(new NodeProperty("Type (Meta)", "Type (Meta)", "no description", content.getMetaTypeAsString()));
|
||||
ss.put(new NodeProperty("Known", "Known", "no description", content.getKnown().getName()));
|
||||
Map<String, Object> map = new LinkedHashMap<String, Object>();
|
||||
fillPropertyMap(map, content);
|
||||
|
||||
FsContentPropertyType[] fsTypes = FsContentPropertyType.values();
|
||||
final int FS_PROPS_LEN = fsTypes.length;
|
||||
final String NO_DESCR = "no description";
|
||||
for (int i = 0; i < FS_PROPS_LEN; ++i) {
|
||||
final FsContentPropertyType propType = FsContentPropertyType.values()[i];
|
||||
final String propString = propType.toString();
|
||||
ss.put(new NodeProperty(propString, propString, NO_DESCR, map.get(propString)));
|
||||
}
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fill map with FsContent properties
|
||||
* @param map, with preserved ordering, where property names/values are put
|
||||
* @param content to extract properties from
|
||||
*/
|
||||
public static void fillPropertyMap(Map<String, Object> map, FsContent content) {
|
||||
map.put(FsContentPropertyType.NAME.toString(), content.getName());
|
||||
map.put(FsContentPropertyType.LOCATION.toString(), DataConversion.getformattedPath(ContentUtils.getDisplayPath(content), 0));
|
||||
map.put(FsContentPropertyType.MOD_TIME.toString(), content.getMtimeAsDate());
|
||||
map.put(FsContentPropertyType.CHANGED_TIME.toString(), content.getCtimeAsDate());
|
||||
map.put(FsContentPropertyType.ACCESS_TIME.toString(), content.getAtimeAsDate());
|
||||
map.put(FsContentPropertyType.CREATED_TIME.toString(), content.getCrtimeAsDate());
|
||||
map.put(FsContentPropertyType.SIZE.toString(), Long.toString(content.getSize()));
|
||||
map.put(FsContentPropertyType.FLAGS_DIR.toString(), content.getDirFlagsAsString());
|
||||
map.put(FsContentPropertyType.FLAGS_META.toString(), content.getMetaFlagsAsString());
|
||||
map.put(FsContentPropertyType.MODE.toString(), content.getModeAsString());
|
||||
map.put(FsContentPropertyType.USER_ID.toString(), Long.toString(content.getUid()));
|
||||
map.put(FsContentPropertyType.GROUP_ID.toString(), Long.toString(content.getGid()));
|
||||
map.put(FsContentPropertyType.META_ADDR.toString(), Long.toString(content.getMeta_addr()));
|
||||
map.put(FsContentPropertyType.ATTR_ADDR.toString(), Long.toString(content.getAttr_type()) + "-" + Long.toString(content.getAttr_id()));
|
||||
map.put(FsContentPropertyType.TYPE_DIR.toString(), content.getDirTypeAsString());
|
||||
map.put(FsContentPropertyType.TYPE_META.toString(), content.getMetaTypeAsString());
|
||||
map.put(FsContentPropertyType.KNOWN.toString(), content.getKnown().getName());
|
||||
}
|
||||
}
|
||||
|
2
DataModel/src/org/sleuthkit/autopsy/datamodel/DataConversion.java
Executable file → Normal file
2
DataModel/src/org/sleuthkit/autopsy/datamodel/DataConversion.java
Executable file → Normal file
@ -151,7 +151,7 @@ public class DataConversion {
|
||||
if (counter >= parameter) {
|
||||
// add to the result and also add the new line at the end
|
||||
result.append(temp);
|
||||
result.append(Character.toString(NL));
|
||||
result.append(NLS);
|
||||
}
|
||||
// reset the temp and counter
|
||||
temp = new StringBuilder();
|
||||
|
0
DataModel/src/org/sleuthkit/autopsy/datamodel/KeyValueNode.java
Executable file → Normal file
0
DataModel/src/org/sleuthkit/autopsy/datamodel/KeyValueNode.java
Executable file → Normal file
@ -4,4 +4,5 @@ OpenIDE-Module-Implementation-Version: 1
|
||||
OpenIDE-Module-Install: org/sleuthkit/autopsy/keywordsearch/Installer.class
|
||||
OpenIDE-Module-Layer: org/sleuthkit/autopsy/keywordsearch/layer.xml
|
||||
OpenIDE-Module-Localizing-Bundle: org/sleuthkit/autopsy/keywordsearch/Bundle.properties
|
||||
OpenIDE-Module-Requires: org.openide.windows.WindowManager
|
||||
|
||||
|
@ -1,10 +1,9 @@
|
||||
CTL_KeywordSearchTabsTopComponentAction=Keyword Search
|
||||
CTL_KeywordSearchTabsTopComponentTopComponent=Keyword Search
|
||||
HINT_KeywordSearchTabsTopComponentTopComponent=This is a Keyword Search window
|
||||
OpenIDE-Module-Name=KeywordSearch
|
||||
IndexProgressPanel.statusText.text=Status text
|
||||
IndexProgressPanel.cancelButton.text=Cancel
|
||||
KeywordSearchTopComponent.searchButton.text=Search
|
||||
KeywordSearchTopComponent.queryLabel.text=Query:
|
||||
KeywordSearchTopComponent.filesIndexedNameLabel.text=Files indexed:
|
||||
KeywordSearchTopComponent.filesIndexedValLabel.text=-
|
||||
KeywordSearchTopComponent.filesIndexedNameLabel.AccessibleContext.accessibleName=Files indexed:
|
||||
KeywordSearchTopComponent.filesIndexedValLabel.AccessibleContext.accessibleName=-
|
||||
ExtractedContentPanel.hitLabel.text=Match:
|
||||
@ -14,5 +13,9 @@ ExtractedContentPanel.hitTotalLabel.text=-
|
||||
ExtractedContentPanel.hitButtonsLabel.text=Match
|
||||
ExtractedContentPanel.hitPreviousButton.text=
|
||||
ExtractedContentPanel.hitNextButton.text=
|
||||
KeywordSearchTopComponent.luceneQRadioButton.text=Lucene
|
||||
KeywordSearchTopComponent.regexQRadioButton.text=RegEx
|
||||
KeywordSearchSimpleTopComponent.filesIndexedValLabel.text=-
|
||||
KeywordSearchSimpleTopComponent.filesIndexedNameLabel.text=Files indexed:
|
||||
KeywordSearchSimpleTopComponent.queryLabel.text=Query:
|
||||
KeywordSearchSimpleTopComponent.searchButton.text=Search
|
||||
KeywordSearchSimpleTopComponent.regexQRadioButton.text=RegEx
|
||||
KeywordSearchSimpleTopComponent.luceneQRadioButton.text=Lucene
|
||||
|
@ -53,8 +53,8 @@
|
||||
<Component id="hitPreviousButton" min="-2" pref="23" max="-2" attributes="0"/>
|
||||
<Component id="hitNextButton" min="-2" pref="23" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<EmptySpace max="32767" attributes="0"/>
|
||||
<Component id="jScrollPane1" min="-2" pref="287" max="-2" attributes="0"/>
|
||||
<EmptySpace min="-2" max="-2" attributes="0"/>
|
||||
<Component id="jScrollPane1" pref="287" max="32767" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
|
@ -135,8 +135,8 @@ class ExtractedContentPanel extends javax.swing.JPanel {
|
||||
.addComponent(hitCountLabel))
|
||||
.addComponent(hitPreviousButton, javax.swing.GroupLayout.PREFERRED_SIZE, 23, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||
.addComponent(hitNextButton, javax.swing.GroupLayout.PREFERRED_SIZE, 23, javax.swing.GroupLayout.PREFERRED_SIZE))
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
||||
.addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 287, javax.swing.GroupLayout.PREFERRED_SIZE))
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 287, Short.MAX_VALUE))
|
||||
);
|
||||
}// </editor-fold>//GEN-END:initComponents
|
||||
// Variables declaration - do not modify//GEN-BEGIN:variables
|
||||
|
@ -27,11 +27,10 @@ import java.awt.event.WindowAdapter;
|
||||
import java.awt.event.WindowEvent;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Comparator;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.TreeSet;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
@ -112,17 +111,15 @@ public class IndexContentFilesAction extends AbstractAction {
|
||||
Collection<FsContent> ingestableFiles = c.accept(ingestableV);
|
||||
Collection<FsContent> allFiles = c.accept(allV);
|
||||
|
||||
//calculate non ingestable Collection (complement of allFiles / ingestableFiles)
|
||||
Collection<FsContent> nonIngestibleFiles = new TreeSet<FsContent>(new Comparator<FsContent>() {
|
||||
|
||||
@Override
|
||||
public int compare(FsContent fsc1, FsContent fsc2) {
|
||||
return (int) (fsc1.getId() - fsc2.getId());
|
||||
|
||||
//calculate non ingestable Collection (complement of allFiles / ingestableFiles
|
||||
//TODO implement a facility that selects different categories of FsContent
|
||||
Collection<FsContent> nonIngestibleFiles = new LinkedHashSet<FsContent>();
|
||||
|
||||
for (FsContent fs : allFiles) {
|
||||
if (! ingestableFiles.contains(fs) ) {
|
||||
nonIngestibleFiles.add(fs);
|
||||
}
|
||||
});
|
||||
nonIngestibleFiles.addAll(allFiles);
|
||||
nonIngestibleFiles.removeAll(ingestableFiles);
|
||||
}
|
||||
|
||||
// track number complete or with errors
|
||||
problemFilesCount = 0;
|
||||
|
@ -36,13 +36,13 @@ import org.sleuthkit.autopsy.keywordsearch.KeywordSearch.QueryType;
|
||||
public class KeywordSearchDataExplorer implements DataExplorer {
|
||||
|
||||
private static KeywordSearchDataExplorer theInstance;
|
||||
private KeywordSearchTopComponent tc;
|
||||
private KeywordSearchTabsTopComponent tc;
|
||||
|
||||
public KeywordSearchDataExplorer() {
|
||||
this.setTheInstance();
|
||||
this.tc = new KeywordSearchTopComponent();
|
||||
this.tc.addSearchButtonListener(new ActionListener() {
|
||||
this.tc = new KeywordSearchTabsTopComponent();
|
||||
|
||||
this.tc.addSearchButtonListener(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
tc.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
|
||||
@ -62,6 +62,8 @@ public class KeywordSearchDataExplorer implements DataExplorer {
|
||||
|
||||
KeywordSearch.changeSupport.addPropertyChangeListener(KeywordSearch.NUM_FILES_CHANGE_EVT, new IndexChangeListener());
|
||||
}
|
||||
|
||||
|
||||
|
||||
private synchronized void setTheInstance() {
|
||||
if (theInstance == null) {
|
||||
|
@ -84,21 +84,21 @@
|
||||
<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="KeywordSearchTopComponent.searchButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/keywordsearch/Bundle.properties" key="KeywordSearchSimpleTopComponent.searchButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
</Component>
|
||||
<Component class="javax.swing.JLabel" name="queryLabel">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/keywordsearch/Bundle.properties" key="KeywordSearchTopComponent.queryLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/keywordsearch/Bundle.properties" key="KeywordSearchSimpleTopComponent.queryLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</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="KeywordSearchTopComponent.filesIndexedNameLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/keywordsearch/Bundle.properties" key="KeywordSearchSimpleTopComponent.filesIndexedNameLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<AccessibilityProperties>
|
||||
@ -110,7 +110,7 @@
|
||||
<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="KeywordSearchTopComponent.filesIndexedValLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/keywordsearch/Bundle.properties" key="KeywordSearchSimpleTopComponent.filesIndexedValLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<AccessibilityProperties>
|
||||
@ -123,14 +123,14 @@
|
||||
<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="KeywordSearchTopComponent.luceneQRadioButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
<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>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/keywordsearch/Bundle.properties" key="KeywordSearchTopComponent.regexQRadioButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/keywordsearch/Bundle.properties" key="KeywordSearchSimpleTopComponent.regexQRadioButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
</Component>
|
@ -19,31 +19,22 @@
|
||||
package org.sleuthkit.autopsy.keywordsearch;
|
||||
|
||||
import java.awt.event.ActionListener;
|
||||
import java.beans.PropertyChangeEvent;
|
||||
import java.beans.PropertyChangeListener;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
import org.apache.solr.client.solrj.SolrServerException;
|
||||
import org.openide.windows.TopComponent;
|
||||
|
||||
public class KeywordSearchTopComponent extends TopComponent {
|
||||
public class KeywordSearchSimpleTopComponent extends TopComponent implements KeywordSearchTopComponentInterface {
|
||||
|
||||
private Logger logger = Logger.getLogger(KeywordSearchTopComponent.class.getName());
|
||||
private PropertyChangeListener serverChangeListener;
|
||||
private Logger logger = Logger.getLogger(KeywordSearchSimpleTopComponent.class.getName());
|
||||
|
||||
/** Creates new form KeywordSearchTopComponent */
|
||||
public KeywordSearchTopComponent() {
|
||||
/** Creates new form KeywordSearchSimpleTopComponent */
|
||||
public KeywordSearchSimpleTopComponent() {
|
||||
initComponents();
|
||||
setName("Keyword Search");
|
||||
setName("Simple");
|
||||
buttonGroup1.add(luceneQRadioButton);
|
||||
buttonGroup1.add(regexQRadioButton);
|
||||
searchButton.setEnabled(false);
|
||||
|
||||
putClientProperty(TopComponent.PROP_CLOSING_DISABLED, Boolean.TRUE);
|
||||
|
||||
//register with server Actions
|
||||
serverChangeListener = new KeywordSearchServerListener();
|
||||
KeywordSearch.getServer().addServerActionListener(serverChangeListener);
|
||||
}
|
||||
|
||||
/** This method is called from within the constructor to
|
||||
@ -69,18 +60,18 @@ public class KeywordSearchTopComponent extends TopComponent {
|
||||
queryTextArea.setRows(5);
|
||||
jScrollPane1.setViewportView(queryTextArea);
|
||||
|
||||
searchButton.setText(org.openide.util.NbBundle.getMessage(KeywordSearchTopComponent.class, "KeywordSearchTopComponent.searchButton.text")); // NOI18N
|
||||
searchButton.setText(org.openide.util.NbBundle.getMessage(KeywordSearchSimpleTopComponent.class, "KeywordSearchSimpleTopComponent.searchButton.text")); // NOI18N
|
||||
|
||||
queryLabel.setText(org.openide.util.NbBundle.getMessage(KeywordSearchTopComponent.class, "KeywordSearchTopComponent.queryLabel.text")); // NOI18N
|
||||
queryLabel.setText(org.openide.util.NbBundle.getMessage(KeywordSearchSimpleTopComponent.class, "KeywordSearchSimpleTopComponent.queryLabel.text")); // NOI18N
|
||||
|
||||
filesIndexedNameLabel.setText(org.openide.util.NbBundle.getMessage(KeywordSearchTopComponent.class, "KeywordSearchTopComponent.filesIndexedNameLabel.text")); // NOI18N
|
||||
filesIndexedNameLabel.setText(org.openide.util.NbBundle.getMessage(KeywordSearchSimpleTopComponent.class, "KeywordSearchSimpleTopComponent.filesIndexedNameLabel.text")); // NOI18N
|
||||
|
||||
filesIndexedValLabel.setText(org.openide.util.NbBundle.getMessage(KeywordSearchTopComponent.class, "KeywordSearchTopComponent.filesIndexedValLabel.text")); // NOI18N
|
||||
filesIndexedValLabel.setText(org.openide.util.NbBundle.getMessage(KeywordSearchSimpleTopComponent.class, "KeywordSearchSimpleTopComponent.filesIndexedValLabel.text")); // NOI18N
|
||||
|
||||
luceneQRadioButton.setSelected(true);
|
||||
luceneQRadioButton.setText(org.openide.util.NbBundle.getMessage(KeywordSearchTopComponent.class, "KeywordSearchTopComponent.luceneQRadioButton.text")); // NOI18N
|
||||
luceneQRadioButton.setText(org.openide.util.NbBundle.getMessage(KeywordSearchSimpleTopComponent.class, "KeywordSearchSimpleTopComponent.luceneQRadioButton.text")); // NOI18N
|
||||
|
||||
regexQRadioButton.setText(org.openide.util.NbBundle.getMessage(KeywordSearchTopComponent.class, "KeywordSearchTopComponent.regexQRadioButton.text")); // NOI18N
|
||||
regexQRadioButton.setText(org.openide.util.NbBundle.getMessage(KeywordSearchSimpleTopComponent.class, "KeywordSearchSimpleTopComponent.regexQRadioButton.text")); // NOI18N
|
||||
|
||||
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
|
||||
this.setLayout(layout);
|
||||
@ -122,8 +113,8 @@ public class KeywordSearchTopComponent extends TopComponent {
|
||||
.addContainerGap(106, Short.MAX_VALUE))
|
||||
);
|
||||
|
||||
filesIndexedNameLabel.getAccessibleContext().setAccessibleName(org.openide.util.NbBundle.getMessage(KeywordSearchTopComponent.class, "KeywordSearchTopComponent.filesIndexedNameLabel.AccessibleContext.accessibleName")); // NOI18N
|
||||
filesIndexedValLabel.getAccessibleContext().setAccessibleName(org.openide.util.NbBundle.getMessage(KeywordSearchTopComponent.class, "KeywordSearchTopComponent.filesIndexedValLabel.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
|
||||
}// </editor-fold>//GEN-END:initComponents
|
||||
// Variables declaration - do not modify//GEN-BEGIN:variables
|
||||
private javax.swing.ButtonGroup buttonGroup1;
|
||||
@ -143,18 +134,23 @@ public class KeywordSearchTopComponent extends TopComponent {
|
||||
// clear old search
|
||||
queryTextArea.setText("");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addSearchButtonListener(ActionListener l) {
|
||||
searchButton.addActionListener(l);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getQueryText() {
|
||||
return queryTextArea.getText();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isLuceneQuerySelected() {
|
||||
return luceneQRadioButton.isSelected();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isRegexQuerySelected() {
|
||||
return regexQRadioButton.isSelected();
|
||||
}
|
||||
@ -163,13 +159,14 @@ public class KeywordSearchTopComponent extends TopComponent {
|
||||
* Overwrite when you want to change default persistence type. Default
|
||||
* persistence type is PERSISTENCE_ALWAYS
|
||||
*
|
||||
* @return TopComponent.PERSISTENCE_ALWAYS
|
||||
* @return TopComponent.PERSISTENCE_NEVER
|
||||
*/
|
||||
@Override
|
||||
public int getPersistenceType() {
|
||||
return TopComponent.PERSISTENCE_NEVER;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setFilesIndexed(int filesIndexed) {
|
||||
filesIndexedValLabel.setText(Integer.toString(filesIndexed));
|
||||
if (filesIndexed == 0) {
|
||||
@ -179,29 +176,4 @@ public class KeywordSearchTopComponent extends TopComponent {
|
||||
}
|
||||
}
|
||||
|
||||
class KeywordSearchServerListener implements PropertyChangeListener {
|
||||
|
||||
@Override
|
||||
public void propertyChange(PropertyChangeEvent evt) {
|
||||
String eventType = evt.getPropertyName();
|
||||
|
||||
if (eventType.equals(Server.CORE_EVT)) {
|
||||
final Server.CORE_EVT_STATES state = (Server.CORE_EVT_STATES) evt.getNewValue();
|
||||
switch (state) {
|
||||
case STARTED:
|
||||
try {
|
||||
final int numIndexedFiles = KeywordSearch.getServer().getCore().queryNumIndexedFiles();
|
||||
KeywordSearch.changeSupport.firePropertyChange(KeywordSearch.NUM_FILES_CHANGE_EVT, null, new Integer(numIndexedFiles));
|
||||
} catch (SolrServerException se) {
|
||||
logger.log(Level.SEVERE, "Error executing Solr query, " + se.getMessage());
|
||||
}
|
||||
break;
|
||||
case STOPPED:
|
||||
break;
|
||||
default:
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,34 @@
|
||||
<?xml version="1.1" encoding="UTF-8" ?>
|
||||
|
||||
<Form version="1.3" 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">
|
||||
<Component id="tabs" alignment="0" pref="400" max="32767" attributes="0"/>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
<DimensionLayout dim="1">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Component id="tabs" alignment="0" pref="300" max="32767" attributes="0"/>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
</Layout>
|
||||
<SubComponents>
|
||||
<Container class="javax.swing.JTabbedPane" name="tabs">
|
||||
|
||||
<Layout class="org.netbeans.modules.form.compat2.layouts.support.JTabbedPaneSupportLayout"/>
|
||||
</Container>
|
||||
</SubComponents>
|
||||
</Form>
|
@ -0,0 +1,186 @@
|
||||
/*
|
||||
* 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.beans.PropertyChangeEvent;
|
||||
import java.beans.PropertyChangeListener;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
import org.apache.solr.client.solrj.SolrServerException;
|
||||
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;
|
||||
|
||||
/**
|
||||
* Keyword Search explorer top component, container for specific Keyword Search tabs
|
||||
*/
|
||||
@ConvertAsProperties(dtd = "-//org.sleuthkit.autopsy.keywordsearch//KeywordSearchTabsTopComponent//EN",
|
||||
autostore = false)
|
||||
@TopComponent.Description(preferredID = "KeywordSearchTabsTopComponent",
|
||||
//iconBase="SET/PATH/TO/ICON/HERE",
|
||||
persistenceType = TopComponent.PERSISTENCE_NEVER)
|
||||
@TopComponent.Registration(mode = "explorer", openAtStartup = false)
|
||||
@ActionID(category = "Window", id = "org.sleuthkit.autopsy.keywordsearch.KeywordSearchTabsTopComponentTopComponent")
|
||||
@ActionReference(path = "Menu/Window" /*, position = 333 */)
|
||||
@TopComponent.OpenActionRegistration(displayName = "#CTL_KeywordSearchTabsTopComponentAction",
|
||||
preferredID = "KeywordSearchTabsTopComponent")
|
||||
public final class KeywordSearchTabsTopComponent extends TopComponent implements KeywordSearchTopComponentInterface {
|
||||
|
||||
private Logger logger = Logger.getLogger(KeywordSearchTabsTopComponent.class.getName());
|
||||
private PropertyChangeListener serverChangeListener;
|
||||
|
||||
public KeywordSearchTabsTopComponent() {
|
||||
initComponents();
|
||||
initTabs();
|
||||
setName(NbBundle.getMessage(KeywordSearchTabsTopComponent.class, "CTL_KeywordSearchTabsTopComponentTopComponent"));
|
||||
setToolTipText(NbBundle.getMessage(KeywordSearchTabsTopComponent.class, "HINT_KeywordSearchTabsTopComponentTopComponent"));
|
||||
|
||||
|
||||
putClientProperty(TopComponent.PROP_CLOSING_DISABLED, Boolean.TRUE);
|
||||
|
||||
//register with server Actions
|
||||
serverChangeListener = new KeywordSearchServerListener();
|
||||
KeywordSearch.getServer().addServerActionListener(serverChangeListener);
|
||||
}
|
||||
|
||||
/** 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() {
|
||||
|
||||
tabs = new javax.swing.JTabbedPane();
|
||||
|
||||
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
|
||||
this.setLayout(layout);
|
||||
layout.setHorizontalGroup(
|
||||
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addComponent(tabs, javax.swing.GroupLayout.DEFAULT_SIZE, 400, Short.MAX_VALUE)
|
||||
);
|
||||
layout.setVerticalGroup(
|
||||
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addComponent(tabs, javax.swing.GroupLayout.DEFAULT_SIZE, 300, Short.MAX_VALUE)
|
||||
);
|
||||
}// </editor-fold>//GEN-END:initComponents
|
||||
// Variables declaration - do not modify//GEN-BEGIN:variables
|
||||
private javax.swing.JTabbedPane tabs;
|
||||
// End of variables declaration//GEN-END:variables
|
||||
|
||||
private void initTabs() {
|
||||
tabs.addTab("Simple", null, new KeywordSearchSimpleTopComponent(), "Single keyword or regex search");
|
||||
}
|
||||
|
||||
@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");
|
||||
// store your settings
|
||||
}
|
||||
|
||||
void readProperties(java.util.Properties p) {
|
||||
String version = p.getProperty("version");
|
||||
// read your settings according to their version
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addSearchButtonListener(ActionListener l) {
|
||||
final int tabsCount = tabs.getTabCount();
|
||||
for (int i = 0; i < tabsCount; ++i) {
|
||||
KeywordSearchTopComponentInterface ks = (KeywordSearchTopComponentInterface) tabs.getComponentAt(i);
|
||||
ks.addSearchButtonListener(l);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getQueryText() {
|
||||
KeywordSearchTopComponentInterface selected = (KeywordSearchTopComponentInterface) tabs.getSelectedComponent();
|
||||
if (selected == null) {
|
||||
return "";
|
||||
}
|
||||
return selected.getQueryText();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isLuceneQuerySelected() {
|
||||
KeywordSearchTopComponentInterface selected = (KeywordSearchTopComponentInterface) tabs.getSelectedComponent();
|
||||
if (selected == null) {
|
||||
return false;
|
||||
}
|
||||
return selected.isLuceneQuerySelected();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isRegexQuerySelected() {
|
||||
KeywordSearchTopComponentInterface selected = (KeywordSearchTopComponentInterface) tabs.getSelectedComponent();
|
||||
if (selected == null) {
|
||||
return false;
|
||||
}
|
||||
return selected.isRegexQuerySelected();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setFilesIndexed(int filesIndexed) {
|
||||
final int tabsCount = tabs.getTabCount();
|
||||
for (int i = 0; i < tabsCount; ++i) {
|
||||
KeywordSearchTopComponentInterface ks = (KeywordSearchTopComponentInterface) tabs.getComponentAt(i);
|
||||
ks.setFilesIndexed(filesIndexed);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class KeywordSearchServerListener implements PropertyChangeListener {
|
||||
@Override
|
||||
public void propertyChange(PropertyChangeEvent evt) {
|
||||
String eventType = evt.getPropertyName();
|
||||
|
||||
if (eventType.equals(Server.CORE_EVT)) {
|
||||
final Server.CORE_EVT_STATES state = (Server.CORE_EVT_STATES) evt.getNewValue();
|
||||
switch (state) {
|
||||
case STARTED:
|
||||
try {
|
||||
final int numIndexedFiles = KeywordSearch.getServer().getCore().queryNumIndexedFiles();
|
||||
KeywordSearch.changeSupport.firePropertyChange(KeywordSearch.NUM_FILES_CHANGE_EVT, null, new Integer(numIndexedFiles));
|
||||
//setFilesIndexed(numIndexedFiles);
|
||||
} catch (SolrServerException se) {
|
||||
logger.log(Level.SEVERE, "Error executing Solr query, " + se.getMessage());
|
||||
}
|
||||
break;
|
||||
case STOPPED:
|
||||
break;
|
||||
default:
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,36 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
|
||||
/**
|
||||
* common methods for the KeywordSearch TCs / tabs
|
||||
*
|
||||
*/
|
||||
public interface KeywordSearchTopComponentInterface {
|
||||
|
||||
boolean isLuceneQuerySelected();
|
||||
boolean isRegexQuerySelected();
|
||||
String getQueryText();
|
||||
void setFilesIndexed(int filesIndexed);
|
||||
void addSearchButtonListener(ActionListener l);
|
||||
|
||||
}
|
@ -46,9 +46,12 @@ 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.AbstractFsContentNode;
|
||||
import org.sleuthkit.autopsy.datamodel.AbstractFsContentNode.FsContentPropertyType;
|
||||
import org.sleuthkit.autopsy.datamodel.KeyValueNode;
|
||||
import org.sleuthkit.autopsy.datamodel.KeyValueThing;
|
||||
import org.sleuthkit.datamodel.Content;
|
||||
import org.sleuthkit.datamodel.File;
|
||||
import org.sleuthkit.datamodel.FsContent;
|
||||
|
||||
public class RegexQuery implements KeywordSearchQuery {
|
||||
@ -60,6 +63,30 @@ public class RegexQuery implements KeywordSearchQuery {
|
||||
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
|
||||
//these are merged with FsContentPropertyType defined properties
|
||||
private static enum CommonPropertyTypes {
|
||||
QUERY {
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Query";
|
||||
}
|
||||
},
|
||||
MATCH {
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Match";
|
||||
}
|
||||
},
|
||||
/* MATCH_RANK {
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Match Rank";
|
||||
}
|
||||
},*/
|
||||
}
|
||||
|
||||
|
||||
public RegexQuery(String query) {
|
||||
this.regexQuery = query;
|
||||
@ -109,33 +136,101 @@ public class RegexQuery implements KeywordSearchQuery {
|
||||
|
||||
Iterator<Term> it = terms.iterator();
|
||||
int termID = 0;
|
||||
long totalMatches = 0;
|
||||
//long totalMatches = 0;
|
||||
while (it.hasNext()) {
|
||||
Term term = it.next();
|
||||
Map<String, Object> kvs = new LinkedHashMap<String, Object>();
|
||||
long matches = term.getFrequency();
|
||||
kvs.put("#exact matches", matches);
|
||||
things.add(new KeyValueThing(term.getTerm(), kvs, ++termID));
|
||||
totalMatches += matches;
|
||||
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) {
|
||||
if (things.size() > 0) {
|
||||
Children childThingNodes =
|
||||
Children.create(new RegexResultChildFactory(things), true);
|
||||
Children.create(new RegexResultQueryChildFactory(regexQuery, things), true);
|
||||
|
||||
rootNode = new AbstractNode(childThingNodes);
|
||||
} else {
|
||||
rootNode = Node.EMPTY;
|
||||
}
|
||||
|
||||
String pathText = "RegEx query: " + regexQuery
|
||||
+ " Files with exact matches: " + Long.toString(totalMatches) + " (also listing approximate matches)";
|
||||
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
|
||||
* properties are displayed as columns (since we are doing lazy child Node load
|
||||
* we need to preinitialize properties when sending parent Node)
|
||||
* @param toSet property set map for a Node
|
||||
*/
|
||||
private static void initCommonProperties(Map<String, Object> toSet) {
|
||||
CommonPropertyTypes [] commonTypes = CommonPropertyTypes.values();
|
||||
final int COMMON_PROPS_LEN = commonTypes.length;
|
||||
for (int i = 0; i< COMMON_PROPS_LEN; ++i) {
|
||||
toSet.put(commonTypes[i].toString(), "");
|
||||
}
|
||||
|
||||
FsContentPropertyType [] fsTypes = FsContentPropertyType.values();
|
||||
final int FS_PROPS_LEN = fsTypes.length;
|
||||
for (int i = 0; i< FS_PROPS_LEN; ++i) {
|
||||
toSet.put(fsTypes[i].toString(), "");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static void setCommonProperty(Map<String, Object> toSet, CommonPropertyTypes type, String value) {
|
||||
final String typeStr = type.toString();
|
||||
toSet.put(typeStr, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* factory produces top level result nodes showing query used
|
||||
*/
|
||||
class RegexResultQueryChildFactory extends ChildFactory<KeyValueThing> {
|
||||
|
||||
Collection<String> queries;
|
||||
Collection<KeyValueThing> things;
|
||||
|
||||
|
||||
RegexResultQueryChildFactory(Collection<String>queries, Collection<KeyValueThing> things) {
|
||||
this.queries = queries;
|
||||
this.things = things;
|
||||
}
|
||||
|
||||
RegexResultQueryChildFactory(String query, Collection<KeyValueThing> things) {
|
||||
queries = new ArrayList<String>();
|
||||
queries.add(query);
|
||||
this.things = things;
|
||||
}
|
||||
|
||||
@Override
|
||||
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
|
||||
protected Node createNodeForKey(KeyValueThing thing) {
|
||||
return new KeyValueNode(thing, Children.create(new RegexResultChildFactory(things), true));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* factory produces top level result nodes showing *exact* regex match result
|
||||
@ -192,25 +287,15 @@ public class RegexQuery implements KeywordSearchQuery {
|
||||
uniqueMatches.addAll(matches);
|
||||
|
||||
int resID = 0;
|
||||
for (FsContent f : uniqueMatches) {
|
||||
for (FsContent f : uniqueMatches) {
|
||||
Map<String, Object> resMap = new LinkedHashMap<String, Object>();
|
||||
//final String name = f.getName();
|
||||
final long id = f.getId();
|
||||
|
||||
//build dir name
|
||||
String dirName = KeywordSearchUtil.buildDirName(f);
|
||||
|
||||
resMap.put("dir", dirName);
|
||||
resMap.put("id", Long.toString(id));
|
||||
final String name = dirName + f.getName();
|
||||
resMap.put("name", name);
|
||||
|
||||
toPopulate.add(new KeyValueThingContent(name, resMap, ++resID, f, keywordQuery));
|
||||
AbstractFsContentNode.fillPropertyMap(resMap, (File)f);
|
||||
toPopulate.add(new KeyValueThingContent(f.getName(), resMap, ++resID, f, keywordQuery));
|
||||
}
|
||||
//TODO fix showing of 2nd level child attributes in the GUI (DataResultViewerTable issue?)
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected Node createNodeForKey(KeyValueThing thing) {
|
||||
@ -308,10 +393,10 @@ public class RegexQuery implements KeywordSearchQuery {
|
||||
progress.progress("RegEx query completed.");
|
||||
|
||||
//debug query
|
||||
StringBuilder sb = new StringBuilder();
|
||||
for (Term t : terms) {
|
||||
sb.append(t.getTerm() + " : " + t.getFrequency() + "\n");
|
||||
}
|
||||
//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
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user