19 package org.sleuthkit.autopsy.discovery.search;
 
   21 import java.sql.ResultSet;
 
   22 import java.sql.SQLException;
 
   23 import java.util.ArrayList;
 
   24 import java.util.Arrays;
 
   25 import java.util.HashMap;
 
   26 import java.util.HashSet;
 
   27 import java.util.Iterator;
 
   28 import java.util.List;
 
   31 import java.util.logging.Level;
 
   32 import org.openide.util.NbBundle;
 
   47 import java.util.StringJoiner;
 
  129     static class DataSourceAttribute 
extends AttributeType {
 
  132         public DiscoveryKeyUtils.GroupKey getGroupKey(Result result) {
 
  133             return new DiscoveryKeyUtils.DataSourceGroupKey(result);
 
  140     static class FileTypeAttribute 
extends AttributeType {
 
  143         public DiscoveryKeyUtils.GroupKey getGroupKey(Result file) {
 
  144             return new DiscoveryKeyUtils.FileTypeGroupKey(file);
 
  152     static class DomainCategoryAttribute 
extends AttributeType {
 
  155         public DiscoveryKeyUtils.GroupKey getGroupKey(Result result) {
 
  156             return new DiscoveryKeyUtils.DomainCategoryGroupKey(result);
 
  160         public void addAttributeToResults(List<Result> results, SleuthkitCase caseDb,
 
  161                 CentralRepository centralRepoDb, SearchContext context) 
throws DiscoveryException, SearchCancellationException {
 
  163                 Map<String, Set<String>> domainsToCategories = getDomainsWithWebCategories(caseDb, context);
 
  164                 for (Result result : results) {
 
  165                     if (context.searchIsCancelled()) {
 
  166                         throw new SearchCancellationException(
"The search was cancelled while Domain Category Attribute was being added.");
 
  168                     if (result instanceof ResultDomain) {
 
  169                         ResultDomain domain = (ResultDomain) result;
 
  170                         domain.addWebCategories(domainsToCategories.get(domain.getDomain()));
 
  173             } 
catch (TskCoreException | InterruptedException ex) {
 
  174                 throw new DiscoveryException(
"Error fetching TSK_WEB_CATEGORY artifacts from the database", ex);
 
  195         private Map<String, Set<String>> getDomainsWithWebCategories(SleuthkitCase caseDb, SearchContext context) 
throws TskCoreException, InterruptedException, SearchCancellationException {
 
  196             Map<String, Set<String>> domainToCategory = 
new HashMap<>();
 
  198             for (BlackboardArtifact artifact : caseDb.getBlackboardArtifacts(TSK_WEB_CATEGORIZATION)) {
 
  199                 if (Thread.currentThread().isInterrupted()) {
 
  200                     throw new InterruptedException();
 
  202                 if (context.searchIsCancelled()) {
 
  203                     throw new SearchCancellationException(
"Search was cancelled while getting domains for artifact type: " + artifact.getDisplayName());
 
  205                 BlackboardAttribute webCategory = artifact.getAttribute(
new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_NAME));
 
  206                 BlackboardAttribute domain = artifact.getAttribute(
new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DOMAIN));
 
  207                 if (webCategory != null && domain != null) {
 
  208                     String domainDisplayName = domain.getValueString().trim().toLowerCase();
 
  209                     if (!domainToCategory.containsKey(domainDisplayName)) {
 
  210                         domainToCategory.put(domainDisplayName, 
new HashSet<>());
 
  212                     domainToCategory.get(domainDisplayName).add(webCategory.getValueString());
 
  215             return domainToCategory;
 
  222     static class KeywordListAttribute 
extends AttributeType {
 
  225         public DiscoveryKeyUtils.GroupKey getGroupKey(Result file) {
 
  226             return new DiscoveryKeyUtils.KeywordListGroupKey((ResultFile) file);
 
  230         public void addAttributeToResults(List<Result> results, SleuthkitCase caseDb,
 
  231                 CentralRepository centralRepoDb, SearchContext context) 
throws DiscoveryException, SearchCancellationException {
 
  235             String selectQuery = 
createSetNameClause(results, BlackboardArtifact.ARTIFACT_TYPE.TSK_KEYWORD_HIT.getTypeID(),
 
  236                     BlackboardAttribute.ATTRIBUTE_TYPE.TSK_SET_NAME.getTypeID());
 
  237             SetKeywordListNamesCallback callback = 
new SetKeywordListNamesCallback(results);
 
  238             if (context.searchIsCancelled()) {
 
  239                 throw new SearchCancellationException(
"The search was cancelled while Keyword List Attribute was being added.");
 
  242                 caseDb.getCaseDbAccessManager().select(selectQuery, callback);
 
  243             } 
catch (TskCoreException ex) {
 
  244                 throw new DiscoveryException(
"Error looking up keyword list attributes", ex); 
 
  255             List<Result> resultFiles;
 
  263                 this.resultFiles = resultFiles;
 
  270                     Map<Long, ResultFile> tempMap = 
new HashMap<>();
 
  271                     for (
Result result : resultFiles) {
 
  281                             Long objId = rs.getLong(
"object_id"); 
 
  282                             String keywordListName = rs.getString(
"set_name"); 
 
  286                         } 
catch (SQLException ex) {
 
  287                             logger.log(Level.SEVERE, 
"Unable to get object_id or set_name from result set", ex); 
 
  290                 } 
catch (SQLException ex) {
 
  291                     logger.log(Level.SEVERE, 
"Failed to get keyword list names", ex); 
 
  319         final Map<String, List<ResultDomain>> resultDomainTable = 
new HashMap<>();
 
  322                 final String domainValue = domainInstance.getDomain();
 
  324                 final List<ResultDomain> bucket = resultDomainTable.getOrDefault(normalizedDomain, 
new ArrayList<>());
 
  325                 bucket.add(domainInstance);
 
  326                 resultDomainTable.put(normalizedDomain, bucket);
 
  327                 if (context.searchIsCancelled()) {
 
  331                 logger.log(Level.INFO, String.format(
"Domain [%s] failed normalization, skipping...", domainInstance.getDomain()));
 
  334         return resultDomainTable;
 
  343         StringJoiner joiner = 
new StringJoiner(
", ");
 
  344         for (String value : values) {
 
  345             joiner.add(
"'" + value + 
"'");
 
  347         return joiner.toString();
 
  353     static class PreviouslyNotableAttribute 
extends AttributeType {
 
  355         static final int DOMAIN_BATCH_SIZE = 500; 
 
  363         public void addAttributeToResults(List<Result> results, SleuthkitCase caseDb,
 
  364                 CentralRepository centralRepoDb, SearchContext context) 
throws DiscoveryException, SearchCancellationException {
 
  366             if (centralRepoDb != null) {
 
  367                 processFilesWithCr(results, centralRepoDb, context);
 
  385         private void processFilesWithCr(List<Result> results, CentralRepository centralRepo, SearchContext context) 
throws DiscoveryException, SearchCancellationException {
 
  387             List<ResultDomain> domainsBatch = 
new ArrayList<>();
 
  388             for (Result result : results) {
 
  389                 if (context.searchIsCancelled()) {
 
  390                     throw new SearchCancellationException(
"The search was cancelled while Previously Notable attribute was being calculated with the CR.");
 
  393                     domainsBatch.add((ResultDomain) result);
 
  394                     if (domainsBatch.size() == DOMAIN_BATCH_SIZE) {
 
  395                         queryPreviouslyNotable(domainsBatch, centralRepo, context);
 
  396                         domainsBatch.clear();
 
  401             queryPreviouslyNotable(domainsBatch, centralRepo, context);
 
  419         private void queryPreviouslyNotable(List<ResultDomain> domainsBatch, CentralRepository centralRepo, SearchContext context) 
throws DiscoveryException, SearchCancellationException {
 
  420             if (domainsBatch.isEmpty()) {
 
  425                 final CorrelationAttributeInstance.Type attributeType = centralRepo.getCorrelationTypeById(CorrelationAttributeInstance.DOMAIN_TYPE_ID);
 
  426                 final Map<String, List<ResultDomain>> resultDomainTable = 
organizeByValue(domainsBatch, attributeType, context);
 
  427                 final String values = 
createCSV(resultDomainTable.keySet());
 
  428                 if (context.searchIsCancelled()) {
 
  429                     throw new SearchCancellationException(
"Search was cancelled while checking for previously notable domains.");
 
  431                 final String tableName = CentralRepoDbUtil.correlationTypeToInstanceTableName(attributeType);
 
  432                 final String domainFrequencyQuery = 
" value AS domain_name " 
  433                         + 
"FROM " + tableName + 
" " 
  434                         + 
"WHERE value IN (" + values + 
") " 
  435                         + 
"AND known_status = " + TskData.FileKnown.BAD.getFileKnownValue();
 
  437                 final DomainPreviouslyNotableCallback previouslyNotableCallback = 
new DomainPreviouslyNotableCallback(resultDomainTable);
 
  438                 centralRepo.processSelectClause(domainFrequencyQuery, previouslyNotableCallback);
 
  440                 if (previouslyNotableCallback.getCause() != null) {
 
  441                     throw previouslyNotableCallback.getCause();
 
  443             } 
catch (CentralRepoException | SQLException ex) {
 
  444                 throw new DiscoveryException(
"Fatal exception encountered querying the CR.", ex);
 
  460                     while (resultSet.next()) {
 
  461                         String domain = resultSet.getString(
"domain_name");
 
  462                         List<ResultDomain> domainInstances = domainLookup.get(domain);
 
  464                             domainInstance.markAsPreviouslyNotableInCR();
 
  467                 } 
catch (SQLException ex) {
 
  475             SQLException getCause() {
 
  484     static class FrequencyAttribute 
extends AttributeType {
 
  486         static final int BATCH_SIZE = 50; 
 
  488         static final int DOMAIN_BATCH_SIZE = 500; 
 
  491         public DiscoveryKeyUtils.GroupKey getGroupKey(Result file) {
 
  492             return new DiscoveryKeyUtils.FrequencyGroupKey(file);
 
  496         public void addAttributeToResults(List<Result> results, SleuthkitCase caseDb,
 
  497                 CentralRepository centralRepoDb, SearchContext context) 
throws DiscoveryException, SearchCancellationException {
 
  498             if (centralRepoDb == null) {
 
  499                 for (Result result : results) {
 
  505                 processResultFilesForCR(results, centralRepoDb, context);
 
  524         private void processResultFilesForCR(List<Result> results,
 
  525                 CentralRepository centralRepoDb, SearchContext context) 
throws DiscoveryException, SearchCancellationException {
 
  526             List<ResultFile> currentFiles = 
new ArrayList<>();
 
  527             Set<String> hashesToLookUp = 
new HashSet<>();
 
  528             List<ResultDomain> domainsToQuery = 
new ArrayList<>();
 
  529             for (Result result : results) {
 
  530                 if (context.searchIsCancelled()) {
 
  531                     throw new SearchCancellationException(
"The search was cancelled while Frequency attribute was being calculated with the CR.");
 
  540                         ResultFile file = (ResultFile) result;
 
  541                         if (file.getFirstInstance().getMd5Hash() != null
 
  542                                 && !file.getFirstInstance().getMd5Hash().isEmpty()) {
 
  543                             hashesToLookUp.add(file.getFirstInstance().getMd5Hash());
 
  544                             currentFiles.add(file);
 
  547                         if (hashesToLookUp.size() >= BATCH_SIZE) {
 
  550                             hashesToLookUp.clear();
 
  551                             currentFiles.clear();
 
  554                         domainsToQuery.add((ResultDomain) result);
 
  555                         if (domainsToQuery.size() == DOMAIN_BATCH_SIZE) {
 
  557                             domainsToQuery.clear();
 
  582         if (domainsToQuery.isEmpty()) {
 
  587             final Map<String, List<ResultDomain>> resultDomainTable = 
organizeByValue(domainsToQuery, attributeType, context);
 
  588             final String values = 
createCSV(resultDomainTable.keySet());
 
  590             final String domainFrequencyQuery = 
" value AS domain_name, COUNT(value) AS frequency FROM" 
  591                     + 
"(SELECT DISTINCT case_id, value FROM " 
  593                     + 
" WHERE value IN (" 
  595                     + 
")) AS foo GROUP BY value";
 
  599             centralRepository.processSelectClause(domainFrequencyQuery, frequencyCallback);
 
  600             if (context.searchIsCancelled()) {
 
  603             if (frequencyCallback.getCause() != null) {
 
  604                 throw frequencyCallback.getCause();
 
  607             throw new DiscoveryException(
"Fatal exception encountered querying the CR.", ex);
 
  631                 while (resultSet.next()) {
 
  632                     String domain = resultSet.getString(
"domain_name");
 
  633                     Long frequency = resultSet.getLong(
"frequency");
 
  635                     List<ResultDomain> domainInstances = domainLookup.get(domain);
 
  640             } 
catch (SQLException ex) {
 
  650         SQLException getCause() {
 
  661         private final List<ResultFile> 
files;
 
  669             this.files = 
new ArrayList<>(
files);
 
  676                 while (resultSet.next()) {
 
  677                     String hash = resultSet.getString(1);
 
  678                     int count = resultSet.getInt(2);
 
  679                     for (Iterator<ResultFile> iterator = files.iterator(); iterator.hasNext();) {
 
  692             } 
catch (SQLException ex) {
 
  693                 logger.log(Level.WARNING, 
"Error getting frequency counts from Central Repository", ex); 
 
  708             return new DiscoveryKeyUtils.HashHitsGroupKey((ResultFile) result);
 
  712         public void addAttributeToResults(List<Result> results, SleuthkitCase caseDb,
 
  713                 CentralRepository centralRepoDb, SearchContext context) 
throws DiscoveryException, SearchCancellationException {
 
  717             String selectQuery = 
createSetNameClause(results, BlackboardArtifact.ARTIFACT_TYPE.TSK_HASHSET_HIT.getTypeID(),
 
  718                     BlackboardAttribute.ATTRIBUTE_TYPE.TSK_SET_NAME.getTypeID());
 
  720             HashSetNamesCallback callback = 
new HashSetNamesCallback(results);
 
  721             if (context.searchIsCancelled()) {
 
  722                 throw new SearchCancellationException(
"The search was cancelled while Hash Hit attribute was being added.");
 
  725                 caseDb.getCaseDbAccessManager().select(selectQuery, callback);
 
  726             } 
catch (TskCoreException ex) {
 
  727                 throw new DiscoveryException(
"Error looking up hash set attributes", ex); 
 
  737             List<Result> results;
 
  745                 this.results = results;
 
  752                     Map<Long, ResultFile> tempMap = 
new HashMap<>();
 
  753                     for (
Result result : results) {
 
  763                             Long objId = rs.getLong(
"object_id"); 
 
  764                             String hashSetName = rs.getString(
"set_name"); 
 
  766                             tempMap.get(objId).addHashSetName(hashSetName);
 
  768                         } 
catch (SQLException ex) {
 
  769                             logger.log(Level.SEVERE, 
"Unable to get object_id or set_name from result set", ex); 
 
  772                 } 
catch (SQLException ex) {
 
  773                     logger.log(Level.SEVERE, 
"Failed to get hash set names", ex); 
 
  782     static class InterestingItemAttribute 
extends AttributeType {
 
  790         public void addAttributeToResults(List<Result> results, SleuthkitCase caseDb,
 
  791                 CentralRepository centralRepoDb, SearchContext context) 
throws DiscoveryException, SearchCancellationException {
 
  795             String selectQuery = 
createSetNameClause(results, BlackboardArtifact.ARTIFACT_TYPE.TSK_INTERESTING_ITEM.getTypeID(),
 
  796                     BlackboardAttribute.ATTRIBUTE_TYPE.TSK_SET_NAME.getTypeID());
 
  798             InterestingFileSetNamesCallback callback = 
new InterestingFileSetNamesCallback(results);
 
  799             if (context.searchIsCancelled()) {
 
  800                 throw new SearchCancellationException(
"The search was cancelled while Interesting Item attribute was being added.");
 
  803                 caseDb.getCaseDbAccessManager().select(selectQuery, callback);
 
  804             } 
catch (TskCoreException ex) {
 
  805                 throw new DiscoveryException(
"Error looking up interesting file set attributes", ex); 
 
  816             List<Result> results;
 
  825                 this.results = results;
 
  832                     Map<Long, ResultFile> tempMap = 
new HashMap<>();
 
  833                     for (
Result result : results) {
 
  843                             Long objId = rs.getLong(
"object_id"); 
 
  844                             String setName = rs.getString(
"set_name"); 
 
  846                             tempMap.get(objId).addInterestingSetName(setName);
 
  848                         } 
catch (SQLException ex) {
 
  849                             logger.log(Level.SEVERE, 
"Unable to get object_id or set_name from result set", ex); 
 
  852                 } 
catch (SQLException ex) {
 
  853                     logger.log(Level.SEVERE, 
"Failed to get interesting file set names", ex); 
 
  862     static class LastActivityDateAttribute 
extends AttributeType {
 
  874     static class FirstActivityDateAttribute 
extends AttributeType {
 
  877         public DiscoveryKeyUtils.GroupKey getGroupKey(Result result) {
 
  878             return new DiscoveryKeyUtils.FirstActivityDateGroupKey(result);
 
  887     static class PageViewsAttribute 
extends AttributeType {
 
  890         public DiscoveryKeyUtils.GroupKey getGroupKey(Result result) {
 
  891             return new DiscoveryKeyUtils.PageViewsGroupKey(result);
 
  898     static class ObjectDetectedAttribute 
extends AttributeType {
 
  901         public DiscoveryKeyUtils.GroupKey getGroupKey(Result file) {
 
  902             return new DiscoveryKeyUtils.ObjectDetectedGroupKey((ResultFile) file);
 
  906         public void addAttributeToResults(List<Result> results, SleuthkitCase caseDb,
 
  907                 CentralRepository centralRepoDb, SearchContext context) 
throws DiscoveryException, SearchCancellationException {
 
  911             String selectQuery = 
createSetNameClause(results, BlackboardArtifact.ARTIFACT_TYPE.TSK_OBJECT_DETECTED.getTypeID(),
 
  912                     BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DESCRIPTION.getTypeID());
 
  914             ObjectDetectedNamesCallback callback = 
new ObjectDetectedNamesCallback(results);
 
  915             if (context.searchIsCancelled()) {
 
  916                 throw new SearchCancellationException(
"The search was cancelled while Object Detected attribute was being added.");
 
  919                 caseDb.getCaseDbAccessManager().select(selectQuery, callback);
 
  920             } 
catch (TskCoreException ex) {
 
  921                 throw new DiscoveryException(
"Error looking up object detected attributes", ex); 
 
  932             List<Result> results;
 
  940                 this.results = results;
 
  947                     Map<Long, ResultFile> tempMap = 
new HashMap<>();
 
  948                     for (
Result result : results) {
 
  958                             Long objId = rs.getLong(
"object_id"); 
 
  959                             String setName = rs.getString(
"set_name"); 
 
  961                             tempMap.get(objId).addObjectDetectedName(setName);
 
  963                         } 
catch (SQLException ex) {
 
  964                             logger.log(Level.SEVERE, 
"Unable to get object_id or set_name from result set", ex); 
 
  967                 } 
catch (SQLException ex) {
 
  968                     logger.log(Level.SEVERE, 
"Failed to get object detected names", ex); 
 
  985         public void addAttributeToResults(List<Result> results, SleuthkitCase caseDb,
 
  986                 CentralRepository centralRepoDb, SearchContext context) 
throws DiscoveryException, SearchCancellationException {
 
  989                 for (Result result : results) {
 
  990                     if (context.searchIsCancelled()) {
 
  991                         throw new SearchCancellationException(
"The search was cancelled while File Tag attribute was being added.");
 
  996                     ResultFile file = (ResultFile) result;
 
  997                     List<ContentTag> contentTags = caseDb.getContentTagsByContent(file.getFirstInstance());
 
  999                     for (ContentTag tag : contentTags) {
 
 1000                         result.
addTagName(tag.getName().getDisplayName());
 
 1003             } 
catch (TskCoreException ex) {
 
 1004                 throw new DiscoveryException(
"Error looking up file tag attributes", ex); 
 
 1012     @NbBundle.Messages({
 
 1013         "DiscoveryAttributes.GroupingAttributeType.fileType.displayName=File Type",
 
 1014         "DiscoveryAttributes.GroupingAttributeType.frequency.displayName=Past Occurrences",
 
 1015         "DiscoveryAttributes.GroupingAttributeType.keywordList.displayName=Keyword",
 
 1016         "DiscoveryAttributes.GroupingAttributeType.size.displayName=File Size",
 
 1017         "DiscoveryAttributes.GroupingAttributeType.datasource.displayName=Data Source",
 
 1018         "DiscoveryAttributes.GroupingAttributeType.parent.displayName=Parent Folder",
 
 1019         "DiscoveryAttributes.GroupingAttributeType.hash.displayName=Hash Set",
 
 1020         "DiscoveryAttributes.GroupingAttributeType.interestingItem.displayName=Interesting Item",
 
 1021         "DiscoveryAttributes.GroupingAttributeType.tag.displayName=Tag",
 
 1022         "DiscoveryAttributes.GroupingAttributeType.object.displayName=Object Detected",
 
 1023         "DiscoveryAttributes.GroupingAttributeType.lastDate.displayName=Final Activity Date",
 
 1024         "DiscoveryAttributes.GroupingAttributeType.firstDate.displayName=First Activity Date",
 
 1025         "DiscoveryAttributes.GroupingAttributeType.pageViews.displayName=Page Views",
 
 1026         "DiscoveryAttributes.GroupingAttributeType.none.displayName=None",
 
 1027         "DiscoveryAttributes.GroupingAttributeType.previouslyNotable.displayName=Previous Notability",
 
 1028         "DiscoveryAttributes.GroupingAttributeType.webCategory.displayName=Domain Category"})
 
 1031         FREQUENCY(
new FrequencyAttribute(), Bundle.DiscoveryAttributes_GroupingAttributeType_frequency_displayName()),
 
 1032         KEYWORD_LIST_NAME(
new KeywordListAttribute(), Bundle.DiscoveryAttributes_GroupingAttributeType_keywordList_displayName()),
 
 1033         DATA_SOURCE(
new DataSourceAttribute(), Bundle.DiscoveryAttributes_GroupingAttributeType_datasource_displayName()),
 
 1035         HASH_LIST_NAME(
new HashHitsAttribute(), Bundle.DiscoveryAttributes_GroupingAttributeType_hash_displayName()),
 
 1036         INTERESTING_ITEM_SET(
new InterestingItemAttribute(), Bundle.DiscoveryAttributes_GroupingAttributeType_interestingItem_displayName()),
 
 1037         FILE_TAG(
new FileTagAttribute(), Bundle.DiscoveryAttributes_GroupingAttributeType_tag_displayName()),
 
 1038         OBJECT_DETECTED(
new ObjectDetectedAttribute(), Bundle.DiscoveryAttributes_GroupingAttributeType_object_displayName()),
 
 1039         LAST_ACTIVITY_DATE(
new LastActivityDateAttribute(), Bundle.DiscoveryAttributes_GroupingAttributeType_lastDate_displayName()),
 
 1040         FIRST_ACTIVITY_DATE(
new FirstActivityDateAttribute(), Bundle.DiscoveryAttributes_GroupingAttributeType_firstDate_displayName()),
 
 1041         PAGE_VIEWS(
new PageViewsAttribute(), Bundle.DiscoveryAttributes_GroupingAttributeType_pageViews_displayName()),
 
 1042         NO_GROUPING(
new NoGroupingAttribute(), Bundle.DiscoveryAttributes_GroupingAttributeType_none_displayName()),
 
 1043         PREVIOUSLY_NOTABLE(
new PreviouslyNotableAttribute(), Bundle.DiscoveryAttributes_GroupingAttributeType_previouslyNotable_displayName()),
 
 1044         DOMAIN_CATEGORY(
new DomainCategoryAttribute(), Bundle.DiscoveryAttributes_GroupingAttributeType_webCategory_displayName());
 
 1058             this.attributeType = attributeType;
 
 1059             this.displayName = displayName;
 
 1073             return attributeType;
 
 1082             return Arrays.asList(FILE_SIZE, FREQUENCY, PARENT_PATH, OBJECT_DETECTED, HASH_LIST_NAME, INTERESTING_ITEM_SET);
 
 1092                 return Arrays.asList(PAGE_VIEWS, FREQUENCY, LAST_ACTIVITY_DATE, FIRST_ACTIVITY_DATE, PREVIOUSLY_NOTABLE, DOMAIN_CATEGORY);
 
 1094                 return Arrays.asList(PAGE_VIEWS, LAST_ACTIVITY_DATE, FIRST_ACTIVITY_DATE, DOMAIN_CATEGORY);
 
 1115         if (hashesToLookUp.isEmpty()) {
 
 1119         String hashes = String.join(
"','", hashesToLookUp);
 
 1120         hashes = 
"'" + hashes + 
"'";
 
 1125             String selectClause = 
" value, COUNT(value) FROM " 
 1126                     + 
"(SELECT DISTINCT case_id, value FROM " + tableName
 
 1127                     + 
" WHERE value IN (" 
 1129                     + 
")) AS foo GROUP BY value";
 
 1132             centralRepoDb.processSelectClause(selectClause, callback);
 
 1133             if (context.searchIsCancelled()) {
 
 1137             logger.log(Level.WARNING, 
"Error getting frequency counts from Central Repository", ex); 
 
 1156             int artifactTypeID, 
int setNameAttrID) 
throws DiscoveryException {
 
 1159         String objIdList = 
""; 
 
 1160         for (
Result result : results) {
 
 1165             if (!objIdList.isEmpty()) {
 
 1173         return "blackboard_artifacts.obj_id AS object_id, blackboard_attributes.value_text AS set_name " 
 1174                 + 
"FROM blackboard_artifacts " 
 1175                 + 
"INNER JOIN blackboard_attributes ON blackboard_artifacts.artifact_id=blackboard_attributes.artifact_id " 
 1176                 + 
"WHERE blackboard_attributes.artifact_type_id=\'" + artifactTypeID + 
"\' " 
 1177                 + 
"AND blackboard_attributes.attribute_type_id=\'" + setNameAttrID + 
"\' " 
 1178                 + 
"AND blackboard_artifacts.obj_id IN (" + objIdList
 
static String createSetNameClause(List< Result > results, int artifactTypeID, int setNameAttrID)
 
AttributeType getAttributeType()
 
DiscoveryKeyUtils.GroupKey getGroupKey(Result file)
 
DomainPreviouslyNotableCallback(Map< String, List< ResultDomain >> domainLookup)
 
static List< GroupingAttributeType > getOptionsForGroupingForDomains()
 
DomainFrequencyCallback(Map< String, List< ResultDomain >> domainLookup)
 
SearchData.Frequency getFrequency()
 
void process(ResultSet rs)
 
abstract TskData.FileKnown getKnown()
 
static final Logger logger
 
void process(ResultSet resultSet)
 
void addTagName(String tagName)
 
static Frequency fromCount(long count)
 
abstract SearchData.Type getType()
 
FrequencyCallback(List< ResultFile > files)
 
GroupingAttributeType(AttributeType attributeType, String displayName)
 
static List< GroupingAttributeType > getOptionsForGroupingForFiles()
 
static void queryDomainFrequency(List< ResultDomain > domainsToQuery, CentralRepository centralRepository, SearchContext context)
 
final void setFrequency(SearchData.Frequency frequency)
 
static String correlationTypeToInstanceTableName(CorrelationAttributeInstance.Type type)
 
static String normalize(CorrelationAttributeInstance.Type attributeType, String data)
 
void addAttributeToResults(List< Result > results, SleuthkitCase caseDb, CentralRepository centralRepoDb, SearchContext context)
 
AbstractFile getFirstInstance()
 
void process(ResultSet resultSet)
 
DiscoveryKeyUtils.GroupKey getGroupKey(Result result)
 
static final int DOMAIN_TYPE_ID
 
void process(ResultSet rs)
 
abstract DiscoveryKeyUtils.GroupKey getGroupKey(Result result)
 
final List< ResultFile > files
 
final Map< String, List< ResultDomain > > domainLookup
 
void process(ResultSet rs)
 
void addKeywordListName(String keywordListName)
 
final Map< String, List< ResultDomain > > domainLookup
 
void process(ResultSet rs)
 
static Map< String, List< ResultDomain > > organizeByValue(List< ResultDomain > domainsBatch, CorrelationAttributeInstance.Type attributeType, SearchContext context)
 
synchronized static Logger getLogger(String name)
 
void process(ResultSet resultSet)
 
static String createCSV(Set< String > values)
 
static void computeFrequency(Set< String > hashesToLookUp, List< ResultFile > currentFiles, CentralRepository centralRepoDb, SearchContext context)
 
static final int FILES_TYPE_ID
 
final AttributeType attributeType
 
static boolean isEnabled()