Autopsy  4.16.0
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 2019 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 
21 import java.util.ArrayList;
22 import java.util.Arrays;
23 import java.util.Collections;
24 import java.util.Comparator;
25 import java.util.List;
26 import org.openide.util.NbBundle;
27 import org.sleuthkit.datamodel.TskCoreException;
28 
32 public class ResultsSorter implements Comparator<Result> {
33 
34  private final List<Comparator<Result>> comparators = new ArrayList<>();
35 
43  public ResultsSorter(SortingMethod method) {
44 
45  // Set up the primary comparators that should applied to the results
46  switch (method) {
47  case BY_DATA_SOURCE:
48  comparators.add(getDataSourceComparator());
49  break;
50  case BY_FILE_SIZE:
51  comparators.add(getFileSizeComparator());
52  break;
53  case BY_FILE_TYPE:
54  comparators.add(getTypeComparator());
55  comparators.add(getMIMETypeComparator());
56  break;
57  case BY_FREQUENCY:
58  comparators.add(getFrequencyComparator());
59  break;
60  case BY_KEYWORD_LIST_NAMES:
61  comparators.add(getKeywordListNameComparator());
62  break;
63  case BY_FULL_PATH:
64  comparators.add(getParentPathComparator());
65  break;
66  case BY_FILE_NAME:
67  comparators.add(getFileNameComparator());
68  break;
69  case BY_DOMAIN_NAME:
70  comparators.add(getDomainNameComparator());
71  break;
72  default:
73  // The default comparator will be added afterward
74  break;
75  }
76 
77  // Add the default comparator to the end. This will ensure a consistent sort
78  // order regardless of the order the results were added to the list.
79  comparators.add(getDefaultComparator());
80  }
81 
82  @Override
83  public int compare(Result result1, Result result2) {
84 
85  int result = 0;
86  for (Comparator<Result> comp : comparators) {
87  result = comp.compare(result1, result2);
88  if (result != 0) {
89  return result;
90  }
91  }
92 
93  // The results are the same
94  return result;
95  }
96 
103  private static Comparator<Result> getDataSourceComparator() {
104  return (Result result1, Result result2) -> Long.compare(result1.getDataSourceObjectId(), result2.getDataSourceObjectId());
105  }
106 
113  private static Comparator<Result> getTypeComparator() {
114  return (Result result1, Result result2) -> Integer.compare(result1.getType().getRanking(), result2.getType().getRanking());
115  }
116 
125  private static Comparator<Result> getKeywordListNameComparator() {
126  return (Result result1, Result result2) -> {
127  // Put empty lists at the bottom
128  if (result1.getType() == SearchData.Type.DOMAIN) {
129  return 0;
130  }
131  ResultFile file1 = (ResultFile) result1;
132  ResultFile file2 = (ResultFile) result2;
133  if (file1.getKeywordListNames().isEmpty()) {
134  if (file2.getKeywordListNames().isEmpty()) {
135  return 0;
136  }
137  return 1;
138  } else if (file2.getKeywordListNames().isEmpty()) {
139  return -1;
140  }
141 
142  String list1 = String.join(",", file1.getKeywordListNames());
143  String list2 = String.join(",", file2.getKeywordListNames());
144  return compareStrings(list1, list2);
145  };
146  }
147 
154  private static Comparator<Result> getParentPathComparator() {
155 
156  return new Comparator<Result>() {
157  @Override
158  public int compare(Result result1, Result result2) {
159  if (result1.getType() == SearchData.Type.DOMAIN) {
160  return 0;
161  }
162  ResultFile file1 = (ResultFile) result1;
163  ResultFile file2 = (ResultFile) result2;
164  String file1ParentPath;
165  try {
166  file1ParentPath = file1.getFirstInstance().getParent().getUniquePath();
167  } catch (TskCoreException ingored) {
168  file1ParentPath = file1.getFirstInstance().getParentPath();
169  }
170  String file2ParentPath;
171  try {
172  file2ParentPath = file2.getFirstInstance().getParent().getUniquePath();
173  } catch (TskCoreException ingored) {
174  file2ParentPath = file2.getFirstInstance().getParentPath();
175  }
176  return compareStrings(file1ParentPath.toLowerCase(), file2ParentPath.toLowerCase());
177  }
178  };
179  }
180 
188  private static Comparator<Result> getFrequencyComparator() {
189  return (Result result1, Result result2) -> Integer.compare(result1.getFrequency().getRanking(), result2.getFrequency().getRanking());
190  }
191 
198  private static Comparator<Result> getMIMETypeComparator() {
199  return (Result result1, Result result2) -> {
200  if (result1.getType() == SearchData.Type.DOMAIN) {
201  return 0;
202  }
203  return compareStrings(((ResultFile) result1).getFirstInstance().getMIMEType(), ((ResultFile) result2).getFirstInstance().getMIMEType());
204  };
205  }
206 
212  private static Comparator<Result> getFileSizeComparator() {
213  return (Result result1, Result result2) -> {
214  if (result1.getType() == SearchData.Type.DOMAIN) {
215  return 0;
216  }
217  return -1 * Long.compare(((ResultFile) result1).getFirstInstance().getSize(), ((ResultFile) result2).getFirstInstance().getSize()); // Sort large to small
218  };
219  }
220 
226  private static Comparator<Result> getFileNameComparator() {
227  return (Result result1, Result result2) -> {
228  if (result1.getType() == SearchData.Type.DOMAIN) {
229  return 0;
230  }
231  return compareStrings(((ResultFile) result1).getFirstInstance().getName().toLowerCase(), (((ResultFile) result2).getFirstInstance().getName().toLowerCase()));
232  };
233  }
234 
240  private static Comparator<Result> getDomainNameComparator() {
241  return (Result domain1, Result domain2) -> {
242  if (domain1.getType() != SearchData.Type.DOMAIN) {
243  return 0;
244  }
245 
246  ResultDomain first = (ResultDomain) domain1;
247  ResultDomain second = (ResultDomain) domain2;
248  return compareStrings(first.getDomain().toLowerCase(), second.getDomain().toLowerCase());
249  };
250  }
251 
257  private static Comparator<Result> getMostRecentDateTimeComparator() {
258  return (Result result1, Result result2) -> {
259  if (result1.getType() != SearchData.Type.DOMAIN) {
260  return 0;
261  }
262 
263  ResultDomain first = (ResultDomain) result1;
264  ResultDomain second = (ResultDomain) result2;
265  return Long.compare(second.getActivityEnd(), first.getActivityEnd());
266  };
267  }
268 
277  private static Comparator<Result> getDefaultComparator() {
278  return (Result result1, Result result2) -> {
279  // Compare file names and then object ID (to ensure a consistent sort)
280  if (result1.getType() == SearchData.Type.DOMAIN) {
281  return getFrequencyComparator().compare(result1, result2);
282  } else {
283  ResultFile file1 = (ResultFile) result1;
284  ResultFile file2 = (ResultFile) result2;
285  int result = getFileNameComparator().compare(file1, file2);
286  if (result == 0) {
287  return Long.compare(file1.getFirstInstance().getId(), file2.getFirstInstance().getId());
288  }
289  return result;
290  }
291 
292  };
293  }
294 
303  private static int compareStrings(String s1, String s2) {
304  String string1 = s1 == null ? "" : s1;
305  String string2 = s2 == null ? "" : s2;
306  return string1.compareTo(string2);
307 
308  }
309 
313  @NbBundle.Messages({
314  "FileSorter.SortingMethod.datasource.displayName=Data Source",
315  "FileSorter.SortingMethod.filename.displayName=File Name",
316  "FileSorter.SortingMethod.filesize.displayName=File Size",
317  "FileSorter.SortingMethod.filetype.displayName=File Type",
318  "FileSorter.SortingMethod.frequency.displayName=Central Repo Frequency",
319  "FileSorter.SortingMethod.keywordlist.displayName=Keyword List Names",
320  "FileSorter.SortingMethod.fullPath.displayName=Full Path",
321  "FileSorter.SortingMethod.domain.displayName=Domain"})
322  public enum SortingMethod {
323  BY_FILE_NAME(new ArrayList<>(),
324  Bundle.FileSorter_SortingMethod_filename_displayName()), // Sort alphabetically by file name
325  BY_DATA_SOURCE(new ArrayList<>(),
326  Bundle.FileSorter_SortingMethod_datasource_displayName()), // Sort in increasing order of data source ID
327  BY_FILE_SIZE(new ArrayList<>(),
328  Bundle.FileSorter_SortingMethod_filesize_displayName()), // Sort in decreasing order of size
329  BY_FILE_TYPE(Arrays.asList(new DiscoveryAttributes.FileTypeAttribute()),
330  Bundle.FileSorter_SortingMethod_filetype_displayName()), // Sort in order of file type (defined in FileType enum), with secondary sort on MIME type
331  BY_FREQUENCY(Arrays.asList(new DiscoveryAttributes.FrequencyAttribute()),
332  Bundle.FileSorter_SortingMethod_frequency_displayName()), // Sort by decreasing rarity in the central repository
333  BY_KEYWORD_LIST_NAMES(Arrays.asList(new DiscoveryAttributes.KeywordListAttribute()),
334  Bundle.FileSorter_SortingMethod_keywordlist_displayName()), // Sort alphabetically by list of keyword list names found
335  BY_FULL_PATH(new ArrayList<>(),
336  Bundle.FileSorter_SortingMethod_fullPath_displayName()), // Sort alphabetically by path
337  BY_DOMAIN_NAME(new ArrayList<>(),
338  Bundle.FileSorter_SortingMethod_domain_displayName());
339 
340  private final String displayName;
342 
350  SortingMethod(List<DiscoveryAttributes.AttributeType> attributes, String displayName) {
351  this.requiredAttributes = attributes;
352  this.displayName = displayName;
353  }
354 
355  @Override
356  public String toString() {
357  return displayName;
358  }
359 
366  return Collections.unmodifiableList(requiredAttributes);
367  }
368 
374  public static List<SortingMethod> getOptionsForOrderingFiles() {
375  return Arrays.asList(BY_FILE_SIZE, BY_FULL_PATH, BY_FILE_NAME, BY_DATA_SOURCE);
376  }
377 
383  public static List<SortingMethod> getOptionsForOrderingDomains() {
384  return Arrays.asList(BY_DOMAIN_NAME, BY_DATA_SOURCE);
385  }
386 
387  }
388 }
int compare(Result result1, Result result2)
final List< Comparator< Result > > comparators
SortingMethod(List< DiscoveryAttributes.AttributeType > attributes, String displayName)
static Comparator< Result > getKeywordListNameComparator()
final List< DiscoveryAttributes.AttributeType > requiredAttributes
List< DiscoveryAttributes.AttributeType > getRequiredAttributes()
static Comparator< Result > getMostRecentDateTimeComparator()

Copyright © 2012-2020 Basis Technology. Generated on: Tue Sep 22 2020
This work is licensed under a Creative Commons Attribution-Share Alike 3.0 United States License.