19 package org.sleuthkit.autopsy.filequery;
23 import java.util.ArrayList;
24 import java.util.Collections;
25 import java.util.List;
26 import java.util.logging.Level;
27 import org.openide.util.NbBundle;
44 private final static Logger logger = Logger.getLogger(ResultFile.class.getName());
45 private FileSearchData.Frequency frequency;
46 private final List<String> keywordListNames;
47 private final List<String> hashSetNames;
48 private final List<String> tagNames;
49 private final List<String> interestingSetNames;
50 private final List<String> objectDetectedNames;
51 private final List<AbstractFile> instances =
new ArrayList<>();
52 private DataResultViewerTable.Score currentScore = DataResultViewerTable.Score.NO_SCORE;
53 private String scoreDescription = null;
54 private boolean deleted =
false;
55 private FileType fileType;
62 ResultFile(AbstractFile abstractFile) {
65 abstractFile.getUniquePath();
66 }
catch (TskCoreException ignored) {
70 instances.add(abstractFile);
71 if (abstractFile.isDirNameFlagSet(TskData.TSK_FS_NAME_FLAG_ENUM.UNALLOC)) {
74 updateScoreAndDescription(abstractFile);
75 this.frequency = FileSearchData.Frequency.UNKNOWN;
76 keywordListNames =
new ArrayList<>();
77 hashSetNames =
new ArrayList<>();
78 tagNames =
new ArrayList<>();
79 interestingSetNames =
new ArrayList<>();
80 objectDetectedNames =
new ArrayList<>();
81 fileType = FileType.fromMIMEtype(abstractFile.getMIMEType());
89 FileSearchData.Frequency getFrequency() {
98 void setFrequency(FileSearchData.Frequency frequency) {
99 this.frequency = frequency;
108 void addDuplicate(AbstractFile duplicate) {
109 if (deleted && !duplicate.isDirNameFlagSet(TskData.TSK_FS_NAME_FLAG_ENUM.UNALLOC)) {
112 if (fileType == FileType.OTHER) {
113 fileType = FileType.fromMIMEtype(duplicate.getMIMEType());
115 updateScoreAndDescription(duplicate);
118 duplicate.getUniquePath();
119 }
catch (TskCoreException ignored) {
122 instances.add(duplicate);
131 DataResultViewerTable.Score getScore() {
140 String getScoreDescription() {
141 return scoreDescription;
150 boolean isDeleted() {
161 List<AbstractFile> getAllInstances() {
162 return Collections.unmodifiableList(instances);
170 FileType getFileType() {
179 void addKeywordListName(String keywordListName) {
180 if (!keywordListNames.contains(keywordListName)) {
181 keywordListNames.add(keywordListName);
185 Collections.sort(keywordListNames);
193 List<String> getKeywordListNames() {
194 return Collections.unmodifiableList(keywordListNames);
202 void addHashSetName(String hashSetName) {
203 if (!hashSetNames.contains(hashSetName)) {
204 hashSetNames.add(hashSetName);
208 Collections.sort(hashSetNames);
216 List<String> getHashSetNames() {
217 return Collections.unmodifiableList(hashSetNames);
225 void addTagName(String tagName) {
226 if (!tagNames.contains(tagName)) {
227 tagNames.add(tagName);
231 Collections.sort(tagNames);
239 List<String> getTagNames() {
240 return Collections.unmodifiableList(tagNames);
248 void addInterestingSetName(String interestingSetName) {
249 if (!interestingSetNames.contains(interestingSetName)) {
250 interestingSetNames.add(interestingSetName);
254 Collections.sort(interestingSetNames);
262 List<String> getInterestingSetNames() {
263 return Collections.unmodifiableList(interestingSetNames);
271 void addObjectDetectedName(String objectDetectedName) {
272 if (!objectDetectedNames.contains(objectDetectedName)) {
273 objectDetectedNames.add(objectDetectedName);
277 Collections.sort(objectDetectedNames);
285 List<String> getObjectDetectedNames() {
286 return Collections.unmodifiableList(objectDetectedNames);
294 AbstractFile getFirstInstance() {
295 return instances.get(0);
299 public String toString() {
300 return getFirstInstance().getName() +
"(" + getFirstInstance().getId() +
") - "
301 + getFirstInstance().getSize() +
", " + getFirstInstance().getParentPath() +
", "
302 + getFirstInstance().getDataSourceObjectId() +
", " + frequency.toString() +
", "
303 + String.join(
",", keywordListNames) +
", " + getFirstInstance().getMIMEType();
307 public int hashCode() {
308 if (this.getFirstInstance().getMd5Hash() == null
309 || HashUtility.isNoDataMd5(
this.getFirstInstance().getMd5Hash())
310 || !HashUtility.isValidMd5Hash(
this.getFirstInstance().getMd5Hash())) {
311 return super.hashCode();
314 return this.getFirstInstance().getMd5Hash().hashCode();
320 public boolean equals(Object obj) {
321 if (!(obj instanceof ResultFile)
322 || this.getFirstInstance().getMd5Hash() == null
323 || HashUtility.isNoDataMd5(
this.getFirstInstance().getMd5Hash())
324 || !HashUtility.isValidMd5Hash(
this.getFirstInstance().getMd5Hash())) {
325 return super.equals(obj);
328 return this.getFirstInstance().getMd5Hash().equals(((ResultFile) obj).getFirstInstance().getMd5Hash());
337 private List<ContentTag> getContentTagsFromDatabase(AbstractFile file) {
338 List<ContentTag> tags =
new ArrayList<>();
340 tags.addAll(Case.getCurrentCaseThrows().getServices().getTagsManager().getContentTagsByContent(file));
341 }
catch (TskCoreException | NoCurrentCaseException ex) {
342 logger.log(Level.SEVERE,
"Failed to get tags for file " + file.getName(), ex);
348 "ResultFile.score.notableFile.description=At least one instance of the file was recognized as notable.",
349 "ResultFile.score.interestingResult.description=At least one instance of the file has an interesting result associated with it.",
350 "ResultFile.score.taggedFile.description=At least one instance of the file has been tagged.",
351 "ResultFile.score.notableTaggedFile.description=At least one instance of the file is tagged with a notable tag."})
352 private void updateScoreAndDescription(AbstractFile file) {
353 if (currentScore == DataResultViewerTable.Score.NOTABLE_SCORE) {
357 if (file.getKnown() == TskData.FileKnown.BAD) {
358 currentScore = DataResultViewerTable.Score.NOTABLE_SCORE;
359 scoreDescription = Bundle.ResultFile_score_notableFile_description();
363 if (currentScore == DataResultViewerTable.Score.NO_SCORE && !file.getArtifacts(BlackboardArtifact.ARTIFACT_TYPE.TSK_INTERESTING_FILE_HIT).isEmpty()) {
364 currentScore = DataResultViewerTable.Score.INTERESTING_SCORE;
365 scoreDescription = Bundle.ResultFile_score_interestingResult_description();
367 }
catch (TskCoreException ex) {
368 logger.log(Level.WARNING,
"Error getting artifacts for file: " + file.getName(), ex);
370 List<ContentTag> tags = getContentTagsFromDatabase(file);
371 if (!tags.isEmpty()) {
372 currentScore = DataResultViewerTable.Score.INTERESTING_SCORE;
373 scoreDescription = Bundle.ResultFile_score_taggedFile_description();
374 for (Tag tag : tags) {
375 if (tag.getName().getKnownStatus() == TskData.FileKnown.BAD) {
376 currentScore = DataResultViewerTable.Score.NOTABLE_SCORE;
377 scoreDescription = Bundle.ResultFile_score_notableTaggedFile_description();