Autopsy  4.20.0
Graphical digital forensics platform for The Sleuth Kit and other tools.
ResultFile.java
Go to the documentation of this file.
1 /*
2  * Autopsy Forensic Browser
3  *
4  * Copyright 2019-2020 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.discovery.search;
20 
22 import org.sleuthkit.datamodel.AbstractFile;
23 import java.util.ArrayList;
24 import java.util.Collections;
25 import java.util.List;
26 import org.apache.commons.lang.StringUtils;
27 import org.openide.util.NbBundle;
33 import org.sleuthkit.datamodel.Content;
34 import org.sleuthkit.datamodel.HashUtility;
35 import org.sleuthkit.datamodel.Score;
36 import org.sleuthkit.datamodel.TskCoreException;
37 import org.sleuthkit.datamodel.TskData;
38 
42 public class ResultFile extends Result {
43 
44  private final static Logger logger = Logger.getLogger(ResultFile.class.getName());
45  private final List<String> keywordListNames;
46  private final List<String> hashSetNames;
47  private final List<String> interestingSetNames;
48  private final List<String> objectDetectedNames;
49  private final List<AbstractFile> instances = new ArrayList<>();
50  private Score currentScore = Score.SCORE_UNKNOWN;
51  private String scoreDescription = null;
52  private boolean deleted = false;
53  private Type fileType;
54 
60  public ResultFile(AbstractFile abstractFile) {
61  try {
62  //call get uniquePath to cache the path
63  abstractFile.getUniquePath();
64  } catch (TskCoreException ignored) {
65  //path wasnt cached will likely be called on EDT later JIRA-5972
66  }
67  //store the file the ResultFile was created for as the first value in the instances list
68  instances.add(abstractFile);
69  if (abstractFile.isDirNameFlagSet(TskData.TSK_FS_NAME_FLAG_ENUM.UNALLOC)) {
70  deleted = true;
71  }
72  updateScoreAndDescription(abstractFile);
73  keywordListNames = new ArrayList<>();
74  hashSetNames = new ArrayList<>();
75  interestingSetNames = new ArrayList<>();
76  objectDetectedNames = new ArrayList<>();
77  fileType = fromMIMEtype(abstractFile.getMIMEType());
78  }
79 
86  public void addDuplicate(AbstractFile duplicate) {
87  if (deleted && !duplicate.isDirNameFlagSet(TskData.TSK_FS_NAME_FLAG_ENUM.UNALLOC)) {
88  deleted = false;
89  }
90  if (fileType == Type.OTHER) {
91  fileType = fromMIMEtype(duplicate.getMIMEType());
92  }
93  updateScoreAndDescription(duplicate);
94  try {
95  //call get uniquePath to cache the path
96  duplicate.getUniquePath();
97  } catch (TskCoreException ignored) {
98  //path wasnt cached will likely be called on EDT later JIRA-5972
99  }
100  instances.add(duplicate);
101  }
102 
109  public Score getScore() {
110  return currentScore;
111  }
112 
118  public String getScoreDescription() {
119  return scoreDescription;
120  }
121 
128  public boolean isDeleted() {
129  return deleted;
130  }
131 
139  public List<AbstractFile> getAllInstances() {
140  return Collections.unmodifiableList(instances);
141  }
142 
148  public Type getFileType() {
149  return fileType;
150  }
151 
157  public void addKeywordListName(String keywordListName) {
158  if (!keywordListNames.contains(keywordListName)) {
159  keywordListNames.add(keywordListName);
160  }
161 
162  // Sort the list so the getKeywordListNames() will be consistent regardless of the order added
163  Collections.sort(keywordListNames);
164  }
165 
171  public List<String> getKeywordListNames() {
172  return Collections.unmodifiableList(keywordListNames);
173  }
174 
180  public void addHashSetName(String hashSetName) {
181  if (!hashSetNames.contains(hashSetName)) {
182  hashSetNames.add(hashSetName);
183  }
184 
185  // Sort the list so the getHashHitNames() will be consistent regardless of the order added
186  Collections.sort(hashSetNames);
187  }
188 
194  public List<String> getHashSetNames() {
195  return Collections.unmodifiableList(hashSetNames);
196  }
197 
203  public void addInterestingSetName(String interestingSetName) {
204  if (!interestingSetNames.contains(interestingSetName)) {
205  interestingSetNames.add(interestingSetName);
206  }
207 
208  // Sort the list so the getInterestingSetNames() will be consistent regardless of the order added
209  Collections.sort(interestingSetNames);
210  }
211 
217  public List<String> getInterestingSetNames() {
218  return Collections.unmodifiableList(interestingSetNames);
219  }
220 
226  public void addObjectDetectedName(String objectDetectedName) {
227  if (!objectDetectedNames.contains(objectDetectedName)) {
228  objectDetectedNames.add(objectDetectedName);
229  }
230 
231  // Sort the list so the getObjectDetectedNames() will be consistent regardless of the order added
232  Collections.sort(objectDetectedNames);
233  }
234 
240  public List<String> getObjectDetectedNames() {
241  return Collections.unmodifiableList(objectDetectedNames);
242  }
243 
249  public AbstractFile getFirstInstance() {
250  return instances.get(0);
251  }
252 
253  @Override
254  public String toString() {
255  return getFirstInstance().getName() + "(" + getFirstInstance().getId() + ") - "
256  + getFirstInstance().getSize() + ", " + getFirstInstance().getParentPath() + ", "
257  + getFirstInstance().getDataSourceObjectId() + ", " + getFrequency().toString() + ", "
258  + String.join(",", keywordListNames) + ", " + getFirstInstance().getMIMEType();
259  }
260 
261  @Override
262  public int hashCode() {
263  if (StringUtils.isBlank(this.getFirstInstance().getMd5Hash())
264  || HashUtility.isNoDataMd5(this.getFirstInstance().getMd5Hash())) {
265  return super.hashCode();
266  } else {
267  //if the file has a valid MD5 use the hashcode of the MD5 for deduping files with the same MD5
268  return this.getFirstInstance().getMd5Hash().hashCode();
269  }
270 
271  }
272 
273  @Override
274  public boolean equals(Object obj) {
275  if (!(obj instanceof ResultFile)
276  || StringUtils.isBlank(this.getFirstInstance().getMd5Hash())
277  || HashUtility.isNoDataMd5(this.getFirstInstance().getMd5Hash())) {
278  return super.equals(obj);
279  } else {
280  //if the file has a valid MD5 compare use the MD5 for equality check
281  return this.getFirstInstance().getMd5Hash().equals(((ResultFile) obj).getFirstInstance().getMd5Hash());
282  }
283  }
284 
285 
286  @NbBundle.Messages({
287  "# {0} - significanceDisplayName",
288  "ResultFile_updateScoreAndDescription_description=Has an {0} analysis result score"
289  })
290  private void updateScoreAndDescription(AbstractFile file) {
291  Score score = Score.SCORE_UNKNOWN;
292  try {
293  score = Case.getCurrentCaseThrows().getSleuthkitCase().getScoringManager().getAggregateScore(file.getId());
294  } catch (NoCurrentCaseException | TskCoreException ex) {
295 
296  }
297 
298  this.currentScore = score;
299  String significanceDisplay = score.getSignificance().getDisplayName();
300  this.scoreDescription = Bundle.ResultFile_updateScoreAndDescription_description(significanceDisplay);
301  }
302 
310  public static Type fromMIMEtype(String mimeType) {
311  for (Type type : Type.values()) {
312  if (type.getMediaTypes().contains(mimeType)) {
313  return type;
314  }
315  }
316  return OTHER;
317  }
318 
319  @Override
320  public long getDataSourceObjectId() {
321  return getFirstInstance().getDataSourceObjectId();
322  }
323 
324  @Override
325  public Content getDataSource() throws TskCoreException {
326  return getFirstInstance().getDataSource();
327  }
328 
329  @Override
330  public TskData.FileKnown getKnown() {
331  return getFirstInstance().getKnown();
332  }
333 
334  @Override
335  public Type getType() {
336  return fileType;
337  }
338 }
void addKeywordListName(String keywordListName)
synchronized static Logger getLogger(String name)
Definition: Logger.java:124
void addInterestingSetName(String interestingSetName)
void addObjectDetectedName(String objectDetectedName)

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.