Autopsy 4.22.1
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 */
19package org.sleuthkit.autopsy.contentviewers.analysisresults;
20
21import java.util.Collection;
22import java.util.Collections;
23import java.util.List;
24import java.util.Objects;
25import java.util.Optional;
26import java.util.logging.Level;
27import java.util.logging.Logger;
28import java.util.stream.Collectors;
29import java.util.stream.Stream;
30import org.apache.commons.lang3.tuple.Pair;
31import org.openide.nodes.Node;
32import org.openide.util.NbBundle;
33import org.sleuthkit.autopsy.datamodel.AnalysisResultItem;
34import org.sleuthkit.autopsy.datamodel.TskContentItem;
35import org.sleuthkit.datamodel.AnalysisResult;
36import org.sleuthkit.datamodel.BlackboardArtifact;
37import org.sleuthkit.datamodel.Content;
38import org.sleuthkit.datamodel.Score;
39import org.sleuthkit.datamodel.TskCoreException;
40
45
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< ResultDisplayAttributes > getOrderedDisplayAttributes(Collection< AnalysisResult > analysisResults)
synchronized static Logger getLogger(String name)
Definition Logger.java:124

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