mirror of
https://github.com/overcuriousity/autopsy-flatpak.git
synced 2025-07-14 17:06:16 +00:00
Merge pull request #6245 from gdicristofaro/6778-analysisSummaryTab
6778 analysis summary tab
This commit is contained in:
commit
cc6254ced2
@ -0,0 +1,159 @@
|
|||||||
|
/*
|
||||||
|
* Autopsy Forensic Browser
|
||||||
|
*
|
||||||
|
* Copyright 2020 Basis Technology Corp.
|
||||||
|
* Contact: carrier <at> sleuthkit <dot> 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.datasourcesummary.datamodel;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.function.Function;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
import org.apache.commons.lang3.tuple.Pair;
|
||||||
|
import org.sleuthkit.autopsy.datasourcesummary.datamodel.SleuthkitCaseProvider.SleuthkitCaseProviderException;
|
||||||
|
import org.sleuthkit.datamodel.BlackboardArtifact;
|
||||||
|
import org.sleuthkit.datamodel.BlackboardArtifact.ARTIFACT_TYPE;
|
||||||
|
import org.sleuthkit.datamodel.BlackboardAttribute;
|
||||||
|
import org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE;
|
||||||
|
import org.sleuthkit.datamodel.DataSource;
|
||||||
|
import org.sleuthkit.datamodel.SleuthkitCase;
|
||||||
|
import org.sleuthkit.datamodel.TskCoreException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Providing data for the data source analysis tab.
|
||||||
|
*/
|
||||||
|
public class DataSourceAnalysisSummary {
|
||||||
|
|
||||||
|
private static final BlackboardAttribute.Type TYPE_SET_NAME = new BlackboardAttribute.Type(ATTRIBUTE_TYPE.TSK_SET_NAME);
|
||||||
|
|
||||||
|
private static final Set<String> EXCLUDED_KEYWORD_SEARCH_ITEMS = new HashSet<>(Arrays.asList(
|
||||||
|
"PHONE NUMBERS",
|
||||||
|
"IP ADDRESSES",
|
||||||
|
"EMAIL ADDRESSES",
|
||||||
|
"URLS",
|
||||||
|
"CREDIT CARD NUMBERS"
|
||||||
|
));
|
||||||
|
|
||||||
|
private final SleuthkitCaseProvider provider;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Main constructor.
|
||||||
|
*/
|
||||||
|
public DataSourceAnalysisSummary() {
|
||||||
|
this(SleuthkitCaseProvider.DEFAULT);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Main constructor.
|
||||||
|
*
|
||||||
|
* @param provider The means of obtaining a sleuthkit case.
|
||||||
|
*/
|
||||||
|
public DataSourceAnalysisSummary(SleuthkitCaseProvider provider) {
|
||||||
|
this.provider = provider;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets counts for hashset hits.
|
||||||
|
*
|
||||||
|
* @param dataSource The datasource for which to identify hashset hits.
|
||||||
|
*
|
||||||
|
* @return The hashset set name with the number of hits in descending order.
|
||||||
|
*
|
||||||
|
* @throws SleuthkitCaseProviderException
|
||||||
|
* @throws TskCoreException
|
||||||
|
*/
|
||||||
|
public List<Pair<String, Long>> getHashsetCounts(DataSource dataSource) throws SleuthkitCaseProviderException, TskCoreException {
|
||||||
|
return getCountsData(dataSource, TYPE_SET_NAME, ARTIFACT_TYPE.TSK_HASHSET_HIT);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets counts for keyword hits.
|
||||||
|
*
|
||||||
|
* @param dataSource The datasource for which to identify keyword hits.
|
||||||
|
*
|
||||||
|
* @return The keyword set name with the number of hits in descending order.
|
||||||
|
*
|
||||||
|
* @throws SleuthkitCaseProviderException
|
||||||
|
* @throws TskCoreException
|
||||||
|
*/
|
||||||
|
public List<Pair<String, Long>> getKeywordCounts(DataSource dataSource) throws SleuthkitCaseProviderException, TskCoreException {
|
||||||
|
return getCountsData(dataSource, TYPE_SET_NAME, ARTIFACT_TYPE.TSK_KEYWORD_HIT).stream()
|
||||||
|
// make sure we have a valid set and that that set does not belong to the set of excluded items
|
||||||
|
.filter((pair) -> pair != null && pair.getKey() != null && !EXCLUDED_KEYWORD_SEARCH_ITEMS.contains(pair.getKey().toUpperCase().trim()))
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets counts for interesting item hits.
|
||||||
|
*
|
||||||
|
* @param dataSource The datasource for which to identify interesting item
|
||||||
|
* hits.
|
||||||
|
*
|
||||||
|
* @return The interesting item set name with the number of hits in
|
||||||
|
* descending order.
|
||||||
|
*
|
||||||
|
* @throws SleuthkitCaseProviderException
|
||||||
|
* @throws TskCoreException
|
||||||
|
*/
|
||||||
|
public List<Pair<String, Long>> getInterestingItemCounts(DataSource dataSource) throws SleuthkitCaseProviderException, TskCoreException {
|
||||||
|
return getCountsData(dataSource, TYPE_SET_NAME, ARTIFACT_TYPE.TSK_INTERESTING_FILE_HIT, ARTIFACT_TYPE.TSK_INTERESTING_ARTIFACT_HIT);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get counts for the artifact of the specified type.
|
||||||
|
*
|
||||||
|
* @param dataSource The datasource.
|
||||||
|
* @param keyType The attribute to use as the key type.
|
||||||
|
* @param artifactTypes The types of artifacts for which to query.
|
||||||
|
*
|
||||||
|
* @return A list of key value pairs where the key is the attribute type
|
||||||
|
* value and the value is the count of items found. This list is
|
||||||
|
* sorted by the count descending max to min.
|
||||||
|
*
|
||||||
|
* @throws SleuthkitCaseProviderException
|
||||||
|
* @throws TskCoreException
|
||||||
|
*/
|
||||||
|
private List<Pair<String, Long>> getCountsData(DataSource dataSource, BlackboardAttribute.Type keyType, ARTIFACT_TYPE... artifactTypes)
|
||||||
|
throws SleuthkitCaseProviderException, TskCoreException {
|
||||||
|
List<BlackboardArtifact> artifacts = new ArrayList<>();
|
||||||
|
SleuthkitCase skCase = provider.get();
|
||||||
|
|
||||||
|
// get all artifacts in one list for each artifact type
|
||||||
|
for (ARTIFACT_TYPE type : artifactTypes) {
|
||||||
|
artifacts.addAll(skCase.getBlackboard().getArtifacts(type.getTypeID(), dataSource.getId()));
|
||||||
|
}
|
||||||
|
|
||||||
|
// group those based on the value of the attribute type that should serve as a key
|
||||||
|
Map<String, Long> countedKeys = artifacts.stream()
|
||||||
|
.map((art) -> {
|
||||||
|
String key = DataSourceInfoUtilities.getStringOrNull(art, keyType);
|
||||||
|
return (StringUtils.isBlank(key)) ? null : key;
|
||||||
|
})
|
||||||
|
.filter((key) -> key != null)
|
||||||
|
.collect(Collectors.groupingBy(Function.identity(), Collectors.counting()));
|
||||||
|
|
||||||
|
// sort from max to min counts
|
||||||
|
return countedKeys.entrySet().stream()
|
||||||
|
.map((e) -> Pair.of(e.getKey(), e.getValue()))
|
||||||
|
.sorted((a, b) -> -a.getValue().compareTo(b.getValue()))
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,263 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8" ?>
|
||||||
|
|
||||||
|
<Form version="1.4" maxVersion="1.9" type="org.netbeans.modules.form.forminfo.JPanelFormInfo">
|
||||||
|
<AuxValues>
|
||||||
|
<AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="1"/>
|
||||||
|
<AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/>
|
||||||
|
<AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/>
|
||||||
|
<AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="true"/>
|
||||||
|
<AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="true"/>
|
||||||
|
<AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/>
|
||||||
|
<AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/>
|
||||||
|
<AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/>
|
||||||
|
<AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/>
|
||||||
|
</AuxValues>
|
||||||
|
|
||||||
|
<Layout>
|
||||||
|
<DimensionLayout dim="0">
|
||||||
|
<Group type="103" groupAlignment="0" attributes="0">
|
||||||
|
<Component id="mainScrollPane" alignment="0" pref="756" max="32767" attributes="0"/>
|
||||||
|
</Group>
|
||||||
|
</DimensionLayout>
|
||||||
|
<DimensionLayout dim="1">
|
||||||
|
<Group type="103" groupAlignment="0" attributes="0">
|
||||||
|
<Component id="mainScrollPane" alignment="0" pref="300" max="32767" attributes="0"/>
|
||||||
|
</Group>
|
||||||
|
</DimensionLayout>
|
||||||
|
</Layout>
|
||||||
|
<SubComponents>
|
||||||
|
<Container class="javax.swing.JScrollPane" name="mainScrollPane">
|
||||||
|
<AuxValues>
|
||||||
|
<AuxValue name="JavaCodeGenerator_VariableLocal" type="java.lang.Boolean" value="true"/>
|
||||||
|
<AuxValue name="JavaCodeGenerator_VariableModifier" type="java.lang.Integer" value="0"/>
|
||||||
|
</AuxValues>
|
||||||
|
|
||||||
|
<Layout class="org.netbeans.modules.form.compat2.layouts.support.JScrollPaneSupportLayout"/>
|
||||||
|
<SubComponents>
|
||||||
|
<Container class="javax.swing.JPanel" name="mainContentPanel">
|
||||||
|
<Properties>
|
||||||
|
<Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor">
|
||||||
|
<Border info="org.netbeans.modules.form.compat2.border.EmptyBorderInfo">
|
||||||
|
<EmptyBorder bottom="10" left="10" right="10" top="10"/>
|
||||||
|
</Border>
|
||||||
|
</Property>
|
||||||
|
<Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||||
|
<Dimension value="[32767, 452]"/>
|
||||||
|
</Property>
|
||||||
|
<Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||||
|
<Dimension value="[200, 452]"/>
|
||||||
|
</Property>
|
||||||
|
</Properties>
|
||||||
|
<AuxValues>
|
||||||
|
<AuxValue name="JavaCodeGenerator_VariableLocal" type="java.lang.Boolean" value="true"/>
|
||||||
|
<AuxValue name="JavaCodeGenerator_VariableModifier" type="java.lang.Integer" value="0"/>
|
||||||
|
</AuxValues>
|
||||||
|
|
||||||
|
<Layout class="org.netbeans.modules.form.compat2.layouts.DesignBoxLayout">
|
||||||
|
<Property name="axis" type="int" value="3"/>
|
||||||
|
</Layout>
|
||||||
|
<SubComponents>
|
||||||
|
<Component class="javax.swing.JLabel" name="hashsetHitsLabel">
|
||||||
|
<Properties>
|
||||||
|
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||||
|
<ResourceString bundle="org/sleuthkit/autopsy/datasourcesummary/ui/Bundle.properties" key="AnalysisPanel.hashsetHitsLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||||
|
</Property>
|
||||||
|
</Properties>
|
||||||
|
<AuxValues>
|
||||||
|
<AuxValue name="JavaCodeGenerator_VariableLocal" type="java.lang.Boolean" value="true"/>
|
||||||
|
<AuxValue name="JavaCodeGenerator_VariableModifier" type="java.lang.Integer" value="0"/>
|
||||||
|
</AuxValues>
|
||||||
|
</Component>
|
||||||
|
<Component class="javax.swing.Box$Filler" name="filler1">
|
||||||
|
<Properties>
|
||||||
|
<Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||||
|
<Dimension value="[32767, 2]"/>
|
||||||
|
</Property>
|
||||||
|
<Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||||
|
<Dimension value="[0, 2]"/>
|
||||||
|
</Property>
|
||||||
|
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||||
|
<Dimension value="[0, 2]"/>
|
||||||
|
</Property>
|
||||||
|
</Properties>
|
||||||
|
<AuxValues>
|
||||||
|
<AuxValue name="JavaCodeGenerator_VariableLocal" type="java.lang.Boolean" value="true"/>
|
||||||
|
<AuxValue name="JavaCodeGenerator_VariableModifier" type="java.lang.Integer" value="0"/>
|
||||||
|
<AuxValue name="classDetails" type="java.lang.String" value="Box.Filler.VerticalStrut"/>
|
||||||
|
</AuxValues>
|
||||||
|
</Component>
|
||||||
|
<Container class="javax.swing.JPanel" name="hashSetHitsPanel">
|
||||||
|
<Properties>
|
||||||
|
<Property name="alignmentX" type="float" value="0.0"/>
|
||||||
|
<Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||||
|
<Dimension value="[32767, 106]"/>
|
||||||
|
</Property>
|
||||||
|
<Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||||
|
<Dimension value="[10, 106]"/>
|
||||||
|
</Property>
|
||||||
|
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||||
|
<Dimension value="[10, 106]"/>
|
||||||
|
</Property>
|
||||||
|
</Properties>
|
||||||
|
<AuxValues>
|
||||||
|
<AuxValue name="JavaCodeGenerator_CreateCodeCustom" type="java.lang.String" value="hashsetHitsTable"/>
|
||||||
|
<AuxValue name="JavaCodeGenerator_VariableLocal" type="java.lang.Boolean" value="true"/>
|
||||||
|
<AuxValue name="JavaCodeGenerator_VariableModifier" type="java.lang.Integer" value="0"/>
|
||||||
|
</AuxValues>
|
||||||
|
|
||||||
|
<Layout class="org.netbeans.modules.form.compat2.layouts.DesignFlowLayout"/>
|
||||||
|
</Container>
|
||||||
|
<Component class="javax.swing.Box$Filler" name="filler2">
|
||||||
|
<Properties>
|
||||||
|
<Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||||
|
<Dimension value="[32767, 20]"/>
|
||||||
|
</Property>
|
||||||
|
<Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||||
|
<Dimension value="[0, 20]"/>
|
||||||
|
</Property>
|
||||||
|
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||||
|
<Dimension value="[0, 20]"/>
|
||||||
|
</Property>
|
||||||
|
</Properties>
|
||||||
|
<AuxValues>
|
||||||
|
<AuxValue name="JavaCodeGenerator_VariableLocal" type="java.lang.Boolean" value="true"/>
|
||||||
|
<AuxValue name="JavaCodeGenerator_VariableModifier" type="java.lang.Integer" value="0"/>
|
||||||
|
<AuxValue name="classDetails" type="java.lang.String" value="Box.Filler.VerticalStrut"/>
|
||||||
|
</AuxValues>
|
||||||
|
</Component>
|
||||||
|
<Component class="javax.swing.JLabel" name="keywordHitsLabel">
|
||||||
|
<Properties>
|
||||||
|
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||||
|
<ResourceString bundle="org/sleuthkit/autopsy/datasourcesummary/ui/Bundle.properties" key="AnalysisPanel.keywordHitsLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||||
|
</Property>
|
||||||
|
</Properties>
|
||||||
|
<AuxValues>
|
||||||
|
<AuxValue name="JavaCodeGenerator_VariableLocal" type="java.lang.Boolean" value="true"/>
|
||||||
|
<AuxValue name="JavaCodeGenerator_VariableModifier" type="java.lang.Integer" value="0"/>
|
||||||
|
</AuxValues>
|
||||||
|
</Component>
|
||||||
|
<Component class="javax.swing.Box$Filler" name="filler4">
|
||||||
|
<Properties>
|
||||||
|
<Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||||
|
<Dimension value="[32767, 2]"/>
|
||||||
|
</Property>
|
||||||
|
<Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||||
|
<Dimension value="[0, 2]"/>
|
||||||
|
</Property>
|
||||||
|
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||||
|
<Dimension value="[0, 2]"/>
|
||||||
|
</Property>
|
||||||
|
</Properties>
|
||||||
|
<AuxValues>
|
||||||
|
<AuxValue name="JavaCodeGenerator_VariableLocal" type="java.lang.Boolean" value="true"/>
|
||||||
|
<AuxValue name="JavaCodeGenerator_VariableModifier" type="java.lang.Integer" value="0"/>
|
||||||
|
<AuxValue name="classDetails" type="java.lang.String" value="Box.Filler.VerticalStrut"/>
|
||||||
|
</AuxValues>
|
||||||
|
</Component>
|
||||||
|
<Container class="javax.swing.JPanel" name="keywordHitsPanel">
|
||||||
|
<Properties>
|
||||||
|
<Property name="alignmentX" type="float" value="0.0"/>
|
||||||
|
<Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||||
|
<Dimension value="[32767, 106]"/>
|
||||||
|
</Property>
|
||||||
|
<Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||||
|
<Dimension value="[10, 106]"/>
|
||||||
|
</Property>
|
||||||
|
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||||
|
<Dimension value="[10, 106]"/>
|
||||||
|
</Property>
|
||||||
|
</Properties>
|
||||||
|
<AuxValues>
|
||||||
|
<AuxValue name="JavaCodeGenerator_CreateCodeCustom" type="java.lang.String" value="keywordHitsTable"/>
|
||||||
|
<AuxValue name="JavaCodeGenerator_VariableLocal" type="java.lang.Boolean" value="true"/>
|
||||||
|
<AuxValue name="JavaCodeGenerator_VariableModifier" type="java.lang.Integer" value="0"/>
|
||||||
|
</AuxValues>
|
||||||
|
|
||||||
|
<Layout class="org.netbeans.modules.form.compat2.layouts.DesignFlowLayout"/>
|
||||||
|
</Container>
|
||||||
|
<Component class="javax.swing.Box$Filler" name="filler5">
|
||||||
|
<Properties>
|
||||||
|
<Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||||
|
<Dimension value="[32767, 20]"/>
|
||||||
|
</Property>
|
||||||
|
<Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||||
|
<Dimension value="[0, 20]"/>
|
||||||
|
</Property>
|
||||||
|
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||||
|
<Dimension value="[0, 20]"/>
|
||||||
|
</Property>
|
||||||
|
</Properties>
|
||||||
|
<AuxValues>
|
||||||
|
<AuxValue name="JavaCodeGenerator_VariableLocal" type="java.lang.Boolean" value="true"/>
|
||||||
|
<AuxValue name="JavaCodeGenerator_VariableModifier" type="java.lang.Integer" value="0"/>
|
||||||
|
<AuxValue name="classDetails" type="java.lang.String" value="Box.Filler.VerticalStrut"/>
|
||||||
|
</AuxValues>
|
||||||
|
</Component>
|
||||||
|
<Component class="javax.swing.JLabel" name="interestingItemLabel">
|
||||||
|
<Properties>
|
||||||
|
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||||
|
<ResourceString bundle="org/sleuthkit/autopsy/datasourcesummary/ui/Bundle.properties" key="AnalysisPanel.interestingItemLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||||
|
</Property>
|
||||||
|
</Properties>
|
||||||
|
<AuxValues>
|
||||||
|
<AuxValue name="JavaCodeGenerator_VariableLocal" type="java.lang.Boolean" value="true"/>
|
||||||
|
<AuxValue name="JavaCodeGenerator_VariableModifier" type="java.lang.Integer" value="0"/>
|
||||||
|
</AuxValues>
|
||||||
|
</Component>
|
||||||
|
<Component class="javax.swing.Box$Filler" name="filler6">
|
||||||
|
<Properties>
|
||||||
|
<Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||||
|
<Dimension value="[32767, 2]"/>
|
||||||
|
</Property>
|
||||||
|
<Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||||
|
<Dimension value="[0, 2]"/>
|
||||||
|
</Property>
|
||||||
|
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||||
|
<Dimension value="[0, 2]"/>
|
||||||
|
</Property>
|
||||||
|
</Properties>
|
||||||
|
<AuxValues>
|
||||||
|
<AuxValue name="JavaCodeGenerator_VariableLocal" type="java.lang.Boolean" value="true"/>
|
||||||
|
<AuxValue name="JavaCodeGenerator_VariableModifier" type="java.lang.Integer" value="0"/>
|
||||||
|
<AuxValue name="classDetails" type="java.lang.String" value="Box.Filler.VerticalStrut"/>
|
||||||
|
</AuxValues>
|
||||||
|
</Component>
|
||||||
|
<Container class="javax.swing.JPanel" name="interestingItemPanel">
|
||||||
|
<Properties>
|
||||||
|
<Property name="alignmentX" type="float" value="0.0"/>
|
||||||
|
<Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||||
|
<Dimension value="[32767, 106]"/>
|
||||||
|
</Property>
|
||||||
|
<Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||||
|
<Dimension value="[10, 106]"/>
|
||||||
|
</Property>
|
||||||
|
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||||
|
<Dimension value="[10, 106]"/>
|
||||||
|
</Property>
|
||||||
|
</Properties>
|
||||||
|
<AuxValues>
|
||||||
|
<AuxValue name="JavaCodeGenerator_CreateCodeCustom" type="java.lang.String" value="interestingItemsTable"/>
|
||||||
|
<AuxValue name="JavaCodeGenerator_VariableLocal" type="java.lang.Boolean" value="true"/>
|
||||||
|
<AuxValue name="JavaCodeGenerator_VariableModifier" type="java.lang.Integer" value="0"/>
|
||||||
|
</AuxValues>
|
||||||
|
|
||||||
|
<Layout class="org.netbeans.modules.form.compat2.layouts.DesignFlowLayout"/>
|
||||||
|
</Container>
|
||||||
|
<Component class="javax.swing.Box$Filler" name="filler3">
|
||||||
|
<Properties>
|
||||||
|
<Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||||
|
<Dimension value="[0, 32767]"/>
|
||||||
|
</Property>
|
||||||
|
</Properties>
|
||||||
|
<AuxValues>
|
||||||
|
<AuxValue name="JavaCodeGenerator_VariableLocal" type="java.lang.Boolean" value="true"/>
|
||||||
|
<AuxValue name="JavaCodeGenerator_VariableModifier" type="java.lang.Integer" value="0"/>
|
||||||
|
<AuxValue name="classDetails" type="java.lang.String" value="Box.Filler.VerticalGlue"/>
|
||||||
|
</AuxValues>
|
||||||
|
</Component>
|
||||||
|
</SubComponents>
|
||||||
|
</Container>
|
||||||
|
</SubComponents>
|
||||||
|
</Container>
|
||||||
|
</SubComponents>
|
||||||
|
</Form>
|
@ -0,0 +1,209 @@
|
|||||||
|
/*
|
||||||
|
* Autopsy Forensic Browser
|
||||||
|
*
|
||||||
|
* Copyright 2020 Basis Technology Corp.
|
||||||
|
* Contact: carrier <at> sleuthkit <dot> 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.datasourcesummary.ui;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
import org.apache.commons.lang3.tuple.Pair;
|
||||||
|
import org.openide.util.NbBundle.Messages;
|
||||||
|
import org.sleuthkit.autopsy.casemodule.Case;
|
||||||
|
import org.sleuthkit.autopsy.datasourcesummary.datamodel.DataSourceAnalysisSummary;
|
||||||
|
import org.sleuthkit.autopsy.datasourcesummary.uiutils.CellModelTableCellRenderer.DefaultCellModel;
|
||||||
|
import org.sleuthkit.autopsy.datasourcesummary.uiutils.DataFetchResult;
|
||||||
|
import org.sleuthkit.autopsy.datasourcesummary.uiutils.DataFetchWorker;
|
||||||
|
import org.sleuthkit.autopsy.datasourcesummary.uiutils.JTablePanel;
|
||||||
|
import org.sleuthkit.autopsy.datasourcesummary.uiutils.JTablePanel.ColumnModel;
|
||||||
|
import org.sleuthkit.datamodel.DataSource;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A tab shown in data source summary displaying hash set hits, keyword hits,
|
||||||
|
* and interesting item hits within a datasource.
|
||||||
|
*/
|
||||||
|
@Messages({
|
||||||
|
"AnalysisPanel_keyColumn_title=Name",
|
||||||
|
"AnalysisPanel_countColumn_title=Count"
|
||||||
|
})
|
||||||
|
public class AnalysisPanel extends BaseDataSourceSummaryPanel {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Default Column definitions for each table
|
||||||
|
*/
|
||||||
|
private static final List<ColumnModel<Pair<String, Long>>> DEFAULT_COLUMNS = Arrays.asList(
|
||||||
|
new ColumnModel<>(
|
||||||
|
Bundle.AnalysisPanel_keyColumn_title(),
|
||||||
|
(pair) -> new DefaultCellModel(pair.getKey()),
|
||||||
|
300
|
||||||
|
),
|
||||||
|
new ColumnModel<>(
|
||||||
|
Bundle.AnalysisPanel_countColumn_title(),
|
||||||
|
(pair) -> new DefaultCellModel(String.valueOf(pair.getValue())),
|
||||||
|
100
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
private final JTablePanel<Pair<String, Long>> hashsetHitsTable = JTablePanel.getJTablePanel(DEFAULT_COLUMNS);
|
||||||
|
|
||||||
|
private final JTablePanel<Pair<String, Long>> keywordHitsTable = JTablePanel.getJTablePanel(DEFAULT_COLUMNS);
|
||||||
|
|
||||||
|
private final JTablePanel<Pair<String, Long>> interestingItemsTable = JTablePanel.getJTablePanel(DEFAULT_COLUMNS);
|
||||||
|
|
||||||
|
private final List<JTablePanel<?>> tables = Arrays.asList(
|
||||||
|
hashsetHitsTable,
|
||||||
|
keywordHitsTable,
|
||||||
|
interestingItemsTable
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* All of the components necessary for data fetch swing workers to load data
|
||||||
|
* for each table.
|
||||||
|
*/
|
||||||
|
private final List<DataFetchWorker.DataFetchComponents<DataSource, ?>> dataFetchComponents;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new DataSourceUserActivityPanel.
|
||||||
|
*/
|
||||||
|
public AnalysisPanel() {
|
||||||
|
this(new DataSourceAnalysisSummary());
|
||||||
|
}
|
||||||
|
|
||||||
|
public AnalysisPanel(DataSourceAnalysisSummary analysisData) {
|
||||||
|
// set up data acquisition methods
|
||||||
|
dataFetchComponents = Arrays.asList(
|
||||||
|
// hashset hits loading components
|
||||||
|
new DataFetchWorker.DataFetchComponents<>(
|
||||||
|
(dataSource) -> analysisData.getHashsetCounts(dataSource),
|
||||||
|
(result) -> hashsetHitsTable.showDataFetchResult(result)),
|
||||||
|
// keyword hits loading components
|
||||||
|
new DataFetchWorker.DataFetchComponents<>(
|
||||||
|
(dataSource) -> analysisData.getKeywordCounts(dataSource),
|
||||||
|
(result) -> keywordHitsTable.showDataFetchResult(result)),
|
||||||
|
// interesting item hits loading components
|
||||||
|
new DataFetchWorker.DataFetchComponents<>(
|
||||||
|
(dataSource) -> analysisData.getInterestingItemCounts(dataSource),
|
||||||
|
(result) -> interestingItemsTable.showDataFetchResult(result))
|
||||||
|
);
|
||||||
|
|
||||||
|
initComponents();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onNewDataSource(DataSource dataSource) {
|
||||||
|
// if no data source is present or the case is not open,
|
||||||
|
// set results for tables to null.
|
||||||
|
if (dataSource == null || !Case.isCaseOpen()) {
|
||||||
|
this.dataFetchComponents.forEach((item) -> item.getResultHandler()
|
||||||
|
.accept(DataFetchResult.getSuccessResult(null)));
|
||||||
|
|
||||||
|
} else {
|
||||||
|
// set tables to display loading screen
|
||||||
|
this.tables.forEach((table) -> table.showDefaultLoadingMessage());
|
||||||
|
|
||||||
|
// create swing workers to run for each table
|
||||||
|
List<DataFetchWorker<?, ?>> workers = dataFetchComponents
|
||||||
|
.stream()
|
||||||
|
.map((components) -> new DataFetchWorker<>(components, dataSource))
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
|
||||||
|
// submit swing workers to run
|
||||||
|
submit(workers);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method is called from within the constructor to initialize the form.
|
||||||
|
* WARNING: Do NOT modify this code. The content of this method is always
|
||||||
|
* regenerated by the Form Editor.
|
||||||
|
*/
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
// <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
|
||||||
|
private void initComponents() {
|
||||||
|
|
||||||
|
javax.swing.JScrollPane mainScrollPane = new javax.swing.JScrollPane();
|
||||||
|
javax.swing.JPanel mainContentPanel = new javax.swing.JPanel();
|
||||||
|
javax.swing.JLabel hashsetHitsLabel = new javax.swing.JLabel();
|
||||||
|
javax.swing.Box.Filler filler1 = new javax.swing.Box.Filler(new java.awt.Dimension(0, 2), new java.awt.Dimension(0, 2), new java.awt.Dimension(32767, 2));
|
||||||
|
javax.swing.JPanel hashSetHitsPanel = hashsetHitsTable;
|
||||||
|
javax.swing.Box.Filler filler2 = new javax.swing.Box.Filler(new java.awt.Dimension(0, 20), new java.awt.Dimension(0, 20), new java.awt.Dimension(32767, 20));
|
||||||
|
javax.swing.JLabel keywordHitsLabel = new javax.swing.JLabel();
|
||||||
|
javax.swing.Box.Filler filler4 = new javax.swing.Box.Filler(new java.awt.Dimension(0, 2), new java.awt.Dimension(0, 2), new java.awt.Dimension(32767, 2));
|
||||||
|
javax.swing.JPanel keywordHitsPanel = keywordHitsTable;
|
||||||
|
javax.swing.Box.Filler filler5 = new javax.swing.Box.Filler(new java.awt.Dimension(0, 20), new java.awt.Dimension(0, 20), new java.awt.Dimension(32767, 20));
|
||||||
|
javax.swing.JLabel interestingItemLabel = new javax.swing.JLabel();
|
||||||
|
javax.swing.Box.Filler filler6 = new javax.swing.Box.Filler(new java.awt.Dimension(0, 2), new java.awt.Dimension(0, 2), new java.awt.Dimension(32767, 2));
|
||||||
|
javax.swing.JPanel interestingItemPanel = interestingItemsTable;
|
||||||
|
javax.swing.Box.Filler filler3 = new javax.swing.Box.Filler(new java.awt.Dimension(0, 0), new java.awt.Dimension(0, 0), new java.awt.Dimension(0, 32767));
|
||||||
|
|
||||||
|
mainContentPanel.setBorder(javax.swing.BorderFactory.createEmptyBorder(10, 10, 10, 10));
|
||||||
|
mainContentPanel.setMaximumSize(new java.awt.Dimension(32767, 452));
|
||||||
|
mainContentPanel.setMinimumSize(new java.awt.Dimension(200, 452));
|
||||||
|
mainContentPanel.setLayout(new javax.swing.BoxLayout(mainContentPanel, javax.swing.BoxLayout.PAGE_AXIS));
|
||||||
|
|
||||||
|
org.openide.awt.Mnemonics.setLocalizedText(hashsetHitsLabel, org.openide.util.NbBundle.getMessage(AnalysisPanel.class, "AnalysisPanel.hashsetHitsLabel.text")); // NOI18N
|
||||||
|
mainContentPanel.add(hashsetHitsLabel);
|
||||||
|
mainContentPanel.add(filler1);
|
||||||
|
|
||||||
|
hashSetHitsPanel.setAlignmentX(0.0F);
|
||||||
|
hashSetHitsPanel.setMaximumSize(new java.awt.Dimension(32767, 106));
|
||||||
|
hashSetHitsPanel.setMinimumSize(new java.awt.Dimension(10, 106));
|
||||||
|
hashSetHitsPanel.setPreferredSize(new java.awt.Dimension(10, 106));
|
||||||
|
mainContentPanel.add(hashSetHitsPanel);
|
||||||
|
mainContentPanel.add(filler2);
|
||||||
|
|
||||||
|
org.openide.awt.Mnemonics.setLocalizedText(keywordHitsLabel, org.openide.util.NbBundle.getMessage(AnalysisPanel.class, "AnalysisPanel.keywordHitsLabel.text")); // NOI18N
|
||||||
|
mainContentPanel.add(keywordHitsLabel);
|
||||||
|
mainContentPanel.add(filler4);
|
||||||
|
|
||||||
|
keywordHitsPanel.setAlignmentX(0.0F);
|
||||||
|
keywordHitsPanel.setMaximumSize(new java.awt.Dimension(32767, 106));
|
||||||
|
keywordHitsPanel.setMinimumSize(new java.awt.Dimension(10, 106));
|
||||||
|
keywordHitsPanel.setPreferredSize(new java.awt.Dimension(10, 106));
|
||||||
|
mainContentPanel.add(keywordHitsPanel);
|
||||||
|
mainContentPanel.add(filler5);
|
||||||
|
|
||||||
|
org.openide.awt.Mnemonics.setLocalizedText(interestingItemLabel, org.openide.util.NbBundle.getMessage(AnalysisPanel.class, "AnalysisPanel.interestingItemLabel.text")); // NOI18N
|
||||||
|
mainContentPanel.add(interestingItemLabel);
|
||||||
|
mainContentPanel.add(filler6);
|
||||||
|
|
||||||
|
interestingItemPanel.setAlignmentX(0.0F);
|
||||||
|
interestingItemPanel.setMaximumSize(new java.awt.Dimension(32767, 106));
|
||||||
|
interestingItemPanel.setMinimumSize(new java.awt.Dimension(10, 106));
|
||||||
|
interestingItemPanel.setPreferredSize(new java.awt.Dimension(10, 106));
|
||||||
|
mainContentPanel.add(interestingItemPanel);
|
||||||
|
mainContentPanel.add(filler3);
|
||||||
|
|
||||||
|
mainScrollPane.setViewportView(mainContentPanel);
|
||||||
|
|
||||||
|
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
|
||||||
|
this.setLayout(layout);
|
||||||
|
layout.setHorizontalGroup(
|
||||||
|
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||||
|
.addComponent(mainScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, 756, Short.MAX_VALUE)
|
||||||
|
);
|
||||||
|
layout.setVerticalGroup(
|
||||||
|
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||||
|
.addComponent(mainScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, 300, Short.MAX_VALUE)
|
||||||
|
);
|
||||||
|
}// </editor-fold>//GEN-END:initComponents
|
||||||
|
|
||||||
|
// Variables declaration - do not modify//GEN-BEGIN:variables
|
||||||
|
// End of variables declaration//GEN-END:variables
|
||||||
|
}
|
@ -35,6 +35,9 @@ DataSourceSummaryUserActivityPanel.recentAccountsLabel.text=Recent Accounts
|
|||||||
DataSourceSummaryUserActivityPanel.topWebSearchLabel.text=Recent Web Searches
|
DataSourceSummaryUserActivityPanel.topWebSearchLabel.text=Recent Web Searches
|
||||||
DataSourceSummaryUserActivityPanel.topDevicesAttachedLabel.text=Recent Devices Attached
|
DataSourceSummaryUserActivityPanel.topDevicesAttachedLabel.text=Recent Devices Attached
|
||||||
DataSourceSummaryUserActivityPanel.recentDomainsLabel.text=Recent Domains
|
DataSourceSummaryUserActivityPanel.recentDomainsLabel.text=Recent Domains
|
||||||
|
AnalysisPanel.hashsetHitsLabel.text=Hashset Hits
|
||||||
|
AnalysisPanel.keywordHitsLabel.text=Keyword Hits
|
||||||
|
AnalysisPanel.interestingItemLabel.text=Interesting Item Hits
|
||||||
RecentFilesPanel.openDocsLabel.text=Recently Opened Documents
|
RecentFilesPanel.openDocsLabel.text=Recently Opened Documents
|
||||||
RecentFilesPanel.downloadLabel.text=Recent Downloads
|
RecentFilesPanel.downloadLabel.text=Recent Downloads
|
||||||
RecentFilesPanel.attachmentLabel.text=Recent Attachements
|
RecentFilesPanel.attachmentLabel.text=Recent Attachements
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
AnalysisPanel_countColumn_title=Count
|
||||||
|
AnalysisPanel_keyColumn_title=Name
|
||||||
CTL_DataSourceSummaryAction=Data Source Summary
|
CTL_DataSourceSummaryAction=Data Source Summary
|
||||||
DataSourceSummaryCountsPanel.ArtifactCountsTableModel.count.header=Count
|
DataSourceSummaryCountsPanel.ArtifactCountsTableModel.count.header=Count
|
||||||
DataSourceSummaryCountsPanel.ArtifactCountsTableModel.type.header=Result Type
|
DataSourceSummaryCountsPanel.ArtifactCountsTableModel.type.header=Result Type
|
||||||
@ -64,6 +66,7 @@ DataSourceSummaryNode.column.status.header=Ingest Status
|
|||||||
DataSourceSummaryNode.column.tags.header=Tags
|
DataSourceSummaryNode.column.tags.header=Tags
|
||||||
DataSourceSummaryNode.column.type.header=Type
|
DataSourceSummaryNode.column.type.header=Type
|
||||||
DataSourceSummaryNode.viewDataSourceAction.text=Go to Data Source
|
DataSourceSummaryNode.viewDataSourceAction.text=Go to Data Source
|
||||||
|
DataSourceSummaryTabbedPane_analysisTab_title=Analysis
|
||||||
DataSourceSummaryTabbedPane_countsTab_title=Counts
|
DataSourceSummaryTabbedPane_countsTab_title=Counts
|
||||||
DataSourceSummaryTabbedPane_detailsTab_title=Container
|
DataSourceSummaryTabbedPane_detailsTab_title=Container
|
||||||
DataSourceSummaryTabbedPane_ingestHistoryTab_title=Ingest History
|
DataSourceSummaryTabbedPane_ingestHistoryTab_title=Ingest History
|
||||||
@ -74,6 +77,9 @@ DataSourceSummaryUserActivityPanel.recentAccountsLabel.text=Recent Accounts
|
|||||||
DataSourceSummaryUserActivityPanel.topWebSearchLabel.text=Recent Web Searches
|
DataSourceSummaryUserActivityPanel.topWebSearchLabel.text=Recent Web Searches
|
||||||
DataSourceSummaryUserActivityPanel.topDevicesAttachedLabel.text=Recent Devices Attached
|
DataSourceSummaryUserActivityPanel.topDevicesAttachedLabel.text=Recent Devices Attached
|
||||||
DataSourceSummaryUserActivityPanel.recentDomainsLabel.text=Recent Domains
|
DataSourceSummaryUserActivityPanel.recentDomainsLabel.text=Recent Domains
|
||||||
|
AnalysisPanel.hashsetHitsLabel.text=Hashset Hits
|
||||||
|
AnalysisPanel.keywordHitsLabel.text=Keyword Hits
|
||||||
|
AnalysisPanel.interestingItemLabel.text=Interesting Item Hits
|
||||||
DataSourceSummaryUserActivityPanel_noDataExists=No communication data exists
|
DataSourceSummaryUserActivityPanel_noDataExists=No communication data exists
|
||||||
DataSourceSummaryUserActivityPanel_tab_title=User Activity
|
DataSourceSummaryUserActivityPanel_tab_title=User Activity
|
||||||
DataSourceSummaryUserActivityPanel_TopAccountTableModel_accountType_header=Account Type
|
DataSourceSummaryUserActivityPanel_TopAccountTableModel_accountType_header=Account Type
|
||||||
|
@ -37,7 +37,8 @@ import org.sleuthkit.datamodel.DataSource;
|
|||||||
"DataSourceSummaryTabbedPane_detailsTab_title=Container",
|
"DataSourceSummaryTabbedPane_detailsTab_title=Container",
|
||||||
"DataSourceSummaryTabbedPane_userActivityTab_title=User Activity",
|
"DataSourceSummaryTabbedPane_userActivityTab_title=User Activity",
|
||||||
"DataSourceSummaryTabbedPane_ingestHistoryTab_title=Ingest History",
|
"DataSourceSummaryTabbedPane_ingestHistoryTab_title=Ingest History",
|
||||||
"DataSourceSummaryTabbedPane_recentFileTab_title=Recent Files"
|
"DataSourceSummaryTabbedPane_recentFileTab_title=Recent Files",
|
||||||
|
"DataSourceSummaryTabbedPane_analysisTab_title=Analysis"
|
||||||
})
|
})
|
||||||
public class DataSourceSummaryTabbedPane extends JTabbedPane {
|
public class DataSourceSummaryTabbedPane extends JTabbedPane {
|
||||||
|
|
||||||
@ -47,7 +48,8 @@ public class DataSourceSummaryTabbedPane extends JTabbedPane {
|
|||||||
private final List<Pair<String, BaseDataSourceSummaryPanel>> tabs = new ArrayList<>(Arrays.asList(
|
private final List<Pair<String, BaseDataSourceSummaryPanel>> tabs = new ArrayList<>(Arrays.asList(
|
||||||
Pair.of(Bundle.DataSourceSummaryTabbedPane_countsTab_title(), new DataSourceSummaryCountsPanel()),
|
Pair.of(Bundle.DataSourceSummaryTabbedPane_countsTab_title(), new DataSourceSummaryCountsPanel()),
|
||||||
Pair.of(Bundle.DataSourceSummaryTabbedPane_userActivityTab_title(), new DataSourceSummaryUserActivityPanel()),
|
Pair.of(Bundle.DataSourceSummaryTabbedPane_userActivityTab_title(), new DataSourceSummaryUserActivityPanel()),
|
||||||
Pair.of(Bundle.DataSourceSummaryTabbedPane_recentFileTab_title(), new RecentFilesPanel())
|
Pair.of(Bundle.DataSourceSummaryTabbedPane_recentFileTab_title(), new RecentFilesPanel()),
|
||||||
|
Pair.of(Bundle.DataSourceSummaryTabbedPane_analysisTab_title(), new AnalysisPanel())
|
||||||
));
|
));
|
||||||
|
|
||||||
private final IngestJobInfoPanel ingestHistoryPanel = new IngestJobInfoPanel();
|
private final IngestJobInfoPanel ingestHistoryPanel = new IngestJobInfoPanel();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user