Autopsy  4.1
Graphical digital forensics platform for The Sleuth Kit and other tools.
DataResultFilterNode.java
Go to the documentation of this file.
1 /*
2  * Autopsy Forensic Browser
3  *
4  * Copyright 2011-2016 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.event.ActionEvent;
22 import java.beans.PropertyVetoException;
23 import java.util.ArrayList;
24 import java.util.List;
25 import java.util.logging.Level;
26 import javax.swing.AbstractAction;
27 import javax.swing.Action;
28 import org.openide.explorer.ExplorerManager;
29 import org.openide.nodes.AbstractNode;
30 import org.openide.nodes.FilterNode;
31 import org.openide.nodes.Node;
32 import org.openide.nodes.Sheet;
33 import org.openide.util.NbBundle;
49 import org.sleuthkit.datamodel.AbstractFile;
50 import org.sleuthkit.datamodel.BlackboardArtifact;
51 import org.sleuthkit.datamodel.BlackboardAttribute;
52 import org.sleuthkit.datamodel.Content;
53 import org.sleuthkit.datamodel.DerivedFile;
54 import org.sleuthkit.datamodel.Directory;
55 import org.sleuthkit.datamodel.File;
56 import org.sleuthkit.datamodel.LayoutFile;
57 import org.sleuthkit.datamodel.LocalFile;
58 import org.sleuthkit.datamodel.TskException;
59 import org.sleuthkit.datamodel.VirtualDirectory;
60 
65 public class DataResultFilterNode extends FilterNode {
66 
67  private ExplorerManager sourceEm;
68 
70 
72 
78  public DataResultFilterNode(Node node, ExplorerManager em) {
79  super(node, new DataResultFilterChildren(node, em));
80  this.sourceEm = em;
81  getActionsDIV = new GetPopupActionsDisplayableItemNodeVisitor();
82  getPreferredActionsDIV = new GetPreferredActionsDisplayableItemNodeVisitor();
83  }
84 
93  @Override
94  public Action[] getActions(boolean popup) {
95 
96  List<Action> actions = new ArrayList<>();
97 
98  final DisplayableItemNode originalNode = (DisplayableItemNode) this.getOriginal();
99  List<Action> accept = originalNode.accept(getActionsDIV);
100  if (accept != null) {
101  actions.addAll(accept);
102  }
103 
104  //actions.add(new IndexContentFilesAction(nodeContent, "Index"));
105  return actions.toArray(new Action[actions.size()]);
106  }
107 
114  @Override
115  public Action getPreferredAction() {
116  final Node original = this.getOriginal();
117  // Once had a org.openide.nodes.ChildFactory$WaitFilterNode passed in
118  if ((original instanceof DisplayableItemNode) == false) {
119  return null;
120  }
121 
122  final DisplayableItemNode originalNode = (DisplayableItemNode) this.getOriginal();
123  return originalNode.accept(getPreferredActionsDIV);
124  }
125 
126  @Override
127  public Node.PropertySet[] getPropertySets() {
128  Node.PropertySet[] propertySets = super.getPropertySets();
129 
130  for (int i = 0; i < propertySets.length; i++) {
131  Node.PropertySet ps = propertySets[i];
132 
133  if (ps.getName().equals(Sheet.PROPERTIES)) {
134  Sheet.Set newPs = new Sheet.Set();
135  newPs.setName(ps.getName());
136  newPs.setDisplayName(ps.getDisplayName());
137  newPs.setShortDescription(ps.getShortDescription());
138 
139  newPs.put(ps.getProperties());
140  if (newPs.remove(AbstractFsContentNode.HIDE_PARENT) != null) {
141  newPs.remove(AbstractFilePropertyType.LOCATION.toString());
142  }
143  propertySets[i] = newPs;
144  }
145  }
146 
147  return propertySets;
148  }
149 
154  private static class GetPopupActionsDisplayableItemNodeVisitor extends DisplayableItemNodeVisitor.Default<List<Action>> {
155 
156  @Override
157  public List<Action> visit(BlackboardArtifactNode ban) {
158  //set up actions for artifact node based on its Content object
159  //TODO all actions need to be consolidated in single place!
160  //they should be set in individual Node subclass and using a utility to get Actions per Content sub-type
161  // TODO UPDATE: There is now a DataModelActionsFactory utility;
162 
163  List<Action> actions = new ArrayList<>();
164 
165  //merge predefined specific node actions if bban subclasses have their own
166  for (Action a : ban.getActions(true)) {
167  actions.add(a);
168  }
169  BlackboardArtifact ba = ban.getLookup().lookup(BlackboardArtifact.class);
170  final int artifactTypeID = ba.getArtifactTypeID();
171 
172  if (artifactTypeID == BlackboardArtifact.ARTIFACT_TYPE.TSK_HASHSET_HIT.getTypeID()
173  || artifactTypeID == BlackboardArtifact.ARTIFACT_TYPE.TSK_KEYWORD_HIT.getTypeID()) {
174  actions.add(new ViewContextAction(
175  NbBundle.getMessage(this.getClass(), "DataResultFilterNode.action.viewFileInDir.text"), ban));
176  } else {
177  // if the artifact links to another file, add an action to go to
178  // that file
179  Content c = findLinked(ban);
180  if (c != null) {
181  actions.add(new ViewContextAction(
182  NbBundle.getMessage(this.getClass(), "DataResultFilterNode.action.viewFileInDir.text"), c));
183  }
184  // action to go to the source file of the artifact
185  actions.add(new ViewContextAction(
186  NbBundle.getMessage(this.getClass(), "DataResultFilterNode.action.viewSrcFileInDir.text"), ban));
187  }
188  Content c = ban.getLookup().lookup(File.class);
189  Node n = null;
190  boolean md5Action = false;
191  if (c != null) {
192  n = new FileNode((AbstractFile) c);
193  md5Action = true;
194  } else if ((c = ban.getLookup().lookup(Directory.class)) != null) {
195  n = new DirectoryNode((Directory) c);
196  } else if ((c = ban.getLookup().lookup(VirtualDirectory.class)) != null) {
197  n = new VirtualDirectoryNode((VirtualDirectory) c);
198  } else if ((c = ban.getLookup().lookup(LayoutFile.class)) != null) {
199  n = new LayoutFileNode((LayoutFile) c);
200  } else if ((c = ban.getLookup().lookup(LocalFile.class)) != null
201  || (c = ban.getLookup().lookup(DerivedFile.class)) != null) {
202  n = new LocalFileNode((AbstractFile) c);
203  }
204  if (n != null) {
205  actions.add(null); // creates a menu separator
206  actions.add(new NewWindowViewAction(
207  NbBundle.getMessage(this.getClass(), "DataResultFilterNode.action.viewInNewWin.text"), n));
208  actions.add(new ExternalViewerAction(
209  NbBundle.getMessage(this.getClass(), "DataResultFilterNode.action.openInExtViewer.text"), n));
210  actions.add(null); // creates a menu separator
211  actions.add(ExtractAction.getInstance());
212  if (md5Action) {
213  actions.add(new HashSearchAction(
214  NbBundle.getMessage(this.getClass(), "DataResultFilterNode.action.searchFilesSameMd5.text"), n));
215  }
216  actions.add(null); // creates a menu separator
217  actions.add(AddContentTagAction.getInstance());
219  actions.addAll(ContextMenuExtensionPoint.getActions());
220  } else {
221  // There's no specific file associated with the artifact, but
222  // we can still tag the artifact itself
223  actions.add(null);
225  }
226  return actions;
227  }
228 
229  @Override
230  public List<Action> visit(Reports.ReportsListNode ditem) {
231  // The base class Action is "Collapse All", inappropriate.
232  return null;
233  }
234 
235  @Override
236  protected List<Action> defaultVisit(DisplayableItemNode ditem) {
237  //preserve the default node's actions
238  List<Action> actions = new ArrayList<>();
239 
240  for (Action action : ditem.getActions(true)) {
241  actions.add(action);
242  }
243 
244  return actions;
245  }
246 
247  private Content findLinked(BlackboardArtifactNode ba) {
248  BlackboardArtifact art = ba.getLookup().lookup(BlackboardArtifact.class);
249  Content c = null;
250  try {
251  for (BlackboardAttribute attr : art.getAttributes()) {
252  if (attr.getAttributeType().getTypeID() == BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PATH_ID.getTypeID()) {
253  switch (attr.getAttributeType().getValueType()) {
254  case INTEGER:
255  int i = attr.getValueInt();
256  if (i != -1) {
257  c = art.getSleuthkitCase().getContentById(i);
258  }
259  break;
260  case LONG:
261  long l = attr.getValueLong();
262  if (l != -1) {
263  c = art.getSleuthkitCase().getContentById(l);
264  }
265  break;
266  }
267  }
268  }
269  } catch (TskException ex) {
270  Logger.getLogger(this.getClass().getName()).log(Level.WARNING, "Error getting linked file", ex); //NON-NLS
271  }
272  return c;
273  }
274  }
275 
276  /*
277  * Action for double-click / preferred action on nodes.
278  */
279  private class GetPreferredActionsDisplayableItemNodeVisitor extends DisplayableItemNodeVisitor.Default<AbstractAction> {
280 
281  @Override
282  public AbstractAction visit(BlackboardArtifactNode ban) {
283  return new ViewContextAction(
284  NbBundle.getMessage(this.getClass(), "DataResultFilterNode.action.viewInDir.text"), ban);
285  }
286 
287  @Override
288  public AbstractAction visit(DirectoryNode dn) {
289  if (dn.getDisplayName().equals(DirectoryNode.DOTDOTDIR)) {
290  return openParent(dn);
291  } else if (dn.getDisplayName().equals(DirectoryNode.DOTDIR) == false) {
292  return openChild(dn);
293  } else {
294  return null;
295  }
296  }
297 
298  @Override
299  public AbstractAction visit(FileNode fn) {
300  if (fn.hasContentChildren()) {
301  return openChild(fn);
302  } else {
303  return null;
304  }
305  }
306 
307  @Override
308  public AbstractAction visit(LocalFileNode dfn) {
309  if (dfn.hasContentChildren()) {
310  return openChild(dfn);
311  } else {
312  return null;
313  }
314  }
315 
316  @Override
317  public AbstractAction visit(Reports.ReportNode reportNode) {
318  return reportNode.getPreferredAction();
319  }
320 
321  @Override
322  protected AbstractAction defaultVisit(DisplayableItemNode c) {
323  return openChild(c);
324  }
325 
334  private AbstractAction openChild(final AbstractNode dataModelNode) {
335  // get the current selection from the directory tree explorer manager,
336  // which is a DirectoryTreeFilterNode. One of that node's children
337  // is a DirectoryTreeFilterNode that wraps the dataModelNode. We need
338  // to set that wrapped node as the selection and root context of the
339  // directory tree explorer manager (sourceEm)
340  final Node currentSelectionInDirectoryTree = sourceEm.getSelectedNodes()[0];
341 
342  return new AbstractAction() {
343  @Override
344  public void actionPerformed(ActionEvent e) {
345  if (currentSelectionInDirectoryTree != null) {
346  // Find the filter version of the passed in dataModelNode.
347  final org.openide.nodes.Children children = currentSelectionInDirectoryTree.getChildren();
348  // This call could break if the DirectoryTree is re-implemented with lazy ChildFactory objects.
349  Node newSelection = children.findChild(dataModelNode.getName());
350 
351  /*
352  * We got null here when we were viewing a ZIP file in
353  * the Views -> Archives area and double clicking on it
354  * got to this code. It tried to find the child in the
355  * tree and didn't find it. An exception was then thrown
356  * from setting the selected node to be null.
357  */
358  if (newSelection != null) {
359  try {
360  sourceEm.setExploredContextAndSelection(newSelection, new Node[]{newSelection});
361  } catch (PropertyVetoException ex) {
362  Logger logger = Logger.getLogger(DataResultFilterNode.class.getName());
363  logger.log(Level.WARNING, "Error: can't open the selected directory.", ex); //NON-NLS
364  }
365  }
366  }
367  }
368  };
369  }
370 
379  private AbstractAction openParent(AbstractNode node) {
380  // @@@ Why do we ignore node?
381  Node[] selectedFilterNodes = sourceEm.getSelectedNodes();
382  Node selectedFilterNode = selectedFilterNodes[0];
383  final Node parentNode = selectedFilterNode.getParentNode();
384 
385  return new AbstractAction() {
386  @Override
387  public void actionPerformed(ActionEvent e) {
388  try {
389  sourceEm.setSelectedNodes(new Node[]{parentNode});
390  } catch (PropertyVetoException ex) {
391  Logger logger = Logger.getLogger(DataResultFilterNode.class.getName());
392  logger.log(Level.WARNING, "Error: can't open the parent directory.", ex); //NON-NLS
393  }
394  }
395  };
396  }
397  }
398 }
final DisplayableItemNodeVisitor< List< Action > > getActionsDIV
static synchronized AddBlackboardArtifactTagAction getInstance()
abstract< T > T accept(DisplayableItemNodeVisitor< T > v)
static synchronized ExtractAction getInstance()
final DisplayableItemNodeVisitor< AbstractAction > getPreferredActionsDIV
synchronized static Logger getLogger(String name)
Definition: Logger.java:161
static synchronized AddContentTagAction getInstance()

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