From 637c4571f6bdb097472dfd6f87ee301e8dc5623c Mon Sep 17 00:00:00 2001 From: Greg DiCristofaro Date: Mon, 14 Jun 2021 14:51:50 -0400 Subject: [PATCH 1/5] bug fix --- .../autopsy/directorytree/ViewContextAction.java | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/Core/src/org/sleuthkit/autopsy/directorytree/ViewContextAction.java b/Core/src/org/sleuthkit/autopsy/directorytree/ViewContextAction.java index c8f5848243..f3e73f1ff8 100644 --- a/Core/src/org/sleuthkit/autopsy/directorytree/ViewContextAction.java +++ b/Core/src/org/sleuthkit/autopsy/directorytree/ViewContextAction.java @@ -31,6 +31,7 @@ import java.util.stream.Collectors; import java.util.stream.Stream; import org.sleuthkit.autopsy.coreutils.Logger; import javax.swing.AbstractAction; +import org.apache.commons.lang3.StringUtils; import org.openide.nodes.AbstractNode; import org.openide.explorer.ExplorerManager; import org.openide.explorer.view.TreeView; @@ -275,6 +276,11 @@ public class ViewContextAction extends AbstractAction { } } } + + // if no node is found, do nothing + if (parentTreeViewNode == null) { + return; + } /* * Set the child selection info of the parent tree node, then select @@ -377,6 +383,11 @@ public class ViewContextAction extends AbstractAction { Node dummyRootNode = new DirectoryTreeFilterNode(new AbstractNode(new RootContentChildren(contentBranch)), true); Children ancestorChildren = dummyRootNode.getChildren(); + // if content is the data source provided, return that. + if (ancestorChildren.getNodesCount() == 1 && StringUtils.equals(ancestorChildren.getNodeAt(0).getName(), node.getName())) { + return node; + } + /* * Search the tree for the parent node. Note that this algorithm * simply discards "extra" ancestor nodes not shown in the tree, From a42cf4eb638051c06cfd82e7d4b0413c705936b7 Mon Sep 17 00:00:00 2001 From: Greg DiCristofaro Date: Tue, 15 Jun 2021 14:11:58 -0400 Subject: [PATCH 2/5] refactoring --- .../directorytree/ViewContextAction.java | 286 +++++++++--------- 1 file changed, 148 insertions(+), 138 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/directorytree/ViewContextAction.java b/Core/src/org/sleuthkit/autopsy/directorytree/ViewContextAction.java index f3e73f1ff8..2c07c8f8df 100644 --- a/Core/src/org/sleuthkit/autopsy/directorytree/ViewContextAction.java +++ b/Core/src/org/sleuthkit/autopsy/directorytree/ViewContextAction.java @@ -26,6 +26,7 @@ import java.util.Arrays; import java.util.Collections; import java.util.List; import java.util.Objects; +import java.util.Optional; import java.util.logging.Level; import java.util.stream.Collectors; import java.util.stream.Stream; @@ -169,159 +170,168 @@ public class ViewContextAction extends AbstractAction { public void actionPerformed(ActionEvent event) { EventQueue.invokeLater(() -> { - /* - * Get the parent content for the content to be selected in the - * results view. If the parent content is null, then the specified - * content is a data source, and the parent tree view node is the - * "Data Sources" node. Otherwise, the tree view needs to be - * searched to find the parent treeview node. - */ - Content parentContent = null; - try { - parentContent = content.getParent(); - } catch (TskCoreException ex) { - MessageNotifyUtil.Message.error(Bundle.ViewContextAction_errorMessage_cannotFindDirectory()); - logger.log(Level.SEVERE, String.format("Could not get parent of Content object: %s", content), ex); //NON-NLS - return; - } + Content parentContent = getParentContent(this.content); - if ((parentContent != null) - && (parentContent instanceof UnsupportedContent)) { + if ((parentContent != null) && (parentContent instanceof UnsupportedContent)) { MessageNotifyUtil.Message.error(Bundle.ViewContextAction_errorMessage_unsupportedParent()); logger.log(Level.WARNING, String.format("Could not navigate to unsupported content with id: %d", parentContent.getId())); //NON-NLS - return; } - - /* - * Get the "Data Sources" node from the tree view. - */ + + // Get the "Data Sources" node from the tree view. DirectoryTreeTopComponent treeViewTopComponent = DirectoryTreeTopComponent.findInstance(); ExplorerManager treeViewExplorerMgr = treeViewTopComponent.getExplorerManager(); + Node parentTreeViewNode = null; - if (Objects.equals(CasePreferences.getGroupItemsInTreeByDataSource(), true)) { // 'Group by Data Source' view - - SleuthkitCase skCase; - String dsname; - try { - // get the objid/name of the datasource of the selected content. - skCase = Case.getCurrentCaseThrows().getSleuthkitCase(); - long contentDSObjid = content.getDataSource().getId(); - DataSource datasource = skCase.getDataSource(contentDSObjid); - dsname = datasource.getName(); - Children rootChildren = treeViewExplorerMgr.getRootContext().getChildren(); - - if (null != parentContent) { - // the tree view needs to be searched to find the parent treeview node. - /* NOTE: we can't do a lookup by data source name here, becase if there - are multiple data sources with the same name, then "getChildren().findChild(dsname)" - simply returns the first one that it finds. Instead we have to loop over all - data sources with that name, and make sure we find the correct one. - */ - List dataSourceLevelNodes = Stream.of(rootChildren.getNodes()) - .flatMap(rootNode -> getDataSourceLevelNodes(rootNode).stream()) - .collect(Collectors.toList()); - - for (Node treeNode : dataSourceLevelNodes) { - // in the root, look for a data source node with the name of interest - if (!(treeNode.getName().equals(dsname))) { - continue; - } - - // for this data source, get the "Data Sources" child node - Node datasourceGroupingNode = treeNode.getChildren().findChild(DataSourceFilesNode.getNameIdentifier()); - - // check whether this is the data source we are looking for - parentTreeViewNode = findParentNodeInTree(parentContent, datasourceGroupingNode); - if (parentTreeViewNode != null) { - // found the data source node - break; - } - } - } else { - /* If the parent content is null, then the specified - * content is a data source, and the parent tree view node is the - * "Data Sources" node. */ - Node datasourceGroupingNode = rootChildren.findChild(dsname); - if (!Objects.isNull(datasourceGroupingNode)) { - Children dsChildren = datasourceGroupingNode.getChildren(); - parentTreeViewNode = dsChildren.findChild(DataSourceFilesNode.getNameIdentifier()); - } - } - - if (parentTreeViewNode == null) { - MessageNotifyUtil.Message.error(Bundle.ViewContextAction_errorMessage_cannotFindNode()); - logger.log(Level.SEVERE, "Failed to locate data source node in tree."); //NON-NLS - return; - } - } catch (NoCurrentCaseException | TskDataException | TskCoreException ex) { - MessageNotifyUtil.Message.error(Bundle.ViewContextAction_errorMessage_cannotFindNode()); - logger.log(Level.SEVERE, "Failed to locate data source node in tree.", ex); //NON-NLS - return; - } - } else { // Classic view - // Start the search at the DataSourcesNode - Children rootChildren = treeViewExplorerMgr.getRootContext().getChildren(); - Node rootDsNode = rootChildren == null ? null : rootChildren.findChild(DataSourcesNode.getNameIdentifier()); - if (rootDsNode != null) { - for (Node dataSourceLevelNode : getDataSourceLevelNodes(rootDsNode)) { - DataSource dataSource = dataSourceLevelNode.getLookup().lookup(DataSource.class); - if (dataSource != null) { - // the tree view needs to be searched to find the parent treeview node. - Node potentialParentTreeViewNode = findParentNodeInTree(parentContent, dataSourceLevelNode); - if (potentialParentTreeViewNode != null) { - parentTreeViewNode = potentialParentTreeViewNode; - break; - } - } - } - } + if (parentContent != null) { + if (Objects.equals(CasePreferences.getGroupItemsInTreeByDataSource(), true)) { + parentTreeViewNode = getParentNodeGroupedByPersonHost(treeViewExplorerMgr, parentContent); + } else { + parentTreeViewNode = getParentNodeGroupedByDataSource(treeViewExplorerMgr, parentContent); + } } - // if no node is found, do nothing + // if no node is found, report error and do nothing if (parentTreeViewNode == null) { + MessageNotifyUtil.Message.error(Bundle.ViewContextAction_errorMessage_cannotFindNode()); + logger.log(Level.SEVERE, "Failed to locate data source node in tree."); //NON-NLS return; } - /* - * Set the child selection info of the parent tree node, then select - * the parent node in the tree view. The results view will retrieve - * this selection info and use it to complete this action when the - * tree view top component responds to the selection of the parent - * node by pushing it into the results view top component. - */ - DisplayableItemNode undecoratedParentNode = (DisplayableItemNode) ((DirectoryTreeFilterNode) parentTreeViewNode).getOriginal(); - undecoratedParentNode.setChildNodeSelectionInfo(new ContentNodeSelectionInfo(content)); - if (content instanceof BlackboardArtifact) { - BlackboardArtifact artifact = ((BlackboardArtifact) content); - long associatedId = artifact.getObjectID(); - try { - Content associatedFileContent = artifact.getSleuthkitCase().getContentById(associatedId); - undecoratedParentNode.setChildNodeSelectionInfo(new ContentNodeSelectionInfo(associatedFileContent)); - } catch (TskCoreException ex) { - logger.log(Level.SEVERE, "Could not find associated content from artifact with id %d", artifact.getId()); - } - } - - TreeView treeView = treeViewTopComponent.getTree(); - treeView.expandNode(parentTreeViewNode); - if (treeViewTopComponent.getSelectedNode().equals(parentTreeViewNode)) { - //In the case where our tree view already has the destination directory selected - //due to an optimization in the ExplorerManager.setExploredContextAndSelection method - //the property change we listen for to call DirectoryTreeTopComponent.respondSelection - //will not be sent so we call it manually ourselves after making - //the directory listing the active tab. - treeViewTopComponent.setDirectoryListingActive(); - treeViewTopComponent.respondSelection(treeViewExplorerMgr.getSelectedNodes(), new Node[]{parentTreeViewNode}); - } else { - try { - treeViewExplorerMgr.setExploredContextAndSelection(parentTreeViewNode, new Node[]{parentTreeViewNode}); - } catch (PropertyVetoException ex) { - MessageNotifyUtil.Message.error(Bundle.ViewContextAction_errorMessage_cannotSelectDirectory()); - logger.log(Level.SEVERE, "Failed to select the parent node in the tree view", ex); //NON-NLS - } - } + setNodeSelection(this.content, parentTreeViewNode, treeViewTopComponent, treeViewExplorerMgr); }); } + + private Content getParentContent(Content content) { + /* + * Get the parent content for the content to be selected in the + * results view. If the parent content is null, then the specified + * content is a data source, and the parent tree view node is the + * "Data Sources" node. Otherwise, the tree view needs to be + * searched to find the parent treeview node. + */ + try { + Content parent = content.getParent(); + if (parent == null && content instanceof DataSource) { + parent = content; + } + return parent; + } catch (TskCoreException ex) { + MessageNotifyUtil.Message.error(Bundle.ViewContextAction_errorMessage_cannotFindDirectory()); + logger.log(Level.SEVERE, String.format("Could not get parent of Content object: %s", content), ex); //NON-NLS + return null; + } + } + + + private Node getParentNodeGroupedByDataSource(ExplorerManager treeViewExplorerMgr, Content parentContent) { + // Classic view + // Start the search at the DataSourcesNode + Children rootChildren = treeViewExplorerMgr.getRootContext().getChildren(); + Node rootDsNode = rootChildren == null ? null : rootChildren.findChild(DataSourcesNode.getNameIdentifier()); + if (rootDsNode != null) { + for (Node dataSourceLevelNode : getDataSourceLevelNodes(rootDsNode)) { + DataSource dataSource = dataSourceLevelNode.getLookup().lookup(DataSource.class); + if (dataSource != null) { + // the tree view needs to be searched to find the parent treeview node. + Node potentialParentTreeViewNode = findParentNodeInTree(parentContent, dataSourceLevelNode); + if (potentialParentTreeViewNode != null) { + return potentialParentTreeViewNode; + } + } + } + } + + return null; + } + + private Node getParentNodeGroupedByPersonHost(ExplorerManager treeViewExplorerMgr, Content parentContent) { + // 'Group by Data Source' view + + SleuthkitCase skCase; + String dsname; + try { + // get the objid/name of the datasource of the selected content. + skCase = Case.getCurrentCaseThrows().getSleuthkitCase(); + long contentDSObjid = parentContent.getDataSource().getId(); + DataSource datasource = skCase.getDataSource(contentDSObjid); + dsname = datasource.getName(); + Children rootChildren = treeViewExplorerMgr.getRootContext().getChildren(); + + // the tree view needs to be searched to find the parent treeview node. + /* NOTE: we can't do a lookup by data source name here, becase if there + are multiple data sources with the same name, then "getChildren().findChild(dsname)" + simply returns the first one that it finds. Instead we have to loop over all + data sources with that name, and make sure we find the correct one. + */ + List dataSourceLevelNodes = Stream.of(rootChildren.getNodes()) + .flatMap(rootNode -> getDataSourceLevelNodes(rootNode).stream()) + .collect(Collectors.toList()); + + for (Node treeNode : dataSourceLevelNodes) { + // in the root, look for a data source node with the name of interest + if (!(treeNode.getName().equals(dsname))) { + continue; + } + + // for this data source, get the "Data Sources" child node + Node datasourceGroupingNode = treeNode.getChildren().findChild(DataSourceFilesNode.getNameIdentifier()); + + // check whether this is the data source we are looking for + Node parentTreeViewNode = findParentNodeInTree(parentContent, datasourceGroupingNode); + if (parentTreeViewNode != null) { + // found the data source node + return parentTreeViewNode; + } + } + } catch (NoCurrentCaseException | TskDataException | TskCoreException ex) { + MessageNotifyUtil.Message.error(Bundle.ViewContextAction_errorMessage_cannotFindNode()); + logger.log(Level.SEVERE, "Failed to locate data source node in tree.", ex); //NON-NLS + } + + return null; + } + + + private void setNodeSelection(Content content, Node parentTreeViewNode, DirectoryTreeTopComponent treeViewTopComponent, ExplorerManager treeViewExplorerMgr) { + /* + * Set the child selection info of the parent tree node, then select + * the parent node in the tree view. The results view will retrieve + * this selection info and use it to complete this action when the + * tree view top component responds to the selection of the parent + * node by pushing it into the results view top component. + */ + DisplayableItemNode undecoratedParentNode = (DisplayableItemNode) ((DirectoryTreeFilterNode) parentTreeViewNode).getOriginal(); + undecoratedParentNode.setChildNodeSelectionInfo(new ContentNodeSelectionInfo(content)); + if (content instanceof BlackboardArtifact) { + BlackboardArtifact artifact = ((BlackboardArtifact) content); + long associatedId = artifact.getObjectID(); + try { + Content associatedFileContent = artifact.getSleuthkitCase().getContentById(associatedId); + undecoratedParentNode.setChildNodeSelectionInfo(new ContentNodeSelectionInfo(associatedFileContent)); + } catch (TskCoreException ex) { + logger.log(Level.SEVERE, "Could not find associated content from artifact with id %d", artifact.getId()); + } + } + + TreeView treeView = treeViewTopComponent.getTree(); + treeView.expandNode(parentTreeViewNode); + if (treeViewTopComponent.getSelectedNode().equals(parentTreeViewNode)) { + //In the case where our tree view already has the destination directory selected + //due to an optimization in the ExplorerManager.setExploredContextAndSelection method + //the property change we listen for to call DirectoryTreeTopComponent.respondSelection + //will not be sent so we call it manually ourselves after making + //the directory listing the active tab. + treeViewTopComponent.setDirectoryListingActive(); + treeViewTopComponent.respondSelection(treeViewExplorerMgr.getSelectedNodes(), new Node[]{parentTreeViewNode}); + } else { + try { + treeViewExplorerMgr.setExploredContextAndSelection(parentTreeViewNode, new Node[]{parentTreeViewNode}); + } catch (PropertyVetoException ex) { + MessageNotifyUtil.Message.error(Bundle.ViewContextAction_errorMessage_cannotSelectDirectory()); + logger.log(Level.SEVERE, "Failed to select the parent node in the tree view", ex); //NON-NLS + } + } + } /** * If the node has lookup of host or person, returns children. If not, just From ab74e249e512a0d9215a6ea50ba0e13ab9692662 Mon Sep 17 00:00:00 2001 From: Greg DiCristofaro Date: Tue, 15 Jun 2021 15:01:27 -0400 Subject: [PATCH 3/5] commenting --- .../directorytree/ViewContextAction.java | 121 +++++++++++------- 1 file changed, 77 insertions(+), 44 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/directorytree/ViewContextAction.java b/Core/src/org/sleuthkit/autopsy/directorytree/ViewContextAction.java index 2c07c8f8df..7dcbcf85de 100644 --- a/Core/src/org/sleuthkit/autopsy/directorytree/ViewContextAction.java +++ b/Core/src/org/sleuthkit/autopsy/directorytree/ViewContextAction.java @@ -26,7 +26,6 @@ import java.util.Arrays; import java.util.Collections; import java.util.List; import java.util.Objects; -import java.util.Optional; import java.util.logging.Level; import java.util.stream.Collectors; import java.util.stream.Stream; @@ -86,7 +85,7 @@ public class ViewContextAction extends AbstractAction { * parent of the content, selecting the parent in the tree view, then * selecting the content in the results view. * - * @param displayName The display name for the action. + * @param displayName The display name for the action. * @param artifactNode The artifact node for the artifact. */ public ViewContextAction(String displayName, BlackboardArtifactNode artifactNode) { @@ -108,9 +107,9 @@ public class ViewContextAction extends AbstractAction { * parent of the content, selecting the parent in the tree view, then * selecting the content in the results view. * - * @param displayName The display name for the action. + * @param displayName The display name for the action. * @param fileSystemContentNode The file system content node for the - * content. + * content. */ public ViewContextAction(String displayName, AbstractFsContentNode fileSystemContentNode) { super(displayName); @@ -123,9 +122,9 @@ public class ViewContextAction extends AbstractAction { * content, selecting the parent in the tree view, then selecting the * content in the results view. * - * @param displayName The display name for the action. + * @param displayName The display name for the action. * @param abstractAbstractFileNode The AbstractAbstractFileNode node for the - * content. + * content. */ public ViewContextAction(String displayName, AbstractAbstractFileNode abstractAbstractFileNode) { super(displayName); @@ -139,7 +138,7 @@ public class ViewContextAction extends AbstractAction { * content in the results view. * * @param displayName The display name for the action. - * @param content The content. + * @param content The content. */ public ViewContextAction(String displayName, Content content) { super(displayName); @@ -151,7 +150,7 @@ public class ViewContextAction extends AbstractAction { * branch of the tree view to the level of the parent of the content, * selecting the parent in the tree view, then selecting the content in the * results view. - * + * * NOTE: This code will likely need updating in the event that the structure * of the nodes is changed (i.e. adding parent levels). Places to look when * changing node structure include: @@ -171,25 +170,25 @@ public class ViewContextAction extends AbstractAction { EventQueue.invokeLater(() -> { Content parentContent = getParentContent(this.content); - + if ((parentContent != null) && (parentContent instanceof UnsupportedContent)) { MessageNotifyUtil.Message.error(Bundle.ViewContextAction_errorMessage_unsupportedParent()); logger.log(Level.WARNING, String.format("Could not navigate to unsupported content with id: %d", parentContent.getId())); //NON-NLS } - + // Get the "Data Sources" node from the tree view. DirectoryTreeTopComponent treeViewTopComponent = DirectoryTreeTopComponent.findInstance(); ExplorerManager treeViewExplorerMgr = treeViewTopComponent.getExplorerManager(); - + Node parentTreeViewNode = null; if (parentContent != null) { - if (Objects.equals(CasePreferences.getGroupItemsInTreeByDataSource(), true)) { + if (Objects.equals(CasePreferences.getGroupItemsInTreeByDataSource(), true)) { parentTreeViewNode = getParentNodeGroupedByPersonHost(treeViewExplorerMgr, parentContent); - } else { + } else { parentTreeViewNode = getParentNodeGroupedByDataSource(treeViewExplorerMgr, parentContent); - } + } } - + // if no node is found, report error and do nothing if (parentTreeViewNode == null) { MessageNotifyUtil.Message.error(Bundle.ViewContextAction_errorMessage_cannotFindNode()); @@ -200,29 +199,44 @@ public class ViewContextAction extends AbstractAction { setNodeSelection(this.content, parentTreeViewNode, treeViewTopComponent, treeViewExplorerMgr); }); } - + + /** + * Get the parent content for the content to be selected in the results + * view. If the parent content is null, then the specified content is a data + * source, and the parent tree view node is the "Data Sources" node. + * Otherwise, the tree view needs to be searched to find the parent treeview + * node. + * + * @param content The content whose parent will be returned. If this item is + * a datasource, it will be returned. + * + * @return The content if content is a data source or the parent of this + * content. + */ private Content getParentContent(Content content) { - /* - * Get the parent content for the content to be selected in the - * results view. If the parent content is null, then the specified - * content is a data source, and the parent tree view node is the - * "Data Sources" node. Otherwise, the tree view needs to be - * searched to find the parent treeview node. - */ + try { - Content parent = content.getParent(); - if (parent == null && content instanceof DataSource) { - parent = content; - } - return parent; + return (content instanceof DataSource) + ? content + : content.getParent(); } catch (TskCoreException ex) { MessageNotifyUtil.Message.error(Bundle.ViewContextAction_errorMessage_cannotFindDirectory()); logger.log(Level.SEVERE, String.format("Could not get parent of Content object: %s", content), ex); //NON-NLS return null; } } - + /** + * Returns the node in the tree related to the parentContent or null if + * can't be found. This method should be used when view is grouped by data + * source. + * + * @param treeViewExplorerMgr The explorer manager. + * @param parentContent The content whose equivalent node will be + * returned if found. + * + * @return The node if found or null. + */ private Node getParentNodeGroupedByDataSource(ExplorerManager treeViewExplorerMgr, Content parentContent) { // Classic view // Start the search at the DataSourcesNode @@ -240,13 +254,24 @@ public class ViewContextAction extends AbstractAction { } } } - + return null; } + /** + * Returns the node in the tree related to the parentContent or null if + * can't be found. This method should be used when view is grouped by + * hosts/persons. + * + * @param treeViewExplorerMgr The explorer manager. + * @param parentContent The content whose equivalent node will be + * returned if found. + * + * @return The node if found or null. + */ private Node getParentNodeGroupedByPersonHost(ExplorerManager treeViewExplorerMgr, Content parentContent) { // 'Group by Data Source' view - + SleuthkitCase skCase; String dsname; try { @@ -262,7 +287,7 @@ public class ViewContextAction extends AbstractAction { are multiple data sources with the same name, then "getChildren().findChild(dsname)" simply returns the first one that it finds. Instead we have to loop over all data sources with that name, and make sure we find the correct one. - */ + */ List dataSourceLevelNodes = Stream.of(rootChildren.getNodes()) .flatMap(rootNode -> getDataSourceLevelNodes(rootNode).stream()) .collect(Collectors.toList()); @@ -282,16 +307,22 @@ public class ViewContextAction extends AbstractAction { // found the data source node return parentTreeViewNode; } - } + } } catch (NoCurrentCaseException | TskDataException | TskCoreException ex) { MessageNotifyUtil.Message.error(Bundle.ViewContextAction_errorMessage_cannotFindNode()); logger.log(Level.SEVERE, "Failed to locate data source node in tree.", ex); //NON-NLS } - + return null; } - - + + /** + * Set the node selection in the tree. + * @param content The content to select. + * @param parentTreeViewNode The node that is the parent of the content. + * @param treeViewTopComponent The DirectoryTreeTopComponent. + * @param treeViewExplorerMgr The ExplorerManager. + */ private void setNodeSelection(Content content, Node parentTreeViewNode, DirectoryTreeTopComponent treeViewTopComponent, ExplorerManager treeViewExplorerMgr) { /* * Set the child selection info of the parent tree node, then select @@ -299,7 +330,7 @@ public class ViewContextAction extends AbstractAction { * this selection info and use it to complete this action when the * tree view top component responds to the selection of the parent * node by pushing it into the results view top component. - */ + */ DisplayableItemNode undecoratedParentNode = (DisplayableItemNode) ((DirectoryTreeFilterNode) parentTreeViewNode).getOriginal(); undecoratedParentNode.setChildNodeSelectionInfo(new ContentNodeSelectionInfo(content)); if (content instanceof BlackboardArtifact) { @@ -312,7 +343,7 @@ public class ViewContextAction extends AbstractAction { logger.log(Level.SEVERE, "Could not find associated content from artifact with id %d", artifact.getId()); } } - + TreeView treeView = treeViewTopComponent.getTree(); treeView.expandNode(parentTreeViewNode); if (treeViewTopComponent.getSelectedNode().equals(parentTreeViewNode)) { @@ -338,15 +369,16 @@ public class ViewContextAction extends AbstractAction { * returns itself. * * @param node The node. + * * @return The child nodes that are at the data source level. */ private List getDataSourceLevelNodes(Node node) { if (node == null) { return Collections.emptyList(); - } else if (node.getLookup().lookup(Host.class) != null || - node.getLookup().lookup(Person.class) != null || - DataSourcesNode.getNameIdentifier().equals(node.getLookup().lookup(String.class)) || - PersonNode.getUnknownPersonId().equals(node.getLookup().lookup(String.class))) { + } else if (node.getLookup().lookup(Host.class) != null + || node.getLookup().lookup(Person.class) != null + || DataSourcesNode.getNameIdentifier().equals(node.getLookup().lookup(String.class)) + || PersonNode.getUnknownPersonId().equals(node.getLookup().lookup(String.class))) { Children children = node.getChildren(); Node[] childNodes = children == null ? null : children.getNodes(); if (childNodes == null) { @@ -366,7 +398,8 @@ public class ViewContextAction extends AbstractAction { * of the specified content. * * @param parentContent parent content for the content to be searched for - * @param node Node tree to search + * @param node Node tree to search + * * @return Node object of the matching parent, NULL if not found */ private Node findParentNodeInTree(Content parentContent, Node node) { @@ -397,7 +430,7 @@ public class ViewContextAction extends AbstractAction { if (ancestorChildren.getNodesCount() == 1 && StringUtils.equals(ancestorChildren.getNodeAt(0).getName(), node.getName())) { return node; } - + /* * Search the tree for the parent node. Note that this algorithm * simply discards "extra" ancestor nodes not shown in the tree, From 976180eb11561edcf91cf6a12f5aaea20e1406e6 Mon Sep 17 00:00:00 2001 From: Greg DiCristofaro Date: Tue, 15 Jun 2021 18:52:45 -0400 Subject: [PATCH 4/5] load optimal --- .../autopsy/directorytree/ViewContextAction.java | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/directorytree/ViewContextAction.java b/Core/src/org/sleuthkit/autopsy/directorytree/ViewContextAction.java index 7dcbcf85de..f3f2dc0419 100644 --- a/Core/src/org/sleuthkit/autopsy/directorytree/ViewContextAction.java +++ b/Core/src/org/sleuthkit/autopsy/directorytree/ViewContextAction.java @@ -288,7 +288,7 @@ public class ViewContextAction extends AbstractAction { simply returns the first one that it finds. Instead we have to loop over all data sources with that name, and make sure we find the correct one. */ - List dataSourceLevelNodes = Stream.of(rootChildren.getNodes()) + List dataSourceLevelNodes = Stream.of(rootChildren.getNodes(true)) .flatMap(rootNode -> getDataSourceLevelNodes(rootNode).stream()) .collect(Collectors.toList()); @@ -380,12 +380,12 @@ public class ViewContextAction extends AbstractAction { || DataSourcesNode.getNameIdentifier().equals(node.getLookup().lookup(String.class)) || PersonNode.getUnknownPersonId().equals(node.getLookup().lookup(String.class))) { Children children = node.getChildren(); - Node[] childNodes = children == null ? null : children.getNodes(); + Node[] childNodes = children == null ? null : children.getNodes(true); if (childNodes == null) { return Collections.emptyList(); } - return Stream.of(node.getChildren().getNodes()) + return Stream.of(node.getChildren().getNodes(true)) .flatMap(parent -> getDataSourceLevelNodes(parent).stream()) .collect(Collectors.toList()); } else { @@ -441,8 +441,9 @@ public class ViewContextAction extends AbstractAction { Node parentTreeViewNode = null; for (int i = 0; i < ancestorChildren.getNodesCount(); i++) { Node ancestorNode = ancestorChildren.getNodeAt(i); - for (int j = 0; j < treeNodeChildren.getNodesCount(); j++) { - Node treeNode = treeNodeChildren.getNodeAt(j); + Node[] treeNodeChilds = treeNodeChildren.getNodes(true); + for (int j = 0; j < treeNodeChilds.length; j++) { + Node treeNode = treeNodeChilds[j]; if (ancestorNode.getName().equals(treeNode.getName())) { parentTreeViewNode = treeNode; treeNodeChildren = treeNode.getChildren(); From 5f3a9ff04a0ee9f06940802c18e0ff8bcc2e1c17 Mon Sep 17 00:00:00 2001 From: Greg DiCristofaro Date: Wed, 16 Jun 2021 10:47:21 -0400 Subject: [PATCH 5/5] early return --- .../org/sleuthkit/autopsy/directorytree/ViewContextAction.java | 1 + 1 file changed, 1 insertion(+) diff --git a/Core/src/org/sleuthkit/autopsy/directorytree/ViewContextAction.java b/Core/src/org/sleuthkit/autopsy/directorytree/ViewContextAction.java index f3f2dc0419..323b340c7f 100644 --- a/Core/src/org/sleuthkit/autopsy/directorytree/ViewContextAction.java +++ b/Core/src/org/sleuthkit/autopsy/directorytree/ViewContextAction.java @@ -174,6 +174,7 @@ public class ViewContextAction extends AbstractAction { if ((parentContent != null) && (parentContent instanceof UnsupportedContent)) { MessageNotifyUtil.Message.error(Bundle.ViewContextAction_errorMessage_unsupportedParent()); logger.log(Level.WARNING, String.format("Could not navigate to unsupported content with id: %d", parentContent.getId())); //NON-NLS + return; } // Get the "Data Sources" node from the tree view.