mirror of
https://github.com/overcuriousity/autopsy-flatpak.git
synced 2025-07-12 16:06:15 +00:00
Merge branch 'develop' of https://github.com/sleuthkit/autopsy into 4606-AddUserLoginsToOsAccountArts
This commit is contained in:
commit
44b34e410f
@ -67,6 +67,7 @@ import org.sleuthkit.autopsy.appservices.AutopsyService;
|
||||
import org.sleuthkit.autopsy.appservices.AutopsyService.CaseContext;
|
||||
import static org.sleuthkit.autopsy.casemodule.Bundle.*;
|
||||
import org.sleuthkit.autopsy.casemodule.CaseMetadata.CaseMetadataException;
|
||||
import org.sleuthkit.autopsy.casemodule.datasourceSummary.DataSourceSummaryAction;
|
||||
import org.sleuthkit.autopsy.casemodule.events.AddingDataSourceEvent;
|
||||
import org.sleuthkit.autopsy.casemodule.events.AddingDataSourceFailedEvent;
|
||||
import org.sleuthkit.autopsy.casemodule.events.BlackBoardArtifactTagAddedEvent;
|
||||
@ -1165,6 +1166,7 @@ public class Case {
|
||||
CallableSystemAction.get(AddImageAction.class).setEnabled(true);
|
||||
CallableSystemAction.get(CaseCloseAction.class).setEnabled(true);
|
||||
CallableSystemAction.get(CasePropertiesAction.class).setEnabled(true);
|
||||
CallableSystemAction.get(DataSourceSummaryAction.class).setEnabled(true);
|
||||
CallableSystemAction.get(CaseDeleteAction.class).setEnabled(true);
|
||||
CallableSystemAction.get(OpenTimelineAction.class).setEnabled(true);
|
||||
CallableSystemAction.get(OpenCommVisualizationToolAction.class).setEnabled(true);
|
||||
@ -1218,6 +1220,7 @@ public class Case {
|
||||
CallableSystemAction.get(AddImageAction.class).setEnabled(false);
|
||||
CallableSystemAction.get(CaseCloseAction.class).setEnabled(false);
|
||||
CallableSystemAction.get(CasePropertiesAction.class).setEnabled(false);
|
||||
CallableSystemAction.get(DataSourceSummaryAction.class).setEnabled(false);
|
||||
CallableSystemAction.get(CaseDeleteAction.class).setEnabled(false);
|
||||
CallableSystemAction.get(OpenTimelineAction.class).setEnabled(false);
|
||||
CallableSystemAction.get(OpenCommVisualizationToolAction.class).setEnabled(false);
|
||||
|
@ -55,7 +55,7 @@ final class CasePropertiesAction extends CallableSystemAction {
|
||||
casePropertiesDialog = new JDialog(mainWindow, title, true);
|
||||
CaseInformationPanel caseInformationPanel = new CaseInformationPanel();
|
||||
caseInformationPanel.addCloseButtonAction((ActionEvent e) -> {
|
||||
casePropertiesDialog.setVisible(false);
|
||||
casePropertiesDialog.dispose();
|
||||
});
|
||||
casePropertiesDialog.add(caseInformationPanel);
|
||||
casePropertiesDialog.setResizable(true);
|
||||
|
@ -61,7 +61,8 @@ public final class IngestJobInfoPanel extends javax.swing.JPanel {
|
||||
private void customizeComponents() {
|
||||
refresh();
|
||||
this.ingestJobTable.getSelectionModel().addListSelectionListener((ListSelectionEvent e) -> {
|
||||
this.ingestModuleTableModel = new IngestModuleTableModel(this.ingestJobs.get(ingestJobTable.getSelectedRow()));
|
||||
IngestJobInfo currJob = (ingestJobTable.getSelectedRow() < 0 ? null : this.ingestJobs.get(ingestJobTable.getSelectedRow()));
|
||||
this.ingestModuleTableModel = new IngestModuleTableModel(currJob);
|
||||
this.ingestModuleTable.setModel(this.ingestModuleTableModel);
|
||||
});
|
||||
|
||||
|
@ -0,0 +1,5 @@
|
||||
DataSourceSummaryPanel.fileCountsLabel.text=Files (based on mimetype)
|
||||
DataSourceSummaryPanel.opperatingSystemLabel.text=OS:
|
||||
DataSourceSummaryPanel.ingestJobsLabel.text=Ingest Jobs
|
||||
DataSourceSummaryPanel.closeButton.text=Close
|
||||
DataSourceSummaryPanel.gotoDataSourceButton.text=Goto Data Source
|
@ -0,0 +1,69 @@
|
||||
/*
|
||||
* Autopsy Forensic Browser
|
||||
*
|
||||
* Copyright 2019 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.casemodule.datasourceSummary;
|
||||
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.beans.PropertyChangeEvent;
|
||||
import java.util.EnumSet;
|
||||
import javax.swing.Action;
|
||||
import org.openide.awt.ActionID;
|
||||
import org.openide.awt.ActionRegistration;
|
||||
import org.openide.util.HelpCtx;
|
||||
import org.openide.util.NbBundle.Messages;
|
||||
import org.openide.util.actions.CallableSystemAction;
|
||||
import org.sleuthkit.autopsy.casemodule.Case;
|
||||
|
||||
@ActionID(category = "Case", id = "org.sleuthkit.autopsy.casemodule.datasourceSummary.DataSourceSummaryAction")
|
||||
@ActionRegistration(displayName = "#CTL_DataSourceSummaryAction", lazy = false)
|
||||
@Messages({"CTL_DataSourceSummaryAction=Data Source Summary"})
|
||||
/**
|
||||
* DataSourceSummaryAction action for the Case menu to activate a ViewSummaryInformationAction selecting the first data source.
|
||||
*/
|
||||
public class DataSourceSummaryAction extends CallableSystemAction {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* Create a datasource summary action which will be disabled when no case is
|
||||
* open.
|
||||
*/
|
||||
DataSourceSummaryAction() {
|
||||
putValue(Action.NAME, Bundle.CTL_DataSourceSummaryAction());
|
||||
this.setEnabled(false);
|
||||
Case.addEventTypeSubscriber(EnumSet.of(Case.Events.CURRENT_CASE), (PropertyChangeEvent evt) -> {
|
||||
setEnabled(null != evt.getNewValue());
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void performAction() {
|
||||
//perform the action of a ViewSummaryInformationAction with a ActionEvent which will not be used
|
||||
new ViewSummaryInformationAction(null).actionPerformed(new ActionEvent(Boolean.TRUE, 0, ""));
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return Bundle.CTL_DataSourceSummaryAction();
|
||||
}
|
||||
|
||||
@Override
|
||||
public HelpCtx getHelpCtx() {
|
||||
return HelpCtx.DEFAULT_HELP;
|
||||
}
|
||||
}
|
@ -0,0 +1,182 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
|
||||
<Form version="1.6" 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="jSeparator1" alignment="1" max="32767" attributes="0"/>
|
||||
<Group type="102" attributes="0">
|
||||
<EmptySpace min="-2" max="-2" attributes="0"/>
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Component id="dataSourcesScrollPane" alignment="1" max="32767" attributes="0"/>
|
||||
<Group type="102" alignment="1" attributes="0">
|
||||
<EmptySpace min="0" pref="0" max="32767" attributes="0"/>
|
||||
<Component id="gotoDataSourceButton" linkSize="1" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="closeButton" linkSize="1" min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<Group type="102" attributes="0">
|
||||
<Group type="103" groupAlignment="1" attributes="0">
|
||||
<Component id="fileCountsLabel" max="32767" attributes="0"/>
|
||||
<Component id="fileCountsScrollPane" alignment="1" min="-2" pref="140" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<EmptySpace type="unrelated" min="-2" max="-2" attributes="0"/>
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Component id="ingestJobsLabel" max="32767" attributes="0"/>
|
||||
<Component id="ingestJobsScrollPane" pref="474" max="32767" attributes="0"/>
|
||||
<Group type="102" alignment="1" attributes="0">
|
||||
<Component id="opperatingSystemLabel" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="opperatingSystemValueLabel" max="32767" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
</Group>
|
||||
</Group>
|
||||
<EmptySpace min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
<DimensionLayout dim="1">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Group type="102" alignment="0" attributes="0">
|
||||
<EmptySpace min="-2" pref="8" max="-2" attributes="0"/>
|
||||
<Component id="dataSourcesScrollPane" pref="120" max="32767" attributes="0"/>
|
||||
<EmptySpace min="-2" max="-2" attributes="0"/>
|
||||
<Component id="jSeparator1" min="-2" pref="5" max="-2" attributes="0"/>
|
||||
<EmptySpace min="-2" max="-2" attributes="0"/>
|
||||
<Group type="103" groupAlignment="3" attributes="0">
|
||||
<Component id="fileCountsLabel" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="ingestJobsLabel" alignment="3" min="-2" pref="14" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<EmptySpace min="-2" max="-2" attributes="0"/>
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Component id="fileCountsScrollPane" min="-2" pref="107" max="-2" attributes="0"/>
|
||||
<Component id="ingestJobsScrollPane" pref="0" max="32767" attributes="0"/>
|
||||
</Group>
|
||||
<EmptySpace min="-2" max="-2" attributes="0"/>
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Component id="opperatingSystemLabel" alignment="1" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="opperatingSystemValueLabel" min="-2" pref="14" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<EmptySpace min="-2" pref="10" max="-2" attributes="0"/>
|
||||
<Group type="103" groupAlignment="3" attributes="0">
|
||||
<Component id="closeButton" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="gotoDataSourceButton" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<EmptySpace min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
</Layout>
|
||||
<SubComponents>
|
||||
<Component class="javax.swing.JSeparator" name="jSeparator1">
|
||||
</Component>
|
||||
<Container class="javax.swing.JScrollPane" name="dataSourcesScrollPane">
|
||||
<AuxValues>
|
||||
<AuxValue name="autoScrollPane" type="java.lang.Boolean" value="true"/>
|
||||
</AuxValues>
|
||||
|
||||
<Layout class="org.netbeans.modules.form.compat2.layouts.support.JScrollPaneSupportLayout"/>
|
||||
<SubComponents>
|
||||
<Component class="javax.swing.JTable" name="dataSourcesTable">
|
||||
<Properties>
|
||||
<Property name="model" type="javax.swing.table.TableModel" editor="org.netbeans.modules.form.RADConnectionPropertyEditor">
|
||||
<Connection code="dataSourceTableModel" type="code"/>
|
||||
</Property>
|
||||
<Property name="selectionModel" type="javax.swing.ListSelectionModel" editor="org.netbeans.modules.form.editors2.JTableSelectionModelEditor">
|
||||
<JTableSelectionModel selectionMode="0"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
</Component>
|
||||
</SubComponents>
|
||||
</Container>
|
||||
<Container class="javax.swing.JScrollPane" name="ingestJobsScrollPane">
|
||||
<AuxValues>
|
||||
<AuxValue name="autoScrollPane" type="java.lang.Boolean" value="true"/>
|
||||
</AuxValues>
|
||||
|
||||
<Layout class="org.netbeans.modules.form.compat2.layouts.support.JScrollPaneSupportLayout"/>
|
||||
<SubComponents>
|
||||
<Component class="javax.swing.JTable" name="ingestJobsTable">
|
||||
<Properties>
|
||||
<Property name="model" type="javax.swing.table.TableModel" editor="org.netbeans.modules.form.RADConnectionPropertyEditor">
|
||||
<Connection code="ingestJobTableModel" type="code"/>
|
||||
</Property>
|
||||
<Property name="selectionModel" type="javax.swing.ListSelectionModel" editor="org.netbeans.modules.form.editors2.JTableSelectionModelEditor">
|
||||
<JTableSelectionModel selectionMode="0"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
</Component>
|
||||
</SubComponents>
|
||||
</Container>
|
||||
<Container class="javax.swing.JScrollPane" name="fileCountsScrollPane">
|
||||
<AuxValues>
|
||||
<AuxValue name="autoScrollPane" type="java.lang.Boolean" value="true"/>
|
||||
</AuxValues>
|
||||
|
||||
<Layout class="org.netbeans.modules.form.compat2.layouts.support.JScrollPaneSupportLayout"/>
|
||||
<SubComponents>
|
||||
<Component class="javax.swing.JTable" name="fileCountsTable">
|
||||
<Properties>
|
||||
<Property name="model" type="javax.swing.table.TableModel" editor="org.netbeans.modules.form.RADConnectionPropertyEditor">
|
||||
<Connection code="filesTableModel" type="code"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
</Component>
|
||||
</SubComponents>
|
||||
</Container>
|
||||
<Component class="javax.swing.JLabel" name="opperatingSystemLabel">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/casemodule/datasourceSummary/Bundle.properties" key="DataSourceSummaryPanel.opperatingSystemLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
</Component>
|
||||
<Component class="javax.swing.JLabel" name="opperatingSystemValueLabel">
|
||||
</Component>
|
||||
<Component class="javax.swing.JLabel" name="fileCountsLabel">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/casemodule/datasourceSummary/Bundle.properties" key="DataSourceSummaryPanel.fileCountsLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
</Component>
|
||||
<Component class="javax.swing.JLabel" name="ingestJobsLabel">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/casemodule/datasourceSummary/Bundle.properties" key="DataSourceSummaryPanel.ingestJobsLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
</Component>
|
||||
<Component class="javax.swing.JButton" name="closeButton">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/casemodule/datasourceSummary/Bundle.properties" key="DataSourceSummaryPanel.closeButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
</Component>
|
||||
<Component class="javax.swing.JButton" name="gotoDataSourceButton">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/casemodule/datasourceSummary/Bundle.properties" key="DataSourceSummaryPanel.gotoDataSourceButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
<Property name="enabled" type="boolean" value="false"/>
|
||||
</Properties>
|
||||
<Events>
|
||||
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="gotoDataSourceButtonActionPerformed"/>
|
||||
</Events>
|
||||
</Component>
|
||||
</SubComponents>
|
||||
</Form>
|
@ -0,0 +1,698 @@
|
||||
/*
|
||||
* Autopsy Forensic Browser
|
||||
*
|
||||
* Copyright 2019 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.casemodule.datasourceSummary;
|
||||
|
||||
import java.awt.Rectangle;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.text.DateFormat;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
import javax.swing.JOptionPane;
|
||||
import javax.swing.event.ListSelectionEvent;
|
||||
import javax.swing.table.AbstractTableModel;
|
||||
import org.openide.util.NbBundle.Messages;
|
||||
import org.sleuthkit.autopsy.casemodule.Case;
|
||||
import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException;
|
||||
import org.sleuthkit.autopsy.datamodel.utils.FileTypeUtils;
|
||||
import org.sleuthkit.autopsy.directorytree.ViewContextAction;
|
||||
import org.sleuthkit.datamodel.BlackboardArtifact;
|
||||
import org.sleuthkit.datamodel.CaseDbAccessManager.CaseDbAccessQueryCallback;
|
||||
import org.sleuthkit.datamodel.DataSource;
|
||||
import org.sleuthkit.datamodel.IngestJobInfo;
|
||||
import org.sleuthkit.datamodel.OSInfo;
|
||||
import org.sleuthkit.datamodel.OSUtility;
|
||||
import org.sleuthkit.datamodel.SleuthkitCase;
|
||||
import org.sleuthkit.datamodel.TskCoreException;
|
||||
import org.sleuthkit.datamodel.TskData;
|
||||
|
||||
final class DataSourceSummaryPanel extends javax.swing.JPanel {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
private final List<IngestJobInfo> allIngestJobs = new ArrayList<>();
|
||||
private List<IngestJobInfo> ingestJobs = new ArrayList<>();
|
||||
private DataSourceTableModel dataSourceTableModel = new DataSourceTableModel();
|
||||
private IngestJobTableModel ingestJobTableModel = new IngestJobTableModel();
|
||||
private FilesTableModel filesTableModel = new FilesTableModel(null);
|
||||
private final List<DataSource> dataSources = new ArrayList<>();
|
||||
private final DateFormat datetimeFormat = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
|
||||
private static final Logger logger = Logger.getLogger(DataSourceSummaryPanel.class.getName());
|
||||
private List<OSInfo> osInfoList;
|
||||
|
||||
/**
|
||||
* Creates new form DataSourceSummaryPanel for displaying a summary of the
|
||||
* data sources for the fcurrent case and the contents found for each
|
||||
* datasource.
|
||||
*/
|
||||
@Messages({"DataSourceSummaryPanel.getDataSources.error.text=Failed to get the list of datasources for the current case.",
|
||||
"DataSourceSummaryPanel.getDataSources.error.title=Load Failure"})
|
||||
DataSourceSummaryPanel() {
|
||||
initComponents();
|
||||
ingestJobsTable.getTableHeader().setReorderingAllowed(false);
|
||||
fileCountsTable.getTableHeader().setReorderingAllowed(false);
|
||||
dataSourcesTable.getTableHeader().setReorderingAllowed(false);
|
||||
try {
|
||||
SleuthkitCase skCase = Case.getCurrentCaseThrows().getSleuthkitCase();
|
||||
allIngestJobs.addAll(skCase.getIngestJobs());
|
||||
dataSources.addAll(skCase.getDataSources());
|
||||
osInfoList = OSUtility.getOSInfo(skCase);
|
||||
} catch (TskCoreException | NoCurrentCaseException ex) {
|
||||
logger.log(Level.SEVERE, "Failed to load ingest jobs.", ex);
|
||||
JOptionPane.showMessageDialog(this, Bundle.DataSourceSummaryPanel_getDataSources_error_text(), Bundle.DataSourceSummaryPanel_getDataSources_error_title(), JOptionPane.ERROR_MESSAGE);
|
||||
}
|
||||
dataSourcesTable.getSelectionModel().addListSelectionListener((ListSelectionEvent e) -> {
|
||||
if (!e.getValueIsAdjusting()) {
|
||||
DataSource selectedDataSource = (dataSourcesTable.getSelectedRow() < 0 ? null : dataSources.get(dataSourcesTable.getSelectedRow()));
|
||||
gotoDataSourceButton.setEnabled(selectedDataSource != null);
|
||||
updateIngestJobs(selectedDataSource);
|
||||
filesTableModel = new FilesTableModel(selectedDataSource);
|
||||
fileCountsTable.setModel(filesTableModel);
|
||||
opperatingSystemValueLabel.setText(getOSName(selectedDataSource));
|
||||
this.repaint();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the name of the operating system if it is available. Otherwise get
|
||||
* and empty string.
|
||||
*
|
||||
* @param selectedDataSource the datasource to get the OS information for
|
||||
*
|
||||
* @return the name of the opperating system on the specified datasource,
|
||||
* empty string if no opperating system info found
|
||||
*/
|
||||
private String getOSName(DataSource selectedDataSource) {
|
||||
String osName = "";
|
||||
if (selectedDataSource != null) {
|
||||
for (OSInfo osInfo : osInfoList) {
|
||||
try {
|
||||
//assumes only one Opperating System per datasource
|
||||
//get the datasource id from the OSInfo's first artifact if it has artifacts
|
||||
if (!osInfo.getArtifacts().isEmpty() && osInfo.getArtifacts().get(0).getDataSource().getId() == selectedDataSource.getId()) {
|
||||
osName = osInfo.getOSName();
|
||||
//if this OSInfo object has a name use it otherwise keep checking OSInfo objects
|
||||
if (!osName.isEmpty()) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
} catch (TskCoreException ignored) {
|
||||
//unable to get datasource for the OSInfo Object
|
||||
//continue checking for OSInfo objects to try and get get the desired information
|
||||
}
|
||||
}
|
||||
}
|
||||
return osName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the ingestJobs list with the ingest jobs for the
|
||||
* selectedDataSource
|
||||
*
|
||||
* @param selectedDataSource the datasource to find the ingest jobs for
|
||||
*/
|
||||
@Messages({"DataSourceSummaryPanel.loadIngestJob.error.text=Failed to load ingest jobs.",
|
||||
"DataSourceSummaryPanel.loadIngestJob.error.title=Load Failure"})
|
||||
private void updateIngestJobs(DataSource selectedDataSource) {
|
||||
ingestJobs.clear();
|
||||
if (selectedDataSource != null) {
|
||||
for (IngestJobInfo ingestJob : allIngestJobs) {
|
||||
if (ingestJob.getObjectId() == selectedDataSource.getId()) {
|
||||
ingestJobs.add(ingestJob);
|
||||
}
|
||||
}
|
||||
}
|
||||
ingestJobTableModel = new IngestJobTableModel();
|
||||
ingestJobsTable.setModel(ingestJobTableModel);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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() {
|
||||
|
||||
jSeparator1 = new javax.swing.JSeparator();
|
||||
dataSourcesScrollPane = new javax.swing.JScrollPane();
|
||||
dataSourcesTable = new javax.swing.JTable();
|
||||
ingestJobsScrollPane = new javax.swing.JScrollPane();
|
||||
ingestJobsTable = new javax.swing.JTable();
|
||||
fileCountsScrollPane = new javax.swing.JScrollPane();
|
||||
fileCountsTable = new javax.swing.JTable();
|
||||
opperatingSystemLabel = new javax.swing.JLabel();
|
||||
opperatingSystemValueLabel = new javax.swing.JLabel();
|
||||
fileCountsLabel = new javax.swing.JLabel();
|
||||
ingestJobsLabel = new javax.swing.JLabel();
|
||||
closeButton = new javax.swing.JButton();
|
||||
gotoDataSourceButton = new javax.swing.JButton();
|
||||
|
||||
dataSourcesTable.setModel(dataSourceTableModel);
|
||||
dataSourcesTable.setSelectionMode(javax.swing.ListSelectionModel.SINGLE_SELECTION);
|
||||
dataSourcesScrollPane.setViewportView(dataSourcesTable);
|
||||
|
||||
ingestJobsTable.setModel(ingestJobTableModel);
|
||||
ingestJobsTable.setSelectionMode(javax.swing.ListSelectionModel.SINGLE_SELECTION);
|
||||
ingestJobsScrollPane.setViewportView(ingestJobsTable);
|
||||
|
||||
fileCountsTable.setModel(filesTableModel);
|
||||
fileCountsScrollPane.setViewportView(fileCountsTable);
|
||||
|
||||
org.openide.awt.Mnemonics.setLocalizedText(opperatingSystemLabel, org.openide.util.NbBundle.getMessage(DataSourceSummaryPanel.class, "DataSourceSummaryPanel.opperatingSystemLabel.text")); // NOI18N
|
||||
|
||||
org.openide.awt.Mnemonics.setLocalizedText(fileCountsLabel, org.openide.util.NbBundle.getMessage(DataSourceSummaryPanel.class, "DataSourceSummaryPanel.fileCountsLabel.text")); // NOI18N
|
||||
|
||||
org.openide.awt.Mnemonics.setLocalizedText(ingestJobsLabel, org.openide.util.NbBundle.getMessage(DataSourceSummaryPanel.class, "DataSourceSummaryPanel.ingestJobsLabel.text")); // NOI18N
|
||||
|
||||
org.openide.awt.Mnemonics.setLocalizedText(closeButton, org.openide.util.NbBundle.getMessage(DataSourceSummaryPanel.class, "DataSourceSummaryPanel.closeButton.text")); // NOI18N
|
||||
|
||||
org.openide.awt.Mnemonics.setLocalizedText(gotoDataSourceButton, org.openide.util.NbBundle.getMessage(DataSourceSummaryPanel.class, "DataSourceSummaryPanel.gotoDataSourceButton.text")); // NOI18N
|
||||
gotoDataSourceButton.setEnabled(false);
|
||||
gotoDataSourceButton.addActionListener(new java.awt.event.ActionListener() {
|
||||
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||
gotoDataSourceButtonActionPerformed(evt);
|
||||
}
|
||||
});
|
||||
|
||||
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
|
||||
this.setLayout(layout);
|
||||
layout.setHorizontalGroup(
|
||||
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addComponent(jSeparator1, javax.swing.GroupLayout.Alignment.TRAILING)
|
||||
.addGroup(layout.createSequentialGroup()
|
||||
.addContainerGap()
|
||||
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addComponent(dataSourcesScrollPane, javax.swing.GroupLayout.Alignment.TRAILING)
|
||||
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
|
||||
.addGap(0, 0, Short.MAX_VALUE)
|
||||
.addComponent(gotoDataSourceButton)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(closeButton))
|
||||
.addGroup(layout.createSequentialGroup()
|
||||
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
|
||||
.addComponent(fileCountsLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
||||
.addComponent(fileCountsScrollPane, javax.swing.GroupLayout.PREFERRED_SIZE, 140, javax.swing.GroupLayout.PREFERRED_SIZE))
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
|
||||
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addComponent(ingestJobsLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
||||
.addComponent(ingestJobsScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, 474, Short.MAX_VALUE)
|
||||
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
|
||||
.addComponent(opperatingSystemLabel)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(opperatingSystemValueLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)))))
|
||||
.addContainerGap())
|
||||
);
|
||||
|
||||
layout.linkSize(javax.swing.SwingConstants.HORIZONTAL, new java.awt.Component[] {closeButton, gotoDataSourceButton});
|
||||
|
||||
layout.setVerticalGroup(
|
||||
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGroup(layout.createSequentialGroup()
|
||||
.addGap(8, 8, 8)
|
||||
.addComponent(dataSourcesScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, 120, Short.MAX_VALUE)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(jSeparator1, javax.swing.GroupLayout.PREFERRED_SIZE, 5, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
|
||||
.addComponent(fileCountsLabel)
|
||||
.addComponent(ingestJobsLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 14, javax.swing.GroupLayout.PREFERRED_SIZE))
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addComponent(fileCountsScrollPane, javax.swing.GroupLayout.PREFERRED_SIZE, 107, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||
.addComponent(ingestJobsScrollPane, javax.swing.GroupLayout.PREFERRED_SIZE, 0, Short.MAX_VALUE))
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addComponent(opperatingSystemLabel, javax.swing.GroupLayout.Alignment.TRAILING)
|
||||
.addComponent(opperatingSystemValueLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 14, javax.swing.GroupLayout.PREFERRED_SIZE))
|
||||
.addGap(10, 10, 10)
|
||||
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
|
||||
.addComponent(closeButton)
|
||||
.addComponent(gotoDataSourceButton))
|
||||
.addContainerGap())
|
||||
);
|
||||
}// </editor-fold>//GEN-END:initComponents
|
||||
|
||||
/**
|
||||
* Adds an action listener to the Close button of the panel.
|
||||
*
|
||||
* @param action
|
||||
*/
|
||||
void addCloseButtonAction(ActionListener action) {
|
||||
this.closeButton.addActionListener(action);
|
||||
//the gotoDataSourceButton should also close the dialog
|
||||
this.gotoDataSourceButton.addActionListener(action);
|
||||
}
|
||||
|
||||
/**
|
||||
* Select the data source with the specicied data source id. If no data
|
||||
* source matches the dataSourceID it will select the first datasource.
|
||||
*
|
||||
* @param dataSourceID the ID of the datasource to select, null will cause
|
||||
* the first datasource to be selected
|
||||
*/
|
||||
void selectDataSource(Long dataSourceID) {
|
||||
if (dataSourceID != null) {
|
||||
for (int i = 0; i < dataSources.size(); i++) {
|
||||
if (dataSources.get(i).getId() == dataSourceID) {
|
||||
dataSourcesTable.setRowSelectionInterval(i, i);
|
||||
//scroll down from top of table to where selected datasource is
|
||||
dataSourcesTable.scrollRectToVisible(new Rectangle(dataSourcesTable.getCellRect(i, 0, true)));
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
//if there are data sources in the list and none were found that matched the specied dataSourceID select the first one
|
||||
if (!dataSources.isEmpty()) {
|
||||
dataSourcesTable.setRowSelectionInterval(0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Performed when the Goto Data Source button is clicked, will cause the
|
||||
* window to be closed and the data source which was selected to be
|
||||
* navigated to in the tree.
|
||||
*/
|
||||
private void gotoDataSourceButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_gotoDataSourceButtonActionPerformed
|
||||
//the dialog will be closed due to the action listener added in addCloseButtonAction
|
||||
DataSource selectedDataSource = (dataSourcesTable.getSelectedRow() < 0 ? null : dataSources.get(dataSourcesTable.getSelectedRow()));
|
||||
if (selectedDataSource != null) {
|
||||
new ViewContextAction("", selectedDataSource).actionPerformed(evt);
|
||||
}
|
||||
}//GEN-LAST:event_gotoDataSourceButtonActionPerformed
|
||||
|
||||
|
||||
// Variables declaration - do not modify//GEN-BEGIN:variables
|
||||
private javax.swing.JButton closeButton;
|
||||
private javax.swing.JScrollPane dataSourcesScrollPane;
|
||||
private javax.swing.JTable dataSourcesTable;
|
||||
private javax.swing.JLabel fileCountsLabel;
|
||||
private javax.swing.JScrollPane fileCountsScrollPane;
|
||||
private javax.swing.JTable fileCountsTable;
|
||||
private javax.swing.JButton gotoDataSourceButton;
|
||||
private javax.swing.JLabel ingestJobsLabel;
|
||||
private javax.swing.JScrollPane ingestJobsScrollPane;
|
||||
private javax.swing.JTable ingestJobsTable;
|
||||
private javax.swing.JSeparator jSeparator1;
|
||||
private javax.swing.JLabel opperatingSystemLabel;
|
||||
private javax.swing.JLabel opperatingSystemValueLabel;
|
||||
// End of variables declaration//GEN-END:variables
|
||||
|
||||
/**
|
||||
* Table model for the Data source table, to display all data sources for
|
||||
* the current case.
|
||||
*/
|
||||
@Messages({"DataSourceSummaryPanel.DataSourceTableModel.dataSourceName.header=Data Source Name",
|
||||
"DataSourceSummaryPanel.DataSourceTableModel.type.header=Type",
|
||||
"DataSourceSummaryPanel.DataSourceTableModel.files.header=Files",
|
||||
"DataSourceSummaryPanel.DataSourceTableModel.results.header=Results",
|
||||
"DataSourceSummaryPanel.DataSourceTableModel.tags.header=Tags"})
|
||||
private class DataSourceTableModel extends AbstractTableModel {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private final List<String> columnHeaders = new ArrayList<>();
|
||||
private final Map<Long, Long> fileCountsMap;
|
||||
private final Map<Long, Long> artifactCountsMap;
|
||||
private final Map<Long, Long> tagCountsMap;
|
||||
|
||||
/**
|
||||
* Create a new DataSourceTableModel for the current case.
|
||||
*/
|
||||
DataSourceTableModel() {
|
||||
columnHeaders.add(Bundle.DataSourceSummaryPanel_DataSourceTableModel_dataSourceName_header());
|
||||
columnHeaders.add(Bundle.DataSourceSummaryPanel_DataSourceTableModel_type_header());
|
||||
columnHeaders.add(Bundle.DataSourceSummaryPanel_DataSourceTableModel_files_header());
|
||||
columnHeaders.add(Bundle.DataSourceSummaryPanel_DataSourceTableModel_results_header());
|
||||
columnHeaders.add(Bundle.DataSourceSummaryPanel_DataSourceTableModel_tags_header());
|
||||
fileCountsMap = getCountsOfFiles();
|
||||
artifactCountsMap = getCountsOfArtifacts();
|
||||
tagCountsMap = getCountsOfTags();
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getRowCount() {
|
||||
return dataSources.size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getColumnCount() {
|
||||
return columnHeaders.size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getValueAt(int rowIndex, int columnIndex) {
|
||||
DataSource currentDataSource = dataSources.get(rowIndex);
|
||||
Long count;
|
||||
switch (columnIndex) {
|
||||
case 0:
|
||||
return currentDataSource.getName();
|
||||
case 1:
|
||||
return "";
|
||||
case 2:
|
||||
//display 0 if no count is found
|
||||
count = fileCountsMap.get(currentDataSource.getId());
|
||||
return count == null ? 0 : count;
|
||||
case 3:
|
||||
//display 0 if no count is found
|
||||
count = artifactCountsMap.get(currentDataSource.getId());
|
||||
return count == null ? 0 : count;
|
||||
case 4:
|
||||
//display 0 if no count is found
|
||||
count = tagCountsMap.get(currentDataSource.getId());
|
||||
return count == null ? 0 : count;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a map containing the number of files in each data source in the
|
||||
* current case.
|
||||
*
|
||||
* @return Collection which maps datasource id to a count for the number
|
||||
* of files in the datasource, will only contain entries for
|
||||
* datasources which have at least 1 file
|
||||
*/
|
||||
private Map<Long, Long> getCountsOfFiles() {
|
||||
try {
|
||||
SleuthkitCase skCase = Case.getCurrentCaseThrows().getSleuthkitCase();
|
||||
DataSourceCountsCallback callback = new DataSourceCountsCallback();
|
||||
final String countFilesQuery = "data_source_obj_id, COUNT(*) AS count"
|
||||
+ " FROM tsk_files WHERE type<>" + TskData.TSK_DB_FILES_TYPE_ENUM.VIRTUAL_DIR.getFileType()
|
||||
+ " AND dir_type<>" + TskData.TSK_FS_NAME_TYPE_ENUM.VIRT_DIR.getValue()
|
||||
+ " AND name<>'' GROUP BY data_source_obj_id"; //NON-NLS
|
||||
skCase.getCaseDbAccessManager().select(countFilesQuery, callback);
|
||||
return callback.getMapOfCounts();
|
||||
} catch (TskCoreException | NoCurrentCaseException ex) {
|
||||
logger.log(Level.WARNING, "Unable to get counts of files for all datasources, providing empty results", ex);
|
||||
return Collections.emptyMap();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a map containing the number of artifacts in each data source in
|
||||
* the current case.
|
||||
*
|
||||
* @return Collection which maps datasource id to a count for the number
|
||||
* of artifacts in the datasource, will only contain entries for
|
||||
* datasources which have at least 1 artifact
|
||||
*/
|
||||
private Map<Long, Long> getCountsOfArtifacts() {
|
||||
try {
|
||||
SleuthkitCase skCase = Case.getCurrentCaseThrows().getSleuthkitCase();
|
||||
DataSourceCountsCallback callback = new DataSourceCountsCallback();
|
||||
final String countArtifactsQuery = "data_source_obj_id, COUNT(*) AS count"
|
||||
+ " FROM blackboard_artifacts WHERE review_status_id !=" + BlackboardArtifact.ReviewStatus.REJECTED.getID()
|
||||
+ " GROUP BY data_source_obj_id"; //NON-NLS
|
||||
skCase.getCaseDbAccessManager().select(countArtifactsQuery, callback);
|
||||
return callback.getMapOfCounts();
|
||||
} catch (TskCoreException | NoCurrentCaseException ex) {
|
||||
logger.log(Level.WARNING, "Unable to get counts of artifacts for all datasources, providing empty results", ex);
|
||||
return Collections.emptyMap();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a map containing the number of tags which have been applied in
|
||||
* each data source in the current case. Not necessarily the same as the
|
||||
* number of items tagged, as an item can have any number of tags.
|
||||
*
|
||||
* @return Collection which maps datasource id to a count for the number
|
||||
* of tags which have been applied in the datasource, will only
|
||||
* contain entries for datasources which have at least 1 item
|
||||
* tagged.
|
||||
*/
|
||||
private Map<Long, Long> getCountsOfTags() {
|
||||
try {
|
||||
SleuthkitCase skCase = Case.getCurrentCaseThrows().getSleuthkitCase();
|
||||
DataSourceCountsCallback fileCountcallback = new DataSourceCountsCallback();
|
||||
final String countFileTagsQuery = "data_source_obj_id, COUNT(*) AS count"
|
||||
+ " FROM content_tags as content_tags, tsk_files as tsk_files"
|
||||
+ " WHERE content_tags.obj_id = tsk_files.obj_id"
|
||||
+ " GROUP BY data_source_obj_id"; //NON-NLS
|
||||
skCase.getCaseDbAccessManager().select(countFileTagsQuery, fileCountcallback);
|
||||
Map<Long, Long> tagCountMap = new HashMap<>(fileCountcallback.getMapOfCounts());
|
||||
DataSourceCountsCallback artifactCountcallback = new DataSourceCountsCallback();
|
||||
final String countArtifactTagsQuery = "data_source_obj_id, COUNT(*) AS count"
|
||||
+ " FROM blackboard_artifact_tags as artifact_tags, blackboard_artifacts AS arts"
|
||||
+ " WHERE artifact_tags.artifact_id = arts.artifact_id"
|
||||
+ " GROUP BY data_source_obj_id"; //NON-NLS
|
||||
skCase.getCaseDbAccessManager().select(countArtifactTagsQuery, artifactCountcallback);
|
||||
//combine the results from the count artifact tags query into the copy of the mapped results from the count file tags query
|
||||
artifactCountcallback.getMapOfCounts().forEach((key, value) -> tagCountMap.merge(key, value, (value1, value2) -> value1 + value2));
|
||||
return tagCountMap;
|
||||
} catch (TskCoreException | NoCurrentCaseException ex) {
|
||||
logger.log(Level.WARNING, "Unable to get counts of tags for all datasources, providing empty results", ex);
|
||||
return Collections.emptyMap();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getColumnName(int column) {
|
||||
return columnHeaders.get(column);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the map of Data Source ID to counts of items found for a query
|
||||
* which selects data_source_obj_id and count(*) with a group by
|
||||
* data_source_obj_id clause.
|
||||
*/
|
||||
private class DataSourceCountsCallback implements CaseDbAccessQueryCallback {
|
||||
|
||||
Map<Long, Long> dataSourceObjIdCounts = new HashMap<>();
|
||||
|
||||
@Override
|
||||
public void process(ResultSet rs) {
|
||||
try {
|
||||
while (rs.next()) {
|
||||
try {
|
||||
dataSourceObjIdCounts.put(rs.getLong("data_source_obj_id"), rs.getLong("count"));
|
||||
} catch (SQLException ex) {
|
||||
logger.log(Level.WARNING, "Unable to get data_source_obj_id or count from result set", ex);
|
||||
}
|
||||
}
|
||||
} catch (SQLException ex) {
|
||||
logger.log(Level.WARNING, "Failed to get next result for counts by datasource", ex);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the processed results
|
||||
*
|
||||
* @return Collection which maps datasource id to a count for the
|
||||
* number of items found with that datasource id, only
|
||||
* contains entries for datasources with at least 1 item
|
||||
* found.
|
||||
*/
|
||||
Map<Long, Long> getMapOfCounts() {
|
||||
return Collections.unmodifiableMap(dataSourceObjIdCounts);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Table model for the Ingest Job table to display ingest jobs for the
|
||||
* selected datasource.
|
||||
*/
|
||||
@Messages({"DataSourceSummaryPanel.IngestJobTableModel.StartTime.header=Start Time",
|
||||
"DataSourceSummaryPanel.IngestJobTableModel.EndTime.header=End Time",
|
||||
"DataSourceSummaryPanel.IngestJobTableModel.IngestStatus.header=Ingest Status"})
|
||||
private class IngestJobTableModel extends AbstractTableModel {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private final List<String> columnHeaders = new ArrayList<>();
|
||||
|
||||
/**
|
||||
* Create a new IngestJobTableModel
|
||||
*/
|
||||
IngestJobTableModel() {
|
||||
columnHeaders.add(Bundle.DataSourceSummaryPanel_IngestJobTableModel_StartTime_header());
|
||||
columnHeaders.add(Bundle.DataSourceSummaryPanel_IngestJobTableModel_EndTime_header());
|
||||
columnHeaders.add(Bundle.DataSourceSummaryPanel_IngestJobTableModel_IngestStatus_header());
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getRowCount() {
|
||||
return ingestJobs.size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getColumnCount() {
|
||||
return columnHeaders.size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getValueAt(int rowIndex, int columnIndex) {
|
||||
IngestJobInfo currIngestJob = ingestJobs.get(rowIndex);
|
||||
switch (columnIndex) {
|
||||
case 0:
|
||||
return datetimeFormat.format(currIngestJob.getStartDateTime());
|
||||
case 1:
|
||||
Date endDate = currIngestJob.getEndDateTime();
|
||||
if (endDate.getTime() == 0) {
|
||||
return "N/A";
|
||||
}
|
||||
return datetimeFormat.format(currIngestJob.getEndDateTime());
|
||||
case 2:
|
||||
return currIngestJob.getStatus().getDisplayName();
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getColumnName(int column) {
|
||||
return columnHeaders.get(column);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Table model for the files table model to display counts of specific file
|
||||
* types found in the currently selected data source.
|
||||
*/
|
||||
@Messages({"DataSourceSummaryPanel.FilesTableModel.type.header=File Type",
|
||||
"DataSourceSummaryPanel.FilesTableModel.count.header=Count"})
|
||||
private class FilesTableModel extends AbstractTableModel {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
private final DataSource currentDataSource;
|
||||
private final List<String> columnHeaders = new ArrayList<>();
|
||||
|
||||
/**
|
||||
* Create a FilesTableModel for the speicified datasource.
|
||||
*
|
||||
* @param selectedDataSource the datasource which this filesTablemodel
|
||||
* will represent
|
||||
*/
|
||||
FilesTableModel(DataSource selectedDataSource) {
|
||||
columnHeaders.add(Bundle.DataSourceSummaryPanel_FilesTableModel_type_header());
|
||||
columnHeaders.add(Bundle.DataSourceSummaryPanel_FilesTableModel_count_header());
|
||||
currentDataSource = selectedDataSource;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getRowCount() {
|
||||
//should be kept equal to the number of types we are displaying in the tables
|
||||
return 5;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getColumnCount() {
|
||||
return columnHeaders.size();
|
||||
}
|
||||
|
||||
@Messages({
|
||||
"DataSourceSummaryPanel.FilesTableModel.images.row=Images",
|
||||
"DataSourceSummaryPanel.FilesTableModel.videos.row=Videos",
|
||||
"DataSourceSummaryPanel.FilesTableModel.audio.row=Audio",
|
||||
"DataSourceSummaryPanel.FilesTableModel.documents.row=Documents",
|
||||
"DataSourceSummaryPanel.FilesTableModel.executables.row=Executables"
|
||||
})
|
||||
@Override
|
||||
public Object getValueAt(int rowIndex, int columnIndex) {
|
||||
if (columnIndex == 0) {
|
||||
switch (rowIndex) {
|
||||
case 0:
|
||||
return Bundle.DataSourceSummaryPanel_FilesTableModel_images_row();
|
||||
case 1:
|
||||
return Bundle.DataSourceSummaryPanel_FilesTableModel_videos_row();
|
||||
case 2:
|
||||
return Bundle.DataSourceSummaryPanel_FilesTableModel_audio_row();
|
||||
case 3:
|
||||
return Bundle.DataSourceSummaryPanel_FilesTableModel_documents_row();
|
||||
case 4:
|
||||
return Bundle.DataSourceSummaryPanel_FilesTableModel_executables_row();
|
||||
default:
|
||||
break;
|
||||
}
|
||||
} else if (columnIndex == 1) {
|
||||
switch (rowIndex) {
|
||||
case 0:
|
||||
return getCountOfFiles(FileTypeUtils.FileTypeCategory.IMAGE.getMediaTypes());
|
||||
case 1:
|
||||
return getCountOfFiles(FileTypeUtils.FileTypeCategory.VIDEO.getMediaTypes());
|
||||
case 2:
|
||||
return getCountOfFiles(FileTypeUtils.FileTypeCategory.AUDIO.getMediaTypes());
|
||||
case 3:
|
||||
return getCountOfFiles(FileTypeUtils.FileTypeCategory.DOCUMENTS.getMediaTypes());
|
||||
case 4:
|
||||
return getCountOfFiles(FileTypeUtils.FileTypeCategory.EXECUTABLE.getMediaTypes());
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the number of files in the case database for the current data
|
||||
* source which have the specified mimetypes.
|
||||
*
|
||||
* @param setOfMimeTypes the set of mime types which we are finding the
|
||||
* number of occurences of
|
||||
*
|
||||
* @return a Long value which represents the number of occurrences of
|
||||
* the specified mime types in the current case for the
|
||||
* specified data source, null if no count was retrieved
|
||||
*/
|
||||
private Long getCountOfFiles(Set<String> setOfMimeTypes) {
|
||||
if (currentDataSource != null) {
|
||||
try {
|
||||
String inClause = String.join("', '", setOfMimeTypes);
|
||||
SleuthkitCase skCase = Case.getCurrentCaseThrows().getSleuthkitCase();
|
||||
return skCase.countFilesWhere("data_source_obj_id=" + currentDataSource.getId()
|
||||
+ " AND type<>" + TskData.TSK_DB_FILES_TYPE_ENUM.VIRTUAL_DIR.getFileType()
|
||||
+ " AND dir_type<>" + TskData.TSK_FS_NAME_TYPE_ENUM.VIRT_DIR.getValue()
|
||||
+ " AND mime_type IN ('" + inClause + "')"
|
||||
+ " AND name<>''");
|
||||
} catch (TskCoreException | NoCurrentCaseException ex) {
|
||||
logger.log(Level.WARNING, "Unable to get count of files for specified mime types", ex);
|
||||
//unable to get count of files for the specified mimetypes cell will be displayed as empty
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getColumnName(int column) {
|
||||
return columnHeaders.get(column);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,75 @@
|
||||
/*
|
||||
* Autopsy Forensic Browser
|
||||
*
|
||||
* Copyright 2019 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.casemodule.datasourceSummary;
|
||||
|
||||
import java.awt.Frame;
|
||||
import java.awt.event.ActionEvent;
|
||||
import javax.swing.AbstractAction;
|
||||
import javax.swing.JDialog;
|
||||
import javax.swing.SwingUtilities;
|
||||
import org.openide.util.NbBundle.Messages;
|
||||
import org.openide.windows.WindowManager;
|
||||
|
||||
/**
|
||||
* ViewSummaryInformationAction action for opening a Data Source Summary Panel
|
||||
* with the specified data source selected if it is present.
|
||||
*/
|
||||
public final class ViewSummaryInformationAction extends AbstractAction {
|
||||
|
||||
private static JDialog dataSourceSummaryDialog;
|
||||
private static Long selectDataSource;
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* Create a ViewSummaryInformationAction for the selected datasource.
|
||||
*
|
||||
* @param selectedDataSource - the data source which is currently selected
|
||||
* and will be selected initially when the
|
||||
* DataSourceSummaryPanel opens.
|
||||
*/
|
||||
@Messages({"ViewSummaryInformationAction.name.text=View Summary Information"})
|
||||
public ViewSummaryInformationAction(Long selectedDataSource) {
|
||||
super(Bundle.ViewSummaryInformationAction_name_text());
|
||||
selectDataSource = selectedDataSource;
|
||||
}
|
||||
|
||||
@Messages({"ViewSummaryInformationAction.window.title=Data Source Summary"})
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent actionEvent) {
|
||||
SwingUtilities.invokeLater(() -> {
|
||||
String title = Bundle.ViewSummaryInformationAction_window_title();
|
||||
Frame mainWindow = WindowManager.getDefault().getMainWindow();
|
||||
dataSourceSummaryDialog = new JDialog(mainWindow, title, true);
|
||||
DataSourceSummaryPanel dataSourceSummaryPanel = new DataSourceSummaryPanel();
|
||||
//allow the buttons in DataSourceSummaryPanel to close this dialog
|
||||
dataSourceSummaryPanel.addCloseButtonAction((ActionEvent event) -> {
|
||||
dataSourceSummaryDialog.dispose();
|
||||
});
|
||||
//select the specifed data source
|
||||
dataSourceSummaryPanel.selectDataSource(selectDataSource);
|
||||
dataSourceSummaryDialog.add(dataSourceSummaryPanel);
|
||||
dataSourceSummaryDialog.setResizable(true);
|
||||
dataSourceSummaryDialog.pack();
|
||||
dataSourceSummaryDialog.setLocationRelativeTo(mainWindow);
|
||||
dataSourceSummaryDialog.setVisible(true);
|
||||
dataSourceSummaryDialog.toFront();
|
||||
});
|
||||
}
|
||||
|
||||
}
|
@ -48,6 +48,7 @@
|
||||
<attr name="noIconInMenu" boolvalue="false"/>
|
||||
</file>
|
||||
<file name="org-sleuthkit-autopsy-casemodule-CasePropertiesAction.instance"/>
|
||||
<file name="org-sleuthkit-autopsy-casemodule-datasourceSummary-DataSourceSummaryAction.instance"/>
|
||||
<file name="org-sleuthkit-autopsy-casemodule-CaseDeleteAction.instance"/>
|
||||
<file name="org-sleuthkit-autopsy-casemodule-CaseSaveAction.instance">
|
||||
<attr name="delegate" newvalue="org.sleuthkit.autopsy.casemodule.CaseSaveAction"/>
|
||||
@ -182,6 +183,10 @@
|
||||
<attr name="originalFile" stringvalue="Actions/Case/org-sleuthkit-autopsy-casemodule-CasePropertiesAction.instance"/>
|
||||
<attr name="position" intvalue="301"/>
|
||||
</file>
|
||||
<file name="org-sleuthkit-autopsy-casemodule-datasourceSummary-DataSourceSummaryAction.shadow">
|
||||
<attr name="originalFile" stringvalue="Actions/Case/org-sleuthkit-autopsy-casemodule-datasourceSummary-DataSourceSummaryAction.instance"/>
|
||||
<attr name="position" intvalue="302"/>
|
||||
</file>
|
||||
<file name="org-netbeans-modules-print-action-PageSetupAction.shadow_hidden"/>
|
||||
<file name="org-netbeans-modules-print-action-PrintAction.shadow_hidden"/>
|
||||
<file name="org-openide-actions-SaveAction.shadow_hidden"/>
|
||||
|
@ -34,6 +34,7 @@ import org.openide.util.NbBundle;
|
||||
import org.openide.util.NbBundle.Messages;
|
||||
import org.sleuthkit.autopsy.casemodule.Case;
|
||||
import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException;
|
||||
import org.sleuthkit.autopsy.casemodule.datasourceSummary.ViewSummaryInformationAction;
|
||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||
import org.sleuthkit.autopsy.directorytree.ExplorerNodeActionVisitor;
|
||||
import org.sleuthkit.autopsy.directorytree.FileSearchAction;
|
||||
@ -108,6 +109,7 @@ public class ImageNode extends AbstractContentNode<Image> {
|
||||
actionsList.addAll(ExplorerNodeActionVisitor.getActions(content));
|
||||
actionsList.add(new FileSearchAction(
|
||||
Bundle.ImageNode_getActions_openFileSearchByAttr_text()));
|
||||
actionsList.add(new ViewSummaryInformationAction(content.getId()));
|
||||
actionsList.add(new RunIngestModulesAction(Collections.<Content>singletonList(content)));
|
||||
actionsList.add(new NewWindowViewAction(
|
||||
NbBundle.getMessage(this.getClass(), "ImageNode.getActions.viewInNewWin.text"), this));
|
||||
|
@ -23,6 +23,7 @@ import java.util.Collections;
|
||||
import java.util.List;
|
||||
import javax.swing.Action;
|
||||
import org.openide.util.NbBundle;
|
||||
import org.sleuthkit.autopsy.casemodule.datasourceSummary.ViewSummaryInformationAction;
|
||||
import org.sleuthkit.autopsy.coreutils.ContextMenuExtensionPoint;
|
||||
import org.sleuthkit.autopsy.directorytree.ExtractAction;
|
||||
import org.sleuthkit.autopsy.directorytree.FileSearchAction;
|
||||
@ -63,6 +64,7 @@ public abstract class SpecialDirectoryNode extends AbstractAbstractFileNode<Spec
|
||||
actions.add(null); // creates a menu separator
|
||||
actions.add(new FileSearchAction(Bundle.ImageNode_getActions_openFileSearchByAttr_text()));
|
||||
if (content.isDataSource()) {
|
||||
actions.add(new ViewSummaryInformationAction(content.getId()));
|
||||
actions.add(new RunIngestModulesAction(Collections.<Content>singletonList(content)));
|
||||
} else {
|
||||
actions.add(new RunIngestModulesAction(content));
|
||||
|
@ -0,0 +1,207 @@
|
||||
/*
|
||||
* Autopsy Forensic Browser
|
||||
*
|
||||
* Copyright 2018-2019 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.datamodel.utils;
|
||||
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import static java.util.Arrays.asList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import javax.imageio.ImageIO;
|
||||
import static org.apache.commons.collections4.ListUtils.removeAll;
|
||||
import org.openide.util.NbBundle;
|
||||
|
||||
/**
|
||||
* Utilities for dealing with file/mime-types
|
||||
*/
|
||||
public final class FileTypeUtils {
|
||||
|
||||
private static final ImmutableSet<String> IMAGE_MIME_TYPES
|
||||
= new ImmutableSet.Builder<String>()
|
||||
.addAll(removeAll(asList(ImageIO.getReaderMIMETypes()),
|
||||
asList("application/octet-stream"))) //this claims to be supported, but is not really an image.
|
||||
.add("image/bmp", //NON-NLS
|
||||
"image/gif", //NON-NLS
|
||||
"image/jpeg", //NON-NLS
|
||||
"image/png", //NON-NLS
|
||||
"image/tiff", //NON-NLS
|
||||
"image/vnd.adobe.photoshop", //NON-NLS
|
||||
"image/x-raw-nikon", //NON-NLS
|
||||
"image/x-ms-bmp", //NON-NLS
|
||||
"image/x-icon", //NON-NLS
|
||||
"image/webp", //NON-NLS
|
||||
"image/vnd.microsoft.icon", //NON-NLS
|
||||
"image/x-rgb", //NON-NLS
|
||||
"image/x-ms-bmp", //NON-NLS
|
||||
"image/x-xbitmap", //NON-NLS
|
||||
"image/x-portable-graymap", //NON-NLS
|
||||
"image/x-portable-bitmap" //NON-NLS
|
||||
).build();
|
||||
private static final ImmutableSet<String> AUDIO_MIME_TYPES
|
||||
= new ImmutableSet.Builder<String>()
|
||||
.add("audio/midi", //NON-NLS
|
||||
"audio/mpeg", //NON-NLS
|
||||
"audio/webm", //NON-NLS
|
||||
"audio/ogg", //NON-NLS
|
||||
"audio/wav", //NON-NLS
|
||||
"audio/vnd.wave", //NON-NLS
|
||||
"audio/x-ms-wma"//NON-NLS
|
||||
).build();
|
||||
private static final ImmutableSet<String> VIDEO_MIME_TYPES
|
||||
= new ImmutableSet.Builder<String>()
|
||||
.add("video/webm", //NON-NLS
|
||||
"video/3gpp", //NON-NLS
|
||||
"video/3gpp2", //NON-NLS
|
||||
"video/ogg", //NON-NLS
|
||||
"video/mpeg", //NON-NLS
|
||||
"video/mp4", //NON-NLS
|
||||
"video/quicktime", //NON-NLS
|
||||
"video/x-msvideo", //NON-NLS
|
||||
"video/x-flv", //NON-NLS
|
||||
"video/x-m4v", //NON-NLS
|
||||
"video/x-ms-wmv"//NON-NLS
|
||||
).build();
|
||||
private static final ImmutableSet<String> DOCUMENT_MIME_TYPES
|
||||
= new ImmutableSet.Builder<String>()
|
||||
.add("text/plain", //NON-NLS
|
||||
"text/css", //NON-NLS
|
||||
"text/html", //NON-NLS
|
||||
"text/csv", //NON-NLS
|
||||
"text/xml", //NON-NLS
|
||||
"text/x-log", //NON-NLS
|
||||
"application/rtf", //NON-NLS
|
||||
"application/pdf", //NON-NLS
|
||||
"application/json", //NON-NLS
|
||||
"application/javascript", //NON-NLS
|
||||
"application/xml", //NON-NLS
|
||||
"application/x-msoffice", //NON-NLS
|
||||
"application/x-ooxml", //NON-NLS
|
||||
"application/msword", //NON-NLS
|
||||
"application/msword2", //NON-NLS
|
||||
"application/vnd.wordperfect", //NON-NLS
|
||||
"application/vnd.openxmlformats-officedocument.wordprocessingml.document", //NON-NLS
|
||||
"application/vnd.ms-powerpoint", //NON-NLS
|
||||
"application/vnd.openxmlformats-officedocument.presentationml.presentation", //NON-NLS
|
||||
"application/vnd.ms-excel", //NON-NLS
|
||||
"application/vnd.ms-excel.sheet.4", //NON-NLS
|
||||
"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", //NON-NLS
|
||||
"application/vnd.oasis.opendocument.presentation", //NON-NLS
|
||||
"application/vnd.oasis.opendocument.spreadsheet", //NON-NLS
|
||||
"application/vnd.oasis.opendocument.text" //NON-NLS
|
||||
).build();
|
||||
private static final ImmutableSet<String> EXECUTABLE_MIME_TYPES
|
||||
= new ImmutableSet.Builder<String>()
|
||||
.add("application/x-bat",//NON-NLS
|
||||
"application/x-dosexec",//NON-NLS
|
||||
"application/vnd.microsoft.portable-executable",//NON-NLS
|
||||
"application/x-msdownload",//NON-NLS
|
||||
"application/exe",//NON-NLS
|
||||
"application/x-exe",//NON-NLS
|
||||
"application/dos-exe",//NON-NLS
|
||||
"vms/exe",//NON-NLS
|
||||
"application/x-winexe",//NON-NLS
|
||||
"application/msdos-windows",//NON-NLS
|
||||
"application/x-msdos-program"//NON-NLS
|
||||
).build();
|
||||
private static final ImmutableSet<String> MULTI_MEDIA_MIME_TYPES
|
||||
= new ImmutableSet.Builder<String>()
|
||||
.addAll(IMAGE_MIME_TYPES)
|
||||
.addAll(AUDIO_MIME_TYPES)
|
||||
.addAll(VIDEO_MIME_TYPES)
|
||||
.build();
|
||||
private static final ImmutableSet<String> VISUAL_MEDIA_MIME_TYPES
|
||||
= new ImmutableSet.Builder<String>()
|
||||
.addAll(IMAGE_MIME_TYPES)
|
||||
.addAll(VIDEO_MIME_TYPES)
|
||||
.add("application/vnd.ms-asf", //NON-NLS
|
||||
"application/vnd.rn-realmedia", //NON-NLS
|
||||
"application/x-shockwave-flash" //NON-NLS
|
||||
).build();
|
||||
|
||||
private FileTypeUtils() {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Enum of categories/groups of file types.
|
||||
*/
|
||||
@NbBundle.Messages({
|
||||
"FileTypeCategory.Audio.displayName=Audio",
|
||||
"FileTypeCategory.Video.displayName=Video",
|
||||
"FileTypeCategory.Image.displayName=Image",
|
||||
"FileTypeCategory.Media.displayName=Media",
|
||||
"FileTypeCategory.Visual.displayName=Visual",
|
||||
"FileTypeCategory.Documents.displayName=Documents",
|
||||
"FileTypeCategory.Executables.displayName=Executables"})
|
||||
public enum FileTypeCategory {
|
||||
|
||||
IMAGE(Bundle.FileTypeCategory_Image_displayName(),
|
||||
IMAGE_MIME_TYPES,
|
||||
Collections.emptyList()),
|
||||
VIDEO(Bundle.FileTypeCategory_Video_displayName(),
|
||||
VIDEO_MIME_TYPES,
|
||||
Collections.emptyList()),
|
||||
AUDIO(Bundle.FileTypeCategory_Audio_displayName(),
|
||||
AUDIO_MIME_TYPES,
|
||||
Collections.emptyList()),
|
||||
/**
|
||||
* Images, Videos, flash Animations, etc
|
||||
*/
|
||||
VISUAL(Bundle.FileTypeCategory_Media_displayName(),
|
||||
VISUAL_MEDIA_MIME_TYPES,
|
||||
Collections.emptyList()),
|
||||
/**
|
||||
* VISUAL plus AUDIO.
|
||||
*/
|
||||
MEDIA(Bundle.FileTypeCategory_Media_displayName(),
|
||||
MULTI_MEDIA_MIME_TYPES,
|
||||
Collections.emptyList()),
|
||||
EXECUTABLE(Bundle.FileTypeCategory_Executables_displayName(),
|
||||
EXECUTABLE_MIME_TYPES,
|
||||
Collections.emptyList()),
|
||||
/**
|
||||
* (Plain) Text and "Office" documents.
|
||||
*/
|
||||
DOCUMENTS(Bundle.FileTypeCategory_Documents_displayName(),
|
||||
DOCUMENT_MIME_TYPES,
|
||||
Collections.emptyList());
|
||||
|
||||
private final String displayName;
|
||||
private final ImmutableSet<String> mediaTypes;
|
||||
private final ImmutableSet<String> extensions;
|
||||
|
||||
private FileTypeCategory(String displayName, Collection<String> mediaTypes, Collection<String> extensions) {
|
||||
this.displayName = displayName;
|
||||
this.mediaTypes = ImmutableSet.copyOf(mediaTypes);
|
||||
this.extensions = ImmutableSet.copyOf(extensions);
|
||||
}
|
||||
|
||||
public String getDisplayName() {
|
||||
return displayName;
|
||||
}
|
||||
|
||||
public ImmutableSet<String> getMediaTypes() {
|
||||
return mediaTypes;
|
||||
|
||||
}
|
||||
|
||||
public ImmutableSet<String> getExtensions() {
|
||||
throw new UnsupportedOperationException("This method is not implemented yet."); //just to be explicit.
|
||||
}
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user