Autopsy  4.8.0
Graphical digital forensics platform for The Sleuth Kit and other tools.
ViewContextAction.java
Go to the documentation of this file.
1 /*
2  * Autopsy Forensic Browser
3  *
4  * Copyright 2011-2018 Basis Technology Corp.
5  * Contact: carrier <at> sleuthkit <dot> org
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  * http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  */
19 package org.sleuthkit.autopsy.directorytree;
20 
21 import java.awt.EventQueue;
22 import java.awt.event.ActionEvent;
23 import java.beans.PropertyVetoException;
24 import java.util.ArrayList;
25 import java.util.Collections;
26 import java.util.List;
27 import java.util.Objects;
28 import java.util.logging.Level;
30 import javax.swing.AbstractAction;
31 import org.openide.nodes.AbstractNode;
32 import org.openide.explorer.ExplorerManager;
33 import org.openide.explorer.view.TreeView;
34 import org.openide.nodes.Children;
35 import org.openide.nodes.Node;
36 import org.openide.util.NbBundle.Messages;
48 import org.sleuthkit.datamodel.AbstractFile;
49 import org.sleuthkit.datamodel.Content;
50 import org.sleuthkit.datamodel.ContentVisitor;
51 import org.sleuthkit.datamodel.DataSource;
52 import org.sleuthkit.datamodel.FileSystem;
53 import org.sleuthkit.datamodel.SleuthkitCase;
54 import org.sleuthkit.datamodel.TskCoreException;
55 import org.sleuthkit.datamodel.TskData;
56 import org.sleuthkit.datamodel.TskDataException;
57 import org.sleuthkit.datamodel.VolumeSystem;
58 
65 public class ViewContextAction extends AbstractAction {
66 
67  private static final long serialVersionUID = 1L;
68  private static final Logger logger = Logger.getLogger(ViewContextAction.class.getName());
69  private final Content content;
70 
80  public ViewContextAction(String displayName, BlackboardArtifactNode artifactNode) {
81  super(displayName);
82  this.content = artifactNode.getLookup().lookup(AbstractFile.class);
83  if (this.content != null) {
84  AbstractFile file = (AbstractFile) content;
85  if ((TskData.FileKnown.KNOWN == file.getKnown() && UserPreferences.hideKnownFilesInDataSourcesTree())
86  || (TskData.TSK_DB_FILES_TYPE_ENUM.SLACK == file.getType() && UserPreferences.hideSlackFilesInDataSourcesTree())) {
87  this.setEnabled(false);
88  }
89  }
90  }
91 
102  public ViewContextAction(String displayName, AbstractFsContentNode<? extends AbstractFile> fileSystemContentNode) {
103  super(displayName);
104  this.content = fileSystemContentNode.getLookup().lookup(Content.class);
105  }
106 
116  public ViewContextAction(String displayName, Content content) {
117  super(displayName);
118  this.content = content;
119  }
120 
129  @Override
130  @Messages({
131  "ViewContextAction.errorMessage.cannotFindDirectory=Failed to locate directory.",
132  "ViewContextAction.errorMessage.cannotSelectDirectory=Failed to select directory in tree.",
133  "ViewContextAction.errorMessage.cannotFindNode=Failed to locate data source node in tree."
134  })
135  public void actionPerformed(ActionEvent event) {
136  EventQueue.invokeLater(() -> {
137  /*
138  * Get the "Data Sources" node from the tree view.
139  */
141  ExplorerManager treeViewExplorerMgr = treeViewTopComponent.getExplorerManager();
142  Node parentTreeViewNode;
143  if (Objects.equals(CasePreferences.getGroupItemsInTreeByDataSource(), true)) { // 'Group by Data Source' view
144 
145  SleuthkitCase skCase;
146  String dsname;
147  try {
148  // get the objid/name of the datasource of the selected content.
150  long contentDSObjid = content.getDataSource().getId();
151  DataSource datasource = skCase.getDataSource(contentDSObjid);
152  dsname = datasource.getName();
153 
154  Children rootChildren = treeViewExplorerMgr.getRootContext().getChildren();
155  Node datasourceGroupingNode = rootChildren.findChild(dsname);
156  if (! Objects.isNull(datasourceGroupingNode) ) {
157  Children dsChildren = datasourceGroupingNode.getChildren();
158  parentTreeViewNode = dsChildren.findChild(DataSourcesNode.NAME);
159  }
160  else {
161  MessageNotifyUtil.Message.error(Bundle.ViewContextAction_errorMessage_cannotFindNode());
162  logger.log(Level.SEVERE, "Failed to locate data source node in tree."); //NON-NLS
163  return;
164  }
165  } catch (NoCurrentCaseException | TskDataException | TskCoreException ex) {
166  MessageNotifyUtil.Message.error(Bundle.ViewContextAction_errorMessage_cannotFindNode());
167  logger.log(Level.SEVERE, "Failed to locate data source node in tree.", ex); //NON-NLS
168  return;
169  }
170  } else { // Classic view
171  // Start the search at the DataSourcesNode
172  parentTreeViewNode = treeViewExplorerMgr.getRootContext().getChildren().findChild(DataSourcesNode.NAME);
173  }
174 
175  /*
176  * Get the parent content for the content to be selected in the
177  * results view. If the parent content is null, then the specified
178  * content is a data source, and the parent tree view node is the
179  * "Data Sources" node. Otherwise, the tree view needs to be
180  * searched to find the parent treeview node.
181  */
182  Content parentContent = null;
183  try {
184  parentContent = content.getParent();
185  } catch (TskCoreException ex) {
186  MessageNotifyUtil.Message.error(Bundle.ViewContextAction_errorMessage_cannotFindDirectory());
187  logger.log(Level.SEVERE, String.format("Could not get parent of Content object: %s", content), ex); //NON-NLS
188  return;
189  }
190  if (null != parentContent) {
191  /*
192  * Get an ordered list of the ancestors of the specified
193  * content, starting with its data source.
194  *
195  */
196  AncestorVisitor ancestorVisitor = new AncestorVisitor();
197  List<Content> contentBranch = parentContent.accept(ancestorVisitor);
198  Collections.reverse(contentBranch);
199 
212  Node dummyRootNode = new DirectoryTreeFilterNode(new AbstractNode(new RootContentChildren(contentBranch)), true);
213  Children ancestorChildren = dummyRootNode.getChildren();
214 
215  /*
216  * Search the tree for the parent node. Note that this algorithm
217  * simply discards "extra" ancestor nodes not shown in the tree,
218  * such as the root directory of the file system for file system
219  * content.
220  */
221  Children treeNodeChildren = parentTreeViewNode.getChildren();
222  for (int i = 0; i < ancestorChildren.getNodesCount(); i++) {
223  Node ancestorNode = ancestorChildren.getNodeAt(i);
224  for (int j = 0; j < treeNodeChildren.getNodesCount(); j++) {
225  Node treeNode = treeNodeChildren.getNodeAt(j);
226  if (ancestorNode.getDisplayName().equals(treeNode.getDisplayName())) {
227  parentTreeViewNode = treeNode;
228  treeNodeChildren = treeNode.getChildren();
229  break;
230  }
231  }
232  }
233  }
234 
235  /*
236  * Set the child selection info of the parent tree node, then select
237  * the parent node in the tree view. The results view will retrieve
238  * this selection info and use it to complete this action when the
239  * tree view top component responds to the selection of the parent
240  * node by pushing it into the results view top component.
241  */
242  DisplayableItemNode undecoratedParentNode = (DisplayableItemNode) ((DirectoryTreeFilterNode) parentTreeViewNode).getOriginal();
243  undecoratedParentNode.setChildNodeSelectionInfo(new ContentNodeSelectionInfo(content));
244  TreeView treeView = treeViewTopComponent.getTree();
245  treeView.expandNode(parentTreeViewNode);
246  if (treeViewTopComponent.getSelectedNode().equals(parentTreeViewNode)) {
247  //In the case where our tree view already has the destination directory selected
248  //due to an optimization in the ExplorerManager.setExploredContextAndSelection method
249  //the property change we listen for to call DirectoryTreeTopComponent.respondSelection
250  //will not be sent so we call it manually ourselves after making
251  //the directory listing the active tab.
252  treeViewTopComponent.setDirectoryListingActive();
253  treeViewTopComponent.respondSelection(treeViewExplorerMgr.getSelectedNodes(), new Node[]{parentTreeViewNode});
254  } else {
255  try {
256  treeViewExplorerMgr.setExploredContextAndSelection(parentTreeViewNode, new Node[]{parentTreeViewNode});
257  } catch (PropertyVetoException ex) {
258  MessageNotifyUtil.Message.error(Bundle.ViewContextAction_errorMessage_cannotSelectDirectory());
259  logger.log(Level.SEVERE, "Failed to select the parent node in the tree view", ex); //NON-NLS
260  }
261  }
262  });
263  }
264 
270  private static class AncestorVisitor extends ContentVisitor.Default<List<Content>> {
271 
272  List<Content> lineage = new ArrayList<>();
273 
274  @Override
275  protected List<Content> defaultVisit(Content content) {
276  lineage.add(content);
277  Content parent = null;
278  try {
279  parent = content.getParent();
280  } catch (TskCoreException ex) {
281  logger.log(Level.SEVERE, String.format("Could not get parent of Content object: %s", content), ex); //NON-NLS
282  }
283  return parent == null ? lineage : parent.accept(this);
284  }
285 
286  @Override
287  public List<Content> visit(VolumeSystem volumeSystem) {
288  /*
289  * Volume systems are not shown in the tree view. This is not
290  * strictly necesssary given the algorithm above, but it is a simple
291  * optimization.
292  */
293  return skipToParent(volumeSystem);
294  }
295 
296  @Override
297  public List<Content> visit(FileSystem fileSystem) {
298  /*
299  * File systems are not shown in the tree view. This is not strictly
300  * necesssary given the algorithm above, but it is a simple
301  * optimization.
302  */
303  return skipToParent(fileSystem);
304  }
305 
306  private List<Content> skipToParent(Content content) {
307  Content parent = null;
308  try {
309  parent = content.getParent();
310  } catch (TskCoreException ex) {
311  logger.log(Level.SEVERE, String.format("Could not get parent of Content object: %s", content), ex); //NON-NLS
312  }
313  return parent == null ? lineage : parent.accept(this);
314  }
315  }
316 
317 }
ViewContextAction(String displayName, Content content)
ViewContextAction(String displayName, BlackboardArtifactNode artifactNode)
ViewContextAction(String displayName, AbstractFsContentNode<?extends AbstractFile > fileSystemContentNode)
synchronized static Logger getLogger(String name)
Definition: Logger.java:124
void setChildNodeSelectionInfo(NodeSelectionInfo selectedChildNodeInfo)
static synchronized DirectoryTreeTopComponent findInstance()

Copyright © 2012-2018 Basis Technology. Generated on: Thu Oct 4 2018
This work is licensed under a Creative Commons Attribution-Share Alike 3.0 United States License.