Autopsy  4.20.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  private final SearchContext context;
63 
78  SearchKey(String userName, List<AbstractFilter> filters,
79  DiscoveryAttributes.AttributeType groupAttributeType,
80  Group.GroupSortingAlgorithm groupSortingType,
81  ResultsSorter.SortingMethod sortingMethod,
82  SleuthkitCase sleuthkitCase, CentralRepository centralRepository, SearchContext context) {
83  this.groupAttributeType = groupAttributeType;
84  this.groupSortingType = groupSortingType;
85  this.sortingMethod = sortingMethod;
86  this.filters = filters;
87  this.context = context;
88 
89  StringBuilder searchStringBuilder = new StringBuilder();
90  searchStringBuilder.append(userName);
91  for (AbstractFilter filter : filters) {
92  searchStringBuilder.append(filter.toString());
93  }
94  searchStringBuilder.append(groupAttributeType).append(groupSortingType).append(sortingMethod);
95  keyString = searchStringBuilder.toString();
96  this.sleuthkitCase = sleuthkitCase;
97  this.centralRepository = centralRepository;
98  }
99 
110  SearchKey(String userName, List<AbstractFilter> filters,
111  DiscoveryAttributes.AttributeType groupAttributeType,
112  Group.GroupSortingAlgorithm groupSortingType,
113  ResultsSorter.SortingMethod sortingMethod) {
114  this(userName, filters, groupAttributeType, groupSortingType,
115  sortingMethod, null, null, null);
116  //this constructor should only be used putting things directly into a map or getting if present since casedb, cr, and search context will be null
117  }
118 
119  @Override
120  public int compareTo(SearchKey otherSearchKey) {
121  return getKeyString().compareTo(otherSearchKey.getKeyString());
122  }
123 
124  @Override
125  public boolean equals(Object otherKey) {
126  if (otherKey == this) {
127  return true;
128  }
129 
130  if (!(otherKey instanceof SearchKey)) {
131  return false;
132  }
133 
134  SearchKey otherSearchKey = (SearchKey) otherKey;
135  if (this.sleuthkitCase != otherSearchKey.getSleuthkitCase()
136  || this.centralRepository != otherSearchKey.getCentralRepository()) {
137  return false;
138  }
139 
140  return getKeyString().equals(otherSearchKey.getKeyString());
141  }
142 
143  @Override
144  public int hashCode() {
145  int hash = 5;
146  hash = 79 * hash + Objects.hashCode(getKeyString());
147  return hash;
148  }
149 
160  SearchContext getContext() throws DiscoveryException {
161  if (context == null) {
162  throw new DiscoveryException("The key in use was created without a context and does not support retrieving information from the databases.");
163  }
164  return context;
165  }
166 
172  String getKeyString() {
173  return keyString;
174  }
175 
181  List<AbstractFilter> getFilters() {
182  return Collections.unmodifiableList(this.filters);
183  }
184 
190  Group.GroupSortingAlgorithm getGroupSortingType() {
191  return groupSortingType;
192  }
193 
199  DiscoveryAttributes.AttributeType getGroupAttributeType() {
200  return groupAttributeType;
201  }
202 
208  ResultsSorter.SortingMethod getFileSortingMethod() {
209  return sortingMethod;
210  }
211 
217  SleuthkitCase getSleuthkitCase() {
218  return this.sleuthkitCase;
219  }
220 
226  CentralRepository getCentralRepository() {
227  return this.centralRepository;
228  }
229  }
230 
234  public abstract static class GroupKey implements Comparable<GroupKey> {
235 
242  abstract String getDisplayName();
243 
251  @Override
252  abstract public boolean equals(Object otherKey);
253 
259  @Override
260  abstract public int hashCode();
261 
271  int compareClassNames(GroupKey otherGroupKey) {
272  return this.getClass().getName().compareTo(otherGroupKey.getClass().getName());
273  }
274 
275  @Override
276  public String toString() {
277  return getDisplayName();
278  }
279  }
280 
284  static class FileSizeGroupKey extends GroupKey {
285 
286  private final SearchData.FileSize fileSize;
287 
293  FileSizeGroupKey(Result file) {
294  ResultFile resultFile = (ResultFile) file;
295  if (resultFile.getFileType() == SearchData.Type.VIDEO) {
296  fileSize = SearchData.FileSize.fromVideoSize(resultFile.getFirstInstance().getSize());
297  } else {
298  fileSize = SearchData.FileSize.fromImageSize(resultFile.getFirstInstance().getSize());
299  }
300  }
301 
302  @Override
303  String getDisplayName() {
304  return getFileSize().toString();
305  }
306 
307  @Override
308  public int compareTo(GroupKey otherGroupKey) {
309  if (otherGroupKey instanceof FileSizeGroupKey) {
310  FileSizeGroupKey otherFileSizeGroupKey = (FileSizeGroupKey) otherGroupKey;
311  return Integer.compare(getFileSize().getRanking(), otherFileSizeGroupKey.getFileSize().getRanking());
312  } else {
313  return compareClassNames(otherGroupKey);
314  }
315  }
316 
317  @Override
318  public boolean equals(Object otherKey) {
319  if (otherKey == this) {
320  return true;
321  }
322 
323  if (!(otherKey instanceof FileSizeGroupKey)) {
324  return false;
325  }
326 
327  FileSizeGroupKey otherFileSizeGroupKey = (FileSizeGroupKey) otherKey;
328  return getFileSize().equals(otherFileSizeGroupKey.getFileSize());
329  }
330 
331  @Override
332  public int hashCode() {
333  return Objects.hash(getFileSize().getRanking());
334  }
335 
341  SearchData.FileSize getFileSize() {
342  return fileSize;
343  }
344  }
345 
349  static class FileTypeGroupKey extends GroupKey {
350 
351  private final SearchData.Type fileType;
352 
358  FileTypeGroupKey(Result file) {
359  fileType = ((ResultFile) file).getFileType();
360  }
361 
362  @Override
363  String getDisplayName() {
364  return getFileType().toString();
365  }
366 
367  @Override
368  public int compareTo(GroupKey otherGroupKey) {
369  if (otherGroupKey instanceof FileTypeGroupKey) {
370  FileTypeGroupKey otherFileTypeGroupKey = (FileTypeGroupKey) otherGroupKey;
371  return Integer.compare(getFileType().getRanking(), otherFileTypeGroupKey.getFileType().getRanking());
372  } else {
373  return compareClassNames(otherGroupKey);
374  }
375  }
376 
377  @Override
378  public boolean equals(Object otherKey) {
379  if (otherKey == this) {
380  return true;
381  }
382 
383  if (!(otherKey instanceof FileTypeGroupKey)) {
384  return false;
385  }
386 
387  FileTypeGroupKey otherFileTypeGroupKey = (FileTypeGroupKey) otherKey;
388  return getFileType().equals(otherFileTypeGroupKey.getFileType());
389  }
390 
391  @Override
392  public int hashCode() {
393  return Objects.hash(getFileType().getRanking());
394  }
395 
401  SearchData.Type getFileType() {
402  return fileType;
403  }
404  }
405 
409  static class KeywordListGroupKey extends GroupKey {
410 
411  private final List<String> keywordListNames;
412  private final String keywordListNamesString;
413 
419  @NbBundle.Messages({
420  "DiscoveryKeyUtils.KeywordListGroupKey.noKeywords=None"})
421  KeywordListGroupKey(ResultFile file) {
422  keywordListNames = file.getKeywordListNames();
423  if (keywordListNames.isEmpty()) {
424  keywordListNamesString = Bundle.DiscoveryKeyUtils_KeywordListGroupKey_noKeywords();
425  } else {
426  keywordListNamesString = String.join(",", keywordListNames); // NON-NLS
427  }
428  }
429 
430  @Override
431  String getDisplayName() {
432  return getKeywordListNamesString();
433  }
434 
435  @Override
436  public int compareTo(GroupKey otherGroupKey) {
437  if (otherGroupKey instanceof KeywordListGroupKey) {
438  KeywordListGroupKey otherKeywordListNamesGroupKey = (KeywordListGroupKey) otherGroupKey;
439 
440  // Put the empty list at the end
441  if (getKeywordListNames().isEmpty()) {
442  if (otherKeywordListNamesGroupKey.getKeywordListNames().isEmpty()) {
443  return 0;
444  } else {
445  return 1;
446  }
447  } else if (otherKeywordListNamesGroupKey.getKeywordListNames().isEmpty()) {
448  return -1;
449  }
450 
451  return getKeywordListNamesString().compareTo(otherKeywordListNamesGroupKey.getKeywordListNamesString());
452  } else {
453  return compareClassNames(otherGroupKey);
454  }
455  }
456 
457  @Override
458  public boolean equals(Object otherKey) {
459  if (otherKey == this) {
460  return true;
461  }
462 
463  if (!(otherKey instanceof KeywordListGroupKey)) {
464  return false;
465  }
466 
467  KeywordListGroupKey otherKeywordListGroupKey = (KeywordListGroupKey) otherKey;
468  return getKeywordListNamesString().equals(otherKeywordListGroupKey.getKeywordListNamesString());
469  }
470 
471  @Override
472  public int hashCode() {
473  return Objects.hash(getKeywordListNamesString());
474  }
475 
481  List<String> getKeywordListNames() {
482  return Collections.unmodifiableList(keywordListNames);
483  }
484 
492  String getKeywordListNamesString() {
493  return keywordListNamesString;
494  }
495  }
496 
500  static class FileTagGroupKey extends GroupKey {
501 
502  private final List<String> tagNames;
503  private final String tagNamesString;
504 
510  @NbBundle.Messages({
511  "DiscoveryKeyUtils.FileTagGroupKey.noSets=None"})
512  FileTagGroupKey(ResultFile file) {
513  tagNames = file.getTagNames();
514 
515  if (tagNames.isEmpty()) {
516  tagNamesString = Bundle.DiscoveryKeyUtils_FileTagGroupKey_noSets();
517  } else {
518  tagNamesString = String.join(",", tagNames); // NON-NLS
519  }
520  }
521 
522  @Override
523  String getDisplayName() {
524  return getTagNamesString();
525  }
526 
527  @Override
528  public int compareTo(GroupKey otherGroupKey) {
529  if (otherGroupKey instanceof FileTagGroupKey) {
530  FileTagGroupKey otherFileTagGroupKey = (FileTagGroupKey) otherGroupKey;
531 
532  // Put the empty list at the end
533  if (getTagNames().isEmpty()) {
534  if (otherFileTagGroupKey.getTagNames().isEmpty()) {
535  return 0;
536  } else {
537  return 1;
538  }
539  } else if (otherFileTagGroupKey.getTagNames().isEmpty()) {
540  return -1;
541  }
542 
543  return getTagNamesString().compareTo(otherFileTagGroupKey.getTagNamesString());
544  } else {
545  return compareClassNames(otherGroupKey);
546  }
547  }
548 
549  @Override
550  public boolean equals(Object otherKey) {
551  if (otherKey == this) {
552  return true;
553  }
554  if (!(otherKey instanceof FileTagGroupKey)) {
555  return false;
556  }
557  FileTagGroupKey otherFileTagGroupKey = (FileTagGroupKey) otherKey;
558  return getTagNamesString().equals(otherFileTagGroupKey.getTagNamesString());
559  }
560 
561  @Override
562  public int hashCode() {
563  return Objects.hash(getTagNamesString());
564  }
565 
571  List<String> getTagNames() {
572  return Collections.unmodifiableList(tagNames);
573  }
574 
582  String getTagNamesString() {
583  return tagNamesString;
584  }
585  }
586 
590  static class ParentPathGroupKey extends GroupKey {
591 
592  private String parentPath;
593  private Long parentID;
594 
600  ParentPathGroupKey(ResultFile file) {
601  Content parent;
602  try {
603  parent = file.getFirstInstance().getParent();
604  } catch (TskCoreException ignored) {
605  parent = null;
606  }
607  //Find the directory this file is in if it is an embedded file
608  while (parent != null && parent instanceof AbstractFile && ((AbstractFile) parent).isFile()) {
609  try {
610  parent = parent.getParent();
611  } catch (TskCoreException ignored) {
612  parent = null;
613  }
614  }
615  setParentPathAndID(parent, file);
616  }
617 
624  private void setParentPathAndID(Content parent, ResultFile file) {
625  if (parent != null) {
626  try {
627  parentPath = parent.getUniquePath();
628  parentID = parent.getId();
629  } catch (TskCoreException ignored) {
630  //catch block left blank purposefully next if statement will handle case when exception takes place as well as when parent is null
631  }
632 
633  }
634  if (parentPath == null) {
635  if (file.getFirstInstance().getParentPath() != null) {
636  parentPath = file.getFirstInstance().getParentPath();
637  } else {
638  parentPath = ""; // NON-NLS
639  }
640  parentID = -1L;
641  }
642  }
643 
644  @Override
645  String getDisplayName() {
646  return getParentPath();
647  }
648 
649  @Override
650  public int compareTo(GroupKey otherGroupKey) {
651  if (otherGroupKey instanceof ParentPathGroupKey) {
652  ParentPathGroupKey otherParentPathGroupKey = (ParentPathGroupKey) otherGroupKey;
653  int comparisonResult = getParentPath().compareTo(otherParentPathGroupKey.getParentPath());
654  if (comparisonResult == 0) {
655  comparisonResult = getParentID().compareTo(otherParentPathGroupKey.getParentID());
656  }
657  return comparisonResult;
658  } else {
659  return compareClassNames(otherGroupKey);
660  }
661  }
662 
663  @Override
664  public boolean equals(Object otherKey) {
665  if (otherKey == this) {
666  return true;
667  }
668 
669  if (!(otherKey instanceof ParentPathGroupKey)) {
670  return false;
671  }
672 
673  ParentPathGroupKey otherParentPathGroupKey = (ParentPathGroupKey) otherKey;
674  return getParentPath().equals(otherParentPathGroupKey.getParentPath()) && getParentID().equals(otherParentPathGroupKey.getParentID());
675  }
676 
677  @Override
678  public int hashCode() {
679  int hashCode = 11;
680  hashCode = 61 * hashCode + Objects.hash(getParentPath());
681  hashCode = 61 * hashCode + Objects.hash(getParentID());
682  return hashCode;
683  }
684 
690  String getParentPath() {
691  return parentPath;
692  }
693 
699  Long getParentID() {
700  return parentID;
701  }
702  }
703 
707  static class DataSourceGroupKey extends GroupKey {
708 
709  private final long dataSourceID;
710  private String displayName;
711 
717  @NbBundle.Messages({
718  "# {0} - Data source name",
719  "# {1} - Data source ID",
720  "DiscoveryKeyUtils.DataSourceGroupKey.datasourceAndID={0}(ID: {1})",
721  "# {0} - Data source ID",
722  "DiscoveryKeyUtils.DataSourceGroupKey.idOnly=Data source (ID: {0})"})
723  DataSourceGroupKey(Result result) {
724  //get the id first so that it can be used when logging if necessary
725  dataSourceID = result.getDataSourceObjectId();
726  try {
727  // The data source should be cached so this won't actually be a database query.
728  Content ds = result.getDataSource();
729  displayName = Bundle.DiscoveryKeyUtils_DataSourceGroupKey_datasourceAndID(ds.getName(), ds.getId());
730  } catch (TskCoreException ex) {
731  logger.log(Level.WARNING, "Error looking up data source with ID " + dataSourceID, ex); // NON-NLS
732  displayName = Bundle.DiscoveryKeyUtils_DataSourceGroupKey_idOnly(dataSourceID);
733  }
734  }
735 
736  @Override
737  String getDisplayName() {
738  return displayName;
739  }
740 
741  @Override
742  public int compareTo(GroupKey otherGroupKey) {
743  if (otherGroupKey instanceof DataSourceGroupKey) {
744  DataSourceGroupKey otherDataSourceGroupKey = (DataSourceGroupKey) otherGroupKey;
745  return Long.compare(getDataSourceID(), otherDataSourceGroupKey.getDataSourceID());
746  } else {
747  return compareClassNames(otherGroupKey);
748  }
749  }
750 
751  @Override
752  public boolean equals(Object otherKey) {
753  if (otherKey == this) {
754  return true;
755  }
756 
757  if (!(otherKey instanceof DataSourceGroupKey)) {
758  return false;
759  }
760 
761  DataSourceGroupKey otherDataSourceGroupKey = (DataSourceGroupKey) otherKey;
762  return getDataSourceID() == otherDataSourceGroupKey.getDataSourceID();
763  }
764 
765  @Override
766  public int hashCode() {
767  return Objects.hash(getDataSourceID());
768  }
769 
775  long getDataSourceID() {
776  return dataSourceID;
777  }
778  }
779 
784  static class NoGroupingGroupKey extends GroupKey {
785 
789  NoGroupingGroupKey() {
790  // Nothing to save - all files will get the same GroupKey
791  }
792 
793  @NbBundle.Messages({
794  "DiscoveryKeyUtils.NoGroupingGroupKey.allFiles=All Files"})
795  @Override
796  String getDisplayName() {
797  return Bundle.DiscoveryKeyUtils_NoGroupingGroupKey_allFiles();
798  }
799 
800  @Override
801  public int compareTo(GroupKey otherGroupKey) {
802  // As long as the other key is the same type, they are equal
803  if (otherGroupKey instanceof NoGroupingGroupKey) {
804  return 0;
805  } else {
806  return compareClassNames(otherGroupKey);
807  }
808  }
809 
810  @Override
811  public boolean equals(Object otherKey) {
812  if (otherKey == this) {
813  return true;
814  }
815  // As long as the other key is the same type, they are equal
816  return otherKey instanceof NoGroupingGroupKey;
817  }
818 
819  @Override
820  public int hashCode() {
821  return 0;
822  }
823  }
824 
828  static class DomainCategoryGroupKey extends GroupKey {
829 
830  private final Set<String> webCategories = new HashSet<>();
831  private final String displayName;
832 
833  DomainCategoryGroupKey(Result result) {
834  if (result instanceof ResultDomain) {
835  ResultDomain domain = (ResultDomain) result;
836  this.webCategories.addAll(domain.getWebCategories());
837  displayName = String.join(",", webCategories);
838  } else {
839  throw new IllegalArgumentException("Input result should be of type ResultDomain");
840  }
841  }
842 
843  @Override
844  String getDisplayName() {
845 
846  return this.displayName;
847  }
848 
849  @Override
850  public boolean equals(Object otherKey) {
851  if (otherKey instanceof GroupKey) {
852  return compareTo((GroupKey) otherKey) == 0;
853  }
854  return false;
855  }
856 
857  @Override
858  public int hashCode() {
859  return Objects.hash(webCategories);
860  }
861 
862  @Override
863  public int compareTo(GroupKey otherGroupKey) {
864  if (otherGroupKey instanceof DomainCategoryGroupKey) {
865  if (webCategories.size() != ((DomainCategoryGroupKey) otherGroupKey).getWebCategories().size()) {
866  return 1;
867  }
868  if (webCategories.containsAll(((DomainCategoryGroupKey) otherGroupKey).getWebCategories())) {
869  return 0;
870  } else {
871  return -1;
872  }
873  } else {
874  return compareClassNames(otherGroupKey);
875  }
876  }
877 
878  Set<String> getWebCategories() {
879  return Collections.unmodifiableSet(webCategories);
880  }
881  }
882 
886  static class PreviouslyNotableGroupKey extends GroupKey {
887 
888  private final SearchData.PreviouslyNotable notableStatus;
889 
890  PreviouslyNotableGroupKey(Result result) {
891  this.notableStatus = result.getPreviouslyNotableInCR();
892  }
893 
894  @Override
895  String getDisplayName() {
896  return this.notableStatus.toString();
897  }
898 
899  @Override
900  public boolean equals(Object otherKey) {
901  if (otherKey instanceof GroupKey) {
902  return compareTo((GroupKey) otherKey) == 0;
903  }
904  return false;
905  }
906 
907  @Override
908  public int hashCode() {
909  return Objects.hash(getStatus().getRanking());
910  }
911 
912  @Override
913  public int compareTo(GroupKey otherGroupKey) {
914  if (otherGroupKey instanceof PreviouslyNotableGroupKey) {
915  PreviouslyNotableGroupKey otherFrequencyGroupKey = (PreviouslyNotableGroupKey) otherGroupKey;
916  return Integer.compare(getStatus().getRanking(), otherFrequencyGroupKey.getStatus().getRanking());
917  } else {
918  return compareClassNames(otherGroupKey);
919  }
920  }
921 
922  SearchData.PreviouslyNotable getStatus() {
923  return notableStatus;
924  }
925  }
926 
930  static class FrequencyGroupKey extends GroupKey {
931 
932  private final SearchData.Frequency frequency;
933 
939  FrequencyGroupKey(Result result) {
940  frequency = result.getFrequency();
941  }
942 
943  @Override
944  String getDisplayName() {
945  return getFrequency().toString();
946  }
947 
948  @Override
949  public int compareTo(GroupKey otherGroupKey) {
950  if (otherGroupKey instanceof FrequencyGroupKey) {
951  FrequencyGroupKey otherFrequencyGroupKey = (FrequencyGroupKey) otherGroupKey;
952  return Integer.compare(getFrequency().getRanking(), otherFrequencyGroupKey.getFrequency().getRanking());
953  } else {
954  return compareClassNames(otherGroupKey);
955  }
956  }
957 
958  @Override
959  public boolean equals(Object otherKey) {
960  if (otherKey == this) {
961  return true;
962  }
963 
964  if (!(otherKey instanceof FrequencyGroupKey)) {
965  return false;
966  }
967 
968  FrequencyGroupKey otherFrequencyGroupKey = (FrequencyGroupKey) otherKey;
969  return getFrequency().equals(otherFrequencyGroupKey.getFrequency());
970  }
971 
972  @Override
973  public int hashCode() {
974  return Objects.hash(getFrequency().getRanking());
975  }
976 
982  SearchData.Frequency getFrequency() {
983  return frequency;
984  }
985  }
986 
990  static class HashHitsGroupKey extends GroupKey {
991 
992  private final List<String> hashSetNames;
993  private final String hashSetNamesString;
994 
1000  @NbBundle.Messages({
1001  "DiscoveryKeyUtils.HashHitsGroupKey.noHashHits=None"})
1002  HashHitsGroupKey(ResultFile file) {
1003  hashSetNames = file.getHashSetNames();
1004 
1005  if (hashSetNames.isEmpty()) {
1006  hashSetNamesString = Bundle.DiscoveryKeyUtils_HashHitsGroupKey_noHashHits();
1007  } else {
1008  hashSetNamesString = String.join(",", hashSetNames); // NON-NLS
1009  }
1010  }
1011 
1012  @Override
1013  String getDisplayName() {
1014  return getHashSetNamesString();
1015  }
1016 
1017  @Override
1018  public int compareTo(GroupKey otherGroupKey) {
1019  if (otherGroupKey instanceof HashHitsGroupKey) {
1020  HashHitsGroupKey otherHashHitsGroupKey = (HashHitsGroupKey) otherGroupKey;
1021 
1022  // Put the empty list at the end
1023  if (getHashSetNames().isEmpty()) {
1024  if (otherHashHitsGroupKey.getHashSetNames().isEmpty()) {
1025  return 0;
1026  } else {
1027  return 1;
1028  }
1029  } else if (otherHashHitsGroupKey.getHashSetNames().isEmpty()) {
1030  return -1;
1031  }
1032 
1033  return getHashSetNamesString().compareTo(otherHashHitsGroupKey.getHashSetNamesString());
1034  } else {
1035  return compareClassNames(otherGroupKey);
1036  }
1037  }
1038 
1039  @Override
1040  public boolean equals(Object otherKey) {
1041  if (otherKey == this) {
1042  return true;
1043  }
1044 
1045  if (!(otherKey instanceof HashHitsGroupKey)) {
1046  return false;
1047  }
1048 
1049  HashHitsGroupKey otherHashHitsGroupKey = (HashHitsGroupKey) otherKey;
1050  return getHashSetNamesString().equals(otherHashHitsGroupKey.getHashSetNamesString());
1051  }
1052 
1053  @Override
1054  public int hashCode() {
1055  return Objects.hash(getHashSetNamesString());
1056  }
1057 
1063  List<String> getHashSetNames() {
1064  return Collections.unmodifiableList(hashSetNames);
1065  }
1066 
1072  String getHashSetNamesString() {
1073  return hashSetNamesString;
1074  }
1075  }
1076 
1080  static class InterestingItemGroupKey extends GroupKey {
1081 
1082  private final List<String> interestingItemSetNames;
1083  private final String interestingItemSetNamesString;
1084 
1090  @NbBundle.Messages({
1091  "DiscoveryKeyUtils.InterestingItemGroupKey.noSets=None"})
1092  InterestingItemGroupKey(ResultFile file) {
1093  interestingItemSetNames = file.getInterestingSetNames();
1094 
1095  if (interestingItemSetNames.isEmpty()) {
1096  interestingItemSetNamesString = Bundle.DiscoveryKeyUtils_InterestingItemGroupKey_noSets();
1097  } else {
1098  interestingItemSetNamesString = String.join(",", interestingItemSetNames); // NON-NLS
1099  }
1100  }
1101 
1102  @Override
1103  String getDisplayName() {
1104  return getInterestingItemSetNamesString();
1105  }
1106 
1107  @Override
1108  public int compareTo(GroupKey otherGroupKey) {
1109  if (otherGroupKey instanceof InterestingItemGroupKey) {
1110  InterestingItemGroupKey otherInterestingItemGroupKey = (InterestingItemGroupKey) otherGroupKey;
1111 
1112  // Put the empty list at the end
1113  if (this.getInterestingItemSetNames().isEmpty()) {
1114  if (otherInterestingItemGroupKey.getInterestingItemSetNames().isEmpty()) {
1115  return 0;
1116  } else {
1117  return 1;
1118  }
1119  } else if (otherInterestingItemGroupKey.getInterestingItemSetNames().isEmpty()) {
1120  return -1;
1121  }
1122 
1123  return getInterestingItemSetNamesString().compareTo(otherInterestingItemGroupKey.getInterestingItemSetNamesString());
1124  } else {
1125  return compareClassNames(otherGroupKey);
1126  }
1127  }
1128 
1129  @Override
1130  public boolean equals(Object otherKey) {
1131  if (otherKey == this) {
1132  return true;
1133  }
1134 
1135  if (!(otherKey instanceof InterestingItemGroupKey)) {
1136  return false;
1137  }
1138 
1139  InterestingItemGroupKey otherInterestingItemGroupKey = (InterestingItemGroupKey) otherKey;
1140  return getInterestingItemSetNamesString().equals(otherInterestingItemGroupKey.getInterestingItemSetNamesString());
1141  }
1142 
1143  @Override
1144  public int hashCode() {
1145  return Objects.hash(getInterestingItemSetNamesString());
1146  }
1147 
1153  List<String> getInterestingItemSetNames() {
1154  return Collections.unmodifiableList(interestingItemSetNames);
1155  }
1156 
1164  String getInterestingItemSetNamesString() {
1165  return interestingItemSetNamesString;
1166  }
1167  }
1168 
1172  static class LastActivityDateGroupKey extends GroupKey {
1173 
1174  private ZonedDateTime currentWeekCutOff;
1175 
1181  LastActivityDateGroupKey(Result result) {
1182  if (result instanceof ResultDomain) {
1183  ResultDomain domainResult = ((ResultDomain) result);
1184  currentWeekCutOff = getCurrentWeekCutOff(domainResult.getActivityEnd(), domainResult);
1185  } else {
1186  throw new IllegalArgumentException("Expected a domain result only.");
1187  }
1188  }
1189 
1190  @NbBundle.Messages({
1191  "# {0} - month abbreviation",
1192  "# {1} - day of month",
1193  "# {2} - year",
1194  "DiscoveryAttributes.ActivityDateGroupKey.getDisplayNameTemplate=Week of {0} {1}, {2}"
1195  })
1196  @Override
1197  String getDisplayName() {
1198  MonthAbbreviation currentCutOffMonth = MonthAbbreviation.fromMonthValue(currentWeekCutOff.getMonthValue());
1199  return Bundle.DiscoveryAttributes_ActivityDateGroupKey_getDisplayNameTemplate(
1200  currentCutOffMonth.toString(), Integer.toString(currentWeekCutOff.getDayOfMonth()),
1201  Integer.toString(currentWeekCutOff.getYear()));
1202  }
1203 
1204  @Override
1205  public boolean equals(Object otherKey) {
1206  if (otherKey == this) {
1207  return true;
1208  }
1209 
1210  if (!(otherKey instanceof LastActivityDateGroupKey)) {
1211  return false;
1212  }
1213 
1214  LastActivityDateGroupKey dateGroupKey = (LastActivityDateGroupKey) otherKey;
1215  return getDisplayName().equals(dateGroupKey.getDisplayName());
1216  }
1217 
1218  @Override
1219  public int hashCode() {
1220  return Objects.hash(getDisplayName());
1221  }
1222 
1223  @Override
1224  public int compareTo(GroupKey otherGroupKey) {
1225  if (otherGroupKey instanceof LastActivityDateGroupKey) {
1226  LastActivityDateGroupKey otherDateGroupKey = (LastActivityDateGroupKey) otherGroupKey;
1227  return Long.compare(otherDateGroupKey.currentWeekCutOff.toEpochSecond(), currentWeekCutOff.toEpochSecond());
1228  } else {
1229  return compareClassNames(otherGroupKey);
1230  }
1231  }
1232  }
1233 
1239  private static ZonedDateTime getCurrentWeekCutOff(long epochSeconds, ResultDomain domainResult) {
1240  Instant startActivityAsInsant = Instant.ofEpochSecond(epochSeconds);
1241  // Determines the timezone using the settings panel or value parsed from the
1242  // parent data source
1243  TimeZone currentTimeZone = TimeZoneUtils.getTimeZone();
1244  // Convert to a datetime using epoch and timezone.
1245  ZonedDateTime startActivityAsDateTime = ZonedDateTime.ofInstant(startActivityAsInsant, currentTimeZone.toZoneId());
1246  // Get the closest Sunday, which is the cut off for the current week.
1247  // Use this cut off to perform grouping and comparing.
1248  return startActivityAsDateTime.with(TemporalAdjusters.nextOrSame(DayOfWeek.SUNDAY));
1249  }
1250 
1254  static class FirstActivityDateGroupKey extends GroupKey {
1255 
1256  private ZonedDateTime currentWeekCutOff;
1257 
1263  FirstActivityDateGroupKey(Result result) {
1264  if (result instanceof ResultDomain) {
1265  ResultDomain domainResult = ((ResultDomain) result);
1266  currentWeekCutOff = getCurrentWeekCutOff(domainResult.getActivityStart(), domainResult);
1267  } else {
1268  throw new IllegalArgumentException("Expected a domain result only.");
1269  }
1270  }
1271 
1272  @Override
1273  String getDisplayName() {
1274  MonthAbbreviation currentCutOffMonth = MonthAbbreviation.fromMonthValue(currentWeekCutOff.getMonthValue());
1275  return Bundle.DiscoveryAttributes_ActivityDateGroupKey_getDisplayNameTemplate(
1276  currentCutOffMonth.toString(), Integer.toString(currentWeekCutOff.getDayOfMonth()),
1277  Integer.toString(currentWeekCutOff.getYear()));
1278  }
1279 
1280  @Override
1281  public boolean equals(Object otherKey) {
1282  if (otherKey == this) {
1283  return true;
1284  }
1285 
1286  if (!(otherKey instanceof FirstActivityDateGroupKey)) {
1287  return false;
1288  }
1289 
1290  FirstActivityDateGroupKey dateGroupKey = (FirstActivityDateGroupKey) otherKey;
1291  return getDisplayName().equals(dateGroupKey.getDisplayName());
1292  }
1293 
1294  @Override
1295  public int hashCode() {
1296  return Objects.hash(getDisplayName());
1297  }
1298 
1299  @Override
1300  public int compareTo(GroupKey otherGroupKey) {
1301  if (otherGroupKey instanceof FirstActivityDateGroupKey) {
1302  FirstActivityDateGroupKey otherDateGroupKey = (FirstActivityDateGroupKey) otherGroupKey;
1303  return Long.compare(otherDateGroupKey.currentWeekCutOff.toEpochSecond(), currentWeekCutOff.toEpochSecond());
1304  } else {
1305  return compareClassNames(otherGroupKey);
1306  }
1307  }
1308  }
1309 
1314  static class PageViewsGroupKey extends GroupKey {
1315 
1316  private final String displayName;
1317  private final PageViews pageViews;
1318 
1324  PageViewsGroupKey(Result result) {
1325  if (result instanceof ResultDomain) {
1326  Long totalPageViews = ((ResultDomain) result).getTotalPageViews();
1327  if (totalPageViews == null) {
1328  totalPageViews = 0L;
1329  }
1330  pageViews = PageViews.fromPageViewCount(totalPageViews);
1331  displayName = pageViews.toString();
1332  } else {
1333  throw new IllegalArgumentException("Expected a domain instance only.");
1334  }
1335  }
1336 
1337  @Override
1338  String getDisplayName() {
1339  return displayName;
1340  }
1341 
1342  @Override
1343  public int hashCode() {
1344  return Objects.hash(displayName);
1345  }
1346 
1352  PageViews getPageViews() {
1353  return pageViews;
1354  }
1355 
1356  @Override
1357  public boolean equals(Object otherKey) {
1358  if (otherKey == this) {
1359  return true;
1360  }
1361 
1362  if (!(otherKey instanceof PageViewsGroupKey)) {
1363  return false;
1364  }
1365 
1366  PageViewsGroupKey pageViewsKey = (PageViewsGroupKey) otherKey;
1367  return pageViews.equals(pageViewsKey.getPageViews());
1368  }
1369 
1370  @Override
1371  public int compareTo(GroupKey otherGroupKey) {
1372  if (otherGroupKey instanceof PageViewsGroupKey) {
1373  PageViewsGroupKey pageViewsKey = (PageViewsGroupKey) otherGroupKey;
1374  return getPageViews().compareTo(pageViewsKey.getPageViews());
1375  } else {
1376  return compareClassNames(otherGroupKey);
1377  }
1378  }
1379  }
1380 
1384  static class ObjectDetectedGroupKey extends GroupKey {
1385 
1386  private final List<String> objectDetectedNames;
1387  private final String objectDetectedNamesString;
1388 
1394  @NbBundle.Messages({
1395  "DiscoveryKeyUtils.ObjectDetectedGroupKey.noSets=None"})
1396  ObjectDetectedGroupKey(ResultFile file) {
1397  objectDetectedNames = file.getObjectDetectedNames();
1398  if (objectDetectedNames.isEmpty()) {
1399  objectDetectedNamesString = Bundle.DiscoveryKeyUtils_ObjectDetectedGroupKey_noSets();
1400  } else {
1401  objectDetectedNamesString = String.join(",", objectDetectedNames); // NON-NLS
1402  }
1403  }
1404 
1405  @Override
1406  String getDisplayName() {
1407  return getObjectDetectedNamesString();
1408  }
1409 
1410  @Override
1411  public int compareTo(GroupKey otherGroupKey) {
1412  if (otherGroupKey instanceof ObjectDetectedGroupKey) {
1413  ObjectDetectedGroupKey otherObjectDetectedGroupKey = (ObjectDetectedGroupKey) otherGroupKey;
1414 
1415  // Put the empty list at the end
1416  if (this.getObjectDetectedNames().isEmpty()) {
1417  if (otherObjectDetectedGroupKey.getObjectDetectedNames().isEmpty()) {
1418  return 0;
1419  } else {
1420  return 1;
1421  }
1422  } else if (otherObjectDetectedGroupKey.getObjectDetectedNames().isEmpty()) {
1423  return -1;
1424  }
1425 
1426  return getObjectDetectedNamesString().compareTo(otherObjectDetectedGroupKey.getObjectDetectedNamesString());
1427  } else {
1428  return compareClassNames(otherGroupKey);
1429  }
1430  }
1431 
1432  @Override
1433  public boolean equals(Object otherKey) {
1434  if (otherKey == this) {
1435  return true;
1436  }
1437 
1438  if (!(otherKey instanceof ObjectDetectedGroupKey)) {
1439  return false;
1440  }
1441 
1442  ObjectDetectedGroupKey otherObjectDetectedGroupKey = (ObjectDetectedGroupKey) otherKey;
1443  return getObjectDetectedNamesString().equals(otherObjectDetectedGroupKey.getObjectDetectedNamesString());
1444  }
1445 
1446  @Override
1447  public int hashCode() {
1448  return Objects.hash(getObjectDetectedNamesString());
1449  }
1450 
1456  List<String> getObjectDetectedNames() {
1457  return Collections.unmodifiableList(objectDetectedNames);
1458  }
1459 
1467  String getObjectDetectedNamesString() {
1468  return objectDetectedNamesString;
1469  }
1470  }
1471 
1475  private DiscoveryKeyUtils() {
1476  //private constructor in a utility class intentionally left blank
1477  }
1478 }
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-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.