Autopsy  4.17.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 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.List;
27 import java.util.Objects;
28 import java.util.TimeZone;
29 import java.util.logging.Level;
30 import org.openide.util.NbBundle;
36 import org.sleuthkit.datamodel.AbstractFile;
37 import org.sleuthkit.datamodel.Content;
38 import org.sleuthkit.datamodel.SleuthkitCase;
39 import org.sleuthkit.datamodel.TskCoreException;
40 
44 public class DiscoveryKeyUtils {
45 
46  private final static Logger logger = Logger.getLogger(DiscoveryKeyUtils.class.getName());
47 
51  static class SearchKey implements Comparable<SearchKey> {
52 
53  private final String keyString;
54  private final Group.GroupSortingAlgorithm groupSortingType;
55  private final DiscoveryAttributes.AttributeType groupAttributeType;
56  private final ResultsSorter.SortingMethod sortingMethod;
57  private final List<AbstractFilter> filters;
58  private final SleuthkitCase sleuthkitCase;
59  private final CentralRepository centralRepository;
60 
72  SearchKey(String userName, List<AbstractFilter> filters,
73  DiscoveryAttributes.AttributeType groupAttributeType,
74  Group.GroupSortingAlgorithm groupSortingType,
75  ResultsSorter.SortingMethod sortingMethod,
76  SleuthkitCase sleuthkitCase, CentralRepository centralRepository) {
77  this.groupAttributeType = groupAttributeType;
78  this.groupSortingType = groupSortingType;
79  this.sortingMethod = sortingMethod;
80  this.filters = filters;
81 
82  StringBuilder searchStringBuilder = new StringBuilder();
83  searchStringBuilder.append(userName);
84  for (AbstractFilter filter : filters) {
85  searchStringBuilder.append(filter.toString());
86  }
87  searchStringBuilder.append(groupAttributeType).append(groupSortingType).append(sortingMethod);
88  keyString = searchStringBuilder.toString();
89  this.sleuthkitCase = sleuthkitCase;
90  this.centralRepository = centralRepository;
91  }
92 
103  SearchKey(String userName, List<AbstractFilter> filters,
104  DiscoveryAttributes.AttributeType groupAttributeType,
105  Group.GroupSortingAlgorithm groupSortingType,
106  ResultsSorter.SortingMethod sortingMethod) {
107  this(userName, filters, groupAttributeType, groupSortingType,
108  sortingMethod, null, null);
109  }
110 
111  @Override
112  public int compareTo(SearchKey otherSearchKey) {
113  return getKeyString().compareTo(otherSearchKey.getKeyString());
114  }
115 
116  @Override
117  public boolean equals(Object otherKey) {
118  if (otherKey == this) {
119  return true;
120  }
121 
122  if (!(otherKey instanceof SearchKey)) {
123  return false;
124  }
125 
126  SearchKey otherSearchKey = (SearchKey) otherKey;
127  if (this.sleuthkitCase != otherSearchKey.getSleuthkitCase()
128  || this.centralRepository != otherSearchKey.getCentralRepository()) {
129  return false;
130  }
131 
132  return getKeyString().equals(otherSearchKey.getKeyString());
133  }
134 
135  @Override
136  public int hashCode() {
137  int hash = 5;
138  hash = 79 * hash + Objects.hashCode(getKeyString());
139  return hash;
140  }
141 
147  String getKeyString() {
148  return keyString;
149  }
150 
156  List<AbstractFilter> getFilters() {
157  return Collections.unmodifiableList(this.filters);
158  }
159 
165  Group.GroupSortingAlgorithm getGroupSortingType() {
166  return groupSortingType;
167  }
168 
174  DiscoveryAttributes.AttributeType getGroupAttributeType() {
175  return groupAttributeType;
176  }
177 
183  ResultsSorter.SortingMethod getFileSortingMethod() {
184  return sortingMethod;
185  }
186 
192  SleuthkitCase getSleuthkitCase() {
193  return this.sleuthkitCase;
194  }
195 
201  CentralRepository getCentralRepository() {
202  return this.centralRepository;
203  }
204  }
205 
209  public abstract static class GroupKey implements Comparable<GroupKey> {
210 
217  abstract String getDisplayName();
218 
226  @Override
227  abstract public boolean equals(Object otherKey);
228 
234  @Override
235  abstract public int hashCode();
236 
246  int compareClassNames(GroupKey otherGroupKey) {
247  return this.getClass().getName().compareTo(otherGroupKey.getClass().getName());
248  }
249 
250  @Override
251  public String toString() {
252  return getDisplayName();
253  }
254  }
255 
259  static class FileSizeGroupKey extends GroupKey {
260 
261  private final SearchData.FileSize fileSize;
262 
268  FileSizeGroupKey(Result file) {
269  ResultFile resultFile = (ResultFile) file;
270  if (resultFile.getFileType() == SearchData.Type.VIDEO) {
271  fileSize = SearchData.FileSize.fromVideoSize(resultFile.getFirstInstance().getSize());
272  } else {
273  fileSize = SearchData.FileSize.fromImageSize(resultFile.getFirstInstance().getSize());
274  }
275  }
276 
277  @Override
278  String getDisplayName() {
279  return getFileSize().toString();
280  }
281 
282  @Override
283  public int compareTo(GroupKey otherGroupKey) {
284  if (otherGroupKey instanceof FileSizeGroupKey) {
285  FileSizeGroupKey otherFileSizeGroupKey = (FileSizeGroupKey) otherGroupKey;
286  return Integer.compare(getFileSize().getRanking(), otherFileSizeGroupKey.getFileSize().getRanking());
287  } else {
288  return compareClassNames(otherGroupKey);
289  }
290  }
291 
292  @Override
293  public boolean equals(Object otherKey) {
294  if (otherKey == this) {
295  return true;
296  }
297 
298  if (!(otherKey instanceof FileSizeGroupKey)) {
299  return false;
300  }
301 
302  FileSizeGroupKey otherFileSizeGroupKey = (FileSizeGroupKey) otherKey;
303  return getFileSize().equals(otherFileSizeGroupKey.getFileSize());
304  }
305 
306  @Override
307  public int hashCode() {
308  return Objects.hash(getFileSize().getRanking());
309  }
310 
316  SearchData.FileSize getFileSize() {
317  return fileSize;
318  }
319  }
320 
324  static class FileTypeGroupKey extends GroupKey {
325 
326  private final SearchData.Type fileType;
327 
333  FileTypeGroupKey(Result file) {
334  fileType = ((ResultFile) file).getFileType();
335  }
336 
337  @Override
338  String getDisplayName() {
339  return getFileType().toString();
340  }
341 
342  @Override
343  public int compareTo(GroupKey otherGroupKey) {
344  if (otherGroupKey instanceof FileTypeGroupKey) {
345  FileTypeGroupKey otherFileTypeGroupKey = (FileTypeGroupKey) otherGroupKey;
346  return Integer.compare(getFileType().getRanking(), otherFileTypeGroupKey.getFileType().getRanking());
347  } else {
348  return compareClassNames(otherGroupKey);
349  }
350  }
351 
352  @Override
353  public boolean equals(Object otherKey) {
354  if (otherKey == this) {
355  return true;
356  }
357 
358  if (!(otherKey instanceof FileTypeGroupKey)) {
359  return false;
360  }
361 
362  FileTypeGroupKey otherFileTypeGroupKey = (FileTypeGroupKey) otherKey;
363  return getFileType().equals(otherFileTypeGroupKey.getFileType());
364  }
365 
366  @Override
367  public int hashCode() {
368  return Objects.hash(getFileType().getRanking());
369  }
370 
376  SearchData.Type getFileType() {
377  return fileType;
378  }
379  }
380 
384  static class KeywordListGroupKey extends GroupKey {
385 
386  private final List<String> keywordListNames;
387  private final String keywordListNamesString;
388 
394  @NbBundle.Messages({
395  "DiscoveryKeyUtils.KeywordListGroupKey.noKeywords=None"})
396  KeywordListGroupKey(ResultFile file) {
397  keywordListNames = file.getKeywordListNames();
398  if (keywordListNames.isEmpty()) {
399  keywordListNamesString = Bundle.DiscoveryKeyUtils_KeywordListGroupKey_noKeywords();
400  } else {
401  keywordListNamesString = String.join(",", keywordListNames); // NON-NLS
402  }
403  }
404 
405  @Override
406  String getDisplayName() {
407  return getKeywordListNamesString();
408  }
409 
410  @Override
411  public int compareTo(GroupKey otherGroupKey) {
412  if (otherGroupKey instanceof KeywordListGroupKey) {
413  KeywordListGroupKey otherKeywordListNamesGroupKey = (KeywordListGroupKey) otherGroupKey;
414 
415  // Put the empty list at the end
416  if (getKeywordListNames().isEmpty()) {
417  if (otherKeywordListNamesGroupKey.getKeywordListNames().isEmpty()) {
418  return 0;
419  } else {
420  return 1;
421  }
422  } else if (otherKeywordListNamesGroupKey.getKeywordListNames().isEmpty()) {
423  return -1;
424  }
425 
426  return getKeywordListNamesString().compareTo(otherKeywordListNamesGroupKey.getKeywordListNamesString());
427  } else {
428  return compareClassNames(otherGroupKey);
429  }
430  }
431 
432  @Override
433  public boolean equals(Object otherKey) {
434  if (otherKey == this) {
435  return true;
436  }
437 
438  if (!(otherKey instanceof KeywordListGroupKey)) {
439  return false;
440  }
441 
442  KeywordListGroupKey otherKeywordListGroupKey = (KeywordListGroupKey) otherKey;
443  return getKeywordListNamesString().equals(otherKeywordListGroupKey.getKeywordListNamesString());
444  }
445 
446  @Override
447  public int hashCode() {
448  return Objects.hash(getKeywordListNamesString());
449  }
450 
456  List<String> getKeywordListNames() {
457  return Collections.unmodifiableList(keywordListNames);
458  }
459 
467  String getKeywordListNamesString() {
468  return keywordListNamesString;
469  }
470  }
471 
475  static class FileTagGroupKey extends GroupKey {
476 
477  private final List<String> tagNames;
478  private final String tagNamesString;
479 
485  @NbBundle.Messages({
486  "DiscoveryKeyUtils.FileTagGroupKey.noSets=None"})
487  FileTagGroupKey(ResultFile file) {
488  tagNames = file.getTagNames();
489 
490  if (tagNames.isEmpty()) {
491  tagNamesString = Bundle.DiscoveryKeyUtils_FileTagGroupKey_noSets();
492  } else {
493  tagNamesString = String.join(",", tagNames); // NON-NLS
494  }
495  }
496 
497  @Override
498  String getDisplayName() {
499  return getTagNamesString();
500  }
501 
502  @Override
503  public int compareTo(GroupKey otherGroupKey) {
504  if (otherGroupKey instanceof FileTagGroupKey) {
505  FileTagGroupKey otherFileTagGroupKey = (FileTagGroupKey) otherGroupKey;
506 
507  // Put the empty list at the end
508  if (getTagNames().isEmpty()) {
509  if (otherFileTagGroupKey.getTagNames().isEmpty()) {
510  return 0;
511  } else {
512  return 1;
513  }
514  } else if (otherFileTagGroupKey.getTagNames().isEmpty()) {
515  return -1;
516  }
517 
518  return getTagNamesString().compareTo(otherFileTagGroupKey.getTagNamesString());
519  } else {
520  return compareClassNames(otherGroupKey);
521  }
522  }
523 
524  @Override
525  public boolean equals(Object otherKey) {
526  if (otherKey == this) {
527  return true;
528  }
529  if (!(otherKey instanceof FileTagGroupKey)) {
530  return false;
531  }
532  FileTagGroupKey otherFileTagGroupKey = (FileTagGroupKey) otherKey;
533  return getTagNamesString().equals(otherFileTagGroupKey.getTagNamesString());
534  }
535 
536  @Override
537  public int hashCode() {
538  return Objects.hash(getTagNamesString());
539  }
540 
546  List<String> getTagNames() {
547  return Collections.unmodifiableList(tagNames);
548  }
549 
557  String getTagNamesString() {
558  return tagNamesString;
559  }
560  }
561 
565  static class ParentPathGroupKey extends GroupKey {
566 
567  private String parentPath;
568  private Long parentID;
569 
575  ParentPathGroupKey(ResultFile file) {
576  Content parent;
577  try {
578  parent = file.getFirstInstance().getParent();
579  } catch (TskCoreException ignored) {
580  parent = null;
581  }
582  //Find the directory this file is in if it is an embedded file
583  while (parent != null && parent instanceof AbstractFile && ((AbstractFile) parent).isFile()) {
584  try {
585  parent = parent.getParent();
586  } catch (TskCoreException ignored) {
587  parent = null;
588  }
589  }
590  setParentPathAndID(parent, file);
591  }
592 
599  private void setParentPathAndID(Content parent, ResultFile file) {
600  if (parent != null) {
601  try {
602  parentPath = parent.getUniquePath();
603  parentID = parent.getId();
604  } catch (TskCoreException ignored) {
605  //catch block left blank purposefully next if statement will handle case when exception takes place as well as when parent is null
606  }
607 
608  }
609  if (parentPath == null) {
610  if (file.getFirstInstance().getParentPath() != null) {
611  parentPath = file.getFirstInstance().getParentPath();
612  } else {
613  parentPath = ""; // NON-NLS
614  }
615  parentID = -1L;
616  }
617  }
618 
619  @Override
620  String getDisplayName() {
621  return getParentPath();
622  }
623 
624  @Override
625  public int compareTo(GroupKey otherGroupKey) {
626  if (otherGroupKey instanceof ParentPathGroupKey) {
627  ParentPathGroupKey otherParentPathGroupKey = (ParentPathGroupKey) otherGroupKey;
628  int comparisonResult = getParentPath().compareTo(otherParentPathGroupKey.getParentPath());
629  if (comparisonResult == 0) {
630  comparisonResult = getParentID().compareTo(otherParentPathGroupKey.getParentID());
631  }
632  return comparisonResult;
633  } else {
634  return compareClassNames(otherGroupKey);
635  }
636  }
637 
638  @Override
639  public boolean equals(Object otherKey) {
640  if (otherKey == this) {
641  return true;
642  }
643 
644  if (!(otherKey instanceof ParentPathGroupKey)) {
645  return false;
646  }
647 
648  ParentPathGroupKey otherParentPathGroupKey = (ParentPathGroupKey) otherKey;
649  return getParentPath().equals(otherParentPathGroupKey.getParentPath()) && getParentID().equals(otherParentPathGroupKey.getParentID());
650  }
651 
652  @Override
653  public int hashCode() {
654  int hashCode = 11;
655  hashCode = 61 * hashCode + Objects.hash(getParentPath());
656  hashCode = 61 * hashCode + Objects.hash(getParentID());
657  return hashCode;
658  }
659 
665  String getParentPath() {
666  return parentPath;
667  }
668 
674  Long getParentID() {
675  return parentID;
676  }
677  }
678 
682  static class DataSourceGroupKey extends GroupKey {
683 
684  private final long dataSourceID;
685  private String displayName;
686 
692  @NbBundle.Messages({
693  "# {0} - Data source name",
694  "# {1} - Data source ID",
695  "DiscoveryKeyUtils.DataSourceGroupKey.datasourceAndID={0}(ID: {1})",
696  "# {0} - Data source ID",
697  "DiscoveryKeyUtils.DataSourceGroupKey.idOnly=Data source (ID: {0})"})
698  DataSourceGroupKey(Result result) {
699  //get the id first so that it can be used when logging if necessary
700  dataSourceID = result.getDataSourceObjectId();
701  try {
702  // The data source should be cached so this won't actually be a database query.
703  Content ds = result.getDataSource();
704  displayName = Bundle.DiscoveryKeyUtils_DataSourceGroupKey_datasourceAndID(ds.getName(), ds.getId());
705  } catch (TskCoreException ex) {
706  logger.log(Level.WARNING, "Error looking up data source with ID " + dataSourceID, ex); // NON-NLS
707  displayName = Bundle.DiscoveryKeyUtils_DataSourceGroupKey_idOnly(dataSourceID);
708  }
709  }
710 
711  @Override
712  String getDisplayName() {
713  return displayName;
714  }
715 
716  @Override
717  public int compareTo(GroupKey otherGroupKey) {
718  if (otherGroupKey instanceof DataSourceGroupKey) {
719  DataSourceGroupKey otherDataSourceGroupKey = (DataSourceGroupKey) otherGroupKey;
720  return Long.compare(getDataSourceID(), otherDataSourceGroupKey.getDataSourceID());
721  } else {
722  return compareClassNames(otherGroupKey);
723  }
724  }
725 
726  @Override
727  public boolean equals(Object otherKey) {
728  if (otherKey == this) {
729  return true;
730  }
731 
732  if (!(otherKey instanceof DataSourceGroupKey)) {
733  return false;
734  }
735 
736  DataSourceGroupKey otherDataSourceGroupKey = (DataSourceGroupKey) otherKey;
737  return getDataSourceID() == otherDataSourceGroupKey.getDataSourceID();
738  }
739 
740  @Override
741  public int hashCode() {
742  return Objects.hash(getDataSourceID());
743  }
744 
750  long getDataSourceID() {
751  return dataSourceID;
752  }
753  }
754 
759  static class NoGroupingGroupKey extends GroupKey {
760 
764  NoGroupingGroupKey() {
765  // Nothing to save - all files will get the same GroupKey
766  }
767 
768  @NbBundle.Messages({
769  "DiscoveryKeyUtils.NoGroupingGroupKey.allFiles=All Files"})
770  @Override
771  String getDisplayName() {
772  return Bundle.DiscoveryKeyUtils_NoGroupingGroupKey_allFiles();
773  }
774 
775  @Override
776  public int compareTo(GroupKey otherGroupKey) {
777  // As long as the other key is the same type, they are equal
778  if (otherGroupKey instanceof NoGroupingGroupKey) {
779  return 0;
780  } else {
781  return compareClassNames(otherGroupKey);
782  }
783  }
784 
785  @Override
786  public boolean equals(Object otherKey) {
787  if (otherKey == this) {
788  return true;
789  }
790  // As long as the other key is the same type, they are equal
791  return otherKey instanceof NoGroupingGroupKey;
792  }
793 
794  @Override
795  public int hashCode() {
796  return 0;
797  }
798  }
799 
803  static class DomainCategoryGroupKey extends GroupKey {
804 
805  private final String webCategory;
806 
807  DomainCategoryGroupKey(Result result) {
808  if (result instanceof ResultDomain) {
809  ResultDomain domain = (ResultDomain) result;
810  this.webCategory = domain.getWebCategory();
811  } else {
812  throw new IllegalArgumentException("Input result should be of type ResultDomain");
813  }
814  }
815 
816  @Override
817  String getDisplayName() {
818  return this.webCategory;
819  }
820 
821  @Override
822  public boolean equals(Object otherKey) {
823  if (otherKey instanceof GroupKey) {
824  return compareTo((GroupKey) otherKey) == 0;
825  }
826  return false;
827  }
828 
829  @Override
830  public int hashCode() {
831  return Objects.hash(getWebCategory());
832  }
833 
834  @Override
835  public int compareTo(GroupKey otherGroupKey) {
836  if (otherGroupKey instanceof DomainCategoryGroupKey) {
837  DomainCategoryGroupKey webCategoryKey = (DomainCategoryGroupKey) otherGroupKey;
838  return this.webCategory.compareTo(webCategoryKey.getWebCategory());
839  } else {
840  return compareClassNames(otherGroupKey);
841  }
842  }
843 
844  String getWebCategory() {
845  return this.webCategory;
846  }
847  }
848 
852  static class PreviouslyNotableGroupKey extends GroupKey {
853 
854  private final SearchData.PreviouslyNotable notableStatus;
855 
856  PreviouslyNotableGroupKey(Result result) {
857  this.notableStatus = result.getPreviouslyNotableInCR();
858  }
859 
860  @Override
861  String getDisplayName() {
862  return this.notableStatus.toString();
863  }
864 
865  @Override
866  public boolean equals(Object otherKey) {
867  if (otherKey instanceof GroupKey) {
868  return compareTo((GroupKey) otherKey) == 0;
869  }
870  return false;
871  }
872 
873  @Override
874  public int hashCode() {
875  return Objects.hash(getStatus().getRanking());
876  }
877 
878  @Override
879  public int compareTo(GroupKey otherGroupKey) {
880  if (otherGroupKey instanceof PreviouslyNotableGroupKey) {
881  PreviouslyNotableGroupKey otherFrequencyGroupKey = (PreviouslyNotableGroupKey) otherGroupKey;
882  return Integer.compare(getStatus().getRanking(), otherFrequencyGroupKey.getStatus().getRanking());
883  } else {
884  return compareClassNames(otherGroupKey);
885  }
886  }
887 
888  SearchData.PreviouslyNotable getStatus() {
889  return notableStatus;
890  }
891  }
892 
896  static class FrequencyGroupKey extends GroupKey {
897 
898  private final SearchData.Frequency frequency;
899 
905  FrequencyGroupKey(Result result) {
906  frequency = result.getFrequency();
907  }
908 
909  @Override
910  String getDisplayName() {
911  return getFrequency().toString();
912  }
913 
914  @Override
915  public int compareTo(GroupKey otherGroupKey) {
916  if (otherGroupKey instanceof FrequencyGroupKey) {
917  FrequencyGroupKey otherFrequencyGroupKey = (FrequencyGroupKey) otherGroupKey;
918  return Integer.compare(getFrequency().getRanking(), otherFrequencyGroupKey.getFrequency().getRanking());
919  } else {
920  return compareClassNames(otherGroupKey);
921  }
922  }
923 
924  @Override
925  public boolean equals(Object otherKey) {
926  if (otherKey == this) {
927  return true;
928  }
929 
930  if (!(otherKey instanceof FrequencyGroupKey)) {
931  return false;
932  }
933 
934  FrequencyGroupKey otherFrequencyGroupKey = (FrequencyGroupKey) otherKey;
935  return getFrequency().equals(otherFrequencyGroupKey.getFrequency());
936  }
937 
938  @Override
939  public int hashCode() {
940  return Objects.hash(getFrequency().getRanking());
941  }
942 
948  SearchData.Frequency getFrequency() {
949  return frequency;
950  }
951  }
952 
956  static class HashHitsGroupKey extends GroupKey {
957 
958  private final List<String> hashSetNames;
959  private final String hashSetNamesString;
960 
966  @NbBundle.Messages({
967  "DiscoveryKeyUtils.HashHitsGroupKey.noHashHits=None"})
968  HashHitsGroupKey(ResultFile file) {
969  hashSetNames = file.getHashSetNames();
970 
971  if (hashSetNames.isEmpty()) {
972  hashSetNamesString = Bundle.DiscoveryKeyUtils_HashHitsGroupKey_noHashHits();
973  } else {
974  hashSetNamesString = String.join(",", hashSetNames); // NON-NLS
975  }
976  }
977 
978  @Override
979  String getDisplayName() {
980  return getHashSetNamesString();
981  }
982 
983  @Override
984  public int compareTo(GroupKey otherGroupKey) {
985  if (otherGroupKey instanceof HashHitsGroupKey) {
986  HashHitsGroupKey otherHashHitsGroupKey = (HashHitsGroupKey) otherGroupKey;
987 
988  // Put the empty list at the end
989  if (getHashSetNames().isEmpty()) {
990  if (otherHashHitsGroupKey.getHashSetNames().isEmpty()) {
991  return 0;
992  } else {
993  return 1;
994  }
995  } else if (otherHashHitsGroupKey.getHashSetNames().isEmpty()) {
996  return -1;
997  }
998 
999  return getHashSetNamesString().compareTo(otherHashHitsGroupKey.getHashSetNamesString());
1000  } else {
1001  return compareClassNames(otherGroupKey);
1002  }
1003  }
1004 
1005  @Override
1006  public boolean equals(Object otherKey) {
1007  if (otherKey == this) {
1008  return true;
1009  }
1010 
1011  if (!(otherKey instanceof HashHitsGroupKey)) {
1012  return false;
1013  }
1014 
1015  HashHitsGroupKey otherHashHitsGroupKey = (HashHitsGroupKey) otherKey;
1016  return getHashSetNamesString().equals(otherHashHitsGroupKey.getHashSetNamesString());
1017  }
1018 
1019  @Override
1020  public int hashCode() {
1021  return Objects.hash(getHashSetNamesString());
1022  }
1023 
1029  List<String> getHashSetNames() {
1030  return Collections.unmodifiableList(hashSetNames);
1031  }
1032 
1038  String getHashSetNamesString() {
1039  return hashSetNamesString;
1040  }
1041  }
1042 
1046  static class InterestingItemGroupKey extends GroupKey {
1047 
1048  private final List<String> interestingItemSetNames;
1049  private final String interestingItemSetNamesString;
1050 
1056  @NbBundle.Messages({
1057  "DiscoveryKeyUtils.InterestingItemGroupKey.noSets=None"})
1058  InterestingItemGroupKey(ResultFile file) {
1059  interestingItemSetNames = file.getInterestingSetNames();
1060 
1061  if (interestingItemSetNames.isEmpty()) {
1062  interestingItemSetNamesString = Bundle.DiscoveryKeyUtils_InterestingItemGroupKey_noSets();
1063  } else {
1064  interestingItemSetNamesString = String.join(",", interestingItemSetNames); // NON-NLS
1065  }
1066  }
1067 
1068  @Override
1069  String getDisplayName() {
1070  return getInterestingItemSetNamesString();
1071  }
1072 
1073  @Override
1074  public int compareTo(GroupKey otherGroupKey) {
1075  if (otherGroupKey instanceof InterestingItemGroupKey) {
1076  InterestingItemGroupKey otherInterestingItemGroupKey = (InterestingItemGroupKey) otherGroupKey;
1077 
1078  // Put the empty list at the end
1079  if (this.getInterestingItemSetNames().isEmpty()) {
1080  if (otherInterestingItemGroupKey.getInterestingItemSetNames().isEmpty()) {
1081  return 0;
1082  } else {
1083  return 1;
1084  }
1085  } else if (otherInterestingItemGroupKey.getInterestingItemSetNames().isEmpty()) {
1086  return -1;
1087  }
1088 
1089  return getInterestingItemSetNamesString().compareTo(otherInterestingItemGroupKey.getInterestingItemSetNamesString());
1090  } else {
1091  return compareClassNames(otherGroupKey);
1092  }
1093  }
1094 
1095  @Override
1096  public boolean equals(Object otherKey) {
1097  if (otherKey == this) {
1098  return true;
1099  }
1100 
1101  if (!(otherKey instanceof InterestingItemGroupKey)) {
1102  return false;
1103  }
1104 
1105  InterestingItemGroupKey otherInterestingItemGroupKey = (InterestingItemGroupKey) otherKey;
1106  return getInterestingItemSetNamesString().equals(otherInterestingItemGroupKey.getInterestingItemSetNamesString());
1107  }
1108 
1109  @Override
1110  public int hashCode() {
1111  return Objects.hash(getInterestingItemSetNamesString());
1112  }
1113 
1119  List<String> getInterestingItemSetNames() {
1120  return Collections.unmodifiableList(interestingItemSetNames);
1121  }
1122 
1130  String getInterestingItemSetNamesString() {
1131  return interestingItemSetNamesString;
1132  }
1133  }
1134 
1138  static class LastActivityDateGroupKey extends GroupKey {
1139 
1140  private ZonedDateTime currentWeekCutOff;
1141 
1147  LastActivityDateGroupKey(Result result) {
1148  if (result instanceof ResultDomain) {
1149  ResultDomain domainResult = ((ResultDomain) result);
1150  currentWeekCutOff = getCurrentWeekCutOff(domainResult.getActivityEnd(), domainResult);
1151  } else {
1152  throw new IllegalArgumentException("Expected a domain result only.");
1153  }
1154  }
1155 
1156  @NbBundle.Messages({
1157  "# {0} - month abbreviation",
1158  "# {1} - day of month",
1159  "# {2} - year",
1160  "DiscoveryAttributes.ActivityDateGroupKey.getDisplayNameTemplate=Week of {0} {1}, {2}"
1161  })
1162  @Override
1163  String getDisplayName() {
1164  MonthAbbreviation currentCutOffMonth = MonthAbbreviation.fromMonthValue(currentWeekCutOff.getMonthValue());
1165  return Bundle.DiscoveryAttributes_ActivityDateGroupKey_getDisplayNameTemplate(
1166  currentCutOffMonth.toString(), Integer.toString(currentWeekCutOff.getDayOfMonth()),
1167  Integer.toString(currentWeekCutOff.getYear()));
1168  }
1169 
1170  @Override
1171  public boolean equals(Object otherKey) {
1172  if (otherKey == this) {
1173  return true;
1174  }
1175 
1176  if (!(otherKey instanceof LastActivityDateGroupKey)) {
1177  return false;
1178  }
1179 
1180  LastActivityDateGroupKey dateGroupKey = (LastActivityDateGroupKey) otherKey;
1181  return getDisplayName().equals(dateGroupKey.getDisplayName());
1182  }
1183 
1184  @Override
1185  public int hashCode() {
1186  return Objects.hash(getDisplayName());
1187  }
1188 
1189  @Override
1190  public int compareTo(GroupKey otherGroupKey) {
1191  if (otherGroupKey instanceof LastActivityDateGroupKey) {
1192  LastActivityDateGroupKey otherDateGroupKey = (LastActivityDateGroupKey) otherGroupKey;
1193  return Long.compare(otherDateGroupKey.currentWeekCutOff.toEpochSecond(), currentWeekCutOff.toEpochSecond());
1194  } else {
1195  return compareClassNames(otherGroupKey);
1196  }
1197  }
1198  }
1199 
1205  private static ZonedDateTime getCurrentWeekCutOff(long epochSeconds, ResultDomain domainResult) {
1206  Instant startActivityAsInsant = Instant.ofEpochSecond(epochSeconds);
1207  // Determines the timezone using the settings panel or value parsed from the
1208  // parent data source
1209  TimeZone currentTimeZone = ContentUtils.getTimeZone(domainResult.getDataSource());
1210  // Convert to a datetime using epoch and timezone.
1211  ZonedDateTime startActivityAsDateTime = ZonedDateTime.ofInstant(startActivityAsInsant, currentTimeZone.toZoneId());
1212  // Get the closest Sunday, which is the cut off for the current week.
1213  // Use this cut off to perform grouping and comparing.
1214  return startActivityAsDateTime.with(TemporalAdjusters.nextOrSame(DayOfWeek.SUNDAY));
1215  }
1216 
1220  static class FirstActivityDateGroupKey extends GroupKey {
1221 
1222  private ZonedDateTime currentWeekCutOff;
1223 
1229  FirstActivityDateGroupKey(Result result) {
1230  if (result instanceof ResultDomain) {
1231  ResultDomain domainResult = ((ResultDomain) result);
1232  currentWeekCutOff = getCurrentWeekCutOff(domainResult.getActivityStart(), domainResult);
1233  } else {
1234  throw new IllegalArgumentException("Expected a domain result only.");
1235  }
1236  }
1237 
1238  @Override
1239  String getDisplayName() {
1240  MonthAbbreviation currentCutOffMonth = MonthAbbreviation.fromMonthValue(currentWeekCutOff.getMonthValue());
1241  return Bundle.DiscoveryAttributes_ActivityDateGroupKey_getDisplayNameTemplate(
1242  currentCutOffMonth.toString(), Integer.toString(currentWeekCutOff.getDayOfMonth()),
1243  Integer.toString(currentWeekCutOff.getYear()));
1244  }
1245 
1246  @Override
1247  public boolean equals(Object otherKey) {
1248  if (otherKey == this) {
1249  return true;
1250  }
1251 
1252  if (!(otherKey instanceof FirstActivityDateGroupKey)) {
1253  return false;
1254  }
1255 
1256  FirstActivityDateGroupKey dateGroupKey = (FirstActivityDateGroupKey) otherKey;
1257  return getDisplayName().equals(dateGroupKey.getDisplayName());
1258  }
1259 
1260  @Override
1261  public int hashCode() {
1262  return Objects.hash(getDisplayName());
1263  }
1264 
1265  @Override
1266  public int compareTo(GroupKey otherGroupKey) {
1267  if (otherGroupKey instanceof FirstActivityDateGroupKey) {
1268  FirstActivityDateGroupKey otherDateGroupKey = (FirstActivityDateGroupKey) otherGroupKey;
1269  return Long.compare(otherDateGroupKey.currentWeekCutOff.toEpochSecond(), currentWeekCutOff.toEpochSecond());
1270  } else {
1271  return compareClassNames(otherGroupKey);
1272  }
1273  }
1274  }
1275 
1281  static class PageViewsGroupKey extends GroupKey {
1282 
1283  private final String displayName;
1284  private final PageViews pageViews;
1285 
1291  PageViewsGroupKey(Result result) {
1292  if (result instanceof ResultDomain) {
1293  Long totalPageViews = ((ResultDomain) result).getTotalPageViews();
1294  if (totalPageViews == null) {
1295  totalPageViews = 0L;
1296  }
1297  pageViews = PageViews.fromPageViewCount(totalPageViews);
1298  displayName = pageViews.toString();
1299  } else {
1300  throw new IllegalArgumentException("Expected a domain instance only.");
1301  }
1302  }
1303 
1304  @Override
1305  String getDisplayName() {
1306  return displayName;
1307  }
1308 
1309  @Override
1310  public int hashCode() {
1311  return Objects.hash(displayName);
1312  }
1313 
1319  PageViews getPageViews() {
1320  return pageViews;
1321  }
1322 
1323  @Override
1324  public boolean equals(Object otherKey) {
1325  if (otherKey == this) {
1326  return true;
1327  }
1328 
1329  if (!(otherKey instanceof PageViewsGroupKey)) {
1330  return false;
1331  }
1332 
1333  PageViewsGroupKey pageViewsKey = (PageViewsGroupKey) otherKey;
1334  return pageViews.equals(pageViewsKey.getPageViews());
1335  }
1336 
1337  @Override
1338  public int compareTo(GroupKey otherGroupKey) {
1339  if (otherGroupKey instanceof PageViewsGroupKey) {
1340  PageViewsGroupKey pageViewsKey = (PageViewsGroupKey) otherGroupKey;
1341  return getPageViews().compareTo(pageViewsKey.getPageViews());
1342  } else {
1343  return compareClassNames(otherGroupKey);
1344  }
1345  }
1346  }
1347 
1351  static class ObjectDetectedGroupKey extends GroupKey {
1352 
1353  private final List<String> objectDetectedNames;
1354  private final String objectDetectedNamesString;
1355 
1361  @NbBundle.Messages({
1362  "DiscoveryKeyUtils.ObjectDetectedGroupKey.noSets=None"})
1363  ObjectDetectedGroupKey(ResultFile file) {
1364  objectDetectedNames = file.getObjectDetectedNames();
1365  if (objectDetectedNames.isEmpty()) {
1366  objectDetectedNamesString = Bundle.DiscoveryKeyUtils_ObjectDetectedGroupKey_noSets();
1367  } else {
1368  objectDetectedNamesString = String.join(",", objectDetectedNames); // NON-NLS
1369  }
1370  }
1371 
1372  @Override
1373  String getDisplayName() {
1374  return getObjectDetectedNamesString();
1375  }
1376 
1377  @Override
1378  public int compareTo(GroupKey otherGroupKey) {
1379  if (otherGroupKey instanceof ObjectDetectedGroupKey) {
1380  ObjectDetectedGroupKey otherObjectDetectedGroupKey = (ObjectDetectedGroupKey) otherGroupKey;
1381 
1382  // Put the empty list at the end
1383  if (this.getObjectDetectedNames().isEmpty()) {
1384  if (otherObjectDetectedGroupKey.getObjectDetectedNames().isEmpty()) {
1385  return 0;
1386  } else {
1387  return 1;
1388  }
1389  } else if (otherObjectDetectedGroupKey.getObjectDetectedNames().isEmpty()) {
1390  return -1;
1391  }
1392 
1393  return getObjectDetectedNamesString().compareTo(otherObjectDetectedGroupKey.getObjectDetectedNamesString());
1394  } else {
1395  return compareClassNames(otherGroupKey);
1396  }
1397  }
1398 
1399  @Override
1400  public boolean equals(Object otherKey) {
1401  if (otherKey == this) {
1402  return true;
1403  }
1404 
1405  if (!(otherKey instanceof ObjectDetectedGroupKey)) {
1406  return false;
1407  }
1408 
1409  ObjectDetectedGroupKey otherObjectDetectedGroupKey = (ObjectDetectedGroupKey) otherKey;
1410  return getObjectDetectedNamesString().equals(otherObjectDetectedGroupKey.getObjectDetectedNamesString());
1411  }
1412 
1413  @Override
1414  public int hashCode() {
1415  return Objects.hash(getObjectDetectedNamesString());
1416  }
1417 
1423  List<String> getObjectDetectedNames() {
1424  return Collections.unmodifiableList(objectDetectedNames);
1425  }
1426 
1434  String getObjectDetectedNamesString() {
1435  return objectDetectedNamesString;
1436  }
1437  }
1438 
1442  private DiscoveryKeyUtils() {
1443  //private constructor in a utility class intentionally left blank
1444  }
1445 }
static TimeZone getTimeZone(Content content)
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: Tue Jan 19 2021
This work is licensed under a Creative Commons Attribution-Share Alike 3.0 United States License.