This commit is contained in:
adam-m 2012-02-23 16:42:57 -05:00
commit 0ea28b766a
21 changed files with 351 additions and 163 deletions

View File

@ -277,12 +277,30 @@ public class DataContentViewerArtifact extends javax.swing.JPanel implements Dat
@Override
public boolean isSupported(Node node) {
return true;
if (node == null) {
return false;
}
ArtifactStringContent artifact = node.getLookup().lookup(ArtifactStringContent.class);
Content content = node.getLookup().lookup(Content.class);
if(artifact != null) {
return true;
}
if(content != null) {
try {
int size = content.getAllArtifacts().size();
return size > 0;
} catch (TskException ex) {
logger.log(Level.WARNING, "Couldn't get All blackboard Artifacts", ex);
}
}
return false;
}
@Override
public boolean isPreferred(Node node, boolean isSupported) {
return false;
return node.getLookup().lookup(ArtifactStringContent.class) != null;
}
private void customizeComponents(){

View File

@ -31,6 +31,7 @@ import org.openide.util.lookup.ServiceProvider;
import org.sleuthkit.autopsy.corecomponentinterfaces.DataContentViewer;
import org.sleuthkit.autopsy.datamodel.DataConversion;
import org.sleuthkit.datamodel.Content;
import org.sleuthkit.datamodel.File;
import org.sleuthkit.datamodel.TskException;
/**
@ -370,6 +371,12 @@ public class DataContentViewerHex extends javax.swing.JPanel implements DataCont
@Override
public boolean isSupported(Node node) {
if(node == null) {
return false;
}
File file = node.getLookup().lookup(File.class);
if(file != null && file.getSize() == 0)
return false;
return true;
}

View File

@ -150,22 +150,22 @@ public class DataContentViewerPicture extends javax.swing.JPanel implements Data
|| //node.getDisplayName().toLowerCase().endsWith(".tif") ||
//node.getDisplayName().toLowerCase().endsWith(".tiff") ||
//node.getDisplayName().toLowerCase().endsWith(".tga") ||
node.getDisplayName().toLowerCase().endsWith(".png");*/
node.getDisplayName().toLowerCase().endsWith(".png");*/
File file = node.getLookup().lookup(File.class);
if(file != null){
return file.getName().toLowerCase().endsWith(".jpg")
|| file.getName().toLowerCase().endsWith(".jpeg")
|| file.getName().toLowerCase().endsWith(".jpe")
|| file.getName().toLowerCase().endsWith(".jfif")
|| file.getName().toLowerCase().endsWith(".gif")
|| file.getName().toLowerCase().endsWith(".bmp")
|| //node.getName().toLowerCase().endsWith(".tif") ||
//node.getName().toLowerCase().endsWith(".tiff") ||
//node.getName().toLowerCase().endsWith(".tga") ||
file.getName().toLowerCase().endsWith(".png");
}
else{
if (file != null) {
return file.getSize() > 0
&& (file.getName().toLowerCase().endsWith(".jpg")
|| file.getName().toLowerCase().endsWith(".jpeg")
|| file.getName().toLowerCase().endsWith(".jpe")
|| file.getName().toLowerCase().endsWith(".jfif")
|| file.getName().toLowerCase().endsWith(".gif")
|| file.getName().toLowerCase().endsWith(".bmp")
|| //node.getName().toLowerCase().endsWith(".tif") ||
//node.getName().toLowerCase().endsWith(".tiff") ||
//node.getName().toLowerCase().endsWith(".tga") ||
file.getName().toLowerCase().endsWith(".png"));
} else {
return false;
}
} else {

View File

@ -32,6 +32,7 @@ import org.sleuthkit.autopsy.corecomponentinterfaces.DataContentViewer;
import org.sleuthkit.autopsy.datamodel.DataConversion;
import org.sleuthkit.autopsy.datamodel.StringContent;
import org.sleuthkit.datamodel.Content;
import org.sleuthkit.datamodel.File;
import org.sleuthkit.datamodel.TskException;
/**
@ -360,6 +361,12 @@ public class DataContentViewerString extends javax.swing.JPanel implements DataC
@Override
public boolean isSupported(Node node) {
if(node == null) {
return false;
}
File file = node.getLookup().lookup(File.class);
if(file != null && file.getSize() == 0)
return false;
return true;
}

View File

@ -18,10 +18,13 @@
*/
package org.sleuthkit.autopsy.datamodel;
import java.sql.SQLException;
import java.util.Arrays;
import org.openide.util.Exceptions;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.sleuthkit.datamodel.BlackboardArtifact;
import org.sleuthkit.datamodel.BlackboardAttribute;
import org.sleuthkit.datamodel.File;
import org.sleuthkit.datamodel.TskException;
/**
@ -31,6 +34,7 @@ import org.sleuthkit.datamodel.TskException;
*/
public class ArtifactStringContent implements StringContent{
BlackboardArtifact wrapped;
static final Logger logger = Logger.getLogger(ArtifactStringContent.class.getName());
public ArtifactStringContent(BlackboardArtifact art){
wrapped = art;
@ -74,4 +78,15 @@ public class ArtifactStringContent implements StringContent{
}
}
public static File getAssociatedFile(BlackboardArtifact artifact){
try {
return artifact.getSleuthkitCase().getFileById(artifact.getObjectID());
} catch (SQLException ex) {
logger.log(Level.WARNING, "SQL query threw exception", ex);
} catch (TskException ex) {
logger.log(Level.WARNING, "Getting file failed", ex);
}
throw new IllegalArgumentException("Couldn't get file from database");
}
}

View File

@ -26,6 +26,7 @@ import java.util.logging.Logger;
import org.openide.nodes.AbstractNode;
import org.openide.nodes.Children;
import org.openide.nodes.Sheet;
import org.openide.util.Lookup;
import org.openide.util.lookup.Lookups;
import org.sleuthkit.datamodel.BlackboardArtifact;
import org.sleuthkit.datamodel.BlackboardAttribute;
@ -44,7 +45,8 @@ public class BlackboardArtifactNode extends AbstractNode implements DisplayableI
static final Logger logger = Logger.getLogger(BlackboardArtifactNode.class.getName());
public BlackboardArtifactNode(BlackboardArtifact artifact) {
super(Children.LEAF, Lookups.singleton(new ArtifactStringContent(artifact)));
super(Children.LEAF, Lookups.singleton(getAssociatedFile(artifact)));
//super(Children.LEAF, Lookups.singleton(new ArtifactStringContent(artifact)));
this.artifact = artifact;
this.setName(Long.toString(artifact.getArtifactID()));
this.setDisplayName(artifact.getDisplayName());
@ -129,6 +131,17 @@ public class BlackboardArtifactNode extends AbstractNode implements DisplayableI
throw new IllegalArgumentException("Couldn't get file from database");
}
public static File getAssociatedFile(BlackboardArtifact artifact){
try {
return artifact.getSleuthkitCase().getFileById(artifact.getObjectID());
} catch (SQLException ex) {
logger.log(Level.WARNING, "SQL query threw exception", ex);
} catch (TskException ex) {
logger.log(Level.WARNING, "Getting file failed", ex);
}
throw new IllegalArgumentException("Couldn't get file from database");
}
public Directory getParentDirectory(){
try{
return getAssociatedFile().getParentDirectory();

View File

@ -44,6 +44,7 @@ class FileSearchFilterChildren extends ChildFactory<Content> {
SleuthkitCase skCase;
FileSearchFilter filter;
Logger logger = Logger.getLogger(FileSearchFilterChildren.class.getName());
public FileSearchFilterChildren(FileSearchFilter filter, SleuthkitCase skCase) {
this.filter = filter;
@ -57,10 +58,11 @@ class FileSearchFilterChildren extends ChildFactory<Content> {
}
private String createQuery(){
String query = "select * from tsk_files where 0";
String query = "select * from tsk_files where known <> 1 and (0";
for(String s : filter.getFilter()){
query += " or name like '%" + s + "'";
}
query += ')';
return query;
}
@ -78,8 +80,7 @@ class FileSearchFilterChildren extends ChildFactory<Content> {
if (s != null)
s.close();
} catch (SQLException ex) {
Logger.getLogger(FileSearchFilterChildren.class.getName())
.log(Level.INFO, "Couldn't get search results", ex);
logger.log(Level.INFO, "Couldn't get search results", ex);
}
return list;

View File

@ -18,8 +18,13 @@
*/
package org.sleuthkit.autopsy.datamodel;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Arrays;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.openide.nodes.ChildFactory;
import org.openide.nodes.Node;
import org.sleuthkit.datamodel.SleuthkitCase;
@ -31,6 +36,8 @@ import org.sleuthkit.datamodel.SleuthkitCase;
public class RecentFilesChildren extends ChildFactory<RecentFiles.RecentFilesFilter>{
SleuthkitCase skCase;
long latestUpdateTime;
private final static Logger logger = Logger.getLogger(RecentFilesChildren.class.getName());
public RecentFilesChildren(SleuthkitCase skCase) {
this.skCase = skCase;
@ -39,12 +46,45 @@ public class RecentFilesChildren extends ChildFactory<RecentFiles.RecentFilesFil
@Override
protected boolean createKeys(List<RecentFiles.RecentFilesFilter> list) {
list.addAll(Arrays.asList(RecentFiles.RecentFilesFilter.values()));
latestUpdateTime = getLastTime();
return true;
}
@Override
protected Node createNodeForKey(RecentFiles.RecentFilesFilter key){
return new RecentFilesFilterNode(skCase, key);
return new RecentFilesFilterNode(skCase, key, latestUpdateTime);
}
private long getLastTime() {
String query = createMaxQuery("crtime");
long maxcr = runTimeQuery(query);
query = createMaxQuery("ctime");
long maxc = runTimeQuery(query);
query = createMaxQuery("mtime");
long maxm = runTimeQuery(query);
query = createMaxQuery("atime");
long maxa = runTimeQuery(query);
return Math.max(maxcr, Math.max(maxc, Math.max(maxm, maxa)));
}
private String createMaxQuery(String attr){
return "select max(" + attr + ") from tsk_files where " + attr + " < " + System.currentTimeMillis()/1000;
}
private long runTimeQuery(String query) {
long result = 0;
try {
ResultSet rs = skCase.runQuery(query);
result = rs.getLong(1);
Statement s = rs.getStatement();
rs.close();
if (s != null)
s.close();
} catch (SQLException ex) {
Logger.getLogger(RecentFilesFilterChildren.class.getName())
.log(Level.INFO, "Couldn't get search results", ex);
}
return result;
}
}

View File

@ -44,11 +44,13 @@ public class RecentFilesFilterChildren extends ChildFactory<Content>{
SleuthkitCase skCase;
RecentFilesFilter filter;
long latestUpdate;
private final static Logger logger = Logger.getLogger(RecentFilesFilterChildren.class.getName());
RecentFilesFilterChildren(RecentFilesFilter filter, SleuthkitCase skCase) {
RecentFilesFilterChildren(RecentFilesFilter filter, SleuthkitCase skCase, long latestUpdate) {
this.skCase = skCase;
this.filter = filter;
this.latestUpdate = latestUpdate;
}
@Override
@ -59,7 +61,6 @@ public class RecentFilesFilterChildren extends ChildFactory<Content>{
private String createQuery(){
String query = "select * from tsk_files where ";
long latestUpdate = getLastTime();
long threshold = latestUpdate-filter.getDurationSeconds();
query += "(crtime between " + threshold + " and " + latestUpdate + ") or ";
query += "(ctime between " + threshold + " and " + latestUpdate + ") or ";
@ -109,36 +110,4 @@ public class RecentFilesFilterChildren extends ChildFactory<Content>{
});
}
private long getLastTime() {
String query = createMaxQuery("crtime");
long maxcr = runTimeQuery(query);
query = createMaxQuery("ctime");
long maxc = runTimeQuery(query);
query = createMaxQuery("mtime");
long maxm = runTimeQuery(query);
query = createMaxQuery("atime");
long maxa = runTimeQuery(query);
return Math.max(maxcr, Math.max(maxc, Math.max(maxm, maxa)));
}
private String createMaxQuery(String attr){
return "select max(" + attr + ") from tsk_files where " + attr + " < " + System.currentTimeMillis()/1000;
}
private long runTimeQuery(String query) {
long result = 0;
try {
ResultSet rs = skCase.runQuery(query);
result = rs.getLong(1);
Statement s = rs.getStatement();
rs.close();
if (s != null)
s.close();
} catch (SQLException ex) {
Logger.getLogger(RecentFilesFilterChildren.class.getName())
.log(Level.INFO, "Couldn't get search results", ex);
}
return result;
}
}

View File

@ -18,6 +18,12 @@
*/
package org.sleuthkit.autopsy.datamodel;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Date;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.openide.nodes.AbstractNode;
import org.openide.nodes.Children;
import org.openide.nodes.Sheet;
@ -34,12 +40,15 @@ public class RecentFilesFilterNode extends AbstractNode implements DisplayableIt
SleuthkitCase skCase;
RecentFilesFilter filter;
RecentFilesFilterNode(SleuthkitCase skCase, RecentFilesFilter filter) {
super(Children.create(new RecentFilesFilterChildren(filter, skCase), true), Lookups.singleton(filter));
RecentFilesFilterNode(SleuthkitCase skCase, RecentFilesFilter filter, long latestUpdate) {
super(Children.create(new RecentFilesFilterChildren(filter, skCase, latestUpdate), true), Lookups.singleton(filter));
super.setName(filter.getName());
super.setDisplayName(filter.getDisplayName());
this.skCase = skCase;
this.filter = filter;
String tooltip = "Between " + new Date((latestUpdate-filter.getDurationSeconds())*1000).toString();
tooltip += "\n and " + new Date(latestUpdate*1000).toString();
this.setShortDescription(tooltip);
this.setIconBaseWithExtension("org/sleuthkit/autopsy/images/recent-icon.png");
}

View File

@ -30,10 +30,15 @@ public class SearchFilters implements AutopsyVisitableItem{
SleuthkitCase skCase;
public enum FileSearchFilter implements AutopsyVisitableItem {
TSK_IMAGE_FILTER(0, "TSK_IMAGE_FILTER", "Images", Arrays.asList(".jpg", ".jpeg", ".png", ".psd", ".nef")),
TSK_VIDEO_FILTER(1, "TSK_VIDEO_FILTER", "Videos", Arrays.asList(".mov", ".avi", ".m4v")),
TSK_AUDIO_FILTER(2, "TSK_AUDIO_FILTER", "Audio", Arrays.asList(".mp3", ".aac", ".wav", ".ogg", ".wma", ".m4a")),
TSK_DOCUMENT_FILTER(3, "TSK_DOCUMENT_FILTER", "Documents", Arrays.asList(".doc", ".docx", ".pdf", ".xls"));
TSK_IMAGE_FILTER(0, "TSK_IMAGE_FILTER", "Images", Arrays.asList(".jpg", ".jpeg", ".png", ".psd", ".nef", ".tiff")),
TSK_VIDEO_FILTER(1, "TSK_VIDEO_FILTER", "Videos",
Arrays.asList(".aaf", ".3gp", ".asf", ".avi", ".m1v", ".m2v", ".m4v",
".mov", ".mpeg", ".mpg", ".mpe", ".mp4", ".rm", ".wmv", ".mpv")),
TSK_AUDIO_FILTER(2, "TSK_AUDIO_FILTER", "Audio",
Arrays.asList(".aiff", ".aif", ".flac", ".wav", ".m4a", ".ape", ".wma", ".mp2",
".mp1", ".mp3", ".aac", ".mp4", ".m4p", ".m1a", ".m2a", ".m4r", ".mpa",
".m3u", ".mid", ".midi", ".ogg")),
TSK_DOCUMENT_FILTER(3, "TSK_DOCUMENT_FILTER", "Documents", Arrays.asList(".doc", ".docx", ".pdf", ".xls", ".rtf", ".txt"));
int id;
String name;

View File

@ -32,8 +32,8 @@ public class SearchFiltersNode extends AbstractNode implements DisplayableItemNo
SearchFiltersNode(SleuthkitCase skCase) {
super(Children.create(new SearchFiltersChildren(skCase), true));
super.setName("Search Filters");
super.setDisplayName("Search Filters");
super.setName("File Types");
super.setDisplayName("File Types");
this.skCase = skCase;
this.setIconBaseWithExtension("org/sleuthkit/autopsy/images/filter-icon.png");
}

View File

@ -579,8 +579,11 @@ public final class DirectoryTreeTopComponent extends TopComponent implements Dat
Node treeNode = DirectoryTreeTopComponent.this.getSelectedNode();
if (treeNode != null) {
Node originNode = treeNode.getLookup().lookup(DirectoryTreeFilterNode.OriginalNode.class).getNode();
OriginalNode origin = treeNode.getLookup().lookup(DirectoryTreeFilterNode.OriginalNode.class);
if(origin == null)
return;
Node originNode = origin.getNode();
//int count = originNode.getChildren().getNodesCount(true);
//if (count > 1000) {
// DirectoryTreeTopComponent.this.setCursor(null);
@ -723,10 +726,10 @@ public final class DirectoryTreeTopComponent extends TopComponent implements Dat
@Override
public void run() {
Children resultChilds = dataResult.getRootNode().getChildren();
Node select = resultChilds.findChild(Long.toString(art.getArtifactID()));
if (select != null) {
dataResult.requestActive();
dataResult.setSelectedNodes(new Node[]{select});
}
}

View File

@ -69,10 +69,11 @@ class ViewContextAction extends AbstractAction {
ReverseHierarchyVisitor vtor = new ReverseHierarchyVisitor();
List<Content> hierarchy = node.getAssociatedFile().accept(vtor);
Collections.reverse(hierarchy);
Node generated = new AbstractNode(new RootContentChildren(hierarchy));
Node generated = new DirectoryTreeFilterNode(new AbstractNode(new RootContentChildren(hierarchy)));
Children genChilds = generated.getChildren();
final DirectoryTreeTopComponent directoryTree = DirectoryTreeTopComponent.findInstance();
TreeView tree = directoryTree.getTree();
ExplorerManager man = directoryTree.getExplorerManager();
Node dirRoot = man.getRootContext();
Children dirChilds = dirRoot.getChildren();
@ -85,6 +86,7 @@ class ViewContextAction extends AbstractAction {
Node currentDirectoryTreeNode = dirChilds.getNodeAt(j);
if (currentGeneratedNode.getDisplayName().equals(currentDirectoryTreeNode.getDisplayName())) {
dirExplored = currentDirectoryTreeNode;
tree.expandNode(dirExplored);
dirChilds = currentDirectoryTreeNode.getChildren();
break;
}
@ -93,7 +95,6 @@ class ViewContextAction extends AbstractAction {
try {
if (dirExplored != null) {
TreeView tree = directoryTree.getTree();
tree.expandNode(dirExplored);
man.setExploredContextAndSelection(dirExplored, new Node[]{dirExplored});
}
@ -114,6 +115,7 @@ class ViewContextAction extends AbstractAction {
for (int i = 0; i < resultChilds.getNodesCount(); i++) {
Node current = resultChilds.getNodeAt(i);
if (generated.getName().equals(current.getName())) {
dataResult.requestActive();
dataResult.setSelectedNodes(new Node[]{current});
break;
}

View File

@ -82,3 +82,4 @@ KeywordSearchPanel.settingsLabel.text=
KeywordSearchPanel.listsButton.text=Watch Lists
KeywordSearchListsViewerPanel.searchAddButton.text=Search
KeywordSearchListsViewerPanel.manageListsButton.text=Manage Lists
KeywordSearchListsViewerPanel.ingestLabel.text=Lists added during ingest will be enqueued until index is ready for searching

View File

@ -26,16 +26,19 @@ package org.sleuthkit.autopsy.keywordsearch;
import java.awt.Dimension;
import java.awt.Toolkit;
import java.util.logging.Logger;
import javax.swing.JFrame;
import org.sleuthkit.autopsy.ingest.IngestManager;
/**
*
* @author dfickling
*/
public class KeywordSearchConfigurationDialog extends javax.swing.JDialog {
KeywordSearchListsManagementPanel listsManagementPanel;
KeywordSearchEditListPanel editListPanel;
private final static Logger logger = Logger.getLogger(KeywordSearchConfigurationDialog.class.getName());
/** Creates new form KeywordSearchConfigurationDialog */
public KeywordSearchConfigurationDialog(String title) {
@ -44,17 +47,17 @@ public class KeywordSearchConfigurationDialog extends javax.swing.JDialog {
initComponents();
customizeComponents();
}
private void customizeComponents() {
listsManagementPanel = KeywordSearchListsManagementPanel.getDefault();
editListPanel = KeywordSearchEditListPanel.getDefault();
listsManagementPanel.addListSelectionListener(KeywordSearchEditListPanel.getDefault());
mainSplitPane.setLeftComponent(listsManagementPanel);
mainSplitPane.setRightComponent(editListPanel);
mainSplitPane.revalidate();
mainSplitPane.repaint();
Dimension screenDimension = Toolkit.getDefaultToolkit().getScreenSize();
// set the popUp window / JFrame
@ -113,9 +116,17 @@ public class KeywordSearchConfigurationDialog extends javax.swing.JDialog {
private void applyButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_applyButtonActionPerformed
editListPanel.save();
KeywordSearchListsXML loader = KeywordSearchListsXML.getCurrent();
KeywordSearchIngestService service = KeywordSearchIngestService.getDefault();
if (IngestManager.getDefault().isServiceRunning(service)) {
for (KeywordSearchList list : loader.getListsL()) {
if (list.getUseForIngest()) {
service.addToKeywordLists(list.getName());
}
}
}
this.dispose();
}//GEN-LAST:event_applyButtonActionPerformed
// Variables declaration - do not modify//GEN-BEGIN:variables
private javax.swing.JButton applyButton;
private javax.swing.JSplitPane mainSplitPane;

View File

@ -27,6 +27,8 @@ package org.sleuthkit.autopsy.keywordsearch;
import java.awt.Component;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.io.File;
import java.util.ArrayList;
import java.util.Iterator;
@ -48,16 +50,18 @@ import javax.swing.filechooser.FileNameExtensionFilter;
import javax.swing.table.AbstractTableModel;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.TableColumn;
import org.sleuthkit.autopsy.ingest.IngestManager;
/**
*
* @author dfickling
*/
public class KeywordSearchEditListPanel extends javax.swing.JPanel implements ListSelectionListener{
class KeywordSearchEditListPanel extends javax.swing.JPanel implements ListSelectionListener{
private static Logger logger = Logger.getLogger(KeywordSearchEditListPanel.class.getName());
private KeywordTableModel tableModel;
private String currentKeywordList;
private boolean ingestRunning;
private static KeywordSearchEditListPanel instance = null;
@ -137,19 +141,69 @@ public class KeywordSearchEditListPanel extends javax.swing.JPanel implements Li
copyMenuItem.addActionListener(actList);
pasteMenuItem.addActionListener(actList);
selectAllMenuItem.addActionListener(actList);
if(IngestManager.getDefault().isServiceRunning(KeywordSearchIngestService.getDefault()))
initIngest(0);
else
initIngest(1);
IngestManager.addPropertyChangeListener(new PropertyChangeListener() {
@Override
public void propertyChange(PropertyChangeEvent evt) {
String changed = evt.getPropertyName();
Object oldValue = evt.getOldValue();
if(changed.equals(IngestManager.SERVICE_COMPLETED_EVT) &&
((String) oldValue).equals(KeywordSearchIngestService.MODULE_NAME))
initIngest(1);
else if(changed.equals(IngestManager.SERVICE_STARTED_EVT) &&
((String) oldValue).equals(KeywordSearchIngestService.MODULE_NAME))
initIngest(0);
else if(changed.equals(IngestManager.SERVICE_STOPPED_EVT) &&
((String) oldValue).equals(KeywordSearchIngestService.MODULE_NAME))
initIngest(1);
}
});
}
/**
* Initialize this panel depending on whether ingest is running
* @param running
* case 0: ingest running
* case 1: ingest not running
*/
private void initIngest(int running) {
switch (running) {
case 0:
ingestRunning = true;
break;
case 1:
ingestRunning = false;
break;
}
initButtons();
}
private void initButtons() {
void initButtons() {
//initialize buttons
boolean listSet = (currentKeywordList != null);
addWordButton.setEnabled(listSet);
addWordField.setEnabled(listSet);
chRegex.setEnabled(listSet);
useForIngestCheckbox.setEnabled(listSet);
List<String> locked = new ArrayList<String>();
if (ingestRunning) {
locked = KeywordSearchIngestService.getDefault().getKeywordLists();
}
boolean currentUnlocked = !locked.contains(currentKeywordList);
addWordButton.setEnabled(listSet && currentUnlocked);
addWordField.setEnabled(listSet && currentUnlocked);
chRegex.setEnabled(listSet && currentUnlocked);
useForIngestCheckbox.setEnabled(listSet && currentUnlocked);
saveListButton.setEnabled(listSet);
exportButton.setEnabled(listSet);
deleteListButton.setEnabled(listSet);
deleteWordButton.setEnabled(listSet);
deleteListButton.setEnabled(listSet && currentUnlocked);
deleteWordButton.setEnabled(listSet && currentUnlocked);
if (getAllKeywords().isEmpty()) {
saveListButton.setEnabled(false);

View File

@ -64,6 +64,7 @@ public final class KeywordSearchIngestService implements IngestServiceFsContent
private volatile boolean commitIndex = false; //whether to commit index next time
private volatile boolean runTimer = false;
private List<Keyword> keywords; //keywords to search
private List<String> keywordLists; // lists currently being searched
//private final Object lock = new Object();
private Thread timer;
private Indexer indexer;
@ -188,8 +189,9 @@ public final class KeywordSearchIngestService implements IngestServiceFsContent
reportedHits = new HashMap<String, List<FsContent>>();
keywords = new ArrayList<Keyword>();
keywordLists = new ArrayList<String>();
updateKeywords();
initKeywords();
if (keywords.isEmpty()) {
managerProxy.postMessage(IngestMessage.createErrorMessage(++messageID, instance, "No keywords in keyword list. Will index and skip search."));
@ -288,16 +290,42 @@ public final class KeywordSearchIngestService implements IngestServiceFsContent
}
}
/**
* Initialize the keyword search lists from the XML loader
*/
private void initKeywords() {
KeywordSearchListsXML loader = KeywordSearchListsXML.getCurrent();
keywords.clear();
keywordLists.clear();
for(KeywordSearchList list : loader.getListsL()){
if(list.getUseForIngest())
keywordLists.add(list.getName());
keywords.addAll(list.getKeywords());
}
}
/**
* Retrieve the updated keyword search lists from the XML loader
*/
private void updateKeywords() {
KeywordSearchListsXML loader = KeywordSearchListsXML.getCurrent();
keywords.clear();
for(KeywordSearchList list : loader.getListsL()){
if(list.getUseForIngest())
keywords.addAll(list.getKeywords());
for(String name : keywordLists) {
keywords.addAll(loader.getList(name).getKeywords());
}
logger.info(keywords.size()+"");
}
List<String> getKeywordLists() {
return keywordLists == null ? new ArrayList<String>() : keywordLists;
}
void addToKeywordLists(String name) {
if(!keywordLists.contains(name))
keywordLists.add(name);
}
//CommitTimer wakes up every interval ms
@ -554,6 +582,8 @@ public final class KeywordSearchIngestService implements IngestServiceFsContent
//logger.log(Level.INFO, "Finished search");
if (finalRun) {
keywords.clear();
keywordLists.clear();
managerProxy.postMessage(IngestMessage.createMessage(++messageID, MessageType.INFO, KeywordSearchIngestService.instance, "Completed"));
}
}

View File

@ -46,7 +46,7 @@ import javax.swing.table.DefaultTableCellRenderer;
*
* @author dfickling
*/
public class KeywordSearchListsManagementPanel extends javax.swing.JPanel {
class KeywordSearchListsManagementPanel extends javax.swing.JPanel {
private Logger logger = Logger.getLogger(KeywordSearchListsManagementPanel.class.getName());
private KeywordListTableModel tableModel;
@ -411,27 +411,6 @@ public class KeywordSearchListsManagementPanel extends javax.swing.JPanel {
}
}
}
/**
* tooltips that show text
*/
private static class CellTooltipRenderer extends DefaultTableCellRenderer {
@Override
public Component getTableCellRendererComponent(
JTable table, Object value,
boolean isSelected, boolean hasFocus,
int row, int column) {
if (column < 3) {
String val = (String) table.getModel().getValueAt(row, column);
setToolTipText(val);
setText(val);
}
return this;
}
}
void addListSelectionListener(ListSelectionListener l) {
listsTable.getSelectionModel().addListSelectionListener(l);

View File

@ -24,13 +24,20 @@
<Component id="manageListsButton" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
</Group>
<Group type="102" alignment="0" attributes="0">
<EmptySpace max="-2" attributes="0"/>
<Component id="ingestLabel" min="-2" max="-2" attributes="0"/>
<EmptySpace pref="51" max="32767" attributes="0"/>
</Group>
</Group>
</DimensionLayout>
<DimensionLayout dim="1">
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" alignment="0" attributes="0">
<Component id="jSplitPane1" min="-2" pref="268" max="-2" attributes="0"/>
<EmptySpace pref="8" max="32767" attributes="0"/>
<EmptySpace pref="7" max="32767" attributes="0"/>
<Component id="ingestLabel" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Group type="103" groupAlignment="3" attributes="0">
<Component id="manageListsButton" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="searchAddButton" alignment="3" min="-2" max="-2" attributes="0"/>
@ -42,19 +49,11 @@
</Layout>
<SubComponents>
<Container class="javax.swing.JSplitPane" name="jSplitPane1">
<Properties>
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[406, 404]"/>
</Property>
</Properties>
<Layout class="org.netbeans.modules.form.compat2.layouts.support.JSplitPaneSupportLayout"/>
<SubComponents>
<Container class="javax.swing.JScrollPane" name="leftPane">
<Properties>
<Property name="background" type="java.awt.Color" editor="org.netbeans.beaninfo.editors.ColorEditor">
<Color blue="cc" green="cc" red="cc" type="rgb"/>
</Property>
<Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[150, 23]"/>
</Property>
@ -85,11 +84,6 @@
</SubComponents>
</Container>
<Container class="javax.swing.JScrollPane" name="rightPane">
<Properties>
<Property name="background" type="java.awt.Color" editor="org.netbeans.beaninfo.editors.ColorEditor">
<Color blue="cc" green="cc" red="cc" type="rgb"/>
</Property>
</Properties>
<Constraints>
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.support.JSplitPaneSupportLayout" value="org.netbeans.modules.form.compat2.layouts.support.JSplitPaneSupportLayout$JSplitPaneConstraintsDescription">
<JSplitPaneConstraints position="right"/>
@ -131,5 +125,15 @@
</Property>
</Properties>
</Component>
<Component class="javax.swing.JLabel" name="ingestLabel">
<Properties>
<Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor">
<Font name="Tahoma" size="10" style="0"/>
</Property>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/keywordsearch/Bundle.properties" key="KeywordSearchListsViewerPanel.ingestLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
</Component>
</SubComponents>
</Form>

View File

@ -24,6 +24,7 @@
*/
package org.sleuthkit.autopsy.keywordsearch;
import java.awt.Component;
import java.awt.Cursor;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
@ -35,10 +36,15 @@ import java.util.List;
import java.util.Set;
import java.util.TreeSet;
import java.util.logging.Logger;
import javax.swing.JCheckBox;
import javax.swing.JTable;
import javax.swing.ListSelectionModel;
import javax.swing.border.Border;
import javax.swing.border.EmptyBorder;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import javax.swing.table.AbstractTableModel;
import javax.swing.table.TableCellRenderer;
import javax.swing.table.TableColumn;
import org.openide.util.actions.SystemAction;
import org.sleuthkit.autopsy.ingest.IngestManager;
@ -47,7 +53,7 @@ import org.sleuthkit.autopsy.ingest.IngestManager;
*
* @author dfickling
*/
public class KeywordSearchListsViewerPanel extends AbstractKeywordSearchPerformer {
class KeywordSearchListsViewerPanel extends AbstractKeywordSearchPerformer {
private static final Logger logger = Logger.getLogger(KeywordSearchListsViewerPanel.class.getName());
private static KeywordSearchListsViewerPanel instance;
@ -74,9 +80,9 @@ public class KeywordSearchListsViewerPanel extends AbstractKeywordSearchPerforme
}
private void customizeComponents() {
listsTableModel.resync();
ingestLabel.setVisible(false);
listsTable.setTableHeader(null);
listsTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
//customize column witdhs
final int leftWidth = leftPane.getPreferredSize().width;
TableColumn column = null;
@ -84,6 +90,7 @@ public class KeywordSearchListsViewerPanel extends AbstractKeywordSearchPerforme
column = listsTable.getColumnModel().getColumn(i);
if (i == 0) {
column.setPreferredWidth(((int) (leftWidth * 0.10)));
column.setCellRenderer(new CheckBoxRenderer());
} else {
column.setPreferredWidth(((int) (leftWidth * 0.89)));
}
@ -116,6 +123,7 @@ public class KeywordSearchListsViewerPanel extends AbstractKeywordSearchPerforme
else
listsTable.getSelectionModel().clearSelection();
} else if (changed.equals(KeywordSearchListsXML.ListsEvt.LIST_UPDATED.toString())) {
//keywordsTableModel.resync(loader.getList((String) newValue));
listsTableModel.resync();
}
}
@ -147,7 +155,7 @@ public class KeywordSearchListsViewerPanel extends AbstractKeywordSearchPerforme
}
};
if(IngestManager.getDefault().isFileIngestRunning())
if(IngestManager.getDefault().isServiceRunning(KeywordSearchIngestService.getDefault()))
initIngest(0);
else
initIngest(1);
@ -164,6 +172,9 @@ public class KeywordSearchListsViewerPanel extends AbstractKeywordSearchPerforme
else if(changed.equals(IngestManager.SERVICE_STARTED_EVT) &&
((String) oldValue).equals(KeywordSearchIngestService.MODULE_NAME))
initIngest(0);
else if(changed.equals(IngestManager.SERVICE_STOPPED_EVT) &&
((String) oldValue).equals(KeywordSearchIngestService.MODULE_NAME))
initIngest(1);
}
});
@ -174,8 +185,6 @@ public class KeywordSearchListsViewerPanel extends AbstractKeywordSearchPerforme
* @param running
* case 0: ingest running
* case 1: ingest not running
* case 2: ingest completed
* case 3: ingest started
*/
private void initIngest(int running) {
ActionListener[] current = searchAddButton.getActionListeners();
@ -189,12 +198,14 @@ public class KeywordSearchListsViewerPanel extends AbstractKeywordSearchPerforme
searchAddButton.setText("Add to Ingest");
searchAddButton.addActionListener(ingestListener);
listsTableModel.resync();
ingestLabel.setVisible(true);
break;
case 1:
ingestRunning = false;
searchAddButton.setText("Search");
searchAddButton.addActionListener(searchListener);
listsTableModel.resync();
ingestLabel.setVisible(false);
break;
}
}
@ -215,10 +226,8 @@ public class KeywordSearchListsViewerPanel extends AbstractKeywordSearchPerforme
keywordsTable = new javax.swing.JTable();
manageListsButton = new javax.swing.JButton();
searchAddButton = new javax.swing.JButton();
ingestLabel = new javax.swing.JLabel();
jSplitPane1.setPreferredSize(new java.awt.Dimension(406, 404));
leftPane.setBackground(new java.awt.Color(204, 204, 204));
leftPane.setMinimumSize(new java.awt.Dimension(150, 23));
listsTable.setBackground(new java.awt.Color(240, 240, 240));
@ -230,8 +239,6 @@ public class KeywordSearchListsViewerPanel extends AbstractKeywordSearchPerforme
jSplitPane1.setLeftComponent(leftPane);
rightPane.setBackground(new java.awt.Color(204, 204, 204));
keywordsTable.setBackground(new java.awt.Color(240, 240, 240));
keywordsTable.setModel(keywordsTableModel);
keywordsTable.setShowHorizontalLines(false);
@ -249,6 +256,9 @@ public class KeywordSearchListsViewerPanel extends AbstractKeywordSearchPerforme
searchAddButton.setText(org.openide.util.NbBundle.getMessage(KeywordSearchListsViewerPanel.class, "KeywordSearchListsViewerPanel.searchAddButton.text")); // NOI18N
ingestLabel.setFont(new java.awt.Font("Tahoma", 0, 10)); // NOI18N
ingestLabel.setText(org.openide.util.NbBundle.getMessage(KeywordSearchListsViewerPanel.class, "KeywordSearchListsViewerPanel.ingestLabel.text")); // NOI18N
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
this.setLayout(layout);
layout.setHorizontalGroup(
@ -260,12 +270,18 @@ public class KeywordSearchListsViewerPanel extends AbstractKeywordSearchPerforme
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 220, Short.MAX_VALUE)
.addComponent(manageListsButton)
.addContainerGap())
.addGroup(layout.createSequentialGroup()
.addContainerGap()
.addComponent(ingestLabel)
.addContainerGap(51, Short.MAX_VALUE))
);
layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addComponent(jSplitPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 268, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 8, Short.MAX_VALUE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 7, Short.MAX_VALUE)
.addComponent(ingestLabel)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(manageListsButton)
.addComponent(searchAddButton))
@ -278,6 +294,7 @@ public class KeywordSearchListsViewerPanel extends AbstractKeywordSearchPerforme
}//GEN-LAST:event_manageListsButtonActionPerformed
// Variables declaration - do not modify//GEN-BEGIN:variables
private javax.swing.JLabel ingestLabel;
private javax.swing.JSplitPane jSplitPane1;
private javax.swing.JTable keywordsTable;
private javax.swing.JScrollPane leftPane;
@ -302,7 +319,9 @@ public class KeywordSearchListsViewerPanel extends AbstractKeywordSearchPerforme
}
private void addToIngestAction(ActionEvent e) {
//TODO: something
for(KeywordSearchList list : listsTableModel.getSelectedListsL()){
KeywordSearchIngestService.getDefault().addToKeywordLists(list.getName());
}
}
@Override
@ -393,7 +412,8 @@ public class KeywordSearchListsViewerPanel extends AbstractKeywordSearchPerforme
@Override
public boolean isCellEditable(int rowIndex, int columnIndex) {
return columnIndex == 0;
List<String> locked = KeywordSearchIngestService.getDefault().getKeywordLists();
return (columnIndex == 0 && (!ingestRunning || !locked.contains((String)getValueAt(rowIndex, 1))));
}
@Override
@ -407,7 +427,7 @@ public class KeywordSearchListsViewerPanel extends AbstractKeywordSearchPerforme
if(entry != null) {
entry.selected = (Boolean) aValue;
if(ingestRunning) {
updateUseForIngest(getListAt(rowIndex), (Boolean) aValue);
//updateUseForIngest(getListAt(rowIndex), (Boolean) aValue);
}
}
@ -420,6 +440,7 @@ public class KeywordSearchListsViewerPanel extends AbstractKeywordSearchPerforme
}
private void updateUseForIngest(KeywordSearchList list, boolean selected) {
// This causes an event to be fired which resyncs the list and makes user lose selection
listsHandle.addList(list.getName(), list.getKeywords(), selected);
}
@ -464,29 +485,6 @@ public class KeywordSearchListsViewerPanel extends AbstractKeywordSearchPerforme
fireTableDataChanged();
}
//resync single model entry from handle, then update table
void resync(String listName) {
ListTableEntry found = null;
for (ListTableEntry e : listData) {
if (e.name.equals(listName)) {
found = e;
break;
}
}
if (found != null) {
listData.remove(found);
addList(listsHandle.getList(listName));
}
fireTableDataChanged();
}
//add list to the model
private void addList(KeywordSearchList list) {
if (!listExists(list.getName())) {
listData.add(new ListTableEntry(list, ingestRunning));
}
}
//add lists to the model
private void addLists(List<KeywordSearchList> lists) {
for (KeywordSearchList list : lists) {
@ -614,5 +612,27 @@ public class KeywordSearchListsViewerPanel extends AbstractKeywordSearchPerforme
}
}
private static class CheckBoxRenderer extends JCheckBox implements TableCellRenderer{
private static final Border noFocusBorder = new EmptyBorder(3, 6, 3, 3);
@Override
public Component getTableCellRendererComponent(
JTable table, Object value,
boolean isSelected, boolean hasFocus,
int row, int column) {
setBorder(noFocusBorder);
if (column == 0) {
String name = (String) table.getModel().getValueAt(row, 1);
Boolean selected = (Boolean) table.getModel().getValueAt(row, 0);
List<String> locked = KeywordSearchIngestService.getDefault().getKeywordLists();
setEnabled(!locked.contains(name));
setSelected(selected);
}
return this;
}
}
}