Merge branch '3788-intercase-correlation' of https://github.com/briangsweeney/autopsy into 3788-intercase-correlation

This commit is contained in:
Andrew Ziehl 2018-05-20 13:22:14 -07:00
commit a69a04ec26
10 changed files with 456 additions and 263 deletions

View File

@ -19,8 +19,22 @@
*/ */
package org.sleuthkit.autopsy.commonfilesearch; package org.sleuthkit.autopsy.commonfilesearch;
import java.sql.SQLException;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.logging.Level;
import java.util.stream.Collectors;
import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException;
import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationAttributeCommonInstance;
import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationCase;
import org.sleuthkit.autopsy.centralrepository.datamodel.EamDb;
import org.sleuthkit.autopsy.centralrepository.datamodel.EamDbException;
import static org.sleuthkit.autopsy.commonfilesearch.CommonFilesMetadataBuilder.SELECT_PREFIX; import static org.sleuthkit.autopsy.commonfilesearch.CommonFilesMetadataBuilder.SELECT_PREFIX;
import static org.sleuthkit.autopsy.timeline.datamodel.eventtype.ArtifactEventType.LOGGER;
import org.sleuthkit.datamodel.HashUtility;
import org.sleuthkit.datamodel.TskCoreException;
/** /**
@ -30,6 +44,8 @@ public class AllDataSourcesEamDbCommonFilesAlgorithm extends CommonFilesMetadat
private static final String WHERE_CLAUSE = "%s md5 in (select md5 from tsk_files where (known != 1 OR known IS NULL)%s GROUP BY md5) order by md5"; //NON-NLS private static final String WHERE_CLAUSE = "%s md5 in (select md5 from tsk_files where (known != 1 OR known IS NULL)%s GROUP BY md5) order by md5"; //NON-NLS
private EamDb dbManager;
/** /**
* Implements the algorithm for getting common files across all data * Implements the algorithm for getting common files across all data
* sources. * sources.
@ -38,9 +54,78 @@ public class AllDataSourcesEamDbCommonFilesAlgorithm extends CommonFilesMetadat
* @param filterByMediaMimeType match only on files whose mime types can be broadly categorized as media types * @param filterByMediaMimeType match only on files whose mime types can be broadly categorized as media types
* @param filterByDocMimeType match only on files whose mime types can be broadly categorized as document types * @param filterByDocMimeType match only on files whose mime types can be broadly categorized as document types
*/ */
AllDataSourcesEamDbCommonFilesAlgorithm(Map<Long, String> dataSourceIdMap, boolean filterByMediaMimeType, boolean filterByDocMimeType) { AllDataSourcesEamDbCommonFilesAlgorithm(Map<Long, String> dataSourceIdMap, boolean filterByMediaMimeType, boolean filterByDocMimeType) throws EamDbException {
super(dataSourceIdMap, filterByMediaMimeType, filterByDocMimeType); super(dataSourceIdMap, filterByMediaMimeType, filterByDocMimeType);
dbManager = EamDb.getInstance();
}
public CommonFilesMetadata findEamDbCommonFiles() throws TskCoreException, NoCurrentCaseException, SQLException, EamDbException {
return this.findEamDbCommonFiles(null);
}
public CommonFilesMetadata findEamDbCommonFiles(int correlationCaseId) throws TskCoreException, NoCurrentCaseException, SQLException, EamDbException, Exception {
CorrelationCase cCase = this.getCorrelationCaseFromId(correlationCaseId);
return this.findEamDbCommonFiles(cCase);
}
/**
* TODO Refactor, abstract shared code above, call this method via new AllDataSourcesEamDbCommonFilesAlgorithm Class
* @param correlationCase Optionally null, otherwise a case, or could be a CR case ID
* @return
* @throws TskCoreException
* @throws NoCurrentCaseException
* @throws SQLException
* @throws EamDbException
*/
public CommonFilesMetadata findEamDbCommonFiles(CorrelationCase correlationCase) throws TskCoreException, NoCurrentCaseException, SQLException, EamDbException {
CommonFilesMetadata metaData = this.findCommonFiles();
Map<String, Md5Metadata> commonFiles = metaData.getMetadata();
List<String> values = Arrays.asList((String[]) commonFiles.keySet().toArray());
Map<String, Md5Metadata> interCaseCommonFiles = metaData.getMetadata();
try {
Collection<CorrelationAttributeCommonInstance> artifactInstances = dbManager.getArtifactInstancesByCaseValues(correlationCase, values).stream()
.collect(Collectors.toList());
for (CorrelationAttributeCommonInstance instance : artifactInstances) {
//Long objectId = 1L; //TODO, need to retrieve ALL (even count < 2) AbstractFiles from this case to us for objectId for CR matches;
String md5 = instance.getValue();
String dataSource = instance.getCorrelationDataSource().getName();
if (md5 == null || HashUtility.isNoDataMd5(md5)) {
continue;
}
//Builds a 3rd list which contains instances which are in commonFiles map, uses current case objectId
if (commonFiles.containsKey(md5)) {
// TODO sloppy, but we don't *have* all the information for the rows in the CR, so what do we do?
Long objectId = commonFiles.get(md5).getMetadata().iterator().next().getObjectId();
if(interCaseCommonFiles.containsKey(md5)) {
//Add to intercase metaData
final Md5Metadata md5Metadata = interCaseCommonFiles.get(md5);
md5Metadata.addFileInstanceMetadata(new FileInstanceMetadata(objectId, dataSource));
} else {
// Create new intercase metadata
final Md5Metadata md5Metadata = commonFiles.get(md5);
md5Metadata.addFileInstanceMetadata(new FileInstanceMetadata(objectId, dataSource));
interCaseCommonFiles.put(md5, md5Metadata);
}
} else {
// TODO This should never happen. All current case files with potential matches are in comonFiles Map.
}
}
} catch (EamDbException ex) {
LOGGER.log(Level.SEVERE, "Error getting artifact instances from database.", ex); // NON-NLS
}
// Builds intercase-only matches metadata
return new CommonFilesMetadata(interCaseCommonFiles);
} }
@Override @Override
@ -55,4 +140,14 @@ public class AllDataSourcesEamDbCommonFilesAlgorithm extends CommonFilesMetadat
final String titleTemplate = Bundle.CommonFilesMetadataBuilder_buildTabTitle_titleEamDb(); final String titleTemplate = Bundle.CommonFilesMetadataBuilder_buildTabTitle_titleEamDb();
return String.format(titleTemplate, new Object[]{buildCategorySelectionString}); return String.format(titleTemplate, new Object[]{buildCategorySelectionString});
} }
private CorrelationCase getCorrelationCaseFromId(int correlationCaseId) throws EamDbException, Exception {
//TODO is there a better way???
for(CorrelationCase cCase : this.dbManager.getCases()){
if(cCase.getID() == correlationCaseId){
return cCase;
}
}
throw new Exception("Cannont locate case.");
}
} }

View File

@ -1,21 +1,23 @@
CommonFilesPanel.searchButton.text=Search CommonFilesPanel.searchButton.text=Search
CommonFilesPanel.cancelButton.text=Cancel CommonFilesPanel.cancelButton.text=Cancel
CommonFilesPanel.cancelButton.actionCommand=Cancel CommonFilesPanel.cancelButton.actionCommand=Cancel
CommonFilesPanel.selectedFileCategoriesButton.text=Match on the following file categories: CommonFilesPanel.selectedFileCategoriesButton.text=Only the selected file types:
CommonFilesPanel.selectedFileCategoriesButton.toolTipText=Select from the options below... CommonFilesPanel.selectedFileCategoriesButton.toolTipText=Select from the options below...
CommonFilesPanel.pictureVideoCheckbox.text=Pictures and Videos CommonFilesPanel.pictureVideoCheckbox.text=Pictures and Videos
CommonFilesPanel.documentsCheckbox.text=Documents CommonFilesPanel.documentsCheckbox.text=Documents
CommonFilesPanel.allFileCategoriesRadioButton.toolTipText=No filtering applied to results... CommonFilesPanel.allFileCategoriesRadioButton.toolTipText=No filtering applied to results...
CommonFilesPanel.allFileCategoriesRadioButton.text=Match on all file types CommonFilesPanel.allFileCategoriesRadioButton.text=All file types
CommonFilesPanel.text=Indicate which data sources to consider while searching for duplicates: CommonFilesPanel.text=Indicate which data sources to consider while searching for duplicates:
CommonFilesPanel.categoriesLabel.text=Indicate which file types to include in results: CommonFilesPanel.categoriesLabel.text=File Types To Include:
CommonFilesPanel.errorText.text=In order to search, you must select a file category. CommonFilesPanel.errorText.text=In order to search, you must select a file category.
CommonFilesPanel.commonFilesSearchLabel1.text=<html>Find Common Files.</html>
CommonFilesPanel.jRadioButton1.text=jRadioButton1 CommonFilesPanel.jRadioButton1.text=jRadioButton1
CommonFilesPanel.jRadioButton2.text=Correlate amongst external cases (compares files in current case with Central Repo) CommonFilesPanel.jRadioButton2.text=With previous cases in the Central Repository
CommonFilesPanel.intraCaseRadio.label=Correlate within current case only CommonFilesPanel.intraCaseRadio.label=Correlate within current case only
CommonFilesPanel.interCaseRadio.label=Correlate amongst all known cases (uses Central Repo) CommonFilesPanel.interCaseRadio.label=Correlate amongst all known cases (uses Central Repo)
IntraCasePanel.allDataSourcesRadioButton.text=Matches may be from any data source IntraCasePanel.allDataSourcesRadioButton.text=Matches may be from any data source
IntraCasePanel.withinDataSourceRadioButton.text=At least one match must appear in the data source selected below: IntraCasePanel.withinDataSourceRadioButton.text=At least one match must appear in the data source selected below:
InterCasePanel.anCentralRepoCaseRadio.text=Matches may be from any Central Repo case
InterCasePanel.specificCentralRepoCaseRadio.text=Matches must be from the following Central Repo case: InterCasePanel.specificCentralRepoCaseRadio.text=Matches must be from the following Central Repo case:
InterCasePanel.anyCentralRepoCaseRadio.text=Matches may be from any Central Repo case
CommonFilesPanel.commonFilesSearchLabel1.text=<html>Find common files to correlate data soures or cases.</html>
CommonFilesPanel.commonFilesSearchLabel2.text=Scope of Search
CommonFilesPanel.intraCaseRadio.text=Within current case

