diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/Case.java b/Core/src/org/sleuthkit/autopsy/casemodule/Case.java index 340d847343..d6226a06d8 100644 --- a/Core/src/org/sleuthkit/autopsy/casemodule/Case.java +++ b/Core/src/org/sleuthkit/autopsy/casemodule/Case.java @@ -377,7 +377,9 @@ public class Case { * * @param eventNames The events the subscriber is interested in. * @param subscriber The subscriber (PropertyChangeListener) to add. + * @deprecated Use addEventTypeSubscriber instead. */ + @Deprecated public static void addEventSubscriber(Set eventNames, PropertyChangeListener subscriber) { eventPublisher.addSubscriber(eventNames, subscriber); } @@ -385,9 +387,23 @@ public class Case { /** * Adds a subscriber to specific case events. * - * @param eventName The event the subscriber is interested in. + * @param eventTypes The events the subscriber is interested in. * @param subscriber The subscriber (PropertyChangeListener) to add. */ + public static void addEventTypeSubscriber(Set eventTypes, PropertyChangeListener subscriber) { + eventTypes.forEach((Events event) -> { + eventPublisher.addSubscriber(event.toString(), subscriber); + }); + } + + /** + * Adds a subscriber to specific case events. + * + * @param eventName The event the subscriber is interested in. + * @param subscriber The subscriber (PropertyChangeListener) to add. + * @deprecated Use addEventTypeSubscriber instead. + */ + @Deprecated public static void addEventSubscriber(String eventName, PropertyChangeListener subscriber) { eventPublisher.addSubscriber(eventName, subscriber); } @@ -412,6 +428,18 @@ public class Case { eventPublisher.removeSubscriber(eventNames, subscriber); } + /** + * Removes a subscriber to specific case events. + * + * @param eventTypes The events the subscriber is no longer interested in. + * @param subscriber The subscriber (PropertyChangeListener) to remove. + */ + public static void removeEventTypeSubscriber(Set eventTypes, PropertyChangeListener subscriber) { + eventTypes.forEach((Events event) -> { + eventPublisher.removeSubscriber(event.toString(), subscriber); + }); + } + /** * Checks if a case display name is valid, i.e., does not include any * characters that cannot be used in file names. diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/CaseDeleteAction.java b/Core/src/org/sleuthkit/autopsy/casemodule/CaseDeleteAction.java index 2df3bfcc33..3ef30f2594 100644 --- a/Core/src/org/sleuthkit/autopsy/casemodule/CaseDeleteAction.java +++ b/Core/src/org/sleuthkit/autopsy/casemodule/CaseDeleteAction.java @@ -20,6 +20,7 @@ package org.sleuthkit.autopsy.casemodule; import java.awt.event.ActionEvent; import java.beans.PropertyChangeEvent; +import java.util.EnumSet; import java.util.concurrent.ExecutionException; import java.util.logging.Level; import javax.swing.Action; @@ -49,7 +50,7 @@ final class CaseDeleteAction extends CallableSystemAction { CaseDeleteAction() { putValue(Action.NAME, NbBundle.getMessage(CaseDeleteAction.class, "CTL_CaseDeleteAction")); this.setEnabled(false); - Case.addEventSubscriber(Case.Events.CURRENT_CASE.toString(), (PropertyChangeEvent evt) -> { + Case.addEventTypeSubscriber(EnumSet.of(Case.Events.CURRENT_CASE), (PropertyChangeEvent evt) -> { setEnabled(null != evt.getNewValue() && UserPreferences.getMode() != UserPreferences.SelectedMode.REVIEW); }); } diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/CasePropertiesAction.java b/Core/src/org/sleuthkit/autopsy/casemodule/CasePropertiesAction.java index 7cd6a93b10..c50c561564 100644 --- a/Core/src/org/sleuthkit/autopsy/casemodule/CasePropertiesAction.java +++ b/Core/src/org/sleuthkit/autopsy/casemodule/CasePropertiesAction.java @@ -22,6 +22,7 @@ import java.awt.Dimension; import java.awt.Toolkit; import java.awt.event.ActionEvent; import java.beans.PropertyChangeEvent; +import java.util.EnumSet; import javax.swing.Action; import javax.swing.JDialog; import javax.swing.SwingUtilities; @@ -42,7 +43,7 @@ final class CasePropertiesAction extends CallableSystemAction { CasePropertiesAction() { putValue(Action.NAME, NbBundle.getMessage(CasePropertiesAction.class, "CTL_CasePropertiesAction")); this.setEnabled(false); - Case.addEventSubscriber(Case.Events.CURRENT_CASE.toString(), (PropertyChangeEvent evt) -> { + Case.addEventTypeSubscriber(EnumSet.of(Case.Events.CURRENT_CASE), (PropertyChangeEvent evt) -> { setEnabled(null != evt.getNewValue()); }); } diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/CollaborationMonitor.java b/Core/src/org/sleuthkit/autopsy/casemodule/CollaborationMonitor.java index 6042c24d12..ab55b67c5b 100644 --- a/Core/src/org/sleuthkit/autopsy/casemodule/CollaborationMonitor.java +++ b/Core/src/org/sleuthkit/autopsy/casemodule/CollaborationMonitor.java @@ -24,9 +24,8 @@ import java.beans.PropertyChangeListener; import java.io.Serializable; import java.time.Duration; import java.time.Instant; -import java.util.Arrays; +import java.util.EnumSet; import java.util.HashMap; -import java.util.HashSet; import java.util.Iterator; import java.util.Map; import java.util.Set; @@ -57,7 +56,8 @@ final class CollaborationMonitor { private static final String EVENT_CHANNEL_NAME = "%s-Collaboration-Monitor-Events"; //NON-NLS private static final String COLLABORATION_MONITOR_EVENT = "COLLABORATION_MONITOR_EVENT"; //NON-NLS - private static final Set CASE_EVENTS_OF_INTEREST = new HashSet<>(Arrays.asList(new String[]{Case.Events.ADDING_DATA_SOURCE.toString(), Case.Events.DATA_SOURCE_ADDED.toString(), Case.Events.ADDING_DATA_SOURCE_FAILED.toString()})); + private static final Set CASE_EVENTS_OF_INTEREST = EnumSet.of(Case.Events.ADDING_DATA_SOURCE, + Case.Events.DATA_SOURCE_ADDED, Case.Events.ADDING_DATA_SOURCE_FAILED); private static final int NUMBER_OF_PERIODIC_TASK_THREADS = 2; private static final String PERIODIC_TASK_THREAD_NAME = "collab-monitor-periodic-tasks-%d"; //NON-NLS private static final long HEARTBEAT_INTERVAL_MINUTES = 1; @@ -113,7 +113,7 @@ final class CollaborationMonitor { */ localTasksManager = new LocalTasksManager(); IngestManager.getInstance().addIngestJobEventListener(localTasksManager); - Case.addEventSubscriber(CASE_EVENTS_OF_INTEREST, localTasksManager); + Case.addEventTypeSubscriber(CASE_EVENTS_OF_INTEREST, localTasksManager); /** * Start periodic tasks that: @@ -141,7 +141,7 @@ final class CollaborationMonitor { } } - Case.removeEventSubscriber(CASE_EVENTS_OF_INTEREST, localTasksManager); + Case.removeEventTypeSubscriber(CASE_EVENTS_OF_INTEREST, localTasksManager); IngestManager.getInstance().removeIngestJobEventListener(localTasksManager); if (null != eventPublisher) { diff --git a/Core/src/org/sleuthkit/autopsy/coreutils/ImageUtils.java b/Core/src/org/sleuthkit/autopsy/coreutils/ImageUtils.java index eb6a16e6e0..eabc56e3bd 100755 --- a/Core/src/org/sleuthkit/autopsy/coreutils/ImageUtils.java +++ b/Core/src/org/sleuthkit/autopsy/coreutils/ImageUtils.java @@ -35,6 +35,7 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.Collections; +import java.util.EnumSet; import java.util.Iterator; import java.util.List; import static java.util.Objects.nonNull; @@ -153,7 +154,7 @@ public class ImageUtils { SUPPORTED_IMAGE_MIME_TYPES.removeIf("application/octet-stream"::equals); //NON-NLS //Clear the file map when the case changes, so we don't accidentaly get images from the old case. - Case.addEventSubscriber(Case.Events.CURRENT_CASE.toString(), evt -> cacheFileMap.clear()); + Case.addEventTypeSubscriber(EnumSet.of(Case.Events.CURRENT_CASE), evt -> cacheFileMap.clear()); } /** diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/AbstractAbstractFileNode.java b/Core/src/org/sleuthkit/autopsy/datamodel/AbstractAbstractFileNode.java index e3c750826d..f3e08622d5 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/AbstractAbstractFileNode.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/AbstractAbstractFileNode.java @@ -21,9 +21,11 @@ package org.sleuthkit.autopsy.datamodel; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import java.util.ArrayList; +import java.util.EnumSet; import java.util.List; import org.openide.nodes.Children; import java.util.Map; +import java.util.Set; import java.util.logging.Level; import java.util.stream.Collectors; import org.apache.commons.lang3.StringUtils; @@ -49,6 +51,9 @@ public abstract class AbstractAbstractFileNode extends A private static final Logger LOGGER = Logger.getLogger(AbstractAbstractFileNode.class.getName()); + private static final Set CASE_EVENTS_OF_INTEREST = EnumSet.of(Case.Events.CURRENT_CASE, + Case.Events.CONTENT_TAG_ADDED, Case.Events.CONTENT_TAG_DELETED); + /** * @param type of the AbstractFile data to encapsulate * @param abstractFile file to encapsulate @@ -68,13 +73,14 @@ public abstract class AbstractAbstractFileNode extends A } } } - // Listen for case events so that we can detect when case is closed - Case.addPropertyChangeListener(pcl); + // Listen for case events so that we can detect when the case is closed + // or when tags are added. + Case.addEventTypeSubscriber(CASE_EVENTS_OF_INTEREST, pcl); } private void removeListeners() { IngestManager.getInstance().removeIngestModuleEventListener(pcl); - Case.removePropertyChangeListener(pcl); + Case.removeEventTypeSubscriber(CASE_EVENTS_OF_INTEREST, pcl); } private final PropertyChangeListener pcl = (PropertyChangeEvent evt) -> { @@ -96,7 +102,11 @@ public abstract class AbstractAbstractFileNode extends A // If so, refresh our children. try { Children parentsChildren = getParentNode().getChildren(); - if (parentsChildren != null) { + // We only want to refresh our parents children if we are in the + // data sources branch of the tree. The parent nodes in other + // branches of the tree (e.g. File Types and Deleted Files) do + // not need to be refreshed. + if (parentsChildren instanceof ContentChildren) { ((ContentChildren) parentsChildren).refreshChildren(); parentsChildren.getNodesCount(); } diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactNode.java b/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactNode.java index 47870bb9bf..ad96345202 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactNode.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactNode.java @@ -25,6 +25,7 @@ import java.beans.PropertyChangeListener; import java.text.MessageFormat; import java.util.ArrayList; import java.util.Arrays; +import java.util.EnumSet; import java.util.HashSet; import java.util.LinkedHashMap; import java.util.List; @@ -67,13 +68,11 @@ import org.sleuthkit.datamodel.TskCoreException; public class BlackboardArtifactNode extends DisplayableItemNode { private static final Logger LOGGER = Logger.getLogger(BlackboardArtifactNode.class.getName()); - private static final Set CASE_EVENTS_OF_INTEREST = new HashSet<>(Arrays.asList(new String[]{ - Case.Events.BLACKBOARD_ARTIFACT_TAG_ADDED.toString(), - Case.Events.BLACKBOARD_ARTIFACT_TAG_DELETED.toString(), - Case.Events.CONTENT_TAG_ADDED.toString(), - Case.Events.CONTENT_TAG_DELETED.toString(), - Case.Events.CURRENT_CASE.toString() - })); + private static final Set CASE_EVENTS_OF_INTEREST = EnumSet.of(Case.Events.BLACKBOARD_ARTIFACT_TAG_ADDED, + Case.Events.BLACKBOARD_ARTIFACT_TAG_DELETED, + Case.Events.CONTENT_TAG_ADDED, + Case.Events.CONTENT_TAG_DELETED, + Case.Events.CURRENT_CASE); private static Cache contentCache = CacheBuilder.newBuilder() .expireAfterWrite(1, TimeUnit.MINUTES). @@ -148,7 +147,7 @@ public class BlackboardArtifactNode extends DisplayableItemNode { this.setName(Long.toString(artifact.getArtifactID())); this.setDisplayName(); this.setIconBaseWithExtension(iconPath); - Case.addEventSubscriber(CASE_EVENTS_OF_INTEREST, WeakListeners.propertyChange(pcl, null)); + Case.addEventTypeSubscriber(CASE_EVENTS_OF_INTEREST, WeakListeners.propertyChange(pcl, null)); } /** @@ -165,11 +164,11 @@ public class BlackboardArtifactNode extends DisplayableItemNode { this.setName(Long.toString(artifact.getArtifactID())); this.setDisplayName(); this.setIconBaseWithExtension(ExtractedContent.getIconFilePath(artifact.getArtifactTypeID())); //NON-NLS - Case.addEventSubscriber(CASE_EVENTS_OF_INTEREST, WeakListeners.propertyChange(pcl, null)); + Case.addEventTypeSubscriber(CASE_EVENTS_OF_INTEREST, WeakListeners.propertyChange(pcl, null)); } private void removeListeners() { - Case.removeEventSubscriber(CASE_EVENTS_OF_INTEREST, pcl); + Case.removeEventTypeSubscriber(CASE_EVENTS_OF_INTEREST, pcl); } @Override diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/DataSourcesNode.java b/Core/src/org/sleuthkit/autopsy/datamodel/DataSourcesNode.java index 7ac9e37398..43ddd069a3 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/DataSourcesNode.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/DataSourcesNode.java @@ -22,6 +22,7 @@ import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import java.util.ArrayList; import java.util.Collections; +import java.util.EnumSet; import java.util.List; import java.util.logging.Level; import org.openide.nodes.Sheet; @@ -88,13 +89,13 @@ public class DataSourcesNode extends DisplayableItemNode { @Override protected void addNotify() { - Case.addPropertyChangeListener(pcl); + Case.addEventTypeSubscriber(EnumSet.of(Case.Events.DATA_SOURCE_ADDED), pcl); reloadKeys(); } @Override protected void removeNotify() { - Case.removePropertyChangeListener(pcl); + Case.removeEventTypeSubscriber(EnumSet.of(Case.Events.DATA_SOURCE_ADDED), pcl); currentKeys.clear(); setKeys(Collections.emptySet()); } diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/DeletedContent.java b/Core/src/org/sleuthkit/autopsy/datamodel/DeletedContent.java index 9c738fb3ed..a8873decde 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/DeletedContent.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/DeletedContent.java @@ -22,9 +22,11 @@ import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import java.util.ArrayList; import java.util.Arrays; +import java.util.EnumSet; import java.util.List; import java.util.Observable; import java.util.Observer; +import java.util.Set; import java.util.logging.Level; import javax.swing.JOptionPane; import javax.swing.SwingUtilities; @@ -172,68 +174,69 @@ public class DeletedContent implements AutopsyVisitableItem { * Listens for case and ingest invest. Updates observers when events are * fired. Other nodes are listening to this for changes. */ - private final class DeletedContentsChildrenObservable extends Observable { + private static final class DeletedContentsChildrenObservable extends Observable { + private static final Set CASE_EVENTS_OF_INTEREST = EnumSet.of( + Case.Events.DATA_SOURCE_ADDED, + Case.Events.CURRENT_CASE + ); DeletedContentsChildrenObservable() { IngestManager.getInstance().addIngestJobEventListener(pcl); IngestManager.getInstance().addIngestModuleEventListener(pcl); - Case.addPropertyChangeListener(pcl); + Case.addEventTypeSubscriber(CASE_EVENTS_OF_INTEREST, pcl); } private void removeListeners() { deleteObservers(); IngestManager.getInstance().removeIngestJobEventListener(pcl); IngestManager.getInstance().removeIngestModuleEventListener(pcl); - Case.removePropertyChangeListener(pcl); + Case.removeEventTypeSubscriber(CASE_EVENTS_OF_INTEREST, pcl); } - private final PropertyChangeListener pcl = new PropertyChangeListener() { - @Override - public void propertyChange(PropertyChangeEvent evt) { - String eventType = evt.getPropertyName(); - if (eventType.equals(IngestManager.IngestModuleEvent.CONTENT_CHANGED.toString())) { + private final PropertyChangeListener pcl = (PropertyChangeEvent evt) -> { + String eventType = evt.getPropertyName(); + if (eventType.equals(IngestManager.IngestModuleEvent.CONTENT_CHANGED.toString())) { + /** + * + // @@@ COULD CHECK If the new file is deleted + * before notifying... Checking for a current case is a + * stop gap measure + update(); 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.getCurrentCase(); + // new file was added + // @@@ COULD CHECK If the new file is deleted before notifying... + update(); + } catch (IllegalStateException notUsed) { /** - * + // @@@ COULD CHECK If the new file is deleted - * before notifying... Checking for a current case is a - * stop gap measure + update(); 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. + * Case is closed, do nothing. */ - try { - Case.getCurrentCase(); - // new file was added - // @@@ COULD CHECK If the new file is deleted before notifying... - update(); - } catch (IllegalStateException notUsed) { - /** - * Case is closed, do nothing. - */ - } - } else if (eventType.equals(IngestManager.IngestJobEvent.COMPLETED.toString()) - || eventType.equals(IngestManager.IngestJobEvent.CANCELLED.toString()) - || eventType.equals(Case.Events.DATA_SOURCE_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.getCurrentCase(); - update(); - } catch (IllegalStateException notUsed) { - /** - * Case is closed, do nothing. - */ - } - } else if (eventType.equals(Case.Events.CURRENT_CASE.toString())) { - // case was closed. Remove listeners so that we don't get called with a stale case handle - if (evt.getNewValue() == null) { - removeListeners(); - } - maxFilesDialogShown = false; } + } else if (eventType.equals(IngestManager.IngestJobEvent.COMPLETED.toString()) + || eventType.equals(IngestManager.IngestJobEvent.CANCELLED.toString()) + || eventType.equals(Case.Events.DATA_SOURCE_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.getCurrentCase(); + update(); + } catch (IllegalStateException notUsed) { + /** + * Case is closed, do nothing. + */ + } + } else if (eventType.equals(Case.Events.CURRENT_CASE.toString())) { + // case was closed. Remove listeners so that we don't get called with a stale case handle + if (evt.getNewValue() == null) { + removeListeners(); + } + maxFilesDialogShown = false; } }; diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/EmailExtracted.java b/Core/src/org/sleuthkit/autopsy/datamodel/EmailExtracted.java index ca4602e30a..4f1e190f4b 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/EmailExtracted.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/EmailExtracted.java @@ -23,6 +23,7 @@ import java.beans.PropertyChangeListener; import java.sql.ResultSet; import java.sql.SQLException; import java.util.ArrayList; +import java.util.EnumSet; import java.util.HashMap; import java.util.LinkedHashMap; import java.util.List; @@ -285,7 +286,7 @@ public class EmailExtracted implements AutopsyVisitableItem { protected void addNotify() { IngestManager.getInstance().addIngestJobEventListener(pcl); IngestManager.getInstance().addIngestModuleEventListener(pcl); - Case.addPropertyChangeListener(pcl); + Case.addEventTypeSubscriber(EnumSet.of(Case.Events.CURRENT_CASE), pcl); emailResults.update(); emailResults.addObserver(this); } @@ -294,7 +295,7 @@ public class EmailExtracted implements AutopsyVisitableItem { protected void removeNotify() { IngestManager.getInstance().removeIngestJobEventListener(pcl); IngestManager.getInstance().removeIngestModuleEventListener(pcl); - Case.removePropertyChangeListener(pcl); + Case.removeEventTypeSubscriber(EnumSet.of(Case.Events.CURRENT_CASE), pcl); emailResults.deleteObserver(this); } diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/ExtractedContent.java b/Core/src/org/sleuthkit/autopsy/datamodel/ExtractedContent.java index 896cec5322..317cb42d10 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/ExtractedContent.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/ExtractedContent.java @@ -23,6 +23,7 @@ import java.beans.PropertyChangeListener; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; +import java.util.EnumSet; import java.util.HashMap; import java.util.List; import java.util.logging.Level; @@ -251,14 +252,14 @@ public class ExtractedContent implements AutopsyVisitableItem { protected void addNotify() { IngestManager.getInstance().addIngestJobEventListener(pcl); IngestManager.getInstance().addIngestModuleEventListener(pcl); - Case.addPropertyChangeListener(pcl); + Case.addEventTypeSubscriber(EnumSet.of(Case.Events.CURRENT_CASE), pcl); } @Override protected void removeNotify() { IngestManager.getInstance().removeIngestJobEventListener(pcl); IngestManager.getInstance().removeIngestModuleEventListener(pcl); - Case.removePropertyChangeListener(pcl); + Case.removeEventTypeSubscriber(EnumSet.of(Case.Events.CURRENT_CASE), pcl); typeNodeList.clear(); } @@ -309,7 +310,7 @@ public class ExtractedContent implements AutopsyVisitableItem { */ public class TypeNode extends DisplayableItemNode { - private BlackboardArtifact.Type type; + private final BlackboardArtifact.Type type; private long childCount = 0; TypeNode(BlackboardArtifact.Type type) { diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/FileSize.java b/Core/src/org/sleuthkit/autopsy/datamodel/FileSize.java index 19fd4659e8..bc515b6d29 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/FileSize.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/FileSize.java @@ -22,9 +22,11 @@ import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import java.util.ArrayList; import java.util.Arrays; +import java.util.EnumSet; import java.util.List; import java.util.Observable; import java.util.Observer; +import java.util.Set; import java.util.logging.Level; import org.openide.nodes.AbstractNode; import org.openide.nodes.ChildFactory; @@ -168,65 +170,64 @@ public class FileSize implements AutopsyVisitableItem { * Listens for case and ingest invest. Updates observers when events are * fired. Size-based nodes are listening to this for changes. */ - private final class FileSizeRootChildrenObservable extends Observable { + private static final class FileSizeRootChildrenObservable extends Observable { + + private static final Set CASE_EVENTS_OF_INTEREST = EnumSet.of(Case.Events.DATA_SOURCE_ADDED, Case.Events.CURRENT_CASE); FileSizeRootChildrenObservable() { IngestManager.getInstance().addIngestJobEventListener(pcl); IngestManager.getInstance().addIngestModuleEventListener(pcl); - Case.addPropertyChangeListener(pcl); + Case.addEventTypeSubscriber(CASE_EVENTS_OF_INTEREST, pcl); } private void removeListeners() { deleteObservers(); IngestManager.getInstance().removeIngestJobEventListener(pcl); IngestManager.getInstance().removeIngestModuleEventListener(pcl); - Case.removePropertyChangeListener(pcl); + Case.removeEventTypeSubscriber(CASE_EVENTS_OF_INTEREST, pcl); } - private final PropertyChangeListener pcl = new PropertyChangeListener() { - @Override - public void propertyChange(PropertyChangeEvent evt) { - String eventType = evt.getPropertyName(); + private final PropertyChangeListener pcl = (PropertyChangeEvent evt) -> { + String eventType = evt.getPropertyName(); - if (eventType.equals(IngestManager.IngestModuleEvent.CONTENT_CHANGED.toString())) { + if (eventType.equals(IngestManager.IngestModuleEvent.CONTENT_CHANGED.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 { + // new file was added + // @@@ could check the size here and only fire off updates if we know the file meets the min size criteria + Case.getCurrentCase(); + update(); + } catch (IllegalStateException notUsed) { /** - * 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. + * Case is closed, do nothing. */ - try { - // new file was added - // @@@ could check the size here and only fire off updates if we know the file meets the min size criteria - Case.getCurrentCase(); - update(); - } catch (IllegalStateException notUsed) { - /** - * Case is closed, do nothing. - */ - } - } else if (eventType.equals(IngestManager.IngestJobEvent.COMPLETED.toString()) - || eventType.equals(IngestManager.IngestJobEvent.CANCELLED.toString()) - || eventType.equals(Case.Events.DATA_SOURCE_ADDED.toString())) { + } + } else if (eventType.equals(IngestManager.IngestJobEvent.COMPLETED.toString()) + || eventType.equals(IngestManager.IngestJobEvent.CANCELLED.toString()) + || eventType.equals(Case.Events.DATA_SOURCE_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.getCurrentCase(); + update(); + } catch (IllegalStateException notUsed) { /** - * 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. + * Case is closed, do nothing. */ - try { - Case.getCurrentCase(); - update(); - } catch (IllegalStateException notUsed) { - /** - * Case is closed, do nothing. - */ - } - } else if (eventType.equals(Case.Events.CURRENT_CASE.toString())) { - // case was closed. Remove listeners so that we don't get called with a stale case handle - if (evt.getNewValue() == null) { - removeListeners(); - } + } + } else if (eventType.equals(Case.Events.CURRENT_CASE.toString())) { + // case was closed. Remove listeners so that we don't get called with a stale case handle + if (evt.getNewValue() == null) { + removeListeners(); } } }; diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/FileTypesByExtension.java b/Core/src/org/sleuthkit/autopsy/datamodel/FileTypesByExtension.java index 2e1fba50cc..1f109bd8d5 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/FileTypesByExtension.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/FileTypesByExtension.java @@ -21,10 +21,11 @@ package org.sleuthkit.autopsy.datamodel; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import java.util.Arrays; +import java.util.EnumSet; import java.util.List; import java.util.Observable; import java.util.Observer; -import java.util.function.Function; +import java.util.Set; import java.util.logging.Level; import java.util.stream.Collectors; import org.apache.commons.lang.StringUtils; @@ -39,8 +40,6 @@ import org.sleuthkit.autopsy.core.UserPreferences; import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.autopsy.datamodel.FileTypes.FileTypesKey; import org.sleuthkit.autopsy.ingest.IngestManager; -import org.sleuthkit.datamodel.AbstractFile; -import org.sleuthkit.datamodel.Content; import org.sleuthkit.datamodel.SleuthkitCase; import org.sleuthkit.datamodel.TskCoreException; import org.sleuthkit.datamodel.TskData; @@ -75,9 +74,11 @@ public final class FileTypesByExtension implements AutopsyVisitableItem { private class FileTypesByExtObservable extends Observable { private final PropertyChangeListener pcl; + private final Set CASE_EVENTS_OF_INTEREST; private FileTypesByExtObservable() { super(); + this.CASE_EVENTS_OF_INTEREST = EnumSet.of(Case.Events.DATA_SOURCE_ADDED, Case.Events.CURRENT_CASE); this.pcl = (PropertyChangeEvent evt) -> { String eventType = evt.getPropertyName(); if (eventType.equals(IngestManager.IngestModuleEvent.CONTENT_CHANGED.toString()) @@ -109,15 +110,14 @@ public final class FileTypesByExtension implements AutopsyVisitableItem { IngestManager.getInstance().addIngestJobEventListener(pcl); IngestManager.getInstance().addIngestModuleEventListener(pcl); - Case.addPropertyChangeListener(pcl); - + Case.addEventTypeSubscriber(CASE_EVENTS_OF_INTEREST, pcl); } private void removeListeners() { deleteObservers(); IngestManager.getInstance().removeIngestJobEventListener(pcl); IngestManager.getInstance().removeIngestModuleEventListener(pcl); - Case.removePropertyChangeListener(pcl); + Case.removeEventTypeSubscriber(CASE_EVENTS_OF_INTEREST, pcl); } private void update() { diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/FileTypesByMimeType.java b/Core/src/org/sleuthkit/autopsy/datamodel/FileTypesByMimeType.java index e5bd41b6e8..9fe183a8a8 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/FileTypesByMimeType.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/FileTypesByMimeType.java @@ -24,11 +24,13 @@ import java.sql.ResultSet; import java.sql.SQLException; import java.util.ArrayList; import java.util.Collections; +import java.util.EnumSet; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Observable; import java.util.Observer; +import java.util.Set; import java.util.logging.Level; import java.util.stream.Collectors; import org.apache.commons.lang3.StringUtils; @@ -44,7 +46,6 @@ import static org.sleuthkit.autopsy.core.UserPreferences.hideSlackFilesInViewsTr import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.autopsy.datamodel.FileTypes.FileTypesKey; import org.sleuthkit.autopsy.ingest.IngestManager; -import org.sleuthkit.datamodel.Content; import org.sleuthkit.datamodel.SleuthkitCase; import org.sleuthkit.datamodel.TskCoreException; import org.sleuthkit.datamodel.TskData; @@ -79,6 +80,8 @@ public final class FileTypesByMimeType extends Observable implements AutopsyVisi */ private final PropertyChangeListener pcl; + private static final Set CASE_EVENTS_OF_INTEREST = EnumSet.of(Case.Events.DATA_SOURCE_ADDED, Case.Events.CURRENT_CASE); + /** * Create the base expression used as the where clause in the queries for * files by mime type. Filters out certain kinds of files and directories, @@ -102,7 +105,7 @@ public final class FileTypesByMimeType extends Observable implements AutopsyVisi private void removeListeners() { deleteObservers(); IngestManager.getInstance().removeIngestJobEventListener(pcl); - Case.removePropertyChangeListener(pcl); + Case.removeEventTypeSubscriber(CASE_EVENTS_OF_INTEREST, pcl); } /** @@ -175,7 +178,7 @@ public final class FileTypesByMimeType extends Observable implements AutopsyVisi } }; IngestManager.getInstance().addIngestJobEventListener(pcl); - Case.addPropertyChangeListener(pcl); + Case.addEventTypeSubscriber(CASE_EVENTS_OF_INTEREST, pcl); populateHashMap(); } diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/HashsetHits.java b/Core/src/org/sleuthkit/autopsy/datamodel/HashsetHits.java index 2665894481..df3d239aef 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/HashsetHits.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/HashsetHits.java @@ -24,6 +24,7 @@ import java.sql.ResultSet; import java.sql.SQLException; import java.util.ArrayList; import java.util.Collections; +import java.util.EnumSet; import java.util.HashMap; import java.util.HashSet; import java.util.LinkedHashMap; @@ -252,7 +253,7 @@ public class HashsetHits implements AutopsyVisitableItem { protected void addNotify() { IngestManager.getInstance().addIngestJobEventListener(pcl); IngestManager.getInstance().addIngestModuleEventListener(pcl); - Case.addPropertyChangeListener(pcl); + Case.addEventTypeSubscriber(EnumSet.of(Case.Events.CURRENT_CASE), pcl); hashsetResults.update(); hashsetResults.addObserver(this); } @@ -261,7 +262,7 @@ public class HashsetHits implements AutopsyVisitableItem { protected void removeNotify() { IngestManager.getInstance().removeIngestJobEventListener(pcl); IngestManager.getInstance().removeIngestModuleEventListener(pcl); - Case.removePropertyChangeListener(pcl); + Case.removeEventTypeSubscriber(EnumSet.of(Case.Events.CURRENT_CASE), pcl); hashsetResults.deleteObserver(this); } diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/ImageNode.java b/Core/src/org/sleuthkit/autopsy/datamodel/ImageNode.java index 682a3fa225..4efe1db364 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/ImageNode.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/ImageNode.java @@ -24,6 +24,7 @@ import java.sql.ResultSet; import java.sql.SQLException; import java.util.ArrayList; import java.util.Collections; +import java.util.EnumSet; import java.util.List; import java.util.logging.Level; import javax.swing.Action; @@ -79,12 +80,12 @@ public class ImageNode extends AbstractContentNode { // Listen for ingest events so that we can detect new added files (e.g. carved) IngestManager.getInstance().addIngestModuleEventListener(pcl); // Listen for case events so that we can detect when case is closed - Case.addPropertyChangeListener(pcl); + Case.addEventTypeSubscriber(EnumSet.of(Case.Events.CURRENT_CASE), pcl); } private void removeListeners() { IngestManager.getInstance().removeIngestModuleEventListener(pcl); - Case.removePropertyChangeListener(pcl); + Case.removeEventTypeSubscriber(EnumSet.of(Case.Events.CURRENT_CASE), pcl); } /** diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/InterestingHits.java b/Core/src/org/sleuthkit/autopsy/datamodel/InterestingHits.java index d9fecdcdb2..7a0b6b9ad9 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/InterestingHits.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/InterestingHits.java @@ -24,6 +24,7 @@ import java.sql.ResultSet; import java.sql.SQLException; import java.util.ArrayList; import java.util.Collections; +import java.util.EnumSet; import java.util.HashMap; import java.util.HashSet; import java.util.LinkedHashMap; @@ -188,57 +189,54 @@ public class InterestingHits implements AutopsyVisitableItem { * nice methods for its startup and shutdown, so it seemed like a * cleaner place to register the property change listener. */ - private final PropertyChangeListener pcl = new PropertyChangeListener() { - @Override - public void propertyChange(PropertyChangeEvent evt) { - String eventType = evt.getPropertyName(); - if (eventType.equals(IngestManager.IngestModuleEvent.DATA_ADDED.toString())) { + private final PropertyChangeListener pcl = (PropertyChangeEvent evt) -> { + 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.getCurrentCase(); /** - * 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. + * 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. */ - try { - Case.getCurrentCase(); - /** - * 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 && (eventData.getBlackboardArtifactType().getTypeID() == BlackboardArtifact.ARTIFACT_TYPE.TSK_INTERESTING_ARTIFACT_HIT.getTypeID() - || eventData.getBlackboardArtifactType().getTypeID() == BlackboardArtifact.ARTIFACT_TYPE.TSK_INTERESTING_FILE_HIT.getTypeID())) { - interestingResults.update(); - } - } catch (IllegalStateException notUsed) { - /** - * Case is closed, do nothing. - */ - } - } else if (eventType.equals(IngestManager.IngestJobEvent.COMPLETED.toString()) - || eventType.equals(IngestManager.IngestJobEvent.CANCELLED.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.getCurrentCase(); + ModuleDataEvent eventData = (ModuleDataEvent) evt.getOldValue(); + if (null != eventData && (eventData.getBlackboardArtifactType().getTypeID() == BlackboardArtifact.ARTIFACT_TYPE.TSK_INTERESTING_ARTIFACT_HIT.getTypeID() + || eventData.getBlackboardArtifactType().getTypeID() == BlackboardArtifact.ARTIFACT_TYPE.TSK_INTERESTING_FILE_HIT.getTypeID())) { interestingResults.update(); - } catch (IllegalStateException notUsed) { - /** - * Case is closed, do nothing. - */ - } - } else if (eventType.equals(Case.Events.CURRENT_CASE.toString())) { - // case was closed. Remove listeners so that we don't get called with a stale case handle - if (evt.getNewValue() == null) { - removeNotify(); - skCase = null; } + } catch (IllegalStateException notUsed) { + /** + * Case is closed, do nothing. + */ + } + } else if (eventType.equals(IngestManager.IngestJobEvent.COMPLETED.toString()) + || eventType.equals(IngestManager.IngestJobEvent.CANCELLED.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.getCurrentCase(); + interestingResults.update(); + } catch (IllegalStateException notUsed) { + /** + * Case is closed, do nothing. + */ + } + } else if (eventType.equals(Case.Events.CURRENT_CASE.toString())) { + // case was closed. Remove listeners so that we don't get called with a stale case handle + if (evt.getNewValue() == null) { + removeNotify(); + skCase = null; } } }; @@ -247,7 +245,7 @@ public class InterestingHits implements AutopsyVisitableItem { protected void addNotify() { IngestManager.getInstance().addIngestJobEventListener(pcl); IngestManager.getInstance().addIngestModuleEventListener(pcl); - Case.addPropertyChangeListener(pcl); + Case.addEventTypeSubscriber(EnumSet.of(Case.Events.CURRENT_CASE), pcl); interestingResults.update(); interestingResults.addObserver(this); } @@ -256,7 +254,7 @@ public class InterestingHits implements AutopsyVisitableItem { protected void removeNotify() { IngestManager.getInstance().removeIngestJobEventListener(pcl); IngestManager.getInstance().removeIngestModuleEventListener(pcl); - Case.removePropertyChangeListener(pcl); + Case.removeEventTypeSubscriber(EnumSet.of(Case.Events.CURRENT_CASE), pcl); interestingResults.deleteObserver(this); } diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/KeywordHits.java b/Core/src/org/sleuthkit/autopsy/datamodel/KeywordHits.java index 343074ddc9..75873d135e 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/KeywordHits.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/KeywordHits.java @@ -24,6 +24,7 @@ import java.sql.ResultSet; import java.sql.SQLException; import java.util.ArrayList; import java.util.Collections; +import java.util.EnumSet; import java.util.HashSet; import java.util.LinkedHashMap; import java.util.List; @@ -455,7 +456,7 @@ public class KeywordHits implements AutopsyVisitableItem { protected void addNotify() { IngestManager.getInstance().addIngestJobEventListener(pcl); IngestManager.getInstance().addIngestModuleEventListener(pcl); - Case.addPropertyChangeListener(pcl); + Case.addEventTypeSubscriber(EnumSet.of(Case.Events.CURRENT_CASE), pcl); keywordResults.update(); super.addNotify(); } @@ -464,7 +465,7 @@ public class KeywordHits implements AutopsyVisitableItem { protected void removeNotify() { IngestManager.getInstance().removeIngestJobEventListener(pcl); IngestManager.getInstance().removeIngestModuleEventListener(pcl); - Case.removePropertyChangeListener(pcl); + Case.removeEventTypeSubscriber(EnumSet.of(Case.Events.CURRENT_CASE), pcl); super.removeNotify(); } diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/Reports.java b/Core/src/org/sleuthkit/autopsy/datamodel/Reports.java index c606984056..14cf3bfbd4 100755 --- a/Core/src/org/sleuthkit/autopsy/datamodel/Reports.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/Reports.java @@ -28,7 +28,9 @@ import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; +import java.util.EnumSet; import java.util.List; +import java.util.Set; import java.util.logging.Level; import javax.swing.AbstractAction; import javax.swing.Action; @@ -103,8 +105,10 @@ public final class Reports implements AutopsyVisitableItem { */ private static final class ReportNodeFactory extends ChildFactory { + private static final Set CASE_EVENTS_OF_INTEREST = EnumSet.of(Case.Events.REPORT_ADDED, Case.Events.REPORT_DELETED); + ReportNodeFactory() { - Case.addPropertyChangeListener((PropertyChangeEvent evt) -> { + Case.addEventTypeSubscriber(CASE_EVENTS_OF_INTEREST, (PropertyChangeEvent evt) -> { String eventType = evt.getPropertyName(); if (eventType.equals(Case.Events.REPORT_ADDED.toString()) || eventType.equals(Case.Events.REPORT_DELETED.toString())) { /** diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/Tags.java b/Core/src/org/sleuthkit/autopsy/datamodel/Tags.java index b8127fe5a7..64b77ac245 100755 --- a/Core/src/org/sleuthkit/autopsy/datamodel/Tags.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/Tags.java @@ -21,9 +21,11 @@ package org.sleuthkit.autopsy.datamodel; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import java.util.Collections; +import java.util.EnumSet; import java.util.List; import java.util.Observable; import java.util.Observer; +import java.util.Set; import java.util.logging.Level; import org.openide.nodes.ChildFactory; import org.openide.nodes.Children; @@ -118,6 +120,12 @@ public class Tags implements AutopsyVisitableItem { private class TagNameNodeFactory extends ChildFactory.Detachable implements Observer { + private final Set CASE_EVENTS_OF_INTEREST = EnumSet.of(Case.Events.BLACKBOARD_ARTIFACT_TAG_ADDED, + Case.Events.BLACKBOARD_ARTIFACT_TAG_DELETED, + Case.Events.CONTENT_TAG_ADDED, + Case.Events.CONTENT_TAG_DELETED, + Case.Events.CURRENT_CASE); + private final PropertyChangeListener pcl = new PropertyChangeListener() { @Override public void propertyChange(PropertyChangeEvent evt) { @@ -171,7 +179,7 @@ public class Tags implements AutopsyVisitableItem { protected void addNotify() { IngestManager.getInstance().addIngestJobEventListener(pcl); IngestManager.getInstance().addIngestModuleEventListener(pcl); - Case.addPropertyChangeListener(pcl); + Case.addEventTypeSubscriber(CASE_EVENTS_OF_INTEREST, pcl); tagResults.update(); tagResults.addObserver(this); } @@ -180,7 +188,7 @@ public class Tags implements AutopsyVisitableItem { protected void removeNotify() { IngestManager.getInstance().removeIngestJobEventListener(pcl); IngestManager.getInstance().removeIngestModuleEventListener(pcl); - Case.removePropertyChangeListener(pcl); + Case.removeEventTypeSubscriber(CASE_EVENTS_OF_INTEREST, pcl); tagResults.deleteObserver(this); } diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/VolumeNode.java b/Core/src/org/sleuthkit/autopsy/datamodel/VolumeNode.java index ba37cd4f09..ee5a5713a3 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/VolumeNode.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/VolumeNode.java @@ -21,6 +21,7 @@ package org.sleuthkit.autopsy.datamodel; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import java.util.ArrayList; +import java.util.EnumSet; import java.util.List; import javax.swing.Action; import org.openide.nodes.Children; @@ -72,12 +73,12 @@ public class VolumeNode extends AbstractContentNode { // Listen for ingest events so that we can detect new added files (e.g. carved) IngestManager.getInstance().addIngestModuleEventListener(pcl); // Listen for case events so that we can detect when case is closed - Case.addPropertyChangeListener(pcl); + Case.addEventTypeSubscriber(EnumSet.of(Case.Events.CURRENT_CASE), pcl); } private void removeListeners() { IngestManager.getInstance().removeIngestModuleEventListener(pcl); - Case.removePropertyChangeListener(pcl); + Case.removeEventTypeSubscriber(EnumSet.of(Case.Events.CURRENT_CASE), pcl); } /* diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/accounts/Accounts.java b/Core/src/org/sleuthkit/autopsy/datamodel/accounts/Accounts.java index 6545ac0bef..e1ba5a2ca8 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/accounts/Accounts.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/accounts/Accounts.java @@ -32,6 +32,7 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.Collections; +import java.util.EnumSet; import java.util.HashSet; import java.util.List; import java.util.Objects; @@ -311,7 +312,7 @@ final public class Accounts implements AutopsyVisitableItem { protected void removeNotify() { IngestManager.getInstance().removeIngestJobEventListener(pcl); IngestManager.getInstance().removeIngestModuleEventListener(pcl); - Case.removePropertyChangeListener(pcl); + Case.removeEventTypeSubscriber(EnumSet.of(Case.Events.CURRENT_CASE), pcl); super.removeNotify(); } @@ -319,7 +320,7 @@ final public class Accounts implements AutopsyVisitableItem { protected void addNotify() { IngestManager.getInstance().addIngestJobEventListener(pcl); IngestManager.getInstance().addIngestModuleEventListener(pcl); - Case.addPropertyChangeListener(pcl); + Case.addEventTypeSubscriber(EnumSet.of(Case.Events.CURRENT_CASE), pcl); super.addNotify(); refreshKeys(); } diff --git a/Core/src/org/sleuthkit/autopsy/directorytree/DirectoryTreeTopComponent.java b/Core/src/org/sleuthkit/autopsy/directorytree/DirectoryTreeTopComponent.java index bfb98e5220..03c265daee 100644 --- a/Core/src/org/sleuthkit/autopsy/directorytree/DirectoryTreeTopComponent.java +++ b/Core/src/org/sleuthkit/autopsy/directorytree/DirectoryTreeTopComponent.java @@ -26,6 +26,7 @@ import java.beans.PropertyVetoException; import java.io.IOException; import java.util.ArrayList; import java.util.Arrays; +import java.util.EnumSet; import java.util.HashSet; import java.util.LinkedList; import java.util.List; @@ -151,7 +152,7 @@ public final class DirectoryTreeTopComponent extends TopComponent implements Dat } } }); - Case.addEventSubscriber(new HashSet<>(Arrays.asList(Case.Events.CURRENT_CASE.toString(), Case.Events.DATA_SOURCE_ADDED.toString())), this); + Case.addEventTypeSubscriber(EnumSet.of(Case.Events.CURRENT_CASE, Case.Events.DATA_SOURCE_ADDED), this); this.em.addPropertyChangeListener(this); IngestManager.getInstance().addIngestJobEventListener(this); IngestManager.getInstance().addIngestModuleEventListener(this); diff --git a/Core/src/org/sleuthkit/autopsy/filesearch/DateSearchFilter.java b/Core/src/org/sleuthkit/autopsy/filesearch/DateSearchFilter.java index f7ae47cc73..205db56998 100644 --- a/Core/src/org/sleuthkit/autopsy/filesearch/DateSearchFilter.java +++ b/Core/src/org/sleuthkit/autopsy/filesearch/DateSearchFilter.java @@ -28,6 +28,7 @@ import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Calendar; import java.util.Date; +import java.util.EnumSet; import java.util.Iterator; import java.util.List; import java.util.Set; @@ -53,6 +54,9 @@ class DateSearchFilter extends AbstractFileSearchFilter { private static final DateFormat DATE_FORMAT = new SimpleDateFormat("MM/dd/yyyy"); private static final String SEPARATOR = "SEPARATOR"; //NON-NLS + private static final Set CASE_EVENTS_OF_INTEREST = EnumSet.of(Case.Events.CURRENT_CASE, + Case.Events.DATA_SOURCE_ADDED, Case.Events.DATA_SOURCE_DELETED); + /** * New DateSearchFilter with the default panel */ @@ -62,7 +66,7 @@ class DateSearchFilter extends AbstractFileSearchFilter { private DateSearchFilter(DateSearchPanel panel) { super(panel); - Case.addPropertyChangeListener(this.new CasePropertyChangeListener()); + Case.addEventTypeSubscriber(CASE_EVENTS_OF_INTEREST, this.new CasePropertyChangeListener()); } @Override diff --git a/Core/src/org/sleuthkit/autopsy/filesearch/FileSearchAction.java b/Core/src/org/sleuthkit/autopsy/filesearch/FileSearchAction.java index 603d9d1623..fb66a4b6d7 100644 --- a/Core/src/org/sleuthkit/autopsy/filesearch/FileSearchAction.java +++ b/Core/src/org/sleuthkit/autopsy/filesearch/FileSearchAction.java @@ -20,7 +20,7 @@ package org.sleuthkit.autopsy.filesearch; import java.awt.event.ActionEvent; import java.beans.PropertyChangeEvent; -import java.beans.PropertyChangeListener; +import java.util.EnumSet; import org.openide.util.HelpCtx; import org.openide.util.NbBundle; import org.openide.util.actions.CallableSystemAction; @@ -35,14 +35,10 @@ final class FileSearchAction extends CallableSystemAction implements FileSearchP FileSearchAction() { super(); setEnabled(Case.isCaseOpen()); - Case.addPropertyChangeListener(new PropertyChangeListener() { - @Override - public void propertyChange(PropertyChangeEvent evt) { - if (evt.getPropertyName().equals(Case.Events.CURRENT_CASE.toString())) { - setEnabled(evt.getNewValue() != null); - } + Case.addEventTypeSubscriber(EnumSet.of(Case.Events.CURRENT_CASE), (PropertyChangeEvent evt) -> { + if (evt.getPropertyName().equals(Case.Events.CURRENT_CASE.toString())) { + setEnabled(evt.getNewValue() != null); } - }); } diff --git a/Core/src/org/sleuthkit/autopsy/ingest/IngestManager.java b/Core/src/org/sleuthkit/autopsy/ingest/IngestManager.java index 99f8e09fd8..e61f8d61f7 100644 --- a/Core/src/org/sleuthkit/autopsy/ingest/IngestManager.java +++ b/Core/src/org/sleuthkit/autopsy/ingest/IngestManager.java @@ -26,6 +26,7 @@ import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.Date; +import java.util.EnumSet; import java.util.HashMap; import java.util.HashSet; import java.util.List; @@ -229,7 +230,7 @@ public class IngestManager { * opened/closed) events. */ private void subscribeToCaseEvents() { - Case.addEventSubscriber(Case.Events.CURRENT_CASE.toString(), (PropertyChangeEvent event) -> { + Case.addEventTypeSubscriber(EnumSet.of(Case.Events.CURRENT_CASE), (PropertyChangeEvent event) -> { if (event.getNewValue() != null) { handleCaseOpened(); } else { diff --git a/Core/src/org/sleuthkit/autopsy/ingest/IngestMessagesToolbar.java b/Core/src/org/sleuthkit/autopsy/ingest/IngestMessagesToolbar.java index 20b791c64d..432cb48810 100644 --- a/Core/src/org/sleuthkit/autopsy/ingest/IngestMessagesToolbar.java +++ b/Core/src/org/sleuthkit/autopsy/ingest/IngestMessagesToolbar.java @@ -25,6 +25,7 @@ import java.awt.Font; import java.awt.Graphics; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; +import java.util.EnumSet; import javax.swing.JButton; import org.openide.util.NbBundle; import org.openide.windows.Mode; @@ -128,7 +129,7 @@ class IngestMessagesToolbar extends javax.swing.JPanel { } }); - Case.addPropertyChangeListener((PropertyChangeEvent evt) -> { + Case.addEventTypeSubscriber(EnumSet.of(Case.Events.CURRENT_CASE), (PropertyChangeEvent evt) -> { if (evt.getPropertyName().equals(Case.Events.CURRENT_CASE.toString())) { setEnabled(evt.getNewValue() != null && RuntimeProperties.runningWithGUI()); } diff --git a/Core/src/org/sleuthkit/autopsy/ingest/IngestMonitor.java b/Core/src/org/sleuthkit/autopsy/ingest/IngestMonitor.java index 771380c415..f6580a3cbc 100644 --- a/Core/src/org/sleuthkit/autopsy/ingest/IngestMonitor.java +++ b/Core/src/org/sleuthkit/autopsy/ingest/IngestMonitor.java @@ -23,6 +23,7 @@ import java.awt.event.ActionListener; import java.beans.PropertyChangeEvent; import java.io.File; import java.io.IOException; +import java.util.EnumSet; import java.util.logging.FileHandler; import java.util.logging.Level; import java.util.logging.SimpleFormatter; @@ -121,7 +122,7 @@ public final class IngestMonitor { MonitorTimerAction() { findRootDirectoryForCurrentCase(); - Case.addEventSubscriber(Case.Events.CURRENT_CASE.toString(), (PropertyChangeEvent evt) -> { + Case.addEventTypeSubscriber(EnumSet.of(Case.Events.CURRENT_CASE), (PropertyChangeEvent evt) -> { if (evt instanceof AutopsyEvent) { AutopsyEvent event = (AutopsyEvent) evt; if (AutopsyEvent.SourceType.LOCAL == event.getSourceType() && event.getPropertyName().equals(Case.Events.CURRENT_CASE.toString())) { diff --git a/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/HashDbPanelSearchAction.java b/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/HashDbPanelSearchAction.java index d7471df562..268f828fc7 100644 --- a/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/HashDbPanelSearchAction.java +++ b/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/HashDbPanelSearchAction.java @@ -23,7 +23,7 @@ import java.awt.event.ActionListener; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; import java.beans.PropertyChangeEvent; -import java.beans.PropertyChangeListener; +import java.util.EnumSet; import org.openide.util.HelpCtx; import org.openide.util.NbBundle; import org.openide.util.actions.CallableSystemAction; @@ -43,13 +43,9 @@ class HashDbPanelSearchAction extends CallableSystemAction { HashDbPanelSearchAction() { super(); setEnabled(Case.isCaseOpen()); - Case.addPropertyChangeListener(new PropertyChangeListener() { - - @Override - public void propertyChange(PropertyChangeEvent evt) { - if (evt.getPropertyName().equals(Case.Events.CURRENT_CASE.toString())) { - setEnabled(evt.getNewValue() != null); - } + Case.addEventTypeSubscriber(EnumSet.of(Case.Events.CURRENT_CASE), (PropertyChangeEvent evt) -> { + if (evt.getPropertyName().equals(Case.Events.CURRENT_CASE.toString())) { + setEnabled(evt.getNewValue() != null); } }); } diff --git a/Core/src/org/sleuthkit/autopsy/report/ReportWizardAction.java b/Core/src/org/sleuthkit/autopsy/report/ReportWizardAction.java index 75c8f7c205..49f37008be 100644 --- a/Core/src/org/sleuthkit/autopsy/report/ReportWizardAction.java +++ b/Core/src/org/sleuthkit/autopsy/report/ReportWizardAction.java @@ -27,6 +27,7 @@ import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.beans.PropertyChangeEvent; import java.text.MessageFormat; +import java.util.EnumSet; import java.util.Map; import javax.swing.ImageIcon; import javax.swing.JButton; @@ -81,7 +82,7 @@ public final class ReportWizardAction extends CallableSystemAction implements Pr public ReportWizardAction() { setEnabled(false); - Case.addPropertyChangeListener((PropertyChangeEvent evt) -> { + Case.addEventTypeSubscriber(EnumSet.of(Case.Events.CURRENT_CASE), (PropertyChangeEvent evt) -> { if (evt.getPropertyName().equals(Case.Events.CURRENT_CASE.toString())) { Case newCase = (Case) evt.getNewValue(); setEnabled(newCase != null && RuntimeProperties.runningWithGUI()); diff --git a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/DropdownToolbar.java b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/DropdownToolbar.java index 3272b9dad1..1ad473dd01 100644 --- a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/DropdownToolbar.java +++ b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/DropdownToolbar.java @@ -23,6 +23,7 @@ import java.awt.event.ActionListener; import java.awt.event.MouseEvent; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; +import java.util.EnumSet; import java.util.logging.Level; import javax.swing.SwingUtilities; import javax.swing.event.PopupMenuEvent; @@ -76,7 +77,7 @@ class DropdownToolbar extends javax.swing.JPanel { private void customizeComponents() { searchSettingsChangeListener = new SearchSettingsChangeListener(); KeywordSearch.getServer().addServerActionListener(searchSettingsChangeListener); - Case.addPropertyChangeListener(searchSettingsChangeListener); + Case.addEventTypeSubscriber(EnumSet.of(Case.Events.CURRENT_CASE), searchSettingsChangeListener); DropdownListSearchPanel listsPanel = DropdownListSearchPanel.getDefault(); listsPanel.addSearchButtonActionListener((ActionEvent e) -> {