Autopsy  4.19.2
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 2012-2020 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.text.MessageFormat;
24 import java.util.ArrayList;
25 import java.util.Arrays;
26 import java.util.List;
27 import java.util.logging.Level;
28 import javax.swing.AbstractAction;
29 import javax.swing.Action;
30 import org.openide.explorer.ExplorerManager;
31 import org.openide.nodes.AbstractNode;
32 import org.openide.nodes.FilterNode;
33 import org.openide.nodes.Node;
34 import org.openide.nodes.Sheet;
35 import org.openide.util.NbBundle;
53 import org.sleuthkit.datamodel.BlackboardArtifact;
54 import org.sleuthkit.datamodel.BlackboardArtifact.ARTIFACT_TYPE;
55 import org.sleuthkit.datamodel.TskCoreException;
56 
62 public class DataResultFilterNode extends FilterNode {
63 
64  private static final Logger LOGGER = Logger.getLogger(DataResultFilterNode.class.getName());
65 
68 
69  // Assumptions are made in GetPreferredActionsDisplayableItemNodeVisitor that
70  // sourceEm is the directory tree explorer manager.
71  private final ExplorerManager sourceEm;
72 
80  public DataResultFilterNode(Node node) {
81  this(node, null);
82  }
83 
93  public DataResultFilterNode(Node node, ExplorerManager em) {
94  super(node, new DataResultFilterChildren(node, em));
95  this.sourceEm = em;
96  }
97 
106  @Override
107  public Action[] getActions(boolean popup) {
108 
109  List<Action> actions = new ArrayList<>();
110  if (this.getOriginal() instanceof DisplayableItemNode) {
111  final DisplayableItemNode originalNode = (DisplayableItemNode) this.getOriginal();
112  List<Action> accept = originalNode.accept(getActionsDIV);
113  if (accept != null) {
114  actions.addAll(accept);
115  }
116  }
117 
118  //actions.add(new IndexContentFilesAction(nodeContent, "Index"));
119  return actions.toArray(new Action[actions.size()]);
120  }
121 
128  @Override
129  public Action getPreferredAction() {
130  final Node original = this.getOriginal();
131  // Once had a org.openide.nodes.ChildFactory$WaitFilterNode passed in
132  if ((original instanceof DisplayableItemNode) == false) {
133  return null;
134  }
135 
136  final DisplayableItemNode originalNode = (DisplayableItemNode) this.getOriginal();
137  return originalNode.accept(getPreferredActionsDIV);
138  }
139 
140  @Override
141  public Node.PropertySet[] getPropertySets() {
142  Node.PropertySet[] propertySets = super.getPropertySets();
143 
144  for (int i = 0; i < propertySets.length; i++) {
145  Node.PropertySet ps = propertySets[i];
146 
147  if (ps.getName().equals(Sheet.PROPERTIES)) {
148  Sheet.Set newPs = new Sheet.Set();
149  newPs.setName(ps.getName());
150  newPs.setDisplayName(ps.getDisplayName());
151  newPs.setShortDescription(ps.getShortDescription());
152 
153  newPs.put(ps.getProperties());
154  newPs.remove(AbstractFsContentNode.HIDE_PARENT);
155  propertySets[i] = newPs;
156  }
157  }
158 
159  return propertySets;
160  }
161 
168  public void setChildNodeSelectionInfo(NodeSelectionInfo selectedChildNodeInfo) {
169  if (getOriginal() instanceof DisplayableItemNode) {
170  ((DisplayableItemNode) getOriginal()).setChildNodeSelectionInfo(selectedChildNodeInfo);
171  }
172  }
173 
182  if (getOriginal() instanceof DisplayableItemNode) {
183  return ((DisplayableItemNode) getOriginal()).getChildNodeSelectionInfo();
184  } else {
185  return null;
186  }
187  }
188 
194  private static class DataResultFilterChildren extends FilterNode.Children {
195 
196  private final ExplorerManager sourceEm;
197  private final boolean filterArtifacts; // display message artifacts in the DataSource subtree
198 
202  private DataResultFilterChildren(Node arg, ExplorerManager sourceEm) {
203  super(arg);
204 
205  filterArtifacts = SelectionContext.getSelectionContext(arg).equals(SelectionContext.DATA_SOURCES);
206 
207  this.sourceEm = sourceEm;
208  }
209 
210  @Override
211  protected Node[] createNodes(Node key) {
212  // if displaying the results from the Data Source tree
213  // filter out artifacts
214 
215  // In older versions of Autopsy, attachments were children of email/message artifacts
216  // and hence email/messages with attachments are shown in the tree data source tree,
217  BlackboardArtifact art = key.getLookup().lookup(BlackboardArtifact.class);
218  if (art != null && filterArtifacts
219  && ((FilterNodeUtils.showMessagesInDatasourceTree() == false)
220  || (FilterNodeUtils.showMessagesInDatasourceTree()
221  && art.getArtifactTypeID() != BlackboardArtifact.ARTIFACT_TYPE.TSK_EMAIL_MSG.getTypeID()
222  && art.getArtifactTypeID() != BlackboardArtifact.ARTIFACT_TYPE.TSK_MESSAGE.getTypeID()))) {
223  return new Node[]{};
224  }
225 
226  return new Node[]{new DataResultFilterNode(key, sourceEm)};
227  }
228  }
229 
230  @NbBundle.Messages("DataResultFilterNode.viewSourceArtifact.text=View Source Result")
235  private static class GetPopupActionsDisplayableItemNodeVisitor extends DisplayableItemNodeVisitor.Default<List<Action>> {
236 
237  @Override
238  public List<Action> visit(BlackboardArtifactNode ban) {
239  return Arrays.asList(ban.getActions(true));
240  }
241 
242  @Override
243  public List<Action> visit(Reports.ReportsListNode ditem) {
244  // The base class Action is "Collapse All", inappropriate.
245  return null;
246  }
247 
248  @Override
249  public List<Action> visit(FileTypesNode fileTypes) {
250  return defaultVisit(fileTypes);
251  }
252 
253  @Override
254  protected List<Action> defaultVisit(DisplayableItemNode ditem) {
255  return Arrays.asList(ditem.getActions(true));
256  }
257  }
258 
259  /*
260  * Action for double-click / preferred action on nodes.
261  */
262  private class GetPreferredActionsDisplayableItemNodeVisitor extends DisplayableItemNodeVisitor.Default<AbstractAction> {
263 
264  @Override
265  public AbstractAction visit(InstanceCountNode icn) {
266  return null;
267  }
268 
269  @Override
270  public AbstractAction visit(InstanceCaseNode icn) {
271  return null;
272  }
273 
274  @Override
275  public AbstractAction visit(InstanceDataSourceNode icn) {
276  return null;
277  }
278 
279  @Override
280  public AbstractAction visit(CommonAttributeValueNode md5n) {
281  return null;
282  }
283 
284  @Override
285  public AbstractAction visit(CaseDBCommonAttributeInstanceNode fin) {
286  return null;
287  }
288 
289  @Override
290  public AbstractAction visit(CentralRepoCommonAttributeInstanceNode iccan) {
291  return null;
292  }
293 
294  @Override
295  public AbstractAction visit(BlackboardArtifactNode ban) {
296 
297  Action preferredAction = ban.getPreferredAction();
298  if (preferredAction instanceof AbstractAction) {
299  return (AbstractAction) preferredAction;
300  }
301 
302  BlackboardArtifact artifact = ban.getArtifact();
303  try {
304  if ((artifact.getArtifactTypeID() == ARTIFACT_TYPE.TSK_EMAIL_MSG.getTypeID())
305  || (artifact.getArtifactTypeID() == ARTIFACT_TYPE.TSK_MESSAGE.getTypeID())) {
306  if (artifact.hasChildren()) {
307  return openChild(ban);
308  }
309  }
310  } catch (TskCoreException ex) {
311  LOGGER.log(Level.SEVERE, MessageFormat.format("Error getting children from blackboard artifact{0}.", artifact.getArtifactID()), ex); //NON-NLS
312  }
313  return new ViewContextAction(
314  NbBundle.getMessage(this.getClass(), "DataResultFilterNode.action.viewInDir.text"), ban);
315  }
316 
317  @Override
318  public AbstractAction visit(DirectoryNode dn) {
319  if (dn.getDisplayName().equals(DirectoryNode.DOTDOTDIR)) {
320  return openParent(dn);
321  } else if (dn.getDisplayName().equals(DirectoryNode.DOTDIR) == false) {
322  return openChild(dn);
323  } else {
324  return null;
325  }
326  }
327 
328  @Override
329  public AbstractAction visit(FileNode fn) {
330  if (fn.hasContentChildren()) {
331  return openChild(fn);
332  } else {
333  return null;
334  }
335  }
336 
337  @Override
338  public AbstractAction visit(LocalFileNode dfn) {
339  if (dfn.hasContentChildren()) {
340  return openChild(dfn);
341  } else {
342  return null;
343  }
344  }
345 
346  @Override
347  public AbstractAction visit(Reports.ReportNode reportNode) {
348  return reportNode.getPreferredAction();
349  }
350 
351  @Override
352  protected AbstractAction defaultVisit(DisplayableItemNode c) {
353  return openChild(c);
354  }
355 
356  @Override
357  public AbstractAction visit(FileTypesNode fileTypes) {
358  return openChild(fileTypes);
359  }
360 
369  private AbstractAction openChild(final AbstractNode dataModelNode) {
370  // get the current selection from the directory tree explorer manager,
371  // which is a DirectoryTreeFilterNode. One of that node's children
372  // is a DirectoryTreeFilterNode that wraps the dataModelNode. We need
373  // to set that wrapped node as the selection and root context of the
374  // directory tree explorer manager (sourceEm)
375  if (sourceEm == null || sourceEm.getSelectedNodes().length == 0) {
376  return null;
377  }
378  final Node currentSelectionInDirectoryTree = sourceEm.getSelectedNodes()[0];
379 
380  return new AbstractAction() {
381  @Override
382  public void actionPerformed(ActionEvent e) {
383  if (currentSelectionInDirectoryTree != null) {
384  // Find the filter version of the passed in dataModelNode.
385  final org.openide.nodes.Children children = currentSelectionInDirectoryTree.getChildren();
386  // This call could break if the DirectoryTree is re-implemented with lazy ChildFactory objects.
387  Node newSelection = children.findChild(dataModelNode.getName());
388 
389  /*
390  * We got null here when we were viewing a ZIP file in
391  * the Views -> Archives area and double clicking on it
392  * got to this code. It tried to find the child in the
393  * tree and didn't find it. An exception was then thrown
394  * from setting the selected node to be null.
395  */
396  if (newSelection != null) {
397  try {
398  sourceEm.setExploredContextAndSelection(newSelection, new Node[]{newSelection});
399  } catch (PropertyVetoException ex) {
400  Logger logger = Logger.getLogger(DataResultFilterNode.class.getName());
401  logger.log(Level.WARNING, "Error: can't open the selected directory.", ex); //NON-NLS
402  }
403  }
404  }
405  }
406  };
407  }
408 
417  private AbstractAction openParent(AbstractNode node) {
418  if (sourceEm == null) {
419  return null;
420  }
421  // @@@ Why do we ignore node?
422  Node[] selectedFilterNodes = sourceEm.getSelectedNodes();
423  Node selectedFilterNode = selectedFilterNodes[0];
424  final Node parentNode = selectedFilterNode.getParentNode();
425 
426  return new AbstractAction() {
427  @Override
428  public void actionPerformed(ActionEvent e) {
429  try {
430  sourceEm.setSelectedNodes(new Node[]{parentNode});
431  } catch (PropertyVetoException ex) {
432  Logger logger = Logger.getLogger(DataResultFilterNode.class.getName());
433  logger.log(Level.WARNING, "Error: can't open the parent directory.", ex); //NON-NLS
434  }
435  }
436  };
437  }
438  }
439 }
abstract< T > T accept(DisplayableItemNodeVisitor< T > visitor)
static final DisplayableItemNodeVisitor< List< Action > > getActionsDIV
void setChildNodeSelectionInfo(NodeSelectionInfo selectedChildNodeInfo)
final DisplayableItemNodeVisitor< AbstractAction > getPreferredActionsDIV
synchronized static Logger getLogger(String name)
Definition: Logger.java:124

Copyright © 2012-2021 Basis Technology. Generated on: Tue Feb 22 2022
This work is licensed under a Creative Commons Attribution-Share Alike 3.0 United States License.