6531 resolve merge conflicts

This commit is contained in:
William Schaefer
2020-07-22 11:45:27 -04:00
6 changed files with 122 additions and 14 deletions
@@ -23,6 +23,7 @@ import java.awt.Color;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.EnumSet;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.logging.Level;
@@ -30,21 +31,31 @@ import org.apache.commons.lang.StringUtils;
import org.openide.util.NbBundle.Messages;
import org.openide.windows.WindowManager;
import org.sleuthkit.autopsy.casemodule.Case;
import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException;
import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepoException;
import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepository;
import org.sleuthkit.autopsy.coreutils.Logger;
import org.sleuthkit.autopsy.discovery.FileGroup.GroupSortingAlgorithm;
import static org.sleuthkit.autopsy.discovery.FileGroup.GroupSortingAlgorithm.BY_GROUP_SIZE;
import org.sleuthkit.autopsy.discovery.FileSearch.GroupingAttributeType;
import static org.sleuthkit.autopsy.discovery.FileSearch.GroupingAttributeType.PARENT_PATH;
import org.sleuthkit.autopsy.discovery.FileSorter.SortingMethod;
import org.sleuthkit.autopsy.ingest.IngestManager;
import org.sleuthkit.autopsy.ingest.ModuleDataEvent;
import org.sleuthkit.datamodel.BlackboardArtifact;
import org.sleuthkit.datamodel.BlackboardAttribute;
import org.sleuthkit.datamodel.TskCoreException;
import static org.sleuthkit.autopsy.discovery.FileSorter.SortingMethod.BY_FILE_NAME;
/**
* Dialog for displaying the controls and filters for configuration of a
* Discovery search.
*/
final class DiscoveryDialog extends javax.swing.JDialog {
private static final Set<Case.Events> CASE_EVENTS_OF_INTEREST = EnumSet.of(Case.Events.CURRENT_CASE,
Case.Events.DATA_SOURCE_ADDED, Case.Events.DATA_SOURCE_DELETED);
private static final Set<IngestManager.IngestModuleEvent> INGEST_MODULE_EVENTS_OF_INTEREST = EnumSet.of(IngestManager.IngestModuleEvent.DATA_ADDED);
private static final long serialVersionUID = 1L;
private final static Logger logger = Logger.getLogger(DiscoveryDialog.class.getName());
private ImageFilterPanel imageFilterPanel = null;
@@ -54,8 +65,12 @@ final class DiscoveryDialog extends javax.swing.JDialog {
private static final Color UNSELECTED_COLOR = new Color(240, 240, 240);
private SearchWorker searchWorker = null;
private static DiscoveryDialog discDialog;
private static volatile boolean shouldUpdate = false;
private FileSearchData.FileType fileType = FileSearchData.FileType.IMAGE;
private final PropertyChangeListener listener;
private final Set<BlackboardAttribute> objectsDetected = new HashSet<>();
private final Set<BlackboardAttribute> interestingItems = new HashSet<>();
private final Set<BlackboardAttribute> hashSets = new HashSet<>();
/**
* Get the Discovery dialog instance.
@@ -66,6 +81,10 @@ final class DiscoveryDialog extends javax.swing.JDialog {
if (discDialog == null) {
discDialog = new DiscoveryDialog();
}
if (shouldUpdate) {
discDialog.updateSearchSettings();
shouldUpdate = false;
}
return discDialog;
}
@@ -89,6 +108,7 @@ final class DiscoveryDialog extends javax.swing.JDialog {
}
updateSearchSettings();
Case.addEventTypeSubscriber(CASE_EVENTS_OF_INTEREST, this.new CasePropertyChangeListener());
IngestManager.getInstance().addIngestModuleEventListener(INGEST_MODULE_EVENTS_OF_INTEREST, this.new ModuleChangeListener());
}
/**
@@ -116,6 +136,7 @@ final class DiscoveryDialog extends javax.swing.JDialog {
add(imageFilterPanel, CENTER);
imageFilterPanel.addPropertyChangeListener(listener);
updateComboBoxes();
groupSortingComboBox.setSelectedItem(BY_GROUP_SIZE);
pack();
repaint();
}
@@ -129,6 +150,7 @@ final class DiscoveryDialog extends javax.swing.JDialog {
for (FileSearch.GroupingAttributeType type : FileSearch.GroupingAttributeType.getOptionsForGrouping()) {
addTypeToGroupByComboBox(type);
}
groupByCombobox.setSelectedItem(PARENT_PATH);
orderByCombobox.removeAllItems();
// Set up the file order list
for (FileSorter.SortingMethod method : FileSorter.SortingMethod.getOptionsForOrdering()) {
@@ -136,7 +158,7 @@ final class DiscoveryDialog extends javax.swing.JDialog {
orderByCombobox.addItem(method);
}
}
groupSortingComboBox.setSelectedIndex(0);
orderByCombobox.setSelectedItem(BY_FILE_NAME);
}
/**
@@ -512,7 +534,7 @@ final class DiscoveryDialog extends javax.swing.JDialog {
tc.toFront();
tc.requestActive();
}//GEN-LAST:event_searchButtonActionPerformed
@Override
public void dispose() {
setVisible(false);
@@ -531,7 +553,8 @@ final class DiscoveryDialog extends javax.swing.JDialog {
* The adjust the controls to reflect whether the settings are valid based
* on the error.
*
* @param error The error message to display, empty string if there is no error.
* @param error The error message to display, empty string if there is no
* error.
*/
private void setValid(String error) {
if (StringUtils.isBlank(error)) {
@@ -560,7 +583,7 @@ final class DiscoveryDialog extends javax.swing.JDialog {
* filters available.
*/
private class CasePropertyChangeListener implements PropertyChangeListener {
@Override
@SuppressWarnings("fallthrough")
public void propertyChange(PropertyChangeEvent evt) {
@@ -575,7 +598,7 @@ final class DiscoveryDialog extends javax.swing.JDialog {
case DATA_SOURCE_ADDED:
//fallthrough
case DATA_SOURCE_DELETED:
updateSearchSettings();
shouldUpdate = true;
break;
default:
//do nothing if the event is not one of the above events.
@@ -583,4 +606,83 @@ final class DiscoveryDialog extends javax.swing.JDialog {
}
}
}
/**
* PropertyChangeListener to listen to ingest module events that may modify
* the filters available.
*/
private class ModuleChangeListener implements PropertyChangeListener {
@Override
@SuppressWarnings("fallthrough")
public void propertyChange(PropertyChangeEvent evt) {
if (!shouldUpdate) {
String eventType = evt.getPropertyName();
if (eventType.equals(IngestManager.IngestModuleEvent.DATA_ADDED.toString())) {
/**
* Checking for a current case is a stop gap measure until a
* different way of handling the closing of cases is worked
* out. Currently, remote events may be received for a case
* that is already closed.
*/
try {
Case.getCurrentCaseThrows();
/**
* Even with the check above, it is still possible that
* the case will be closed in a different thread before
* this code executes. If that happens, it is possible
* for the event to have a null oldValue.
*/
ModuleDataEvent eventData = (ModuleDataEvent) evt.getOldValue();
if (null != eventData) {
if (eventData.getBlackboardArtifactType().getTypeID() == BlackboardArtifact.ARTIFACT_TYPE.TSK_OBJECT_DETECTED.getTypeID() && eventData.getArtifacts() != null) {
shouldUpdate = shouldUpdateFilters(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DESCRIPTION.getTypeID(), eventData, objectsDetected);
} else if (eventData.getBlackboardArtifactType().getTypeID() == BlackboardArtifact.ARTIFACT_TYPE.TSK_HASHSET_HIT.getTypeID()) {
shouldUpdate = shouldUpdateFilters(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_SET_NAME.getTypeID(), eventData, hashSets);
} else if (eventData.getBlackboardArtifactType().getTypeID() == BlackboardArtifact.ARTIFACT_TYPE.TSK_INTERESTING_FILE_HIT.getTypeID()
|| eventData.getBlackboardArtifactType().getTypeID() == BlackboardArtifact.ARTIFACT_TYPE.TSK_INTERESTING_ARTIFACT_HIT.getTypeID()) {
shouldUpdate = shouldUpdateFilters(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_SET_NAME.getTypeID(), eventData, interestingItems);
}
}
} catch (NoCurrentCaseException notUsed) {
// Case is closed, do nothing.
} catch (TskCoreException ex) {
logger.log(Level.WARNING, "Unable to determine if discovery UI should be updated", ex);
}
}
}
}
/**
* Helper method to determine if the artifact in the eventData
* represents a new value for the filter.
*
* @param attributeTypeId The attribute id of the attribute which
* contains the value for the filter.
* @param eventData The event which contains the artifacts.
* @param filterSetToCheck The set of current values for the relevant
* filter.
*
* @return True if the value is a new value for the filter, false
* otherwise.
*
* @throws TskCoreException Thrown because the attributes were unable to
* be retrieved for one of the artifacts in the
* eventData.
*/
private boolean shouldUpdateFilters(int attributeTypeId, ModuleDataEvent eventData, Set<BlackboardAttribute> filterSetToCheck) throws TskCoreException {
for (BlackboardArtifact artifact : eventData.getArtifacts()) {
if (artifact.getAttributes() != null) {
for (BlackboardAttribute attr : artifact.getAttributes()) {
if (attr.getAttributeType().getTypeID() == attributeTypeId && !filterSetToCheck.contains(attr)) {
filterSetToCheck.add(attr);
return true;
}
}
}
}
return false;
}
}
}
@@ -54,9 +54,11 @@ public final class DiscoveryTopComponent extends TopComponent {
private final ResultsPanel resultsPanel;
private int dividerLocation = -1;
private static final int ANIMATION_INCREMENT = 10;
private volatile static int resultsAreaSize = 250;
private volatile static int previousResultsAreaSize = -1;
private static final int ANIMATION_INCREMENT = 30;
private SwingAnimator animator = null;
@@ -34,13 +34,15 @@ final class DocumentFilterPanel extends AbstractFiltersPanel {
DocumentFilterPanel() {
super();
initComponents();
addFilter(new SizeFilterPanel(FileSearchData.FileType.DOCUMENTS), false, null, 0);
SizeFilterPanel sizeFilterPanel = new SizeFilterPanel(FILE_TYPE);
int[] sizeIndicesSelected = {3, 4, 5};
addFilter(sizeFilterPanel, true, sizeIndicesSelected, 0);
addFilter(new DataSourceFilterPanel(), false, null, 0);
int[] pastOccurrencesIndices;
if (!CentralRepository.isEnabled()) {
pastOccurrencesIndices = new int[]{0};
} else {
pastOccurrencesIndices = new int[]{1, 2, 3, 4, 5, 6, 7};
pastOccurrencesIndices = new int[]{2, 3, 4};
}
addFilter(new PastOccurrencesFilterPanel(), true, pastOccurrencesIndices, 0);
addFilter(new HashSetFilterPanel(), false, null, 1);
@@ -35,14 +35,14 @@ final class ImageFilterPanel extends AbstractFiltersPanel {
super();
initComponents();
SizeFilterPanel sizeFilterPanel = new SizeFilterPanel(FILE_TYPE);
int[] sizeIndicesSelected = {1, 2, 3, 4, 5};
int[] sizeIndicesSelected = {3, 4, 5};
addFilter(sizeFilterPanel, true, sizeIndicesSelected, 0);
addFilter(new DataSourceFilterPanel(), false, null, 0);
int[] pastOccurrencesIndices;
if (!CentralRepository.isEnabled()) {
pastOccurrencesIndices = new int[]{0};
} else {
pastOccurrencesIndices = new int[]{1, 2, 3, 4, 5, 6, 7};
pastOccurrencesIndices = new int[]{2, 3, 4};
}
addFilter(new PastOccurrencesFilterPanel(), true, pastOccurrencesIndices, 0);
addFilter(new UserCreatedFilterPanel(), false, null, 1);
@@ -39,7 +39,7 @@ final class SwingAnimator {
private Timer timer = null;
//duration in milliseconds betweeen each firing of the Timer
private static final int INITIAL_TIMING = 10;
private static final int INITIAL_TIMING = 30;
private int timing = INITIAL_TIMING;
/**
@@ -34,13 +34,15 @@ final class VideoFilterPanel extends AbstractFiltersPanel {
VideoFilterPanel() {
super();
initComponents();
addFilter(new SizeFilterPanel(FileSearchData.FileType.VIDEO), false, null, 0);
SizeFilterPanel sizeFilterPanel = new SizeFilterPanel(FILE_TYPE);
int[] sizeIndicesSelected = {3, 4, 5};
addFilter(sizeFilterPanel, true, sizeIndicesSelected, 0);
addFilter(new DataSourceFilterPanel(), false, null, 0);
int[] pastOccurrencesIndices;
if (!CentralRepository.isEnabled()) {
pastOccurrencesIndices = new int[]{0};
} else {
pastOccurrencesIndices = new int[]{1, 2, 3, 4, 5, 6, 7};
pastOccurrencesIndices = new int[]{2, 3, 4};
}
addFilter(new PastOccurrencesFilterPanel(), true, pastOccurrencesIndices, 0);
addFilter(new UserCreatedFilterPanel(), false, null, 1);