re-work child factories to have better model inheritance. Need to update package locations, fix sqlWhereClause

This commit is contained in:
Andrew Ziehl 2018-03-29 17:56:55 -07:00 committed by Brian Sweeney
parent 4a7fbdae59
commit a89c4f6538
8 changed files with 114 additions and 86 deletions

View File

@ -20,7 +20,9 @@
package org.sleuthkit.autopsy.commonfilesearch;
import java.sql.SQLException;
import java.util.List;
import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException;
import org.sleuthkit.datamodel.AbstractFile;
import org.sleuthkit.datamodel.TskCoreException;
/**
@ -28,8 +30,8 @@ import org.sleuthkit.datamodel.TskCoreException;
*/
public class AllCommonFiles extends CommonFilesMetaData {
AllCommonFiles() throws TskCoreException, SQLException, NoCurrentCaseException{
super();
AllCommonFiles(String md5, List<AbstractFile> childNodes) throws TskCoreException, SQLException, NoCurrentCaseException{
super(md5, childNodes);
}
private final String whereClause = "md5 in (select md5 from tsk_files where (known != 1 OR known IS NULL) GROUP BY md5 HAVING COUNT(*) > 1) order by md5";

View File

@ -32,51 +32,30 @@ import org.sleuthkit.autopsy.datamodel.CommonFileParentNode;
/**
* Makes nodes for common files search results.
*/
final class CommonFilesChildren extends ChildFactory<String> {
public final class CommonFilesChildren extends ChildFactory<CommonFilesMetaData> {
private CommonFilesMetaData metaData;
private List<CommonFilesMetaData> metaDataList;
CommonFilesChildren(CommonFilesMetaData theMetaData) {
public CommonFilesChildren(List<CommonFilesMetaData> theMetaDataList) {
super();
this.metaData = theMetaData;
this.metaDataList = theMetaDataList;
}
protected void removeNotify() {
metaData = null;
metaDataList = null;
}
@Override
protected Node createNodeForKey(String md5) {
protected Node createNodeForKey(CommonFilesMetaData metaData) {
List<AbstractFile> children = this.metaData.getChildrenForFile(md5);
int instanceCount = children.size();
String dataSources = selectDataSources(children);
return new CommonFileParentNode(Children.create(new CommonFilesDescendants(children, this.metaData.getDataSourceIdToNameMap()), true), md5, instanceCount, dataSources);
return new CommonFileParentNode(metaData);
}
@Override
protected boolean createKeys(List<String> toPopulate) {
final Map<String, List<org.sleuthkit.datamodel.AbstractFile>> filesMap = this.metaData.getFilesMap();
Collection<String> files = filesMap.keySet();
toPopulate.addAll(files);
protected boolean createKeys(List<CommonFilesMetaData> toPopulate) {
toPopulate.addAll(metaDataList);
return true;
}
private String selectDataSources(List<AbstractFile> children) {
Map<Long, String> dataSources = this.metaData.getDataSourceIdToNameMap();
Set<String> dataSourceStrings = new HashSet<>();
for (AbstractFile child : children) {
String dataSource = dataSources.get(child.getDataSourceObjectId());
dataSourceStrings.add(dataSource);
}
return String.join(", ", dataSourceStrings);
}
}

View File

@ -34,7 +34,7 @@ public class CommonFilesDescendants extends ChildFactory<AbstractFile> {
private final List<AbstractFile> descendants;
private Map<Long, String> dataSourceMap;
CommonFilesDescendants(List<AbstractFile> descendants, Map<Long, String> dataSourceMap){
public CommonFilesDescendants(List<AbstractFile> descendants, Map<Long, String> dataSourceMap){
super();
this.descendants = descendants;
this.dataSourceMap = dataSourceMap;

View File

@ -24,8 +24,10 @@ import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.sleuthkit.autopsy.casemodule.Case;
import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException;
import org.sleuthkit.datamodel.AbstractFile;
@ -36,15 +38,17 @@ import org.sleuthkit.datamodel.TskCoreException;
* Utility and wrapper around data required for Common Files Search results.
* Subclass this to implement different selections of files from the case.
*/
abstract class CommonFilesMetaData {
public abstract class CommonFilesMetaData {
private final Map<String, List<AbstractFile>> parentNodes;
private final String parentMd5;
private final List<AbstractFile> children;
private final Map<Long, String> dataSourceIdToNameMap;
private final SleuthkitCase sleuthkitCase;
CommonFilesMetaData() throws TskCoreException, SQLException, NoCurrentCaseException {
parentNodes = new HashMap<>();
CommonFilesMetaData(String md5, List<AbstractFile> childNodes) throws TskCoreException, SQLException, NoCurrentCaseException {
parentMd5 = md5;
children = childNodes;
dataSourceIdToNameMap = new HashMap<>();
this.sleuthkitCase = Case.getOpenCase().getSleuthkitCase();
@ -66,40 +70,31 @@ abstract class CommonFilesMetaData {
}
}
}
Map<String, List<AbstractFile>> getFilesMap() {
return Collections.unmodifiableMap(this.parentNodes);
public String getMd5() {
return parentMd5;
}
public List<AbstractFile> getChildren() {
return Collections.unmodifiableList(this.children);
}
Map<Long, String> getDataSourceIdToNameMap() {
public Map<Long, String> getDataSourceIdToNameMap() {
return Collections.unmodifiableMap(dataSourceIdToNameMap);
}
/**
* Sorts files in selection into a parent/child hierarchy where actual files
* are nested beneath a parent node which represents the common match.
*
* @return returns a reference to itself for ease of use.
* @throws TskCoreException
*/
CommonFilesMetaData collateFiles() throws TskCoreException {
public String selectDataSources() {
List<AbstractFile> files = this.sleuthkitCase.findAllFilesWhere(getSqlWhereClause());
Map<Long, String> dataSources = this.getDataSourceIdToNameMap();
for (AbstractFile file : files) {
Set<String> dataSourceStrings = new HashSet<>();
String currentMd5 = file.getMd5Hash();
if(parentNodes.containsKey(currentMd5)){
parentNodes.get(currentMd5).add(file);
} else {
List<AbstractFile> children = new ArrayList<>();
children.add(file);
parentNodes.put(currentMd5, children);
}
for (AbstractFile child : getChildren()) {
String dataSource = dataSources.get(child.getDataSourceObjectId());
dataSourceStrings.add(dataSource);
}
return this;
return String.join(", ", dataSourceStrings);
}
/**
@ -112,12 +107,4 @@ abstract class CommonFilesMetaData {
*/
protected abstract String getSqlWhereClause();
/**
*
* @param t
* @return
*/
List<AbstractFile> getChildrenForFile(String md5) {
return this.parentNodes.get(md5);
}
}

View File

@ -21,7 +21,9 @@ package org.sleuthkit.autopsy.commonfilesearch;
import java.awt.event.ActionListener;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.concurrent.ExecutionException;
@ -30,6 +32,7 @@ import javax.swing.AbstractListModel;
import javax.swing.ComboBoxModel;
import javax.swing.SwingWorker;
import javax.swing.event.ListDataListener;
import org.openide.util.Exceptions;
import org.openide.util.NbBundle;
import org.sleuthkit.autopsy.casemodule.Case;
import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException;
@ -39,6 +42,7 @@ import org.sleuthkit.autopsy.coreutils.Logger;
import org.sleuthkit.autopsy.coreutils.MessageNotifyUtil;
import org.sleuthkit.autopsy.directorytree.DataResultFilterNode;
import org.sleuthkit.autopsy.directorytree.DirectoryTreeTopComponent;
import org.sleuthkit.datamodel.AbstractFile;
import org.sleuthkit.datamodel.SleuthkitCase;
import org.sleuthkit.datamodel.SleuthkitCase.CaseDbQuery;
import org.sleuthkit.datamodel.TskCoreException;
@ -114,6 +118,47 @@ public final class CommonFilesPanel extends javax.swing.JPanel {
void addListenerToAll(ActionListener l) { //TODO double click the button
this.searchButton.addActionListener(l);
}
/**
* Sorts files in selection into a parent/child hierarchy where actual files
* are nested beneath a parent node which represents the common match.
*
* @return returns a reference to itself for ease of use.
* @throws TskCoreException
*/
private List<CommonFilesMetaData> collateFiles() throws TskCoreException, SQLException {
SleuthkitCase sleuthkitCase;
List<CommonFilesMetaData> metaDataModels = new ArrayList<>();
try {
sleuthkitCase = Case.getOpenCase().getSleuthkitCase();
String whereClause = "md5 in (select md5 from tsk_files where (known != 1 OR known IS NULL) GROUP BY md5 HAVING COUNT(*) > 1) order by md5";
List<AbstractFile> files = sleuthkitCase.findAllFilesWhere(whereClause);
Map<String, List<AbstractFile>> parentNodes = new HashMap<>();
for (AbstractFile file : files) {
String currentMd5 = file.getMd5Hash();
if (parentNodes.containsKey(currentMd5)) {
parentNodes.get(currentMd5).add(file);
} else {
List<AbstractFile> children = new ArrayList<>();
children.add(file);
parentNodes.put(currentMd5, children);
}
}
for (String key : parentNodes.keySet()) {
metaDataModels.add(new AllCommonFiles(key, parentNodes.get(key)));
}
} catch (NoCurrentCaseException ex) {
Exceptions.printStackTrace(ex);
}
return metaDataModels;
}
@NbBundle.Messages({
"CommonFilesPanel.search.results.title=Common Files",
@ -128,11 +173,11 @@ public final class CommonFilesPanel extends javax.swing.JPanel {
String title = Bundle.CommonFilesPanel_search_results_title();
String pathText = Bundle.CommonFilesPanel_search_results_pathText();
new SwingWorker<CommonFilesMetaData, Void>() {
new SwingWorker<List<CommonFilesMetaData>, Void>() {
@Override
@SuppressWarnings("FinallyDiscardsException")
protected CommonFilesMetaData doInBackground() throws TskCoreException, NoCurrentCaseException, SQLException {
protected List<CommonFilesMetaData> doInBackground() throws TskCoreException, NoCurrentCaseException, SQLException {
//TODO cleanup - encapsulate business logic
if(singleDataSource) {
@ -143,9 +188,11 @@ public final class CommonFilesPanel extends javax.swing.JPanel {
break;
}
}
return new SingleDataSourceCommonFiles(selectedObjId).collateFiles();
//return new SingleDataSourceCommonFiles(selectedObjId).collateFiles();
return collateFiles();
} else {
return new AllCommonFiles().collateFiles();
//return new AllCommonFiles().collateFiles();
return collateFiles();
}
}
@ -154,7 +201,7 @@ public final class CommonFilesPanel extends javax.swing.JPanel {
try {
super.done();
CommonFilesMetaData metadata = get();
List<CommonFilesMetaData> metadata = get();
CommonFilesSearchNode commonFilesNode = new CommonFilesSearchNode(metadata);
@ -165,8 +212,11 @@ public final class CommonFilesPanel extends javax.swing.JPanel {
DataResultTopComponent component = DataResultTopComponent.createInstance(title);
//component.enableTreeMode();
DataResultTopComponent.initInstance(pathText, tableFilterWithDescendantsNode, metadata.getFilesMap().size(), component);
int totalNodes = 0;
for(CommonFilesMetaData meta : metadata) {
totalNodes += meta.getChildren().size();
}
DataResultTopComponent.initInstance(pathText, tableFilterWithDescendantsNode, totalNodes, component);
} catch (InterruptedException ex) {
LOGGER.log(Level.SEVERE, "Interrupted while loading Common Files", ex);

View File

@ -18,6 +18,7 @@
*/
package org.sleuthkit.autopsy.commonfilesearch;
import java.util.List;
import org.openide.nodes.Children;
import org.openide.util.NbBundle;
import org.openide.util.lookup.Lookups;
@ -30,8 +31,8 @@ import org.sleuthkit.autopsy.datamodel.DisplayableItemNodeVisitor;
*/
final public class CommonFilesSearchNode extends DisplayableItemNode {
CommonFilesSearchNode(CommonFilesMetaData metaData) {
super(Children.create(new CommonFilesChildren(metaData), true), Lookups.singleton(metaData));
CommonFilesSearchNode(List<CommonFilesMetaData> metaDataList) {
super(Children.create(new CommonFilesChildren(metaDataList), true), Lookups.singleton(metaDataList));
}
@NbBundle.Messages({

View File

@ -20,7 +20,9 @@
package org.sleuthkit.autopsy.commonfilesearch;
import java.sql.SQLException;
import java.util.List;
import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException;
import org.sleuthkit.datamodel.AbstractFile;
import org.sleuthkit.datamodel.TskCoreException;
/**
@ -30,8 +32,8 @@ public class SingleDataSourceCommonFiles extends CommonFilesMetaData {
private final String whereClause;
SingleDataSourceCommonFiles(long dataSourceId) throws TskCoreException, SQLException, NoCurrentCaseException{
super();
SingleDataSourceCommonFiles(String md5, List<AbstractFile> childNodes, long dataSourceId) throws TskCoreException, SQLException, NoCurrentCaseException{
super(md5, childNodes);
Object[] args = new String[] {Long.toString(dataSourceId), Long.toString(dataSourceId)};
this.whereClause = String.format(

View File

@ -24,6 +24,10 @@ import java.util.Map;
import org.openide.nodes.Children;
import org.openide.nodes.Sheet;
import org.openide.util.NbBundle;
import org.openide.util.lookup.Lookups;
import org.sleuthkit.autopsy.commonfilesearch.CommonFilesChildren;
import org.sleuthkit.autopsy.commonfilesearch.CommonFilesDescendants;
import org.sleuthkit.autopsy.commonfilesearch.CommonFilesMetaData;
/**
* Represents a common files match - two or more files which appear to be the
@ -35,11 +39,14 @@ public class CommonFileParentNode extends DisplayableItemNode {
private final int commonFileCount;
private final String dataSources;
public CommonFileParentNode(Children children, String md5Hash, int commonFileCount, String dataSources) {
super(children);
this.commonFileCount = commonFileCount;
this.dataSources = dataSources;
this.md5Hash = md5Hash;
public CommonFileParentNode(CommonFilesMetaData metaData) {
super(Children.create(
new CommonFilesDescendants(metaData.getChildren(),
metaData.getDataSourceIdToNameMap()), true),
Lookups.singleton(metaData));
this.commonFileCount = metaData.getChildren().size();
this.dataSources = metaData.selectDataSources();
this.md5Hash = metaData.getMd5();
this.setDisplayName(md5Hash);
}