19 package org.sleuthkit.autopsy.keywordsearch.multicase;
 
   21 import java.awt.Toolkit;
 
   22 import java.awt.datatransfer.StringSelection;
 
   23 import java.awt.event.ActionEvent;
 
   25 import java.nio.file.Paths;
 
   26 import java.util.ArrayList;
 
   27 import java.util.Collection;
 
   28 import java.util.Collections;
 
   29 import java.util.List;
 
   30 import java.util.logging.Level;
 
   31 import javax.swing.AbstractAction;
 
   32 import javax.swing.Action;
 
   33 import org.openide.nodes.AbstractNode;
 
   34 import org.openide.nodes.Children;
 
   35 import org.openide.nodes.Node;
 
   36 import org.openide.nodes.Sheet;
 
   37 import org.openide.util.NbBundle;
 
   48     "MultiCaseKeywordSearchNode.properties.case=Case",
 
   49     "MultiCaseKeywordSearchNode.properties.caseDirectory=Case Directory",
 
   50     "MultiCaseKeywordSearchNode.properties.dataSource=Data Source",
 
   51     "MultiCaseKeywordSearchNode.properties.sourceType=Keyword Hit Source Type",
 
   52     "MultiCaseKeywordSearchNode.properties.source=Keyword Hit Source",
 
   53     "MultiCaseKeywordSearchNode.properties.path=Keyword Hit Source Path" 
   60 class MultiCaseKeywordSearchNode extends AbstractNode {
 
   62     private static final Logger LOGGER = Logger.getLogger(MultiCaseKeywordSearchNode.class.getName());
 
   70     MultiCaseKeywordSearchNode(Collection<SearchHit> resultList) {
 
   71         super(
new MultiCaseKeywordSearchChildren(resultList));
 
   77     static class MultiCaseKeywordSearchChildren 
extends Children.Keys<SearchHit> {
 
   79         private final Collection<SearchHit> resultList;
 
   87         MultiCaseKeywordSearchChildren(Collection<SearchHit> resultList) {
 
   88             this.resultList = resultList;
 
   92         protected void addNotify() {
 
   98         protected void removeNotify() {
 
  100             setKeys(Collections.emptyList());
 
  104         protected Node[] createNodes(SearchHit t) {
 
  105             return new Node[]{
new SearchHitNode(t)};
 
  109         public Object clone() {
 
  110             return super.clone();
 
  118     static final class SearchHitNode 
extends AbstractNode {
 
  120         private final SearchHit searchHit;
 
  128         SearchHitNode(SearchHit kwsHit) {
 
  129             super(Children.LEAF);
 
  131             super.setName(searchHit.getCaseDisplayName());
 
  132             setDisplayName(searchHit.getCaseDisplayName());
 
  136         public Action getPreferredAction() {
 
  137             return new OpenCaseAction(getCasePath());
 
  146         private String getCasePath() {
 
  147             return searchHit.getCaseDirectoryPath();
 
  151         protected Sheet createSheet() {
 
  152             Sheet s = super.createSheet();
 
  153             Sheet.Set ss = s.get(Sheet.PROPERTIES);
 
  155                 ss = Sheet.createPropertiesSet();
 
  158             ss.put(
new NodeProperty<>(Bundle.MultiCaseKeywordSearchNode_properties_case(), Bundle.MultiCaseKeywordSearchNode_properties_case(), Bundle.MultiCaseKeywordSearchNode_properties_case(),
 
  159                     searchHit.getCaseDisplayName()));
 
  160             ss.put(
new NodeProperty<>(Bundle.MultiCaseKeywordSearchNode_properties_caseDirectory(), Bundle.MultiCaseKeywordSearchNode_properties_caseDirectory(), Bundle.MultiCaseKeywordSearchNode_properties_caseDirectory(),
 
  161                     searchHit.getCaseDirectoryPath()));
 
  162             ss.put(
new NodeProperty<>(Bundle.MultiCaseKeywordSearchNode_properties_dataSource(), Bundle.MultiCaseKeywordSearchNode_properties_dataSource(), Bundle.MultiCaseKeywordSearchNode_properties_dataSource(),
 
  163                     searchHit.getDataSourceName()));
 
  164             ss.put(
new NodeProperty<>(Bundle.MultiCaseKeywordSearchNode_properties_path(), Bundle.MultiCaseKeywordSearchNode_properties_path(), Bundle.MultiCaseKeywordSearchNode_properties_path(),
 
  165                     searchHit.getSourcePath()));
 
  166             ss.put(
new NodeProperty<>(Bundle.MultiCaseKeywordSearchNode_properties_sourceType(), Bundle.MultiCaseKeywordSearchNode_properties_sourceType(), Bundle.MultiCaseKeywordSearchNode_properties_sourceType(),
 
  167                     searchHit.getSourceType().getDisplayName()));
 
  168             ss.put(
new NodeProperty<>(Bundle.MultiCaseKeywordSearchNode_properties_source(), Bundle.MultiCaseKeywordSearchNode_properties_source(), Bundle.MultiCaseKeywordSearchNode_properties_source(),
 
  169                     searchHit.getSourceName()));
 
  174         public Action[] getActions(
boolean context) {
 
  175             List<Action> actions = 
new ArrayList<>();
 
  176             actions.add(
new OpenCaseAction(getCasePath()));
 
  177             actions.add(
new CopyResultAction(searchHit));
 
  178             return actions.toArray(
new Action[actions.size()]);
 
  182     @NbBundle.Messages({
"MultiCaseKeywordSearchNode.copyResultAction.text=Copy to clipboard"})
 
  189         private static final long serialVersionUID = 1L;
 
  197             super(Bundle.MultiCaseKeywordSearchNode_copyResultAction_text());
 
  198             result = selectedResult;
 
  203             StringSelection resultSelection = 
new StringSelection(result.getCaseDisplayName() + 
"\t" 
  204                     + result.getCaseDirectoryPath() + 
"\t" 
  205                     + result.getDataSourceName() + 
"\t" 
  206                     + result.getSourceType().getDisplayName() + 
"\t" 
  207                     + result.getSourceName() + 
"\t" 
  208                     + result.getSourcePath() + 
"\t");
 
  209             Toolkit.getDefaultToolkit().getSystemClipboard().setContents(resultSelection, resultSelection);
 
  213         public Object 
clone() throws CloneNotSupportedException {
 
  214             return super.clone(); 
 
  219     @NbBundle.Messages({
"MultiCaseKeywordSearchNode.OpenCaseAction.text=Open Case"})
 
  225         private static final long serialVersionUID = 1L;
 
  238             File caseFolder = Paths.get(caseDirectory).toFile();
 
  239             if (caseFolder.exists()) {
 
  243                 File[] fileArray = caseFolder.listFiles();
 
  244                 if (fileArray == null) {
 
  247                 String autFilePath = null;
 
  248                 for (File file : fileArray) {
 
  249                     String name = file.getName().toLowerCase();
 
  250                     if (autFilePath == null && name.endsWith(getFileExtension())) {
 
  251                         return file.getAbsolutePath();
 
  265             super(Bundle.MultiCaseKeywordSearchNode_OpenCaseAction_text());
 
  278                                 LOGGER.log(Level.SEVERE, String.format(
"Error opening case with metadata file path %s", caseDirPath), ex); 
 
  287         public Object 
clone() throws CloneNotSupportedException {
 
  288             return super.clone(); 
 
void actionPerformed(ActionEvent e)
static String findAutFile(String caseDirectory)
static void openAsCurrentCase(String caseMetadataFilePath)
void actionPerformed(ActionEvent e)
static StartupWindowProvider getInstance()
static void error(String message)