Merge branch 'develop' of https://github.com/sleuthkit/autopsy into 1916-L01Processor

This commit is contained in:
William Schaefer 2018-02-14 13:25:02 -05:00
commit 5254bdaefa
12 changed files with 859 additions and 514 deletions

View File

@ -38,8 +38,6 @@ FilesSetRulePanel.interesting.jLabel5.text=Enter information about files that yo
FilesSetRulePanel.ingest.jLabel5.text=Enter information about files that you want to run ingest on. FilesSetRulePanel.ingest.jLabel5.text=Enter information about files that you want to run ingest on.
FilesSetRulePanel.nameCheck.text=Name Pattern: FilesSetRulePanel.nameCheck.text=Name Pattern:
FilesSetRulePanel.pathCheck.text=Path Pattern: FilesSetRulePanel.pathCheck.text=Path Pattern:
FilesSetRulePanel.mimeCheck.text=MIME Type:
FilesSetRulePanel.fileSizeCheck.text=File Size:
FilesSetRulePanel.filesRadioButton.text=Files FilesSetRulePanel.filesRadioButton.text=Files
FilesSetRulePanel.dirsRadioButton.text=Directories FilesSetRulePanel.dirsRadioButton.text=Directories
FilesSetDefsPanel.interesting.setsListLabel.text=Rule Sets: FilesSetDefsPanel.interesting.setsListLabel.text=Rule Sets:
@ -79,3 +77,10 @@ FilesSetDefsPanel.ingoreUnallocCheckbox.text=Ignore Unallocated Space
FilesSetDefsPanel.ingoreUnallocCheckbox.toolTipText=Ignores unallocated space, such as deleted files. May run faster but produce less complete results. FilesSetDefsPanel.ingoreUnallocCheckbox.toolTipText=Ignores unallocated space, such as deleted files. May run faster but produce less complete results.
FilesSetDefsPanel.ingestWarningLabel.text=Ingest is ongoing, some settings will be unavailable until it finishes. FilesSetDefsPanel.ingestWarningLabel.text=Ingest is ongoing, some settings will be unavailable until it finishes.
FilesSetDefsPanel.allRadioButton.text=All FilesSetDefsPanel.allRadioButton.text=All
FilesSetRulePanel.dateCheck.text=Modified Within:
FilesSetRulePanel.fileSizeCheck.text=File Size:
FilesSetRulePanel.mimeCheck.text=MIME Type:
FilesSetDefsPanel.modifiedDateLabel.text=Modified Within:
FilesSetDefsPanel.daysIncludedTextField.text=
FilesSetDefsPanel.daysIncludedLabel.text=day(s)
FilesSetRulePanel.daysIncludedLabel.text=day(s)

View File

