diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/AbstractContentChildren.java b/Core/src/org/sleuthkit/autopsy/datamodel/AbstractContentChildren.java index 77ca0752fb..0719a18c3c 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/AbstractContentChildren.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/AbstractContentChildren.java @@ -176,11 +176,7 @@ abstract class AbstractContentChildren extends Keys { @Override public AbstractNode visit(DataSources i) { - try { - return new DataSourcesNode(Case.getCurrentCase().getDataSources()); - } catch (TskCoreException ex) { - return defaultVisit(i); - } + return new DataSourcesNode(); } @Override diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/DataSourcesNode.java b/Core/src/org/sleuthkit/autopsy/datamodel/DataSourcesNode.java index 4d0ed1feb4..f113a1b515 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/DataSourcesNode.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/DataSourcesNode.java @@ -18,12 +18,18 @@ */ package org.sleuthkit.autopsy.datamodel; +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; +import java.util.ArrayList; +import java.util.Collections; import java.util.List; - import org.openide.nodes.Sheet; import org.openide.util.NbBundle; import org.openide.util.lookup.Lookups; +import org.sleuthkit.autopsy.casemodule.Case; +import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.datamodel.Content; +import org.sleuthkit.datamodel.TskCoreException; /** * Nodes for the images @@ -32,13 +38,84 @@ public class DataSourcesNode extends DisplayableItemNode { public static final String NAME = NbBundle.getMessage(DataSourcesNode.class, "DataSourcesNode.name"); + // NOTE: The images passed in via argument will be ignored. + @Deprecated public DataSourcesNode(List images) { - super(new RootContentChildren(images), Lookups.singleton(NAME)); + super(new DataSourcesNodeChildren(), Lookups.singleton(NAME)); + init(); + } + + public DataSourcesNode() { + super(new DataSourcesNodeChildren(), Lookups.singleton(NAME)); + init(); + } + + private void init() { setName(NAME); setDisplayName(NAME); this.setIconBaseWithExtension("org/sleuthkit/autopsy/images/image.png"); //NON-NLS } + /* Custom Keys implementation that listens for new data sources being added. */ + // @@@ This can become private once DirectoryTree doesn't want to refresh the entire tree + public static class DataSourcesNodeChildren extends AbstractContentChildren { + + private static final Logger logger = Logger.getLogger(DataSourcesNodeChildren.class.getName()); + + List currentKeys; + + public DataSourcesNodeChildren() { + super(); + this.currentKeys = new ArrayList<>(); + } + + private final PropertyChangeListener pcl = new PropertyChangeListener() { + @Override + public void propertyChange(PropertyChangeEvent evt) { + String eventType = evt.getPropertyName(); + if (eventType.equals(Case.Events.DATA_SOURCE_ADDED.toString())) { + reloadKeys(); + } + } + }; + + @Override + protected void addNotify() { + Case.addPropertyChangeListener(pcl); + reloadKeys(); + } + + @Override + protected void removeNotify() { + Case.removePropertyChangeListener(pcl); + currentKeys.clear(); + setKeys(Collections.emptySet()); + } + + private void reloadKeys() { + try { + currentKeys = Case.getCurrentCase().getDataSources(); + setKeys(currentKeys); + } catch (TskCoreException | IllegalStateException ex) { + logger.severe("Error getting data sources: " + ex.getMessage()); // NON-NLS + setKeys(Collections.emptySet()); + } + } + + /** + * Refresh all content keys + * This creates new nodes of keys have changed. + */ + // I think this goes away once we get more listeners in place + // It was added as an interim stage + @Deprecated + public void refreshContentKeys() { + for (Content key : currentKeys) { + refreshKey(key); + } + } + } + @Override public boolean isLeafTypeNode() { return false; diff --git a/Core/src/org/sleuthkit/autopsy/directorytree/DirectoryTreeTopComponent.java b/Core/src/org/sleuthkit/autopsy/directorytree/DirectoryTreeTopComponent.java index 8161914bb9..8d0a814355 100644 --- a/Core/src/org/sleuthkit/autopsy/directorytree/DirectoryTreeTopComponent.java +++ b/Core/src/org/sleuthkit/autopsy/directorytree/DirectoryTreeTopComponent.java @@ -573,7 +573,8 @@ public final class DirectoryTreeTopComponent extends TopComponent implements Dat } } // if the image is added to the case else if (changed.equals(Case.Events.DATA_SOURCE_ADDED.toString())) { - componentOpened(); + // we don't need to do anything in here. + // DataSourcesNode is listening for these events and updates itself } // change in node selection else if (changed.equals(ExplorerManager.PROP_SELECTED_NODES)) { @@ -778,7 +779,7 @@ public final class DirectoryTreeTopComponent extends TopComponent implements Dat Node imagesNode = imagesNodeOrig.getNode(); - RootContentChildren contentRootChildren = (RootContentChildren) imagesNode.getChildren(); + DataSourcesNode.DataSourcesNodeChildren contentRootChildren = (DataSourcesNode.DataSourcesNodeChildren) imagesNode.getChildren(); contentRootChildren.refreshContentKeys(); //final TreeView tree = getTree();