Autopsy 4.22.1
Graphical digital forensics platform for The Sleuth Kit and other tools.
ResultsSorter.java
Go to the documentation of this file.
1/*
2 * Autopsy Forensic Browser
3 *
4 * Copyright 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 */
19package org.sleuthkit.autopsy.discovery.search;
20
21import java.util.ArrayList;
22import java.util.Arrays;
23import java.util.Collections;
24import java.util.Comparator;
25import java.util.List;
26import org.openide.util.NbBundle;
27import org.sleuthkit.datamodel.TskCoreException;
28
32public class ResultsSorter implements Comparator<Result> {
33
34 private final List<Comparator<Result>> comparators = new ArrayList<>();
35
44
45 // Set up the primary comparators that should applied to the results
46 switch (method) {
47 case BY_DATA_SOURCE:
49 break;
50 case BY_FILE_SIZE:
52 break;
53 case BY_FILE_TYPE:
56 break;
57 case BY_FREQUENCY:
59 break;
60 case BY_KEYWORD_LIST_NAMES:
62 break;
63 case BY_FULL_PATH:
65 break;
66 case BY_FILE_NAME:
68 break;
69 case BY_DOMAIN_NAME:
71 break;
72 case BY_PAGE_VIEWS:
74 break;
75 case BY_LAST_ACTIVITY:
77 break;
78 case BY_DOWNLOADS:
80 break;
81 default:
82 // The default comparator will be added afterward
83 break;
84 }
85
86 // Add the default comparator to the end. This will ensure a consistent sort
87 // order regardless of the order the results were added to the list.
89 }
90
91 @Override
92 public int compare(Result result1, Result result2) {
93
94 int result = 0;
95 for (Comparator<Result> comp : comparators) {
96 result = comp.compare(result1, result2);
97 if (result != 0) {
98 return result;
99 }
100 }
101
102 // The results are the same
103 return result;
104 }
105
112 private static Comparator<Result> getDataSourceComparator() {
113 return (Result result1, Result result2) -> Long.compare(result1.getDataSourceObjectId(), result2.getDataSourceObjectId());
114 }
115
122 private static Comparator<Result> getTypeComparator() {
123 return (Result result1, Result result2) -> Integer.compare(result1.getType().getRanking(), result2.getType().getRanking());
124 }
125
134 private static Comparator<Result> getKeywordListNameComparator() {
135 return (Result result1, Result result2) -> {
136 // Put empty lists at the bottom
137 if (result1.getType() == SearchData.Type.DOMAIN) {
138 return 0;
139 }
140 ResultFile file1 = (ResultFile) result1;
141 ResultFile file2 = (ResultFile) result2;
142 if (file1.getKeywordListNames().isEmpty()) {
143 if (file2.getKeywordListNames().isEmpty()) {
144 return 0;
145 }
146 return 1;
147 } else if (file2.getKeywordListNames().isEmpty()) {
148 return -1;
149 }
150
151 String list1 = String.join(",", file1.getKeywordListNames());
152 String list2 = String.join(",", file2.getKeywordListNames());
153 return compareStrings(list1, list2);
154 };
155 }
156
163 private static Comparator<Result> getParentPathComparator() {
164
165 return new Comparator<Result>() {
166 @Override
167 public int compare(Result result1, Result result2) {
168 if (result1.getType() == SearchData.Type.DOMAIN) {
169 return 0;
170 }
171 ResultFile file1 = (ResultFile) result1;
172 ResultFile file2 = (ResultFile) result2;
173 String file1ParentPath;
174 try {
175 file1ParentPath = file1.getFirstInstance().getParent().getUniquePath();
176 } catch (TskCoreException ingored) {
177 file1ParentPath = file1.getFirstInstance().getParentPath();
178 }
179 String file2ParentPath;
180 try {
181 file2ParentPath = file2.getFirstInstance().getParent().getUniquePath();
182 } catch (TskCoreException ingored) {
183 file2ParentPath = file2.getFirstInstance().getParentPath();
184 }
185 return compareStrings(file1ParentPath.toLowerCase(), file2ParentPath.toLowerCase());
186 }
187 };
188 }
189
197 private static Comparator<Result> getFrequencyComparator() {
198 return (Result result1, Result result2) -> Integer.compare(result1.getFrequency().getRanking(), result2.getFrequency().getRanking());
199 }
200
207 private static Comparator<Result> getMIMETypeComparator() {
208 return (Result result1, Result result2) -> {
209 if (result1.getType() == SearchData.Type.DOMAIN) {
210 return 0;
211 }
212 return compareStrings(((ResultFile) result1).getFirstInstance().getMIMEType(), ((ResultFile) result2).getFirstInstance().getMIMEType());
213 };
214 }
215
221 private static Comparator<Result> getFileSizeComparator() {
222 return (Result result1, Result result2) -> {
223 if (result1.getType() == SearchData.Type.DOMAIN) {
224 return 0;
225 }
226 return -1 * Long.compare(((ResultFile) result1).getFirstInstance().getSize(), ((ResultFile) result2).getFirstInstance().getSize()); // Sort large to small
227 };
228 }
229
235 private static Comparator<Result> getFileNameComparator() {
236 return (Result result1, Result result2) -> {
237 if (result1.getType() == SearchData.Type.DOMAIN) {
238 return 0;
239 }
240 return compareStrings(((ResultFile) result1).getFirstInstance().getName().toLowerCase(), (((ResultFile) result2).getFirstInstance().getName().toLowerCase()));
241 };
242 }
243
249 private static Comparator<Result> getDomainNameComparator() {
250 return (Result domain1, Result domain2) -> {
251 if (domain1.getType() != SearchData.Type.DOMAIN) {
252 return 0;
253 }
254
255 ResultDomain first = (ResultDomain) domain1;
256 ResultDomain second = (ResultDomain) domain2;
257 return compareStrings(first.getDomain().toLowerCase(), second.getDomain().toLowerCase());
258 };
259 }
260
266 private static Comparator<Result> getPageViewComparator() {
267 return (Result domain1, Result domain2) -> {
268 if (domain1.getType() != SearchData.Type.DOMAIN
269 || domain2.getType() != SearchData.Type.DOMAIN) {
270 return 0;
271 }
272
273 ResultDomain first = (ResultDomain) domain1;
274 ResultDomain second = (ResultDomain) domain2;
275
276 long firstPageViews = first.getTotalPageViews();
277 long secondPageViews = second.getTotalPageViews();
278 return Long.compare(secondPageViews, firstPageViews);
279 };
280 }
281
286 private static Comparator<Result> getLastActivityDateTimeComparator() {
287 return (Result domain1, Result domain2) -> {
288 if (domain1.getType() != SearchData.Type.DOMAIN
289 || domain2.getType() != SearchData.Type.DOMAIN) {
290 return 0;
291 }
292 ResultDomain first = (ResultDomain) domain1;
293 ResultDomain second = (ResultDomain) domain2;
294
295 long firstActivityEnd = first.getActivityEnd();
296 long secondActivityEnd = second.getActivityEnd();
297 return Long.compare(secondActivityEnd, firstActivityEnd);
298 };
299 }
300
305 private static Comparator<Result> getWebDownloadsComparator() {
306 return (Result domain1, Result domain2) -> {
307 if (domain1.getType() != SearchData.Type.DOMAIN
308 || domain2.getType() != SearchData.Type.DOMAIN) {
309 return 0;
310 }
311 ResultDomain first = (ResultDomain) domain1;
312 ResultDomain second = (ResultDomain) domain2;
313
314 long firstFilesDownloaded = first.getFilesDownloaded();
315 long secondFilesDownloaded = second.getFilesDownloaded();
316 return Long.compare(secondFilesDownloaded, firstFilesDownloaded);
317 };
318 }
319
328 private static Comparator<Result> getDefaultComparator() {
329 return (Result result1, Result result2) -> {
330 // Compare file names and then object ID (to ensure a consistent sort)
331 if (result1.getType() == SearchData.Type.DOMAIN) {
332 return getFrequencyComparator().compare(result1, result2);
333 } else {
334 ResultFile file1 = (ResultFile) result1;
335 ResultFile file2 = (ResultFile) result2;
336 int result = getFileNameComparator().compare(file1, file2);
337 if (result == 0) {
338 return Long.compare(file1.getFirstInstance().getId(), file2.getFirstInstance().getId());
339 }
340 return result;
341 }
342
343 };
344 }
345
354 private static int compareStrings(String s1, String s2) {
355 String string1 = s1 == null ? "" : s1;
356 String string2 = s2 == null ? "" : s2;
357 return string1.compareTo(string2);
358
359 }
360
364 @NbBundle.Messages({
365 "FileSorter.SortingMethod.datasource.displayName=Data Source",
366 "FileSorter.SortingMethod.filename.displayName=File Name",
367 "FileSorter.SortingMethod.filesize.displayName=File Size",
368 "FileSorter.SortingMethod.filetype.displayName=File Type",
369 "FileSorter.SortingMethod.frequency.displayName=Central Repo Frequency",
370 "FileSorter.SortingMethod.keywordlist.displayName=Keyword List Names",
371 "FileSorter.SortingMethod.fullPath.displayName=Full Path",
372 "FileSorter.SortingMethod.domain.displayName=Domain Name",
373 "FileSorter.SortingMethod.pageViews.displayName=Page Views",
374 "FileSorter.SortingMethod.downloads.displayName=File Downloads",
375 "FileSorter.SortingMethod.activity.displayName=Last Activity Date"})
376 public enum SortingMethod {
377 BY_FILE_NAME(new ArrayList<>(),
378 Bundle.FileSorter_SortingMethod_filename_displayName()), // Sort alphabetically by file name
379 BY_DATA_SOURCE(new ArrayList<>(),
380 Bundle.FileSorter_SortingMethod_datasource_displayName()), // Sort in increasing order of data source ID
381 BY_FILE_SIZE(new ArrayList<>(),
382 Bundle.FileSorter_SortingMethod_filesize_displayName()), // Sort in decreasing order of size
384 Bundle.FileSorter_SortingMethod_filetype_displayName()), // Sort in order of file type (defined in FileType enum), with secondary sort on MIME type
386 Bundle.FileSorter_SortingMethod_frequency_displayName()), // Sort by decreasing rarity in the central repository
388 Bundle.FileSorter_SortingMethod_keywordlist_displayName()), // Sort alphabetically by list of keyword list names found
389 BY_FULL_PATH(new ArrayList<>(),
390 Bundle.FileSorter_SortingMethod_fullPath_displayName()), // Sort alphabetically by path
391 BY_DOMAIN_NAME(Arrays.asList(new DiscoveryAttributes.DomainCategoryAttribute(), new DiscoveryAttributes.PreviouslyNotableAttribute()), Bundle.FileSorter_SortingMethod_domain_displayName()),
392 BY_PAGE_VIEWS(Arrays.asList(new DiscoveryAttributes.DomainCategoryAttribute(), new DiscoveryAttributes.PreviouslyNotableAttribute()), Bundle.FileSorter_SortingMethod_pageViews_displayName()),
393 BY_DOWNLOADS(Arrays.asList(new DiscoveryAttributes.DomainCategoryAttribute(), new DiscoveryAttributes.PreviouslyNotableAttribute()), Bundle.FileSorter_SortingMethod_downloads_displayName()),
394 BY_LAST_ACTIVITY(Arrays.asList(new DiscoveryAttributes.DomainCategoryAttribute(), new DiscoveryAttributes.PreviouslyNotableAttribute()), Bundle.FileSorter_SortingMethod_activity_displayName());
395
396 private final String displayName;
398
406 SortingMethod(List<DiscoveryAttributes.AttributeType> attributes, String displayName) {
407 this.requiredAttributes = attributes;
408 this.displayName = displayName;
409 }
410
411 @Override
412 public String toString() {
413 return displayName;
414 }
415
422 return Collections.unmodifiableList(requiredAttributes);
423 }
424
430 public static List<SortingMethod> getOptionsForOrderingFiles() {
431 return Arrays.asList(BY_FILE_SIZE, BY_FULL_PATH, BY_FILE_NAME, BY_DATA_SOURCE);
432 }
433
439 public static List<SortingMethod> getOptionsForOrderingDomains() {
441 }
442
443 }
444}
static Comparator< Result > getLastActivityDateTimeComparator()
static Comparator< Result > getKeywordListNameComparator()
final List< Comparator< Result > > comparators
int compare(Result result1, Result result2)
final List< DiscoveryAttributes.AttributeType > requiredAttributes
List< DiscoveryAttributes.AttributeType > getRequiredAttributes()
SortingMethod(List< DiscoveryAttributes.AttributeType > attributes, String displayName)

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