Autopsy  4.20.0
Graphical digital forensics platform for The Sleuth Kit and other tools.
AnalysisResultsViewModel.java
Go to the documentation of this file.
1 /*
2  * Autopsy Forensic Browser
3  *
4  * Copyright 2021-2021 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.contentviewers.analysisresults;
20 
21 import java.util.Collection;
22 import java.util.Collections;
23 import java.util.List;
24 import java.util.Objects;
25 import java.util.Optional;
26 import java.util.logging.Level;
27 import java.util.logging.Logger;
28 import java.util.stream.Collectors;
29 import java.util.stream.Stream;
30 import org.apache.commons.lang3.tuple.Pair;
31 import org.openide.nodes.Node;
32 import org.openide.util.NbBundle;
35 import org.sleuthkit.datamodel.AnalysisResult;
36 import org.sleuthkit.datamodel.BlackboardArtifact;
37 import org.sleuthkit.datamodel.Content;
38 import org.sleuthkit.datamodel.Score;
39 import org.sleuthkit.datamodel.TskCoreException;
40 
45 
46  private static final Logger logger = Logger.getLogger(AnalysisResultsViewModel.class.getName());
47 
51  static class ResultDisplayAttributes {
52 
53  private final AnalysisResult analysisResult;
54  private final List<Pair<String, String>> attributesToDisplay;
55 
64  ResultDisplayAttributes(AnalysisResult analysisResult, List<Pair<String, String>> attributesToDisplay) {
65  this.analysisResult = analysisResult;
66  this.attributesToDisplay = attributesToDisplay;
67  }
68 
74  List<Pair<String, String>> getAttributesToDisplay() {
75  return Collections.unmodifiableList(attributesToDisplay);
76  }
77 
83  AnalysisResult getAnalysisResult() {
84  return analysisResult;
85  }
86  }
87 
92  static class NodeResults {
93 
94  private final List<ResultDisplayAttributes> analysisResults;
95  private final Optional<AnalysisResult> selectedResult;
96  private final Optional<Score> aggregateScore;
97  private final Optional<String> itemName;
98 
110  NodeResults(List<ResultDisplayAttributes> analysisResults, Optional<AnalysisResult> selectedResult,
111  Optional<Score> aggregateScore, Optional<String> itemName) {
112  this.analysisResults = analysisResults;
113  this.selectedResult = selectedResult;
114  this.aggregateScore = aggregateScore;
115  this.itemName = itemName;
116  }
117 
123  List<ResultDisplayAttributes> getAnalysisResults() {
124  return Collections.unmodifiableList(analysisResults);
125  }
126 
132  Optional<AnalysisResult> getSelectedResult() {
133  return selectedResult;
134  }
135 
141  Optional<Score> getAggregateScore() {
142  return aggregateScore;
143  }
144 
150  Optional<String> getItemName() {
151  return itemName;
152  }
153  }
154 
163  private String normalizeAttr(String originalAttrStr) {
164  return (originalAttrStr == null) ? "" : originalAttrStr.trim();
165  }
166 
174  @NbBundle.Messages({
175  "AnalysisResultsViewModel_displayAttributes_score=Score",
176  "AnalysisResultsViewModel_displayAttributes_type=Type",
177  "AnalysisResultsViewModel_displayAttributes_configuration=Configuration",
178  "AnalysisResultsViewModel_displayAttributes_conclusion=Conclusion"
179  })
180  private ResultDisplayAttributes getDisplayAttributes(AnalysisResult analysisResult) {
181  // The type of BlackboardArtifact.Type of the analysis result.
182  String type = "";
183  try {
184  type = normalizeAttr(analysisResult.getType().getDisplayName());
185  } catch (TskCoreException ex) {
186  logger.log(Level.SEVERE, "Unable to get type for analysis result with id: " + analysisResult.getArtifactID(), ex);
187  }
188 
189  // The standard attributes to display (score, type, configuration, conclusion)
190  Stream<Pair<String, String>> baseAnalysisAttrs = Stream.of(
191  Pair.of(Bundle.AnalysisResultsViewModel_displayAttributes_score(),
192  normalizeAttr(analysisResult.getScore().getSignificance().getDisplayName())),
193  Pair.of(Bundle.AnalysisResultsViewModel_displayAttributes_type(),
194  normalizeAttr(type)),
195  Pair.of(Bundle.AnalysisResultsViewModel_displayAttributes_configuration(),
196  normalizeAttr(analysisResult.getConfiguration())),
197  Pair.of(Bundle.AnalysisResultsViewModel_displayAttributes_conclusion(),
198  normalizeAttr(analysisResult.getConclusion()))
199  );
200 
201  // The BlackboardAttributes sorted by type display name.
202  Stream<Pair<String, String>> blackboardAttributes = Stream.empty();
203  try {
204 
205  blackboardAttributes = analysisResult.getAttributes().stream()
206  .filter(attr -> attr != null && attr.getAttributeType() != null && attr.getAttributeType().getDisplayName() != null)
207  .map(attr -> Pair.of(attr.getAttributeType().getDisplayName(), normalizeAttr(attr.getDisplayString())))
208  .sorted((a, b) -> a.getKey().compareToIgnoreCase(b.getKey()));
209  } catch (TskCoreException ex) {
210  logger.log(Level.SEVERE, "Unable to get attributes for analysis result with id: " + analysisResult.getArtifactID(), ex);
211  }
212 
213  // return the standard attributes along with the key value pairs of the BlackboardAttribute values.
214  List<Pair<String, String>> allDisplayAttributes = Stream.concat(baseAnalysisAttrs, blackboardAttributes)
215  .collect(Collectors.toList());
216 
217  return new ResultDisplayAttributes(analysisResult, allDisplayAttributes);
218  }
219 
220  private List<ResultDisplayAttributes> getOrderedDisplayAttributes(Collection<AnalysisResult> analysisResults) {
221  return analysisResults.stream()
222  .filter(ar -> ar != null && ar.getScore() != null)
223  // reverse order to push more important scores to the top
224  .sorted((a, b) -> -a.getScore().compareTo(b.getScore()))
225  .map((ar) -> getDisplayAttributes(ar))
226  .collect(Collectors.toList());
227  }
228 
238  private String getName(Content selectedContent) throws TskCoreException {
239  if (selectedContent == null) {
240  return null;
241  } else if (selectedContent instanceof BlackboardArtifact) {
242  return ((BlackboardArtifact) selectedContent).getShortDescription();
243  } else {
244  return selectedContent.getName();
245  }
246  }
247 
256  NodeResults getAnalysisResults(Node node) {
257  if (node == null) {
258  return new NodeResults(Collections.emptyList(), Optional.empty(), Optional.empty(), Optional.empty());
259  }
260 
261  String contentName = null;
262  AnalysisResult selectedAnalysisResult = null;
263  Score aggregateScore = null;
264  List<AnalysisResult> analysisResults = Collections.emptyList();
265  long selectedObjectId = 0;
266  try {
267  AnalysisResultItem analysisResultItem = node.getLookup().lookup(AnalysisResultItem.class);
268  Content analyzedContent;
269  if (Objects.nonNull(analysisResultItem)) {
270  /*
271  * The content represented by the Node is an analysis result.
272  * Set this analysis result as the analysis result to be
273  * selected in the content viewer and get the analyzed content
274  * as the source of the analysis results to display.
275  */
276  selectedAnalysisResult = analysisResultItem.getTskContent();
277  selectedObjectId = selectedAnalysisResult.getId();
278  analyzedContent = selectedAnalysisResult.getParent();
279  } else {
280  /*
281  * The content represented by the Node is something other than
282  * an analysis result. Use it as the source of the analysis
283  * results to display.
284  */
285  TskContentItem<?> contentItem = node.getLookup().lookup(TskContentItem.class);
286  analyzedContent = contentItem.getTskContent();
287  selectedObjectId = analyzedContent.getId();
288  }
289  aggregateScore = analyzedContent.getAggregateScore();
290  analysisResults = analyzedContent.getAllAnalysisResults();
291  contentName = getName(analyzedContent);
292 
293  } catch (TskCoreException ex) {
294  logger.log(Level.SEVERE, String.format("Error getting analysis result data for selected Content (object ID=%d)", selectedObjectId), ex);
295  }
296 
297  /*
298  * Use the data collected above to construct the view model.
299  */
300  List<ResultDisplayAttributes> displayAttributes = getOrderedDisplayAttributes(analysisResults);
301  return new NodeResults(displayAttributes,
302  Optional.ofNullable(selectedAnalysisResult),
303  Optional.ofNullable(aggregateScore),
304  Optional.ofNullable(contentName));
305  }
306 
307 }
List< ResultDisplayAttributes > getOrderedDisplayAttributes(Collection< AnalysisResult > analysisResults)

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