Autopsy  4.10.0
Graphical digital forensics platform for The Sleuth Kit and other tools.
MultiCaseKeywordSearchNode.java
Go to the documentation of this file.
1 /*
2  * Autopsy Forensic Browser
3  *
4  * Copyright 2019 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.keywordsearch.multicase;
20 
21 import java.awt.Toolkit;
22 import java.awt.datatransfer.StringSelection;
23 import java.awt.event.ActionEvent;
24 import java.io.File;
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;
46 
47 @NbBundle.Messages({
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"
54 })
55 
60 class MultiCaseKeywordSearchNode extends AbstractNode {
61 
62  private static final Logger LOGGER = Logger.getLogger(MultiCaseKeywordSearchNode.class.getName());
63 
70  MultiCaseKeywordSearchNode(Collection<SearchHit> resultList) {
71  super(new MultiCaseKeywordSearchChildren(resultList));
72  }
73 
77  static class MultiCaseKeywordSearchChildren extends Children.Keys<SearchHit> {
78 
79  private final Collection<SearchHit> resultList;
80 
87  MultiCaseKeywordSearchChildren(Collection<SearchHit> resultList) {
88  this.resultList = resultList;
89  }
90 
91  @Override
92  protected void addNotify() {
93  super.addNotify();
94  setKeys(resultList);
95  }
96 
97  @Override
98  protected void removeNotify() {
99  super.removeNotify();
100  setKeys(Collections.emptyList());
101  }
102 
103  @Override
104  protected Node[] createNodes(SearchHit t) {
105  return new Node[]{new SearchHitNode(t)};
106  }
107 
108  @Override
109  public Object clone() {
110  return super.clone();
111  }
112 
113  }
114 
118  static final class SearchHitNode extends AbstractNode {
119 
120  private final SearchHit searchHit;
121 
128  SearchHitNode(SearchHit kwsHit) {
129  super(Children.LEAF);
130  searchHit = kwsHit;
131  super.setName(searchHit.getCaseDisplayName());
132  setDisplayName(searchHit.getCaseDisplayName());
133  }
134 
135  @Override
136  public Action getPreferredAction() {
137  return new OpenCaseAction(getCasePath());
138  }
139 
146  private String getCasePath() {
147  return searchHit.getCaseDirectoryPath();
148  }
149 
150  @Override
151  protected Sheet createSheet() {
152  Sheet s = super.createSheet();
153  Sheet.Set ss = s.get(Sheet.PROPERTIES);
154  if (ss == null) {
155  ss = Sheet.createPropertiesSet();
156  s.put(ss);
157  }
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()));
170  return s;
171  }
172 
173  @Override
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()]);
179  }
180  }
181 
182  @NbBundle.Messages({"MultiCaseKeywordSearchNode.copyResultAction.text=Copy to clipboard"})
187  private static class CopyResultAction extends AbstractAction {
188 
189  private static final long serialVersionUID = 1L;
190 
191  SearchHit result;
192 
196  CopyResultAction(SearchHit selectedResult) {
197  super(Bundle.MultiCaseKeywordSearchNode_copyResultAction_text());
198  result = selectedResult;
199  }
200 
201  @Override
202  public void actionPerformed(ActionEvent e) {
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);
210  }
211 
212  @Override
213  public Object clone() throws CloneNotSupportedException {
214  return super.clone(); //To change body of generated methods, choose Tools | Templates.
215  }
216 
217  }
218 
219  @NbBundle.Messages({"MultiCaseKeywordSearchNode.OpenCaseAction.text=Open Case"})
223  private static class OpenCaseAction extends AbstractAction {
224 
225  private static final long serialVersionUID = 1L;
226  private final String caseDirPath;
227 
237  private static String findAutFile(String caseDirectory) throws CaseActionException {
238  File caseFolder = Paths.get(caseDirectory).toFile();
239  if (caseFolder.exists()) {
240  /*
241  * Search for '*.aut' files.
242  */
243  File[] fileArray = caseFolder.listFiles();
244  if (fileArray == null) {
245  throw new CaseActionException("No files found in case directory");
246  }
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();
252  }
253  }
254  throw new CaseActionException("No .aut files found in case directory");
255  }
256  throw new CaseActionException("Case directory was not found");
257  }
258 
264  OpenCaseAction(String path) {
265  super(Bundle.MultiCaseKeywordSearchNode_OpenCaseAction_text());
266  caseDirPath = path;
267  }
268 
269  @Override
270  public void actionPerformed(ActionEvent e) {
272  new Thread(
273  () -> {
274  try {
275  Case.openAsCurrentCase(findAutFile(caseDirPath));
276  } catch (CaseActionException ex) {
277  if (null != ex.getCause() && !(ex.getCause() instanceof CaseActionCancelledException)) {
278  LOGGER.log(Level.SEVERE, String.format("Error opening case with metadata file path %s", caseDirPath), ex); //NON-NLS
279  MessageNotifyUtil.Message.error(ex.getCause().getLocalizedMessage());
280  }
281  }
282  }
283  ).start();
284  }
285 
286  @Override
287  public Object clone() throws CloneNotSupportedException {
288  return super.clone(); //To change body of generated methods, choose Tools | Templates.
289  }
290 
291  }
292 }
static void openAsCurrentCase(String caseMetadataFilePath)
Definition: Case.java:581

Copyright © 2012-2018 Basis Technology. Generated on: Fri Mar 22 2019
This work is licensed under a Creative Commons Attribution-Share Alike 3.0 United States License.