Autopsy  4.5.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-2017 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.logging.Level;
29 import javax.swing.AbstractAction;
30 import org.openide.nodes.AbstractNode;
31 import org.openide.explorer.ExplorerManager;
32 import org.openide.explorer.view.TreeView;
33 import org.openide.nodes.Children;
34 import org.openide.nodes.Node;
35 import org.openide.util.NbBundle.Messages;
44 import org.sleuthkit.datamodel.AbstractFile;
45 import org.sleuthkit.datamodel.Content;
46 import org.sleuthkit.datamodel.ContentVisitor;
47 import org.sleuthkit.datamodel.FileSystem;
48 import org.sleuthkit.datamodel.TskCoreException;
49 import org.sleuthkit.datamodel.TskData;
50 import org.sleuthkit.datamodel.VolumeSystem;
51 
58 public class ViewContextAction extends AbstractAction {
59 
60  private static final long serialVersionUID = 1L;
61  private static final Logger logger = Logger.getLogger(ViewContextAction.class.getName());
62  private final Content content;
63 
73  public ViewContextAction(String displayName, BlackboardArtifactNode artifactNode) {
74  super(displayName);
75  this.content = artifactNode.getLookup().lookup(AbstractFile.class);
76  if (this.content != null) {
77  AbstractFile file = (AbstractFile) content;
78  if ((TskData.FileKnown.KNOWN == file.getKnown() && UserPreferences.hideKnownFilesInDataSourcesTree())
79  || (TskData.TSK_DB_FILES_TYPE_ENUM.SLACK == file.getType() && UserPreferences.hideSlackFilesInDataSourcesTree())) {
80  this.setEnabled(false);
81  }
82  }
83  }
84 
95  public ViewContextAction(String displayName, AbstractFsContentNode<? extends AbstractFile> fileSystemContentNode) {
96  super(displayName);
97  this.content = fileSystemContentNode.getLookup().lookup(Content.class);
98  }
99 
109  public ViewContextAction(String displayName, Content content) {
110  super(displayName);
111  this.content = content;
112  }
113 
122  @Override
123  @Messages({
124  "ViewContextAction.errorMessage.cannotFindDirectory=Failed to locate directory.",
125  "ViewContextAction.errorMessage.cannotSelectDirectory=Failed to select directory in tree.",})
126  public void actionPerformed(ActionEvent event) {
127  EventQueue.invokeLater(() -> {
128  /*
129  * Get the "Data Sources" node from the tree view.
130  */
132  ExplorerManager treeViewExplorerMgr = treeViewTopComponent.getExplorerManager();
133  Node parentTreeViewNode = treeViewExplorerMgr.getRootContext().getChildren().findChild(DataSourcesNode.NAME);
134  /*
135  * Get the parent content for the content to be selected in the
136  * results view. If the parent content is null, then the specified
137  * content is a data source, and the parent tree view node is the
138  * "Data Sources" node. Otherwise, the tree view needs to be
139  * searched to find the parent treeview node.
140  */
141  Content parentContent = null;
142  try {
143  parentContent = content.getParent();
144  } catch (TskCoreException ex) {
145  MessageNotifyUtil.Message.error(Bundle.ViewContextAction_errorMessage_cannotFindDirectory());
146  logger.log(Level.SEVERE, String.format("Could not get parent of Content object: %s", content), ex); //NON-NLS
147  return;
148  }
149  if (null != parentContent) {
150  /*
151  * Get an ordered list of the ancestors of the specified
152  * content, starting with its data source.
153  *
154  */
155  AncestorVisitor ancestorVisitor = new AncestorVisitor();
156  List<Content> contentBranch = parentContent.accept(ancestorVisitor);
157  Collections.reverse(contentBranch);
158 
171  Node dummyRootNode = new DirectoryTreeFilterNode(new AbstractNode(new RootContentChildren(contentBranch)), true);
172  Children ancestorChildren = dummyRootNode.getChildren();
173 
174  /*
175  * Search the tree for the parent node. Note that this algorithm
176  * simply discards "extra" ancestor nodes not shown in the tree,
177  * such as the root directory of the file system for file system
178  * content.
179  */
180  Children treeNodeChildren = parentTreeViewNode.getChildren();
181  for (int i = 0; i < ancestorChildren.getNodesCount(); i++) {
182  Node ancestorNode = ancestorChildren.getNodeAt(i);
183  for (int j = 0; j < treeNodeChildren.getNodesCount(); j++) {
184  Node treeNode = treeNodeChildren.getNodeAt(j);
185  if (ancestorNode.getDisplayName().equals(treeNode.getDisplayName())) {
186  parentTreeViewNode = treeNode;
187  treeNodeChildren = treeNode.getChildren();
188  break;
189  }
190  }
191  }
192  }
193 
194  /*
195  * Set the child selection info of the parent tree node, then select
196  * the parent node in the tree view. The results view will retrieve
197  * this selection info and use it to complete this action when the
198  * tree view top component responds to the selection of the parent
199  * node by pushing it into the results view top component.
200  */
201  DisplayableItemNode undecoratedParentNode = (DisplayableItemNode) ((DirectoryTreeFilterNode) parentTreeViewNode).getOriginal();
202  undecoratedParentNode.setChildNodeSelectionInfo(new ContentNodeSelectionInfo(content));
203  TreeView treeView = treeViewTopComponent.getTree();
204  treeView.expandNode(parentTreeViewNode);
205  if (treeViewTopComponent.getSelectedNode().equals(parentTreeViewNode)) {
206  //In the case where our tree view already has the destination directory selected
207  //due to an optimization in the ExplorerManager.setExploredContextAndSelection method
208  //the property change we listen for to call DirectoryTreeTopComponent.respondSelection
209  //will not be sent so we call it manually ourselves after making
210  //the directory listing the active tab.
211  treeViewTopComponent.setDirectoryListingActive();
212  treeViewTopComponent.respondSelection(treeViewExplorerMgr.getSelectedNodes(), new Node[]{parentTreeViewNode});
213  } else {
214  try {
215  treeViewExplorerMgr.setExploredContextAndSelection(parentTreeViewNode, new Node[]{parentTreeViewNode});
216  } catch (PropertyVetoException ex) {
217  MessageNotifyUtil.Message.error(Bundle.ViewContextAction_errorMessage_cannotSelectDirectory());
218  logger.log(Level.SEVERE, "Failed to select the parent node in the tree view", ex); //NON-NLS
219  }
220  }
221  });
222  }
223 
229  private static class AncestorVisitor extends ContentVisitor.Default<List<Content>> {
230 
231  List<Content> lineage = new ArrayList<>();
232 
233  @Override
234  protected List<Content> defaultVisit(Content content) {
235  lineage.add(content);
236  Content parent = null;
237  try {
238  parent = content.getParent();
239  } catch (TskCoreException ex) {
240  logger.log(Level.SEVERE, String.format("Could not get parent of Content object: %s", content), ex); //NON-NLS
241  }
242  return parent == null ? lineage : parent.accept(this);
243  }
244 
245  @Override
246  public List<Content> visit(VolumeSystem volumeSystem) {
247  /*
248  * Volume systems are not shown in the tree view. This is not
249  * strictly necesssary given the algorithm above, but it is a simple
250  * optimization.
251  */
252  return skipToParent(volumeSystem);
253  }
254 
255  @Override
256  public List<Content> visit(FileSystem fileSystem) {
257  /*
258  * File systems are not shown in the tree view. This is not strictly
259  * necesssary given the algorithm above, but it is a simple
260  * optimization.
261  */
262  return skipToParent(fileSystem);
263  }
264 
265  private List<Content> skipToParent(Content content) {
266  Content parent = null;
267  try {
268  parent = content.getParent();
269  } catch (TskCoreException ex) {
270  logger.log(Level.SEVERE, String.format("Could not get parent of Content object: %s", content), ex); //NON-NLS
271  }
272  return parent == null ? lineage : parent.accept(this);
273  }
274  }
275 
276 }
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-2016 Basis Technology. Generated on: Tue Feb 20 2018
This work is licensed under a Creative Commons Attribution-Share Alike 3.0 United States License.