@ -1,7 +1,7 @@
/* /*
* Autopsy Forensic Browser * Autopsy Forensic Browser
* *
* Copyright 2011-2017 Basis Technology Corp. * Copyright 2011-2018 Basis Technology Corp.
* Contact: carrier <at> sleuthkit <dot> org * Contact: carrier <at> sleuthkit <dot> org
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
@ -25,6 +25,7 @@ import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.UUID; import java.util.UUID;
import java.util.regex.Pattern; import java.util.regex.Pattern;
import org.openide.util.NbBundle;
import org.sleuthkit.datamodel.AbstractFile; import org.sleuthkit.datamodel.AbstractFile;
import org.sleuthkit.datamodel.TskData; import org.sleuthkit.datamodel.TskData;
@ -169,6 +170,7 @@ public final class FilesSet implements Serializable {
private final ParentPathCondition pathCondition; private final ParentPathCondition pathCondition;
private final MimeTypeCondition mimeTypeCondition; private final MimeTypeCondition mimeTypeCondition;
private final FileSizeCondition fileSizeCondition; private final FileSizeCondition fileSizeCondition;
private final DateCondition dateCondition;
private final List<FileAttributeCondition> conditions = new ArrayList<>(); private final List<FileAttributeCondition> conditions = new ArrayList<>();
/** /**
@ -180,8 +182,10 @@ public final class FilesSet implements Serializable {
* @param pathCondition A file path condition, may be null. * @param pathCondition A file path condition, may be null.
* @param mimeTypeCondition A file mime type condition, may be null. * @param mimeTypeCondition A file mime type condition, may be null.
* @param fileSizeCondition A file size condition, may be null. * @param fileSizeCondition A file size condition, may be null.
* @param dateCondition A file date created or modified condition,
* may be null
*/ */
Rule(String ruleName, FileNameCondition fileNameCondition, MetaTypeCondition metaTypeCondition, ParentPathCondition pathCondition, MimeTypeCondition mimeTypeCondition, FileSizeCondition fileSizeCondition) { Rule(String ruleName, FileNameCondition fileNameCondition, MetaTypeCondition metaTypeCondition, ParentPathCondition pathCondition, MimeTypeCondition mimeTypeCondition, FileSizeCondition fileSizeCondition, DateCondition dateCondition) {
// since ruleName is optional, ruleUUID can be used to uniquely identify a rule. // since ruleName is optional, ruleUUID can be used to uniquely identify a rule.
this.uuid = UUID.randomUUID().toString(); this.uuid = UUID.randomUUID().toString();
if (metaTypeCondition == null) { if (metaTypeCondition == null) {
@ -216,6 +220,10 @@ public final class FilesSet implements Serializable {
if (this.pathCondition != null) { if (this.pathCondition != null) {
this.conditions.add(this.pathCondition); this.conditions.add(this.pathCondition);
} }
this.dateCondition = dateCondition;
if (this.dateCondition != null) {
this.conditions.add(this.dateCondition);
}
} }
/** /**
@ -254,6 +262,10 @@ public final class FilesSet implements Serializable {
return this.pathCondition; return this.pathCondition;
} }
DateCondition getDateCondition() {
return this.dateCondition;
}
/** /**
* Determines whether or not a file satisfies the rule. * Determines whether or not a file satisfies the rule.
* *
@ -270,6 +282,10 @@ public final class FilesSet implements Serializable {
return true; return true;
} }
@NbBundle.Messages({
"# {0} - daysIncluded",
"FilesSet.rule.dateRule.toString=(modified within {0} day(s))"
})
@Override @Override
public String toString() { public String toString() {
// This override is designed to provide a display name for use with // This override is designed to provide a display name for use with
@ -283,6 +299,8 @@ public final class FilesSet implements Serializable {
} else if (this.fileSizeCondition != null) { } else if (this.fileSizeCondition != null) {
return this.ruleName + " (" + fileSizeCondition.getComparator().getSymbol() + " " + fileSizeCondition.getSizeValue() return this.ruleName + " (" + fileSizeCondition.getComparator().getSymbol() + " " + fileSizeCondition.getSizeValue()
+ " " + fileSizeCondition.getUnit().getName() + ")"; + " " + fileSizeCondition.getUnit().getName() + ")";
} else if (this.dateCondition != null) {
return this.ruleName + Bundle.FilesSet_rule_dateRule_toString(dateCondition.getDaysIncluded());
} else { } else {
return this.ruleName + " ()"; return this.ruleName + " ()";
} }
@ -537,7 +555,7 @@ public final class FilesSet implements Serializable {
case FILES: case FILES:
return file.isFile(); return file.isFile();
case DIRECTORIES: case DIRECTORIES:
return file.getMetaType() == TskData.TSK_FS_META_TYPE_ENUM.TSK_FS_META_TYPE_DIR return file.getMetaType() == TskData.TSK_FS_META_TYPE_ENUM.TSK_FS_META_TYPE_DIR
|| file.getMetaType() == TskData.TSK_FS_META_TYPE_ENUM.TSK_FS_META_TYPE_VIRT_DIR; || file.getMetaType() == TskData.TSK_FS_META_TYPE_ENUM.TSK_FS_META_TYPE_VIRT_DIR;
case FILES_AND_DIRECTORIES: case FILES_AND_DIRECTORIES:
return file.getMetaType() == TskData.TSK_FS_META_TYPE_ENUM.TSK_FS_META_TYPE_REG return file.getMetaType() == TskData.TSK_FS_META_TYPE_ENUM.TSK_FS_META_TYPE_REG
@ -737,6 +755,46 @@ public final class FilesSet implements Serializable {
} }
/**
* A class for checking whether a file's creation or modification
* occured in a specific range of time
*/
static final class DateCondition implements FileAttributeCondition {
private final static long SECS_PER_DAY = 60 * 60 * 24;
private int daysIncluded;
/**
* Construct a new DateCondition
*
* @param days - files created or modified more recently than this
* number of days will pass
*/
DateCondition(int days) {
daysIncluded = days;
}
/**
* Get the number of days which this condition allows to pass
*
* @return integer value of the number days which will pass
*/
int getDaysIncluded() {
return daysIncluded;
}
@Override
public boolean passes(AbstractFile file) {
long dateThreshold = System.currentTimeMillis() / 1000 - daysIncluded * SECS_PER_DAY;
if (file.getCrtime() > dateThreshold || file.getMtime() > dateThreshold) {
return true;
}
return false;
}
}
/** /**
* A file name extension condition for an interesting files set * A file name extension condition for an interesting files set
* membership rule. The immutability of a file name extension condition * membership rule. The immutability of a file name extension condition

View File

@ -90,109 +90,91 @@
</Group> </Group>
<EmptySpace min="-2" max="-2" attributes="0"/> <EmptySpace min="-2" max="-2" attributes="0"/>
<Component id="separator" min="-2" max="-2" attributes="0"/> <Component id="separator" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Group type="103" groupAlignment="0" attributes="0"> <Group type="103" groupAlignment="0" attributes="0">
<Group type="102" alignment="0" attributes="0">
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" alignment="0" attributes="0">
<EmptySpace min="-2" pref="101" max="-2" attributes="0"/>
<Component id="filesRadioButton" min="-2" pref="47" max="-2" attributes="0"/>
<EmptySpace type="unrelated" max="-2" attributes="0"/>
<Component id="dirsRadioButton" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="allRadioButton" min="-2" max="-2" attributes="0"/>
</Group>
<Group type="102" alignment="0" attributes="0">
<EmptySpace min="-2" pref="105" max="-2" attributes="0"/>
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" alignment="0" attributes="0">
<Component id="fileNameRadioButton" min="-2" max="-2" attributes="0"/>
<EmptySpace min="-2" pref="4" max="-2" attributes="0"/>
<Component id="fileNameExtensionRadioButton" min="-2" max="-2" attributes="0"/>
<EmptySpace type="unrelated" max="-2" attributes="0"/>
<Component id="fileNameRegexCheckbox" min="-2" max="-2" attributes="0"/>
</Group>
<Component id="rulePathConditionRegexCheckBox" alignment="0" min="-2" max="-2" attributes="0"/>
</Group>
</Group>
<Group type="102" alignment="0" attributes="0">
<EmptySpace min="-2" max="-2" attributes="0"/>
<Group type="103" groupAlignment="0" attributes="0">
<Component id="rulesListLabel" min="-2" max="-2" attributes="0"/>
<Component id="jLabel1" alignment="0" min="-2" max="-2" attributes="0"/>
<Group type="102" alignment="0" attributes="0">
<Component id="newRuleButton" min="-2" max="-2" attributes="0"/>
<EmptySpace type="separate" max="-2" attributes="0"/>
<Component id="editRuleButton" min="-2" max="-2" attributes="0"/>
<EmptySpace type="separate" max="-2" attributes="0"/>
<Component id="deleteRuleButton" min="-2" max="-2" attributes="0"/>
</Group>
<Group type="102" alignment="0" attributes="0">
<Component id="ignoreKnownFilesCheckbox" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="ingoreUnallocCheckbox" min="-2" pref="158" max="-2" attributes="0"/>
</Group>
<Group type="102" alignment="0" attributes="0">
<Group type="103" groupAlignment="0" attributes="0">
<Component id="jLabel5" alignment="0" min="-2" max="-2" attributes="0"/>
<Component id="jLabel6" alignment="0" min="-2" max="-2" attributes="0"/>
</Group>
<EmptySpace max="-2" attributes="0"/>
<Component id="ingestWarningLabel" min="-2" max="-2" attributes="0"/>
</Group>
</Group>
</Group>
</Group>
<EmptySpace min="24" pref="28" max="32767" attributes="0"/>
</Group>
<Group type="102" attributes="0"> <Group type="102" attributes="0">
<Group type="103" groupAlignment="0" attributes="0"> <Group type="103" groupAlignment="0" attributes="0">
<Component id="rulesListScrollPane" alignment="1" max="32767" attributes="0"/>
<Component id="setDescScrollPanel" alignment="1" max="32767" attributes="0"/>
<Group type="102" alignment="0" attributes="0"> <Group type="102" alignment="0" attributes="0">
<EmptySpace min="-2" pref="22" max="-2" attributes="0"/> <EmptySpace min="-2" pref="16" max="-2" attributes="0"/>
<Group type="103" groupAlignment="0" attributes="0"> <Group type="103" groupAlignment="0" max="-2" attributes="0">
<Group type="102" alignment="0" attributes="0"> <Component id="jLabel7" alignment="0" min="-2" max="-2" attributes="0"/>
<Group type="103" groupAlignment="0" attributes="0"> <Component id="jLabel8" alignment="0" min="-2" max="-2" attributes="0"/>
<Component id="jLabel7" alignment="0" min="-2" max="-2" attributes="0"/> <Component id="jLabel2" alignment="0" min="-2" max="-2" attributes="0"/>
<Component id="jLabel8" alignment="0" min="-2" max="-2" attributes="0"/> <Component id="jLabel4" alignment="0" min="-2" max="-2" attributes="0"/>
</Group> <Component id="modifiedDateLabel" alignment="0" max="32767" attributes="0"/>
<EmptySpace type="separate" max="-2" attributes="0"/> <Component id="jLabel3" alignment="0" max="32767" attributes="0"/>
</Group>
<Group type="103" alignment="0" groupAlignment="0" attributes="0">
<Group type="102" alignment="0" attributes="0">
<Group type="103" groupAlignment="0" attributes="0">
<Component id="jLabel3" alignment="0" min="-2" max="-2" attributes="0"/>
<Component id="jLabel2" alignment="0" min="-2" max="-2" attributes="0"/>
</Group>
<EmptySpace min="-2" pref="6" max="-2" attributes="0"/>
</Group>
<Group type="102" alignment="1" attributes="0">
<Component id="jLabel4" min="-2" max="-2" attributes="0"/>
<EmptySpace type="unrelated" max="-2" attributes="0"/>
</Group>
</Group>
</Group> </Group>
<EmptySpace type="unrelated" max="-2" attributes="0"/>
<Group type="103" groupAlignment="0" attributes="0"> <Group type="103" groupAlignment="0" attributes="0">
<Group type="102" alignment="0" attributes="0">
<Component id="equalitySignComboBox" min="-2" pref="44" max="-2" attributes="0"/>
<EmptySpace min="-2" max="-2" attributes="0"/>
<Component id="fileSizeSpinner" max="32767" attributes="0"/>
<EmptySpace min="-2" max="-2" attributes="0"/>
<Component id="fileSizeUnitComboBox" min="-2" pref="79" max="-2" attributes="0"/>
</Group>
<Component id="rulePathConditionTextField" alignment="0" max="32767" attributes="0"/> <Component id="rulePathConditionTextField" alignment="0" max="32767" attributes="0"/>
<Component id="fileNameTextField" alignment="1" max="32767" attributes="0"/> <Component id="fileNameTextField" alignment="1" max="32767" attributes="0"/>
<Component id="mimeTypeComboBox" alignment="0" max="32767" attributes="0"/> <Component id="mimeTypeComboBox" alignment="0" max="32767" attributes="0"/>
</Group> <Group type="102" alignment="0" attributes="0">
</Group> <Component id="equalitySignComboBox" min="-2" pref="60" max="-2" attributes="0"/>
<Group type="102" alignment="1" attributes="0"> <EmptySpace max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/> <Component id="fileSizeSpinner" max="32767" attributes="0"/>
<Group type="103" groupAlignment="0" attributes="0"> <EmptySpace max="-2" attributes="0"/>
<Component id="rulesListScrollPane" alignment="1" max="32767" attributes="0"/> <Component id="fileSizeUnitComboBox" min="-2" pref="79" max="-2" attributes="0"/>
<Component id="setDescScrollPanel" alignment="1" max="32767" attributes="0"/> </Group>
<Group type="102" attributes="0">
<Group type="103" groupAlignment="0" attributes="0">
<Component id="fileNameRadioButton" min="-2" max="-2" attributes="0"/>
<Component id="rulePathConditionRegexCheckBox" min="-2" max="-2" attributes="0"/>
<Group type="102" attributes="0">
<Component id="daysIncludedTextField" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="daysIncludedLabel" min="-2" max="-2" attributes="0"/>
</Group>
<Group type="102" attributes="0">
<Component id="filesRadioButton" min="-2" pref="47" max="-2" attributes="0"/>
<EmptySpace type="unrelated" max="-2" attributes="0"/>
<Component id="dirsRadioButton" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="allRadioButton" min="-2" max="-2" attributes="0"/>
</Group>
</Group>
<EmptySpace min="0" pref="0" max="32767" attributes="0"/>
</Group>
</Group> </Group>
</Group> </Group>
</Group> </Group>
<EmptySpace min="-2" pref="8" max="-2" attributes="0"/> <EmptySpace min="-2" pref="8" max="-2" attributes="0"/>
</Group> </Group>
<Group type="102" attributes="0">
<Group type="103" groupAlignment="0" attributes="0">
<Component id="rulesListLabel" min="-2" max="-2" attributes="0"/>
<Group type="102" alignment="0" attributes="0">
<Component id="ignoreKnownFilesCheckbox" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="ingoreUnallocCheckbox" min="-2" pref="158" max="-2" attributes="0"/>
</Group>
<Group type="102" alignment="0" attributes="0">
<Group type="103" groupAlignment="0" attributes="0">
<Component id="jLabel5" alignment="0" min="-2" max="-2" attributes="0"/>
<Component id="jLabel6" alignment="0" min="-2" max="-2" attributes="0"/>
</Group>
<EmptySpace max="-2" attributes="0"/>
<Component id="ingestWarningLabel" min="-2" max="-2" attributes="0"/>
</Group>
<Group type="102" alignment="0" attributes="0">
<EmptySpace min="-2" pref="174" max="-2" attributes="0"/>
<Component id="fileNameExtensionRadioButton" min="-2" max="-2" attributes="0"/>
<EmptySpace type="unrelated" max="-2" attributes="0"/>
<Component id="fileNameRegexCheckbox" min="-2" max="-2" attributes="0"/>
</Group>
<Component id="jLabel1" alignment="0" min="-2" max="-2" attributes="0"/>
<Group type="102" alignment="0" attributes="0">
<Component id="newRuleButton" min="-2" max="-2" attributes="0"/>
<EmptySpace type="separate" max="-2" attributes="0"/>
<Component id="editRuleButton" min="-2" max="-2" attributes="0"/>
<EmptySpace type="separate" max="-2" attributes="0"/>
<Component id="deleteRuleButton" min="-2" max="-2" attributes="0"/>
</Group>
</Group>
<EmptySpace min="24" pref="28" max="32767" attributes="0"/>
</Group>
</Group> </Group>
</Group> </Group>
</Group> </Group>
@ -213,9 +195,9 @@
</Group> </Group>
<Component id="ingestWarningLabel" alignment="1" min="-2" max="-2" attributes="0"/> <Component id="ingestWarningLabel" alignment="1" min="-2" max="-2" attributes="0"/>
</Group> </Group>
<EmptySpace max="-2" attributes="0"/> <EmptySpace min="-2" max="-2" attributes="0"/>
<Component id="setDescScrollPanel" min="-2" pref="45" max="-2" attributes="0"/> <Component id="setDescScrollPanel" pref="69" max="32767" attributes="0"/>
<EmptySpace min="-2" pref="6" max="-2" attributes="0"/> <EmptySpace min="-2" max="-2" attributes="0"/>
<Group type="103" groupAlignment="3" attributes="0"> <Group type="103" groupAlignment="3" attributes="0">
<Component id="ignoreKnownFilesCheckbox" alignment="3" min="-2" max="-2" attributes="0"/> <Component id="ignoreKnownFilesCheckbox" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="ingoreUnallocCheckbox" alignment="3" min="-2" pref="23" max="-2" attributes="0"/> <Component id="ingoreUnallocCheckbox" alignment="3" min="-2" pref="23" max="-2" attributes="0"/>
@ -223,7 +205,7 @@
<EmptySpace type="unrelated" min="-2" max="-2" attributes="0"/> <EmptySpace type="unrelated" min="-2" max="-2" attributes="0"/>
<Component id="rulesListLabel" min="-2" max="-2" attributes="0"/> <Component id="rulesListLabel" min="-2" max="-2" attributes="0"/>
<EmptySpace min="-2" max="-2" attributes="0"/> <EmptySpace min="-2" max="-2" attributes="0"/>
<Component id="rulesListScrollPane" pref="82" max="32767" attributes="0"/> <Component id="rulesListScrollPane" pref="61" max="32767" attributes="0"/>
<EmptySpace min="-2" max="-2" attributes="0"/> <EmptySpace min="-2" max="-2" attributes="0"/>
<Group type="103" groupAlignment="3" attributes="0"> <Group type="103" groupAlignment="3" attributes="0">
<Component id="newRuleButton" linkSize="2" alignment="3" min="-2" max="-2" attributes="0"/> <Component id="newRuleButton" linkSize="2" alignment="3" min="-2" max="-2" attributes="0"/>
@ -232,14 +214,14 @@
</Group> </Group>
<EmptySpace min="-2" max="-2" attributes="0"/> <EmptySpace min="-2" max="-2" attributes="0"/>
<Component id="jLabel1" min="-2" max="-2" attributes="0"/> <Component id="jLabel1" min="-2" max="-2" attributes="0"/>
<EmptySpace min="-2" pref="8" max="-2" attributes="0"/> <EmptySpace min="-2" max="-2" attributes="0"/>
<Group type="103" groupAlignment="3" attributes="0"> <Group type="103" groupAlignment="3" attributes="0">
<Component id="jLabel2" alignment="3" min="-2" max="-2" attributes="0"/> <Component id="jLabel2" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="filesRadioButton" alignment="3" min="-2" max="-2" attributes="0"/> <Component id="filesRadioButton" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="dirsRadioButton" alignment="3" min="-2" max="-2" attributes="0"/> <Component id="dirsRadioButton" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="allRadioButton" alignment="3" min="-2" max="-2" attributes="0"/> <Component id="allRadioButton" alignment="3" min="-2" max="-2" attributes="0"/>
</Group> </Group>
<EmptySpace min="-2" pref="8" max="-2" attributes="0"/> <EmptySpace min="-2" max="-2" attributes="0"/>
<Group type="103" groupAlignment="3" attributes="0"> <Group type="103" groupAlignment="3" attributes="0">
<Component id="jLabel3" alignment="3" min="-2" max="-2" attributes="0"/> <Component id="jLabel3" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="fileNameTextField" alignment="3" min="-2" pref="20" max="-2" attributes="0"/> <Component id="fileNameTextField" alignment="3" min="-2" pref="20" max="-2" attributes="0"/>
@ -250,26 +232,32 @@
<Component id="fileNameExtensionRadioButton" alignment="3" min="-2" max="-2" attributes="0"/> <Component id="fileNameExtensionRadioButton" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="fileNameRegexCheckbox" alignment="3" min="-2" max="-2" attributes="0"/> <Component id="fileNameRegexCheckbox" alignment="3" min="-2" max="-2" attributes="0"/>
</Group> </Group>
<EmptySpace min="-2" pref="8" max="-2" attributes="0"/> <EmptySpace min="-2" max="-2" attributes="0"/>
<Group type="103" groupAlignment="3" attributes="0"> <Group type="103" groupAlignment="3" attributes="0">
<Component id="jLabel4" alignment="3" min="-2" max="-2" attributes="0"/> <Component id="jLabel4" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="rulePathConditionTextField" alignment="3" min="-2" pref="20" max="-2" attributes="0"/> <Component id="rulePathConditionTextField" alignment="3" min="-2" pref="20" max="-2" attributes="0"/>
</Group> </Group>
<EmptySpace min="-2" pref="6" max="-2" attributes="0"/> <EmptySpace min="-2" max="-2" attributes="0"/>
<Component id="rulePathConditionRegexCheckBox" min="-2" max="-2" attributes="0"/> <Component id="rulePathConditionRegexCheckBox" min="-2" max="-2" attributes="0"/>
<EmptySpace type="unrelated" min="-2" max="-2" attributes="0"/> <EmptySpace min="-2" max="-2" attributes="0"/>
<Group type="103" groupAlignment="3" attributes="0"> <Group type="103" groupAlignment="3" attributes="0">
<Component id="jLabel7" alignment="3" min="-2" max="-2" attributes="0"/> <Component id="jLabel7" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="mimeTypeComboBox" alignment="3" min="-2" max="-2" attributes="0"/> <Component id="mimeTypeComboBox" alignment="3" min="-2" max="-2" attributes="0"/>
</Group> </Group>
<EmptySpace type="unrelated" min="-2" max="-2" attributes="0"/> <EmptySpace min="-2" max="-2" attributes="0"/>
<Group type="103" groupAlignment="3" attributes="0"> <Group type="103" groupAlignment="3" attributes="0">
<Component id="jLabel8" alignment="3" min="-2" max="-2" attributes="0"/> <Component id="jLabel8" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="equalitySignComboBox" alignment="3" min="-2" max="-2" attributes="0"/> <Component id="equalitySignComboBox" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="fileSizeSpinner" alignment="3" min="-2" max="-2" attributes="0"/> <Component id="fileSizeSpinner" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="fileSizeUnitComboBox" alignment="3" min="-2" max="-2" attributes="0"/> <Component id="fileSizeUnitComboBox" alignment="3" min="-2" max="-2" attributes="0"/>
</Group> </Group>
<EmptySpace min="-2" pref="5" max="-2" attributes="0"/> <EmptySpace min="-2" max="-2" attributes="0"/>
<Group type="103" groupAlignment="3" attributes="0">
<Component id="modifiedDateLabel" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="daysIncludedTextField" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="daysIncludedLabel" alignment="3" min="-2" max="-2" attributes="0"/>
</Group>
<EmptySpace min="-2" max="-2" attributes="0"/>
</Group> </Group>
<Group type="102" attributes="0"> <Group type="102" attributes="0">
<Component id="jScrollPane2" min="-2" max="-2" attributes="0"/> <Component id="jScrollPane2" min="-2" max="-2" attributes="0"/>
@ -437,7 +425,7 @@
</FontInfo> </FontInfo>
</Property> </Property>
<Property name="lineWrap" type="boolean" value="true"/> <Property name="lineWrap" type="boolean" value="true"/>
<Property name="rows" type="int" value="10"/> <Property name="rows" type="int" value="6"/>
<Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> <Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[10, 22]"/> <Dimension value="[10, 22]"/>
</Property> </Property>
@ -996,6 +984,36 @@
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="exportSetButtonActionPerformed"/> <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="exportSetButtonActionPerformed"/>
</Events> </Events>
</Component> </Component>
<Component class="javax.swing.JLabel" name="modifiedDateLabel">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/modules/interestingitems/Bundle.properties" key="FilesSetDefsPanel.modifiedDateLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
</Component>
<Component class="javax.swing.JTextField" name="daysIncludedTextField">
<Properties>
<Property name="editable" type="boolean" value="false"/>
<Property name="horizontalAlignment" type="int" value="11"/>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/modules/interestingitems/Bundle.properties" key="FilesSetDefsPanel.daysIncludedTextField.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
<Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[60, 20]"/>
</Property>
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[60, 20]"/>
</Property>
</Properties>
</Component>
<Component class="javax.swing.JLabel" name="daysIncludedLabel">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/modules/interestingitems/Bundle.properties" key="FilesSetDefsPanel.daysIncludedLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
<Property name="enabled" type="boolean" value="false"/>
</Properties>
</Component>
</SubComponents> </SubComponents>
</Container> </Container>
</SubComponents> </SubComponents>

View File

@ -1,7 +1,7 @@
/* /*
* Autopsy Forensic Browser * Autopsy Forensic Browser
* *
* Copyright 2011-2017 Basis Technology Corp. * Copyright 2011-2018 Basis Technology Corp.
* Contact: carrier <at> sleuthkit <dot> org * Contact: carrier <at> sleuthkit <dot> org
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
@ -251,6 +251,7 @@ public final class FilesSetDefsPanel extends IngestModuleGlobalSettingsPanel imp
this.fileNameRegexCheckbox.setSelected(false); this.fileNameRegexCheckbox.setSelected(false);
this.filesRadioButton.setSelected(true); this.filesRadioButton.setSelected(true);
this.rulePathConditionTextField.setText(""); this.rulePathConditionTextField.setText("");
this.daysIncludedTextField.setText("");
this.rulePathConditionRegexCheckBox.setSelected(false); this.rulePathConditionRegexCheckBox.setSelected(false);
this.mimeTypeComboBox.setSelectedIndex(0); this.mimeTypeComboBox.setSelectedIndex(0);
this.equalitySignComboBox.setSelectedIndex(2); this.equalitySignComboBox.setSelectedIndex(2);
@ -326,7 +327,7 @@ public final class FilesSetDefsPanel extends IngestModuleGlobalSettingsPanel imp
FilesSet.Rule.ParentPathCondition pathCondition = rule.getPathCondition(); FilesSet.Rule.ParentPathCondition pathCondition = rule.getPathCondition();
FilesSet.Rule.MimeTypeCondition mimeTypeCondition = rule.getMimeTypeCondition(); FilesSet.Rule.MimeTypeCondition mimeTypeCondition = rule.getMimeTypeCondition();
FilesSet.Rule.FileSizeCondition fileSizeCondition = rule.getFileSizeCondition(); FilesSet.Rule.FileSizeCondition fileSizeCondition = rule.getFileSizeCondition();
FilesSet.Rule.DateCondition dateCondition = rule.getDateCondition();
// Populate the components that display the properties of the // Populate the components that display the properties of the
// selected rule. // selected rule.
if (nameCondition != null) { if (nameCondition != null) {
@ -372,7 +373,12 @@ public final class FilesSetDefsPanel extends IngestModuleGlobalSettingsPanel imp
FilesSetDefsPanel.this.equalitySignComboBox.setSelectedIndex(2); FilesSetDefsPanel.this.equalitySignComboBox.setSelectedIndex(2);
FilesSetDefsPanel.this.fileSizeSpinner.setValue(0); FilesSetDefsPanel.this.fileSizeSpinner.setValue(0);
} }
if (dateCondition != null){
FilesSetDefsPanel.this.daysIncludedTextField.setText(Integer.toString(dateCondition.getDaysIncluded()));
}
else {
FilesSetDefsPanel.this.daysIncludedTextField.setText("");
}
// Enable the new, edit and delete rule buttons. // Enable the new, edit and delete rule buttons.
FilesSetDefsPanel.this.newRuleButton.setEnabled(true && canBeEnabled); FilesSetDefsPanel.this.newRuleButton.setEnabled(true && canBeEnabled);
FilesSetDefsPanel.this.editRuleButton.setEnabled(true && canBeEnabled); FilesSetDefsPanel.this.editRuleButton.setEnabled(true && canBeEnabled);
@ -477,7 +483,7 @@ public final class FilesSetDefsPanel extends IngestModuleGlobalSettingsPanel imp
if (selectedRule != null) { if (selectedRule != null) {
rules.remove(selectedRule.getUuid()); rules.remove(selectedRule.getUuid());
} }
FilesSet.Rule newRule = new FilesSet.Rule(panel.getRuleName(), panel.getFileNameCondition(), panel.getMetaTypeCondition(), panel.getPathCondition(), panel.getMimeTypeCondition(), panel.getFileSizeCondition()); FilesSet.Rule newRule = new FilesSet.Rule(panel.getRuleName(), panel.getFileNameCondition(), panel.getMetaTypeCondition(), panel.getPathCondition(), panel.getMimeTypeCondition(), panel.getFileSizeCondition(), panel.getDateCondition());
rules.put(newRule.getUuid(), newRule); rules.put(newRule.getUuid(), newRule);
// Add the new/edited files set definition, replacing any previous // Add the new/edited files set definition, replacing any previous
@ -590,6 +596,9 @@ public final class FilesSetDefsPanel extends IngestModuleGlobalSettingsPanel imp
copySetButton = new javax.swing.JButton(); copySetButton = new javax.swing.JButton();
importSetButton = new javax.swing.JButton(); importSetButton = new javax.swing.JButton();
exportSetButton = new javax.swing.JButton(); exportSetButton = new javax.swing.JButton();
modifiedDateLabel = new javax.swing.JLabel();
daysIncludedTextField = new javax.swing.JTextField();
daysIncludedLabel = new javax.swing.JLabel();
setFont(getFont().deriveFont(getFont().getStyle() & ~java.awt.Font.BOLD, 11)); setFont(getFont().deriveFont(getFont().getStyle() & ~java.awt.Font.BOLD, 11));
@ -643,7 +652,7 @@ public final class FilesSetDefsPanel extends IngestModuleGlobalSettingsPanel imp
setDescriptionTextArea.setColumns(20); setDescriptionTextArea.setColumns(20);
setDescriptionTextArea.setFont(setDescriptionTextArea.getFont().deriveFont(setDescriptionTextArea.getFont().getStyle() & ~java.awt.Font.BOLD, 13)); setDescriptionTextArea.setFont(setDescriptionTextArea.getFont().deriveFont(setDescriptionTextArea.getFont().getStyle() & ~java.awt.Font.BOLD, 13));
setDescriptionTextArea.setLineWrap(true); setDescriptionTextArea.setLineWrap(true);
setDescriptionTextArea.setRows(10); setDescriptionTextArea.setRows(6);
setDescriptionTextArea.setMinimumSize(new java.awt.Dimension(10, 22)); setDescriptionTextArea.setMinimumSize(new java.awt.Dimension(10, 22));
setDescScrollPanel.setViewportView(setDescriptionTextArea); setDescScrollPanel.setViewportView(setDescriptionTextArea);
@ -841,6 +850,17 @@ public final class FilesSetDefsPanel extends IngestModuleGlobalSettingsPanel imp
} }
}); });
org.openide.awt.Mnemonics.setLocalizedText(modifiedDateLabel, org.openide.util.NbBundle.getMessage(FilesSetDefsPanel.class, "FilesSetDefsPanel.modifiedDateLabel.text")); // NOI18N
daysIncludedTextField.setEditable(false);
daysIncludedTextField.setHorizontalAlignment(javax.swing.JTextField.TRAILING);
daysIncludedTextField.setText(org.openide.util.NbBundle.getMessage(FilesSetDefsPanel.class, "FilesSetDefsPanel.daysIncludedTextField.text")); // NOI18N
daysIncludedTextField.setMinimumSize(new java.awt.Dimension(60, 20));
daysIncludedTextField.setPreferredSize(new java.awt.Dimension(60, 20));
org.openide.awt.Mnemonics.setLocalizedText(daysIncludedLabel, org.openide.util.NbBundle.getMessage(FilesSetDefsPanel.class, "FilesSetDefsPanel.daysIncludedLabel.text")); // NOI18N
daysIncludedLabel.setEnabled(false);
javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1); javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1);
jPanel1.setLayout(jPanel1Layout); jPanel1.setLayout(jPanel1Layout);
jPanel1Layout.setHorizontalGroup( jPanel1Layout.setHorizontalGroup(
@ -867,83 +887,74 @@ public final class FilesSetDefsPanel extends IngestModuleGlobalSettingsPanel imp
.addComponent(setsListLabel)) .addComponent(setsListLabel))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(separator, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addComponent(separator, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(jPanel1Layout.createSequentialGroup() .addGroup(jPanel1Layout.createSequentialGroup()
.addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(rulesListScrollPane, javax.swing.GroupLayout.Alignment.TRAILING)
.addComponent(setDescScrollPanel, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addGroup(jPanel1Layout.createSequentialGroup() .addGroup(jPanel1Layout.createSequentialGroup()
.addGap(101, 101, 101) .addGap(16, 16, 16)
.addComponent(filesRadioButton, javax.swing.GroupLayout.PREFERRED_SIZE, 47, javax.swing.GroupLayout.PREFERRED_SIZE) .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
.addComponent(jLabel7)
.addComponent(jLabel8)
.addComponent(jLabel2)
.addComponent(jLabel4)
.addComponent(modifiedDateLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addComponent(jLabel3, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
.addComponent(dirsRadioButton)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(allRadioButton))
.addGroup(jPanel1Layout.createSequentialGroup()
.addGap(105, 105, 105)
.addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(rulePathConditionTextField)
.addComponent(fileNameTextField, javax.swing.GroupLayout.Alignment.TRAILING)
.addComponent(mimeTypeComboBox, 0, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addGroup(jPanel1Layout.createSequentialGroup() .addGroup(jPanel1Layout.createSequentialGroup()
.addComponent(fileNameRadioButton) .addComponent(equalitySignComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, 60, javax.swing.GroupLayout.PREFERRED_SIZE)
.addGap(4, 4, 4)
.addComponent(fileNameExtensionRadioButton)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
.addComponent(fileNameRegexCheckbox))
.addComponent(rulePathConditionRegexCheckBox)))
.addGroup(jPanel1Layout.createSequentialGroup()
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(rulesListLabel)
.addComponent(jLabel1)
.addGroup(jPanel1Layout.createSequentialGroup()
.addComponent(newRuleButton)
.addGap(18, 18, 18)
.addComponent(editRuleButton)
.addGap(18, 18, 18)
.addComponent(deleteRuleButton))
.addGroup(jPanel1Layout.createSequentialGroup()
.addComponent(ignoreKnownFilesCheckbox)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(ingoreUnallocCheckbox, javax.swing.GroupLayout.PREFERRED_SIZE, 158, javax.swing.GroupLayout.PREFERRED_SIZE))
.addGroup(jPanel1Layout.createSequentialGroup()
.addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(jLabel5)
.addComponent(jLabel6))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(ingestWarningLabel)))))
.addGap(24, 28, Short.MAX_VALUE))
.addGroup(jPanel1Layout.createSequentialGroup()
.addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(jPanel1Layout.createSequentialGroup()
.addGap(22, 22, 22)
.addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(jPanel1Layout.createSequentialGroup()
.addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(jLabel7)
.addComponent(jLabel8))
.addGap(18, 18, 18))
.addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(jPanel1Layout.createSequentialGroup()
.addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(jLabel3)
.addComponent(jLabel2))
.addGap(6, 6, 6))
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel1Layout.createSequentialGroup()
.addComponent(jLabel4)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED))))
.addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(jPanel1Layout.createSequentialGroup()
.addComponent(equalitySignComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, 44, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(fileSizeSpinner, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addComponent(fileSizeSpinner, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(fileSizeUnitComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, 79, javax.swing.GroupLayout.PREFERRED_SIZE)) .addComponent(fileSizeUnitComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, 79, javax.swing.GroupLayout.PREFERRED_SIZE))
.addComponent(rulePathConditionTextField) .addGroup(jPanel1Layout.createSequentialGroup()
.addComponent(fileNameTextField, javax.swing.GroupLayout.Alignment.TRAILING) .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(mimeTypeComboBox, 0, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))) .addComponent(fileNameRadioButton)
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel1Layout.createSequentialGroup() .addComponent(rulePathConditionRegexCheckBox)
.addGroup(jPanel1Layout.createSequentialGroup()
.addComponent(daysIncludedTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(daysIncludedLabel))
.addGroup(jPanel1Layout.createSequentialGroup()
.addComponent(filesRadioButton, javax.swing.GroupLayout.PREFERRED_SIZE, 47, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
.addComponent(dirsRadioButton)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(allRadioButton)))
.addGap(0, 0, Short.MAX_VALUE)))))
.addGap(8, 8, 8))
.addGroup(jPanel1Layout.createSequentialGroup()
.addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(rulesListLabel)
.addGroup(jPanel1Layout.createSequentialGroup()
.addComponent(ignoreKnownFilesCheckbox)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(ingoreUnallocCheckbox, javax.swing.GroupLayout.PREFERRED_SIZE, 158, javax.swing.GroupLayout.PREFERRED_SIZE))
.addGroup(jPanel1Layout.createSequentialGroup()
.addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(rulesListScrollPane, javax.swing.GroupLayout.Alignment.TRAILING) .addComponent(jLabel5)
.addComponent(setDescScrollPanel, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)))) .addComponent(jLabel6))
.addGap(8, 8, 8)))) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(ingestWarningLabel))
.addGroup(jPanel1Layout.createSequentialGroup()
.addGap(174, 174, 174)
.addComponent(fileNameExtensionRadioButton)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
.addComponent(fileNameRegexCheckbox))
.addComponent(jLabel1)
.addGroup(jPanel1Layout.createSequentialGroup()
.addComponent(newRuleButton)
.addGap(18, 18, 18)
.addComponent(editRuleButton)
.addGap(18, 18, 18)
.addComponent(deleteRuleButton)))
.addGap(24, 28, Short.MAX_VALUE))))
); );
jPanel1Layout.linkSize(javax.swing.SwingConstants.HORIZONTAL, new java.awt.Component[] {copySetButton, deleteSetButton, editSetButton, exportSetButton, importSetButton, newSetButton}); jPanel1Layout.linkSize(javax.swing.SwingConstants.HORIZONTAL, new java.awt.Component[] {copySetButton, deleteSetButton, editSetButton, exportSetButton, importSetButton, newSetButton});
@ -963,15 +974,15 @@ public final class FilesSetDefsPanel extends IngestModuleGlobalSettingsPanel imp
.addGap(1, 1, 1)) .addGap(1, 1, 1))
.addComponent(ingestWarningLabel, javax.swing.GroupLayout.Alignment.TRAILING)) .addComponent(ingestWarningLabel, javax.swing.GroupLayout.Alignment.TRAILING))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(setDescScrollPanel, javax.swing.GroupLayout.PREFERRED_SIZE, 45, javax.swing.GroupLayout.PREFERRED_SIZE) .addComponent(setDescScrollPanel, javax.swing.GroupLayout.DEFAULT_SIZE, 69, Short.MAX_VALUE)
.addGap(6, 6, 6) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(ignoreKnownFilesCheckbox) .addComponent(ignoreKnownFilesCheckbox)
.addComponent(ingoreUnallocCheckbox, javax.swing.GroupLayout.PREFERRED_SIZE, 23, javax.swing.GroupLayout.PREFERRED_SIZE)) .addComponent(ingoreUnallocCheckbox, javax.swing.GroupLayout.PREFERRED_SIZE, 23, javax.swing.GroupLayout.PREFERRED_SIZE))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
.addComponent(rulesListLabel) .addComponent(rulesListLabel)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(rulesListScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, 82, Short.MAX_VALUE) .addComponent(rulesListScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, 61, Short.MAX_VALUE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(newRuleButton) .addComponent(newRuleButton)
@ -979,13 +990,13 @@ public final class FilesSetDefsPanel extends IngestModuleGlobalSettingsPanel imp
.addComponent(deleteRuleButton)) .addComponent(deleteRuleButton))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(jLabel1) .addComponent(jLabel1)
.addGap(8, 8, 8) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(jLabel2) .addComponent(jLabel2)
.addComponent(filesRadioButton) .addComponent(filesRadioButton)
.addComponent(dirsRadioButton) .addComponent(dirsRadioButton)
.addComponent(allRadioButton)) .addComponent(allRadioButton))
.addGap(8, 8, 8) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(jLabel3) .addComponent(jLabel3)
.addComponent(fileNameTextField, javax.swing.GroupLayout.PREFERRED_SIZE, 20, javax.swing.GroupLayout.PREFERRED_SIZE)) .addComponent(fileNameTextField, javax.swing.GroupLayout.PREFERRED_SIZE, 20, javax.swing.GroupLayout.PREFERRED_SIZE))
@ -994,23 +1005,28 @@ public final class FilesSetDefsPanel extends IngestModuleGlobalSettingsPanel imp
.addComponent(fileNameRadioButton) .addComponent(fileNameRadioButton)
.addComponent(fileNameExtensionRadioButton) .addComponent(fileNameExtensionRadioButton)
.addComponent(fileNameRegexCheckbox)) .addComponent(fileNameRegexCheckbox))
.addGap(8, 8, 8) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(jLabel4) .addComponent(jLabel4)
.addComponent(rulePathConditionTextField, javax.swing.GroupLayout.PREFERRED_SIZE, 20, javax.swing.GroupLayout.PREFERRED_SIZE)) .addComponent(rulePathConditionTextField, javax.swing.GroupLayout.PREFERRED_SIZE, 20, javax.swing.GroupLayout.PREFERRED_SIZE))
.addGap(6, 6, 6) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(rulePathConditionRegexCheckBox) .addComponent(rulePathConditionRegexCheckBox)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(jLabel7) .addComponent(jLabel7)
.addComponent(mimeTypeComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) .addComponent(mimeTypeComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(jLabel8) .addComponent(jLabel8)
.addComponent(equalitySignComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addComponent(equalitySignComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(fileSizeSpinner, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addComponent(fileSizeSpinner, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(fileSizeUnitComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) .addComponent(fileSizeUnitComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
.addGap(5, 5, 5)) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(modifiedDateLabel)
.addComponent(daysIncludedTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(daysIncludedLabel))
.addContainerGap())
.addGroup(jPanel1Layout.createSequentialGroup() .addGroup(jPanel1Layout.createSequentialGroup()
.addComponent(jScrollPane2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addComponent(jScrollPane2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
@ -1262,6 +1278,8 @@ public final class FilesSetDefsPanel extends IngestModuleGlobalSettingsPanel imp
// Variables declaration - do not modify//GEN-BEGIN:variables // Variables declaration - do not modify//GEN-BEGIN:variables
private javax.swing.JRadioButton allRadioButton; private javax.swing.JRadioButton allRadioButton;
private javax.swing.JButton copySetButton; private javax.swing.JButton copySetButton;
private javax.swing.JLabel daysIncludedLabel;
private javax.swing.JTextField daysIncludedTextField;
private javax.swing.JButton deleteRuleButton; private javax.swing.JButton deleteRuleButton;
private javax.swing.JButton deleteSetButton; private javax.swing.JButton deleteSetButton;
private javax.swing.JRadioButton dirsRadioButton; private javax.swing.JRadioButton dirsRadioButton;
@ -1294,6 +1312,7 @@ public final class FilesSetDefsPanel extends IngestModuleGlobalSettingsPanel imp
private javax.swing.JScrollPane jScrollPane2; private javax.swing.JScrollPane jScrollPane2;
private javax.swing.JTextArea jTextArea1; private javax.swing.JTextArea jTextArea1;
private javax.swing.JComboBox<String> mimeTypeComboBox; private javax.swing.JComboBox<String> mimeTypeComboBox;
private javax.swing.JLabel modifiedDateLabel;
private javax.swing.JButton newRuleButton; private javax.swing.JButton newRuleButton;
private javax.swing.JButton newSetButton; private javax.swing.JButton newSetButton;
private javax.swing.JCheckBox rulePathConditionRegexCheckBox; private javax.swing.JCheckBox rulePathConditionRegexCheckBox;

View File

@ -23,82 +23,80 @@
<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">
<Group type="103" groupAlignment="1" attributes="0"> <Group type="103" groupAlignment="0" attributes="0">
<Group type="102" alignment="1" attributes="0"> <Group type="102" alignment="0" attributes="0">
<EmptySpace min="-2" pref="8" max="-2" attributes="0"/> <EmptySpace min="-2" pref="8" max="-2" attributes="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" alignment="1" attributes="0">
<Component id="ruleNameLabel" max="32767" attributes="0"/> <Component id="ruleNameLabel" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/> <EmptySpace min="-2" pref="5" max="-2" attributes="0"/>
<Component id="ruleNameTextField" min="-2" pref="234" max="-2" attributes="0"/> <Group type="103" groupAlignment="0" attributes="0">
</Group> <Component id="mimeTypeComboBox" alignment="0" max="32767" attributes="0"/>
<Group type="102" attributes="0"> <Component id="pathTextField" alignment="0" max="32767" attributes="0"/>
<Group type="102" alignment="1" attributes="0">
<Component id="equalitySymbolComboBox" max="32767" attributes="0"/>
<EmptySpace min="-2" max="-2" attributes="0"/>
<Component id="fileSizeSpinner" max="32767" attributes="0"/>
<EmptySpace min="-2" max="-2" attributes="0"/>
<Component id="fileSizeComboBox" max="32767" attributes="0"/>
</Group>
<Group type="102" alignment="0" attributes="0">
<Component id="pathRegexCheckBox" min="-2" max="-2" attributes="0"/>
<EmptySpace max="32767" attributes="0"/>
<Component id="pathSeparatorInfoLabel" min="-2" max="-2" attributes="0"/>
</Group>
<Group type="102" attributes="0">
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" attributes="0">
<Component id="daysIncludedTextField" min="-2" pref="69" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="daysIncludedLabel" min="-2" max="-2" attributes="0"/>
</Group>
<Component id="ruleNameTextField" pref="249" max="32767" attributes="0"/>
<Group type="102" alignment="0" attributes="0">
<Component id="fullNameRadioButton" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="extensionRadioButton" min="-2" pref="98" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="nameRegexCheckbox" min="-2" max="-2" attributes="0"/>
</Group>
</Group>
<EmptySpace min="-2" pref="1" max="-2" attributes="0"/>
</Group>
</Group>
</Group>
<Component id="jLabel5" min="-2" max="-2" attributes="0"/>
<Group type="102" alignment="0" attributes="0">
<Group type="103" groupAlignment="0" attributes="0">
<Component id="nameCheck" alignment="1" min="-2" pref="95" max="-2" attributes="0"/>
<Component id="jLabel1" alignment="0" min="-2" max="-2" attributes="0"/>
</Group>
<EmptySpace min="-2" pref="16" max="-2" attributes="0"/>
<Group type="103" groupAlignment="0" attributes="0"> <Group type="103" groupAlignment="0" attributes="0">
<Component id="jLabel5" min="-2" max="-2" attributes="0"/>
<Group type="102" attributes="0"> <Group type="102" attributes="0">
<Component id="jLabel1" min="-2" max="-2" attributes="0"/>
<EmptySpace min="-2" pref="65" max="-2" attributes="0"/>
<Component id="filesRadioButton" min="-2" max="-2" attributes="0"/> <Component id="filesRadioButton" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/> <EmptySpace max="-2" attributes="0"/>
<Component id="dirsRadioButton" min="-2" max="-2" attributes="0"/> <Component id="dirsRadioButton" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/> <EmptySpace max="-2" attributes="0"/>
<Component id="allRadioButton" min="-2" max="-2" attributes="0"/> <Component id="allRadioButton" min="-2" max="-2" attributes="0"/>
</Group> </Group>
<Component id="nameTextField" max="32767" attributes="0"/>
</Group> </Group>
<EmptySpace min="0" pref="0" max="32767" attributes="0"/>
</Group> </Group>
</Group> </Group>
</Group> </Group>
<Group type="102" alignment="1" attributes="0"> <Group type="102" attributes="0">
<EmptySpace max="-2" attributes="0"/>
<Component id="nameCheck" min="-2" max="-2" attributes="0"/>
<EmptySpace max="32767" attributes="0"/>
<Component id="nameTextField" min="-2" pref="249" max="-2" attributes="0"/>
</Group>
<Group type="102" alignment="0" attributes="0">
<EmptySpace max="-2" attributes="0"/>
<Component id="pathCheck" min="-2" max="-2" attributes="0"/>
<EmptySpace min="-2" pref="4" max="-2" attributes="0"/>
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" alignment="0" attributes="0">
<Component id="pathRegexCheckBox" min="-2" max="-2" attributes="0"/>
<EmptySpace max="32767" attributes="0"/>
<Component id="pathSeparatorInfoLabel" min="-2" max="-2" attributes="0"/>
</Group>
<Group type="102" alignment="1" attributes="0">
<EmptySpace min="0" pref="0" max="32767" attributes="0"/>
<Component id="pathTextField" min="-2" pref="250" max="-2" attributes="0"/>
</Group>
<Group type="102" alignment="0" attributes="0">
<Component id="fullNameRadioButton" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="extensionRadioButton" min="-2" pref="114" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="nameRegexCheckbox" min="-2" max="-2" attributes="0"/>
<EmptySpace min="0" pref="0" max="32767" attributes="0"/>
</Group>
</Group>
</Group>
<Group type="102" alignment="1" 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="pathCheck" alignment="0" min="-2" max="-2" attributes="0"/>
<Component id="mimeCheck" min="-2" max="-2" attributes="0"/> <Component id="mimeCheck" min="-2" max="-2" attributes="0"/>
<Component id="fileSizeCheck" alignment="0" min="-2" max="-2" attributes="0"/> <Component id="fileSizeCheck" alignment="0" min="-2" max="-2" attributes="0"/>
<Component id="dateCheck" alignment="0" min="-2" max="-2" attributes="0"/>
</Group> </Group>
<EmptySpace max="32767" attributes="0"/> <EmptySpace min="0" pref="0" max="32767" attributes="0"/>
<Group type="103" groupAlignment="1" attributes="0">
<Group type="102" alignment="1" attributes="0">
<Component id="equalitySymbolComboBox" min="-2" pref="36" max="-2" attributes="0"/>
<EmptySpace type="separate" max="-2" attributes="0"/>
<Component id="fileSizeSpinner" min="-2" pref="94" max="-2" attributes="0"/>
<EmptySpace type="separate" max="-2" attributes="0"/>
<Component id="fileSizeComboBox" min="-2" pref="82" max="-2" attributes="0"/>
</Group>
<Component id="mimeTypeComboBox" min="-2" pref="250" max="-2" attributes="0"/>
</Group>
</Group> </Group>
</Group> </Group>
<EmptySpace max="-2" attributes="0"/> <EmptySpace min="-2" max="-2" attributes="0"/>
</Group> </Group>
</Group> </Group>
</DimensionLayout> </DimensionLayout>
@ -106,17 +104,22 @@
<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">
<Component id="jLabel5" min="-2" max="-2" attributes="0"/> <Component id="jLabel5" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/> <EmptySpace min="-2" pref="3" max="-2" attributes="0"/>
<Group type="103" groupAlignment="3" attributes="0"> <Group type="103" groupAlignment="1" attributes="0">
<Component id="jLabel1" alignment="3" min="-2" max="-2" attributes="0"/> <Group type="102" alignment="1" attributes="0">
<Component id="filesRadioButton" alignment="3" min="-2" max="-2" attributes="0"/> <Component id="jLabel1" min="-2" max="-2" attributes="0"/>
<Component id="dirsRadioButton" alignment="3" min="-2" max="-2" attributes="0"/> <EmptySpace min="-2" pref="10" max="-2" attributes="0"/>
<Component id="allRadioButton" alignment="3" min="-2" max="-2" attributes="0"/> <Component id="nameCheck" min="-2" max="-2" attributes="0"/>
</Group> </Group>
<EmptySpace min="-2" pref="5" max="-2" attributes="0"/> <Group type="102" alignment="1" attributes="0">
<Group type="103" groupAlignment="3" attributes="0"> <Group type="103" groupAlignment="3" attributes="0">
<Component id="nameTextField" alignment="3" min="-2" pref="20" max="-2" attributes="0"/> <Component id="filesRadioButton" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="nameCheck" alignment="3" min="-2" max="-2" attributes="0"/> <Component id="dirsRadioButton" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="allRadioButton" alignment="3" min="-2" max="-2" attributes="0"/>
</Group>
<EmptySpace type="unrelated" max="-2" attributes="0"/>
<Component id="nameTextField" min="-2" pref="20" max="-2" attributes="0"/>
</Group>
</Group> </Group>
<EmptySpace max="-2" attributes="0"/> <EmptySpace max="-2" attributes="0"/>
<Group type="103" groupAlignment="3" attributes="0"> <Group type="103" groupAlignment="3" attributes="0">
@ -134,7 +137,7 @@
<Component id="pathRegexCheckBox" alignment="3" min="-2" max="-2" attributes="0"/> <Component id="pathRegexCheckBox" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="pathSeparatorInfoLabel" alignment="3" min="-2" max="-2" attributes="0"/> <Component id="pathSeparatorInfoLabel" alignment="3" min="-2" max="-2" attributes="0"/>
</Group> </Group>
<EmptySpace pref="8" max="32767" attributes="0"/> <EmptySpace type="unrelated" max="-2" attributes="0"/>
<Group type="103" groupAlignment="3" attributes="0"> <Group type="103" groupAlignment="3" attributes="0">
<Component id="mimeTypeComboBox" alignment="3" min="-2" max="-2" attributes="0"/> <Component id="mimeTypeComboBox" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="mimeCheck" alignment="3" min="-2" max="-2" attributes="0"/> <Component id="mimeCheck" alignment="3" min="-2" max="-2" attributes="0"/>
@ -146,7 +149,13 @@
<Component id="fileSizeSpinner" alignment="3" min="-2" max="-2" attributes="0"/> <Component id="fileSizeSpinner" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="fileSizeCheck" alignment="3" min="-2" max="-2" attributes="0"/> <Component id="fileSizeCheck" alignment="3" min="-2" max="-2" attributes="0"/>
</Group> </Group>
<EmptySpace min="-2" pref="15" max="-2" attributes="0"/> <EmptySpace type="unrelated" max="-2" attributes="0"/>
<Group type="103" groupAlignment="3" attributes="0">
<Component id="daysIncludedTextField" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="daysIncludedLabel" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="dateCheck" alignment="3" min="-2" max="-2" attributes="0"/>
</Group>
<EmptySpace type="unrelated" max="-2" attributes="0"/>
<Group type="103" groupAlignment="3" attributes="0"> <Group type="103" groupAlignment="3" attributes="0">
<Component id="ruleNameTextField" alignment="3" min="-2" max="-2" attributes="0"/> <Component id="ruleNameTextField" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="ruleNameLabel" alignment="3" max="32767" attributes="0"/> <Component id="ruleNameLabel" alignment="3" max="32767" attributes="0"/>
@ -170,9 +179,6 @@
<ResourceString bundle="org/sleuthkit/autopsy/modules/interestingitems/Bundle.properties" key="FilesSetRulePanel.ruleNameTextField.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/> <ResourceString bundle="org/sleuthkit/autopsy/modules/interestingitems/Bundle.properties" key="FilesSetRulePanel.ruleNameTextField.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property> </Property>
</Properties> </Properties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="ruleNameTextFieldActionPerformed"/>
</Events>
</Component> </Component>
<Component class="javax.swing.JLabel" name="jLabel1"> <Component class="javax.swing.JLabel" name="jLabel1">
<Properties> <Properties>
@ -380,5 +386,33 @@
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="allRadioButtonActionPerformed"/> <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="allRadioButtonActionPerformed"/>
</Events> </Events>
</Component> </Component>
<Component class="javax.swing.JTextField" name="daysIncludedTextField">
<Properties>
<Property name="enabled" type="boolean" value="false"/>
<Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[60, 20]"/>
</Property>
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[60, 20]"/>
</Property>
</Properties>
</Component>
<Component class="javax.swing.JLabel" name="daysIncludedLabel">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/modules/interestingitems/Bundle.properties" key="FilesSetRulePanel.daysIncludedLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
</Component>
<Component class="javax.swing.JCheckBox" name="dateCheck">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/modules/interestingitems/Bundle.properties" key="FilesSetRulePanel.dateCheck.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="dateCheckActionPerformed"/>
</Events>
</Component>
</SubComponents> </SubComponents>
</Form> </Form>

View File

@ -1,7 +1,7 @@
/* /*
* Autopsy Forensic Browser * Autopsy Forensic Browser
* *
* Copyright 2014-2017 Basis Technology Corp. * Copyright 2014-2018 Basis Technology Corp.
* Contact: carrier <at> sleuthkit <dot> org * Contact: carrier <at> sleuthkit <dot> org
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
@ -19,7 +19,6 @@
package org.sleuthkit.autopsy.modules.interestingitems; package org.sleuthkit.autopsy.modules.interestingitems;
import java.awt.event.ActionEvent; import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.List; import java.util.List;
import java.util.SortedSet; import java.util.SortedSet;
import java.util.logging.Level; import java.util.logging.Level;
@ -50,6 +49,8 @@ final class FilesSetRulePanel extends javax.swing.JPanel {
"FilesSetRulePanel.NoMimeTypeError=Please select a valid MIME type.", "FilesSetRulePanel.NoMimeTypeError=Please select a valid MIME type.",
"FilesSetRulePanel.NoNameError=Name cannot be empty", "FilesSetRulePanel.NoNameError=Name cannot be empty",
"FilesSetRulePanel.NoPathError=Path cannot be empty", "FilesSetRulePanel.NoPathError=Path cannot be empty",
"FilesSetRulePanel.DaysIncludedEmptyError=Number of days included cannot be empty.",
"FilesSetRulePanel.DaysIncludedInvalidError=Number of days included must be a positive integer.",
"FilesSetRulePanel.ZeroFileSizeError=File size condition value must not be 0 (Unless = is selected)." "FilesSetRulePanel.ZeroFileSizeError=File size condition value must not be 0 (Unless = is selected)."
}) })
@ -82,6 +83,7 @@ final class FilesSetRulePanel extends javax.swing.JPanel {
} else { } else {
populateMimeTypesComboBox(); populateMimeTypesComboBox();
} }
this.dateCheckActionPerformed(null);
populateComponentsWithDefaultValues(); populateComponentsWithDefaultValues();
this.setButtons(okButton, cancelButton); this.setButtons(okButton, cancelButton);
} }
@ -108,12 +110,14 @@ final class FilesSetRulePanel extends javax.swing.JPanel {
populateMimeTypesComboBox(); populateMimeTypesComboBox();
populateMimeConditionComponents(rule); populateMimeConditionComponents(rule);
populateSizeConditionComponents(rule); populateSizeConditionComponents(rule);
} }
populateMimeTypesComboBox(); populateMimeTypesComboBox();
populateRuleNameComponent(rule); populateRuleNameComponent(rule);
populateTypeConditionComponents(rule); populateTypeConditionComponents(rule);
populateNameConditionComponents(rule); populateNameConditionComponents(rule);
populatePathConditionComponents(rule); populatePathConditionComponents(rule);
populateDateConditionComponents(rule);
this.setButtons(okButton, cancelButton); this.setButtons(okButton, cancelButton);
} }
@ -176,7 +180,7 @@ final class FilesSetRulePanel extends javax.swing.JPanel {
private void setOkButton() { private void setOkButton() {
if (this.okButton != null) { if (this.okButton != null) {
this.okButton.setEnabled(this.fileSizeCheck.isSelected() || this.mimeCheck.isSelected() this.okButton.setEnabled(this.fileSizeCheck.isSelected() || this.mimeCheck.isSelected()
|| this.nameCheck.isSelected() || this.pathCheck.isSelected()); || this.nameCheck.isSelected() || this.pathCheck.isSelected() || this.dateCheck.isSelected());
} }
} }
@ -274,6 +278,21 @@ final class FilesSetRulePanel extends javax.swing.JPanel {
} }
} }
/**
* Populates the UI components that display the optional date condition for
* a rule.
*
* @param rule The files set rule to be edited.
*/
private void populateDateConditionComponents(FilesSet.Rule rule) {
FilesSet.Rule.DateCondition dateCondition = rule.getDateCondition();
if (dateCondition != null) {
this.dateCheck.setSelected(true);
this.dateCheckActionPerformed(null);
this.daysIncludedTextField.setText(Integer.toString(dateCondition.getDaysIncluded()));
}
}
/** /**
* Returns whether or not the data entered in the panel constitutes a valid * Returns whether or not the data entered in the panel constitutes a valid
* files set membership rule definition, displaying a dialog explaining the * files set membership rule definition, displaying a dialog explaining the
@ -283,7 +302,7 @@ final class FilesSetRulePanel extends javax.swing.JPanel {
*/ */
boolean isValidRuleDefinition() { boolean isValidRuleDefinition() {
if (!(this.mimeCheck.isSelected() || this.fileSizeCheck.isSelected() || this.pathCheck.isSelected() || this.nameCheck.isSelected())) { if (!(this.mimeCheck.isSelected() || this.fileSizeCheck.isSelected() || this.pathCheck.isSelected() || this.nameCheck.isSelected() || this.dateCheck.isSelected())) {
NotifyDescriptor notifyDesc = new NotifyDescriptor.Message( NotifyDescriptor notifyDesc = new NotifyDescriptor.Message(
Bundle.FilesSetRulePanel_NoConditionError(), Bundle.FilesSetRulePanel_NoConditionError(),
NotifyDescriptor.WARNING_MESSAGE); NotifyDescriptor.WARNING_MESSAGE);
@ -367,6 +386,28 @@ final class FilesSetRulePanel extends javax.swing.JPanel {
} }
} }
if (this.dateCheck.isSelected()) {
if (this.daysIncludedTextField.getText().isEmpty()) {
NotifyDescriptor notifyDesc = new NotifyDescriptor.Message(
Bundle.FilesSetRulePanel_DaysIncludedEmptyError(),
NotifyDescriptor.WARNING_MESSAGE);
DialogDisplayer.getDefault().notify(notifyDesc);
return false;
}
try {
int value = Integer.parseInt(daysIncludedTextField.getText());
if (value < 0) {
throw new NumberFormatException("Negative numbers are not allowed for the within N days condition");
}
} catch (NumberFormatException e) {
//field did not contain an integer
NotifyDescriptor notifyDesc = new NotifyDescriptor.Message(
Bundle.FilesSetRulePanel_DaysIncludedInvalidError(),
NotifyDescriptor.WARNING_MESSAGE);
DialogDisplayer.getDefault().notify(notifyDesc);
return false;
}
}
return true; return true;
} }
@ -504,6 +545,23 @@ final class FilesSetRulePanel extends javax.swing.JPanel {
return condition; return condition;
} }
/**
* Gets the optional date condition for the rule that was created or edited.
* Should only be called if isValidDefintion() returns true.
*
* @return A date condition or null if no date condition was specified.
*
* @throws IllegalStateException if the specified date condition is not
* valid.
*/
FilesSet.Rule.DateCondition getDateCondition() {
FilesSet.Rule.DateCondition dateCondition = null;
if (!daysIncludedTextField.getText().isEmpty()) {
dateCondition = new FilesSet.Rule.DateCondition(Integer.parseInt(daysIncludedTextField.getText()));
}
return dateCondition;
}
/** /**
* Checks an input string for the use of illegal characters. * Checks an input string for the use of illegal characters.
* *
@ -582,15 +640,13 @@ final class FilesSetRulePanel extends javax.swing.JPanel {
filesRadioButton = new javax.swing.JRadioButton(); filesRadioButton = new javax.swing.JRadioButton();
dirsRadioButton = new javax.swing.JRadioButton(); dirsRadioButton = new javax.swing.JRadioButton();
allRadioButton = new javax.swing.JRadioButton(); allRadioButton = new javax.swing.JRadioButton();
daysIncludedTextField = new javax.swing.JTextField();
daysIncludedLabel = new javax.swing.JLabel();
dateCheck = new javax.swing.JCheckBox();
org.openide.awt.Mnemonics.setLocalizedText(ruleNameLabel, org.openide.util.NbBundle.getMessage(FilesSetRulePanel.class, "FilesSetRulePanel.ruleNameLabel.text")); // NOI18N org.openide.awt.Mnemonics.setLocalizedText(ruleNameLabel, org.openide.util.NbBundle.getMessage(FilesSetRulePanel.class, "FilesSetRulePanel.ruleNameLabel.text")); // NOI18N
ruleNameTextField.setText(org.openide.util.NbBundle.getMessage(FilesSetRulePanel.class, "FilesSetRulePanel.ruleNameTextField.text")); // NOI18N ruleNameTextField.setText(org.openide.util.NbBundle.getMessage(FilesSetRulePanel.class, "FilesSetRulePanel.ruleNameTextField.text")); // NOI18N
ruleNameTextField.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
ruleNameTextFieldActionPerformed(evt);
}
});
org.openide.awt.Mnemonics.setLocalizedText(jLabel1, org.openide.util.NbBundle.getMessage(FilesSetRulePanel.class, "FilesSetRulePanel.jLabel1.text")); // NOI18N org.openide.awt.Mnemonics.setLocalizedText(jLabel1, org.openide.util.NbBundle.getMessage(FilesSetRulePanel.class, "FilesSetRulePanel.jLabel1.text")); // NOI18N
@ -685,85 +741,99 @@ final class FilesSetRulePanel extends javax.swing.JPanel {
} }
}); });
daysIncludedTextField.setEnabled(false);
daysIncludedTextField.setMinimumSize(new java.awt.Dimension(60, 20));
daysIncludedTextField.setPreferredSize(new java.awt.Dimension(60, 20));
org.openide.awt.Mnemonics.setLocalizedText(daysIncludedLabel, org.openide.util.NbBundle.getMessage(FilesSetRulePanel.class, "FilesSetRulePanel.daysIncludedLabel.text")); // NOI18N
org.openide.awt.Mnemonics.setLocalizedText(dateCheck, org.openide.util.NbBundle.getMessage(FilesSetRulePanel.class, "FilesSetRulePanel.dateCheck.text")); // NOI18N
dateCheck.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
dateCheckActionPerformed(evt);
}
});
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()
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING) .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup() .addGroup(layout.createSequentialGroup()
.addGap(8, 8, 8) .addGap(8, 8, 8)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup() .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
.addComponent(ruleNameLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addComponent(ruleNameLabel)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addGap(5, 5, 5)
.addComponent(ruleNameTextField, javax.swing.GroupLayout.PREFERRED_SIZE, 234, javax.swing.GroupLayout.PREFERRED_SIZE)) .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(mimeTypeComboBox, 0, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addComponent(pathTextField)
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
.addComponent(equalitySymbolComboBox, 0, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(fileSizeSpinner)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(fileSizeComboBox, 0, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
.addGroup(layout.createSequentialGroup()
.addComponent(pathRegexCheckBox)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addComponent(pathSeparatorInfoLabel))
.addGroup(layout.createSequentialGroup()
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addComponent(daysIncludedTextField, javax.swing.GroupLayout.PREFERRED_SIZE, 69, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(daysIncludedLabel))
.addComponent(ruleNameTextField, javax.swing.GroupLayout.DEFAULT_SIZE, 249, Short.MAX_VALUE)
.addGroup(layout.createSequentialGroup()
.addComponent(fullNameRadioButton)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(extensionRadioButton, javax.swing.GroupLayout.PREFERRED_SIZE, 98, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(nameRegexCheckbox)))
.addGap(1, 1, 1))))
.addComponent(jLabel5)
.addGroup(layout.createSequentialGroup() .addGroup(layout.createSequentialGroup()
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(jLabel5) .addComponent(nameCheck, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.PREFERRED_SIZE, 95, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(jLabel1))
.addGap(16, 16, 16)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup() .addGroup(layout.createSequentialGroup()
.addComponent(jLabel1)
.addGap(65, 65, 65)
.addComponent(filesRadioButton) .addComponent(filesRadioButton)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(dirsRadioButton) .addComponent(dirsRadioButton)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(allRadioButton))) .addComponent(allRadioButton))
.addGap(0, 0, Short.MAX_VALUE)))) .addComponent(nameTextField)))))
.addGroup(layout.createSequentialGroup()
.addContainerGap()
.addComponent(nameCheck)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addComponent(nameTextField, javax.swing.GroupLayout.PREFERRED_SIZE, 249, javax.swing.GroupLayout.PREFERRED_SIZE))
.addGroup(javax.swing.GroupLayout.Alignment.LEADING, layout.createSequentialGroup()
.addContainerGap()
.addComponent(pathCheck)
.addGap(4, 4, 4)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addComponent(pathRegexCheckBox)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addComponent(pathSeparatorInfoLabel))
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
.addGap(0, 0, Short.MAX_VALUE)
.addComponent(pathTextField, javax.swing.GroupLayout.PREFERRED_SIZE, 250, javax.swing.GroupLayout.PREFERRED_SIZE))
.addGroup(layout.createSequentialGroup()
.addComponent(fullNameRadioButton)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(extensionRadioButton, javax.swing.GroupLayout.PREFERRED_SIZE, 114, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(nameRegexCheckbox)
.addGap(0, 0, Short.MAX_VALUE))))
.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(pathCheck)
.addComponent(mimeCheck) .addComponent(mimeCheck)
.addComponent(fileSizeCheck)) .addComponent(fileSizeCheck)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addComponent(dateCheck))
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING) .addGap(0, 0, Short.MAX_VALUE)))
.addGroup(layout.createSequentialGroup()
.addComponent(equalitySymbolComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, 36, javax.swing.GroupLayout.PREFERRED_SIZE)
.addGap(18, 18, 18)
.addComponent(fileSizeSpinner, javax.swing.GroupLayout.PREFERRED_SIZE, 94, javax.swing.GroupLayout.PREFERRED_SIZE)
.addGap(18, 18, 18)
.addComponent(fileSizeComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, 82, javax.swing.GroupLayout.PREFERRED_SIZE))
.addComponent(mimeTypeComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, 250, javax.swing.GroupLayout.PREFERRED_SIZE))))
.addContainerGap()) .addContainerGap())
); );
layout.setVerticalGroup( layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup() .addGroup(layout.createSequentialGroup()
.addComponent(jLabel5) .addComponent(jLabel5)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addGap(3, 3, 3)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
.addComponent(jLabel1) .addGroup(layout.createSequentialGroup()
.addComponent(filesRadioButton) .addComponent(jLabel1)
.addComponent(dirsRadioButton) .addGap(10, 10, 10)
.addComponent(allRadioButton)) .addComponent(nameCheck))
.addGap(5, 5, 5) .addGroup(layout.createSequentialGroup()
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(nameTextField, javax.swing.GroupLayout.PREFERRED_SIZE, 20, javax.swing.GroupLayout.PREFERRED_SIZE) .addComponent(filesRadioButton)
.addComponent(nameCheck)) .addComponent(dirsRadioButton)
.addComponent(allRadioButton))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
.addComponent(nameTextField, javax.swing.GroupLayout.PREFERRED_SIZE, 20, javax.swing.GroupLayout.PREFERRED_SIZE)))
.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(fullNameRadioButton) .addComponent(fullNameRadioButton)
@ -777,7 +847,7 @@ final class FilesSetRulePanel extends javax.swing.JPanel {
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(pathRegexCheckBox) .addComponent(pathRegexCheckBox)
.addComponent(pathSeparatorInfoLabel)) .addComponent(pathSeparatorInfoLabel))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 8, Short.MAX_VALUE) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(mimeTypeComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addComponent(mimeTypeComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(mimeCheck)) .addComponent(mimeCheck))
@ -787,7 +857,12 @@ final class FilesSetRulePanel extends javax.swing.JPanel {
.addComponent(fileSizeComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addComponent(fileSizeComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(fileSizeSpinner, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addComponent(fileSizeSpinner, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(fileSizeCheck)) .addComponent(fileSizeCheck))
.addGap(15, 15, 15) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(daysIncludedTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(daysIncludedLabel)
.addComponent(dateCheck))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(ruleNameTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addComponent(ruleNameTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(ruleNameLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) .addComponent(ruleNameLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
@ -795,10 +870,6 @@ final class FilesSetRulePanel extends javax.swing.JPanel {
); );
}// </editor-fold>//GEN-END:initComponents }// </editor-fold>//GEN-END:initComponents
private void ruleNameTextFieldActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_ruleNameTextFieldActionPerformed
// TODO add your handling code here:
}//GEN-LAST:event_ruleNameTextFieldActionPerformed
private void nameCheckActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_nameCheckActionPerformed private void nameCheckActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_nameCheckActionPerformed
if (!this.nameCheck.isSelected()) { if (!this.nameCheck.isSelected()) {
this.nameTextField.setEnabled(false); this.nameTextField.setEnabled(false);
@ -831,15 +902,30 @@ final class FilesSetRulePanel extends javax.swing.JPanel {
this.setOkButton(); this.setOkButton();
}//GEN-LAST:event_pathCheckActionPerformed }//GEN-LAST:event_pathCheckActionPerformed
private void mimeCheckActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_mimeCheckActionPerformed private void filesRadioButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_filesRadioButtonActionPerformed
if (!this.mimeCheck.isSelected()) {
this.mimeTypeComboBox.setEnabled(false); this.setComponentsForSearchType();
this.mimeTypeComboBox.setSelectedIndex(0); }//GEN-LAST:event_filesRadioButtonActionPerformed
private void dirsRadioButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_dirsRadioButtonActionPerformed
this.setComponentsForSearchType();
}//GEN-LAST:event_dirsRadioButtonActionPerformed
private void allRadioButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_allRadioButtonActionPerformed
this.setComponentsForSearchType();
}//GEN-LAST:event_allRadioButtonActionPerformed
private void dateCheckActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_dateCheckActionPerformed
if (!this.dateCheck.isSelected()) {
this.daysIncludedTextField.setEnabled(false);
this.daysIncludedLabel.setEnabled(false);
this.daysIncludedTextField.setText("");
} else { } else {
this.mimeTypeComboBox.setEnabled(true); this.daysIncludedTextField.setEnabled(true);
this.daysIncludedLabel.setEnabled(true);
} }
this.setOkButton(); this.setOkButton();
}//GEN-LAST:event_mimeCheckActionPerformed }//GEN-LAST:event_dateCheckActionPerformed
private void fileSizeCheckActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_fileSizeCheckActionPerformed private void fileSizeCheckActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_fileSizeCheckActionPerformed
if (!this.fileSizeCheck.isSelected()) { if (!this.fileSizeCheck.isSelected()) {
@ -855,21 +941,21 @@ final class FilesSetRulePanel extends javax.swing.JPanel {
this.setOkButton(); this.setOkButton();
}//GEN-LAST:event_fileSizeCheckActionPerformed }//GEN-LAST:event_fileSizeCheckActionPerformed
private void filesRadioButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_filesRadioButtonActionPerformed private void mimeCheckActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_mimeCheckActionPerformed
if (!this.mimeCheck.isSelected()) {
this.setComponentsForSearchType(); this.mimeTypeComboBox.setEnabled(false);
}//GEN-LAST:event_filesRadioButtonActionPerformed this.mimeTypeComboBox.setSelectedIndex(0);
} else {
private void dirsRadioButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_dirsRadioButtonActionPerformed this.mimeTypeComboBox.setEnabled(true);
this.setComponentsForSearchType(); }
}//GEN-LAST:event_dirsRadioButtonActionPerformed this.setOkButton();
}//GEN-LAST:event_mimeCheckActionPerformed
private void allRadioButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_allRadioButtonActionPerformed
this.setComponentsForSearchType();
}//GEN-LAST:event_allRadioButtonActionPerformed
// Variables declaration - do not modify//GEN-BEGIN:variables // Variables declaration - do not modify//GEN-BEGIN:variables
private javax.swing.JRadioButton allRadioButton; private javax.swing.JRadioButton allRadioButton;
private javax.swing.JCheckBox dateCheck;
private javax.swing.JLabel daysIncludedLabel;
private javax.swing.JTextField daysIncludedTextField;
private javax.swing.JRadioButton dirsRadioButton; private javax.swing.JRadioButton dirsRadioButton;
private javax.swing.JComboBox<String> equalitySymbolComboBox; private javax.swing.JComboBox<String> equalitySymbolComboBox;
private javax.swing.JRadioButton extensionRadioButton; private javax.swing.JRadioButton extensionRadioButton;

View File

@ -1,7 +1,7 @@
/* /*
* Autopsy Forensic Browser * Autopsy Forensic Browser
* *
* Copyright 2014 Basis Technology Corp. * Copyright 2014-2018 Basis Technology Corp.
* Contact: carrier <at> sleuthkit <dot> org * Contact: carrier <at> sleuthkit <dot> org
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
@ -52,7 +52,7 @@ public final class FilesSetsManager extends Observable {
{ {
put(Bundle.FilesSetsManager_allFilesAndDirectories(), put(Bundle.FilesSetsManager_allFilesAndDirectories(),
new Rule(Bundle.FilesSetsManager_allFilesAndDirectories(), null, new Rule(Bundle.FilesSetsManager_allFilesAndDirectories(), null,
new MetaTypeCondition(MetaTypeCondition.Type.ALL), null, null, null)); new MetaTypeCondition(MetaTypeCondition.Type.ALL), null, null, null, null));
} }
}); });
private static final FilesSet FILES_DIRS_UNALLOC_INGEST_FILTER = new FilesSet( private static final FilesSet FILES_DIRS_UNALLOC_INGEST_FILTER = new FilesSet(
@ -61,7 +61,7 @@ public final class FilesSetsManager extends Observable {
{ {
put(Bundle.FilesSetsManager_allFilesDirectoriesAndUnallocated(), put(Bundle.FilesSetsManager_allFilesDirectoriesAndUnallocated(),
new Rule(Bundle.FilesSetsManager_allFilesDirectoriesAndUnallocated(), null, new Rule(Bundle.FilesSetsManager_allFilesDirectoriesAndUnallocated(), null,
new MetaTypeCondition(MetaTypeCondition.Type.ALL), null, null, null)); new MetaTypeCondition(MetaTypeCondition.Type.ALL), null, null, null, null));
} }
}); });

View File

@ -1,7 +1,7 @@
/* /*
* Autopsy Forensic Browser * Autopsy Forensic Browser
* *
* Copyright 2011-2017 Basis Technology Corp. * Copyright 2011-2018 Basis Technology Corp.
* Contact: carrier <at> sleuthkit <dot> org * Contact: carrier <at> sleuthkit <dot> org
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
@ -44,6 +44,7 @@ import org.sleuthkit.autopsy.modules.interestingitems.FilesSet.Rule.FileSizeCond
import org.sleuthkit.autopsy.modules.interestingitems.FilesSet.Rule.MetaTypeCondition; import org.sleuthkit.autopsy.modules.interestingitems.FilesSet.Rule.MetaTypeCondition;
import org.sleuthkit.autopsy.modules.interestingitems.FilesSet.Rule.MimeTypeCondition; import org.sleuthkit.autopsy.modules.interestingitems.FilesSet.Rule.MimeTypeCondition;
import org.sleuthkit.autopsy.modules.interestingitems.FilesSet.Rule.ParentPathCondition; import org.sleuthkit.autopsy.modules.interestingitems.FilesSet.Rule.ParentPathCondition;
import org.sleuthkit.autopsy.modules.interestingitems.FilesSet.Rule.DateCondition;
import org.w3c.dom.Document; import org.w3c.dom.Document;
import org.w3c.dom.Element; import org.w3c.dom.Element;
import org.w3c.dom.NodeList; import org.w3c.dom.NodeList;
@ -67,6 +68,7 @@ class InterestingItemsFilesSetSettings implements Serializable {
private static final String FILE_SET_TAG = "INTERESTING_FILE_SET"; //NON-NLS private static final String FILE_SET_TAG = "INTERESTING_FILE_SET"; //NON-NLS
private static final String NAME_RULE_TAG = "NAME"; //NON-NLS private static final String NAME_RULE_TAG = "NAME"; //NON-NLS
private static final String NAME_ATTR = "name"; //NON-NLS private static final String NAME_ATTR = "name"; //NON-NLS
private static final String DAYS_INCLUDED_ATTR = "daysIncluded";
private static final String MIME_ATTR = "mimeType"; private static final String MIME_ATTR = "mimeType";
private static final String FS_COMPARATOR_ATTR = "comparatorSymbol"; private static final String FS_COMPARATOR_ATTR = "comparatorSymbol";
private static final String FS_SIZE_ATTR = "sizeValue"; private static final String FS_SIZE_ATTR = "sizeValue";
@ -166,6 +168,35 @@ class InterestingItemsFilesSetSettings implements Serializable {
return pathCondition; return pathCondition;
} }
/**
* Construct a date condition for a FilesSet membership rule from data in an
* XML element.
*
* @param ruleElement The XML element.
*
* @return The date condition, or null if there is an error (logged).
*
* @throws
* org.sleuthkit.autopsy.modules.interestingitems.FilesSetsManager.FilesSetsManagerException
*/
private static DateCondition readDateCondition(Element ruleElement) throws FilesSetsManager.FilesSetsManagerException {
// Read in the optional path condition. Null is o.k., but if the attribute
// is there, be sure it is not malformed.
DateCondition dateCondition = null;
if (!ruleElement.getAttribute(DAYS_INCLUDED_ATTR).isEmpty()) {
String daysIncluded = ruleElement.getAttribute(DAYS_INCLUDED_ATTR);
if (!daysIncluded.isEmpty()) {
try {
dateCondition = new DateCondition(Integer.parseInt(daysIncluded));
} catch (NumberFormatException ex) {
logger.log(Level.SEVERE, "Error creating condition for " + daysIncluded + ", ignoring malformed date condition definition", ex); // NON-NLS
throw new FilesSetsManager.FilesSetsManagerException(String.format("error compiling %s regex", DAYS_INCLUDED_ATTR), ex);
}
}
}
return dateCondition;
}
/** /**
* Attempts to compile a regular expression. * Attempts to compile a regular expression.
* *
@ -183,12 +214,13 @@ class InterestingItemsFilesSetSettings implements Serializable {
} }
/** /**
* Construct a fileset membership rule from the data in an xml element for * Construct a fileset membership rule from the data in an xml element for
* use in a FilesSet. * use in a FilesSet.
* *
* @param elem The XML element. * @param elem The XML element.
* *
* @return A file set constructed from the conditions available in the XML element * @return A file set constructed from the conditions available in the XML
* element
* *
* @throws * @throws
* org.sleuthkit.autopsy.modules.interestingitems.FilesSetsManager.FilesSetsManagerException * org.sleuthkit.autopsy.modules.interestingitems.FilesSetsManager.FilesSetsManagerException
@ -200,17 +232,17 @@ class InterestingItemsFilesSetSettings implements Serializable {
ParentPathCondition pathCondition = readPathCondition(elem); ParentPathCondition pathCondition = readPathCondition(elem);
MimeTypeCondition mimeCondition = readMimeCondition(elem); MimeTypeCondition mimeCondition = readMimeCondition(elem);
FileSizeCondition sizeCondition = readSizeCondition(elem); FileSizeCondition sizeCondition = readSizeCondition(elem);
//if meta type condition or all four types of conditions the user can create are all null then don't make the rule DateCondition dateCondition = readDateCondition(elem); //if meta type condition or all four types of conditions the user can create are all null then don't make the rule
if (metaCondition == null || (nameCondition == null && pathCondition == null && mimeCondition == null && sizeCondition == null)) { if (metaCondition == null || (nameCondition == null && pathCondition == null && mimeCondition == null && sizeCondition == null && dateCondition == null)) {
logger.log(Level.WARNING, "Error Reading Rule, " + ruleName + " was either missing a meta condition or contained only a meta condition. No rule was imported."); // NON-NLS logger.log(Level.WARNING, "Error Reading Rule, " + ruleName + " was either missing a meta condition or contained only a meta condition. No rule was imported."); // NON-NLS
throw new FilesSetsManager.FilesSetsManagerException(String.format("Invalid Rule in FilesSet xml, missing necessary conditions for %s", ruleName)); throw new FilesSetsManager.FilesSetsManagerException(String.format("Invalid Rule in FilesSet xml, missing necessary conditions for %s", ruleName));
} }
return new FilesSet.Rule(ruleName, nameCondition, metaCondition, pathCondition, mimeCondition, sizeCondition); return new FilesSet.Rule(ruleName, nameCondition, metaCondition, pathCondition, mimeCondition, sizeCondition, dateCondition);
} }
/** /**
* Construct a file name condition for a FilesSet membership rule from data in an * Construct a file name condition for a FilesSet membership rule from data
* XML element. * in an XML element.
* *
* @param ruleElement The XML element. * @param ruleElement The XML element.
* *
@ -256,8 +288,8 @@ class InterestingItemsFilesSetSettings implements Serializable {
} }
/** /**
* Construct a MIME type condition for a FilesSet membership rule from data in an * Construct a MIME type condition for a FilesSet membership rule from data
* XML element. * in an XML element.
* *
* @param ruleElement The XML element. * @param ruleElement The XML element.
* *
@ -275,8 +307,8 @@ class InterestingItemsFilesSetSettings implements Serializable {
} }
/** /**
* Construct a file size condition for a FilesSet membership rule from data in an * Construct a file size condition for a FilesSet membership rule from data
* XML element. * in an XML element.
* *
* @param ruleElement The XML element. * @param ruleElement The XML element.
* *
@ -544,6 +576,13 @@ class InterestingItemsFilesSetSettings implements Serializable {
ruleElement.setAttribute(FS_SIZE_ATTR, Integer.toString(sizeCondition.getSizeValue())); ruleElement.setAttribute(FS_SIZE_ATTR, Integer.toString(sizeCondition.getSizeValue()));
ruleElement.setAttribute(FS_UNITS_ATTR, sizeCondition.getUnit().getName()); ruleElement.setAttribute(FS_UNITS_ATTR, sizeCondition.getUnit().getName());
} }
//Add the optional date condition
DateCondition dateCondition = rule.getDateCondition();
if (dateCondition != null) {
ruleElement.setAttribute(DAYS_INCLUDED_ATTR, Integer.toString(dateCondition.getDaysIncluded()));
}
setElement.appendChild(ruleElement); setElement.appendChild(ruleElement);
} }
rootElement.appendChild(setElement); rootElement.appendChild(setElement);

View File

@ -33,6 +33,7 @@ import org.openide.util.lookup.ServiceProvider;
import org.sleuthkit.autopsy.casemodule.Case; import org.sleuthkit.autopsy.casemodule.Case;
import org.sleuthkit.autopsy.corecomponentinterfaces.DataContentViewer; import org.sleuthkit.autopsy.corecomponentinterfaces.DataContentViewer;
import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.autopsy.coreutils.Logger;
import org.sleuthkit.autopsy.keywordsearch.KeywordSearchResultFactory.AdHocQueryResult;
import org.sleuthkit.datamodel.AbstractFile; import org.sleuthkit.datamodel.AbstractFile;
import org.sleuthkit.datamodel.Account; import org.sleuthkit.datamodel.Account;
import org.sleuthkit.datamodel.BlackboardArtifact; import org.sleuthkit.datamodel.BlackboardArtifact;
@ -52,7 +53,6 @@ public class ExtractedContentViewer implements DataContentViewer {
private static final Logger logger = Logger.getLogger(ExtractedContentViewer.class.getName()); private static final Logger logger = Logger.getLogger(ExtractedContentViewer.class.getName());
private static final long INVALID_DOCUMENT_ID = 0L;
private static final BlackboardAttribute.Type TSK_ASSOCIATED_ARTIFACT_TYPE = new BlackboardAttribute.Type(TSK_ASSOCIATED_ARTIFACT); private static final BlackboardAttribute.Type TSK_ASSOCIATED_ARTIFACT_TYPE = new BlackboardAttribute.Type(TSK_ASSOCIATED_ARTIFACT);
public static final BlackboardAttribute.Type TSK_ACCOUNT_TYPE = new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_ACCOUNT_TYPE); public static final BlackboardAttribute.Type TSK_ACCOUNT_TYPE = new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_ACCOUNT_TYPE);
@ -92,54 +92,77 @@ public class ExtractedContentViewer implements DataContentViewer {
currentNode = node; currentNode = node;
} }
Lookup nodeLookup = node.getLookup();
AbstractFile content = nodeLookup.lookup(AbstractFile.class);
/* /*
* Assemble a collection of all of the indexed text "sources" for the * Assemble a collection of all of the indexed text "sources" for the
* node. * node.
*/ */
List<IndexedText> sources = new ArrayList<>(); List<IndexedText> sources = new ArrayList<>();
Lookup nodeLookup = node.getLookup();
AdHocQueryResult adHocQueryResult = nodeLookup.lookup(AdHocQueryResult.class);
AbstractFile file = null;
BlackboardArtifact artifact;
/*
* If we have an ad hoc query result, pull the file and artifact objects
* from that. Otherwise, pull them from the lookup.
*/
if (adHocQueryResult != null) {
artifact = adHocQueryResult.getArtifact();
Content content = adHocQueryResult.getContent();
if (content instanceof AbstractFile) {
file = (AbstractFile) content;
}
} else {
artifact = nodeLookup.lookup(BlackboardArtifact.class);
file = nodeLookup.lookup(AbstractFile.class);
}
/*
* First, get text with highlighted hits if this node is for a search
* result.
*/
IndexedText highlightedHitText = null; IndexedText highlightedHitText = null;
IndexedText rawContentText = null; if (adHocQueryResult != null) {
/*
if (null != content && solrHasContent(content.getId())) { * The node is an ad hoc search result node.
QueryResults hits = nodeLookup.lookup(QueryResults.class); */
BlackboardArtifact artifact = nodeLookup.lookup(BlackboardArtifact.class); highlightedHitText = new HighlightedText(adHocQueryResult.getSolrObjectId(), adHocQueryResult.getResults());
if (hits != null) { } else if (artifact != null) {
if (artifact.getArtifactTypeID() == TSK_KEYWORD_HIT.getTypeID()) {
/* /*
* if there is a QueryReslt object, in the lookup use that. This * The node is a keyword hit artifact node.
* happens when a user selects a row in an ad-hoc search result
*/ */
highlightedHitText = new HighlightedText(content.getId(), hits);
} else if (artifact != null
&& artifact.getArtifactTypeID() == TSK_ACCOUNT.getTypeID()) {
try { try {
// if the artifact is an account artifact, get an account text .
highlightedHitText = getAccountsText(content, nodeLookup);
} catch (TskCoreException ex) {
logger.log(Level.SEVERE, "Failed to create AccountsText for " + content, ex); //NON-NLS
}
} else if (artifact != null
&& artifact.getArtifactTypeID() == TSK_KEYWORD_HIT.getTypeID()) {
try {
//if there is kwh artifact use that to construct the HighlightedText
highlightedHitText = new HighlightedText(artifact); highlightedHitText = new HighlightedText(artifact);
} catch (TskCoreException ex) { } catch (TskCoreException ex) {
logger.log(Level.SEVERE, "Failed to create HighlightedText for " + artifact, ex); //NON-NLS logger.log(Level.SEVERE, "Failed to create HighlightedText for " + artifact, ex); //NON-NLS
} }
} else if (artifact.getArtifactTypeID() == TSK_ACCOUNT.getTypeID() && file != null) {
try {
BlackboardAttribute attribute = artifact.getAttribute(TSK_ACCOUNT_TYPE);
if (attribute != null && Account.Type.CREDIT_CARD.getTypeName().equals(attribute.getValueString())) {
/*
* The node is an credit card account node.
*/
highlightedHitText = getAccountsText(file, nodeLookup);
}
} catch (TskCoreException ex) {
logger.log(Level.SEVERE, "Failed to create AccountsText for " + file, ex); //NON-NLS
}
} }
}
if (highlightedHitText != null) {
sources.add(highlightedHitText);
}
if (highlightedHitText != null) { /*
sources.add(highlightedHitText); * Next, add the "raw" (not highlighted) text, if any, for any file
} * associated with the node.
*/
/* IndexedText rawContentText = null;
* Next, add the "raw" (not highlighted) text, if any, for any if (file != null) {
* content associated with the node. rawContentText = new RawText(file, file.getId());
*/
rawContentText = new RawText(content, content.getId());
sources.add(rawContentText); sources.add(rawContentText);
} }
@ -149,22 +172,21 @@ public class ExtractedContentViewer implements DataContentViewer {
*/ */
IndexedText rawArtifactText = null; IndexedText rawArtifactText = null;
try { try {
rawArtifactText = getRawArtifactText(nodeLookup); rawArtifactText = getRawArtifactText(artifact);
if (rawArtifactText != null) {
sources.add(rawArtifactText);
}
} catch (TskCoreException ex) { } catch (TskCoreException ex) {
logger.log(Level.SEVERE, "Error creating RawText for " + content, ex); //NON-NLS logger.log(Level.SEVERE, "Error creating RawText for " + file, ex); //NON-NLS
}
if (rawArtifactText != null) {
sources.add(rawArtifactText);
} }
// Now set the default source to be displayed. // Now set the default source to be displayed.
if (null != highlightedHitText) { if (highlightedHitText != null) {
currentSource = highlightedHitText; currentSource = highlightedHitText;
} else if (null != rawContentText) { } else if (rawArtifactText != null) {
currentSource = rawContentText;
} else {
currentSource = rawArtifactText; currentSource = rawArtifactText;
} else {
currentSource = rawContentText;
} }
// Push the text sources into the panel. // Push the text sources into the panel.
@ -177,16 +199,15 @@ public class ExtractedContentViewer implements DataContentViewer {
panel.updateControls(currentSource); panel.updateControls(currentSource);
String contentName = ""; String contentName = "";
if (content != null) { if (file != null) {
contentName = content.getName(); contentName = file.getName();
} }
setPanel(contentName, sources); setPanel(contentName, sources);
} }
static private IndexedText getRawArtifactText(Lookup nodeLookup) throws TskCoreException { static private IndexedText getRawArtifactText(BlackboardArtifact artifact) throws TskCoreException {
IndexedText rawArtifactText = null; IndexedText rawArtifactText = null;
BlackboardArtifact artifact = nodeLookup.lookup(BlackboardArtifact.class);
if (null != artifact) { if (null != artifact) {
/* /*
* For keyword hit artifacts, add the text of the artifact that hit, * For keyword hit artifacts, add the text of the artifact that hit,
@ -275,37 +296,69 @@ public class ExtractedContentViewer implements DataContentViewer {
} }
/* /*
* Is there a credit card or keyword hit artifact in the lookup * If the lookup of the node contains an ad hoc search result object,
* then there must be indexed text that produced the hit.
*/ */
Collection<? extends BlackboardArtifact> artifacts = node.getLookup().lookupAll(BlackboardArtifact.class); AdHocQueryResult adHocQueryResult = node.getLookup().lookup(AdHocQueryResult.class);
if (artifacts != null) { if (adHocQueryResult != null) {
for (BlackboardArtifact art : artifacts) { return true;
final int artifactTypeID = art.getArtifactTypeID(); }
if (artifactTypeID == TSK_ACCOUNT.getTypeID()) {
try { /*
BlackboardAttribute attribute = art.getAttribute(TSK_ACCOUNT_TYPE); * If the lookup of the node contains either a keyword hit artifact or
if (attribute != null && Account.Type.CREDIT_CARD.getTypeName().equals(attribute.getValueString())) { * one to many credit card account artifacts from a credit card account
return true; * numbers search, then there must be indexed text that produced the
} * hit(s).
} catch (TskCoreException ex) { */
logger.log(Level.SEVERE, "Error getting TSK_ACCOUNT_TYPE attribute from artifact " + art.getArtifactID(), ex); BlackboardArtifact artifact = node.getLookup().lookup(BlackboardArtifact.class);
if (artifact != null) {
final int artifactTypeID = artifact.getArtifactTypeID();
if (artifactTypeID == TSK_KEYWORD_HIT.getTypeID()) {
return true;
} else if (artifactTypeID == TSK_ACCOUNT.getTypeID()) {
try {
BlackboardAttribute attribute = artifact.getAttribute(TSK_ACCOUNT_TYPE);
if (attribute != null && Account.Type.CREDIT_CARD.getTypeName().equals(attribute.getValueString())) {
return true;
} }
} else if (artifactTypeID == TSK_KEYWORD_HIT.getTypeID()) { } catch (TskCoreException ex) {
/*
* If there is an error, log it and return true. The reason
* for returning true is so that the user will have an
* opportunity to see an error message in the panel when
* this query fails again when setNode is called, instead of
* having an unexpectedly disabled content viewer with no
* other feedback.
*/
logger.log(Level.SEVERE, "Error getting TSK_ACCOUNT_TYPE attribute from artifact " + artifact.getArtifactID(), ex);
return true; return true;
} }
} }
} }
/* /*
* No highlighted text for a keyword hit, so is there any indexed text * If the lookup of the node contains an artifact that is neither a
* at all for this node? * keyword hit artifact nor a credit card account artifact, check to see
* if there is indexed text for the artifact.
*/ */
long documentID = getDocumentId(node); if (artifact != null) {
if (INVALID_DOCUMENT_ID == documentID) { return solrHasContent(artifact.getArtifactID());
return false;
} }
return solrHasContent(documentID); /*
* If the lookup of the node contains no artifacts but does contain a
* file, check to see if there is indexed text for the file.
*/
AbstractFile file = node.getLookup().lookup(AbstractFile.class);
if (file != null) {
return solrHasContent(file.getId());
}
/*
* If the lookup of the node contains neither ad hoc search results, nor
* artifacts, nor a file, there is no indexed text.
*/
return false;
} }
@Override @Override
@ -357,57 +410,6 @@ public class ExtractedContentViewer implements DataContentViewer {
} }
} }
/**
* Gets the object ID to use as the document ID for accessing any indexed
* text for the given node.
*
* @param node The node.
*
* @return The document ID or zero, which is an invalid document ID.
*/
private Long getDocumentId(Node node) {
/**
* If the node is a Blackboard artifact node for anything other than a
* keyword hit, the document ID for the text extracted from the artifact
* (the concatenation of its attributes) is the artifact ID, a large,
* negative integer. If it is a keyword hit, see if there is an
* associated artifact. If there is, get the associated artifact's ID
* and return it.
*/
BlackboardArtifact artifact = node.getLookup().lookup(BlackboardArtifact.class);
if (null != artifact) {
if (artifact.getArtifactTypeID() != BlackboardArtifact.ARTIFACT_TYPE.TSK_KEYWORD_HIT.getTypeID()) {
return artifact.getArtifactID();
} else {
try {
// Get the associated artifact attribute and return its value as the ID
BlackboardAttribute blackboardAttribute = artifact.getAttribute(TSK_ASSOCIATED_ARTIFACT_TYPE);
if (blackboardAttribute != null) {
return blackboardAttribute.getValueLong();
}
} catch (TskCoreException ex) {
logger.log(Level.SEVERE, "Error getting associated artifact attributes", ex); //NON-NLS
}
}
}
/*
* For keyword search hit artifact nodes and all other nodes, the
* document ID for the extracted text is the ID of the associated
* content, if any, unless there is an associated artifact, which is
* handled above.
*/
Content content = node.getLookup().lookup(Content.class);
if (content != null) {
return content.getId();
}
/*
* No extracted text, return an invalid docuemnt ID.
*/
return 0L;
}
private class NextFindActionListener implements ActionListener { private class NextFindActionListener implements ActionListener {
@Override @Override

View File

@ -68,7 +68,7 @@ class HighlightedText implements IndexedText {
final private Server solrServer = KeywordSearch.getServer(); final private Server solrServer = KeywordSearch.getServer();
private final long objectId; private final long solrObjectId;
/* /*
* The keywords to highlight * The keywords to highlight
*/ */
@ -104,14 +104,14 @@ class HighlightedText implements IndexedText {
* search results. In that case we have the entire QueryResults object and * search results. In that case we have the entire QueryResults object and
* need to arrange the paging. * need to arrange the paging.
* *
* @param objectId The objectID of the content whose text will be * @param solrObjectId The solrObjectId of the content whose text will be
* highlighted. * highlighted.
* @param QueryResults The QueryResults for the ad-hoc search from whose * @param QueryResults The QueryResults for the ad-hoc search from whose
* results a selection was made leading to this * results a selection was made leading to this
* HighlightedText. * HighlightedText.
*/ */
HighlightedText(long objectId, QueryResults hits) { HighlightedText(long solrObjectId, QueryResults hits) {
this.objectId = objectId; this.solrObjectId = solrObjectId;
this.hits = hits; this.hits = hits;
} }
@ -127,9 +127,9 @@ class HighlightedText implements IndexedText {
this.artifact = artifact; this.artifact = artifact;
BlackboardAttribute attribute = artifact.getAttribute(TSK_ASSOCIATED_ARTIFACT); BlackboardAttribute attribute = artifact.getAttribute(TSK_ASSOCIATED_ARTIFACT);
if (attribute != null) { if (attribute != null) {
this.objectId = attribute.getValueLong(); this.solrObjectId = attribute.getValueLong();
} else { } else {
this.objectId = artifact.getObjectID(); this.solrObjectId = artifact.getObjectID();
} }
} }
@ -143,7 +143,7 @@ class HighlightedText implements IndexedText {
return; return;
} }
this.numberPages = solrServer.queryNumFileChunks(this.objectId); this.numberPages = solrServer.queryNumFileChunks(this.solrObjectId);
if (artifact != null) { if (artifact != null) {
loadPageInfoFromArtifact(); loadPageInfoFromArtifact();
@ -190,7 +190,7 @@ class HighlightedText implements IndexedText {
// Run a query to figure out which chunks for the current object have // Run a query to figure out which chunks for the current object have
// hits for this keyword. // hits for this keyword.
chunksQuery.addFilter(new KeywordQueryFilter(FilterType.CHUNK, this.objectId)); chunksQuery.addFilter(new KeywordQueryFilter(FilterType.CHUNK, this.solrObjectId));
hits = chunksQuery.performQuery(); hits = chunksQuery.performQuery();
loadPageInfoFromHits(); loadPageInfoFromHits();
@ -212,7 +212,7 @@ class HighlightedText implements IndexedText {
for (KeywordHit hit : hits.getResults(k)) { for (KeywordHit hit : hits.getResults(k)) {
int chunkID = hit.getChunkId(); int chunkID = hit.getChunkId();
if (artifact != null) { if (artifact != null) {
if (chunkID != 0 && this.objectId == hit.getSolrObjectId()) { if (chunkID != 0 && this.solrObjectId == hit.getSolrObjectId()) {
String hit1 = hit.getHit(); String hit1 = hit.getHit();
if (keywords.stream().anyMatch(hit1::contains)) { if (keywords.stream().anyMatch(hit1::contains)) {
numberOfHitsPerPage.put(chunkID, 0); //unknown number of matches in the page numberOfHitsPerPage.put(chunkID, 0); //unknown number of matches in the page
@ -221,7 +221,7 @@ class HighlightedText implements IndexedText {
} }
} }
} else { } else {
if (chunkID != 0 && this.objectId == hit.getSolrObjectId()) { if (chunkID != 0 && this.solrObjectId == hit.getSolrObjectId()) {
numberOfHitsPerPage.put(chunkID, 0); //unknown number of matches in the page numberOfHitsPerPage.put(chunkID, 0); //unknown number of matches in the page
currentHitPerPage.put(chunkID, 0); //set current hit to 0th currentHitPerPage.put(chunkID, 0); //set current hit to 0th
@ -350,7 +350,7 @@ class HighlightedText implements IndexedText {
SolrQuery q = new SolrQuery(); SolrQuery q = new SolrQuery();
q.setShowDebugInfo(DEBUG); //debug q.setShowDebugInfo(DEBUG); //debug
String contentIdStr = Long.toString(this.objectId); String contentIdStr = Long.toString(this.solrObjectId);
if (numberPages != 0) { if (numberPages != 0) {
chunkID = Integer.toString(this.currentPage); chunkID = Integer.toString(this.currentPage);
contentIdStr += "0".equals(chunkID) ? "" : "_" + chunkID; contentIdStr += "0".equals(chunkID) ? "" : "_" + chunkID;
@ -423,7 +423,7 @@ class HighlightedText implements IndexedText {
return "<html><pre>" + highlightedContent + "</pre></html>"; //NON-NLS return "<html><pre>" + highlightedContent + "</pre></html>"; //NON-NLS
} catch (TskCoreException | KeywordSearchModuleException | NoOpenCoreException ex) { } catch (TskCoreException | KeywordSearchModuleException | NoOpenCoreException ex) {
logger.log(Level.SEVERE, "Error getting highlighted text for Solr doc id " + objectId + ", chunkID " + chunkID + ", highlight query: " + highlightField, ex); //NON-NLS logger.log(Level.SEVERE, "Error getting highlighted text for Solr doc id " + solrObjectId + ", chunkID " + chunkID + ", highlight query: " + highlightField, ex); //NON-NLS
return Bundle.IndexedText_errorMessage_errorGettingText(); return Bundle.IndexedText_errorMessage_errorGettingText();
} }
} }

View File

@ -1,7 +1,7 @@
/* /*
* Autopsy Forensic Browser * Autopsy Forensic Browser
* *
* Copyright 2013-2017 Basis Technology Corp. * Copyright 2013-2018 Basis Technology Corp.
* Contact: carrier <at> sleuthkit <dot> org * Contact: carrier <at> sleuthkit <dot> org
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
@ -39,6 +39,7 @@ import org.sleuthkit.autopsy.actions.AddContentTagAction;
import org.sleuthkit.autopsy.actions.DeleteFileContentTagAction; import org.sleuthkit.autopsy.actions.DeleteFileContentTagAction;
import org.sleuthkit.autopsy.directorytree.HashSearchAction; import org.sleuthkit.autopsy.directorytree.HashSearchAction;
import org.sleuthkit.autopsy.directorytree.NewWindowViewAction; import org.sleuthkit.autopsy.directorytree.NewWindowViewAction;
import org.sleuthkit.autopsy.keywordsearch.KeywordSearchResultFactory.AdHocQueryResult;
import org.sleuthkit.datamodel.AbstractFile; import org.sleuthkit.datamodel.AbstractFile;
import org.sleuthkit.datamodel.Content; import org.sleuthkit.datamodel.Content;
import org.sleuthkit.datamodel.ContentVisitor; import org.sleuthkit.datamodel.ContentVisitor;
@ -52,12 +53,18 @@ import org.sleuthkit.datamodel.TskData;
import org.sleuthkit.datamodel.VirtualDirectory; import org.sleuthkit.datamodel.VirtualDirectory;
/** /**
* * FilterNode containing properties and actions for keyword search.
*/ */
class KeywordSearchFilterNode extends FilterNode { class KeywordSearchFilterNode extends FilterNode {
KeywordSearchFilterNode(QueryResults highlights, Node original) { /**
super(original, null, new ProxyLookup(Lookups.singleton(highlights), original.getLookup())); * Instantiate a KeywordSearchFilterNode.
*
* @param adHocQueryResult The query content.
* @param original The original source node.
*/
KeywordSearchFilterNode(AdHocQueryResult adHocQueryResult, Node original) {
super(original, null, new ProxyLookup(Lookups.singleton(adHocQueryResult), original.getLookup()));
} }
@Override @Override

View File

@ -37,7 +37,6 @@ 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;
import org.openide.util.NbBundle; import org.openide.util.NbBundle;
import org.openide.util.lookup.Lookups;
import org.sleuthkit.autopsy.casemodule.Case; import org.sleuthkit.autopsy.casemodule.Case;
import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.autopsy.coreutils.Logger;
import org.sleuthkit.autopsy.coreutils.MessageNotifyUtil; import org.sleuthkit.autopsy.coreutils.MessageNotifyUtil;
@ -49,6 +48,7 @@ import org.sleuthkit.autopsy.datamodel.KeyValue;
import org.sleuthkit.autopsy.datamodel.KeyValueNode; import org.sleuthkit.autopsy.datamodel.KeyValueNode;
import org.sleuthkit.autopsy.keywordsearch.KeywordSearchResultFactory.KeyValueQueryContent; import org.sleuthkit.autopsy.keywordsearch.KeywordSearchResultFactory.KeyValueQueryContent;
import org.sleuthkit.datamodel.AbstractFile; import org.sleuthkit.datamodel.AbstractFile;
import org.sleuthkit.datamodel.BlackboardArtifact;
import org.sleuthkit.datamodel.BlackboardAttribute; import org.sleuthkit.datamodel.BlackboardAttribute;
import static org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_KEYWORD; import static org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_KEYWORD;
import static org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_KEYWORD_PREVIEW; import static org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_KEYWORD_PREVIEW;
@ -66,7 +66,7 @@ import org.sleuthkit.datamodel.TskCoreException;
*/ */
class KeywordSearchResultFactory extends ChildFactory<KeyValue> { class KeywordSearchResultFactory extends ChildFactory<KeyValue> {
private static final Logger LOGGER = Logger.getLogger(KeywordSearchResultFactory.class.getName()); private static final Logger logger = Logger.getLogger(KeywordSearchResultFactory.class.getName());
//common properties (superset of all Node properties) to be displayed as columns //common properties (superset of all Node properties) to be displayed as columns
static final List<String> COMMON_PROPERTIES static final List<String> COMMON_PROPERTIES
@ -75,10 +75,10 @@ class KeywordSearchResultFactory extends ChildFactory<KeyValue> {
TSK_KEYWORD, TSK_KEYWORD,
TSK_KEYWORD_REGEXP, TSK_KEYWORD_REGEXP,
TSK_KEYWORD_PREVIEW) TSK_KEYWORD_PREVIEW)
.map(BlackboardAttribute.ATTRIBUTE_TYPE::getDisplayName), .map(BlackboardAttribute.ATTRIBUTE_TYPE::getDisplayName),
Arrays.stream(AbstractAbstractFileNode.AbstractFilePropertyType.values()) Arrays.stream(AbstractAbstractFileNode.AbstractFilePropertyType.values())
.map(Object::toString)) .map(Object::toString))
.collect(Collectors.toList()); .collect(Collectors.toList());
private final Collection<QueryRequest> queryRequests; private final Collection<QueryRequest> queryRequests;
@ -140,7 +140,7 @@ class KeywordSearchResultFactory extends ChildFactory<KeyValue> {
try { try {
queryResults = queryRequest.performQuery(); queryResults = queryRequest.performQuery();
} catch (KeywordSearchModuleException | NoOpenCoreException ex) { } catch (KeywordSearchModuleException | NoOpenCoreException ex) {
LOGGER.log(Level.SEVERE, "Could not perform the query " + queryRequest.getQueryString(), ex); //NON-NLS logger.log(Level.SEVERE, "Could not perform the query " + queryRequest.getQueryString(), ex); //NON-NLS
MessageNotifyUtil.Notify.error(Bundle.KeywordSearchResultFactory_query_exception_msg() + queryRequest.getQueryString(), ex.getCause().getMessage()); MessageNotifyUtil.Notify.error(Bundle.KeywordSearchResultFactory_query_exception_msg() + queryRequest.getQueryString(), ex.getCause().getMessage());
return false; return false;
} }
@ -148,7 +148,7 @@ class KeywordSearchResultFactory extends ChildFactory<KeyValue> {
try { try {
tskCase = Case.getCurrentCase().getSleuthkitCase(); tskCase = Case.getCurrentCase().getSleuthkitCase();
} catch (IllegalStateException ex) { } catch (IllegalStateException ex) {
LOGGER.log(Level.SEVERE, "There was no case open.", ex); //NON-NLS logger.log(Level.SEVERE, "There was no case open.", ex); //NON-NLS
return false; return false;
} }
@ -165,11 +165,11 @@ class KeywordSearchResultFactory extends ChildFactory<KeyValue> {
try { try {
content = tskCase.getContentById(hit.getContentID()); content = tskCase.getContentById(hit.getContentID());
if (content == null) { if (content == null) {
LOGGER.log(Level.SEVERE, "There was a error getting content by id."); //NON-NLS logger.log(Level.SEVERE, "There was a error getting content by id."); //NON-NLS
return false; return false;
} }
} catch (TskCoreException ex) { } catch (TskCoreException ex) {
LOGGER.log(Level.SEVERE, "There was a error getting content by id.", ex); //NON-NLS logger.log(Level.SEVERE, "There was a error getting content by id.", ex); //NON-NLS
return false; return false;
} }
@ -188,18 +188,20 @@ class KeywordSearchResultFactory extends ChildFactory<KeyValue> {
} }
String hitName; String hitName;
BlackboardArtifact artifact = null;
if (hit.isArtifactHit()) { if (hit.isArtifactHit()) {
try { try {
hitName = tskCase.getBlackboardArtifact(hit.getArtifactID().get()).getDisplayName() + " Artifact"; //NON-NLS artifact = tskCase.getBlackboardArtifact(hit.getArtifactID().get());
hitName = artifact.getDisplayName() + " Artifact"; //NON-NLS
} catch (TskCoreException ex) { } catch (TskCoreException ex) {
LOGGER.log(Level.SEVERE, "Error getting blckboard artifact by id", ex); logger.log(Level.SEVERE, "Error getting blckboard artifact by id", ex);
return false; return false;
} }
} else { } else {
hitName = contentName; hitName = contentName;
} }
hitNumber++; hitNumber++;
tempList.add(new KeyValueQueryContent(hitName, properties, hitNumber, hit.getSolrObjectId(), content, queryRequest, queryResults)); tempList.add(new KeyValueQueryContent(hitName, properties, hitNumber, hit.getSolrObjectId(), content, artifact, queryRequest, queryResults));
} }
@ -250,13 +252,12 @@ class KeywordSearchResultFactory extends ChildFactory<KeyValue> {
Node resultNode; Node resultNode;
if (key instanceof KeyValueQueryContent) { if (key instanceof KeyValueQueryContent) {
final Content content = ((KeyValueQueryContent) key).getContent(); AdHocQueryResult adHocQueryResult = new AdHocQueryResult((KeyValueQueryContent) key);
QueryResults hits = ((KeyValueQueryContent) key).getHits();
Node kvNode = new KeyValueNode(key, Children.LEAF, Lookups.singleton(content)); Node kvNode = new KeyValueNode(key, Children.LEAF);
//wrap in KeywordSearchFilterNode for the markup content, might need to override FilterNode for more customization //wrap in KeywordSearchFilterNode for the markup content, might need to override FilterNode for more customization
resultNode = new KeywordSearchFilterNode(hits, kvNode); resultNode = new KeywordSearchFilterNode(adHocQueryResult, kvNode);
} else { } else {
resultNode = new EmptyNode("This Node Is Empty"); resultNode = new EmptyNode("This Node Is Empty");
resultNode.setDisplayName(NbBundle.getMessage(this.getClass(), "KeywordSearchResultFactory.createNodeForKey.noResultsFound.text")); resultNode.setDisplayName(NbBundle.getMessage(this.getClass(), "KeywordSearchResultFactory.createNodeForKey.noResultsFound.text"));
@ -266,6 +267,75 @@ class KeywordSearchResultFactory extends ChildFactory<KeyValue> {
} }
/**
* This class encapsulates content, query results, and an associated Solr
* object ID for storing in the Lookup to be read later.
*/
final class AdHocQueryResult {
private final long solrObjectId;
private final Content content;
private final BlackboardArtifact artifact;
private final QueryResults results;
/**
* Instantiate a AdHocQueryResult object.
*
* @param solrObjectId The Solr object ID associated with the object in
* which the hit was found.
* @param content The content for the query result.
* @param artifact The artifact associated with the query result.
* @param results The query results.
*/
AdHocQueryResult(KeyValueQueryContent key) {
this.solrObjectId = key.getSolrObjectId();
this.content = key.getContent();
this.artifact = key.getArtifact();
this.results = key.getHits();
}
/**
* Get the Solr object ID associated with the object in which the hit
* was found. This could be a file or an artifact.
*
* @return The Solr object ID.
*/
long getSolrObjectId() {
return solrObjectId;
}
/**
* Get the content for the query result. This can be either a file or a
* data source, and it may or may not be the content in which the hit
* occurred. If the hit is in a file, the Content object represents that
* file. But if the hit is in an artifact, the Content object represents
* the source file or data source of the artifact.
*
* @return The content object.
*/
Content getContent() {
return content;
}
/**
* Get the artifact for the query result.
*
* @return The artifact.
*/
BlackboardArtifact getArtifact() {
return artifact;
}
/**
* Get the query results.
*
* @return The query results.
*/
QueryResults getResults() {
return results;
}
}
/** /**
* Used to display keyword search results in table. Eventually turned into a * Used to display keyword search results in table. Eventually turned into a
* node. * node.
@ -275,6 +345,7 @@ class KeywordSearchResultFactory extends ChildFactory<KeyValue> {
private final long solrObjectId; private final long solrObjectId;
private final Content content; private final Content content;
private final BlackboardArtifact artifact;
private final QueryResults hits; private final QueryResults hits;
private final KeywordSearchQuery query; private final KeywordSearchQuery query;
@ -286,15 +357,17 @@ class KeywordSearchResultFactory extends ChildFactory<KeyValue> {
* @param map Contains content metadata, snippets, etc. * @param map Contains content metadata, snippets, etc.
* (property map) * (property map)
* @param id User incremented ID * @param id User incremented ID
* @param solrObjectId * @param solrObjectId The ID of the object.
* @param content File that had the hit. * @param content The content object.
* @param artifact The blackboard artifact.
* @param query Query used in search * @param query Query used in search
* @param hits Full set of search results (for all files! @@@) * @param hits Full set of search results (for all files! @@@)
*/ */
KeyValueQueryContent(String name, Map<String, Object> map, int id, long solrObjectId, Content content, KeywordSearchQuery query, QueryResults hits) { KeyValueQueryContent(String name, Map<String, Object> map, int id, long solrObjectId, Content content, BlackboardArtifact artifact, KeywordSearchQuery query, QueryResults hits) {
super(name, map, id); super(name, map, id);
this.solrObjectId = solrObjectId; this.solrObjectId = solrObjectId;
this.content = content; this.content = content;
this.artifact = artifact;
this.hits = hits; this.hits = hits;
this.query = query; this.query = query;
@ -304,6 +377,10 @@ class KeywordSearchResultFactory extends ChildFactory<KeyValue> {
return content; return content;
} }
BlackboardArtifact getArtifact() {
return artifact;
}
long getSolrObjectId() { long getSolrObjectId() {
return solrObjectId; return solrObjectId;
} }
@ -358,9 +435,9 @@ class KeywordSearchResultFactory extends ChildFactory<KeyValue> {
try { try {
get(); get();
} catch (InterruptedException | CancellationException ex) { } catch (InterruptedException | CancellationException ex) {
LOGGER.log(Level.WARNING, "User cancelled writing of ad hoc search query results for '{0}' to the blackboard", query.getQueryString()); //NON-NLS logger.log(Level.WARNING, "User cancelled writing of ad hoc search query results for '{0}' to the blackboard", query.getQueryString()); //NON-NLS
} catch (ExecutionException ex) { } catch (ExecutionException ex) {
LOGGER.log(Level.SEVERE, "Error writing of ad hoc search query results for " + query.getQueryString() + " to the blackboard", ex); //NON-NLS logger.log(Level.SEVERE, "Error writing of ad hoc search query results for " + query.getQueryString() + " to the blackboard", ex); //NON-NLS
} }
} }