View File

@ -211,64 +211,6 @@ abstract class CommonFilesMetadataBuilder {
return new CommonFilesMetadata(commonFiles); return new CommonFilesMetadata(commonFiles);
} }
/**
* TODO Refactor, abstract shared code above, call this method via new AllDataSourcesEamDbCommonFilesAlgorithm Class
* @param correlationCase Optionally null, otherwise a case, or could be a CR case ID
* @return
* @throws TskCoreException
* @throws NoCurrentCaseException
* @throws SQLException
* @throws EamDbException
*/
public CommonFilesMetadata findEamDbCommonFiles(CorrelationCase correlationCase) throws TskCoreException, NoCurrentCaseException, SQLException, EamDbException {
CommonFilesMetadata metaData = this.findCommonFiles();
Map<String, Md5Metadata> commonFiles = metaData.getMetadata();
List<String> values = Arrays.asList((String[]) commonFiles.keySet().toArray());
Map<String, Md5Metadata> interCaseCommonFiles = metaData.getMetadata();
try {
EamDb dbManager = EamDb.getInstance();
Collection<CorrelationAttributeCommonInstance> artifactInstances = dbManager.getArtifactInstancesByCaseValues(correlationCase, values).stream()
.collect(Collectors.toList());
for (CorrelationAttributeCommonInstance instance : artifactInstances) {
//Long objectId = 1L; //TODO, need to retrieve ALL (even count < 2) AbstractFiles from this case to us for objectId for CR matches;
String md5 = instance.getValue();
String dataSource = instance.getCorrelationDataSource().getName();
if (md5 == null || HashUtility.isNoDataMd5(md5)) {
continue;
}
//Builds a 3rd list which contains instances which are in commonFiles map, uses current case objectId
if (commonFiles.containsKey(md5)) {
// TODO sloppy, but we don't *have* all the information for the rows in the CR, so what do we do?
Long objectId = commonFiles.get(md5).getMetadata().iterator().next().getObjectId();
if(interCaseCommonFiles.containsKey(md5)) {
//Add to intercase metaData
final Md5Metadata md5Metadata = interCaseCommonFiles.get(md5);
md5Metadata.addFileInstanceMetadata(new FileInstanceMetadata(objectId, dataSource));
} else {
// Create new intercase metadata
final Md5Metadata md5Metadata = commonFiles.get(md5);
md5Metadata.addFileInstanceMetadata(new FileInstanceMetadata(objectId, dataSource));
interCaseCommonFiles.put(md5, md5Metadata);
}
} else {
// TODO This should never happen. All current case files with potential matches are in comonFiles Map.
}
}
} catch (EamDbException ex) {
LOGGER.log(Level.SEVERE, "Error getting artifact instances from database.", ex); // NON-NLS
}
// Builds intercase-only matches metadata
return new CommonFilesMetadata(interCaseCommonFiles);
}
/** /**
* Should be used by subclasses, in their * Should be used by subclasses, in their
* <code>buildSqlSelectStatement()</code> function to create an SQL boolean * <code>buildSqlSelectStatement()</code> function to create an SQL boolean

View File

@ -23,39 +23,39 @@
<DimensionLayout dim="0"> <DimensionLayout dim="0">
<Group type="103" groupAlignment="0" attributes="0"> <Group type="103" groupAlignment="0" attributes="0">
<Group type="102" attributes="0"> <Group type="102" attributes="0">
<EmptySpace max="-2" attributes="0"/> <EmptySpace max="32767" attributes="0"/>
<Group type="103" groupAlignment="0" attributes="0"> <Group type="103" groupAlignment="0" attributes="0">
<Component id="commonFilesSearchLabel1" alignment="0" min="-2" max="-2" attributes="0"/> <Component id="commonFilesSearchLabel1" alignment="0" min="-2" max="-2" attributes="0"/>
<Component id="categoriesLabel" alignment="0" min="-2" max="-2" attributes="0"/> <Component id="categoriesLabel" alignment="0" min="-2" max="-2" attributes="0"/>
<Component id="intraCaseRadio" min="-2" max="-2" attributes="0"/> <Component id="commonFilesSearchLabel2" alignment="0" min="-2" max="-2" attributes="0"/>
<Component id="interCaseRadio" min="-2" max="-2" attributes="0"/>
<Group type="102" attributes="0"> <Group type="102" attributes="0">
<EmptySpace min="-2" pref="10" max="-2" attributes="0"/>
<Component id="layoutPanel" min="-2" pref="364" max="-2" attributes="0"/>
</Group>
<Group type="102" alignment="0" attributes="0">
<EmptySpace min="6" pref="6" max="-2" attributes="0"/> <EmptySpace min="6" pref="6" max="-2" attributes="0"/>
<Group type="103" groupAlignment="0" attributes="0"> <Group type="103" groupAlignment="0" attributes="0">
<Component id="allFileCategoriesRadioButton" alignment="0" min="-2" max="-2" attributes="0"/>
<Component id="selectedFileCategoriesButton" alignment="0" min="-2" max="-2" attributes="0"/>
<Group type="102" alignment="0" attributes="0"> <Group type="102" alignment="0" attributes="0">
<EmptySpace min="21" pref="21" max="-2" attributes="0"/> <EmptySpace min="21" pref="21" max="-2" attributes="0"/>
<Group type="103" groupAlignment="0" attributes="0"> <Group type="103" groupAlignment="0" attributes="0">
<Component id="documentsCheckbox" min="-2" max="-2" attributes="0"/>
<Component id="pictureVideoCheckbox" min="-2" max="-2" attributes="0"/> <Component id="pictureVideoCheckbox" min="-2" max="-2" attributes="0"/>
<Component id="documentsCheckbox" alignment="0" min="-2" max="-2" attributes="0"/>
</Group> </Group>
</Group> </Group>
<Component id="allFileCategoriesRadioButton" alignment="0" min="-2" max="-2" attributes="0"/>
<Component id="selectedFileCategoriesButton" alignment="0" min="-2" max="-2" attributes="0"/>
<Component id="interCaseRadio" min="-2" max="-2" attributes="0"/>
<Component id="intraCaseRadio" min="-2" max="-2" attributes="0"/>
<Group type="102" alignment="0" attributes="0">
<EmptySpace min="-2" pref="10" max="-2" attributes="0"/>
<Component id="layoutPanel" min="-2" max="-2" attributes="0"/>
</Group>
<Group type="102" alignment="0" attributes="0">
<Component id="errorText" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="searchButton" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="cancelButton" min="-2" max="-2" attributes="0"/>
</Group>
</Group> </Group>
</Group> </Group>
<Group type="102" alignment="1" attributes="0">
<Component id="errorText" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="searchButton" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="cancelButton" min="-2" max="-2" attributes="0"/>
</Group>
</Group> </Group>
<EmptySpace max="32767" attributes="0"/>
</Group> </Group>
</Group> </Group>
</DimensionLayout> </DimensionLayout>
@ -65,39 +65,42 @@
<EmptySpace max="-2" attributes="0"/> <EmptySpace max="-2" attributes="0"/>
<Component id="commonFilesSearchLabel1" min="-2" max="-2" attributes="0"/> <Component id="commonFilesSearchLabel1" min="-2" max="-2" attributes="0"/>
<EmptySpace type="separate" max="-2" attributes="0"/> <EmptySpace type="separate" max="-2" attributes="0"/>
<Component id="commonFilesSearchLabel2" min="-2" max="-2" attributes="0"/>
<EmptySpace min="-2" pref="2" max="-2" attributes="0"/>
<Component id="intraCaseRadio" min="-2" max="-2" attributes="0"/> <Component id="intraCaseRadio" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/> <EmptySpace max="-2" attributes="0"/>
<Component id="interCaseRadio" min="-2" max="-2" attributes="0"/> <Component id="interCaseRadio" min="-2" max="-2" attributes="0"/>
<EmptySpace min="-2" pref="0" max="-2" attributes="0"/> <EmptySpace min="-2" pref="0" max="-2" attributes="0"/>
<Component id="layoutPanel" max="32767" attributes="0"/> <Component id="layoutPanel" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/> <EmptySpace min="-2" pref="0" max="-2" attributes="0"/>
<Component id="categoriesLabel" min="-2" max="-2" attributes="0"/> <Component id="categoriesLabel" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/> <EmptySpace max="-2" attributes="0"/>
<Group type="103" groupAlignment="0" attributes="0"> <Component id="selectedFileCategoriesButton" min="-2" max="-2" attributes="0"/>
<Group type="102" alignment="0" attributes="0">
<EmptySpace min="-2" pref="80" max="-2" attributes="0"/>
<Component id="allFileCategoriesRadioButton" min="-2" max="-2" attributes="0"/>
</Group>
<Group type="102" alignment="0" attributes="0">
<Component id="selectedFileCategoriesButton" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="pictureVideoCheckbox" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="documentsCheckbox" min="-2" max="-2" attributes="0"/>
</Group>
</Group>
<EmptySpace min="-2" max="-2" attributes="0"/> <EmptySpace min="-2" max="-2" attributes="0"/>
<Component id="pictureVideoCheckbox" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="documentsCheckbox" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="allFileCategoriesRadioButton" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Group type="103" groupAlignment="3" attributes="0"> <Group type="103" groupAlignment="3" attributes="0">
<Component id="cancelButton" alignment="3" min="-2" max="-2" attributes="0"/> <Component id="cancelButton" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="searchButton" alignment="3" min="-2" max="-2" attributes="0"/> <Component id="searchButton" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="errorText" alignment="3" min="-2" max="-2" attributes="0"/> <Component id="errorText" alignment="3" min="-2" max="-2" attributes="0"/>
</Group> </Group>
<EmptySpace max="-2" attributes="0"/>
</Group> </Group>
</Group> </Group>
</DimensionLayout> </DimensionLayout>
</Layout> </Layout>
<SubComponents> <SubComponents>
<Component class="javax.swing.JLabel" name="commonFilesSearchLabel2">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/commonfilesearch/Bundle.properties" key="CommonFilesPanel.commonFilesSearchLabel2.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
<Property name="focusable" type="boolean" value="false"/>
</Properties>
</Component>
<Component class="javax.swing.JButton" name="searchButton"> <Component class="javax.swing.JButton" name="searchButton">
<Properties> <Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
@ -145,7 +148,6 @@
<Property name="buttonGroup" type="javax.swing.ButtonGroup" editor="org.netbeans.modules.form.RADComponent$ButtonGroupPropertyEditor"> <Property name="buttonGroup" type="javax.swing.ButtonGroup" editor="org.netbeans.modules.form.RADComponent$ButtonGroupPropertyEditor">
<ComponentRef name="fileTypeFilterButtonGroup"/> <ComponentRef name="fileTypeFilterButtonGroup"/>
</Property> </Property>
<Property name="selected" type="boolean" value="true"/>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/commonfilesearch/Bundle.properties" key="CommonFilesPanel.selectedFileCategoriesButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/> <ResourceString bundle="org/sleuthkit/autopsy/commonfilesearch/Bundle.properties" key="CommonFilesPanel.selectedFileCategoriesButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property> </Property>
@ -210,8 +212,9 @@
<Property name="buttonGroup" type="javax.swing.ButtonGroup" editor="org.netbeans.modules.form.RADComponent$ButtonGroupPropertyEditor"> <Property name="buttonGroup" type="javax.swing.ButtonGroup" editor="org.netbeans.modules.form.RADComponent$ButtonGroupPropertyEditor">
<ComponentRef name="interIntraButtonGroup"/> <ComponentRef name="interIntraButtonGroup"/>
</Property> </Property>
<Property name="label" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> <Property name="selected" type="boolean" value="true"/>
<ResourceString bundle="org/sleuthkit/autopsy/commonfilesearch/Bundle.properties" key="CommonFilesPanel.intraCaseRadio.label" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/> <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/commonfilesearch/Bundle.properties" key="CommonFilesPanel.intraCaseRadio.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property> </Property>
</Properties> </Properties>
<Events> <Events>
@ -223,7 +226,6 @@
<Property name="buttonGroup" type="javax.swing.ButtonGroup" editor="org.netbeans.modules.form.RADComponent$ButtonGroupPropertyEditor"> <Property name="buttonGroup" type="javax.swing.ButtonGroup" editor="org.netbeans.modules.form.RADComponent$ButtonGroupPropertyEditor">
<ComponentRef name="interIntraButtonGroup"/> <ComponentRef name="interIntraButtonGroup"/>
</Property> </Property>
<Property name="selected" type="boolean" value="true"/>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/commonfilesearch/Bundle.properties" key="CommonFilesPanel.jRadioButton2.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/> <ResourceString bundle="org/sleuthkit/autopsy/commonfilesearch/Bundle.properties" key="CommonFilesPanel.jRadioButton2.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property> </Property>
@ -236,13 +238,6 @@
<Layout class="org.netbeans.modules.form.compat2.layouts.DesignCardLayout"/> <Layout class="org.netbeans.modules.form.compat2.layouts.DesignCardLayout"/>
<SubComponents> <SubComponents>
<Component class="org.sleuthkit.autopsy.commonfilesearch.InterCasePanel" name="interCasePanel">
<Constraints>
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignCardLayout" value="org.netbeans.modules.form.compat2.layouts.DesignCardLayout$CardConstraintsDescription">
<CardConstraints cardName="card2"/>
</Constraint>
</Constraints>
</Component>
<Component class="org.sleuthkit.autopsy.commonfilesearch.IntraCasePanel" name="intraCasePanel"> <Component class="org.sleuthkit.autopsy.commonfilesearch.IntraCasePanel" name="intraCasePanel">
<Constraints> <Constraints>
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignCardLayout" value="org.netbeans.modules.form.compat2.layouts.DesignCardLayout$CardConstraintsDescription"> <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignCardLayout" value="org.netbeans.modules.form.compat2.layouts.DesignCardLayout$CardConstraintsDescription">
@ -250,6 +245,13 @@
</Constraint> </Constraint>
</Constraints> </Constraints>
</Component> </Component>
<Component class="org.sleuthkit.autopsy.commonfilesearch.InterCasePanel" name="interCasePanel">
<Constraints>
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignCardLayout" value="org.netbeans.modules.form.compat2.layouts.DesignCardLayout$CardConstraintsDescription">
<CardConstraints cardName="card2"/>
</Constraint>
</Constraints>
</Component>
</SubComponents> </SubComponents>
</Container> </Container>
</SubComponents> </SubComponents>

View File

@ -40,6 +40,7 @@ import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException;
import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationCase; import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationCase;
import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationDataSource; import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationDataSource;
import org.sleuthkit.autopsy.centralrepository.datamodel.EamDb; import org.sleuthkit.autopsy.centralrepository.datamodel.EamDb;
import org.sleuthkit.autopsy.centralrepository.datamodel.EamDbException;
import org.sleuthkit.autopsy.corecomponentinterfaces.DataResultViewer; import org.sleuthkit.autopsy.corecomponentinterfaces.DataResultViewer;
import org.sleuthkit.autopsy.corecomponents.DataResultTopComponent; import org.sleuthkit.autopsy.corecomponents.DataResultTopComponent;
import org.sleuthkit.autopsy.corecomponents.DataResultViewerTable; import org.sleuthkit.autopsy.corecomponents.DataResultViewerTable;
@ -83,7 +84,27 @@ public final class CommonFilesPanel extends javax.swing.JPanel {
this.interCasePanel.setParent(this); this.interCasePanel.setParent(this);
this.setupDataSources(); this.setupDataSources();
this.setupCases();
if (CommonFilesPanel.isEamDbAvailable()) {
this.setupCases();
} else {
this.disableIntercaseSearch();
}
}
private void disableIntercaseSearch() {
this.intraCaseRadio.setSelected(true);
this.interCaseRadio.setEnabled(false);
}
public static boolean isEamDbAvailable() {
boolean isEamDbAvailable = false;
try {
isEamDbAvailable = EamDb.isEnabled() && !EamDb.getInstance().getCases().isEmpty();
} catch (EamDbException ex) {
LOGGER.log(Level.WARNING, "Error accessing EamDb", ex);
}
return isEamDbAvailable;
} }
@NbBundle.Messages({ @NbBundle.Messages({
@ -113,25 +134,23 @@ public final class CommonFilesPanel extends javax.swing.JPanel {
this.tabTitle = String.format(CommonFilesPanel_search_results_titleSingle, dataSourceName); this.tabTitle = String.format(CommonFilesPanel_search_results_titleSingle, dataSourceName);
} }
private Long determineDataSourceId() { private void setTitleForAllCases() {
Long selectedObjId = CommonFilesPanel.NO_DATA_SOURCE_SELECTED;
if (CommonFilesPanel.this.singleDataSource) { }
for (Entry<Long, String> dataSource : CommonFilesPanel.this.intraCasePanel.getDataSourceMap().entrySet()) {
if (dataSource.getValue().equals(CommonFilesPanel.this.selectedDataSource)) { private void setTitleForSingleCase() {
selectedObjId = dataSource.getKey();
break;
}
}
}
return selectedObjId;
} }
@Override @Override
@SuppressWarnings({"BoxedValueEquality", "NumberEquality"}) @SuppressWarnings({"BoxedValueEquality", "NumberEquality"})
protected CommonFilesMetadata doInBackground() throws TskCoreException, NoCurrentCaseException, SQLException { protected CommonFilesMetadata doInBackground() throws TskCoreException, NoCurrentCaseException, SQLException, EamDbException {
Long dataSourceId = determineDataSourceId(); Long dataSourceId = CommonFilesPanel.this.intraCasePanel.getSelectedDataSourceId();
Integer caseId = CommonFilesPanel.this.interCasePanel.getSelectedCaseId();
CommonFilesMetadataBuilder builder; CommonFilesMetadataBuilder builder;
CommonFilesMetadata metadata;
boolean filterByMedia = false; boolean filterByMedia = false;
boolean filterByDocuments = false; boolean filterByDocuments = false;
if (selectedFileCategoriesButton.isSelected()) { if (selectedFileCategoriesButton.isSelected()) {
@ -142,23 +161,31 @@ public final class CommonFilesPanel extends javax.swing.JPanel {
filterByDocuments = true; filterByDocuments = true;
} }
} }
if (dataSourceId == CommonFilesPanel.NO_DATA_SOURCE_SELECTED) {
builder = new AllDataSourcesCommonFilesAlgorithm(CommonFilesPanel.this.intraCasePanel.getDataSourceMap(), filterByMedia, filterByDocuments);
setTitleForAllDataSources(); if (CommonFilesPanel.this.interCaseRadio.isSelected()) {
builder = new AllDataSourcesEamDbCommonFilesAlgorithm(CommonFilesPanel.this.intraCasePanel.getDataSourceMap(), filterByMedia, filterByDocuments);
if(caseId == InterCasePanel.NO_CASE_SELECTED){
metadata = ((AllDataSourcesEamDbCommonFilesAlgorithm)builder).findEamDbCommonFiles();
} else {
metadata = ((AllDataSourcesEamDbCommonFilesAlgorithm)builder).findEamDbCommonFiles(CommonFilesPanel.this.interCasePanel.getSelectedCaseId());
}
} else { } else {
builder = new SingleDataSource(dataSourceId, CommonFilesPanel.this.intraCasePanel.getDataSourceMap(), filterByMedia, filterByDocuments); if (dataSourceId == CommonFilesPanel.NO_DATA_SOURCE_SELECTED) {
builder = new AllDataSourcesCommonFilesAlgorithm(CommonFilesPanel.this.intraCasePanel.getDataSourceMap(), filterByMedia, filterByDocuments);
setTitleForSingleSource(dataSourceId); setTitleForAllDataSources();
}// else if(false) { } else {
// TODO, is CR cases, add option chosen CorrelationCase ID lookup builder = new SingleDataSource(dataSourceId, CommonFilesPanel.this.intraCasePanel.getDataSourceMap(), filterByMedia, filterByDocuments);
// builder = new AllDataSourcesEamDbCommonFilesAlgorithm(CommonFilesPanel.this.dataSourceMap, filterByMedia, filterByDocuments);
//} setTitleForSingleSource(dataSourceId);
}
metadata = builder.findCommonFiles();
}
this.tabTitle = builder.buildTabTitle(); this.tabTitle = builder.buildTabTitle();
CommonFilesMetadata metadata = builder.findCommonFiles();
return metadata; return metadata;
} }
@ -211,12 +238,13 @@ public final class CommonFilesPanel extends javax.swing.JPanel {
* Sets up the data sources dropdown and returns the data sources map for * Sets up the data sources dropdown and returns the data sources map for
* future usage. * future usage.
* *
* @return a mapping of data correlationCase ids to data correlationCase names * @return a mapping of data correlationCase ids to data correlationCase
* names
*/ */
@NbBundle.Messages({ @NbBundle.Messages({
"CommonFilesPanel.setupDataSources.done.tskCoreException=Unable to run query against DB.", "CommonFilesPanel.setupDataSources.done.tskCoreException=Unable to run query against DB.",
"CommonFilesPanel.setupDataSources.done.noCurrentCaseException=Unable to open case file.", "CommonFilesPanel.setupDataSources.done.noCurrentCaseException=Unable to open case file.",
"CommonFilesPanel.setupDataSources.done.exception=Unexpected exception building data sources map.", "CommonFilesPanel.setupDataSources.done.exception=Unexpected exception loading data sources.",
"CommonFilesPanel.setupDataSources.done.interupted=Something went wrong building the Common Files Search dialog box.", "CommonFilesPanel.setupDataSources.done.interupted=Something went wrong building the Common Files Search dialog box.",
"CommonFilesPanel.setupDataSources.done.sqlException=Unable to query db for data sources.", "CommonFilesPanel.setupDataSources.done.sqlException=Unable to query db for data sources.",
"CommonFilesPanel.setupDataSources.updateUi.noDataSources=No data sources were found."}) "CommonFilesPanel.setupDataSources.updateUi.noDataSources=No data sources were found."})
@ -304,7 +332,6 @@ public final class CommonFilesPanel extends javax.swing.JPanel {
try { try {
CommonFilesPanel.this.intraCasePanel.setDataSourceMap(this.get()); CommonFilesPanel.this.intraCasePanel.setDataSourceMap(this.get());
updateUi(); updateUi();
} catch (InterruptedException ex) { } catch (InterruptedException ex) {
@ -334,36 +361,33 @@ public final class CommonFilesPanel extends javax.swing.JPanel {
@NbBundle.Messages({ @NbBundle.Messages({
"CommonFilesPanel.setupCases.done.interruptedException=Something went wrong building the Common Files Search dialog box.", "CommonFilesPanel.setupCases.done.interruptedException=Something went wrong building the Common Files Search dialog box.",
"CommonFilesPanel.setupCases.done.exeutionException=Unexpected exception building data sources map."}) "CommonFilesPanel.setupCases.done.exeutionException=Unexpected exception loading cases."})
private void setupCases(){ private void setupCases() {
new SwingWorker<Map<Integer, String>, Void>(){ new SwingWorker<Map<Integer, String>, Void>() {
private void updateUi(){ private void updateUi() {
final Map<Integer, String> caseMap = CommonFilesPanel.this.interCasePanel.getCaseMap(); final Map<Integer, String> caseMap = CommonFilesPanel.this.interCasePanel.getCaseMap();
String[] caseNames = new String[caseMap.size()]; String[] caseNames = new String[caseMap.size()];
if(caseNames.length > 0){ if (caseNames.length > 0) {
caseNames = caseMap.values().toArray(caseNames); caseNames = caseMap.values().toArray(caseNames);
CommonFilesPanel.this.interCasePanel.setCaseList(new DataSourceComboBoxModel(caseNames)); CommonFilesPanel.this.interCasePanel.setCaseList(new DataSourceComboBoxModel(caseNames));
boolean multipleCases = this.centralRepoHasMultipleCases(); boolean multipleCases = this.centralRepoHasMultipleCases();
CommonFilesPanel.this.interCasePanel.rigForMultipleCases(multipleCases); CommonFilesPanel.this.interCasePanel.rigForMultipleCases(multipleCases);
//TODO need something more specific
//InterCasePanel.this.parent.setSearchButtonEnabled(true);
} else { } else {
//TODO need something more specific CommonFilesPanel.this.disableIntercaseSearch();
} }
} }
private Map<Integer, String> mapDataSources(List<CorrelationCase> cases) { private Map<Integer, String> mapDataSources(List<CorrelationCase> cases) {
Map<Integer, String> casemap = new HashMap<>(); Map<Integer, String> casemap = new HashMap<>();
for (CorrelationCase correlationCase : cases){ for (CorrelationCase correlationCase : cases) {
casemap.put(correlationCase.getID(), correlationCase.getDisplayName()); casemap.put(correlationCase.getID(), correlationCase.getDisplayName());
} }
@ -381,9 +405,10 @@ public final class CommonFilesPanel extends javax.swing.JPanel {
} }
@Override @Override
protected void done(){ protected void done() {
try{ try {
CommonFilesPanel.this.interCasePanel.setCaseMap(this.get()); Map<Integer, String> cases = this.get();
CommonFilesPanel.this.interCasePanel.setCaseMap(cases);
this.updateUi(); this.updateUi();
} catch (InterruptedException ex) { } catch (InterruptedException ex) {
LOGGER.log(Level.SEVERE, "Interrupted while building Common Files Search dialog.", ex); LOGGER.log(Level.SEVERE, "Interrupted while building Common Files Search dialog.", ex);
@ -400,6 +425,7 @@ public final class CommonFilesPanel extends javax.swing.JPanel {
}.execute(); }.execute();
} }
/** /**
* This method is called from within the constructor to initialize the form. * 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 * WARNING: Do NOT modify this code. The content of this method is always
@ -411,6 +437,7 @@ public final class CommonFilesPanel extends javax.swing.JPanel {
fileTypeFilterButtonGroup = new javax.swing.ButtonGroup(); fileTypeFilterButtonGroup = new javax.swing.ButtonGroup();
interIntraButtonGroup = new javax.swing.ButtonGroup(); interIntraButtonGroup = new javax.swing.ButtonGroup();
commonFilesSearchLabel2 = new javax.swing.JLabel();
searchButton = new javax.swing.JButton(); searchButton = new javax.swing.JButton();
cancelButton = new javax.swing.JButton(); cancelButton = new javax.swing.JButton();
allFileCategoriesRadioButton = new javax.swing.JRadioButton(); allFileCategoriesRadioButton = new javax.swing.JRadioButton();
@ -423,8 +450,11 @@ public final class CommonFilesPanel extends javax.swing.JPanel {
intraCaseRadio = new javax.swing.JRadioButton(); intraCaseRadio = new javax.swing.JRadioButton();
interCaseRadio = new javax.swing.JRadioButton(); interCaseRadio = new javax.swing.JRadioButton();
layoutPanel = new java.awt.Panel(); layoutPanel = new java.awt.Panel();
interCasePanel = new org.sleuthkit.autopsy.commonfilesearch.InterCasePanel();
intraCasePanel = new org.sleuthkit.autopsy.commonfilesearch.IntraCasePanel(); intraCasePanel = new org.sleuthkit.autopsy.commonfilesearch.IntraCasePanel();
interCasePanel = new org.sleuthkit.autopsy.commonfilesearch.InterCasePanel();
org.openide.awt.Mnemonics.setLocalizedText(commonFilesSearchLabel2, org.openide.util.NbBundle.getMessage(CommonFilesPanel.class, "CommonFilesPanel.commonFilesSearchLabel2.text")); // NOI18N
commonFilesSearchLabel2.setFocusable(false);
org.openide.awt.Mnemonics.setLocalizedText(searchButton, org.openide.util.NbBundle.getMessage(CommonFilesPanel.class, "CommonFilesPanel.searchButton.text")); // NOI18N org.openide.awt.Mnemonics.setLocalizedText(searchButton, org.openide.util.NbBundle.getMessage(CommonFilesPanel.class, "CommonFilesPanel.searchButton.text")); // NOI18N
searchButton.setEnabled(false); searchButton.setEnabled(false);
@ -454,7 +484,6 @@ public final class CommonFilesPanel extends javax.swing.JPanel {
}); });
fileTypeFilterButtonGroup.add(selectedFileCategoriesButton); fileTypeFilterButtonGroup.add(selectedFileCategoriesButton);
selectedFileCategoriesButton.setSelected(true);
org.openide.awt.Mnemonics.setLocalizedText(selectedFileCategoriesButton, org.openide.util.NbBundle.getMessage(CommonFilesPanel.class, "CommonFilesPanel.selectedFileCategoriesButton.text")); // NOI18N org.openide.awt.Mnemonics.setLocalizedText(selectedFileCategoriesButton, org.openide.util.NbBundle.getMessage(CommonFilesPanel.class, "CommonFilesPanel.selectedFileCategoriesButton.text")); // NOI18N
selectedFileCategoriesButton.setToolTipText(org.openide.util.NbBundle.getMessage(CommonFilesPanel.class, "CommonFilesPanel.selectedFileCategoriesButton.toolTipText")); // NOI18N selectedFileCategoriesButton.setToolTipText(org.openide.util.NbBundle.getMessage(CommonFilesPanel.class, "CommonFilesPanel.selectedFileCategoriesButton.toolTipText")); // NOI18N
selectedFileCategoriesButton.addActionListener(new java.awt.event.ActionListener() { selectedFileCategoriesButton.addActionListener(new java.awt.event.ActionListener() {
@ -489,7 +518,8 @@ public final class CommonFilesPanel extends javax.swing.JPanel {
commonFilesSearchLabel1.setFocusable(false); commonFilesSearchLabel1.setFocusable(false);
interIntraButtonGroup.add(intraCaseRadio); interIntraButtonGroup.add(intraCaseRadio);
intraCaseRadio.setLabel(org.openide.util.NbBundle.getMessage(CommonFilesPanel.class, "CommonFilesPanel.intraCaseRadio.label")); // NOI18N intraCaseRadio.setSelected(true);
org.openide.awt.Mnemonics.setLocalizedText(intraCaseRadio, org.openide.util.NbBundle.getMessage(CommonFilesPanel.class, "CommonFilesPanel.intraCaseRadio.text")); // NOI18N
intraCaseRadio.addActionListener(new java.awt.event.ActionListener() { intraCaseRadio.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) { public void actionPerformed(java.awt.event.ActionEvent evt) {
intraCaseRadioActionPerformed(evt); intraCaseRadioActionPerformed(evt);
@ -497,7 +527,6 @@ public final class CommonFilesPanel extends javax.swing.JPanel {
}); });
interIntraButtonGroup.add(interCaseRadio); interIntraButtonGroup.add(interCaseRadio);
interCaseRadio.setSelected(true);
org.openide.awt.Mnemonics.setLocalizedText(interCaseRadio, org.openide.util.NbBundle.getMessage(CommonFilesPanel.class, "CommonFilesPanel.jRadioButton2.text")); // NOI18N org.openide.awt.Mnemonics.setLocalizedText(interCaseRadio, org.openide.util.NbBundle.getMessage(CommonFilesPanel.class, "CommonFilesPanel.jRadioButton2.text")); // NOI18N
interCaseRadio.addActionListener(new java.awt.event.ActionListener() { interCaseRadio.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) { public void actionPerformed(java.awt.event.ActionEvent evt) {
@ -506,40 +535,40 @@ public final class CommonFilesPanel extends javax.swing.JPanel {
}); });
layoutPanel.setLayout(new java.awt.CardLayout()); layoutPanel.setLayout(new java.awt.CardLayout());
layoutPanel.add(interCasePanel, "card2");
layoutPanel.add(intraCasePanel, "card3"); layoutPanel.add(intraCasePanel, "card3");
layoutPanel.add(interCasePanel, "card2");
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
this.setLayout(layout); this.setLayout(layout);
layout.setHorizontalGroup( layout.setHorizontalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup() .addGroup(layout.createSequentialGroup()
.addContainerGap() .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(commonFilesSearchLabel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addComponent(commonFilesSearchLabel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(categoriesLabel) .addComponent(categoriesLabel)
.addComponent(intraCaseRadio) .addComponent(commonFilesSearchLabel2)
.addComponent(interCaseRadio)
.addGroup(layout.createSequentialGroup()
.addGap(10, 10, 10)
.addComponent(layoutPanel, javax.swing.GroupLayout.PREFERRED_SIZE, 364, javax.swing.GroupLayout.PREFERRED_SIZE))
.addGroup(layout.createSequentialGroup() .addGroup(layout.createSequentialGroup()
.addGap(6, 6, 6) .addGap(6, 6, 6)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(allFileCategoriesRadioButton)
.addComponent(selectedFileCategoriesButton)
.addGroup(layout.createSequentialGroup() .addGroup(layout.createSequentialGroup()
.addGap(21, 21, 21) .addGap(21, 21, 21)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(pictureVideoCheckbox) .addComponent(documentsCheckbox)
.addComponent(documentsCheckbox))))) .addComponent(pictureVideoCheckbox)))
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup() .addComponent(allFileCategoriesRadioButton)
.addComponent(errorText) .addComponent(selectedFileCategoriesButton)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(interCaseRadio)
.addComponent(searchButton) .addComponent(intraCaseRadio)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addGroup(layout.createSequentialGroup()
.addComponent(cancelButton))) .addGap(10, 10, 10)
.addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) .addComponent(layoutPanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
.addGroup(layout.createSequentialGroup()
.addComponent(errorText)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(searchButton)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(cancelButton))))))
); );
layout.setVerticalGroup( layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
@ -547,30 +576,28 @@ public final class CommonFilesPanel extends javax.swing.JPanel {
.addContainerGap() .addContainerGap()
.addComponent(commonFilesSearchLabel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addComponent(commonFilesSearchLabel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addGap(18, 18, 18) .addGap(18, 18, 18)
.addComponent(commonFilesSearchLabel2)
.addGap(2, 2, 2)
.addComponent(intraCaseRadio) .addComponent(intraCaseRadio)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(interCaseRadio) .addComponent(interCaseRadio)
.addGap(0, 0, 0) .addGap(0, 0, 0)
.addComponent(layoutPanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addComponent(layoutPanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addGap(0, 0, 0)
.addComponent(categoriesLabel) .addComponent(categoriesLabel)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addComponent(selectedFileCategoriesButton)
.addGroup(layout.createSequentialGroup() .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addGap(80, 80, 80) .addComponent(pictureVideoCheckbox)
.addComponent(allFileCategoriesRadioButton)) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addGroup(layout.createSequentialGroup() .addComponent(documentsCheckbox)
.addComponent(selectedFileCategoriesButton) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(allFileCategoriesRadioButton)
.addComponent(pictureVideoCheckbox)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(documentsCheckbox)))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(cancelButton) .addComponent(cancelButton)
.addComponent(searchButton) .addComponent(searchButton)
.addComponent(errorText)) .addComponent(errorText)))
.addContainerGap())
); );
}// </editor-fold>//GEN-END:initComponents }// </editor-fold>//GEN-END:initComponents
@ -601,13 +628,37 @@ public final class CommonFilesPanel extends javax.swing.JPanel {
}//GEN-LAST:event_documentsCheckboxActionPerformed }//GEN-LAST:event_documentsCheckboxActionPerformed
private void intraCaseRadioActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_intraCaseRadioActionPerformed private void intraCaseRadioActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_intraCaseRadioActionPerformed
((java.awt.CardLayout)this.layoutPanel.getLayout()).last(this.layoutPanel); ((java.awt.CardLayout) this.layoutPanel.getLayout()).first(this.layoutPanel);
handleIntraCaseSearchCriteriaChanged();
}//GEN-LAST:event_intraCaseRadioActionPerformed }//GEN-LAST:event_intraCaseRadioActionPerformed
public void handleIntraCaseSearchCriteriaChanged() {
if (this.areIntraCaseSearchCriteriaMet()) {
this.searchButton.setEnabled(true);
this.hideErrorMessages();
} else {
this.searchButton.setEnabled(false);
this.hideErrorMessages();
this.showIntraCaseErrorMessage();
}
}
private void interCaseRadioActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_interCaseRadioActionPerformed private void interCaseRadioActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_interCaseRadioActionPerformed
((java.awt.CardLayout)this.layoutPanel.getLayout()).first(this.layoutPanel); ((java.awt.CardLayout) this.layoutPanel.getLayout()).last(this.layoutPanel);
handleInterCaseSearchCriteriaChanged();
}//GEN-LAST:event_interCaseRadioActionPerformed }//GEN-LAST:event_interCaseRadioActionPerformed
public void handleInterCaseSearchCriteriaChanged() {
if (this.areInterCaseSearchCriteriaMet()) {
this.searchButton.setEnabled(true);
this.hideErrorMessages();
} else {
this.searchButton.setEnabled(false);
this.hideErrorMessages();
this.showInterCaseErrorMessage();
}
}
private void toggleErrorTextAndSearchBox() { private void toggleErrorTextAndSearchBox() {
if (!this.pictureVideoCheckbox.isSelected() && !this.documentsCheckbox.isSelected() && !this.allFileCategoriesRadioButton.isSelected()) { if (!this.pictureVideoCheckbox.isSelected() && !this.documentsCheckbox.isSelected() && !this.allFileCategoriesRadioButton.isSelected()) {
this.searchButton.setEnabled(false); this.searchButton.setEnabled(false);
@ -646,6 +697,7 @@ public final class CommonFilesPanel extends javax.swing.JPanel {
private javax.swing.JButton cancelButton; private javax.swing.JButton cancelButton;
private javax.swing.JLabel categoriesLabel; private javax.swing.JLabel categoriesLabel;
private javax.swing.JLabel commonFilesSearchLabel1; private javax.swing.JLabel commonFilesSearchLabel1;
private javax.swing.JLabel commonFilesSearchLabel2;
private javax.swing.JCheckBox documentsCheckbox; private javax.swing.JCheckBox documentsCheckbox;
private javax.swing.JLabel errorText; private javax.swing.JLabel errorText;
private javax.swing.ButtonGroup fileTypeFilterButtonGroup; private javax.swing.ButtonGroup fileTypeFilterButtonGroup;
@ -663,4 +715,26 @@ public final class CommonFilesPanel extends javax.swing.JPanel {
void setSearchButtonEnabled(boolean enabled) { void setSearchButtonEnabled(boolean enabled) {
this.searchButton.setEnabled(enabled); this.searchButton.setEnabled(enabled);
} }
private boolean areIntraCaseSearchCriteriaMet() {
return this.intraCasePanel.areSearchCriteriaMet();
}
private boolean areInterCaseSearchCriteriaMet() {
return this.interCasePanel.areSearchCriteriaMet();
}
private void hideErrorMessages() {
this.errorText.setVisible(false);
}
private void showIntraCaseErrorMessage() {
this.errorText.setText(this.intraCasePanel.getErrorMessage());
this.errorText.setVisible(true);
}
private void showInterCaseErrorMessage() {
this.errorText.setText(this.interCasePanel.getErrorMessage());
this.errorText.setVisible(true);
}
} }

View File

@ -19,17 +19,25 @@
package org.sleuthkit.autopsy.commonfilesearch; package org.sleuthkit.autopsy.commonfilesearch;
import java.awt.event.ActionEvent; import java.awt.event.ActionEvent;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.openide.util.Exceptions;
import org.openide.util.HelpCtx; import org.openide.util.HelpCtx;
import org.openide.util.NbBundle; import org.openide.util.NbBundle;
import org.openide.util.actions.CallableSystemAction; import org.openide.util.actions.CallableSystemAction;
import org.sleuthkit.autopsy.casemodule.Case; import org.sleuthkit.autopsy.casemodule.Case;
import org.sleuthkit.autopsy.centralrepository.datamodel.EamDb;
import org.sleuthkit.autopsy.centralrepository.datamodel.EamDbException;
import org.sleuthkit.autopsy.core.Installer; import org.sleuthkit.autopsy.core.Installer;
import org.sleuthkit.datamodel.TskCoreException;
/** /**
* Encapsulates a menu action which triggers the common files search dialog. * Encapsulates a menu action which triggers the common files search dialog.
*/ */
final public class CommonFilesSearchAction extends CallableSystemAction { final public class CommonFilesSearchAction extends CallableSystemAction {
private static final Logger LOGGER = Logger.getLogger(CommonFilesSearchAction.class.getName());
private static CommonFilesSearchAction instance = null; private static CommonFilesSearchAction instance = null;
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
@ -40,7 +48,16 @@ final public class CommonFilesSearchAction extends CallableSystemAction {
@Override @Override
public boolean isEnabled(){ public boolean isEnabled(){
return super.isEnabled() && Case.isCaseOpen() && Installer.isJavaFxInited(); boolean isEamDbAvailable = CommonFilesPanel.isEamDbAvailable();
boolean isMultiDataSourceCase = false;
try {
isMultiDataSourceCase = Case.isCaseOpen() && !Case.getCurrentCase().getDataSources().isEmpty();
} catch (TskCoreException ex) {
Exceptions.printStackTrace(ex);
}
return super.isEnabled() && Installer.isJavaFxInited() && (isMultiDataSourceCase || isEamDbAvailable);
} }
public static synchronized CommonFilesSearchAction getDefault() { public static synchronized CommonFilesSearchAction getDefault() {

View File

@ -20,15 +20,15 @@
<Layout> <Layout>
<DimensionLayout dim="0"> <DimensionLayout dim="0">
<Group type="103" groupAlignment="0" attributes="0"> <Group type="103" groupAlignment="0" attributes="0">
<Group type="102" alignment="0" attributes="0"> <Group type="102" attributes="0">
<EmptySpace max="-2" attributes="0"/> <EmptySpace max="-2" attributes="0"/>
<Group type="103" groupAlignment="0" attributes="0"> <Group type="103" groupAlignment="0" attributes="0">
<Component id="anCentralRepoCaseRadio" alignment="0" min="-2" max="-2" attributes="0"/> <Component id="anyCentralRepoCaseRadio" alignment="0" min="-2" max="-2" attributes="0"/>
<Component id="specificCentralRepoCaseRadio" alignment="0" min="-2" max="-2" attributes="0"/> <Group type="102" attributes="0">
<Group type="102" alignment="0" attributes="0"> <EmptySpace min="21" pref="21" max="-2" attributes="0"/>
<EmptySpace min="-2" pref="21" max="-2" attributes="0"/>
<Component id="caseComboBox" min="-2" pref="261" max="-2" attributes="0"/> <Component id="caseComboBox" min="-2" pref="261" max="-2" attributes="0"/>
</Group> </Group>
<Component id="specificCentralRepoCaseRadio" min="-2" max="-2" attributes="0"/>
</Group> </Group>
<EmptySpace max="32767" attributes="0"/> <EmptySpace max="32767" attributes="0"/>
</Group> </Group>
@ -37,30 +37,28 @@
<DimensionLayout dim="1"> <DimensionLayout dim="1">
<Group type="103" groupAlignment="0" attributes="0"> <Group type="103" groupAlignment="0" attributes="0">
<Group type="102" alignment="0" attributes="0"> <Group type="102" alignment="0" attributes="0">
<EmptySpace max="-2" attributes="0"/> <Component id="anyCentralRepoCaseRadio" min="-2" max="-2" attributes="0"/>
<Component id="anCentralRepoCaseRadio" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/> <EmptySpace max="-2" attributes="0"/>
<Component id="specificCentralRepoCaseRadio" min="-2" max="-2" attributes="0"/> <Component id="specificCentralRepoCaseRadio" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/> <EmptySpace max="-2" attributes="0"/>
<Component id="caseComboBox" min="-2" max="-2" attributes="0"/> <Component id="caseComboBox" min="-2" max="-2" attributes="0"/>
<EmptySpace max="32767" attributes="0"/>
</Group> </Group>
</Group> </Group>
</DimensionLayout> </DimensionLayout>
</Layout> </Layout>
<SubComponents> <SubComponents>
<Component class="javax.swing.JRadioButton" name="anCentralRepoCaseRadio"> <Component class="javax.swing.JRadioButton" name="anyCentralRepoCaseRadio">
<Properties> <Properties>
<Property name="buttonGroup" type="javax.swing.ButtonGroup" editor="org.netbeans.modules.form.RADComponent$ButtonGroupPropertyEditor"> <Property name="buttonGroup" type="javax.swing.ButtonGroup" editor="org.netbeans.modules.form.RADComponent$ButtonGroupPropertyEditor">
<ComponentRef name="buttonGroup"/> <ComponentRef name="buttonGroup"/>
</Property> </Property>
<Property name="selected" type="boolean" value="true"/> <Property name="selected" type="boolean" value="true"/>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/commonfilesearch/Bundle.properties" key="InterCasePanel.anCentralRepoCaseRadio.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/> <ResourceString bundle="org/sleuthkit/autopsy/commonfilesearch/Bundle.properties" key="InterCasePanel.anyCentralRepoCaseRadio.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property> </Property>
</Properties> </Properties>
<Events> <Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="anCentralRepoCaseRadioActionPerformed"/> <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="anyCentralRepoCaseRadioActionPerformed"/>
</Events> </Events>
</Component> </Component>
<Component class="javax.swing.JRadioButton" name="specificCentralRepoCaseRadio"> <Component class="javax.swing.JRadioButton" name="specificCentralRepoCaseRadio">

View File

@ -22,6 +22,7 @@ package org.sleuthkit.autopsy.commonfilesearch;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Map.Entry;
import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutionException;
import java.util.logging.Level; import java.util.logging.Level;
import javax.swing.ComboBoxModel; import javax.swing.ComboBoxModel;
@ -40,29 +41,29 @@ import org.sleuthkit.autopsy.coreutils.MessageNotifyUtil;
public class InterCasePanel extends javax.swing.JPanel { public class InterCasePanel extends javax.swing.JPanel {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
static final int NO_CASE_SELECTED = -1;
private static final Logger LOGGER = Logger.getLogger(InterCasePanel.class.getName()); private static final Logger LOGGER = Logger.getLogger(InterCasePanel.class.getName());
private String selectedCase;
private boolean singleCase;
private ComboBoxModel<String> casesList = new DataSourceComboBoxModel(); private ComboBoxModel<String> casesList = new DataSourceComboBoxModel();
private Map<Integer, String> caseMap; private Map<Integer, String> caseMap;
private CommonFilesPanel parent; private CommonFilesPanel parent;
private String errorMessage;
/** /**
* Creates new form InterCasePanel * Creates new form InterCasePanel
*/ */
public InterCasePanel() { public InterCasePanel() {
initComponents(); initComponents();
this.errorMessage = "";
} }
private void specificCaseSelected(boolean selected) { private void specificCaseSelected(boolean selected) {
this.specificCentralRepoCaseRadio.setEnabled(selected); this.specificCentralRepoCaseRadio.setEnabled(selected);
if (this.specificCentralRepoCaseRadio.isEnabled()) { if (this.specificCentralRepoCaseRadio.isEnabled()) {
this.caseComboBox.setSelectedIndex(0); this.caseComboBox.setSelectedIndex(0);
this.singleCase = true;
} }
} }
@ -70,6 +71,10 @@ public class InterCasePanel extends javax.swing.JPanel {
this.parent = parent; this.parent = parent;
} }
String getErrorMessage(){
return this.errorMessage;
}
/** /**
* This method is called from within the constructor to initialize the form. * 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 * WARNING: Do NOT modify this code. The content of this method is always
@ -80,16 +85,16 @@ public class InterCasePanel extends javax.swing.JPanel {
private void initComponents() { private void initComponents() {
buttonGroup = new javax.swing.ButtonGroup(); buttonGroup = new javax.swing.ButtonGroup();
anCentralRepoCaseRadio = new javax.swing.JRadioButton(); anyCentralRepoCaseRadio = new javax.swing.JRadioButton();
specificCentralRepoCaseRadio = new javax.swing.JRadioButton(); specificCentralRepoCaseRadio = new javax.swing.JRadioButton();
caseComboBox = new javax.swing.JComboBox<>(); caseComboBox = new javax.swing.JComboBox<>();
buttonGroup.add(anCentralRepoCaseRadio); buttonGroup.add(anyCentralRepoCaseRadio);
anCentralRepoCaseRadio.setSelected(true); anyCentralRepoCaseRadio.setSelected(true);
org.openide.awt.Mnemonics.setLocalizedText(anCentralRepoCaseRadio, org.openide.util.NbBundle.getMessage(InterCasePanel.class, "InterCasePanel.anCentralRepoCaseRadio.text")); // NOI18N org.openide.awt.Mnemonics.setLocalizedText(anyCentralRepoCaseRadio, org.openide.util.NbBundle.getMessage(InterCasePanel.class, "InterCasePanel.anyCentralRepoCaseRadio.text")); // NOI18N
anCentralRepoCaseRadio.addActionListener(new java.awt.event.ActionListener() { anyCentralRepoCaseRadio.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) { public void actionPerformed(java.awt.event.ActionEvent evt) {
anCentralRepoCaseRadioActionPerformed(evt); anyCentralRepoCaseRadioActionPerformed(evt);
} }
}); });
@ -111,37 +116,40 @@ public class InterCasePanel extends javax.swing.JPanel {
.addGroup(layout.createSequentialGroup() .addGroup(layout.createSequentialGroup()
.addContainerGap() .addContainerGap()
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(anCentralRepoCaseRadio) .addComponent(anyCentralRepoCaseRadio)
.addComponent(specificCentralRepoCaseRadio)
.addGroup(layout.createSequentialGroup() .addGroup(layout.createSequentialGroup()
.addGap(21, 21, 21) .addGap(21, 21, 21)
.addComponent(caseComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, 261, javax.swing.GroupLayout.PREFERRED_SIZE))) .addComponent(caseComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, 261, javax.swing.GroupLayout.PREFERRED_SIZE))
.addComponent(specificCentralRepoCaseRadio))
.addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
); );
layout.setVerticalGroup( layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup() .addGroup(layout.createSequentialGroup()
.addContainerGap() .addComponent(anyCentralRepoCaseRadio)
.addComponent(anCentralRepoCaseRadio)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(specificCentralRepoCaseRadio) .addComponent(specificCentralRepoCaseRadio)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(caseComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addComponent(caseComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
.addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
); );
}// </editor-fold>//GEN-END:initComponents }// </editor-fold>//GEN-END:initComponents
private void specificCentralRepoCaseRadioActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_specificCentralRepoCaseRadioActionPerformed private void specificCentralRepoCaseRadioActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_specificCentralRepoCaseRadioActionPerformed
this.caseComboBox.setEnabled(true); this.caseComboBox.setEnabled(true);
if(this.caseComboBox.getSelectedItem() == null){
this.caseComboBox.setSelectedIndex(0);
}
this.parent.handleInterCaseSearchCriteriaChanged();
}//GEN-LAST:event_specificCentralRepoCaseRadioActionPerformed }//GEN-LAST:event_specificCentralRepoCaseRadioActionPerformed
private void anCentralRepoCaseRadioActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_anCentralRepoCaseRadioActionPerformed private void anyCentralRepoCaseRadioActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_anyCentralRepoCaseRadioActionPerformed
this.caseComboBox.setEnabled(false); this.caseComboBox.setEnabled(false);
}//GEN-LAST:event_anCentralRepoCaseRadioActionPerformed this.parent.handleInterCaseSearchCriteriaChanged();
}//GEN-LAST:event_anyCentralRepoCaseRadioActionPerformed
// Variables declaration - do not modify//GEN-BEGIN:variables // Variables declaration - do not modify//GEN-BEGIN:variables
private javax.swing.JRadioButton anCentralRepoCaseRadio; private javax.swing.JRadioButton anyCentralRepoCaseRadio;
private javax.swing.ButtonGroup buttonGroup; private javax.swing.ButtonGroup buttonGroup;
private javax.swing.JComboBox<String> caseComboBox; private javax.swing.JComboBox<String> caseComboBox;
private javax.swing.JRadioButton specificCentralRepoCaseRadio; private javax.swing.JRadioButton specificCentralRepoCaseRadio;
@ -157,8 +165,8 @@ public class InterCasePanel extends javax.swing.JPanel {
} }
void rigForMultipleCases(boolean multipleCases) { void rigForMultipleCases(boolean multipleCases) {
this.anCentralRepoCaseRadio.setEnabled(multipleCases); this.anyCentralRepoCaseRadio.setEnabled(multipleCases);
this.anCentralRepoCaseRadio.setEnabled(multipleCases); this.anyCentralRepoCaseRadio.setEnabled(multipleCases);
if(!multipleCases){ if(!multipleCases){
this.specificCentralRepoCaseRadio.setSelected(true); this.specificCentralRepoCaseRadio.setSelected(true);
@ -173,4 +181,26 @@ public class InterCasePanel extends javax.swing.JPanel {
boolean centralRepoHasMultipleCases() { boolean centralRepoHasMultipleCases() {
return this.caseMap.size() >= 2; return this.caseMap.size() >= 2;
} }
Integer getSelectedCaseId(){
for(Entry<Integer, String> entry : this.caseMap.entrySet()){
if(entry.getValue().equals(this.caseComboBox.getSelectedItem())){
return entry.getKey();
}
}
return InterCasePanel.NO_CASE_SELECTED;
}
@NbBundle.Messages({
"InterCasePanel.showInterCaseErrorMessage.message=Cannot run intercase correlation search: no cases in Central Repository."
})
boolean areSearchCriteriaMet() {
if(this.caseMap.isEmpty()){
this.errorMessage = Bundle.InterCasePanel_showInterCaseErrorMessage_message();
return false;
} else {
return true;
}
}
} }

View File

@ -20,13 +20,17 @@
<Layout> <Layout>
<DimensionLayout dim="0"> <DimensionLayout dim="0">
<Group type="103" groupAlignment="0" attributes="0"> <Group type="103" groupAlignment="0" attributes="0">
<Group type="102" alignment="0" attributes="0"> <Group type="102" attributes="0">
<EmptySpace max="-2" attributes="0"/>
<Group type="103" groupAlignment="0" attributes="0"> <Group type="103" groupAlignment="0" attributes="0">
<Component id="withinDataSourceRadioButton" alignment="0" min="-2" max="-2" attributes="0"/> <Group type="102" attributes="0">
<Component id="allDataSourcesRadioButton" alignment="0" min="-2" max="-2" attributes="0"/> <EmptySpace max="-2" attributes="0"/>
<Group type="103" groupAlignment="0" attributes="0">
<Component id="allDataSourcesRadioButton" alignment="0" min="-2" max="-2" attributes="0"/>
<Component id="withinDataSourceRadioButton" min="-2" max="-2" attributes="0"/>
</Group>
</Group>
<Group type="102" alignment="0" attributes="0"> <Group type="102" alignment="0" attributes="0">
<EmptySpace min="-2" pref="20" max="-2" attributes="0"/> <EmptySpace min="-2" pref="27" max="-2" attributes="0"/>
<Component id="selectDataSourceComboBox" min="-2" pref="261" max="-2" attributes="0"/> <Component id="selectDataSourceComboBox" min="-2" pref="261" max="-2" attributes="0"/>
</Group> </Group>
</Group> </Group>
@ -37,13 +41,11 @@
<DimensionLayout dim="1"> <DimensionLayout dim="1">
<Group type="103" groupAlignment="0" attributes="0"> <Group type="103" groupAlignment="0" attributes="0">
<Group type="102" alignment="0" attributes="0"> <Group type="102" alignment="0" attributes="0">
<EmptySpace max="-2" attributes="0"/>
<Component id="allDataSourcesRadioButton" min="-2" max="-2" attributes="0"/> <Component id="allDataSourcesRadioButton" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/> <EmptySpace max="-2" attributes="0"/>
<Component id="withinDataSourceRadioButton" min="-2" max="-2" attributes="0"/> <Component id="withinDataSourceRadioButton" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/> <EmptySpace max="-2" attributes="0"/>
<Component id="selectDataSourceComboBox" min="-2" max="-2" attributes="0"/> <Component id="selectDataSourceComboBox" min="-2" max="-2" attributes="0"/>
<EmptySpace max="32767" attributes="0"/>
</Group> </Group>
</Group> </Group>
</DimensionLayout> </DimensionLayout>

View File

@ -24,6 +24,7 @@ import java.sql.ResultSet;
import java.sql.SQLException; import java.sql.SQLException;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
import java.util.Map.Entry;
import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutionException;
import java.util.logging.Level; import java.util.logging.Level;
import javax.swing.ComboBoxModel; import javax.swing.ComboBoxModel;
@ -44,6 +45,7 @@ import org.sleuthkit.datamodel.TskCoreException;
public class IntraCasePanel extends javax.swing.JPanel { public class IntraCasePanel extends javax.swing.JPanel {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
static final long NO_DATA_SOURCE_SELECTED = -1;
private static final Logger LOGGER = Logger.getLogger(CommonFilesPanel.class.getName()); private static final Logger LOGGER = Logger.getLogger(CommonFilesPanel.class.getName());
@ -53,11 +55,14 @@ public class IntraCasePanel extends javax.swing.JPanel {
private Map<Long, String> dataSourceMap; private Map<Long, String> dataSourceMap;
private CommonFilesPanel parent; private CommonFilesPanel parent;
private String errorMessage;
/** /**
* Creates new form IntraCasePanel * Creates new form IntraCasePanel
*/ */
public IntraCasePanel() { public IntraCasePanel() {
initComponents(); initComponents();
this.errorMessage = "";
} }
public void setParent(CommonFilesPanel parent){ public void setParent(CommonFilesPanel parent){
@ -80,7 +85,15 @@ public class IntraCasePanel extends javax.swing.JPanel {
return this.dataSourceMap; return this.dataSourceMap;
} }
Long getSelectedDataSourceId(){
for(Entry<Long, String> entry : this.dataSourceMap.entrySet()){
if(entry.getValue().equals(this.selectDataSourceComboBox.getSelectedItem())){
return entry.getKey();
}
}
return IntraCasePanel.NO_DATA_SOURCE_SELECTED;
}
/** /**
* This method is called from within the constructor to initialize the form. * This method is called from within the constructor to initialize the form.
@ -127,35 +140,37 @@ public class IntraCasePanel extends javax.swing.JPanel {
layout.setHorizontalGroup( layout.setHorizontalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup() .addGroup(layout.createSequentialGroup()
.addContainerGap()
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(withinDataSourceRadioButton)
.addComponent(allDataSourcesRadioButton)
.addGroup(layout.createSequentialGroup() .addGroup(layout.createSequentialGroup()
.addGap(20, 20, 20) .addContainerGap()
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(allDataSourcesRadioButton)
.addComponent(withinDataSourceRadioButton)))
.addGroup(layout.createSequentialGroup()
.addGap(27, 27, 27)
.addComponent(selectDataSourceComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, 261, javax.swing.GroupLayout.PREFERRED_SIZE))) .addComponent(selectDataSourceComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, 261, javax.swing.GroupLayout.PREFERRED_SIZE)))
.addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
); );
layout.setVerticalGroup( layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup() .addGroup(layout.createSequentialGroup()
.addContainerGap()
.addComponent(allDataSourcesRadioButton) .addComponent(allDataSourcesRadioButton)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(withinDataSourceRadioButton) .addComponent(withinDataSourceRadioButton)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(selectDataSourceComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addComponent(selectDataSourceComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
.addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
); );
}// </editor-fold>//GEN-END:initComponents }// </editor-fold>//GEN-END:initComponents
private void allDataSourcesRadioButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_allDataSourcesRadioButtonActionPerformed private void allDataSourcesRadioButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_allDataSourcesRadioButtonActionPerformed
selectDataSourceComboBox.setEnabled(!allDataSourcesRadioButton.isSelected()); selectDataSourceComboBox.setEnabled(!allDataSourcesRadioButton.isSelected());
singleDataSource = false; singleDataSource = false;
this.parent.handleIntraCaseSearchCriteriaChanged();
}//GEN-LAST:event_allDataSourcesRadioButtonActionPerformed }//GEN-LAST:event_allDataSourcesRadioButtonActionPerformed
private void withinDataSourceRadioButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_withinDataSourceRadioButtonActionPerformed private void withinDataSourceRadioButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_withinDataSourceRadioButtonActionPerformed
withinDataSourceSelected(withinDataSourceRadioButton.isSelected()); withinDataSourceSelected(withinDataSourceRadioButton.isSelected());
this.parent.handleIntraCaseSearchCriteriaChanged();
}//GEN-LAST:event_withinDataSourceRadioButtonActionPerformed }//GEN-LAST:event_withinDataSourceRadioButtonActionPerformed
private void selectDataSourceComboBoxActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_selectDataSourceComboBoxActionPerformed private void selectDataSourceComboBoxActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_selectDataSourceComboBoxActionPerformed
@ -200,4 +215,20 @@ public class IntraCasePanel extends javax.swing.JPanel {
void setDataSourceMap(Map<Long, String> dataSourceMap) { void setDataSourceMap(Map<Long, String> dataSourceMap) {
this.dataSourceMap = dataSourceMap; this.dataSourceMap = dataSourceMap;
} }
@NbBundle.Messages({
"IntraCasePanel.areSearchCriteriaMet.message=Cannot run intra-case correlation search."
})
boolean areSearchCriteriaMet() {
if(this.dataSourceMap.isEmpty()){
this.errorMessage = Bundle.IntraCasePanel_areSearchCriteriaMet_message();
return false;
} else {
return true;
}
}
String getErrorMessage() {
return this.errorMessage;
}
} }