comments and access modifiers

# Conflicts:
#	Core/src/org/sleuthkit/autopsy/commonfilesearch/AllDataSources.java
#	Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesPanel.java
#	Core/src/org/sleuthkit/autopsy/commonfilesearch/SingleDataSource.java
This commit is contained in:
Brian Sweeney 2018-04-17 14:32:32 -06:00
parent 0ffd19bea1
commit 538bd3c2af
10 changed files with 97 additions and 57 deletions

View File

@ -24,7 +24,7 @@ import java.util.Map;
/** /**
* Provides logic for selecting common files from all data sources. * Provides logic for selecting common files from all data sources.
*/ */
class AllDataSources extends CommonFilesMetaDataBuilder { final class AllDataSources extends CommonFilesMetaDataBuilder {
private static final String WHERE_CLAUSE = "md5 in (select md5 from tsk_files where (known != 1 OR known IS NULL)%s GROUP BY md5 HAVING COUNT(*) > 1) order by md5"; private static final String WHERE_CLAUSE = "md5 in (select md5 from tsk_files where (known != 1 OR known IS NULL)%s GROUP BY md5 HAVING COUNT(*) > 1) order by md5";

View File

@ -26,27 +26,35 @@ import java.util.Map;
* Utility and wrapper model around data required for Common Files Search results. * Utility and wrapper model around data required for Common Files Search results.
* Subclass this to implement different selections of files from the case. * Subclass this to implement different selections of files from the case.
*/ */
public class CommonFilesMetaData { final class CommonFilesMetaData {
private final Map<String, Md5MetaData> metadata; private final Map<String, Md5MetaData> metadata;
private final Map<Long, String> dataSourceIdToNameMap; private final Map<Long, String> dataSourceIdToNameMap;
/**
* Create meta dat object which can be handed off to the node factories
* @param metadata map of md5 to parent-level node meta data
* @param dataSourcesMap map of obj_id to data source name
*/
CommonFilesMetaData(Map<String, Md5MetaData> metadata, Map<Long,String> dataSourcesMap) { CommonFilesMetaData(Map<String, Md5MetaData> metadata, Map<Long,String> dataSourcesMap) {
this.metadata = metadata; this.metadata = metadata;
this.dataSourceIdToNameMap = dataSourcesMap; this.dataSourceIdToNameMap = dataSourcesMap;
} }
public Md5MetaData getMetaDataForMd5(String md5){ /**
* Find the meta data for the given md5.
*
* This is a convenience method - you can also iterate over <code>getMetaData()</code>.
* @param md5 key
* @return
*/
Md5MetaData getMetaDataForMd5(String md5){
return this.metadata.get(md5); return this.metadata.get(md5);
} }
public Map<String, Md5MetaData> getMataData(){ Map<String, Md5MetaData> getMataData(){
return Collections.unmodifiableMap(this.metadata); return Collections.unmodifiableMap(this.metadata);
} }
public Map<Long, String> getDataSourceIdToNameMap() {
return Collections.unmodifiableMap(this.dataSourceIdToNameMap);
}
int size() { int size() {
int count = 0; int count = 0;

View File

@ -41,8 +41,9 @@ import org.sleuthkit.datamodel.TskCoreException;
/** /**
* *
* Generates a List<CommonFilesMetaData> when collateFiles() is called, which * Generates a <code>List<CommonFilesMetaData></code> when
* organizes AbstractFiles by md5 to prepare to display in viewer. * <code>findCommonFiles()</code> is called, which
* organizes files by md5 to prepare to display in viewer.
* *
* This entire thing runs on a background thread where exceptions are handled. * This entire thing runs on a background thread where exceptions are handled.
*/ */
@ -102,6 +103,14 @@ abstract class CommonFilesMetaDataBuilder {
filterByDoc = filterByDocMimeType; filterByDoc = filterByDocMimeType;
} }
/**
* Use this as a prefix when building the SQL select statement.
*
* <ul>
* <li>You only have to specify the WHERE clause if you use this.</li>
* <li>If you do not use this string, you must use at least the columns selected below, in that order.</li>
* </ul>
*/
protected static String SELECT_PREFIX = "SELECT obj_id, md5, data_source_obj_id from tsk_files where"; protected static String SELECT_PREFIX = "SELECT obj_id, md5, data_source_obj_id from tsk_files where";
/** /**
@ -115,7 +124,16 @@ abstract class CommonFilesMetaDataBuilder {
*/ */
protected abstract String buildSqlSelectStatement(); protected abstract String buildSqlSelectStatement();
public Map<String, Md5MetaData> findCommonFiles() throws TskCoreException, NoCurrentCaseException, SQLException { /**
* Generate a meta data object which encapsulates everything need to
* add the tree table tab to the top component.
* @return a data object with all of the matched files in a hierarchical
* format
* @throws TskCoreException
* @throws NoCurrentCaseException
* @throws SQLException
*/
public CommonFilesMetaData findCommonFiles() throws TskCoreException, NoCurrentCaseException, SQLException {
Map<String, Md5MetaData> commonFiles = new HashMap<>(); Map<String, Md5MetaData> commonFiles = new HashMap<>();
@ -131,17 +149,18 @@ abstract class CommonFilesMetaDataBuilder {
String dataSource = this.dataSourceIdToNameMap.get(dataSourceId); String dataSource = this.dataSourceIdToNameMap.get(dataSourceId);
if(commonFiles.containsKey(md5)){ if(commonFiles.containsKey(md5)){
commonFiles.get(md5).getMetaData().add(new FileInstanceMetaData(objectId, dataSource, dataSourceId)); final Md5MetaData md5MetaData = commonFiles.get(md5);
md5MetaData.addFileInstanceMetaData(new FileInstanceMetaData(objectId, dataSource));
} else { } else {
List<FileInstanceMetaData> fileInstances = new ArrayList<>(); final List<FileInstanceMetaData> fileInstances = new ArrayList<>();
fileInstances.add(new FileInstanceMetaData(objectId, dataSource, dataSourceId)); fileInstances.add(new FileInstanceMetaData(objectId, dataSource));
Md5MetaData md5s = new Md5MetaData(md5, fileInstances); Md5MetaData md5MetaData = new Md5MetaData(md5, fileInstances);
commonFiles.put(md5, md5s); commonFiles.put(md5, md5MetaData);
} }
} }
} }
return commonFiles; return new CommonFilesMetaData(commonFiles, this.dataSourceIdToNameMap);
} }
String determineMimeTypeFilter() { String determineMimeTypeFilter() {

View File

@ -263,8 +263,8 @@ public final class CommonFilesPanel extends javax.swing.JPanel {
setTitleForSingleSource(dataSourceId); setTitleForSingleSource(dataSourceId);
} }
CommonFilesMetaData metaData = new CommonFilesMetaData(builder.findCommonFiles(), CommonFilesPanel.this.dataSourceMap); CommonFilesMetaData metaData = builder.findCommonFiles();
return metaData; return metaData;
} }

View File

@ -20,29 +20,36 @@
package org.sleuthkit.autopsy.commonfilesearch; package org.sleuthkit.autopsy.commonfilesearch;
/** /**
* Encalsulates data required to instantiate a <code>FileInstanceNode</code>. * Encapsulates data required to instantiate a <code>FileInstanceNode</code>.
*/ */
public class FileInstanceMetaData { final public class FileInstanceMetaData {
private Long objectId; private Long objectId;
private String dataSourceName; private String dataSourceName;
private Long dataSourceId;
public FileInstanceMetaData (Long objectId, String dataSourceName, Long dataSourceId){ /**
* Create meta data required to find an abstract file and build a FileInstanceNode.
* @param objectId id of abstract file to find
* @param dataSourceName name of datasource where the object is found
*/
FileInstanceMetaData (Long objectId, String dataSourceName){
this.objectId = objectId; this.objectId = objectId;
this.dataSourceName = dataSourceName; this.dataSourceName = dataSourceName;
this.dataSourceId = dataSourceId;
} }
/**
* obj_id for the file represented by this object
* @return
*/
public Long getObjectId(){ public Long getObjectId(){
return this.objectId; return this.objectId;
} }
/**
* Name of datasource where this instance was found.
* @return
*/
public String getDataSourceName(){ public String getDataSourceName(){
return this.dataSourceName; return this.dataSourceName;
}
public Long getDataSourceId(){
return this.dataSourceId;
} }
} }

View File

@ -19,19 +19,21 @@
*/ */
package org.sleuthkit.autopsy.commonfilesearch; package org.sleuthkit.autopsy.commonfilesearch;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet; import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Set; import java.util.Set;
/** /**
* Encaspsulates data required to instantiate an <code>Md5Node</code>. * Encapsulates data required to instantiate an <code>Md5Node</code>.
*/ */
public class Md5MetaData { final public class Md5MetaData {
private String md5; private String md5;
private List<FileInstanceMetaData> fileInstances; private List<FileInstanceMetaData> fileInstances;
public Md5MetaData(String md5, List<FileInstanceMetaData> fileInstances){ Md5MetaData(String md5, List<FileInstanceMetaData> fileInstances){
this.md5 = md5; this.md5 = md5;
this.fileInstances = fileInstances; this.fileInstances = fileInstances;
} }
@ -40,8 +42,12 @@ public class Md5MetaData {
return this.md5; return this.md5;
} }
public List<FileInstanceMetaData> getMetaData(){ void addFileInstanceMetaData(FileInstanceMetaData metadata){
return this.fileInstances; this.fileInstances.add(metadata);
}
public Collection<FileInstanceMetaData> getMetaData(){
return Collections.unmodifiableCollection(this.fileInstances);
} }
public int size(){ public int size(){

View File

@ -26,12 +26,18 @@ import java.util.Set;
/** /**
* Provides logic for selecting common files from a single data source. * Provides logic for selecting common files from a single data source.
*/ */
class SingleDataSource extends CommonFilesMetaDataBuilder { final class SingleDataSource extends CommonFilesMetaDataBuilder {
private static final String WHERE_CLAUSE = "%s md5 in (select md5 from tsk_files where md5 in (select md5 from tsk_files where (known != 1 OR known IS NULL) and data_source_obj_id=%s%s) GROUP BY md5 HAVING COUNT(*) > 1) order by md5"; private static final String WHERE_CLAUSE = "%s md5 in (select md5 from tsk_files where md5 in (select md5 from tsk_files where (known != 1 OR known IS NULL) and data_source_obj_id=%s%s) GROUP BY md5 HAVING COUNT(*) > 1) order by md5";
private final Long selectedDataSourceId; private final Long selectedDataSourceId;
public SingleDataSource(Long dataSourceId, Map<Long, String> dataSourceIdMap, boolean filterByMediaMimeType, boolean filterByDocMimeType) { /**
* Implements the algorithm for getting common files that appear at least
* once in the given data source.
* @param dataSourceId data source id for which common files must appear at least once
* @param dataSourceIdMap map of obj_id to data source name
*/
public SingleDataSource(Long dataSourceId, Map<Long, String> dataSourceIdMap, boolean filterByMediaMimeType, boolean filterByDocMimeType) {
super(dataSourceIdMap, filterByMediaMimeType, filterByDocMimeType); super(dataSourceIdMap, filterByMediaMimeType, filterByDocMimeType);
this.selectedDataSourceId = dataSourceId; this.selectedDataSourceId = dataSourceId;
} }

View File

@ -22,6 +22,7 @@ package org.sleuthkit.autopsy.datamodel;
import java.util.LinkedHashMap; import java.util.LinkedHashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.logging.Level;
import org.openide.nodes.ChildFactory; import org.openide.nodes.ChildFactory;
import org.openide.nodes.Children; import org.openide.nodes.Children;
import org.openide.nodes.Node; import org.openide.nodes.Node;
@ -31,8 +32,10 @@ import org.openide.util.NbBundle;
import org.openide.util.lookup.Lookups; import org.openide.util.lookup.Lookups;
import org.sleuthkit.autopsy.casemodule.Case; import org.sleuthkit.autopsy.casemodule.Case;
import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException; import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException;
import org.sleuthkit.autopsy.commonfilesearch.CommonFilesPanel;
import org.sleuthkit.autopsy.commonfilesearch.FileInstanceMetaData; import org.sleuthkit.autopsy.commonfilesearch.FileInstanceMetaData;
import org.sleuthkit.autopsy.commonfilesearch.Md5MetaData; import org.sleuthkit.autopsy.commonfilesearch.Md5MetaData;
import org.sleuthkit.autopsy.coreutils.Logger;
import org.sleuthkit.datamodel.AbstractFile; import org.sleuthkit.datamodel.AbstractFile;
import org.sleuthkit.datamodel.SleuthkitCase; import org.sleuthkit.datamodel.SleuthkitCase;
import org.sleuthkit.datamodel.TskCoreException; import org.sleuthkit.datamodel.TskCoreException;
@ -40,10 +43,13 @@ import org.sleuthkit.datamodel.TskCoreException;
/** /**
* Represents a common files match - two or more files which appear to be the * Represents a common files match - two or more files which appear to be the
* same file and appear as children of this node. This node will simply contain * same file and appear as children of this node. This node will simply contain
* the MD5 of the matched files, * the MD5 of the matched files, the data sources those files were found within,
* and a count of the instances represented by the md5.
*/ */
public class Md5Node extends DisplayableItemNode { public class Md5Node extends DisplayableItemNode {
private static final Logger LOGGER = Logger.getLogger(CommonFilesPanel.class.getName());
private final String md5Hash; private final String md5Hash;
private final int commonFileCount; private final int commonFileCount;
private final String dataSources; private final String dataSources;
@ -108,7 +114,7 @@ public class Md5Node extends DisplayableItemNode {
@Override @Override
public <T> T accept(DisplayableItemNodeVisitor<T> visitor) { public <T> T accept(DisplayableItemNodeVisitor<T> visitor) {
return visitor.visit(this); //TODO need to work on this return visitor.visit(this);
} }
@Override @Override
@ -141,31 +147,19 @@ public class Md5Node extends DisplayableItemNode {
return new FileInstanceNode(abstractFile, file.getDataSourceName()); return new FileInstanceNode(abstractFile, file.getDataSourceName());
} catch (NoCurrentCaseException ex) { } catch (NoCurrentCaseException ex) {
Exceptions.printStackTrace(ex); LOGGER.log(Level.SEVERE, String.format("Unable to create node for file with obj_id: %s.", new Object[]{file.getObjectId()}), ex);
//TODO log this
} catch (TskCoreException ex) { } catch (TskCoreException ex) {
Exceptions.printStackTrace(ex); LOGGER.log(Level.SEVERE, String.format("Unable to create node for file with obj_id: %s.", new Object[]{file.getObjectId()}), ex);
//TODO log this
} }
//TODO smells bad... //TODO smells bad...do something?
return null; return null;
} }
@Override @Override
protected boolean createKeys(List<FileInstanceMetaData> list) { protected boolean createKeys(List<FileInstanceMetaData> list) {
//TODO load children from db here
//TODO consider doing db work here???
list.addAll(this.descendants.getMetaData()); list.addAll(this.descendants.getMetaData());
return true; return true;
} }
// @Override
// protected Node createWaitNode() {
// //TODO could skip this...maybe???
// return new CommonFileChildNodeLoading(Children.LEAF);
// }
} }
@NbBundle.Messages({ @NbBundle.Messages({

View File

@ -1,5 +1,5 @@
#Updated by build script #Updated by build script
#Mon, 19 Mar 2018 11:17:11 -0700 #Tue, 17 Apr 2018 09:14:51 -0600
LBL_splash_window_title=Starting Autopsy LBL_splash_window_title=Starting Autopsy
SPLASH_HEIGHT=314 SPLASH_HEIGHT=314
SPLASH_WIDTH=538 SPLASH_WIDTH=538

View File

@ -1,4 +1,4 @@
#Updated by build script #Updated by build script
#Fri, 09 Mar 2018 13:03:41 -0700 #Tue, 17 Apr 2018 09:14:51 -0600
CTL_MainWindow_Title=Autopsy 4.6.0 CTL_MainWindow_Title=Autopsy 4.6.0
CTL_MainWindow_Title_No_Project=Autopsy 4.6.0 CTL_MainWindow_Title_No_Project=Autopsy 4.6.0