diff --git a/Core/src/org/sleuthkit/autopsy/corecomponents/DataResultPanel.java b/Core/src/org/sleuthkit/autopsy/corecomponents/DataResultPanel.java index 6876ccb704..0aec7d9650 100644 --- a/Core/src/org/sleuthkit/autopsy/corecomponents/DataResultPanel.java +++ b/Core/src/org/sleuthkit/autopsy/corecomponents/DataResultPanel.java @@ -72,7 +72,7 @@ import org.sleuthkit.autopsy.mainui.datamodel.AnalysisResultDAO.AnalysisResultFe import org.sleuthkit.autopsy.mainui.datamodel.AnalysisResultDAO.AnalysisResultConfigFetcher; import org.sleuthkit.autopsy.mainui.datamodel.AnalysisResultDAO.KeywordHitResultFetcher; import org.sleuthkit.autopsy.mainui.datamodel.AnalysisResultSearchParam; -import org.sleuthkit.autopsy.mainui.datamodel.AnalysisResultConfigSearchParam; +import org.sleuthkit.autopsy.mainui.datamodel.AnalysisResultSearchParam; import org.sleuthkit.autopsy.mainui.datamodel.CommAccountsDAO.CommAccountFetcher; import org.sleuthkit.autopsy.mainui.datamodel.CreditCardBinSearchParams; import org.sleuthkit.autopsy.mainui.datamodel.CreditCardDAO.CreditCardByBinFetcher; @@ -1440,7 +1440,7 @@ public class DataResultPanel extends javax.swing.JPanel implements DataResult, C * * @param setKey The search parameter query. */ - void displayAnalysisResultSet(AnalysisResultConfigSearchParam setKey) { + void displayAnalysisResultSet(AnalysisResultSearchParam setKey) { try { this.searchResultManager = new SearchManager(new AnalysisResultConfigFetcher(setKey), getPageSize()); SearchResultsDTO results = searchResultManager.getResults(); diff --git a/Core/src/org/sleuthkit/autopsy/corecomponents/DataResultTopComponent.java b/Core/src/org/sleuthkit/autopsy/corecomponents/DataResultTopComponent.java index 799a0c017b..b58fba38ba 100644 --- a/Core/src/org/sleuthkit/autopsy/corecomponents/DataResultTopComponent.java +++ b/Core/src/org/sleuthkit/autopsy/corecomponents/DataResultTopComponent.java @@ -45,7 +45,7 @@ import org.sleuthkit.autopsy.directorytree.ExternalViewerShortcutAction; import org.sleuthkit.autopsy.mainui.datamodel.AnalysisResultSearchParam; import org.sleuthkit.autopsy.mainui.datamodel.FileSystemContentSearchParam; import org.sleuthkit.autopsy.mainui.datamodel.FileSystemHostSearchParam; -import org.sleuthkit.autopsy.mainui.datamodel.AnalysisResultConfigSearchParam; +import org.sleuthkit.autopsy.mainui.datamodel.AnalysisResultSearchParam; import org.sleuthkit.autopsy.mainui.datamodel.CommAccountsSearchParams; import org.sleuthkit.autopsy.mainui.datamodel.CreditCardBinSearchParams; import org.sleuthkit.autopsy.mainui.datamodel.CreditCardFileSearchParams; @@ -468,7 +468,7 @@ public final class DataResultTopComponent extends TopComponent implements DataRe * Displays results of querying the DAO for an artifact type and set name. * @param params The search parameters. */ - public void displayAnalysisResultConfig(AnalysisResultConfigSearchParam params) { + public void displayAnalysisResultConfig(AnalysisResultSearchParam params) { dataResultPanel.displayAnalysisResultSet(params); } diff --git a/Core/src/org/sleuthkit/autopsy/mainui/datamodel/AnalysisResultConfigSearchParam.java b/Core/src/org/sleuthkit/autopsy/mainui/datamodel/AnalysisResultConfigSearchParam.java deleted file mode 100644 index 865d2a2b97..0000000000 --- a/Core/src/org/sleuthkit/autopsy/mainui/datamodel/AnalysisResultConfigSearchParam.java +++ /dev/null @@ -1,75 +0,0 @@ -/* - * Autopsy Forensic Browser - * - * Copyright 2021 Basis Technology Corp. - * Contact: carrier sleuthkit org - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.sleuthkit.autopsy.mainui.datamodel; - -import java.util.Objects; -import org.sleuthkit.datamodel.BlackboardArtifact; - -/** - * Base class for search params for analysis results that filter by configuration. - */ -public class AnalysisResultConfigSearchParam extends AnalysisResultSearchParam { - - private static final String TYPE_ID = "ANALYSIS_RESULT_CONFIG"; - - /** - * @return The type id for this search parameter. - */ - public static String getTypeId() { - return TYPE_ID; - } - - final String configuration; - - public AnalysisResultConfigSearchParam(BlackboardArtifact.Type artifactType, Long dataSourceId, String configuration) { - super(artifactType, dataSourceId); - this.configuration = configuration; - } - - public String getConfiguration() { - return configuration; - } - - @Override - public int hashCode() { - int hash = 3; - hash = 79 * hash + Objects.hashCode(this.configuration); - hash = 79 * hash + super.hashCode(); - return hash; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) { - return true; - } - if (obj == null) { - return false; - } - if (getClass() != obj.getClass()) { - return false; - } - final AnalysisResultConfigSearchParam other = (AnalysisResultConfigSearchParam) obj; - if (!Objects.equals(this.configuration, other.configuration)) { - return false; - } - return super.equals(obj); - } - -} diff --git a/Core/src/org/sleuthkit/autopsy/mainui/datamodel/AnalysisResultDAO.java b/Core/src/org/sleuthkit/autopsy/mainui/datamodel/AnalysisResultDAO.java index eb2725506a..f34ceb2309 100644 --- a/Core/src/org/sleuthkit/autopsy/mainui/datamodel/AnalysisResultDAO.java +++ b/Core/src/org/sleuthkit/autopsy/mainui/datamodel/AnalysisResultDAO.java @@ -18,7 +18,7 @@ */ package org.sleuthkit.autopsy.mainui.datamodel; -import org.sleuthkit.autopsy.mainui.datamodel.events.AnalysisResultConfigEvent; +import org.sleuthkit.autopsy.mainui.datamodel.events.AnalysisResultEvent; import org.sleuthkit.autopsy.mainui.datamodel.events.AnalysisResultEvent; import org.sleuthkit.autopsy.mainui.datamodel.events.DAOEvent; import com.google.common.cache.Cache; @@ -143,7 +143,7 @@ public class AnalysisResultDAO extends BlackboardArtifactDAO { } private final Cache, AnalysisResultTableSearchResultsDTO> analysisResultCache = CacheBuilder.newBuilder().maximumSize(CACHE_SIZE).expireAfterAccess(CACHE_DURATION, CACHE_DURATION_UNITS).build(); - private final Cache, AnalysisResultTableSearchResultsDTO> configHitCache = CacheBuilder.newBuilder().maximumSize(CACHE_SIZE).expireAfterAccess(CACHE_DURATION, CACHE_DURATION_UNITS).build(); + private final Cache, AnalysisResultTableSearchResultsDTO> configHitCache = CacheBuilder.newBuilder().maximumSize(CACHE_SIZE).expireAfterAccess(CACHE_DURATION, CACHE_DURATION_UNITS).build(); private final Cache, AnalysisResultTableSearchResultsDTO> keywordHitCache = CacheBuilder.newBuilder().maximumSize(CACHE_SIZE).expireAfterAccess(CACHE_DURATION, CACHE_DURATION_UNITS).build(); private final TreeCounts treeCounts = new TreeCounts<>(); @@ -187,7 +187,7 @@ public class AnalysisResultDAO extends BlackboardArtifactDAO { } // filters results by configuration attr and needs a search param with the configuration - private AnalysisResultTableSearchResultsDTO fetchConfigResultsForTable(SearchParams cacheKey) throws NoCurrentCaseException, TskCoreException { + private AnalysisResultTableSearchResultsDTO fetchConfigResultsForTable(SearchParams cacheKey) throws NoCurrentCaseException, TskCoreException { SleuthkitCase skCase = getCase(); Blackboard blackboard = skCase.getBlackboard(); @@ -282,16 +282,16 @@ public class AnalysisResultDAO extends BlackboardArtifactDAO { && (key.getDataSourceId() == null || key.getDataSourceId() == analysisResultEvt.getDataSourceId()); } - private boolean isAnalysisResultsConfigInvalidating(AnalysisResultConfigSearchParam key, DAOEvent event) { + private boolean isAnalysisResultsConfigInvalidating(AnalysisResultSearchParam key, DAOEvent event) { if (event instanceof DeleteAnalysisResultEvent) { return true; } - if (!(event instanceof AnalysisResultConfigEvent)) { + if (!(event instanceof AnalysisResultEvent)) { return false; } - AnalysisResultConfigEvent setEvent = (AnalysisResultConfigEvent) event; + AnalysisResultEvent setEvent = (AnalysisResultEvent) event; return isAnalysisResultsInvalidating(key, setEvent) && Objects.equals(key.getConfiguration(), setEvent.getConfiguration()); } @@ -313,14 +313,14 @@ public class AnalysisResultDAO extends BlackboardArtifactDAO { } - public AnalysisResultTableSearchResultsDTO getAnalysisResultConfigResults(AnalysisResultConfigSearchParam artifactKey, long startItem, Long maxCount) throws ExecutionException, IllegalArgumentException { + public AnalysisResultTableSearchResultsDTO getAnalysisResultConfigResults(AnalysisResultSearchParam artifactKey, long startItem, Long maxCount) throws ExecutionException, IllegalArgumentException { if (artifactKey.getDataSourceId() != null && artifactKey.getDataSourceId() < 0) { throw new IllegalArgumentException(MessageFormat.format("Illegal data. " + "Data source id must be null or > 0. " + "Received data source id: {0}", artifactKey.getDataSourceId() == null ? "" : artifactKey.getDataSourceId())); } - SearchParams searchParams = new SearchParams<>(artifactKey, startItem, maxCount); + SearchParams searchParams = new SearchParams<>(artifactKey, startItem, maxCount); return configHitCache.get(searchParams, () -> fetchConfigResultsForTable(searchParams)); } @@ -362,7 +362,7 @@ public class AnalysisResultDAO extends BlackboardArtifactDAO { ? TreeDisplayCount.INDETERMINATE : TreeDisplayCount.getDeterminate(entry.getValue().getLeft()); - return getTreeItem(entry.getKey(), dataSourceId, displayCount, entry.getValue().getRight()); + return getTreeItem(entry.getKey(), null, dataSourceId, displayCount, entry.getValue().getRight()); }) .sorted(Comparator.comparing(countRow -> countRow.getDisplayName())) .collect(Collectors.toList()); @@ -488,21 +488,21 @@ public class AnalysisResultDAO extends BlackboardArtifactDAO { * @throws IllegalArgumentException * @throws ExecutionException */ - public TreeResultsDTO getConfigurationCounts( + public TreeResultsDTO getConfigurationCounts( BlackboardArtifact.Type type, Long dataSourceId, String blankConfigName) throws IllegalArgumentException, ExecutionException { Set indeterminateConfigCounts = new HashSet<>(); for (AnalysisResultEvent evt : this.treeCounts.getEnqueued()) { - if (evt instanceof AnalysisResultConfigEvent + if (evt instanceof AnalysisResultEvent && (dataSourceId == null || Objects.equals(evt.getDataSourceId(), dataSourceId)) && evt.getArtifactType().equals(type)) { - indeterminateConfigCounts.add(((AnalysisResultConfigEvent) evt).getConfiguration()); + indeterminateConfigCounts.add(((AnalysisResultEvent) evt).getConfiguration()); } } - List> allConfigurations + List> allConfigurations = getConfigurationCountsMap(type, dataSourceId).entrySet().stream() .sorted((a, b) -> compareStrings(a.getKey(), b.getKey())) .map(entry -> { @@ -539,7 +539,7 @@ public class AnalysisResultDAO extends BlackboardArtifactDAO { * @throws IllegalArgumentException * @throws ExecutionException */ - public TreeResultsDTO getKwSetCounts( + public TreeResultsDTO getKwSetCounts( Long dataSourceId, String nullSetName) throws IllegalArgumentException, ExecutionException { @@ -551,7 +551,7 @@ public class AnalysisResultDAO extends BlackboardArtifactDAO { } } - List> allSets = new ArrayList<>(); + List> allSets = new ArrayList<>(); try { // get artifact types and counts SleuthkitCase skCase = getCase(); @@ -577,7 +577,7 @@ public class AnalysisResultDAO extends BlackboardArtifactDAO { ? TreeDisplayCount.INDETERMINATE : TreeDisplayCount.getDeterminate(resultSet.getLong("count")); - allSets.add(getSetTreeItem(BlackboardArtifact.Type.TSK_KEYWORD_HIT, + allSets.add(getKeywordListTreeItem( dataSourceId, setName, StringUtils.isBlank(setName) ? nullSetName : setName, @@ -1036,8 +1036,8 @@ public class AnalysisResultDAO extends BlackboardArtifactDAO { Map> keywordHitsMap, boolean ingestIsRunning) { - List analysisResultConfigEvents = resultsWithConfigMap.entrySet().stream() - .flatMap(entry -> entry.getValue().stream().map(dsId -> new AnalysisResultConfigEvent(entry.getKey().getRight(), entry.getKey().getLeft(), dsId))) + List AnalysisResultEvents = resultsWithConfigMap.entrySet().stream() + .flatMap(entry -> entry.getValue().stream().map(dsId -> new AnalysisResultEvent(entry.getKey().getLeft(), entry.getKey().getRight(), dsId))) .collect(Collectors.toList()); // divide into ad hoc searches (null set name) and the rest @@ -1053,7 +1053,7 @@ public class AnalysisResultDAO extends BlackboardArtifactDAO { .collect(Collectors.partitioningBy(kwe -> kwe.getSetName() == null)); // include config results in regular events. - List daoEvents = Stream.of(analysisResultConfigEvents, keywordHitEvts.get(false)) + List daoEvents = Stream.of(AnalysisResultEvents, keywordHitEvts.get(false)) .filter(lst -> lst != null) .flatMap(s -> s.stream()) .collect(Collectors.toList()); @@ -1106,39 +1106,41 @@ public class AnalysisResultDAO extends BlackboardArtifactDAO { khEvt.getConfiguration(), displayCount ); - } else if (arEvt instanceof AnalysisResultConfigEvent) { - AnalysisResultConfigEvent configEvent = (AnalysisResultConfigEvent) arEvt; + } else if (arEvt instanceof AnalysisResultEvent) { + AnalysisResultEvent configEvent = (AnalysisResultEvent) arEvt; return getConfigTreeItem(configEvent.getArtifactType(), configEvent.getDataSourceId(), configEvent.getConfiguration(), configEvent.getConfiguration(), displayCount); } else { - return getTreeItem(arEvt.getArtifactType(), arEvt.getDataSourceId(), displayCount, null); + return getTreeItem(arEvt.getArtifactType(), arEvt.getConfiguration(), arEvt.getDataSourceId(), displayCount, null); } } - private TreeItemDTO getConfigTreeItem(BlackboardArtifact.Type type, + private TreeItemDTO getConfigTreeItem(BlackboardArtifact.Type type, Long dataSourceId, String configuration, String displayName, TreeDisplayCount displayCount) { return new TreeItemDTO<>( - AnalysisResultConfigSearchParam.getTypeId(), - new AnalysisResultConfigSearchParam(type, dataSourceId, configuration), + AnalysisResultSearchParam.getTypeId(), + new AnalysisResultSearchParam(type, configuration, dataSourceId), configuration == null ? 0 : configuration, displayName, displayCount); } - private TreeItemDTO getSetTreeItem(BlackboardArtifact.Type type, + private TreeItemDTO getKeywordListTreeItem( Long dataSourceId, String setName, String displayName, TreeDisplayCount displayCount) { return new TreeItemDTO<>( - AnalysisResultSetSearchParam.getTypeId(), - new AnalysisResultSetSearchParam(type, dataSourceId, setName), + KeywordListSearchParam.getTypeId(), + // there are one to many for keyword lists to configuration so leave as null + new KeywordListSearchParam(dataSourceId, null, setName), setName == null ? 0 : setName, displayName, displayCount); } - private TreeItemDTO getTreeItem(BlackboardArtifact.Type type, Long dataSourceId, TreeDisplayCount displayCount, Boolean hasChildren) { - return new AnalysisResultTreeItem(type, dataSourceId, displayCount, hasChildren); + private TreeItemDTO getTreeItem(BlackboardArtifact.Type type, String configuration, + Long dataSourceId, TreeDisplayCount displayCount, Boolean hasChildren) { + return new AnalysisResultTreeItem(type, configuration, dataSourceId, displayCount, hasChildren); } @Override @@ -1238,9 +1240,9 @@ public class AnalysisResultDAO extends BlackboardArtifactDAO { private final Optional hasChildren; - public AnalysisResultTreeItem(BlackboardArtifact.Type type, Long dataSourceId, TreeDisplayCount displayCount, Boolean hasChildren) { + public AnalysisResultTreeItem(BlackboardArtifact.Type type, String configuration, Long dataSourceId, TreeDisplayCount displayCount, Boolean hasChildren) { super(AnalysisResultSearchParam.getTypeId(), - new AnalysisResultSearchParam(type, dataSourceId), + new AnalysisResultSearchParam(type, configuration, dataSourceId), type.getTypeID(), type.getDisplayName(), displayCount); @@ -1288,14 +1290,14 @@ public class AnalysisResultDAO extends BlackboardArtifactDAO { /** * Handles fetching and paging of configuration filtered results. */ - public static class AnalysisResultConfigFetcher extends DAOFetcher { + public static class AnalysisResultConfigFetcher extends DAOFetcher { /** * Main constructor. * * @param params Parameters to handle fetching of data. */ - public AnalysisResultConfigFetcher(AnalysisResultConfigSearchParam params) { + public AnalysisResultConfigFetcher(AnalysisResultSearchParam params) { super(params); } diff --git a/Core/src/org/sleuthkit/autopsy/mainui/datamodel/AnalysisResultSearchParam.java b/Core/src/org/sleuthkit/autopsy/mainui/datamodel/AnalysisResultSearchParam.java index 5ee118d70f..ccf06dbeea 100644 --- a/Core/src/org/sleuthkit/autopsy/mainui/datamodel/AnalysisResultSearchParam.java +++ b/Core/src/org/sleuthkit/autopsy/mainui/datamodel/AnalysisResultSearchParam.java @@ -18,6 +18,7 @@ */ package org.sleuthkit.autopsy.mainui.datamodel; +import java.util.Objects; import org.sleuthkit.datamodel.BlackboardArtifact; /** @@ -34,8 +35,41 @@ public class AnalysisResultSearchParam extends BlackboardArtifactSearchParam { return TYPE_ID; } - public AnalysisResultSearchParam(BlackboardArtifact.Type artifactType, Long dataSourceId) { + final String configuration; + + public AnalysisResultSearchParam(BlackboardArtifact.Type artifactType, String configuration, Long dataSourceId) { super(artifactType, dataSourceId); + this.configuration = configuration; + } + + public String getConfiguration() { + return configuration; + } + + @Override + public int hashCode() { + int hash = 5; + hash = 29 * hash + Objects.hashCode(this.configuration); + hash = 29 * hash + super.hashCode(); + return hash; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj == null) { + return false; + } + if (getClass() != obj.getClass()) { + return false; + } + final AnalysisResultSearchParam other = (AnalysisResultSearchParam) obj; + if (!Objects.equals(this.configuration, other.configuration)) { + return false; + } + return super.equals(obj); } diff --git a/Core/src/org/sleuthkit/autopsy/mainui/datamodel/HashHitSearchParam.java b/Core/src/org/sleuthkit/autopsy/mainui/datamodel/HashHitSearchParam.java deleted file mode 100644 index 20d65f178d..0000000000 --- a/Core/src/org/sleuthkit/autopsy/mainui/datamodel/HashHitSearchParam.java +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Autopsy Forensic Browser - * - * Copyright 2021 Basis Technology Corp. - * Contact: carrier sleuthkit org - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.sleuthkit.autopsy.mainui.datamodel; - -import org.sleuthkit.datamodel.BlackboardArtifact; - -/** - * Key for keyword hits in order to retrieve data from DAO. - */ -public class HashHitSearchParam extends AnalysisResultConfigSearchParam { - - private static final String TYPE_ID = "HASH_HIT"; - - /** - * @return The type id for this search parameter. - */ - public static String getTypeId() { - return TYPE_ID; - } - - public HashHitSearchParam(Long dataSourceId, String setName) { - super(BlackboardArtifact.Type.TSK_HASHSET_HIT, dataSourceId, setName); - } -} diff --git a/Core/src/org/sleuthkit/autopsy/mainui/datamodel/AnalysisResultSetSearchParam.java b/Core/src/org/sleuthkit/autopsy/mainui/datamodel/KeywordListSearchParam.java similarity index 84% rename from Core/src/org/sleuthkit/autopsy/mainui/datamodel/AnalysisResultSetSearchParam.java rename to Core/src/org/sleuthkit/autopsy/mainui/datamodel/KeywordListSearchParam.java index ca4480d708..462a3881c8 100644 --- a/Core/src/org/sleuthkit/autopsy/mainui/datamodel/AnalysisResultSetSearchParam.java +++ b/Core/src/org/sleuthkit/autopsy/mainui/datamodel/KeywordListSearchParam.java @@ -24,7 +24,7 @@ import org.sleuthkit.datamodel.BlackboardArtifact; /** * Base class for search params for analysis results that filter by set name. */ -public class AnalysisResultSetSearchParam extends AnalysisResultSearchParam { +public class KeywordListSearchParam extends AnalysisResultSearchParam { private static final String TYPE_ID = "ANALYSIS_RESULT_SET"; @@ -37,8 +37,8 @@ public class AnalysisResultSetSearchParam extends AnalysisResultSearchParam { private final String setName; - public AnalysisResultSetSearchParam(BlackboardArtifact.Type artifactType, Long dataSourceId, String setName) { - super(artifactType, dataSourceId); + public KeywordListSearchParam(Long dataSourceId, String configuration, String setName) { + super(BlackboardArtifact.Type.TSK_KEYWORD_HIT, configuration, dataSourceId); this.setName = setName; } @@ -65,7 +65,7 @@ public class AnalysisResultSetSearchParam extends AnalysisResultSearchParam { if (getClass() != obj.getClass()) { return false; } - final AnalysisResultSetSearchParam other = (AnalysisResultSetSearchParam) obj; + final KeywordListSearchParam other = (KeywordListSearchParam) obj; if (!Objects.equals(this.setName, other.setName)) { return false; } diff --git a/Core/src/org/sleuthkit/autopsy/mainui/datamodel/KeywordSearchTermParams.java b/Core/src/org/sleuthkit/autopsy/mainui/datamodel/KeywordSearchTermParams.java index 720ddb6260..6bc2f812e5 100644 --- a/Core/src/org/sleuthkit/autopsy/mainui/datamodel/KeywordSearchTermParams.java +++ b/Core/src/org/sleuthkit/autopsy/mainui/datamodel/KeywordSearchTermParams.java @@ -25,7 +25,7 @@ import org.sleuthkit.datamodel.TskData; /** * Parameters for a keyword search term. */ -public class KeywordSearchTermParams extends AnalysisResultSetSearchParam { +public class KeywordSearchTermParams extends KeywordListSearchParam { private static final String TYPE_ID = "KEYWORD_SEARCH_TERMS"; @@ -39,7 +39,6 @@ public class KeywordSearchTermParams extends AnalysisResultSetSearchParam { private final String searchTerm; private final Boolean hasChildren; private final TskData.KeywordSearchQueryType searchType; - private final String configuration; /** * Main constructor. @@ -55,11 +54,10 @@ public class KeywordSearchTermParams extends AnalysisResultSetSearchParam { * @param dataSourceId The data source id or null. */ public KeywordSearchTermParams(String setName, String searchTerm, TskData.KeywordSearchQueryType searchType, String configuration, boolean hasChildren, Long dataSourceId) { - super(BlackboardArtifact.Type.TSK_KEYWORD_HIT, dataSourceId, setName); + super(dataSourceId, configuration, setName); this.searchTerm = searchTerm; this.hasChildren = hasChildren; this.searchType = searchType; - this.configuration = configuration; } /** @@ -77,10 +75,6 @@ public class KeywordSearchTermParams extends AnalysisResultSetSearchParam { return hasChildren; } - public String getConfiguration() { - return configuration; - } - /** * @return The keyword search type value. */ diff --git a/Core/src/org/sleuthkit/autopsy/mainui/datamodel/events/AnalysisResultConfigEvent.java b/Core/src/org/sleuthkit/autopsy/mainui/datamodel/events/AnalysisResultConfigEvent.java deleted file mode 100644 index adfb7891ec..0000000000 --- a/Core/src/org/sleuthkit/autopsy/mainui/datamodel/events/AnalysisResultConfigEvent.java +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Autopsy Forensic Browser - * - * Copyright 2021 Basis Technology Corp. - * Contact: carrier sleuthkit org - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.sleuthkit.autopsy.mainui.datamodel.events; - -import org.sleuthkit.datamodel.BlackboardArtifact; - -/** - * An event for an Analysis Result that is organized by Set names to - * signal that one has been added or removed on a given data source. - */ -public class AnalysisResultConfigEvent extends AnalysisResultEvent { - private final String configuration; - - public AnalysisResultConfigEvent(String configuration, BlackboardArtifact.Type artifactType, long dataSourceId) { - super(artifactType, dataSourceId); - this.configuration = configuration; - } - - public String getConfiguration() { - return configuration; - } -} diff --git a/Core/src/org/sleuthkit/autopsy/mainui/datamodel/events/AnalysisResultEvent.java b/Core/src/org/sleuthkit/autopsy/mainui/datamodel/events/AnalysisResultEvent.java index 4d0b40c6af..8fafca4df7 100644 --- a/Core/src/org/sleuthkit/autopsy/mainui/datamodel/events/AnalysisResultEvent.java +++ b/Core/src/org/sleuthkit/autopsy/mainui/datamodel/events/AnalysisResultEvent.java @@ -18,15 +18,50 @@ */ package org.sleuthkit.autopsy.mainui.datamodel.events; +import java.util.Objects; import org.sleuthkit.datamodel.BlackboardArtifact; /** - * An event for an artifact added or changed of a particular type possibly for a - * particular data source. + * An event for an Analysis Result that is organized by Set names to + * signal that one has been added or removed on a given data source. */ public class AnalysisResultEvent extends BlackboardArtifactEvent { + private final String configuration; - public AnalysisResultEvent(BlackboardArtifact.Type artifactType, long dataSourceId) { + public AnalysisResultEvent(BlackboardArtifact.Type artifactType, String configuration, long dataSourceId) { super(artifactType, dataSourceId); + this.configuration = configuration; } + + public String getConfiguration() { + return configuration; + } + + @Override + public int hashCode() { + int hash = 7; + hash = 53 * hash + Objects.hashCode(this.configuration); + hash = 53 * hash + super.hashCode(); + return hash; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj == null) { + return false; + } + if (getClass() != obj.getClass()) { + return false; + } + final AnalysisResultEvent other = (AnalysisResultEvent) obj; + if (!Objects.equals(this.configuration, other.configuration)) { + return false; + } + return super.equals(obj); + } + + } diff --git a/Core/src/org/sleuthkit/autopsy/mainui/datamodel/events/KeywordHitEvent.java b/Core/src/org/sleuthkit/autopsy/mainui/datamodel/events/KeywordHitEvent.java index 9fc963a762..e2d419a87e 100644 --- a/Core/src/org/sleuthkit/autopsy/mainui/datamodel/events/KeywordHitEvent.java +++ b/Core/src/org/sleuthkit/autopsy/mainui/datamodel/events/KeywordHitEvent.java @@ -45,7 +45,7 @@ public class KeywordHitEvent extends AnalysisResultEvent { * @param dataSourceId The data source id. */ public KeywordHitEvent(String setName, String searchString, TskData.KeywordSearchQueryType searchType, String match, String configuration, long dataSourceId) { - super(BlackboardArtifact.Type.TSK_KEYWORD_HIT, dataSourceId); + super(BlackboardArtifact.Type.TSK_KEYWORD_HIT, configuration, dataSourceId); this.setName = setName; this.searchString = searchString; this.match = match; diff --git a/Core/src/org/sleuthkit/autopsy/mainui/nodes/AnalysisResultTypeFactory.java b/Core/src/org/sleuthkit/autopsy/mainui/nodes/AnalysisResultTypeFactory.java index 432fb3afb9..4f2a66caac 100644 --- a/Core/src/org/sleuthkit/autopsy/mainui/nodes/AnalysisResultTypeFactory.java +++ b/Core/src/org/sleuthkit/autopsy/mainui/nodes/AnalysisResultTypeFactory.java @@ -36,8 +36,7 @@ import org.sleuthkit.autopsy.datamodel.utils.IconsUtil; import org.sleuthkit.autopsy.mainui.datamodel.AnalysisResultDAO; import org.sleuthkit.autopsy.mainui.datamodel.AnalysisResultDAO.AnalysisResultTreeItem; import org.sleuthkit.autopsy.mainui.datamodel.AnalysisResultSearchParam; -import org.sleuthkit.autopsy.mainui.datamodel.AnalysisResultConfigSearchParam; -import org.sleuthkit.autopsy.mainui.datamodel.AnalysisResultSetSearchParam; +import org.sleuthkit.autopsy.mainui.datamodel.KeywordListSearchParam; import org.sleuthkit.autopsy.mainui.datamodel.KeywordHitSearchParam; import org.sleuthkit.autopsy.mainui.datamodel.MainDAO; import org.sleuthkit.autopsy.mainui.datamodel.TreeResultsDTO; @@ -111,14 +110,15 @@ public class AnalysisResultTypeFactory extends TreeChildFactory { + static class TreeConfigFactory extends TreeChildFactory { private final BlackboardArtifact.Type artifactType; private final Long dataSourceId; @@ -254,28 +254,28 @@ public class AnalysisResultTypeFactory extends TreeChildFactory getChildResults() throws IllegalArgumentException, ExecutionException { + protected TreeResultsDTO getChildResults() throws IllegalArgumentException, ExecutionException { return MainDAO.getInstance().getAnalysisResultDAO().getConfigurationCounts(this.artifactType, this.dataSourceId, this.nullSetName); } @Override - protected TreeNode createNewNode(TreeResultsDTO.TreeItemDTO rowData) { + protected TreeNode createNewNode(TreeResultsDTO.TreeItemDTO rowData) { return new TreeConfigTypeNode(rowData); } @Override - protected TreeResultsDTO.TreeItemDTO getOrCreateRelevantChild(TreeEvent treeEvt) { - TreeResultsDTO.TreeItemDTO originalTreeItem = super.getTypedTreeItem(treeEvt, AnalysisResultConfigSearchParam.class); + protected TreeResultsDTO.TreeItemDTO getOrCreateRelevantChild(TreeEvent treeEvt) { + TreeResultsDTO.TreeItemDTO originalTreeItem = super.getTypedTreeItem(treeEvt, AnalysisResultSearchParam.class); if (originalTreeItem != null && originalTreeItem.getSearchParams().getArtifactType().equals(this.artifactType) && (this.dataSourceId == null || Objects.equals(this.dataSourceId, originalTreeItem.getSearchParams().getDataSourceId()))) { // generate new type so that if it is a subtree event (i.e. keyword hits), the right tree item is created. - AnalysisResultConfigSearchParam searchParam = originalTreeItem.getSearchParams(); + AnalysisResultSearchParam searchParam = originalTreeItem.getSearchParams(); return new TreeResultsDTO.TreeItemDTO<>( - AnalysisResultConfigSearchParam.getTypeId(), - new AnalysisResultConfigSearchParam(this.artifactType, this.dataSourceId, searchParam.getConfiguration()), + AnalysisResultSearchParam.getTypeId(), + new AnalysisResultSearchParam(this.artifactType, searchParam.getConfiguration(), this.dataSourceId), searchParam.getConfiguration() == null ? 0 : searchParam.getConfiguration(), searchParam.getConfiguration() == null ? nullSetName : searchParam.getConfiguration(), originalTreeItem.getDisplayCount()); @@ -284,7 +284,7 @@ public class AnalysisResultTypeFactory extends TreeChildFactory o1, TreeItemDTO o2) { + public int compare(TreeItemDTO o1, TreeItemDTO o2) { return STRING_COMPARATOR.compare(o1.getSearchParams().getConfiguration(), o2.getSearchParams().getConfiguration()); } @@ -305,14 +305,14 @@ public class AnalysisResultTypeFactory extends TreeChildFactory { + static class TreeConfigTypeNode extends TreeNode { /** * Main constructor. * * @param itemData The data to display. */ - TreeConfigTypeNode(TreeResultsDTO.TreeItemDTO itemData) { + TreeConfigTypeNode(TreeResultsDTO.TreeItemDTO itemData) { super(itemData.getSearchParams().getArtifactType().getTypeName() + "_SET_" + itemData.getSearchParams().getConfiguration(), getIconPath(itemData.getSearchParams().getArtifactType()), itemData, @@ -367,7 +367,7 @@ public class AnalysisResultTypeFactory extends TreeChildFactory { + public static class KeywordSetFactory extends TreeChildFactory { private final Long dataSourceId; @@ -376,23 +376,23 @@ public class AnalysisResultTypeFactory extends TreeChildFactory getChildResults() throws IllegalArgumentException, ExecutionException { + protected TreeResultsDTO getChildResults() throws IllegalArgumentException, ExecutionException { return MainDAO.getInstance().getAnalysisResultDAO().getKwSetCounts(this.dataSourceId, Bundle.AnalysisResultTypeFactory_adHocName()); } @Override - protected TreeResultsDTO.TreeItemDTO getOrCreateRelevantChild(TreeEvent treeEvt) { - TreeResultsDTO.TreeItemDTO originalTreeItem = super.getTypedTreeItem(treeEvt, AnalysisResultSetSearchParam.class); + protected TreeResultsDTO.TreeItemDTO getOrCreateRelevantChild(TreeEvent treeEvt) { + TreeResultsDTO.TreeItemDTO originalTreeItem = super.getTypedTreeItem(treeEvt, KeywordListSearchParam.class); if (originalTreeItem != null && originalTreeItem.getSearchParams().getArtifactType().equals(BlackboardArtifact.Type.TSK_KEYWORD_HIT) && (this.dataSourceId == null || Objects.equals(this.dataSourceId, originalTreeItem.getSearchParams().getDataSourceId()))) { // generate new type so that if it is a subtree event (i.e. keyword hits), the right tree item is created. - AnalysisResultSetSearchParam searchParam = originalTreeItem.getSearchParams(); + KeywordListSearchParam searchParam = originalTreeItem.getSearchParams(); return new TreeResultsDTO.TreeItemDTO<>( - AnalysisResultSetSearchParam.getTypeId(), - new AnalysisResultSetSearchParam(BlackboardArtifact.Type.TSK_KEYWORD_HIT, this.dataSourceId, searchParam.getSetName()), + KeywordListSearchParam.getTypeId(), + new KeywordListSearchParam(this.dataSourceId, searchParam.getConfiguration(), searchParam.getSetName()), searchParam.getSetName() == null ? 0 : searchParam.getSetName(), searchParam.getSetName() == null ? Bundle.AnalysisResultTypeFactory_adHocName() : searchParam.getSetName(), originalTreeItem.getDisplayCount()); @@ -401,17 +401,17 @@ public class AnalysisResultTypeFactory extends TreeChildFactory o1, TreeItemDTO o2) { + public int compare(TreeItemDTO o1, TreeItemDTO o2) { return STRING_COMPARATOR.compare(o1.getSearchParams().getSetName(), o2.getSearchParams().getSetName()); } @Override - protected TreeNode createNewNode(TreeResultsDTO.TreeItemDTO rowData) { + protected TreeNode createNewNode(TreeResultsDTO.TreeItemDTO rowData) { return new KeywordSetNode(rowData); } } - static class KeywordSetNode extends TreeNode { + static class KeywordSetNode extends TreeNode { private static final Logger logger = Logger.getLogger(KeywordSetNode.class.getName()); @@ -420,7 +420,7 @@ public class AnalysisResultTypeFactory extends TreeChildFactory itemData) { + public KeywordSetNode(TreeResultsDTO.TreeItemDTO itemData) { super("TSK_KEYWORD_HIT_SET_" + itemData.getSearchParams().getSetName(), getIconPath(itemData.getSearchParams().getArtifactType()), itemData, @@ -462,14 +462,14 @@ public class AnalysisResultTypeFactory extends TreeChildFactory { - private final AnalysisResultSetSearchParam setParams; + private final KeywordListSearchParam setParams; /** * Main constructor. * * @param setParams The parameters for the set. */ - KeywordSearchTermFactory(AnalysisResultSetSearchParam setParams) { + KeywordSearchTermFactory(KeywordListSearchParam setParams) { this.setParams = setParams; } diff --git a/Core/test/qa-functional/src/org/sleuthkit/autopsy/mainui/datamodel/TableSearchTest.java b/Core/test/qa-functional/src/org/sleuthkit/autopsy/mainui/datamodel/TableSearchTest.java index b9387062a6..3eb5f77b4f 100644 --- a/Core/test/qa-functional/src/org/sleuthkit/autopsy/mainui/datamodel/TableSearchTest.java +++ b/Core/test/qa-functional/src/org/sleuthkit/autopsy/mainui/datamodel/TableSearchTest.java @@ -938,7 +938,7 @@ public class TableSearchTest extends NbTestCase { try { // Get all encryption detected artifacts - AnalysisResultSearchParam param = new AnalysisResultSearchParam(BlackboardArtifact.Type.TSK_ENCRYPTION_DETECTED, null); + AnalysisResultSearchParam param = new AnalysisResultSearchParam(BlackboardArtifact.Type.TSK_ENCRYPTION_DETECTED, null, null); AnalysisResultDAO analysisResultDAO = MainDAO.getInstance().getAnalysisResultDAO(); AnalysisResultTableSearchResultsDTO results = analysisResultDAO.getAnalysisResultsForTable(param, 0, null); @@ -947,14 +947,14 @@ public class TableSearchTest extends NbTestCase { assertEquals(3, results.getItems().size()); // Get encryption detected artifacts from data source 2 - param = new AnalysisResultSearchParam(BlackboardArtifact.Type.TSK_ENCRYPTION_DETECTED, dataSource2.getId()); + param = new AnalysisResultSearchParam(BlackboardArtifact.Type.TSK_ENCRYPTION_DETECTED, null, dataSource2.getId()); results = analysisResultDAO.getAnalysisResultsForTable(param, 0, null); assertEquals(BlackboardArtifact.Type.TSK_ENCRYPTION_DETECTED, results.getArtifactType()); assertEquals(1, results.getTotalResultsCount()); assertEquals(1, results.getItems().size()); // Get all custom artifacts - param = new AnalysisResultSearchParam(customAnalysisResultType, null); + param = new AnalysisResultSearchParam(customAnalysisResultType, null, null); results = analysisResultDAO.getAnalysisResultsForTable(param, 0, null); assertEquals(customAnalysisResultType, results.getArtifactType()); assertEquals(1, results.getTotalResultsCount()); @@ -989,7 +989,7 @@ public class TableSearchTest extends NbTestCase { assertTrue(ARTIFACT_COUNT_YARA > pageSize); // Get the first page - param = new AnalysisResultSearchParam(BlackboardArtifact.Type.TSK_YARA_HIT, null); + param = new AnalysisResultSearchParam(BlackboardArtifact.Type.TSK_YARA_HIT, null, null); results = analysisResultDAO.getAnalysisResultsForTable(param, 0, pageSize); assertEquals(ARTIFACT_COUNT_YARA, results.getTotalResultsCount()); assertEquals(pageSize.longValue(), results.getItems().size()); @@ -1005,7 +1005,7 @@ public class TableSearchTest extends NbTestCase { assertEquals(pageSize.longValue(), firstPageObjIds.size()); // Get the second page - param = new AnalysisResultSearchParam(BlackboardArtifact.Type.TSK_YARA_HIT, null); + param = new AnalysisResultSearchParam(BlackboardArtifact.Type.TSK_YARA_HIT, null, null); results = analysisResultDAO.getAnalysisResultsForTable(param, pageSize, pageSize); assertEquals(ARTIFACT_COUNT_YARA, results.getTotalResultsCount()); assertEquals(ARTIFACT_COUNT_YARA - pageSize, results.getItems().size()); @@ -1029,13 +1029,13 @@ public class TableSearchTest extends NbTestCase { try { // Test hash set hits AnalysisResultDAO analysisResultDAO = MainDAO.getInstance().getAnalysisResultDAO(); - HashHitSearchParam hashParam = new HashHitSearchParam(null, HASH_SET_1); + AnalysisResultSearchParam hashParam = new AnalysisResultSearchParam(BlackboardArtifact.Type.TSK_HASHSET_HIT, HASH_SET_1, null); AnalysisResultTableSearchResultsDTO results = analysisResultDAO.getAnalysisResultConfigResults(hashParam, 0, null); assertEquals(BlackboardArtifact.Type.TSK_HASHSET_HIT, results.getArtifactType()); assertEquals(3, results.getTotalResultsCount()); assertEquals(3, results.getItems().size()); - hashParam = new HashHitSearchParam(dataSource2.getId(), HASH_SET_1); + hashParam = new AnalysisResultSearchParam(BlackboardArtifact.Type.TSK_HASHSET_HIT, HASH_SET_1, dataSource2.getId()); results = analysisResultDAO.getAnalysisResultConfigResults(hashParam, 0, null); assertEquals(BlackboardArtifact.Type.TSK_HASHSET_HIT, results.getArtifactType()); assertEquals(1, results.getTotalResultsCount()); @@ -1068,19 +1068,19 @@ public class TableSearchTest extends NbTestCase { try { // Test keyword set hits AnalysisResultDAO analysisResultDAO = MainDAO.getInstance().getAnalysisResultDAO(); - KeywordHitSearchParam kwParam = new KeywordHitSearchParam(null, KEYWORD_SET_1, "keyword1", "", TskData.KeywordSearchQueryType.LITERAL); + KeywordHitSearchParam kwParam = new KeywordHitSearchParam(null, KEYWORD_SET_1, "keyword1", "", TskData.KeywordSearchQueryType.LITERAL, ""); AnalysisResultTableSearchResultsDTO results = analysisResultDAO.getKeywordHitsForTable(kwParam, 0, null); assertEquals(BlackboardArtifact.Type.TSK_KEYWORD_HIT, results.getArtifactType()); assertEquals(1, results.getTotalResultsCount()); assertEquals(1, results.getItems().size()); - kwParam = new KeywordHitSearchParam(dataSource1.getId(), KEYWORD_SET_2, "keyword2", "", TskData.KeywordSearchQueryType.LITERAL); + kwParam = new KeywordHitSearchParam(dataSource1.getId(), KEYWORD_SET_2, "keyword2", "", TskData.KeywordSearchQueryType.LITERAL, ""); results = analysisResultDAO.getKeywordHitsForTable(kwParam, 0, null); assertEquals(BlackboardArtifact.Type.TSK_KEYWORD_HIT, results.getArtifactType()); assertEquals(1, results.getTotalResultsCount()); assertEquals(1, results.getItems().size()); - kwParam = new KeywordHitSearchParam(dataSource2.getId(), KEYWORD_SET_2, KEYWORD, KEYWORD_REGEX, TskData.KeywordSearchQueryType.REGEX); + kwParam = new KeywordHitSearchParam(dataSource2.getId(), KEYWORD_SET_2, KEYWORD, KEYWORD_REGEX, TskData.KeywordSearchQueryType.REGEX, ""); results = analysisResultDAO.getKeywordHitsForTable(kwParam, 0, null); assertEquals(BlackboardArtifact.Type.TSK_KEYWORD_HIT, results.getArtifactType()); assertEquals(1, results.getTotalResultsCount());