19package org.sleuthkit.autopsy.directorytree;
21import java.awt.Cursor;
22import java.awt.EventQueue;
23import java.beans.PropertyChangeEvent;
24import java.beans.PropertyChangeListener;
25import java.beans.PropertyVetoException;
26import java.io.IOException;
27import java.util.ArrayList;
28import java.util.Arrays;
29import java.util.Collections;
30import java.util.EnumSet;
31import java.util.HashSet;
32import java.util.LinkedList;
35import java.util.Objects;
36import java.util.Optional;
38import java.util.concurrent.ExecutionException;
39import java.util.logging.Level;
40import java.util.prefs.PreferenceChangeEvent;
41import java.util.prefs.PreferenceChangeListener;
42import java.util.stream.Collectors;
43import java.util.stream.Stream;
44import javax.swing.Action;
45import javax.swing.SwingUtilities;
46import javax.swing.SwingWorker;
47import javax.swing.event.PopupMenuEvent;
48import javax.swing.event.PopupMenuListener;
49import javax.swing.tree.TreeSelectionModel;
50import org.apache.commons.lang3.StringUtils;
51import org.openide.explorer.ExplorerManager;
52import org.openide.explorer.ExplorerUtils;
53import org.openide.explorer.view.BeanTreeView;
54import org.openide.nodes.AbstractNode;
55import org.openide.nodes.Children;
56import org.openide.nodes.Node;
57import org.openide.nodes.NodeNotFoundException;
58import org.openide.nodes.NodeOp;
59import org.openide.util.NbBundle;
60import org.openide.util.NbBundle.Messages;
61import org.openide.windows.TopComponent;
62import org.openide.windows.WindowManager;
63import org.sleuthkit.autopsy.casemodule.Case;
64import org.sleuthkit.autopsy.casemodule.CasePreferences;
65import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException;
66import org.sleuthkit.autopsy.core.RuntimeProperties;
67import org.sleuthkit.autopsy.core.UserPreferences;
68import org.sleuthkit.autopsy.corecomponentinterfaces.CoreComponentControl;
69import org.sleuthkit.autopsy.corecomponentinterfaces.DataExplorer;
70import org.sleuthkit.autopsy.corecomponents.DataResultTopComponent;
71import org.sleuthkit.autopsy.corecomponents.TableFilterNode;
72import org.sleuthkit.autopsy.corecomponents.ViewPreferencesPanel;
73import org.sleuthkit.autopsy.coreutils.Logger;
74import org.sleuthkit.autopsy.coreutils.ModuleSettings;
75import org.sleuthkit.autopsy.datamodel.AnalysisResults;
76import org.sleuthkit.autopsy.datamodel.ArtifactNodeSelectionInfo;
77import org.sleuthkit.autopsy.datamodel.BlackboardArtifactNode;
78import org.sleuthkit.autopsy.datamodel.CreditCards;
79import org.sleuthkit.autopsy.datamodel.DisplayableItemNode;
80import org.sleuthkit.autopsy.datamodel.EmailExtracted;
81import org.sleuthkit.autopsy.datamodel.EmptyNode;
82import org.sleuthkit.autopsy.datamodel.FileTypesByMimeType;
83import org.sleuthkit.autopsy.datamodel.InterestingHits;
84import org.sleuthkit.autopsy.datamodel.KeywordHits;
85import org.sleuthkit.autopsy.datamodel.AutopsyTreeChildFactory;
86import org.sleuthkit.autopsy.datamodel.DataArtifacts;
87import org.sleuthkit.autopsy.datamodel.OsAccounts;
88import org.sleuthkit.autopsy.datamodel.PersonNode;
89import org.sleuthkit.autopsy.datamodel.Tags;
90import org.sleuthkit.autopsy.datamodel.ViewsNode;
91import org.sleuthkit.autopsy.datamodel.accounts.Accounts;
92import org.sleuthkit.autopsy.datamodel.accounts.BINRange;
93import org.sleuthkit.datamodel.Account;
94import org.sleuthkit.datamodel.BlackboardArtifact;
95import org.sleuthkit.datamodel.BlackboardArtifact.Category;
96import org.sleuthkit.datamodel.BlackboardAttribute;
97import org.sleuthkit.datamodel.Content;
98import org.sleuthkit.datamodel.DataSource;
99import org.sleuthkit.datamodel.Host;
100import org.sleuthkit.datamodel.OsAccount;
101import org.sleuthkit.datamodel.Person;
102import org.sleuthkit.datamodel.TskCoreException;
109 "DirectoryTreeTopComponent.resultsView.title=Listing"
111@SuppressWarnings(
"PMD.SingularField")
114 private final transient ExplorerManager
em =
new ExplorerManager();
120 private static final String
PREFERRED_ID =
"DirectoryTreeTopComponent";
132 .collect(Collectors.toSet());
141 getTree().setSelectionMode(TreeSelectionModel.SINGLE_TREE_SELECTION);
144 putClientProperty(TopComponent.PROP_CLOSING_DISABLED, Boolean.TRUE);
149 associateLookup(ExplorerUtils.createLookup(
em, getActionMap()));
152 this.backList =
new LinkedList<>();
153 this.forwardList =
new LinkedList<>();
161 public void popupMenuWillBecomeVisible(PopupMenuEvent e) {
166 public void popupMenuWillBecomeInvisible(PopupMenuEvent e) {
171 public void popupMenuCanceled(PopupMenuEvent e) {
184 BeanTreeView tree = getTree();
187 Node[] rootChildrenNodes = rootChildren.getNodes(
true);
188 if (rootChildrenNodes ==
null || rootChildrenNodes.length < 1) {
194 Stream.of(rootChildrenNodes)
196 .filter((n) -> n !=
null)
197 .forEach(tree::expandNode);
199 Stream.of(rootChildrenNodes)
201 .forEach(tree::expandNode);
215 return Collections.emptyList();
216 }
else if (node.getLookup().lookup(Person.class) !=
null
218 Children children = node.getChildren();
219 Node[] childNodes = children ==
null ? null : children.getNodes();
220 if (childNodes !=
null) {
221 return Stream.of(childNodes)
223 .collect(Collectors.toList());
225 }
else if (node.getLookup().lookup(Host.class) !=
null) {
226 return Arrays.asList(node);
228 return Collections.emptyList();
237 public void preferenceChange(PreferenceChangeEvent evt) {
238 switch (evt.getKey()) {
262 this.em.addPropertyChangeListener(
this);
266 this.dataResult.requestActive();
270 this.dataResult.
open();
274 return this.dataResult;
308 treeView =
new ExpansionBeanTreeView();
315 backButton.setIcon(
new javax.swing.ImageIcon(getClass().getResource(
"/org/sleuthkit/autopsy/directorytree/btn_step_back.png")));
316 org.openide.awt.Mnemonics.setLocalizedText(
backButton, org.openide.util.NbBundle.getMessage(
DirectoryTreeTopComponent.class,
"DirectoryTreeTopComponent.backButton.text"));
319 backButton.setDisabledIcon(
new javax.swing.ImageIcon(getClass().getResource(
"/org/sleuthkit/autopsy/directorytree/btn_step_back_disabled.png")));
320 backButton.setMargin(
new java.awt.Insets(2, 0, 2, 0));
321 backButton.setMaximumSize(
new java.awt.Dimension(55, 100));
322 backButton.setMinimumSize(
new java.awt.Dimension(5, 5));
323 backButton.setPreferredSize(
new java.awt.Dimension(24, 24));
324 backButton.setRolloverIcon(
new javax.swing.ImageIcon(getClass().getResource(
"/org/sleuthkit/autopsy/directorytree/btn_step_back_hover.png")));
325 backButton.addActionListener(
new java.awt.event.ActionListener() {
326 public void actionPerformed(java.awt.event.ActionEvent evt) {
327 backButtonActionPerformed(evt);
331 forwardButton.setIcon(
new javax.swing.ImageIcon(getClass().getResource(
"/org/sleuthkit/autopsy/directorytree/btn_step_forward.png")));
332 org.openide.awt.Mnemonics.setLocalizedText(forwardButton, org.openide.util.NbBundle.getMessage(
DirectoryTreeTopComponent.class,
"DirectoryTreeTopComponent.forwardButton.text"));
333 forwardButton.setBorderPainted(
false);
334 forwardButton.setContentAreaFilled(
false);
335 forwardButton.setDisabledIcon(
new javax.swing.ImageIcon(getClass().getResource(
"/org/sleuthkit/autopsy/directorytree/btn_step_forward_disabled.png")));
336 forwardButton.setMargin(
new java.awt.Insets(2, 0, 2, 0));
337 forwardButton.setMaximumSize(
new java.awt.Dimension(55, 100));
338 forwardButton.setMinimumSize(
new java.awt.Dimension(5, 5));
339 forwardButton.setPreferredSize(
new java.awt.Dimension(24, 24));
340 forwardButton.setRolloverIcon(
new javax.swing.ImageIcon(getClass().getResource(
"/org/sleuthkit/autopsy/directorytree/btn_step_forward_hover.png")));
341 forwardButton.addActionListener(
new java.awt.event.ActionListener() {
342 public void actionPerformed(java.awt.event.ActionEvent evt) {
343 forwardButtonActionPerformed(evt);
347 openViewPreferencesButton.setIcon(
new javax.swing.ImageIcon(getClass().getResource(
"/org/sleuthkit/autopsy/directorytree/view-preferences-23.png")));
348 org.openide.awt.Mnemonics.setLocalizedText(openViewPreferencesButton, org.openide.util.NbBundle.getMessage(DirectoryTreeTopComponent.class,
"DirectoryTreeTopComponent.openViewPreferencesButton.text"));
349 openViewPreferencesButton.setBorder(javax.swing.BorderFactory.createEmptyBorder(1, 1, 1, 1));
350 openViewPreferencesButton.setBorderPainted(
false);
351 openViewPreferencesButton.setContentAreaFilled(
false);
352 openViewPreferencesButton.setMaximumSize(
new java.awt.Dimension(24, 24));
353 openViewPreferencesButton.setMinimumSize(
new java.awt.Dimension(24, 24));
354 openViewPreferencesButton.setPreferredSize(
new java.awt.Dimension(24, 24));
355 openViewPreferencesButton.addActionListener(
new java.awt.event.ActionListener() {
356 public void actionPerformed(java.awt.event.ActionEvent evt) {
357 openViewPreferencesButtonActionPerformed(evt);
361 javax.swing.GroupLayout layout =
new javax.swing.GroupLayout(
this);
362 this.setLayout(layout);
363 layout.setHorizontalGroup(
364 layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
365 .addComponent(treeView)
366 .addGroup(layout.createSequentialGroup()
368 .addComponent(backButton, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
369 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
370 .addComponent(forwardButton, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
371 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 140, Short.MAX_VALUE)
372 .addComponent(openViewPreferencesButton, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
375 layout.setVerticalGroup(
376 layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
377 .addGroup(layout.createSequentialGroup()
379 .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
380 .addComponent(openViewPreferencesButton, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
381 .addComponent(backButton, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
382 .addComponent(forwardButton, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
383 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
384 .addComponent(treeView, javax.swing.GroupLayout.DEFAULT_SIZE, 919, Short.MAX_VALUE))
390 this.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
393 String[] currentNodePath =
backList.pollLast();
402 String[] newCurrentNodePath =
backList.peekLast();
414 this.setCursor(
null);
419 this.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
421 String[] newCurrentNodePath =
forwardList.pollLast();
428 backList.addLast(newCurrentNodePath);
434 this.setCursor(
null);
472 WindowManager winManager = WindowManager.
getDefault();
473 TopComponent win = winManager.findTopComponent(
PREFERRED_ID);
476 "Cannot find " +
PREFERRED_ID +
" component. It will not be located properly in the window system.");
483 "There seem to be multiple components with the '" +
PREFERRED_ID
484 +
"' ID. That is a potential source of errors and unexpected behavior.");
496 return TopComponent.PERSISTENCE_NEVER;
507 GroupDataSourcesDialog dialog =
new GroupDataSourcesDialog(dataSourceCount);
509 if (dialog.groupByDataSourceSelected()) {
525 @NbBundle.Messages({
"# {0} - dataSourceCount",
526 "DirectoryTreeTopComponent.componentOpened.groupDataSources.text=This case contains {0} data sources. Would you like to group by data source for faster loading?",
527 "DirectoryTreeTopComponent.componentOpened.groupDataSources.title=Group by data source?"})
531 this.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
532 Case openCase =
null;
538 final Case currentCase = openCase;
541 getTree().setRootVisible(
false);
546 Long settingsThreshold =
null;
550 }
catch (NumberFormatException ex) {
551 LOGGER.log(Level.SEVERE,
"Group data sources threshold is not a number", ex);
558 new SwingWorker<Integer, Void>() {
560 protected Integer doInBackground()
throws Exception {
561 int dataSourceCount = 0;
564 }
catch (TskCoreException ex) {
565 LOGGER.log(Level.SEVERE,
"Error loading data sources", ex);
567 return dataSourceCount;
571 protected void done() {
572 int dataSourceCount = 0;
574 dataSourceCount =
get();
575 }
catch (ExecutionException | InterruptedException ex) {
576 LOGGER.log(Level.SEVERE,
"Error loading data sources and getting count on background thread", ex);
579 && dataSourceCount > threshold) {
597 return new Action[]{};
603 public Node.Handle getHandle() {
604 return new Node.Handle() {
606 public Node getNode()
throws IOException {
607 return em.getRootContext();
613 root =
new DirectoryTreeFilterNode(root,
true);
615 em.setRootContext(root);
616 em.getRootContext().setName(currentCase.
getName());
617 em.getRootContext().setDisplayName(currentCase.
getName());
618 getTree().setRootVisible(
false);
622 new SwingWorker<Node[], Void>() {
624 protected Node[] doInBackground()
throws Exception {
625 Children rootChildren =
em.getRootContext().getChildren();
636 if (rootChildren.getNodesCount() > 0) {
637 return new Node[]{rootChildren.getNodeAt(0)};
643 protected void done() {
658 Node[] selections =
get();
659 if (selections !=
null && selections.length > 0) {
660 em.setSelectedNodes(selections);
662 }
catch (PropertyVetoException ex) {
663 LOGGER.log(Level.SEVERE,
"Error setting default selected node.", ex);
664 }
catch (InterruptedException | ExecutionException ex) {
665 LOGGER.log(Level.SEVERE,
"Error expanding tree to initial state.", ex);
686 void writeProperties(java.util.Properties p) {
689 p.setProperty(
"version",
"1.0");
693 Object readProperties(java.util.Properties p) {
694 if (instance ==
null) {
702 String version = p.getProperty(
"version");
748 return new Action[]{};
760 if (selectedNodes.length > 0) {
761 result = selectedNodes[0];
775 String changed =
event.getPropertyName();
785 if (event.getOldValue() !=
null && event.getNewValue() ==
null) {
787 SwingUtilities.invokeLater(() -> {
788 Node emptyNode =
new AbstractNode(Children.LEAF);
789 em.setRootContext(emptyNode);
791 }
else if (event.getNewValue() !=
null) {
793 Case newCase = (
Case) event.getNewValue();
794 final String newCaseName = newCase.
getName();
795 SwingUtilities.invokeLater(() -> {
796 em.getRootContext().setName(newCaseName);
797 em.getRootContext().setDisplayName(newCaseName);
827 SwingUtilities.invokeLater(() -> {
838 else if (changed.equals(ExplorerManager.PROP_SELECTED_NODES)) {
839 respondSelection((Node[]) event.getOldValue(), (Node[]) event.getNewValue());
852 @NbBundle.Messages(
"DirectoryTreeTopComponent.emptyMimeNode.text=Data not available. Run file type identification module.")
853 void respondSelection(
final Node[] oldNodes,
final Node[] newNodes) {
863 EventQueue.invokeLater(() -> {
865 DirectoryTreeTopComponent.this.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
867 Node treeNode = DirectoryTreeTopComponent.this.getSelectedNode();
868 if (treeNode !=
null) {
869 Node originNode = ((DirectoryTreeFilterNode) treeNode).getOriginal();
871 Node drfn =
new DataResultFilterNode(originNode, DirectoryTreeTopComponent.this.em);
873 if (FileTypesByMimeType.isEmptyMimeTypeNode(originNode)) {
876 EmptyNode emptyNode =
new EmptyNode(Bundle.DirectoryTreeTopComponent_emptyMimeNode_text());
877 dataResult.
setNode(
new TableFilterNode(emptyNode,
true,
"This Node Is Empty"));
878 }
else if (originNode instanceof DisplayableItemNode) {
879 dataResult.
setNode(
new TableFilterNode(drfn,
true, ((DisplayableItemNode) originNode).getItemType()));
881 dataResult.
setNode(
new TableFilterNode(drfn,
true));
883 String displayName =
"";
884 Content content = originNode.getLookup().lookup(Content.class);
885 if (content !=
null) {
887 displayName = content.getUniquePath();
888 }
catch (TskCoreException ex) {
889 LOGGER.log(Level.SEVERE,
"Exception while calling Content.getUniquePath() for node: {0}", originNode);
891 }
else if (originNode.getLookup().lookup(String.class) !=
null) {
892 displayName = originNode.getLookup().lookup(String.class);
894 dataResult.
setPath(displayName);
897 if (oldNodes !=
null && newNodes !=
null
898 && (oldNodes.length == newNodes.length)) {
899 boolean sameNodes =
true;
900 for (
int i = 0; i < oldNodes.length; i++) {
901 sameNodes = sameNodes && oldNodes[i].getName().equals(newNodes[i].getName());
904 dataResult.requestActive();
913 updateHistory(em.getSelectedNodes());
917 if (selectedNodes.length == 0) {
921 Node selectedNode = selectedNodes[0];
922 String selectedNodeName = selectedNode.getName();
930 String[] currentLast =
backList.peekLast();
931 String lastNodeName =
null;
932 if (currentLast !=
null && currentLast.length > 0) {
933 lastNodeName = currentLast[currentLast.length - 1];
936 if (currentLast ==
null || !selectedNodeName.equals(lastNodeName)) {
938 final String[] selectedPath = NodeOp.createPath(selectedNode,
em.getRootContext());
968 BeanTreeView getTree() {
969 return (BeanTreeView) this.treeView;
976 SwingUtilities.invokeLater(this::rebuildTree);
983 SwingUtilities.invokeLater(() -> {
992 if (tagsNode !=
null) {
999 if (tagsNode !=
null) {
1012 Case currentCase =
null;
1029 new SwingWorker<Void, Void>() {
1032 protected Void doInBackground()
throws Exception {
1037 protected void done() {
1043 }
catch (InterruptedException | ExecutionException ex) {
1044 LOGGER.log(Level.SEVERE,
"Error selecting tree node.", ex);
1060 if (
null == currentCase) {
1063 hasData = currentCase.
hasData();
1075 private void setSelectedNode(
final String[] previouslySelectedNodePath,
final String rootNodeName) {
1076 if (previouslySelectedNodePath ==
null) {
1079 SwingUtilities.invokeLater(
new Runnable() {
1082 if (previouslySelectedNodePath.length > 0 && (rootNodeName ==
null || previouslySelectedNodePath[0].equals(rootNodeName))) {
1083 Node selectedNode =
null;
1084 ArrayList<String> selectedNodePath =
new ArrayList<>(Arrays.asList(previouslySelectedNodePath));
1085 while (
null == selectedNode && !selectedNodePath.isEmpty()) {
1087 selectedNode = NodeOp.findPath(
em.getRootContext(), selectedNodePath.toArray(
new String[selectedNodePath.size()]));
1088 }
catch (NodeNotFoundException ex) {
1090 if (selectedNodePath.size() > 1) {
1091 selectedNodePath.remove(selectedNodePath.size() - 1);
1093 StringBuilder nodePath =
new StringBuilder();
1094 for (
int i = 0; i < previouslySelectedNodePath.length; ++i) {
1095 nodePath.append(previouslySelectedNodePath[i]).append(
"/");
1097 LOGGER.log(Level.WARNING,
"Failed to find any nodes to select on path " + nodePath.toString(), ex);
1103 if (
null != selectedNode) {
1104 if (rootNodeName !=
null) {
1110 em.setExploredContextAndSelection(selectedNode,
new Node[]{selectedNode});
1111 }
catch (PropertyVetoException ex) {
1112 LOGGER.log(Level.WARNING,
"Property veto from ExplorerManager setting selection to " + selectedNode.getName(), ex);
1144 case ANALYSIS_RESULT:
1147 LOGGER.log(Level.WARNING,
"Unbale to find category of type: " + category.name());
1148 return Optional.empty();
1166 return Optional.empty();
1167 }
else if (node.getLookup().lookup(Host.class) !=
null
1168 || node.getLookup().lookup(Person.class) !=
null
1171 Children children = node.getChildren();
1173 Stream<Node> childNodeStream = children ==
null ? Stream.empty() : Stream.of(children.getNodes());
1174 return childNodeStream
1176 .filter(Optional::isPresent)
1180 DataSource dataSource = node.getLookup().lookup(DataSource.class);
1182 if (dataSource !=
null && dataSource.getId() == dataSourceId) {
1183 Children dsChildren = node.getChildren();
1184 if (dsChildren !=
null) {
1189 return Optional.empty();
1203 Children rootChildren =
em.getRootContext().getChildren();
1205 if (categoryNode.isPresent()) {
1206 return categoryNode;
1211 dataSourceId = art.getDataSource().getId();
1212 }
catch (TskCoreException ex) {
1213 LOGGER.log(Level.WARNING,
"There was an error fetching the data source id for artifact.", ex);
1217 Node[] rootNodes = rootChildren.getNodes();
1218 Stream<Node> rootNodesStream = rootNodes ==
null ? Stream.empty() : Stream.of(rootNodes);
1219 return rootNodesStream
1221 .filter(Optional::isPresent)
1238 return Optional.empty();
1241 Host nodeHost = node.getLookup().lookup(Host.class);
1242 if ((nodeHost !=
null && hosts !=
null && hosts.contains(nodeHost))
1243 || node.getLookup().lookup(DataSource.class) !=
null
1244 || node.getLookup().lookup(Person.class) !=
null
1247 return Stream.of(node.getChildren().getNodes(
true))
1249 .filter(Optional::isPresent)
1256 return Optional.of(node);
1259 return Optional.empty();
1268 Set<Host> hosts =
null;
1273 }
catch (TskCoreException ex) {
1274 LOGGER.log(Level.WARNING,
"Unable to get valid hosts for osAccount: " + osAccount, ex);
1279 final Set<Host> finalHosts = hosts;
1281 Optional<Node> osAccountListNodeOpt = Stream.of(
em.getRootContext().getChildren().getNodes(
true))
1283 .filter(Optional::isPresent)
1287 if (!osAccountListNodeOpt.isPresent()) {
1291 Node osAccountListNode = osAccountListNodeOpt.get();
1295 OsAccount osAcctOfNd = osAcctNd.getLookup().lookup(OsAccount.class);
1296 return osAcctOfNd !=
null && osAcctOfNd.getId() == osAccount.getId();
1298 getTree().expandNode(osAccountListNode);
1300 em.setExploredContextAndSelection(osAccountListNode,
new Node[]{osAccountListNode});
1301 }
catch (PropertyVetoException ex) {
1302 LOGGER.log(Level.WARNING,
"Property Veto: ", ex);
1313 private Optional<BlackboardArtifact.Type>
getType(
long artifactTypeId) {
1316 .filter(type -> type.getTypeID() == artifactTypeId)
1319 LOGGER.log(Level.WARNING,
"Error occurred while looking up blackboard artifact type for: " + artifactTypeId, ex);
1320 return Optional.empty();
1338 @SuppressWarnings(
"deprecation")
1340 int typeID = art.getArtifactTypeID();
1341 String typeName = art.getArtifactTypeName();
1343 Optional<BlackboardArtifact.Type> typeOpt =
getType(typeID);
1344 Optional<Children> categoryChildrenOpt = typeOpt
1346 .flatMap(categoryNode -> Optional.ofNullable(categoryNode.getChildren()));
1348 if (!categoryChildrenOpt.isPresent()) {
1349 LOGGER.log(Level.WARNING, String.format(
"Category node children for artifact of typeID: %d and artifactID: %d not found.",
1350 typeID, art.getArtifactID()));
1354 Children typesChildren = categoryChildrenOpt.get();
1356 Node treeNode =
null;
1357 if (typeID == BlackboardArtifact.Type.TSK_HASHSET_HIT.getTypeID()) {
1359 }
else if (typeID == BlackboardArtifact.Type.TSK_KEYWORD_HIT.getTypeID()) {
1361 }
else if (typeID == BlackboardArtifact.Type.TSK_INTERESTING_FILE_HIT.getTypeID()) {
1363 }
else if (typeID == BlackboardArtifact.Type.TSK_INTERESTING_ARTIFACT_HIT.getTypeID()) {
1364 treeNode =
getInterestingItemNode(typesChildren, BlackboardArtifact.Type.TSK_INTERESTING_ARTIFACT_HIT, art);
1365 }
else if (typeID == BlackboardArtifact.Type.TSK_INTERESTING_ITEM.getTypeID()) {
1367 }
else if (typeID == BlackboardArtifact.Type.TSK_EMAIL_MSG.getTypeID()) {
1369 }
else if (typeID == BlackboardArtifact.Type.TSK_ACCOUNT.getTypeID()) {
1372 treeNode = typesChildren.findChild(typeName);
1375 if (treeNode ==
null) {
1381 getTree().expandNode(treeNode);
1384 this.respondSelection(
em.getSelectedNodes(),
new Node[]{treeNode});
1387 em.setExploredContextAndSelection(treeNode,
new Node[]{treeNode});
1388 }
catch (PropertyVetoException ex) {
1389 LOGGER.log(Level.WARNING,
"Property Veto: ", ex);
1407 Node hashsetRootNode = typesChildren.findChild(art.getArtifactTypeName());
1408 Children hashsetRootChilds = hashsetRootNode.getChildren();
1410 String setName =
null;
1411 List<BlackboardAttribute> attributes = art.getAttributes();
1412 for (BlackboardAttribute att : attributes) {
1413 int typeId = att.getAttributeType().getTypeID();
1414 if (typeId == BlackboardAttribute.ATTRIBUTE_TYPE.TSK_SET_NAME.getTypeID()) {
1415 setName = att.getValueString();
1418 return hashsetRootChilds.findChild(setName);
1419 }
catch (TskCoreException ex) {
1420 LOGGER.log(Level.WARNING,
"Error retrieving attributes", ex);
1437 Node keywordRootNode = typesChildren.findChild(art.getArtifactTypeName());
1438 Children keywordRootChilds = keywordRootNode.getChildren();
1440 String listName =
null;
1441 String keywordName =
null;
1442 String regex =
null;
1443 List<BlackboardAttribute> attributes = art.getAttributes();
1444 for (BlackboardAttribute att : attributes) {
1445 int typeId = att.getAttributeType().getTypeID();
1446 if (typeId == BlackboardAttribute.ATTRIBUTE_TYPE.TSK_SET_NAME.getTypeID()) {
1447 listName = att.getValueString();
1448 }
else if (typeId == BlackboardAttribute.ATTRIBUTE_TYPE.TSK_KEYWORD.getTypeID()) {
1449 keywordName = att.getValueString();
1450 }
else if (typeId == BlackboardAttribute.ATTRIBUTE_TYPE.TSK_KEYWORD_REGEXP.getTypeID()) {
1451 regex = att.getValueString();
1454 if (listName ==
null) {
1455 if (regex ==
null) {
1456 listName = NbBundle.getMessage(
KeywordHits.class,
"KeywordHits.simpleLiteralSearch.text");
1458 listName = NbBundle.getMessage(
KeywordHits.class,
"KeywordHits.singleRegexSearch.text");
1461 Node listNode = keywordRootChilds.findChild(listName);
1462 if (listNode ==
null) {
1465 Children listChildren = listNode.getChildren();
1466 if (listChildren ==
null) {
1469 if (regex !=
null) {
1470 Node regexNode = listChildren.findChild(listName);
1471 regexNode = (regexNode ==
null) ? listChildren.findChild(listName +
"_" + regex) : regexNode;
1472 if (regexNode ==
null) {
1475 listChildren = regexNode.getChildren();
1476 if (listChildren ==
null) {
1481 return listChildren.findChild(keywordName);
1482 }
catch (TskCoreException ex) {
1483 LOGGER.log(Level.WARNING,
"Error retrieving attributes", ex);
1502 Node interestingItemsRootNode = typesChildren.findChild(artifactType.getDisplayName());
1503 Children setNodeChildren = (interestingItemsRootNode ==
null) ?
null : interestingItemsRootNode.getChildren();
1506 if (setNodeChildren ==
null) {
1510 String setName =
null;
1512 setName = art.getAttributes().stream()
1513 .filter(attr -> attr.getAttributeType().getTypeID() == BlackboardAttribute.Type.TSK_SET_NAME.getTypeID())
1514 .map(attr -> attr.getValueString())
1518 }
catch (TskCoreException ex) {
1519 LOGGER.log(Level.WARNING,
"Error retrieving attributes", ex);
1524 if (setName ==
null) {
1529 final String finalSetName = setName;
1530 return Stream.of(setNodeChildren.getNodes(
true))
1531 .filter(setNode -> finalSetName.equals(setNode.getLookup().lookup(String.class)))
1544 private Node
getEmailNode(Children typesChildren, BlackboardArtifact art) {
1545 Node emailMsgRootNode = typesChildren.findChild(art.getArtifactTypeName());
1546 Children emailMsgRootChilds = emailMsgRootNode.getChildren();
1547 Map<String, String> parsedPath =
null;
1549 List<BlackboardAttribute> attributes = art.getAttributes();
1550 for (BlackboardAttribute att : attributes) {
1551 int typeId = att.getAttributeType().getTypeID();
1552 if (typeId == BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PATH.getTypeID()) {
1557 if (parsedPath ==
null) {
1560 Node defaultNode = emailMsgRootChilds.findChild(parsedPath.get(NbBundle.getMessage(
EmailExtracted.class,
"EmailExtracted.defaultAcct.text")));
1561 Children defaultChildren = defaultNode.getChildren();
1562 return defaultChildren.findChild(parsedPath.get(NbBundle.getMessage(
EmailExtracted.class,
"EmailExtracted.defaultFolder.text")));
1563 }
catch (TskCoreException ex) {
1564 LOGGER.log(Level.WARNING,
"Error retrieving attributes", ex);
1579 Node accountRootNode = typesChildren.findChild(art.getDisplayName());
1580 Children accountRootChilds = accountRootNode.getChildren();
1581 List<BlackboardAttribute> attributes;
1582 String accountType =
null;
1583 String ccNumberName =
null;
1585 attributes = art.getAttributes();
1586 for (BlackboardAttribute att : attributes) {
1587 int typeId = att.getAttributeType().getTypeID();
1588 if (typeId == BlackboardAttribute.ATTRIBUTE_TYPE.TSK_ACCOUNT_TYPE.getTypeID()) {
1589 accountType = att.getValueString();
1591 if (typeId == BlackboardAttribute.ATTRIBUTE_TYPE.TSK_CARD_NUMBER.getTypeID()) {
1592 ccNumberName = att.getValueString();
1595 if (accountType ==
null) {
1599 if (accountType.equals(Account.Type.CREDIT_CARD.getTypeName())) {
1602 return accountRootChilds.findChild(accountType);
1604 }
catch (TskCoreException ex) {
1605 LOGGER.log(Level.WARNING,
"Error retrieving attributes", ex);
1621 Node accountNode = accountRootChildren.findChild(Account.Type.CREDIT_CARD.getDisplayName());
1622 if (accountNode ==
null) {
1625 Children accountChildren = accountNode.getChildren();
1626 if (accountChildren ==
null) {
1629 Node binNode = accountChildren.findChild(NbBundle.getMessage(
Accounts.class,
"Accounts.ByBINNode.name"));
1630 if (binNode ==
null) {
1633 Children binChildren = binNode.getChildren();
1634 if (ccNumberName ==
null) {
1639 String binName = StringUtils.rightPad(ccNumberName, 8,
"0");
1640 binName = binName.substring(0, 8);
1643 bin = Integer.parseInt(binName);
1644 }
catch (NumberFormatException ex) {
1645 LOGGER.log(Level.WARNING,
"Unable to parseInt a BIN for node selection from string binName=" + binName, ex);
1649 if (binInfo !=
null) {
1650 int startBin = ((
BINRange) binInfo).getBINstart();
1651 int endBin = ((
BINRange) binInfo).getBINend();
1652 if (startBin != endBin) {
1653 binName = Integer.toString(startBin) +
"-" + Integer.toString(endBin).substring(5);
1656 if (binName ==
null) {
1659 return binChildren.findChild(binName);
1664 NbBundle.getMessage(
this.getClass(),
"DirectoryTreeTopComponent.action.viewArtContent.text"),
List< Content > getDataSources()
SleuthkitCase getSleuthkitCase()
static Case getCurrentCaseThrows()
static Case getCurrentCase()
static boolean isCaseOpen()
static void addEventTypeSubscriber(Set< Events > eventTypes, PropertyChangeListener subscriber)
static Boolean getGroupItemsInTreeByDataSource()
static void setGroupItemsInTreeByDataSource(boolean value)
static boolean runningWithGUI
static final String DISPLAY_TIMES_IN_LOCAL_TIME
static final String HIDE_SLACK_FILES_IN_DATA_SRCS_TREE
static final String SHOW_ONLY_CURRENT_USER_TAGS
static final String TEXT_TRANSLATOR_NAME
static final String TIME_ZONE_FOR_DISPLAYS
static final String HIDE_SCO_COLUMNS
static final String HIDE_KNOWN_FILES_IN_DATA_SRCS_TREE
static final String HIDE_KNOWN_FILES_IN_VIEWS_TREE
static final String KEEP_PREFERRED_VIEWER
static final String HIDE_SLACK_FILES_IN_VIEWS_TREE
static final String DISPLAY_TRANSLATED_NAMES
static void addChangeListener(PreferenceChangeListener listener)
static void openCoreWindows()
void setNode(Node selectedNode)
void setPath(String pathText)
synchronized static Logger getLogger(String name)
static synchronized void setConfigSetting(String moduleName, String settingName, String settingVal)
static final String MAIN_SETTINGS
static synchronized String getConfigSetting(String moduleName, String settingName)
static synchronized boolean settingExists(String moduleName, String settingName)
static synchronized BankIdentificationNumber getBINInfo(int bin)
void setChildNodeSelectionInfo(NodeSelectionInfo selectedChildNodeInfo)
static String getListName()
static String getUnknownPersonId()
static final String PREFERRED_ID
void setDirectoryListingActive()
void readPropertiesImpl(java.util.Properties p)
void setSelectedNode(final String[] previouslySelectedNodePath, final String rootNodeName)
DataResultTopComponent getDirectoryListing()
Optional< Node > getCategoryNodeChild(Children children, Category category)
Node getHashsetNode(Children typesChildren, final BlackboardArtifact art)
static final long DEFAULT_DATASOURCE_GROUPING_THRESHOLD
void updateHistory(Node[] selectedNodes)
void backButtonActionPerformed(java.awt.event.ActionEvent evt)
final ViewPreferencesPanel viewPreferencesPanel
javax.swing.JButton openViewPreferencesButton
void setShowRejectedResults(boolean showRejectedResults)
void viewArtifact(final BlackboardArtifact art)
Optional< BlackboardArtifact.Type > getType(long artifactTypeId)
static final Logger LOGGER
static synchronized DirectoryTreeTopComponent findInstance()
Optional< Node > getCategoryNode(Category category, BlackboardArtifact art)
void addOnFinishedListener(PropertyChangeListener l)
static final String SETTINGS_FILE
boolean getShowRejectedResults()
void refreshContentTreeSafe()
final LinkedList< String[]> forwardList
void subscribeToChangeEvents()
final DataResultTopComponent dataResult
static boolean caseHasData(Case currentCase)
void viewOsAccount(OsAccount osAccount)
void openDirectoryListing()
Node getInterestingItemNode(Children typesChildren, BlackboardArtifact.Type artifactType, BlackboardArtifact art)
javax.swing.JPopupMenu viewPreferencesPopupMenu
static DirectoryTreeTopComponent instance
Node getCreditCardAccountNode(Children accountRootChildren, String ccNumberName)
Node getAccountNode(Children typesChildren, BlackboardArtifact art)
void preExpandNodes(Children rootChildren)
static synchronized DirectoryTreeTopComponent getDefault()
void forwardButtonActionPerformed(java.awt.event.ActionEvent evt)
Node getEmailNode(Children typesChildren, BlackboardArtifact art)
javax.swing.JButton backButton
Children autopsyTreeChildren
List< Node > getHostNodesAndParents(Node node)
TopComponent getTopComponent()
static final String GROUPING_THRESHOLD_NAME
void openViewPreferencesButtonActionPerformed(java.awt.event.ActionEvent evt)
ExplorerManager getExplorerManager()
final transient ExplorerManager em
void promptForDataSourceGrouping(int dataSourceCount)
boolean hasMenuOpenAction()
void propertyChange(PropertyChangeEvent event)
void viewArtifactContent(BlackboardArtifact art)
Optional< Node > searchForCategoryNode(Node node, long dataSourceId, Category category)
boolean showRejectedResults
static final Set< String > NODES_TO_EXPAND
DirectoryTreeTopComponent()
Node getKeywordHitNode(Children typesChildren, BlackboardArtifact art)
javax.swing.JScrollPane treeView
Optional< Node > getOsAccountListNode(Node node, OsAccount osAccount, Set< Host > hosts)
AutopsyTreeChildFactory autopsyTreeChildFactory
final LinkedList< String[]> backList
javax.swing.JButton forwardButton
void actionPerformed(ActionEvent event)