Autopsy 4.22.1
Graphical digital forensics platform for The Sleuth Kit and other tools.
CommonAttributeCaseSearchResults.java
Go to the documentation of this file.
1/*
2 *
3 * Autopsy Forensic Browser
4 *
5 * Copyright 2018-2020 Basis Technology Corp.
6 * Contact: carrier <at> sleuthkit <dot> org
7 *
8 * Licensed under the Apache License, Version 2.0 (the "License");
9 * you may not use this file except in compliance with the License.
10 * You may obtain a copy of the License at
11 *
12 * http://www.apache.org/licenses/LICENSE-2.0
13 *
14 * Unless required by applicable law or agreed to in writing, software
15 * distributed under the License is distributed on an "AS IS" BASIS,
16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 * See the License for the specific language governing permissions and
18 * limitations under the License.
19 */
20package org.sleuthkit.autopsy.commonpropertiessearch;
21
22import java.util.Collections;
23import java.util.HashMap;
24import java.util.HashSet;
25import java.util.Map;
26import java.util.Map.Entry;
27import java.util.Set;
28import java.util.logging.Level;
29import org.sleuthkit.autopsy.casemodule.Case;
30import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException;
31import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationAttributeInstance;
32import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationAttributeNormalizationException;
33import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepoException;
34import org.sleuthkit.autopsy.coreutils.Logger;
35import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepository;
36
41final public class CommonAttributeCaseSearchResults {
42
43 private static final Logger LOGGER = Logger.getLogger(CommonAttributeCaseSearchResults.class.getName());
44
45 // maps instance count to list of attribute values.
46 private final Map<String, Map<String, CommonAttributeValueList>> caseNameToDataSources;
47
58 CommonAttributeCaseSearchResults(Map<String, Map<String, CommonAttributeValueList>> metadata, int percentageThreshold, CorrelationAttributeInstance.Type resultType) {
59 this.caseNameToDataSources = filterMetadata(metadata, percentageThreshold, resultType.getId());
60 }
61
70 CommonAttributeCaseSearchResults(Map<String, Map<String, CommonAttributeValueList>> metadata, int percentageThreshold) {
71 this.caseNameToDataSources = filterMetadata(metadata, percentageThreshold, CorrelationAttributeInstance.FILES_TYPE_ID);
72 }
73
84 Map<String, CommonAttributeValueList> getAttributeValuesForCaseName(String caseName) {
85 return this.caseNameToDataSources.get(caseName);
86 }
87
94 public Map<String, Map<String, CommonAttributeValueList>> getMetadata() {
95 return Collections.unmodifiableMap(this.caseNameToDataSources);
96 }
97
113 private Map<String, Map<String, CommonAttributeValueList>> filterMetadata(Map<String, Map<String, CommonAttributeValueList>> metadata, int percentageThreshold, int resultTypeId) {
114 try {
115 final String currentCaseName;
116 try {
117 currentCaseName = Case.getCurrentCaseThrows().getDisplayName();
118 } catch (NoCurrentCaseException ex) {
119 throw new CentralRepoException("Unable to get current case while performing filtering", ex);
120 }
121 Map<String, CommonAttributeValueList> currentCaseDataSourceMap = metadata.get(currentCaseName);
122 Map<String, Map<String, CommonAttributeValueList>> filteredCaseNameToDataSourcesTree = new HashMap<>();
123 if (currentCaseDataSourceMap == null) { //there are no results
124 return filteredCaseNameToDataSourcesTree;
125 }
127 .stream()
128 .filter(filterType -> filterType.getId() == resultTypeId)
129 .findFirst().get();
130 //Call countUniqueDataSources once to reduce the number of DB queries needed to get the frequencyPercentage
131 Double uniqueCaseDataSourceTuples = CentralRepository.getInstance().getCountUniqueDataSources().doubleValue();
132 Map<String, CommonAttributeValue> valuesToKeepCurrentCase = getValuesToKeepFromCurrentCase(currentCaseDataSourceMap, attributeType, percentageThreshold, uniqueCaseDataSourceTuples);
133 for (Entry<String, Map<String, CommonAttributeValueList>> mapOfDataSources : Collections.unmodifiableMap(metadata).entrySet()) {
134 if (!mapOfDataSources.getKey().equals(currentCaseName)) {
135 //rebuild the metadata structure with items from the current case substituted for their matches in other cases results we want to filter out removed
136 Map<String, CommonAttributeValueList> newTreeForCase = createTreeForCase(valuesToKeepCurrentCase, mapOfDataSources.getValue());
137 if (!newTreeForCase.isEmpty()) {
138 filteredCaseNameToDataSourcesTree.put(mapOfDataSources.getKey(), newTreeForCase);
139 }
140 }
141 }
142 return filteredCaseNameToDataSourcesTree;
143 } catch (CentralRepoException ex) {
144 LOGGER.log(Level.INFO, "Unable to perform filtering returning unfiltered result set", ex);
145 return metadata;
146 }
147
148 }
149
168 private Map<String, CommonAttributeValue> getValuesToKeepFromCurrentCase(Map<String, CommonAttributeValueList> dataSourceToValueList, CorrelationAttributeInstance.Type attributeType, int maximumPercentageThreshold, Double uniqueCaseDataSourceTuples) throws CentralRepoException {
169 Map<String, CommonAttributeValue> valuesToKeep = new HashMap<>();
170 Set<String> valuesToRemove = new HashSet<>();
171 for (Entry<String, CommonAttributeValueList> mapOfValueLists : Collections.unmodifiableMap(dataSourceToValueList).entrySet()) {
172 for (CommonAttributeValue value : mapOfValueLists.getValue().getDelayedMetadataSet()) {
173 if (valuesToRemove.contains(value.getValue())) {
174 //do nothing this value will not be added
175 } else if (filterValue(attributeType, value, maximumPercentageThreshold, uniqueCaseDataSourceTuples)) {
176 valuesToRemove.add(value.getValue());
177 } else {
178 valuesToKeep.put(value.getValue(), value);
179 }
180 }
181 }
182 return valuesToKeep;
183 }
184
198 private Map<String, CommonAttributeValueList> createTreeForCase(Map<String, CommonAttributeValue> valuesToKeepCurrentCase, Map<String, CommonAttributeValueList> dataSourceToValueList) throws CentralRepoException {
199 Map<String, CommonAttributeValueList> treeForCase = new HashMap<>();
200 for (Entry<String, CommonAttributeValueList> mapOfValueLists : Collections.unmodifiableMap(dataSourceToValueList).entrySet()) {
201 for (CommonAttributeValue value : mapOfValueLists.getValue().getDelayedMetadataSet()) {
202 if (valuesToKeepCurrentCase.containsKey(value.getValue())) {
203 if (!treeForCase.containsKey(mapOfValueLists.getKey())) {
204 treeForCase.put(mapOfValueLists.getKey(), new CommonAttributeValueList());
205 }
206 treeForCase.get(mapOfValueLists.getKey()).addMetadataToList(valuesToKeepCurrentCase.get(value.getValue()));
207 }
208 }
209 }
210 return treeForCase;
211 }
212
232 private boolean filterValue(CorrelationAttributeInstance.Type attributeType, CommonAttributeValue value, int maximumPercentageThreshold, Double uniqueCaseDataSourceTuples) throws CentralRepoException {
233 if (maximumPercentageThreshold != 0) { //only do the frequency filtering when a max % was set
234 try {
236 attributeType, value.getValue()).doubleValue();
237 Double commonalityPercentage = uniqueTypeValueTuples / uniqueCaseDataSourceTuples * 100;
238 int frequencyPercentage = commonalityPercentage.intValue();
239 if (frequencyPercentage > maximumPercentageThreshold) {
240 return true;
241 }
243 LOGGER.log(Level.WARNING, "Unable to determine frequency percentage attribute - frequency filter may not be accurate for these results.", ex);
244 }
245 }
246 return false;
247 }
248}
Map< String, CommonAttributeValueList > createTreeForCase(Map< String, CommonAttributeValue > valuesToKeepCurrentCase, Map< String, CommonAttributeValueList > dataSourceToValueList)
boolean filterValue(CorrelationAttributeInstance.Type attributeType, CommonAttributeValue value, int maximumPercentageThreshold, Double uniqueCaseDataSourceTuples)
Map< String, CommonAttributeValue > getValuesToKeepFromCurrentCase(Map< String, CommonAttributeValueList > dataSourceToValueList, CorrelationAttributeInstance.Type attributeType, int maximumPercentageThreshold, Double uniqueCaseDataSourceTuples)
Map< String, Map< String, CommonAttributeValueList > > filterMetadata(Map< String, Map< String, CommonAttributeValueList > > metadata, int percentageThreshold, int resultTypeId)
final Map< String, Map< String, CommonAttributeValueList > > caseNameToDataSources
synchronized static Logger getLogger(String name)
Definition Logger.java:124
Long getCountUniqueCaseDataSourceTuplesHavingTypeValue(CorrelationAttributeInstance.Type aType, String value)
List< CorrelationAttributeInstance.Type > getDefinedCorrelationTypes()

Copyright © 2012-2024 Sleuth Kit Labs. Generated on:
This work is licensed under a Creative Commons Attribution-Share Alike 3.0 United States License.