Autopsy  4.21.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;
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  "AnalysisResultsViewModel_displayAttributes_justification=Justification"
180  })
181  private ResultDisplayAttributes getDisplayAttributes(AnalysisResult analysisResult) {
182  // The type of BlackboardArtifact.Type of the analysis result.
183  String type = "";
184  try {
185  type = normalizeAttr(analysisResult.getType().getDisplayName());
186  } catch (TskCoreException ex) {
187  logger.log(Level.SEVERE, "Unable to get type for analysis result with id: " + analysisResult.getArtifactID(), ex);
188  }
189 
190  // The standard attributes to display (score, type, configuration, conclusion)
191  Stream<Pair<String, String>> baseAnalysisAttrs = Stream.of(
192  Pair.of(Bundle.AnalysisResultsViewModel_displayAttributes_score(),
193  normalizeAttr(analysisResult.getScore().getSignificance().getDisplayName())),
194  Pair.of(Bundle.AnalysisResultsViewModel_displayAttributes_type(),
195  normalizeAttr(type)),
196  Pair.of(Bundle.AnalysisResultsViewModel_displayAttributes_configuration(),
197  normalizeAttr(analysisResult.getConfiguration())),
198  Pair.of(Bundle.AnalysisResultsViewModel_displayAttributes_conclusion(),
199  normalizeAttr(analysisResult.getConclusion())),
200  Pair.of(Bundle.AnalysisResultsViewModel_displayAttributes_justification(),
201  normalizeAttr(analysisResult.getJustification()))
202  );
203 
204  // The BlackboardAttributes sorted by type display name.
205  Stream<Pair<String, String>> blackboardAttributes = Stream.empty();
206  try {
207 
208  blackboardAttributes = analysisResult.getAttributes().stream()
209  .filter(attr -> attr != null && attr.getAttributeType() != null && attr.getAttributeType().getDisplayName() != null)
210  .map(attr -> Pair.of(attr.getAttributeType().getDisplayName(), normalizeAttr(attr.getDisplayString())))
211  .sorted((a, b) -> a.getKey().compareToIgnoreCase(b.getKey()));
212  } catch (TskCoreException ex) {
213  logger.log(Level.SEVERE, "Unable to get attributes for analysis result with id: " + analysisResult.getArtifactID(), ex);
214  }
215 
216  // return the standard attributes along with the key value pairs of the BlackboardAttribute values.
217  List<Pair<String, String>> allDisplayAttributes = Stream.concat(baseAnalysisAttrs, blackboardAttributes)
218  .collect(Collectors.toList());
219 
220  return new ResultDisplayAttributes(analysisResult, allDisplayAttributes);
221  }
222 
223  private List<ResultDisplayAttributes> getOrderedDisplayAttributes(Collection<AnalysisResult> analysisResults) {
224  return analysisResults.stream()
225  .filter(ar -> ar != null && ar.getScore() != null)
226  // reverse order to push more important scores to the top
227  .sorted((a, b) -> -a.getScore().compareTo(b.getScore()))
228  .map((ar) -> getDisplayAttributes(ar))
229  .collect(Collectors.toList());
230  }
231 
241  private String getName(Content selectedContent) throws TskCoreException {
242  if (selectedContent == null) {
243  return null;
244  } else if (selectedContent instanceof BlackboardArtifact) {
245  return ((BlackboardArtifact) selectedContent).getShortDescription();
246  } else {
247  return selectedContent.getName();
248  }
249  }
250 
259  NodeResults getAnalysisResults(Node node) {
260  if (node == null) {
261  return new NodeResults(Collections.emptyList(), Optional.empty(), Optional.empty(), Optional.empty());
262  }
263 
264  String contentName = null;
265  AnalysisResult selectedAnalysisResult = null;
266  Score aggregateScore = null;
267  List<AnalysisResult> analysisResults = Collections.emptyList();
268  long selectedObjectId = 0;
269  try {
270  AnalysisResultItem analysisResultItem = node.getLookup().lookup(AnalysisResultItem.class);
271  Content analyzedContent;
272  if (Objects.nonNull(analysisResultItem)) {
273  /*
274  * The content represented by the Node is an analysis result.
275  * Set this analysis result as the analysis result to be
276  * selected in the content viewer and get the analyzed content
277  * as the source of the analysis results to display.
278  */
279  selectedAnalysisResult = analysisResultItem.getTskContent();
280  selectedObjectId = selectedAnalysisResult.getId();
281  analyzedContent = selectedAnalysisResult.getParent();
282  } else {
283  /*
284  * The content represented by the Node is something other than
285  * an analysis result. Use it as the source of the analysis
286  * results to display.
287  */
288  TskContentItem<?> contentItem = node.getLookup().lookup(TskContentItem.class);
289  analyzedContent = contentItem.getTskContent();
290  selectedObjectId = analyzedContent.getId();
291  }
292  aggregateScore = analyzedContent.getAggregateScore();
293  analysisResults = analyzedContent.getAllAnalysisResults();
294  contentName = getName(analyzedContent);
295 
296  } catch (TskCoreException ex) {
297  logger.log(Level.SEVERE, String.format("Error getting analysis result data for selected Content (object ID=%d)", selectedObjectId), ex);
298  }
299 
300  /*
301  * Use the data collected above to construct the view model.
302  */
303  List<ResultDisplayAttributes> displayAttributes = getOrderedDisplayAttributes(analysisResults);
304  return new NodeResults(displayAttributes,
305  Optional.ofNullable(selectedAnalysisResult),
306  Optional.ofNullable(aggregateScore),
307  Optional.ofNullable(contentName));
308  }
309 
310 }
List< AnalysisResult > getAllAnalysisResults()
List< ResultDisplayAttributes > getOrderedDisplayAttributes(Collection< AnalysisResult > analysisResults)
List< BlackboardAttribute > getAttributes()

Copyright © 2012-2024 Sleuth Kit Labs. Generated on: Mon Mar 17 2025
This work is licensed under a Creative Commons Attribution-Share Alike 3.0 United States License.