Autopsy  4.19.0
Graphical digital forensics platform for The Sleuth Kit and other tools.
DiscoveryKeyUtils.java
Go to the documentation of this file.
1 /*
2  * Autopsy
3  *
4  * Copyright 2020-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  */
19 package org.sleuthkit.autopsy.discovery.search;
20 
21 import java.time.DayOfWeek;
22 import java.time.Instant;
23 import java.time.ZonedDateTime;
24 import java.time.temporal.TemporalAdjusters;
25 import java.util.Collections;
26 import java.util.Set;
27 import java.util.HashSet;
28 import java.util.List;
29 import java.util.Objects;
30 import java.util.TimeZone;
31 import java.util.logging.Level;
32 import org.openide.util.NbBundle;
38 import org.sleuthkit.datamodel.AbstractFile;
39 import org.sleuthkit.datamodel.Content;
40 import org.sleuthkit.datamodel.SleuthkitCase;
41 import org.sleuthkit.datamodel.TskCoreException;
42 
46 public class DiscoveryKeyUtils {
47 
48  private final static Logger logger = Logger.getLogger(DiscoveryKeyUtils.class.getName());
49 
53  static class SearchKey implements Comparable<SearchKey> {
54 
55  private final String keyString;
56  private final Group.GroupSortingAlgorithm groupSortingType;
57  private final DiscoveryAttributes.AttributeType groupAttributeType;
58  private final ResultsSorter.SortingMethod sortingMethod;
59  private final List<AbstractFilter> filters;
60  private final SleuthkitCase sleuthkitCase;
61  private final CentralRepository centralRepository;
62 
74  SearchKey(String userName, List<AbstractFilter> filters,
75  DiscoveryAttributes.AttributeType groupAttributeType,
76  Group.GroupSortingAlgorithm groupSortingType,
77  ResultsSorter.SortingMethod sortingMethod,
78  SleuthkitCase sleuthkitCase, CentralRepository centralRepository) {
79  this.groupAttributeType = groupAttributeType;
80  this.groupSortingType = groupSortingType;
81  this.sortingMethod = sortingMethod;
82  this.filters = filters;
83 
84  StringBuilder searchStringBuilder = new StringBuilder();
85  searchStringBuilder.append(userName);
86  for (AbstractFilter filter : filters) {
87  searchStringBuilder.append(filter.toString());
88  }
89  searchStringBuilder.append(groupAttributeType).append(groupSortingType).append(sortingMethod);
90  keyString = searchStringBuilder.toString();
91  this.sleuthkitCase = sleuthkitCase;
92  this.centralRepository = centralRepository;
93  }
94 
105  SearchKey(String userName, List<AbstractFilter> filters,
106  DiscoveryAttributes.AttributeType groupAttributeType,
107  Group.GroupSortingAlgorithm groupSortingType,
108  ResultsSorter.SortingMethod sortingMethod) {
109  this(userName, filters, groupAttributeType, groupSortingType,
110  sortingMethod, null, null);
111  }
112 
113  @Override
114  public int compareTo(SearchKey otherSearchKey) {
115  return getKeyString().compareTo(otherSearchKey.getKeyString());
116  }
117 
118  @Override
119  public boolean equals(Object otherKey) {
120  if (otherKey == this) {
121  return true;
122  }
123 
124  if (!(otherKey instanceof SearchKey)) {
125  return false;
126  }
127 
128  SearchKey otherSearchKey = (SearchKey) otherKey;
129  if (this.sleuthkitCase != otherSearchKey.getSleuthkitCase()
130  || this.centralRepository != otherSearchKey.getCentralRepository()) {
131  return false;
132  }
133 
134  return getKeyString().equals(otherSearchKey.getKeyString());
135  }
136 
137  @Override
138  public int hashCode() {
139  int hash = 5;
140  hash = 79 * hash + Objects.hashCode(getKeyString());
141  return hash;
142  }
143 
149  String getKeyString() {
150  return keyString;
151  }
152 
158  List<AbstractFilter> getFilters() {
159  return Collections.unmodifiableList(this.filters);
160  }
161 
167  Group.GroupSortingAlgorithm getGroupSortingType() {
168  return groupSortingType;
169  }
170 
176  DiscoveryAttributes.AttributeType getGroupAttributeType() {
177  return groupAttributeType;
178  }
179 
185  ResultsSorter.SortingMethod getFileSortingMethod() {
186  return sortingMethod;
187  }
188 
194  SleuthkitCase getSleuthkitCase() {
195  return this.sleuthkitCase;
196  }
197 
203  CentralRepository getCentralRepository() {
204  return this.centralRepository;
205  }
206  }
207 
211  public abstract static class GroupKey implements Comparable<GroupKey> {
212 
219  abstract String getDisplayName();
220 
228  @Override
229  abstract public boolean equals(Object otherKey);
230 
236  @Override
237  abstract public int hashCode();
238 
248  int compareClassNames(GroupKey otherGroupKey) {
249  return this.getClass().getName().compareTo(otherGroupKey.getClass().getName());
250  }
251 
252  @Override
253  public String toString() {
254  return getDisplayName();
255  }
256  }
257 
261  static class FileSizeGroupKey extends GroupKey {
262 
263  private final SearchData.FileSize fileSize;
264 
270  FileSizeGroupKey(Result file) {
271  ResultFile resultFile = (ResultFile) file;
272  if (resultFile.getFileType() == SearchData.Type.VIDEO) {
273  fileSize = SearchData.FileSize.fromVideoSize(resultFile.getFirstInstance().getSize());
274  } else {
275  fileSize = SearchData.FileSize.fromImageSize(resultFile.getFirstInstance().getSize());
276  }
277  }
278 
279  @Override
280  String getDisplayName() {
281  return getFileSize().toString();
282  }
283 
284  @Override
285  public int compareTo(GroupKey otherGroupKey) {
286  if (otherGroupKey instanceof FileSizeGroupKey) {
287  FileSizeGroupKey otherFileSizeGroupKey = (FileSizeGroupKey) otherGroupKey;
288  return Integer.compare(getFileSize().getRanking(), otherFileSizeGroupKey.getFileSize().getRanking());
289  } else {
290  return compareClassNames(otherGroupKey);
291  }
292  }
293 
294  @Override
295  public boolean equals(Object otherKey) {
296  if (otherKey == this) {
297  return true;
298  }
299 
300  if (!(otherKey instanceof FileSizeGroupKey)) {
301  return false;
302  }
303 
304  FileSizeGroupKey otherFileSizeGroupKey = (FileSizeGroupKey) otherKey;
305  return getFileSize().equals(otherFileSizeGroupKey.getFileSize());
306  }
307 
308  @Override
309  public int hashCode() {
310  return Objects.hash(getFileSize().getRanking());
311  }
312 
318  SearchData.FileSize getFileSize() {
319  return fileSize;
320  }
321  }
322 
326  static class FileTypeGroupKey extends GroupKey {
327 
328  private final SearchData.Type fileType;
329 
335  FileTypeGroupKey(Result file) {
336  fileType = ((ResultFile) file).getFileType();
337  }
338 
339  @Override
340  String getDisplayName() {
341  return getFileType().toString();
342  }
343 
344  @Override
345  public int compareTo(GroupKey otherGroupKey) {
346  if (otherGroupKey instanceof FileTypeGroupKey) {
347  FileTypeGroupKey otherFileTypeGroupKey = (FileTypeGroupKey) otherGroupKey;
348  return Integer.compare(getFileType().getRanking(), otherFileTypeGroupKey.getFileType().getRanking());
349  } else {
350  return compareClassNames(otherGroupKey);
351  }
352  }
353 
354  @Override
355  public boolean equals(Object otherKey) {
356  if (otherKey == this) {
357  return true;
358  }
359 
360  if (!(otherKey instanceof FileTypeGroupKey)) {
361  return false;
362  }
363 
364  FileTypeGroupKey otherFileTypeGroupKey = (FileTypeGroupKey) otherKey;
365  return getFileType().equals(otherFileTypeGroupKey.getFileType());
366  }
367 
368  @Override
369  public int hashCode() {
370  return Objects.hash(getFileType().getRanking());
371  }
372 
378  SearchData.Type getFileType() {
379  return fileType;
380  }
381  }
382 
386  static class KeywordListGroupKey extends GroupKey {
387 
388  private final List<String> keywordListNames;
389  private final String keywordListNamesString;
390 
396  @NbBundle.Messages({
397  "DiscoveryKeyUtils.KeywordListGroupKey.noKeywords=None"})
398  KeywordListGroupKey(ResultFile file) {
399  keywordListNames = file.getKeywordListNames();
400  if (keywordListNames.isEmpty()) {
401  keywordListNamesString = Bundle.DiscoveryKeyUtils_KeywordListGroupKey_noKeywords();
402  } else {
403  keywordListNamesString = String.join(",", keywordListNames); // NON-NLS
404  }
405  }
406 
407  @Override
408  String getDisplayName() {
409  return getKeywordListNamesString();
410  }
411 
412  @Override
413  public int compareTo(GroupKey otherGroupKey) {
414  if (otherGroupKey instanceof KeywordListGroupKey) {
415  KeywordListGroupKey otherKeywordListNamesGroupKey = (KeywordListGroupKey) otherGroupKey;
416 
417  // Put the empty list at the end
418  if (getKeywordListNames().isEmpty()) {
419  if (otherKeywordListNamesGroupKey.getKeywordListNames().isEmpty()) {
420  return 0;
421  } else {
422  return 1;
423  }
424  } else if (otherKeywordListNamesGroupKey.getKeywordListNames().isEmpty()) {
425  return -1;
426  }
427 
428  return getKeywordListNamesString().compareTo(otherKeywordListNamesGroupKey.getKeywordListNamesString());
429  } else {
430  return compareClassNames(otherGroupKey);
431  }
432  }
433 
434  @Override
435  public boolean equals(Object otherKey) {
436  if (otherKey == this) {
437  return true;
438  }
439 
440  if (!(otherKey instanceof KeywordListGroupKey)) {
441  return false;
442  }
443 
444  KeywordListGroupKey otherKeywordListGroupKey = (KeywordListGroupKey) otherKey;
445  return getKeywordListNamesString().equals(otherKeywordListGroupKey.getKeywordListNamesString());
446  }
447 
448  @Override
449  public int hashCode() {
450  return Objects.hash(getKeywordListNamesString());
451  }
452 
458  List<String> getKeywordListNames() {
459  return Collections.unmodifiableList(keywordListNames);
460  }
461 
469  String getKeywordListNamesString() {
470  return keywordListNamesString;
471  }
472  }
473 
477  static class FileTagGroupKey extends GroupKey {
478 
479  private final List<String> tagNames;
480  private final String tagNamesString;
481 
487  @NbBundle.Messages({
488  "DiscoveryKeyUtils.FileTagGroupKey.noSets=None"})
489  FileTagGroupKey(ResultFile file) {
490  tagNames = file.getTagNames();
491 
492  if (tagNames.isEmpty()) {
493  tagNamesString = Bundle.DiscoveryKeyUtils_FileTagGroupKey_noSets();
494  } else {
495  tagNamesString = String.join(",", tagNames); // NON-NLS
496  }
497  }
498 
499  @Override
500  String getDisplayName() {
501  return getTagNamesString();
502  }
503 
504  @Override
505  public int compareTo(GroupKey otherGroupKey) {
506  if (otherGroupKey instanceof FileTagGroupKey) {
507  FileTagGroupKey otherFileTagGroupKey = (FileTagGroupKey) otherGroupKey;
508 
509  // Put the empty list at the end
510  if (getTagNames().isEmpty()) {
511  if (otherFileTagGroupKey.getTagNames().isEmpty()) {
512  return 0;
513  } else {
514  return 1;
515  }
516  } else if (otherFileTagGroupKey.getTagNames().isEmpty()) {
517  return -1;
518  }
519 
520  return getTagNamesString().compareTo(otherFileTagGroupKey.getTagNamesString());
521  } else {
522  return compareClassNames(otherGroupKey);
523  }
524  }
525 
526  @Override
527  public boolean equals(Object otherKey) {
528  if (otherKey == this) {
529  return true;
530  }
531  if (!(otherKey instanceof FileTagGroupKey)) {
532  return false;
533  }
534  FileTagGroupKey otherFileTagGroupKey = (FileTagGroupKey) otherKey;
535  return getTagNamesString().equals(otherFileTagGroupKey.getTagNamesString());
536  }
537 
538  @Override
539  public int hashCode() {
540  return Objects.hash(getTagNamesString());
541  }
542 
548  List<String> getTagNames() {
549  return Collections.unmodifiableList(tagNames);
550  }
551 
559  String getTagNamesString() {
560  return tagNamesString;
561  }
562  }
563 
567  static class ParentPathGroupKey extends GroupKey {
568 
569  private String parentPath;
570  private Long parentID;
571 
577  ParentPathGroupKey(ResultFile file) {
578  Content parent;
579  try {
580  parent = file.getFirstInstance().getParent();
581  } catch (TskCoreException ignored) {
582  parent = null;
583  }
584  //Find the directory this file is in if it is an embedded file
585  while (parent != null && parent instanceof AbstractFile && ((AbstractFile) parent).isFile()) {
586  try {
587  parent = parent.getParent();
588  } catch (TskCoreException ignored) {
589  parent = null;
590  }
591  }
592  setParentPathAndID(parent, file);
593  }
594 
601  private void setParentPathAndID(Content parent, ResultFile file) {
602  if (parent != null) {
603  try {
604  parentPath = parent.getUniquePath();
605  parentID = parent.getId();
606  } catch (TskCoreException ignored) {
607  //catch block left blank purposefully next if statement will handle case when exception takes place as well as when parent is null
608  }
609 
610  }
611  if (parentPath == null) {
612  if (file.getFirstInstance().getParentPath() != null) {
613  parentPath = file.getFirstInstance().getParentPath();
614  } else {
615  parentPath = ""; // NON-NLS
616  }
617  parentID = -1L;
618  }
619  }
620 
621  @Override
622  String getDisplayName() {
623  return getParentPath();
624  }
625 
626  @Override
627  public int compareTo(GroupKey otherGroupKey) {
628  if (otherGroupKey instanceof ParentPathGroupKey) {
629  ParentPathGroupKey otherParentPathGroupKey = (ParentPathGroupKey) otherGroupKey;
630  int comparisonResult = getParentPath().compareTo(otherParentPathGroupKey.getParentPath());
631  if (comparisonResult == 0) {
632  comparisonResult = getParentID().compareTo(otherParentPathGroupKey.getParentID());
633  }
634  return comparisonResult;
635  } else {
636  return compareClassNames(otherGroupKey);
637  }
638  }
639 
640  @Override
641  public boolean equals(Object otherKey) {
642  if (otherKey == this) {
643  return true;
644  }
645 
646  if (!(otherKey instanceof ParentPathGroupKey)) {
647  return false;
648  }
649 
650  ParentPathGroupKey otherParentPathGroupKey = (ParentPathGroupKey) otherKey;
651  return getParentPath().equals(otherParentPathGroupKey.getParentPath()) && getParentID().equals(otherParentPathGroupKey.getParentID());
652  }
653 
654  @Override
655  public int hashCode() {
656  int hashCode = 11;
657  hashCode = 61 * hashCode + Objects.hash(getParentPath());
658  hashCode = 61 * hashCode + Objects.hash(getParentID());
659  return hashCode;
660  }
661 
667  String getParentPath() {
668  return parentPath;
669  }
670 
676  Long getParentID() {
677  return parentID;
678  }
679  }
680 
684  static class DataSourceGroupKey extends GroupKey {
685 
686  private final long dataSourceID;
687  private String displayName;
688 
694  @NbBundle.Messages({
695  "# {0} - Data source name",
696  "# {1} - Data source ID",
697  "DiscoveryKeyUtils.DataSourceGroupKey.datasourceAndID={0}(ID: {1})",
698  "# {0} - Data source ID",
699  "DiscoveryKeyUtils.DataSourceGroupKey.idOnly=Data source (ID: {0})"})
700  DataSourceGroupKey(Result result) {
701  //get the id first so that it can be used when logging if necessary
702  dataSourceID = result.getDataSourceObjectId();
703  try {
704  // The data source should be cached so this won't actually be a database query.
705  Content ds = result.getDataSource();
706  displayName = Bundle.DiscoveryKeyUtils_DataSourceGroupKey_datasourceAndID(ds.getName(), ds.getId());
707  } catch (TskCoreException ex) {
708  logger.log(Level.WARNING, "Error looking up data source with ID " + dataSourceID, ex); // NON-NLS
709  displayName = Bundle.DiscoveryKeyUtils_DataSourceGroupKey_idOnly(dataSourceID);
710  }
711  }
712 
713  @Override
714  String getDisplayName() {
715  return displayName;
716  }
717 
718  @Override
719  public int compareTo(GroupKey otherGroupKey) {
720  if (otherGroupKey instanceof DataSourceGroupKey) {
721  DataSourceGroupKey otherDataSourceGroupKey = (DataSourceGroupKey) otherGroupKey;
722  return Long.compare(getDataSourceID(), otherDataSourceGroupKey.getDataSourceID());
723  } else {
724  return compareClassNames(otherGroupKey);
725  }
726  }
727 
728  @Override
729  public boolean equals(Object otherKey) {
730  if (otherKey == this) {
731  return true;
732  }
733 
734  if (!(otherKey instanceof DataSourceGroupKey)) {
735  return false;
736  }
737 
738  DataSourceGroupKey otherDataSourceGroupKey = (DataSourceGroupKey) otherKey;
739  return getDataSourceID() == otherDataSourceGroupKey.getDataSourceID();
740  }
741 
742  @Override
743  public int hashCode() {
744  return Objects.hash(getDataSourceID());
745  }
746 
752  long getDataSourceID() {
753  return dataSourceID;
754  }
755  }
756 
761  static class NoGroupingGroupKey extends GroupKey {
762 
766  NoGroupingGroupKey() {
767  // Nothing to save - all files will get the same GroupKey
768  }
769 
770  @NbBundle.Messages({
771  "DiscoveryKeyUtils.NoGroupingGroupKey.allFiles=All Files"})
772  @Override
773  String getDisplayName() {
774  return Bundle.DiscoveryKeyUtils_NoGroupingGroupKey_allFiles();
775  }
776 
777  @Override
778  public int compareTo(GroupKey otherGroupKey) {
779  // As long as the other key is the same type, they are equal
780  if (otherGroupKey instanceof NoGroupingGroupKey) {
781  return 0;
782  } else {
783  return compareClassNames(otherGroupKey);
784  }
785  }
786 
787  @Override
788  public boolean equals(Object otherKey) {
789  if (otherKey == this) {
790  return true;
791  }
792  // As long as the other key is the same type, they are equal
793  return otherKey instanceof NoGroupingGroupKey;
794  }
795 
796  @Override
797  public int hashCode() {
798  return 0;
799  }
800  }
801 
805  static class DomainCategoryGroupKey extends GroupKey {
806 
807  private final Set<String> webCategories = new HashSet<>();
808  private final String displayName;
809 
810  DomainCategoryGroupKey(Result result) {
811  if (result instanceof ResultDomain) {
812  ResultDomain domain = (ResultDomain) result;
813  this.webCategories.addAll(domain.getWebCategories());
814  displayName = String.join(",", webCategories);
815  } else {
816  throw new IllegalArgumentException("Input result should be of type ResultDomain");
817  }
818  }
819 
820  @Override
821  String getDisplayName() {
822 
823  return this.displayName;
824  }
825 
826  @Override
827  public boolean equals(Object otherKey) {
828  if (otherKey instanceof GroupKey) {
829  return compareTo((GroupKey) otherKey) == 0;
830  }
831  return false;
832  }
833 
834  @Override
835  public int hashCode() {
836  return Objects.hash(webCategories);
837  }
838 
839  @Override
840  public int compareTo(GroupKey otherGroupKey) {
841  if (otherGroupKey instanceof DomainCategoryGroupKey) {
842  if (webCategories.size() != ((DomainCategoryGroupKey) otherGroupKey).getWebCategories().size()) {
843  return 1;
844  }
845  if (webCategories.containsAll(((DomainCategoryGroupKey) otherGroupKey).getWebCategories())) {
846  return 0;
847  } else {
848  return -1;
849  }
850  } else {
851  return compareClassNames(otherGroupKey);
852  }
853  }
854 
855  Set<String> getWebCategories() {
856  return Collections.unmodifiableSet(webCategories);
857  }
858  }
859 
863  static class PreviouslyNotableGroupKey extends GroupKey {
864 
865  private final SearchData.PreviouslyNotable notableStatus;
866 
867  PreviouslyNotableGroupKey(Result result) {
868  this.notableStatus = result.getPreviouslyNotableInCR();
869  }
870 
871  @Override
872  String getDisplayName() {
873  return this.notableStatus.toString();
874  }
875 
876  @Override
877  public boolean equals(Object otherKey) {
878  if (otherKey instanceof GroupKey) {
879  return compareTo((GroupKey) otherKey) == 0;
880  }
881  return false;
882  }
883 
884  @Override
885  public int hashCode() {
886  return Objects.hash(getStatus().getRanking());
887  }
888 
889  @Override
890  public int compareTo(GroupKey otherGroupKey) {
891  if (otherGroupKey instanceof PreviouslyNotableGroupKey) {
892  PreviouslyNotableGroupKey otherFrequencyGroupKey = (PreviouslyNotableGroupKey) otherGroupKey;
893  return Integer.compare(getStatus().getRanking(), otherFrequencyGroupKey.getStatus().getRanking());
894  } else {
895  return compareClassNames(otherGroupKey);
896  }
897  }
898 
899  SearchData.PreviouslyNotable getStatus() {
900  return notableStatus;
901  }
902  }
903 
907  static class FrequencyGroupKey extends GroupKey {
908 
909  private final SearchData.Frequency frequency;
910 
916  FrequencyGroupKey(Result result) {
917  frequency = result.getFrequency();
918  }
919 
920  @Override
921  String getDisplayName() {
922  return getFrequency().toString();
923  }
924 
925  @Override
926  public int compareTo(GroupKey otherGroupKey) {
927  if (otherGroupKey instanceof FrequencyGroupKey) {
928  FrequencyGroupKey otherFrequencyGroupKey = (FrequencyGroupKey) otherGroupKey;
929  return Integer.compare(getFrequency().getRanking(), otherFrequencyGroupKey.getFrequency().getRanking());
930  } else {
931  return compareClassNames(otherGroupKey);
932  }
933  }
934 
935  @Override
936  public boolean equals(Object otherKey) {
937  if (otherKey == this) {
938  return true;
939  }
940 
941  if (!(otherKey instanceof FrequencyGroupKey)) {
942  return false;
943  }
944 
945  FrequencyGroupKey otherFrequencyGroupKey = (FrequencyGroupKey) otherKey;
946  return getFrequency().equals(otherFrequencyGroupKey.getFrequency());
947  }
948 
949  @Override
950  public int hashCode() {
951  return Objects.hash(getFrequency().getRanking());
952  }
953 
959  SearchData.Frequency getFrequency() {
960  return frequency;
961  }
962  }
963 
967  static class HashHitsGroupKey extends GroupKey {
968 
969  private final List<String> hashSetNames;
970  private final String hashSetNamesString;
971 
977  @NbBundle.Messages({
978  "DiscoveryKeyUtils.HashHitsGroupKey.noHashHits=None"})
979  HashHitsGroupKey(ResultFile file) {
980  hashSetNames = file.getHashSetNames();
981 
982  if (hashSetNames.isEmpty()) {
983  hashSetNamesString = Bundle.DiscoveryKeyUtils_HashHitsGroupKey_noHashHits();
984  } else {
985  hashSetNamesString = String.join(",", hashSetNames); // NON-NLS
986  }
987  }
988 
989  @Override
990  String getDisplayName() {
991  return getHashSetNamesString();
992  }
993 
994  @Override
995  public int compareTo(GroupKey otherGroupKey) {
996  if (otherGroupKey instanceof HashHitsGroupKey) {
997  HashHitsGroupKey otherHashHitsGroupKey = (HashHitsGroupKey) otherGroupKey;
998 
999  // Put the empty list at the end
1000  if (getHashSetNames().isEmpty()) {
1001  if (otherHashHitsGroupKey.getHashSetNames().isEmpty()) {
1002  return 0;
1003  } else {
1004  return 1;
1005  }
1006  } else if (otherHashHitsGroupKey.getHashSetNames().isEmpty()) {
1007  return -1;
1008  }
1009 
1010  return getHashSetNamesString().compareTo(otherHashHitsGroupKey.getHashSetNamesString());
1011  } else {
1012  return compareClassNames(otherGroupKey);
1013  }
1014  }
1015 
1016  @Override
1017  public boolean equals(Object otherKey) {
1018  if (otherKey == this) {
1019  return true;
1020  }
1021 
1022  if (!(otherKey instanceof HashHitsGroupKey)) {
1023  return false;
1024  }
1025 
1026  HashHitsGroupKey otherHashHitsGroupKey = (HashHitsGroupKey) otherKey;
1027  return getHashSetNamesString().equals(otherHashHitsGroupKey.getHashSetNamesString());
1028  }
1029 
1030  @Override
1031  public int hashCode() {
1032  return Objects.hash(getHashSetNamesString());
1033  }
1034 
1040  List<String> getHashSetNames() {
1041  return Collections.unmodifiableList(hashSetNames);
1042  }
1043 
1049  String getHashSetNamesString() {
1050  return hashSetNamesString;
1051  }
1052  }
1053 
1057  static class InterestingItemGroupKey extends GroupKey {
1058 
1059  private final List<String> interestingItemSetNames;
1060  private final String interestingItemSetNamesString;
1061 
1067  @NbBundle.Messages({
1068  "DiscoveryKeyUtils.InterestingItemGroupKey.noSets=None"})
1069  InterestingItemGroupKey(ResultFile file) {
1070  interestingItemSetNames = file.getInterestingSetNames();
1071 
1072  if (interestingItemSetNames.isEmpty()) {
1073  interestingItemSetNamesString = Bundle.DiscoveryKeyUtils_InterestingItemGroupKey_noSets();
1074  } else {
1075  interestingItemSetNamesString = String.join(",", interestingItemSetNames); // NON-NLS
1076  }
1077  }
1078 
1079  @Override
1080  String getDisplayName() {
1081  return getInterestingItemSetNamesString();
1082  }
1083 
1084  @Override
1085  public int compareTo(GroupKey otherGroupKey) {
1086  if (otherGroupKey instanceof InterestingItemGroupKey) {
1087  InterestingItemGroupKey otherInterestingItemGroupKey = (InterestingItemGroupKey) otherGroupKey;
1088 
1089  // Put the empty list at the end
1090  if (this.getInterestingItemSetNames().isEmpty()) {
1091  if (otherInterestingItemGroupKey.getInterestingItemSetNames().isEmpty()) {
1092  return 0;
1093  } else {
1094  return 1;
1095  }
1096  } else if (otherInterestingItemGroupKey.getInterestingItemSetNames().isEmpty()) {
1097  return -1;
1098  }
1099 
1100  return getInterestingItemSetNamesString().compareTo(otherInterestingItemGroupKey.getInterestingItemSetNamesString());
1101  } else {
1102  return compareClassNames(otherGroupKey);
1103  }
1104  }
1105 
1106  @Override
1107  public boolean equals(Object otherKey) {
1108  if (otherKey == this) {
1109  return true;
1110  }
1111 
1112  if (!(otherKey instanceof InterestingItemGroupKey)) {
1113  return false;
1114  }
1115 
1116  InterestingItemGroupKey otherInterestingItemGroupKey = (InterestingItemGroupKey) otherKey;
1117  return getInterestingItemSetNamesString().equals(otherInterestingItemGroupKey.getInterestingItemSetNamesString());
1118  }
1119 
1120  @Override
1121  public int hashCode() {
1122  return Objects.hash(getInterestingItemSetNamesString());
1123  }
1124 
1130  List<String> getInterestingItemSetNames() {
1131  return Collections.unmodifiableList(interestingItemSetNames);
1132  }
1133 
1141  String getInterestingItemSetNamesString() {
1142  return interestingItemSetNamesString;
1143  }
1144  }
1145 
1149  static class LastActivityDateGroupKey extends GroupKey {
1150 
1151  private ZonedDateTime currentWeekCutOff;
1152 
1158  LastActivityDateGroupKey(Result result) {
1159  if (result instanceof ResultDomain) {
1160  ResultDomain domainResult = ((ResultDomain) result);
1161  currentWeekCutOff = getCurrentWeekCutOff(domainResult.getActivityEnd(), domainResult);
1162  } else {
1163  throw new IllegalArgumentException("Expected a domain result only.");
1164  }
1165  }
1166 
1167  @NbBundle.Messages({
1168  "# {0} - month abbreviation",
1169  "# {1} - day of month",
1170  "# {2} - year",
1171  "DiscoveryAttributes.ActivityDateGroupKey.getDisplayNameTemplate=Week of {0} {1}, {2}"
1172  })
1173  @Override
1174  String getDisplayName() {
1175  MonthAbbreviation currentCutOffMonth = MonthAbbreviation.fromMonthValue(currentWeekCutOff.getMonthValue());
1176  return Bundle.DiscoveryAttributes_ActivityDateGroupKey_getDisplayNameTemplate(
1177  currentCutOffMonth.toString(), Integer.toString(currentWeekCutOff.getDayOfMonth()),
1178  Integer.toString(currentWeekCutOff.getYear()));
1179  }
1180 
1181  @Override
1182  public boolean equals(Object otherKey) {
1183  if (otherKey == this) {
1184  return true;
1185  }
1186 
1187  if (!(otherKey instanceof LastActivityDateGroupKey)) {
1188  return false;
1189  }
1190 
1191  LastActivityDateGroupKey dateGroupKey = (LastActivityDateGroupKey) otherKey;
1192  return getDisplayName().equals(dateGroupKey.getDisplayName());
1193  }
1194 
1195  @Override
1196  public int hashCode() {
1197  return Objects.hash(getDisplayName());
1198  }
1199 
1200  @Override
1201  public int compareTo(GroupKey otherGroupKey) {
1202  if (otherGroupKey instanceof LastActivityDateGroupKey) {
1203  LastActivityDateGroupKey otherDateGroupKey = (LastActivityDateGroupKey) otherGroupKey;
1204  return Long.compare(otherDateGroupKey.currentWeekCutOff.toEpochSecond(), currentWeekCutOff.toEpochSecond());
1205  } else {
1206  return compareClassNames(otherGroupKey);
1207  }
1208  }
1209  }
1210 
1216  private static ZonedDateTime getCurrentWeekCutOff(long epochSeconds, ResultDomain domainResult) {
1217  Instant startActivityAsInsant = Instant.ofEpochSecond(epochSeconds);
1218  // Determines the timezone using the settings panel or value parsed from the
1219  // parent data source
1220  TimeZone currentTimeZone = TimeZoneUtils.getTimeZone();
1221  // Convert to a datetime using epoch and timezone.
1222  ZonedDateTime startActivityAsDateTime = ZonedDateTime.ofInstant(startActivityAsInsant, currentTimeZone.toZoneId());
1223  // Get the closest Sunday, which is the cut off for the current week.
1224  // Use this cut off to perform grouping and comparing.
1225  return startActivityAsDateTime.with(TemporalAdjusters.nextOrSame(DayOfWeek.SUNDAY));
1226  }
1227 
1231  static class FirstActivityDateGroupKey extends GroupKey {
1232 
1233  private ZonedDateTime currentWeekCutOff;
1234 
1240  FirstActivityDateGroupKey(Result result) {
1241  if (result instanceof ResultDomain) {
1242  ResultDomain domainResult = ((ResultDomain) result);
1243  currentWeekCutOff = getCurrentWeekCutOff(domainResult.getActivityStart(), domainResult);
1244  } else {
1245  throw new IllegalArgumentException("Expected a domain result only.");
1246  }
1247  }
1248 
1249  @Override
1250  String getDisplayName() {
1251  MonthAbbreviation currentCutOffMonth = MonthAbbreviation.fromMonthValue(currentWeekCutOff.getMonthValue());
1252  return Bundle.DiscoveryAttributes_ActivityDateGroupKey_getDisplayNameTemplate(
1253  currentCutOffMonth.toString(), Integer.toString(currentWeekCutOff.getDayOfMonth()),
1254  Integer.toString(currentWeekCutOff.getYear()));
1255  }
1256 
1257  @Override
1258  public boolean equals(Object otherKey) {
1259  if (otherKey == this) {
1260  return true;
1261  }
1262 
1263  if (!(otherKey instanceof FirstActivityDateGroupKey)) {
1264  return false;
1265  }
1266 
1267  FirstActivityDateGroupKey dateGroupKey = (FirstActivityDateGroupKey) otherKey;
1268  return getDisplayName().equals(dateGroupKey.getDisplayName());
1269  }
1270 
1271  @Override
1272  public int hashCode() {
1273  return Objects.hash(getDisplayName());
1274  }
1275 
1276  @Override
1277  public int compareTo(GroupKey otherGroupKey) {
1278  if (otherGroupKey instanceof FirstActivityDateGroupKey) {
1279  FirstActivityDateGroupKey otherDateGroupKey = (FirstActivityDateGroupKey) otherGroupKey;
1280  return Long.compare(otherDateGroupKey.currentWeekCutOff.toEpochSecond(), currentWeekCutOff.toEpochSecond());
1281  } else {
1282  return compareClassNames(otherGroupKey);
1283  }
1284  }
1285  }
1286 
1291  static class PageViewsGroupKey extends GroupKey {
1292 
1293  private final String displayName;
1294  private final PageViews pageViews;
1295 
1301  PageViewsGroupKey(Result result) {
1302  if (result instanceof ResultDomain) {
1303  Long totalPageViews = ((ResultDomain) result).getTotalPageViews();
1304  if (totalPageViews == null) {
1305  totalPageViews = 0L;
1306  }
1307  pageViews = PageViews.fromPageViewCount(totalPageViews);
1308  displayName = pageViews.toString();
1309  } else {
1310  throw new IllegalArgumentException("Expected a domain instance only.");
1311  }
1312  }
1313 
1314  @Override
1315  String getDisplayName() {
1316  return displayName;
1317  }
1318 
1319  @Override
1320  public int hashCode() {
1321  return Objects.hash(displayName);
1322  }
1323 
1329  PageViews getPageViews() {
1330  return pageViews;
1331  }
1332 
1333  @Override
1334  public boolean equals(Object otherKey) {
1335  if (otherKey == this) {
1336  return true;
1337  }
1338 
1339  if (!(otherKey instanceof PageViewsGroupKey)) {
1340  return false;
1341  }
1342 
1343  PageViewsGroupKey pageViewsKey = (PageViewsGroupKey) otherKey;
1344  return pageViews.equals(pageViewsKey.getPageViews());
1345  }
1346 
1347  @Override
1348  public int compareTo(GroupKey otherGroupKey) {
1349  if (otherGroupKey instanceof PageViewsGroupKey) {
1350  PageViewsGroupKey pageViewsKey = (PageViewsGroupKey) otherGroupKey;
1351  return getPageViews().compareTo(pageViewsKey.getPageViews());
1352  } else {
1353  return compareClassNames(otherGroupKey);
1354  }
1355  }
1356  }
1357 
1361  static class ObjectDetectedGroupKey extends GroupKey {
1362 
1363  private final List<String> objectDetectedNames;
1364  private final String objectDetectedNamesString;
1365 
1371  @NbBundle.Messages({
1372  "DiscoveryKeyUtils.ObjectDetectedGroupKey.noSets=None"})
1373  ObjectDetectedGroupKey(ResultFile file) {
1374  objectDetectedNames = file.getObjectDetectedNames();
1375  if (objectDetectedNames.isEmpty()) {
1376  objectDetectedNamesString = Bundle.DiscoveryKeyUtils_ObjectDetectedGroupKey_noSets();
1377  } else {
1378  objectDetectedNamesString = String.join(",", objectDetectedNames); // NON-NLS
1379  }
1380  }
1381 
1382  @Override
1383  String getDisplayName() {
1384  return getObjectDetectedNamesString();
1385  }
1386 
1387  @Override
1388  public int compareTo(GroupKey otherGroupKey) {
1389  if (otherGroupKey instanceof ObjectDetectedGroupKey) {
1390  ObjectDetectedGroupKey otherObjectDetectedGroupKey = (ObjectDetectedGroupKey) otherGroupKey;
1391 
1392  // Put the empty list at the end
1393  if (this.getObjectDetectedNames().isEmpty()) {
1394  if (otherObjectDetectedGroupKey.getObjectDetectedNames().isEmpty()) {
1395  return 0;
1396  } else {
1397  return 1;
1398  }
1399  } else if (otherObjectDetectedGroupKey.getObjectDetectedNames().isEmpty()) {
1400  return -1;
1401  }
1402 
1403  return getObjectDetectedNamesString().compareTo(otherObjectDetectedGroupKey.getObjectDetectedNamesString());
1404  } else {
1405  return compareClassNames(otherGroupKey);
1406  }
1407  }
1408 
1409  @Override
1410  public boolean equals(Object otherKey) {
1411  if (otherKey == this) {
1412  return true;
1413  }
1414 
1415  if (!(otherKey instanceof ObjectDetectedGroupKey)) {
1416  return false;
1417  }
1418 
1419  ObjectDetectedGroupKey otherObjectDetectedGroupKey = (ObjectDetectedGroupKey) otherKey;
1420  return getObjectDetectedNamesString().equals(otherObjectDetectedGroupKey.getObjectDetectedNamesString());
1421  }
1422 
1423  @Override
1424  public int hashCode() {
1425  return Objects.hash(getObjectDetectedNamesString());
1426  }
1427 
1433  List<String> getObjectDetectedNames() {
1434  return Collections.unmodifiableList(objectDetectedNames);
1435  }
1436 
1444  String getObjectDetectedNamesString() {
1445  return objectDetectedNamesString;
1446  }
1447  }
1448 
1452  private DiscoveryKeyUtils() {
1453  //private constructor in a utility class intentionally left blank
1454  }
1455 }
FileSize(int ranking, long minB, long maxB, String displayName, String displaySize)
synchronized static Logger getLogger(String name)
Definition: Logger.java:124
static ZonedDateTime getCurrentWeekCutOff(long epochSeconds, ResultDomain domainResult)

Copyright © 2012-2021 Basis Technology. Generated on: Fri Aug 6 2021
This work is licensed under a Creative Commons Attribution-Share Alike 3.0 United States License.