Merge branch 'develop' of https://github.com/sleuthkit/autopsy into develop
@@ -20,8 +20,10 @@ package org.sleuthkit.autopsy.casemodule;
|
||||
|
||||
import java.awt.Component;
|
||||
import java.awt.Dialog;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.text.MessageFormat;
|
||||
import java.util.logging.Level;
|
||||
import javax.swing.Action;
|
||||
import javax.swing.ImageIcon;
|
||||
@@ -74,6 +76,7 @@ public final class AddImageAction extends CallableSystemAction implements Presen
|
||||
static final String NOFATORPHANS_PROP = "nofatorphans"; //NON-NLS
|
||||
|
||||
static final Logger logger = Logger.getLogger(AddImageAction.class.getName());
|
||||
static final Dimension SIZE = new Dimension(875, 550);
|
||||
|
||||
private WizardDescriptor wizardDescriptor;
|
||||
private WizardDescriptor.Iterator<WizardDescriptor> iterator;
|
||||
@@ -119,11 +122,14 @@ public final class AddImageAction extends CallableSystemAction implements Presen
|
||||
wizardDescriptor = new WizardDescriptor(iterator);
|
||||
wizardDescriptor.setTitle(NbBundle.getMessage(this.getClass(), "AddImageAction.wizard.title"));
|
||||
wizardDescriptor.putProperty(NAME, e);
|
||||
wizardDescriptor.setTitleFormat(new MessageFormat("{0}"));
|
||||
|
||||
if (dialog != null) {
|
||||
dialog.setVisible(false); // hide the old one
|
||||
}
|
||||
dialog = DialogDisplayer.getDefault().createDialog(wizardDescriptor);
|
||||
Dimension d = dialog.getSize();
|
||||
dialog.setSize(SIZE);
|
||||
dialog.setVisible(true);
|
||||
dialog.toFront();
|
||||
|
||||
|
||||
@@ -34,13 +34,7 @@
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Group type="102" attributes="0">
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Component id="inputPanel" alignment="0" max="32767" attributes="0"/>
|
||||
<Group type="102" attributes="0">
|
||||
<Component id="nextLabel" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace min="0" pref="54" max="32767" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
<Component id="inputPanel" max="32767" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
@@ -48,35 +42,15 @@
|
||||
<DimensionLayout dim="1">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Group type="102" alignment="0" attributes="0">
|
||||
<EmptySpace min="-2" pref="39" max="-2" attributes="0"/>
|
||||
<EmptySpace min="-2" pref="6" max="-2" attributes="0"/>
|
||||
<Component id="inputPanel" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace pref="24" max="32767" attributes="0"/>
|
||||
<Component id="nextLabel" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace min="0" pref="0" max="-2" attributes="0"/>
|
||||
<EmptySpace pref="44" max="32767" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
</Layout>
|
||||
<SubComponents>
|
||||
<Component class="javax.swing.JLabel" name="nextLabel">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/casemodule/Bundle.properties" key="AddImageWizardChooseDataSourceVisual.nextLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||
<Dimension value="[514, 35]"/>
|
||||
</Property>
|
||||
<Property name="verticalTextPosition" type="int" value="3"/>
|
||||
</Properties>
|
||||
</Component>
|
||||
<Container class="javax.swing.JPanel" name="inputPanel">
|
||||
<Properties>
|
||||
<Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor">
|
||||
<Border info="org.netbeans.modules.form.compat2.border.EtchedBorderInfo">
|
||||
<EtchetBorder/>
|
||||
</Border>
|
||||
</Property>
|
||||
</Properties>
|
||||
|
||||
<Layout>
|
||||
<DimensionLayout dim="0">
|
||||
@@ -88,9 +62,9 @@
|
||||
<Component id="typeTabel" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace type="unrelated" max="-2" attributes="0"/>
|
||||
<Component id="typeComboBox" min="-2" pref="292" max="-2" attributes="0"/>
|
||||
<EmptySpace min="0" pref="115" max="32767" attributes="0"/>
|
||||
<EmptySpace min="0" pref="119" max="32767" attributes="0"/>
|
||||
</Group>
|
||||
<Component id="typePanel" alignment="1" pref="544" max="32767" attributes="0"/>
|
||||
<Component id="typePanel" alignment="1" pref="548" max="32767" attributes="0"/>
|
||||
</Group>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
</Group>
|
||||
@@ -105,8 +79,8 @@
|
||||
<Component id="typeComboBox" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<EmptySpace type="unrelated" max="-2" attributes="0"/>
|
||||
<Component id="typePanel" pref="173" max="32767" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="typePanel" min="-2" pref="225" max="-2" attributes="0"/>
|
||||
<EmptySpace max="32767" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
@@ -132,12 +106,12 @@
|
||||
<Layout>
|
||||
<DimensionLayout dim="0">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<EmptySpace min="0" pref="544" max="32767" attributes="0"/>
|
||||
<EmptySpace min="0" pref="548" max="32767" attributes="0"/>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
<DimensionLayout dim="1">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<EmptySpace min="0" pref="173" max="32767" attributes="0"/>
|
||||
<EmptySpace min="0" pref="225" max="32767" attributes="0"/>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
</Layout>
|
||||
|
||||
@@ -205,7 +205,6 @@ final class AddImageWizardChooseDataSourceVisual extends JPanel {
|
||||
|
||||
buttonGroup1 = new javax.swing.ButtonGroup();
|
||||
jLabel2 = new javax.swing.JLabel();
|
||||
nextLabel = new javax.swing.JLabel();
|
||||
inputPanel = new javax.swing.JPanel();
|
||||
typeTabel = new javax.swing.JLabel();
|
||||
typePanel = new javax.swing.JPanel();
|
||||
@@ -215,12 +214,6 @@ final class AddImageWizardChooseDataSourceVisual extends JPanel {
|
||||
|
||||
setPreferredSize(new java.awt.Dimension(588, 328));
|
||||
|
||||
org.openide.awt.Mnemonics.setLocalizedText(nextLabel, org.openide.util.NbBundle.getMessage(AddImageWizardChooseDataSourceVisual.class, "AddImageWizardChooseDataSourceVisual.nextLabel.text")); // NOI18N
|
||||
nextLabel.setPreferredSize(new java.awt.Dimension(514, 35));
|
||||
nextLabel.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
|
||||
|
||||
inputPanel.setBorder(javax.swing.BorderFactory.createEtchedBorder());
|
||||
|
||||
org.openide.awt.Mnemonics.setLocalizedText(typeTabel, org.openide.util.NbBundle.getMessage(AddImageWizardChooseDataSourceVisual.class, "AddImageWizardChooseDataSourceVisual.typeTabel.text")); // NOI18N
|
||||
|
||||
typePanel.setMinimumSize(new java.awt.Dimension(0, 65));
|
||||
@@ -230,11 +223,11 @@ final class AddImageWizardChooseDataSourceVisual extends JPanel {
|
||||
typePanel.setLayout(typePanelLayout);
|
||||
typePanelLayout.setHorizontalGroup(
|
||||
typePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGap(0, 544, Short.MAX_VALUE)
|
||||
.addGap(0, 548, Short.MAX_VALUE)
|
||||
);
|
||||
typePanelLayout.setVerticalGroup(
|
||||
typePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGap(0, 173, Short.MAX_VALUE)
|
||||
.addGap(0, 225, Short.MAX_VALUE)
|
||||
);
|
||||
|
||||
javax.swing.GroupLayout inputPanelLayout = new javax.swing.GroupLayout(inputPanel);
|
||||
@@ -248,8 +241,8 @@ final class AddImageWizardChooseDataSourceVisual extends JPanel {
|
||||
.addComponent(typeTabel)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
|
||||
.addComponent(typeComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, 292, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||
.addGap(0, 115, Short.MAX_VALUE))
|
||||
.addComponent(typePanel, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, 544, Short.MAX_VALUE))
|
||||
.addGap(0, 119, Short.MAX_VALUE))
|
||||
.addComponent(typePanel, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, 548, Short.MAX_VALUE))
|
||||
.addContainerGap())
|
||||
);
|
||||
inputPanelLayout.setVerticalGroup(
|
||||
@@ -260,8 +253,8 @@ final class AddImageWizardChooseDataSourceVisual extends JPanel {
|
||||
.addComponent(typeTabel)
|
||||
.addComponent(typeComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
|
||||
.addComponent(typePanel, javax.swing.GroupLayout.DEFAULT_SIZE, 173, Short.MAX_VALUE)
|
||||
.addContainerGap())
|
||||
.addComponent(typePanel, javax.swing.GroupLayout.PREFERRED_SIZE, 225, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||
.addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
|
||||
);
|
||||
|
||||
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
|
||||
@@ -270,28 +263,21 @@ final class AddImageWizardChooseDataSourceVisual extends JPanel {
|
||||
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGroup(layout.createSequentialGroup()
|
||||
.addContainerGap()
|
||||
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addComponent(inputPanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
||||
.addGroup(layout.createSequentialGroup()
|
||||
.addComponent(nextLabel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||
.addGap(0, 54, Short.MAX_VALUE)))
|
||||
.addComponent(inputPanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
||||
.addContainerGap())
|
||||
);
|
||||
layout.setVerticalGroup(
|
||||
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGroup(layout.createSequentialGroup()
|
||||
.addGap(39, 39, 39)
|
||||
.addGap(6, 6, 6)
|
||||
.addComponent(inputPanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 24, Short.MAX_VALUE)
|
||||
.addComponent(nextLabel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||
.addGap(0, 0, 0))
|
||||
.addContainerGap(44, Short.MAX_VALUE))
|
||||
);
|
||||
}// </editor-fold>//GEN-END:initComponents
|
||||
// Variables declaration - do not modify//GEN-BEGIN:variables
|
||||
private javax.swing.ButtonGroup buttonGroup1;
|
||||
private javax.swing.JPanel inputPanel;
|
||||
private javax.swing.JLabel jLabel2;
|
||||
private javax.swing.JLabel nextLabel;
|
||||
private javax.swing.JComboBox<String> typeComboBox;
|
||||
private javax.swing.JPanel typePanel;
|
||||
private javax.swing.JLabel typeTabel;
|
||||
|
||||
@@ -21,34 +21,19 @@
|
||||
<Layout>
|
||||
<DimensionLayout dim="0">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Group type="102" attributes="0">
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="subtitleLabel" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace pref="218" max="32767" attributes="0"/>
|
||||
<Group type="102" alignment="0" attributes="0">
|
||||
<Component id="configPanel" min="-2" pref="609" max="-2" attributes="0"/>
|
||||
<EmptySpace min="0" pref="0" max="32767" attributes="0"/>
|
||||
</Group>
|
||||
<Component id="configPanel" alignment="0" max="32767" attributes="0"/>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
<DimensionLayout dim="1">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Group type="102" alignment="0" attributes="0">
|
||||
<EmptySpace min="-2" pref="6" max="-2" attributes="0"/>
|
||||
<Component id="subtitleLabel" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace type="unrelated" max="-2" attributes="0"/>
|
||||
<Component id="configPanel" pref="258" max="32767" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<Component id="configPanel" alignment="0" pref="300" max="32767" attributes="0"/>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
</Layout>
|
||||
<SubComponents>
|
||||
<Component class="javax.swing.JLabel" name="subtitleLabel">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/casemodule/Bundle.properties" key="AddImageWizardIngestConfigVisual.subtitleLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
</Component>
|
||||
<Container class="javax.swing.JPanel" name="configPanel">
|
||||
<Properties>
|
||||
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||
@@ -59,12 +44,12 @@
|
||||
<Layout>
|
||||
<DimensionLayout dim="0">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<EmptySpace min="0" pref="569" max="32767" attributes="0"/>
|
||||
<EmptySpace min="0" pref="609" max="32767" attributes="0"/>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
<DimensionLayout dim="1">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<EmptySpace min="0" pref="258" max="32767" attributes="0"/>
|
||||
<EmptySpace min="0" pref="349" max="32767" attributes="0"/>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
</Layout>
|
||||
|
||||
@@ -42,7 +42,6 @@ class AddImageWizardIngestConfigVisual extends JPanel {
|
||||
}
|
||||
|
||||
private void customizeComponents() {
|
||||
configPanel.setBorder(javax.swing.BorderFactory.createLineBorder(new java.awt.Color(0, 0, 0)));
|
||||
configPanel.setLayout(new BorderLayout());
|
||||
configPanel.add(ingestPanel, BorderLayout.CENTER);
|
||||
}
|
||||
@@ -66,24 +65,21 @@ class AddImageWizardIngestConfigVisual extends JPanel {
|
||||
// <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
|
||||
private void initComponents() {
|
||||
|
||||
subtitleLabel = new javax.swing.JLabel();
|
||||
configPanel = new javax.swing.JPanel();
|
||||
|
||||
setPreferredSize(new java.awt.Dimension(569, 300));
|
||||
|
||||
subtitleLabel.setText(org.openide.util.NbBundle.getMessage(AddImageWizardIngestConfigVisual.class, "AddImageWizardIngestConfigVisual.subtitleLabel.text")); // NOI18N
|
||||
|
||||
configPanel.setPreferredSize(new java.awt.Dimension(569, 400));
|
||||
|
||||
javax.swing.GroupLayout configPanelLayout = new javax.swing.GroupLayout(configPanel);
|
||||
configPanel.setLayout(configPanelLayout);
|
||||
configPanelLayout.setHorizontalGroup(
|
||||
configPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGap(0, 569, Short.MAX_VALUE)
|
||||
.addGap(0, 609, Short.MAX_VALUE)
|
||||
);
|
||||
configPanelLayout.setVerticalGroup(
|
||||
configPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGap(0, 258, Short.MAX_VALUE)
|
||||
.addGap(0, 349, Short.MAX_VALUE)
|
||||
);
|
||||
|
||||
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
|
||||
@@ -91,23 +87,15 @@ class AddImageWizardIngestConfigVisual extends JPanel {
|
||||
layout.setHorizontalGroup(
|
||||
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGroup(layout.createSequentialGroup()
|
||||
.addContainerGap()
|
||||
.addComponent(subtitleLabel)
|
||||
.addContainerGap(218, Short.MAX_VALUE))
|
||||
.addComponent(configPanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
||||
.addComponent(configPanel, javax.swing.GroupLayout.PREFERRED_SIZE, 609, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||
.addGap(0, 0, Short.MAX_VALUE))
|
||||
);
|
||||
layout.setVerticalGroup(
|
||||
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGroup(layout.createSequentialGroup()
|
||||
.addGap(6, 6, 6)
|
||||
.addComponent(subtitleLabel)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
|
||||
.addComponent(configPanel, javax.swing.GroupLayout.DEFAULT_SIZE, 258, Short.MAX_VALUE)
|
||||
.addContainerGap())
|
||||
.addComponent(configPanel, javax.swing.GroupLayout.DEFAULT_SIZE, 300, Short.MAX_VALUE)
|
||||
);
|
||||
}// </editor-fold>//GEN-END:initComponents
|
||||
// Variables declaration - do not modify//GEN-BEGIN:variables
|
||||
private javax.swing.JPanel configPanel;
|
||||
private javax.swing.JLabel subtitleLabel;
|
||||
// End of variables declaration//GEN-END:variables
|
||||
}
|
||||
|
||||
@@ -69,11 +69,9 @@ LocalFilesPanel.selectedPaths.toolTipText=
|
||||
LocalFilesPanel.localFileChooser.approveButtonText=Select
|
||||
LocalFilesPanel.localFileChooser.approveButtonToolTipText=
|
||||
LocalFilesPanel.selectButton.actionCommand=Add
|
||||
AddImageWizardIngestConfigVisual.subtitleLabel.text=Configure the ingest modules you would like to run on this data source.
|
||||
AddImageWizardAddingProgressVisual.statusLabel.text=Data source has been added to the local database. Files are being analyzed.
|
||||
AddImageWizardChooseDataSourceVisual.typeTabel.text=Select source type to add:
|
||||
AddImageWizardChooseDataSourceVisual.typeTabel.text=Select data source type:
|
||||
AddImageWizardChooseDataSourceVisual.jLabel2.text=jLabel2
|
||||
AddImageWizardChooseDataSourceVisual.nextLabel.text=<html> Press 'Next' to analyze the input data, extract volume and file system data, and populate a local database.</html>
|
||||
AddImageWizardAddingProgressVisual.progressLabel.text=<progress>
|
||||
AddImageWizardAddingProgressVisual.viewLogButton.text=View Log
|
||||
AddImageWizardAddingProgressVisual.subTitle1Label.text=Processing data source and adding it to a local database. File analysis will start when this finishes.
|
||||
@@ -100,7 +98,7 @@ AddImageWizardAddingProgressVisual.getName.text=Add Data Source
|
||||
AddImageWizardAddingProgressVisual.showErrors.critText=*Failed to add data source (critical errors encountered). Click below to view the log.
|
||||
AddImageWizardAddingProgressVisual.showErrors.nonCritText=*Data Source added (non-critical errors encountered). Click below to view the log.
|
||||
AddImageWizardChooseDataSourcePanel.moveFocusNext=Next >
|
||||
AddImageWizardChooseDataSourceVisual.getName.text=Enter Data Source Information
|
||||
AddImageWizardChooseDataSourceVisual.getName.text=Select Data Source
|
||||
AddImageWizardIngestConfigPanel.dsProcDone.noErrs.text=*Data Source added.
|
||||
AddImageWizardIngestConfigPanel.dsProcDone.errs.text=*Errors encountered in adding Data Source.
|
||||
AddImageWizardIngestConfigVisual.getName.text=Configure Ingest Modules
|
||||
@@ -219,14 +217,6 @@ RecentItems.openRecentCase.msgDlg.text=Case {0} no longer exists.
|
||||
StartupWindow.title.text=Welcome
|
||||
UpdateRecentCases.menuItem.clearRecentCases.text=Clear Recent Cases
|
||||
UpdateRecentCases.menuItem.empty=-Empty-
|
||||
XMLCaseManagement.create.exception.msg=Error setting up Case XML file,
|
||||
XMLCaseManagement.writeFile.exception.noCase.msg=No set case to write management file for.
|
||||
XMLCaseManagement.writeFile.exception.errWriteToFile.msg=Error writing to case file
|
||||
XMLCaseManagement.open.exception.errReadXMLFile.msg=Error reading case XML file\: {0}
|
||||
XMLCaseManagement.open.msgDlg.notAutCase.msg=Error\: This is not an Autopsy config file ("{0}").\n\n\
|
||||
Detail\: \n\
|
||||
Cannot open a non-Autopsy config file (at {1}).
|
||||
XMLCaseManagement.open.msgDlg.notAutCase.title=Error
|
||||
AddImageWizardIngestConfigPanel.CANCEL_BUTTON.text=Cancel
|
||||
ImageFilePanel.errorLabel.text=Error Label
|
||||
DataSourceOnCDriveError.text=Warning\: Path to multi-user data source is on "C\:" drive
|
||||
|
||||
@@ -53,11 +53,9 @@ LocalFilesPanel.clearButton.text=\u30af\u30ea\u30a2
|
||||
LocalFilesPanel.clearButton.toolTipText=\u73fe\u5728\u9078\u629e\u3055\u308c\u3066\u3044\u308b\u30ed\u30fc\u30ab\u30eb\u30d5\u30a1\u30a4\u30eb\u30d1\u30b9\u304c\u30af\u30ea\u30a2\u3055\u308c\u307e\u3059
|
||||
LocalFilesPanel.localFileChooser.approveButtonText=\u9078\u629e
|
||||
LocalFilesPanel.selectButton.actionCommand=\u8ffd\u52a0
|
||||
AddImageWizardIngestConfigVisual.subtitleLabel.text=\u3053\u306e\u30c7\u30fc\u30bf\u30bd\u30fc\u30b9\u306b\u5bfe\u3057\u3066\u5b9f\u884c\u3057\u305f\u3044\u30a4\u30f3\u30b8\u30a7\u30b9\u30c8\u30e2\u30b8\u30e5\u30fc\u30eb\u3092\u8a2d\u5b9a\u3057\u307e\u3059\u3002
|
||||
AddImageWizardAddingProgressVisual.statusLabel.text=\u30ed\u30fc\u30ab\u30eb\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u306b\u30d5\u30a1\u30a4\u30eb\u30b7\u30b9\u30c6\u30e0\u304c\u8ffd\u52a0\u3055\u308c\u307e\u3057\u305f\u3002\u30d5\u30a1\u30a4\u30eb\u3092\u89e3\u6790\u4e2d\u3067\u3059\u3002
|
||||
AddImageWizardChooseDataSourceVisual.typeTabel.text=\u8ffd\u52a0\u3059\u308b\u30bd\u30fc\u30b9\u30bf\u30a4\u30d7\u3092\u9078\u629e\uff1a
|
||||
AddImageWizardChooseDataSourceVisual.jLabel2.text=jLabel2
|
||||
AddImageWizardChooseDataSourceVisual.nextLabel.text=<html> \u300c\u6b21\u3078\u300d\u3092\u30af\u30ea\u30c3\u30af\u3057\u3066\u3001\u30a4\u30f3\u30d7\u30c3\u30c8\u30c7\u30fc\u30bf\u3092\u89e3\u6790\u3001\u30dc\u30ea\u30e5\u30fc\u30e0\u304a\u3088\u3073\u30d5\u30a1\u30a4\u30eb\u30b7\u30b9\u30c6\u30e0\u30c7\u30fc\u30bf\u3092\u62bd\u51fa\u3001\u30ed\u30fc\u30ab\u30eb\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u306b\u30c7\u30fc\u30bf\u3092\u6295\u5165\u3002</html>
|
||||
AddImageWizardAddingProgressVisual.progressLabel.text=\uff1c\u30d7\u30ed\u30b0\u30ec\u30b9\uff1e
|
||||
AddImageWizardAddingProgressVisual.viewLogButton.text=\u30ed\u30b0\u3092\u8868\u793a
|
||||
AddImageWizardAddingProgressVisual.subTitle1Label.text=\u30ed\u30fc\u30ab\u30eb\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u306b\u30d5\u30a1\u30a4\u30eb\u30b7\u30b9\u30c6\u30e0\u60c5\u5831\u3092\u8ffd\u52a0\u4e2d\u3067\u3059\u3002\u3053\u3061\u3089\u304c\u5b8c\u4e86\u6b21\u7b2c\u3001\u30d5\u30a1\u30a4\u30eb\u89e3\u6790\u304c\u59cb\u307e\u308a\u307e\u3059\u3002
|
||||
@@ -178,14 +176,6 @@ RecentItems.openRecentCase.msgDlg.text=\u30a8\u30e9\u30fc\uff1a\u30b1\u30fc\u30b
|
||||
StartupWindow.title.text=\u3088\u3046\u3053\u305d
|
||||
UpdateRecentCases.menuItem.clearRecentCases.text=\u6700\u8fd1\u958b\u3044\u305f\u30b1\u30fc\u30b9\u3092\u30af\u30ea\u30a2
|
||||
UpdateRecentCases.menuItem.empty=-\u7a7a\u767d-
|
||||
XMLCaseManagement.create.exception.msg=\u30b1\u30fc\u30b9XML\u30d5\u30a1\u30a4\u30eb\u306e\u8a2d\u5b9a\u4e2d\u306b\u30a8\u30e9\u30fc\u304c\u767a\u751f\u3057\u307e\u3057\u305f\u3001
|
||||
XMLCaseManagement.writeFile.exception.noCase.msg=\u30de\u30cd\u30b8\u30e1\u30f3\u30c8\u30d5\u30a1\u30a4\u30eb\u3092\u66f8\u304f\u5fc5\u8981\u304c\u3042\u308b\u30b1\u30fc\u30b9\u304c\u3042\u308a\u307e\u305b\u3093\u3002
|
||||
XMLCaseManagement.writeFile.exception.errWriteToFile.msg=\u30b1\u30fc\u30b9\u30d5\u30a1\u30a4\u30eb\u3078\u306e\u66f8\u304d\u8fbc\u307f\u4e2d\u306b\u30a8\u30e9\u30fc\u304c\u767a\u751f\u3057\u307e\u3057\u305f
|
||||
XMLCaseManagement.open.exception.errReadXMLFile.msg=\u30b1\u30fc\u30b9XML\u30d5\u30a1\u30a4\u30eb\u306e\u8aad\u307f\u53d6\u308a\u4e2d\u306b\u30a8\u30e9\u30fc\u304c\u767a\u751f\u3057\u307e\u3057\u305f\uff1a{0}
|
||||
XMLCaseManagement.open.msgDlg.notAutCase.msg=\u30a8\u30e9\u30fc\uff1aAutopsy\u8a2d\u5b9a\u30d5\u30a1\u30a4\u30eb("{0}")\u3067\u306f\u3042\u308a\u307e\u305b\u3093\u3002\n\n\
|
||||
\u8a73\u7d30\uff1a\n\
|
||||
Autopsy\u8a2d\u5b9a\u30d5\u30a1\u30a4\u30eb\u4ee5\u5916\u306f(at {1})\u3067\u958b\u3051\u307e\u305b\u3093\u3002
|
||||
XMLCaseManagement.open.msgDlg.notAutCase.title=\u30a8\u30e9\u30fc
|
||||
ImageFilePanel.noFatOrphansCheckbox.text=FAT\u30d5\u30a1\u30a4\u30eb\u30b7\u30b9\u30c6\u30e0\u306e\u30aa\u30fc\u30d5\u30a1\u30f3\u30d5\u30a1\u30a4\u30eb\u306f\u7121\u8996
|
||||
LocalDiskPanel.noFatOrphansCheckbox.text=FAT\u30d5\u30a1\u30a4\u30eb\u30b7\u30b9\u30c6\u30e0\u306e\u30aa\u30fc\u30d5\u30a1\u30f3\u30d5\u30a1\u30a4\u30eb\u306f\u7121\u8996
|
||||
AddImageWizardIngestConfigPanel.CANCEL_BUTTON.text=\u30ad\u30e3\u30f3\u30bb\u30eb
|
||||
|
||||
@@ -48,6 +48,7 @@ import javax.swing.JOptionPane;
|
||||
import javax.swing.SwingUtilities;
|
||||
import org.apache.commons.io.FileUtils;
|
||||
import org.openide.util.NbBundle;
|
||||
import org.openide.util.NbBundle.Messages;
|
||||
import org.openide.util.actions.CallableSystemAction;
|
||||
import org.openide.windows.WindowManager;
|
||||
import org.sleuthkit.autopsy.casemodule.CaseMetadata.CaseMetadataException;
|
||||
@@ -260,19 +261,12 @@ public class Case implements SleuthkitCase.ErrorObserver {
|
||||
}
|
||||
};
|
||||
|
||||
private String name;
|
||||
private String number;
|
||||
private String examiner;
|
||||
private String configFilePath;
|
||||
private final XMLCaseManagement xmlcm;
|
||||
private final CaseMetadata caseMetadata;
|
||||
private final SleuthkitCase db;
|
||||
// Track the current case (only set with changeCase() method)
|
||||
private static Case currentCase = null;
|
||||
private final CaseType caseType;
|
||||
private final Services services;
|
||||
private static final Logger logger = Logger.getLogger(Case.class.getName());
|
||||
static final String CASE_EXTENSION = "aut"; //NON-NLS
|
||||
static final String CASE_DOT_EXTENSION = "." + CASE_EXTENSION;
|
||||
private final static String CACHE_FOLDER = "Cache"; //NON-NLS
|
||||
private final static String EXPORT_FOLDER = "Export"; //NON-NLS
|
||||
private final static String LOG_FOLDER = "Log"; //NON-NLS
|
||||
@@ -288,13 +282,8 @@ public class Case implements SleuthkitCase.ErrorObserver {
|
||||
/**
|
||||
* Constructor for the Case class
|
||||
*/
|
||||
private Case(String name, String number, String examiner, String configFilePath, XMLCaseManagement xmlcm, SleuthkitCase db, CaseType type) {
|
||||
this.name = name;
|
||||
this.number = number;
|
||||
this.examiner = examiner;
|
||||
this.configFilePath = configFilePath;
|
||||
this.xmlcm = xmlcm;
|
||||
this.caseType = type;
|
||||
private Case(CaseMetadata caseMetadata, SleuthkitCase db) {
|
||||
this.caseMetadata = caseMetadata;
|
||||
this.db = db;
|
||||
this.services = new Services(db);
|
||||
}
|
||||
@@ -365,7 +354,7 @@ public class Case implements SleuthkitCase.ErrorObserver {
|
||||
NbBundle.getMessage(Case.class, "IntervalErrorReport.ErrorText"));
|
||||
doCaseChange(currentCase);
|
||||
SwingUtilities.invokeLater(() -> {
|
||||
RecentCases.getInstance().addRecentCase(currentCase.name, currentCase.configFilePath); // update the recent cases
|
||||
RecentCases.getInstance().addRecentCase(currentCase.getName(), currentCase.getCaseMetadata().getFilePath().toString()); // update the recent cases
|
||||
});
|
||||
if (CaseType.MULTI_USER_CASE == newCase.getCaseType()) {
|
||||
try {
|
||||
@@ -448,8 +437,9 @@ public class Case implements SleuthkitCase.ErrorObserver {
|
||||
* CaseActionException.getCause will return a Throwable
|
||||
* (null otherwise).
|
||||
*
|
||||
* @throws CaseActionException if there is a problem creating the case.
|
||||
* @throws CaseActionException if there is a problem creating the case.
|
||||
*/
|
||||
@Messages({"Case.creationException=Could not create case: failed to make metadata file."})
|
||||
public static void create(String caseDir, String caseName, String caseNumber, String examiner, CaseType caseType) throws CaseActionException {
|
||||
logger.log(Level.INFO, "Creating case with case directory {0}, caseName {1}", new Object[]{caseDir, caseName}); //NON-NLS
|
||||
|
||||
@@ -478,14 +468,13 @@ public class Case implements SleuthkitCase.ErrorObserver {
|
||||
|
||||
/*
|
||||
* Create the case metadata (.aut) file.
|
||||
*
|
||||
* TODO (AUT-1885): Replace use of obsolete and unsafe XMLCaseManagement
|
||||
* class with use of CaseMetadata class.
|
||||
*/
|
||||
String configFilePath = caseDir + File.separator + caseName + CASE_DOT_EXTENSION;
|
||||
XMLCaseManagement xmlcm = new XMLCaseManagement();
|
||||
xmlcm.create(caseDir, caseName, examiner, caseNumber, caseType, dbName, indexName);
|
||||
xmlcm.writeFile();
|
||||
CaseMetadata metadata;
|
||||
try {
|
||||
metadata = new CaseMetadata(caseDir, caseType, caseName, caseNumber, examiner, dbName, indexName);
|
||||
} catch (CaseMetadataException ex) {
|
||||
throw new CaseActionException(Bundle.Case_creationException(), ex);
|
||||
}
|
||||
|
||||
/*
|
||||
* Create the case database.
|
||||
@@ -515,7 +504,7 @@ public class Case implements SleuthkitCase.ErrorObserver {
|
||||
throw new CaseActionException(NbBundle.getMessage(Case.class, "Case.databaseConnectionInfo.error.msg"), ex);
|
||||
}
|
||||
|
||||
Case newCase = new Case(caseName, caseNumber, examiner, configFilePath, xmlcm, db, caseType);
|
||||
Case newCase = new Case(metadata, db);
|
||||
changeCase(newCase);
|
||||
}
|
||||
|
||||
@@ -598,8 +587,8 @@ public class Case implements SleuthkitCase.ErrorObserver {
|
||||
/*
|
||||
* Verify the extension of the case metadata file.
|
||||
*/
|
||||
if (!caseMetadataFilePath.endsWith(CASE_DOT_EXTENSION)) {
|
||||
throw new CaseActionException(NbBundle.getMessage(Case.class, "Case.open.exception.checkFile.msg", CASE_DOT_EXTENSION));
|
||||
if (!caseMetadataFilePath.endsWith(CaseMetadata.getFileExtension())) {
|
||||
throw new CaseActionException(NbBundle.getMessage(Case.class, "Case.open.exception.checkFile.msg", CaseMetadata.getFileExtension()));
|
||||
}
|
||||
|
||||
try {
|
||||
@@ -607,25 +596,23 @@ public class Case implements SleuthkitCase.ErrorObserver {
|
||||
* Get the case metadata required to open the case database.
|
||||
*/
|
||||
CaseMetadata metadata = new CaseMetadata(Paths.get(caseMetadataFilePath));
|
||||
String caseName = metadata.getCaseName();
|
||||
String caseNumber = metadata.getCaseNumber();
|
||||
String examiner = metadata.getExaminer();
|
||||
CaseType caseType = metadata.getCaseType();
|
||||
String caseDir = metadata.getCaseDirectory();
|
||||
|
||||
/*
|
||||
* Open the case database.
|
||||
*/
|
||||
SleuthkitCase db;
|
||||
String caseDir;
|
||||
if (caseType == CaseType.SINGLE_USER_CASE) {
|
||||
String dbPath = Paths.get(caseDir, "autopsy.db").toString(); //NON-NLS
|
||||
String dbPath = metadata.getCaseDatabasePath(); //NON-NLS
|
||||
db = SleuthkitCase.openCase(dbPath);
|
||||
caseDir = new File(dbPath).getParent();
|
||||
} else {
|
||||
if (!UserPreferences.getIsMultiUserModeEnabled()) {
|
||||
throw new CaseActionException(NbBundle.getMessage(Case.class, "Case.open.exception.multiUserCaseNotEnabled"));
|
||||
}
|
||||
try {
|
||||
db = SleuthkitCase.openCase(metadata.getCaseDatabaseName(), UserPreferences.getDatabaseConnectionInfo(), caseDir);
|
||||
db = SleuthkitCase.openCase(metadata.getCaseDatabaseName(), UserPreferences.getDatabaseConnectionInfo(), metadata.getCaseDirectory());
|
||||
} catch (UserPreferencesException ex) {
|
||||
throw new CaseActionException(NbBundle.getMessage(Case.class, "Case.databaseConnectionInfo.error.msg"), ex);
|
||||
}
|
||||
@@ -674,14 +661,7 @@ public class Case implements SleuthkitCase.ErrorObserver {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* TODO (AUT-1885): Replace use of obsolete and unsafe
|
||||
* XMLCaseManagement class with use of CaseMetadata class.
|
||||
*/
|
||||
XMLCaseManagement xmlcm = new XMLCaseManagement();
|
||||
xmlcm.open(caseMetadataFilePath);
|
||||
Case openedCase = new Case(caseName, caseNumber, examiner, caseMetadataFilePath, xmlcm, db, caseType);
|
||||
Case openedCase = new Case(metadata, db);
|
||||
changeCase(openedCase);
|
||||
|
||||
} catch (CaseMetadataException ex) {
|
||||
@@ -859,7 +839,6 @@ public class Case implements SleuthkitCase.ErrorObserver {
|
||||
changeCase(null);
|
||||
try {
|
||||
services.close();
|
||||
this.xmlcm.close(); // close the xmlcm
|
||||
this.db.close();
|
||||
} catch (Exception e) {
|
||||
throw new CaseActionException(NbBundle.getMessage(this.getClass(), "Case.closeCase.exception.msg"), e);
|
||||
@@ -877,11 +856,9 @@ public class Case implements SleuthkitCase.ErrorObserver {
|
||||
logger.log(Level.INFO, "Deleting case.\ncaseDir: {0}", caseDir); //NON-NLS
|
||||
|
||||
try {
|
||||
|
||||
xmlcm.close(); // close the xmlcm
|
||||
boolean result = deleteCaseDirectory(caseDir); // delete the directory
|
||||
|
||||
RecentCases.getInstance().removeRecentCase(this.name, this.configFilePath); // remove it from the recent case
|
||||
RecentCases.getInstance().removeRecentCase(this.caseMetadata.getCaseName(), this.caseMetadata.getFilePath().toString()); // remove it from the recent case
|
||||
Case.changeCase(null);
|
||||
if (result == false) {
|
||||
throw new CaseActionException(
|
||||
@@ -906,8 +883,8 @@ public class Case implements SleuthkitCase.ErrorObserver {
|
||||
*/
|
||||
void updateCaseName(String oldCaseName, String oldPath, String newCaseName, String newPath) throws CaseActionException {
|
||||
try {
|
||||
xmlcm.setCaseName(newCaseName); // set the case
|
||||
name = newCaseName; // change the local value
|
||||
getCaseMetadata().setCaseName(newCaseName); // set the case
|
||||
caseMetadata.setCaseName(newCaseName); // change the local value
|
||||
eventPublisher.publish(new AutopsyEvent(Events.NAME.toString(), oldCaseName, newCaseName));
|
||||
SwingUtilities.invokeLater(() -> {
|
||||
try {
|
||||
@@ -922,42 +899,6 @@ public class Case implements SleuthkitCase.ErrorObserver {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the case examiner
|
||||
*
|
||||
* This should not be called from the EDT.
|
||||
*
|
||||
* @param oldExaminer the old examiner
|
||||
* @param newExaminer the new examiner
|
||||
*/
|
||||
void updateExaminer(String oldExaminer, String newExaminer) throws CaseActionException {
|
||||
try {
|
||||
xmlcm.setCaseExaminer(newExaminer); // set the examiner
|
||||
examiner = newExaminer;
|
||||
eventPublisher.publish(new AutopsyEvent(Events.EXAMINER.toString(), oldExaminer, newExaminer));
|
||||
} catch (Exception e) {
|
||||
throw new CaseActionException(NbBundle.getMessage(this.getClass(), "Case.updateExaminer.exception.msg"), e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the case number
|
||||
*
|
||||
* This should not be called from the EDT.
|
||||
*
|
||||
* @param oldCaseNumber the old case number
|
||||
* @param newCaseNumber the new case number
|
||||
*/
|
||||
void updateCaseNumber(String oldCaseNumber, String newCaseNumber) throws CaseActionException {
|
||||
try {
|
||||
xmlcm.setCaseNumber(newCaseNumber); // set the case number
|
||||
number = newCaseNumber;
|
||||
eventPublisher.publish(new AutopsyEvent(Events.NUMBER.toString(), oldCaseNumber, newCaseNumber));
|
||||
} catch (Exception e) {
|
||||
throw new CaseActionException(NbBundle.getMessage(this.getClass(), "Case.updateCaseNum.exception.msg"), e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether there is a current case open.
|
||||
*
|
||||
@@ -967,24 +908,6 @@ public class Case implements SleuthkitCase.ErrorObserver {
|
||||
return currentCase != null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Uses the given path to store it as the configuration file path
|
||||
*
|
||||
* @param givenPath the given config file path
|
||||
*/
|
||||
private void setConfigFilePath(String givenPath) {
|
||||
configFilePath = givenPath;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the config file path in the given path
|
||||
*
|
||||
* @return configFilePath the path of the configuration file
|
||||
*/
|
||||
String getConfigFilePath() {
|
||||
return configFilePath;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the current version of Autopsy
|
||||
*
|
||||
@@ -994,6 +917,13 @@ public class Case implements SleuthkitCase.ErrorObserver {
|
||||
return autopsyVer;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the caseMetadata
|
||||
*/
|
||||
CaseMetadata getCaseMetadata() {
|
||||
return caseMetadata;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the application name
|
||||
*
|
||||
@@ -1012,7 +942,7 @@ public class Case implements SleuthkitCase.ErrorObserver {
|
||||
* @return name
|
||||
*/
|
||||
public String getName() {
|
||||
return name;
|
||||
return caseMetadata.getCaseName();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1021,7 +951,7 @@ public class Case implements SleuthkitCase.ErrorObserver {
|
||||
* @return number
|
||||
*/
|
||||
public String getNumber() {
|
||||
return number;
|
||||
return caseMetadata.getCaseNumber();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1030,7 +960,7 @@ public class Case implements SleuthkitCase.ErrorObserver {
|
||||
* @return examiner
|
||||
*/
|
||||
public String getExaminer() {
|
||||
return examiner;
|
||||
return caseMetadata.getExaminer();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1039,11 +969,7 @@ public class Case implements SleuthkitCase.ErrorObserver {
|
||||
* @return caseDirectoryPath
|
||||
*/
|
||||
public String getCaseDirectory() {
|
||||
if (xmlcm == null) {
|
||||
return "";
|
||||
} else {
|
||||
return xmlcm.getCaseDirectory();
|
||||
}
|
||||
return caseMetadata.getCaseDirectory();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1052,7 +978,7 @@ public class Case implements SleuthkitCase.ErrorObserver {
|
||||
* @return
|
||||
*/
|
||||
public CaseType getCaseType() {
|
||||
return this.caseType;
|
||||
return this.getCaseMetadata().getCaseType();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1170,7 +1096,7 @@ public class Case implements SleuthkitCase.ErrorObserver {
|
||||
private String getHostDirectory() {
|
||||
String caseDirectory = getCaseDirectory();
|
||||
Path hostPath;
|
||||
if (caseType == CaseType.MULTI_USER_CASE) {
|
||||
if (getCaseMetadata().getCaseType() == CaseType.MULTI_USER_CASE) {
|
||||
hostPath = Paths.get(caseDirectory, NetworkUtils.getLocalHostName());
|
||||
} else {
|
||||
hostPath = Paths.get(caseDirectory);
|
||||
@@ -1241,11 +1167,7 @@ public class Case implements SleuthkitCase.ErrorObserver {
|
||||
* @return case creation date
|
||||
*/
|
||||
public String getCreatedDate() {
|
||||
if (xmlcm == null) {
|
||||
return "";
|
||||
} else {
|
||||
return xmlcm.getCreatedDate();
|
||||
}
|
||||
return getCaseMetadata().getCreatedDate();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1254,11 +1176,7 @@ public class Case implements SleuthkitCase.ErrorObserver {
|
||||
* @return Index name.
|
||||
*/
|
||||
public String getTextIndexName() {
|
||||
if (xmlcm == null) {
|
||||
return "";
|
||||
} else {
|
||||
return xmlcm.getTextIndexName();
|
||||
}
|
||||
return getCaseMetadata().getTextIndexName();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1621,7 +1539,7 @@ public class Case implements SleuthkitCase.ErrorObserver {
|
||||
|
||||
if (RuntimeProperties.coreComponentsAreActive()) {
|
||||
SwingUtilities.invokeLater(() -> {
|
||||
updateMainWindowTitle(currentCase.name);
|
||||
updateMainWindowTitle(currentCase.getName());
|
||||
});
|
||||
} else {
|
||||
SwingUtilities.invokeLater(() -> {
|
||||
@@ -1754,4 +1672,15 @@ public class Case implements SleuthkitCase.ErrorObserver {
|
||||
return hasData;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the full path to the case metadata file for this case.
|
||||
*
|
||||
* @return configFilePath The case metadata file path.
|
||||
* @deprecated Use getCaseMetadata and CaseMetadata.getFilePath instead.
|
||||
*/
|
||||
@Deprecated
|
||||
String getConfigFilePath() {
|
||||
return getCaseMetadata().getFilePath().toString();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,52 +0,0 @@
|
||||
/*
|
||||
* Autopsy Forensic Browser
|
||||
*
|
||||
* Copyright 2011 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;
|
||||
|
||||
/**
|
||||
* NOTE: NOTHING ACTUALLY USES THIS
|
||||
*
|
||||
* The interface for the classes that edit the case configuration file
|
||||
*/
|
||||
//TODO: check that this can just be deleted.
|
||||
interface CaseConfigFileInterface {
|
||||
|
||||
public void open(String conFilePath) throws Exception; // opens the confiuation store (XML, DB...)
|
||||
|
||||
public void writeFile() throws Exception; // writes out the configuration to store
|
||||
|
||||
public void close() throws Exception; // close and clear the document handler
|
||||
// public int[] getImageIDs() throws Exception; // returns a list of image IDs and names
|
||||
// public int getNextImageID() throws Exception; // returns the next free ID to be assigned to new image, and increments the internal counter
|
||||
|
||||
// all the get and set methods
|
||||
public String getCaseName() throws Exception; // get the case name
|
||||
|
||||
public void setCaseName(String caseName) throws Exception; // set the case name
|
||||
|
||||
public String getCaseNumber() throws Exception; // get the case number
|
||||
|
||||
public void setCaseNumber(String caseNumber) throws Exception; // set the case number
|
||||
|
||||
public String getCaseExaminer() throws Exception; // get the examiner
|
||||
|
||||
public void setCaseExaminer(String examiner) throws Exception; // set the examiner
|
||||
|
||||
// public void getXXX(); // methods to get the case attributes
|
||||
// public void setXXX(); // methods to set the case attributes
|
||||
}
|
||||
@@ -81,8 +81,7 @@ final class CaseDeleteAction extends CallableSystemAction {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
Case currentCase = Case.getCurrentCase();
|
||||
File configFile = new File(currentCase.getConfigFilePath());
|
||||
File caseFolder = new File(configFile.getParent());
|
||||
File caseFolder = new File(currentCase.getCaseDirectory());
|
||||
String caseName = currentCase.getName();
|
||||
if (!caseFolder.exists()) {
|
||||
// throw an error
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* Autopsy Forensic Browser
|
||||
*
|
||||
* Copyright 2011-2015 Basis Technology Corp.
|
||||
* Copyright 2011-2016 Basis Technology Corp.
|
||||
* Contact: carrier <at> sleuthkit <dot> org
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
@@ -18,98 +18,138 @@
|
||||
*/
|
||||
package org.sleuthkit.autopsy.casemodule;
|
||||
|
||||
import java.io.BufferedWriter;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStreamWriter;
|
||||
import java.io.StringWriter;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.text.DateFormat;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
import javax.xml.parsers.DocumentBuilder;
|
||||
import javax.xml.parsers.DocumentBuilderFactory;
|
||||
import javax.xml.parsers.ParserConfigurationException;
|
||||
import javax.xml.transform.OutputKeys;
|
||||
import javax.xml.transform.Result;
|
||||
import javax.xml.transform.Source;
|
||||
import javax.xml.transform.Transformer;
|
||||
import javax.xml.transform.TransformerException;
|
||||
import javax.xml.transform.TransformerFactory;
|
||||
import javax.xml.transform.dom.DOMSource;
|
||||
import javax.xml.transform.stream.StreamResult;
|
||||
import org.sleuthkit.autopsy.coreutils.Version;
|
||||
import org.sleuthkit.autopsy.coreutils.XMLUtil;
|
||||
import org.w3c.dom.Document;
|
||||
import org.w3c.dom.Element;
|
||||
import org.w3c.dom.NodeList;
|
||||
import org.xml.sax.SAXException;
|
||||
|
||||
/**
|
||||
* Provides access to case metadata.
|
||||
* Provides access to the case metadata stored in the case metadata file.
|
||||
*/
|
||||
public final class CaseMetadata {
|
||||
|
||||
private static final String FILE_EXTENSION = ".aut";
|
||||
private static final DateFormat DATE_FORMAT = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss (z)");
|
||||
private static final String SCHEMA_VERSION_ONE = "1.0";
|
||||
private final static String AUTOPSY_CREATED_VERSION_ELEMENT_NAME = "AutopsyCreatedVersion"; //NON-NLS
|
||||
private final static String CASE_DATABASE_NAME_ELEMENT_NAME = "DatabaseName"; //NON-NLS
|
||||
private final static String TEXT_INDEX_NAME_ELEMENT = "TextIndexName"; //NON-NLS
|
||||
private static final String CURRENT_SCHEMA_VERSION = "2.0";
|
||||
private final static String ROOT_ELEMENT_NAME = "AutopsyCase"; //NON-NLS
|
||||
private final static String SCHEMA_VERSION_ELEMENT_NAME = "SchemaVersion"; //NON-NLS
|
||||
private final static String CREATED_DATE_ELEMENT_NAME = "CreatedDate"; //NON-NLS
|
||||
private final static String MODIFIED_DATE_ELEMENT_NAME = "ModifiedDate"; //NON-NLS
|
||||
private final static String AUTOPSY_CREATED_BY_ELEMENT_NAME = "CreatedByAutopsyVersion"; //NON-NLS
|
||||
private final static String AUTOPSY_SAVED_BY_ELEMENT_NAME = "SavedByAutopsyVersion"; //NON-NLS
|
||||
private final static String CASE_ELEMENT_NAME = "Case"; //NON-NLS
|
||||
private final static String CASE_NAME_ELEMENT_NAME = "Name"; //NON-NLS
|
||||
private final static String CASE_NUMBER_ELEMENT_NAME = "Number"; //NON-NLS
|
||||
private final static String EXAMINER_ELEMENT_NAME = "Examiner"; //NON-NLS
|
||||
private final static String CASE_TYPE_ELEMENT_NAME = "CaseType"; //NON-NLS
|
||||
private final static String CASE_DATABASE_ELEMENT_NAME = "Database"; //NON-NLS
|
||||
private final static String TEXT_INDEX_ELEMENT = "TextIndex"; //NON-NLS
|
||||
private final Path metadataFilePath;
|
||||
private Case.CaseType caseType;
|
||||
private String caseName;
|
||||
private String caseNumber;
|
||||
private String examiner;
|
||||
private String caseDatabase;
|
||||
private String textIndexName;
|
||||
private String createdDate;
|
||||
private String createdByVersion;
|
||||
|
||||
/**
|
||||
* Exception thrown by the CaseMetadata class when there is a problem
|
||||
* accessing the metadata for a case.
|
||||
* Gets the file extension used for case metadata files.
|
||||
*
|
||||
* @return The file extension.
|
||||
*/
|
||||
public final static class CaseMetadataException extends Exception {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private CaseMetadataException(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
private CaseMetadataException(String message, Throwable cause) {
|
||||
super(message, cause);
|
||||
}
|
||||
public static String getFileExtension() {
|
||||
return FILE_EXTENSION;
|
||||
}
|
||||
|
||||
private final Case.CaseType caseType;
|
||||
private final String caseName;
|
||||
private final String caseNumber;
|
||||
private final String examiner;
|
||||
private final String caseDirectory;
|
||||
private final String caseDatabaseName;
|
||||
private final String caseTextIndexName;
|
||||
/**
|
||||
* Constructs an object that provides access to the case metadata stored in
|
||||
* a new case metadata file that is created using the supplied metadata.
|
||||
*
|
||||
* @param caseDirectory The case directory.
|
||||
* @param caseType The type of case.
|
||||
* @param caseName The name of the case.
|
||||
* @param caseNumber The case number.
|
||||
* @param examiner The name of the case examiner.
|
||||
* @param caseDatabase For a single-user case, the full path to the
|
||||
* case database file. For a multi-user case, the
|
||||
* case database name.
|
||||
* @param caseTextIndexName The text index name.
|
||||
*
|
||||
* @throws CaseMetadataException If the new case metadata file cannot be
|
||||
* created.
|
||||
*/
|
||||
CaseMetadata(String caseDirectory, Case.CaseType caseType, String caseName, String caseNumber, String examiner, String caseDatabase, String caseTextIndexName) throws CaseMetadataException {
|
||||
metadataFilePath = Paths.get(caseDirectory, caseName + FILE_EXTENSION);
|
||||
this.caseType = caseType;
|
||||
this.caseName = caseName;
|
||||
this.caseNumber = caseNumber;
|
||||
this.examiner = examiner;
|
||||
this.caseDatabase = caseDatabase;
|
||||
this.textIndexName = caseTextIndexName;
|
||||
createdByVersion = Version.getVersion();
|
||||
createdDate = CaseMetadata.DATE_FORMAT.format(new Date());
|
||||
writeToFile();
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs an object that provides access to case metadata.
|
||||
* Constructs an object that provides access to the case metadata stored in
|
||||
* an existing case metadata file.
|
||||
*
|
||||
* @param metadataFilePath Path to the metadata (.aut) file for a case.
|
||||
* @param metadataFilePath The full path to the case metadata file.
|
||||
*
|
||||
* @throws CaseMetadataException If the new case metadata file cannot be
|
||||
* read.
|
||||
*/
|
||||
public CaseMetadata(Path metadataFilePath) throws CaseMetadataException {
|
||||
try {
|
||||
/*
|
||||
* TODO (RC): This class should eventually replace the non-public
|
||||
* and unsafe XMLCaseManagement class altogether.
|
||||
*/
|
||||
XMLCaseManagement metadata = new XMLCaseManagement();
|
||||
metadata.open(metadataFilePath.toString());
|
||||
try {
|
||||
caseType = metadata.getCaseType();
|
||||
} catch (NullPointerException unused) {
|
||||
throw new CaseMetadataException("Case type element missing");
|
||||
}
|
||||
try {
|
||||
caseName = metadata.getCaseName();
|
||||
if (caseName.isEmpty()) {
|
||||
throw new CaseMetadataException("Case name missing");
|
||||
}
|
||||
} catch (NullPointerException unused) {
|
||||
throw new CaseMetadataException("Case name element missing");
|
||||
}
|
||||
try {
|
||||
caseNumber = metadata.getCaseNumber();
|
||||
} catch (NullPointerException unused) {
|
||||
throw new CaseMetadataException("Case number element missing");
|
||||
}
|
||||
try {
|
||||
examiner = metadata.getCaseExaminer();
|
||||
} catch (NullPointerException unused) {
|
||||
throw new CaseMetadataException("Examiner element missing");
|
||||
}
|
||||
try {
|
||||
caseDirectory = metadata.getCaseDirectory();
|
||||
if (caseDirectory.isEmpty()) {
|
||||
throw new CaseMetadataException("Case directory missing");
|
||||
}
|
||||
} catch (NullPointerException unused) {
|
||||
throw new CaseMetadataException("Case directory element missing");
|
||||
}
|
||||
try {
|
||||
caseDatabaseName = metadata.getDatabaseName();
|
||||
} catch (NullPointerException unused) {
|
||||
throw new CaseMetadataException("Case database element missing");
|
||||
}
|
||||
try {
|
||||
caseTextIndexName = metadata.getTextIndexName();
|
||||
if (Case.CaseType.MULTI_USER_CASE == caseType && caseDatabaseName.isEmpty()) {
|
||||
throw new CaseMetadataException("Case keyword search index name missing");
|
||||
}
|
||||
} catch (NullPointerException unused) {
|
||||
throw new CaseMetadataException("Case keyword search index name missing");
|
||||
}
|
||||
} catch (CaseActionException ex) {
|
||||
throw new CaseMetadataException(ex.getLocalizedMessage(), ex);
|
||||
}
|
||||
this.metadataFilePath = metadataFilePath;
|
||||
readFromFile();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the full path to the case metadata file.
|
||||
*
|
||||
* @return The path to the metadata file
|
||||
*/
|
||||
Path getFilePath() {
|
||||
return metadataFilePath;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the case directory.
|
||||
*
|
||||
* @return The case directory.
|
||||
*/
|
||||
public String getCaseDirectory() {
|
||||
return metadataFilePath.getParent().toString();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -118,18 +158,35 @@ public final class CaseMetadata {
|
||||
* @return The case type.
|
||||
*/
|
||||
public Case.CaseType getCaseType() {
|
||||
return this.caseType;
|
||||
return caseType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the case name.
|
||||
* Gets the case display name.
|
||||
*
|
||||
* @return The case name.
|
||||
* @return The case display name.
|
||||
*/
|
||||
public String getCaseName() {
|
||||
return caseName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the case display name. This does not change the name of the case
|
||||
* directory, the case database, or the text index name.
|
||||
*
|
||||
* @param caseName A case display name.
|
||||
*/
|
||||
void setCaseName(String caseName) throws CaseMetadataException {
|
||||
String oldCaseName = caseName;
|
||||
this.caseName = caseName;
|
||||
try {
|
||||
writeToFile();
|
||||
} catch (CaseMetadataException ex) {
|
||||
this.caseName = oldCaseName;
|
||||
throw ex;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the case number.
|
||||
*
|
||||
@@ -149,30 +206,281 @@ public final class CaseMetadata {
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the case directory.
|
||||
* Gets the name of the case case database.
|
||||
*
|
||||
* @return The case directory.
|
||||
* @return The case database name.
|
||||
*/
|
||||
public String getCaseDirectory() {
|
||||
return caseDirectory;
|
||||
public String getCaseDatabaseName() {
|
||||
if (caseType == Case.CaseType.MULTI_USER_CASE) {
|
||||
return caseDatabase;
|
||||
} else {
|
||||
return Paths.get(caseDatabase).getFileName().toString();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the case database name.
|
||||
* Gets the full path to the case database file if the case is a single-user
|
||||
* case.
|
||||
*
|
||||
* @return The case database name, will be empty for a single-user case.
|
||||
* @return The full path to the case database file for a single-user case.
|
||||
*
|
||||
* @throws UnsupportedOperationException If called for a multi-user case.
|
||||
*/
|
||||
public String getCaseDatabaseName() {
|
||||
return caseDatabaseName;
|
||||
public String getCaseDatabasePath() throws UnsupportedOperationException {
|
||||
if (caseType == Case.CaseType.SINGLE_USER_CASE) {
|
||||
return caseDatabase;
|
||||
} else {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the text index name.
|
||||
*
|
||||
* @return The case text index name, will be empty for a single-user case.
|
||||
* @return The name of the text index for the case.
|
||||
*/
|
||||
public String getTextIndexName() {
|
||||
return caseTextIndexName;
|
||||
return textIndexName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the date the case was created.
|
||||
*
|
||||
* @return The date this case was created as a string
|
||||
*/
|
||||
String getCreatedDate() {
|
||||
return createdDate;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the date the case was created. Used for preserving the case creation
|
||||
* date during single-user to multi-user case conversion.
|
||||
*
|
||||
* @param createdDate The date the case was created as a string.
|
||||
*/
|
||||
void setCreatedDate(String createdDate) throws CaseMetadataException {
|
||||
String oldCreatedDate = createdDate;
|
||||
this.createdDate = createdDate;
|
||||
try {
|
||||
writeToFile();
|
||||
} catch (CaseMetadataException ex) {
|
||||
this.createdDate = oldCreatedDate;
|
||||
throw ex;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the Autopsy version that created the case.
|
||||
*
|
||||
* @return A build identifier.
|
||||
*/
|
||||
String getCreatedByVersion() {
|
||||
return createdByVersion;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the Autopsy version that created the case. Used for preserving this
|
||||
* metadata during single-user to multi-user case conversion.
|
||||
*
|
||||
* @param buildVersion An build version identifier.
|
||||
*/
|
||||
void setCreatedByVersion(String buildVersion) throws CaseMetadataException {
|
||||
String oldCreatedByVersion = this.createdByVersion;
|
||||
this.createdByVersion = buildVersion;
|
||||
try {
|
||||
this.writeToFile();
|
||||
} catch (CaseMetadataException ex) {
|
||||
this.createdByVersion = oldCreatedByVersion;
|
||||
throw ex;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes the case metadata to the metadata file.
|
||||
*
|
||||
* @throws CaseMetadataException If there is an error writing to the case
|
||||
* metadata file.
|
||||
*/
|
||||
private void writeToFile() throws CaseMetadataException {
|
||||
try {
|
||||
/*
|
||||
* Create the XML DOM.
|
||||
*/
|
||||
Document doc = XMLUtil.createDocument();
|
||||
createXMLDOM(doc);
|
||||
doc.normalize();
|
||||
|
||||
/*
|
||||
* Prepare the DOM for pretty printing to the metadata file.
|
||||
*/
|
||||
Source source = new DOMSource(doc);
|
||||
StringWriter stringWriter = new StringWriter();
|
||||
Result streamResult = new StreamResult(stringWriter);
|
||||
Transformer transformer = TransformerFactory.newInstance().newTransformer();
|
||||
transformer.setOutputProperty(OutputKeys.INDENT, "yes"); //NON-NLS
|
||||
transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "2"); //NON-NLS
|
||||
transformer.transform(source, streamResult);
|
||||
|
||||
/*
|
||||
* Write the DOM to the metadata file.
|
||||
*/
|
||||
try (BufferedWriter fileWriter = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(metadataFilePath.toFile())))) {
|
||||
fileWriter.write(stringWriter.toString());
|
||||
fileWriter.flush();
|
||||
}
|
||||
|
||||
} catch (ParserConfigurationException | TransformerException | IOException ex) {
|
||||
throw new CaseMetadataException(String.format("Error writing to case metadata file %s", metadataFilePath), ex);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Creates an XML DOM from the case metadata.
|
||||
*/
|
||||
private void createXMLDOM(Document doc) {
|
||||
/*
|
||||
* Create the root element and its children.
|
||||
*/
|
||||
Element rootElement = doc.createElement(ROOT_ELEMENT_NAME);
|
||||
doc.appendChild(rootElement);
|
||||
createChildElement(doc, rootElement, SCHEMA_VERSION_ELEMENT_NAME, CURRENT_SCHEMA_VERSION);
|
||||
createChildElement(doc, rootElement, CREATED_DATE_ELEMENT_NAME, createdDate);
|
||||
createChildElement(doc, rootElement, MODIFIED_DATE_ELEMENT_NAME, DATE_FORMAT.format(new Date()));
|
||||
createChildElement(doc, rootElement, AUTOPSY_CREATED_BY_ELEMENT_NAME, createdByVersion);
|
||||
createChildElement(doc, rootElement, AUTOPSY_SAVED_BY_ELEMENT_NAME, Version.getVersion());
|
||||
Element caseElement = doc.createElement(CASE_ELEMENT_NAME);
|
||||
rootElement.appendChild(caseElement);
|
||||
|
||||
/*
|
||||
* Create the children of the case element.
|
||||
*/
|
||||
createChildElement(doc, caseElement, CASE_NAME_ELEMENT_NAME, caseName);
|
||||
createChildElement(doc, caseElement, CASE_NUMBER_ELEMENT_NAME, caseNumber);
|
||||
createChildElement(doc, caseElement, EXAMINER_ELEMENT_NAME, examiner);
|
||||
createChildElement(doc, caseElement, CASE_TYPE_ELEMENT_NAME, caseType.toString());
|
||||
createChildElement(doc, caseElement, CASE_DATABASE_ELEMENT_NAME, caseDatabase);
|
||||
createChildElement(doc, caseElement, TEXT_INDEX_ELEMENT, textIndexName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an XML element for the case metadata XML DOM.
|
||||
*
|
||||
* @param doc The document.
|
||||
* @param parentElement The parent element of the element to be created.
|
||||
* @param elementName The name of the element to be created.
|
||||
* @param elementContent The text content of the element to be created, may
|
||||
* be empty.
|
||||
*/
|
||||
private void createChildElement(Document doc, Element parentElement, String elementName, String elementContent) {
|
||||
Element element = doc.createElement(elementName);
|
||||
element.appendChild(doc.createTextNode(elementContent));
|
||||
parentElement.appendChild(element);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads the case metadata from the metadata file.
|
||||
*
|
||||
* @throws CaseMetadataException If there is an error reading from the case
|
||||
* metadata file.
|
||||
*/
|
||||
private void readFromFile() throws CaseMetadataException {
|
||||
try {
|
||||
/*
|
||||
* Parse the file into an XML DOM and get the root element.
|
||||
*/
|
||||
DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
|
||||
Document doc = builder.parse(this.getFilePath().toFile());
|
||||
doc.getDocumentElement().normalize();
|
||||
Element rootElement = doc.getDocumentElement();
|
||||
if (!rootElement.getNodeName().equals(ROOT_ELEMENT_NAME)) {
|
||||
throw new CaseMetadataException("Case metadata file corrupted");
|
||||
}
|
||||
|
||||
/*
|
||||
* Get the content of the relevant children of the root element.
|
||||
*/
|
||||
String schemaVersion = getElementTextContent(rootElement, SCHEMA_VERSION_ELEMENT_NAME, true);
|
||||
this.createdDate = getElementTextContent(rootElement, CREATED_DATE_ELEMENT_NAME, true);
|
||||
if (schemaVersion.equals(SCHEMA_VERSION_ONE)) {
|
||||
this.createdByVersion = getElementTextContent(rootElement, AUTOPSY_CREATED_VERSION_ELEMENT_NAME, true);
|
||||
} else {
|
||||
this.createdByVersion = getElementTextContent(rootElement, AUTOPSY_CREATED_BY_ELEMENT_NAME, true);
|
||||
}
|
||||
|
||||
/*
|
||||
* Get the content of the children of the case element.
|
||||
*/
|
||||
NodeList caseElements = doc.getElementsByTagName(CASE_ELEMENT_NAME);
|
||||
if (caseElements.getLength() == 0) {
|
||||
throw new CaseMetadataException("Case metadata file corrupted");
|
||||
}
|
||||
Element caseElement = (Element) caseElements.item(0);
|
||||
this.caseName = getElementTextContent(caseElement, CASE_NAME_ELEMENT_NAME, true);
|
||||
this.caseNumber = getElementTextContent(caseElement, CASE_NUMBER_ELEMENT_NAME, false);
|
||||
this.examiner = getElementTextContent(caseElement, EXAMINER_ELEMENT_NAME, false);
|
||||
this.caseType = Case.CaseType.fromString(getElementTextContent(caseElement, CASE_TYPE_ELEMENT_NAME, true));
|
||||
if (null == this.caseType) {
|
||||
throw new CaseMetadataException("Case metadata file corrupted");
|
||||
}
|
||||
if (schemaVersion.equals(SCHEMA_VERSION_ONE)) {
|
||||
this.caseDatabase = getElementTextContent(caseElement, CASE_DATABASE_NAME_ELEMENT_NAME, true);
|
||||
this.textIndexName = getElementTextContent(caseElement, TEXT_INDEX_NAME_ELEMENT, true);
|
||||
} else {
|
||||
this.caseDatabase = getElementTextContent(caseElement, CASE_DATABASE_ELEMENT_NAME, true);
|
||||
this.textIndexName = getElementTextContent(caseElement, TEXT_INDEX_ELEMENT, true);
|
||||
}
|
||||
|
||||
/*
|
||||
* Update the file to the current schema, if necessary.
|
||||
*/
|
||||
if (!schemaVersion.equals(CURRENT_SCHEMA_VERSION)) {
|
||||
writeToFile();
|
||||
}
|
||||
|
||||
} catch (ParserConfigurationException | SAXException | IOException ex) {
|
||||
throw new CaseMetadataException(String.format("Error reading from case metadata file %s", metadataFilePath), ex);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the text content of an XML element.
|
||||
*
|
||||
* @param parentElement The parent element.
|
||||
* @param elementName The element name.
|
||||
* @param contentIsRequired Whether or not the content is required.
|
||||
*
|
||||
* @return The text content, may be empty if not required.
|
||||
*
|
||||
* @throws CaseMetadataException If the element is missing or content is
|
||||
* required and it is empty.
|
||||
*/
|
||||
private String getElementTextContent(Element parentElement, String elementName, boolean contentIsRequired) throws CaseMetadataException {
|
||||
NodeList elementsList = parentElement.getElementsByTagName(elementName);
|
||||
if (elementsList.getLength() == 0) {
|
||||
throw new CaseMetadataException(String.format("Missing %s element from case metadata file %s", elementName, metadataFilePath));
|
||||
}
|
||||
String textContent = elementsList.item(0).getTextContent();
|
||||
if (textContent.isEmpty() && contentIsRequired) {
|
||||
throw new CaseMetadataException(String.format("Empty %s element in case metadata file %s", elementName, metadataFilePath));
|
||||
}
|
||||
return textContent;
|
||||
}
|
||||
|
||||
/**
|
||||
* Exception thrown by the CaseMetadata class when there is a problem
|
||||
* accessing the metadata for a case.
|
||||
*/
|
||||
public final static class CaseMetadataException extends Exception {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private CaseMetadataException(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
private CaseMetadataException(String message, Throwable cause) {
|
||||
super(message, cause);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -54,7 +54,7 @@ public final class CaseOpenAction implements ActionListener {
|
||||
* Constructs an action that opens an existing case.
|
||||
*/
|
||||
public CaseOpenAction() {
|
||||
caseMetadataFileFilter = new FileNameExtensionFilter(NbBundle.getMessage(CaseOpenAction.class, "CaseOpenAction.autFilter.title", Version.getName(), Case.CASE_DOT_EXTENSION), Case.CASE_EXTENSION);
|
||||
caseMetadataFileFilter = new FileNameExtensionFilter(NbBundle.getMessage(CaseOpenAction.class, "CaseOpenAction.autFilter.title", Version.getName(), CaseMetadata.getFileExtension()), CaseMetadata.getFileExtension().substring(1));
|
||||
fileChooser.setDragEnabled(false);
|
||||
fileChooser.setFileSelectionMode(JFileChooser.FILES_ONLY);
|
||||
fileChooser.setMultiSelectionEnabled(false);
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* Autopsy Forensic Browser
|
||||
*
|
||||
* Copyright 2011 Basis Technology Corp.
|
||||
* Copyright 2011-2016 Basis Technology Corp.
|
||||
* Contact: carrier <at> sleuthkit <dot> org
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
@@ -24,7 +24,6 @@
|
||||
*/
|
||||
package org.sleuthkit.autopsy.casemodule;
|
||||
|
||||
import java.awt.*;
|
||||
import java.nio.file.Paths;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.io.File;
|
||||
@@ -41,9 +40,8 @@ import org.openide.NotifyDescriptor;
|
||||
import org.openide.util.actions.CallableSystemAction;
|
||||
|
||||
/**
|
||||
* The form where user can change / update the properties of the current case.
|
||||
*
|
||||
* @author jantonius
|
||||
* The form where user can change / update the properties of the current case
|
||||
* metadata.
|
||||
*/
|
||||
class CasePropertiesForm extends javax.swing.JPanel {
|
||||
|
||||
@@ -89,8 +87,12 @@ class CasePropertiesForm extends javax.swing.JPanel {
|
||||
caseDirTextArea.setText(caseDir);
|
||||
current = currentCase;
|
||||
|
||||
CaseMetadata caseMetadata = new CaseMetadata(Paths.get(currentCase.getConfigFilePath()));
|
||||
tbDbName.setText(caseMetadata.getCaseDatabaseName());
|
||||
CaseMetadata caseMetadata = currentCase.getCaseMetadata();
|
||||
if (caseMetadata.getCaseType() == Case.CaseType.SINGLE_USER_CASE) {
|
||||
tbDbName.setText(caseMetadata.getCaseDatabasePath());
|
||||
} else {
|
||||
tbDbName.setText(caseMetadata.getCaseDatabaseName());
|
||||
}
|
||||
Case.CaseType caseType = caseMetadata.getCaseType();
|
||||
tbDbType.setText(caseType.getLocalizedDisplayName());
|
||||
if (caseType == Case.CaseType.SINGLE_USER_CASE) {
|
||||
@@ -103,15 +105,16 @@ class CasePropertiesForm extends javax.swing.JPanel {
|
||||
|
||||
// create the headers and add all the rows
|
||||
// Header names are internationalized via the generated code, do not overwrite.
|
||||
String[] headers = {imagesTable.getColumnName(0),
|
||||
imagesTable.getColumnName(1)};
|
||||
String[] headers = {imagesTable.getColumnName(0),
|
||||
imagesTable.getColumnName(1)};
|
||||
String[][] rows = new String[totalImages][];
|
||||
|
||||
int i = 0;
|
||||
for (long key : imgPaths.keySet()) {
|
||||
String path = imgPaths.get(key);
|
||||
String shortenPath = shrinkPath(path, 70);
|
||||
rows[i++] = new String[]{shortenPath};
|
||||
rows[i] = new String[]{shortenPath};
|
||||
i++;
|
||||
}
|
||||
|
||||
// create the table inside with the imgPaths information
|
||||
@@ -124,61 +127,17 @@ class CasePropertiesForm extends javax.swing.JPanel {
|
||||
}
|
||||
};
|
||||
imagesTable.setModel(model);
|
||||
|
||||
// // set the size of the remove column
|
||||
// TableColumn removeCol = imagesTable.getColumnModel().getColumn(lastColumn);
|
||||
// removeCol.setPreferredWidth(75);
|
||||
// removeCol.setMaxWidth(75);
|
||||
// removeCol.setMinWidth(75);
|
||||
// removeCol.setResizable(false);
|
||||
// // create the delete action to remove the image from the current case
|
||||
// Action delete = new AbstractAction()
|
||||
// {
|
||||
// @Override
|
||||
// public void actionPerformed(ActionEvent e)
|
||||
// {
|
||||
// // get the image path
|
||||
// JTable table = (JTable)e.getSource();
|
||||
// int modelRow = Integer.valueOf(e.getActionCommand());
|
||||
// String removeColumn = table.getValueAt(modelRow, lastColumn).toString();
|
||||
// // get the image ID
|
||||
// int selectedID = Integer.parseInt(removeColumn.substring(0, removeColumn.indexOf('|')));
|
||||
// String imagePath = removeColumn.substring(removeColumn.indexOf('|') + 1);
|
||||
//
|
||||
// // throw the confirmation first
|
||||
// String confMsg = "Are you sure want to remove image \"" + imagePath + "\" from this case?";
|
||||
// NotifyDescriptor d = new NotifyDescriptor.Confirmation(confMsg, "Create directory", NotifyDescriptor.YES_NO_OPTION, NotifyDescriptor.WARNING_MESSAGE);
|
||||
// d.setValue(NotifyDescriptor.NO_OPTION);
|
||||
//
|
||||
// Object res = DialogDisplayer.getDefault().notify(d);
|
||||
// // if user select "Yes"
|
||||
// if(res != null && res == DialogDescriptor.YES_OPTION){
|
||||
// // remove the image in the case class and in the xml config file
|
||||
// try {
|
||||
// current.removeImage(selectedID, imagePath);
|
||||
// } catch (Exception ex) {
|
||||
// Logger.getLogger(CasePropertiesForm.class.getName()).log(Level.WARNING, "Error: couldn't remove image.", ex);
|
||||
// }
|
||||
// // remove the row of the image path
|
||||
// ((DefaultTableModel)table.getModel()).removeRow(modelRow);
|
||||
// }
|
||||
// }
|
||||
// };
|
||||
//
|
||||
// ButtonColumn buttonColumn = new ButtonColumn(imagesTable, delete, 1, "Remove");
|
||||
// buttonColumn.setMnemonic(KeyEvent.VK_D);
|
||||
}
|
||||
|
||||
/**
|
||||
* In this generated code below, there are 2 strings "Path" and "Remove" that are
|
||||
* table column headers in the DefaultTableModel. When this model is generated,
|
||||
* it puts the hard coded English strings into the generated code. And then about 15
|
||||
* lines later, it separately internationalizes them using:
|
||||
* imagesTable.getColumnModel().getColumn(0).setHeaderValue().
|
||||
* There is no way to prevent the GUI designer from putting the hard coded
|
||||
* English strings into the generated code. So, they remain, and are not used.
|
||||
/**
|
||||
* In this generated code below, there are 2 strings "Path" and "Remove"
|
||||
* that are table column headers in the DefaultTableModel. When this model
|
||||
* is generated, it puts the hard coded English strings into the generated
|
||||
* code. And then about 15 lines later, it separately internationalizes them
|
||||
* using: imagesTable.getColumnModel().getColumn(0).setHeaderValue(). There
|
||||
* is no way to prevent the GUI designer from putting the hard coded English
|
||||
* strings into the generated code. So, they remain, and are not used.
|
||||
*/
|
||||
|
||||
/**
|
||||
* 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
|
||||
@@ -429,9 +388,6 @@ class CasePropertiesForm extends javax.swing.JPanel {
|
||||
private void updateCaseNameButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_updateCaseNameButtonActionPerformed
|
||||
String oldCaseName = Case.getCurrentCase().getName();
|
||||
String newCaseName = caseNameTextField.getText();
|
||||
//String oldPath = caseDirTextArea.getText() + File.separator + oldCaseName + ".aut";
|
||||
//String newPath = caseDirTextArea.getText() + File.separator + newCaseName + ".aut";
|
||||
|
||||
// check if the old and new case name is not equal
|
||||
if (!oldCaseName.equals(newCaseName)) {
|
||||
|
||||
@@ -469,7 +425,7 @@ class CasePropertiesForm extends javax.swing.JPanel {
|
||||
Object res = DialogDisplayer.getDefault().notify(d);
|
||||
if (res != null && res == DialogDescriptor.YES_OPTION) {
|
||||
// if user select "Yes"
|
||||
String oldPath = current.getConfigFilePath();
|
||||
String oldPath = current.getCaseMetadata().getFilePath().toString();
|
||||
try {
|
||||
current.updateCaseName(oldCaseName, oldPath, newCaseName, oldPath);
|
||||
} catch (Exception ex) {
|
||||
|
||||
@@ -1,124 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!--
|
||||
This file describes the schema definition for its twin files, $autopsyCaseDir/$case.aut
|
||||
.aut files are created in the case directory when user makes a new case.
|
||||
-->
|
||||
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
|
||||
|
||||
<!-- definition of simple elements -->
|
||||
<xs:element name="Name" type="String"/>
|
||||
|
||||
<xs:element name="Number" type="String" nillable="true"/>
|
||||
|
||||
<xs:element name="Examiner" type="String" nillable="true"/>
|
||||
|
||||
<xs:element name="CaseType" type="String" nillable="false"/>
|
||||
|
||||
<xs:element name="DatabaseName" type="String" nillable="false"/>
|
||||
|
||||
<xs:element name="TextIndexName" type="String" nillable="true"/>
|
||||
|
||||
<xs:attribute name="Relative" type="xs:boolean"/>
|
||||
|
||||
<xs:element name="CreatedDate" >
|
||||
<xs:simpleType>
|
||||
<xs:restriction base="xs:string">
|
||||
<xs:whiteSpace value="preserve"/>
|
||||
<xs:pattern value="([0-9]{4}/)+([0-1][0-9]/)+([0-3][0-9] )+([0-2][0-9]:[0-5][0-9]:[0-9][0-9] )+(\([A-Z][A-Z][A-Z]\))"/>
|
||||
</xs:restriction>
|
||||
</xs:simpleType>
|
||||
</xs:element>
|
||||
|
||||
<xs:element name="ModifiedDate">
|
||||
<xs:simpleType>
|
||||
<xs:restriction base="xs:string">
|
||||
<xs:whiteSpace value="preserve"/>
|
||||
<xs:pattern value="([0-9]{4}/)+([0-1][0-9]/)+([0-3][0-9] )+([0-2][0-9]:[0-5][0-9]:[0-9][0-9] )+(\([A-Z][A-Z][A-Z]\))"/>
|
||||
</xs:restriction>
|
||||
</xs:simpleType>
|
||||
</xs:element>
|
||||
|
||||
<xs:element name="AutopsyCreatedVersion" type="xs:integer"/>
|
||||
|
||||
<xs:element name="AutopsySavedVersion" type="xs:integer"/>
|
||||
|
||||
<xs:element name="SchemaVersion" type="xs:decimal"/>
|
||||
|
||||
<!-- Wrappers over the built in values to allow empty string elements, eg <number/> -->
|
||||
<xs:simpleType name="Integer">
|
||||
<xs:union memberTypes="xs:integer empty"/>
|
||||
</xs:simpleType>
|
||||
|
||||
<xs:simpleType name="String">
|
||||
<xs:union memberTypes="xs:string empty"/>
|
||||
</xs:simpleType>
|
||||
|
||||
<xs:simpleType name="empty">
|
||||
<xs:restriction base="xs:string">
|
||||
<xs:enumeration value="" />
|
||||
</xs:restriction>
|
||||
</xs:simpleType>
|
||||
|
||||
|
||||
|
||||
|
||||
<!-- definition of complex elements -->
|
||||
|
||||
<xs:element name="ExportFolder">
|
||||
<xs:complexType mixed="true">
|
||||
<xs:attribute ref="Relative" default="true" use="optional"/>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
|
||||
<xs:element name="LogFolder" >
|
||||
<xs:complexType mixed="true">
|
||||
<xs:attribute ref="Relative" default="true" use="optional"/>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
|
||||
<xs:element name="TempFolder">
|
||||
<xs:complexType mixed="true">
|
||||
<xs:attribute ref="Relative" default="true" use="optional"/>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
|
||||
<xs:element name="CacheFolder" >
|
||||
<xs:complexType mixed="true">
|
||||
<xs:attribute ref="Relative" default="true" use="optional"/>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
|
||||
<xs:element name="Case">
|
||||
<xs:complexType>
|
||||
<xs:sequence>
|
||||
<xs:element ref="Name"/>
|
||||
<xs:element ref="Number" />
|
||||
<xs:element ref="Examiner" />
|
||||
<xs:element ref="ExportFolder"/>
|
||||
<xs:element ref="LogFolder"/>
|
||||
<xs:element ref="TempFolder"/>
|
||||
<xs:element ref="CacheFolder"/>
|
||||
<xs:sequence minOccurs="0" maxOccurs="1">
|
||||
<xs:element ref="CaseType"/>
|
||||
<xs:element ref="DatabaseName"/>
|
||||
<xs:element ref="TextIndexName"/>
|
||||
</xs:sequence>
|
||||
</xs:sequence>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
|
||||
<xs:element name="AutopsyCase">
|
||||
<xs:complexType>
|
||||
<xs:sequence>
|
||||
<xs:element ref="CreatedDate" />
|
||||
<xs:element ref="ModifiedDate" />
|
||||
<xs:element ref="AutopsyCreatedVersion"/>
|
||||
<xs:element ref="AutopsySavedVersion"/>
|
||||
<xs:element ref="SchemaVersion"/>
|
||||
<xs:element ref="Case"/>
|
||||
</xs:sequence>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
|
||||
|
||||
</xs:schema>
|
||||
@@ -408,7 +408,7 @@ final class RecentCases extends CallableSystemAction implements Presenter.Menu {
|
||||
String[] casePaths = new String[LENGTH];
|
||||
String currentCasePath = null;
|
||||
try {
|
||||
currentCasePath = Case.getCurrentCase().getConfigFilePath();
|
||||
currentCasePath = Case.getCurrentCase().getCaseMetadata().getFilePath().toString();
|
||||
} catch (IllegalStateException ex) {
|
||||
// in case there is no current case.
|
||||
}
|
||||
|
||||
@@ -46,7 +46,7 @@ import org.sleuthkit.autopsy.coreutils.NetworkUtils;
|
||||
public class SingleUserCaseConverter {
|
||||
|
||||
private static final String AUTOPSY_DB_FILE = "autopsy.db"; //NON-NLS
|
||||
private static final String DOTAUT = ".aut"; //NON-NLS
|
||||
private static final String DOTAUT = CaseMetadata.getFileExtension(); //NON-NLS
|
||||
private static final String TIMELINE_FOLDER = "Timeline"; //NON-NLS
|
||||
private static final String TIMELINE_FILE = "events.db"; //NON-NLS
|
||||
private static final String POSTGRES_DEFAULT_DB_NAME = "postgres"; //NON-NLS
|
||||
@@ -165,9 +165,8 @@ public class SingleUserCaseConverter {
|
||||
}
|
||||
|
||||
// Read old xml config
|
||||
XMLCaseManagement oldXmlCaseManagement = new XMLCaseManagement();
|
||||
oldXmlCaseManagement.open(icd.getCaseInputFolder().resolve(icd.getAutFileName()).toString());
|
||||
if (oldXmlCaseManagement.getCaseType() == CaseType.MULTI_USER_CASE) {
|
||||
CaseMetadata oldCaseMetadata = new CaseMetadata(icd.getCaseInputFolder().resolve(icd.getAutFileName()));
|
||||
if (oldCaseMetadata.getCaseType() == CaseType.MULTI_USER_CASE) {
|
||||
throw new Exception(NbBundle.getMessage(SingleUserCaseConverter.class, "SingleUserCaseConverter.AlreadyMultiUser")); //NON-NLS
|
||||
}
|
||||
|
||||
@@ -191,15 +190,15 @@ public class SingleUserCaseConverter {
|
||||
copyImages(icd);
|
||||
|
||||
// Create new .aut file
|
||||
XMLCaseManagement newXmlCaseManagement = new XMLCaseManagement();
|
||||
newXmlCaseManagement.create(icd.getCaseOutputFolder().toString(),
|
||||
CaseMetadata newCaseMetadata = new CaseMetadata(icd.getCaseOutputFolder().toString(),
|
||||
CaseType.MULTI_USER_CASE,
|
||||
icd.getNewCaseName(),
|
||||
oldXmlCaseManagement.getCaseExaminer(),
|
||||
oldXmlCaseManagement.getCaseNumber(),
|
||||
CaseType.MULTI_USER_CASE, dbName, solrName);
|
||||
|
||||
oldCaseMetadata.getCaseNumber(),
|
||||
oldCaseMetadata.getExaminer(),
|
||||
dbName, solrName);
|
||||
// Set created date. This calls writefile, no need to call it again
|
||||
newXmlCaseManagement.setCreatedDate(oldXmlCaseManagement.getCreatedDate());
|
||||
newCaseMetadata.setCreatedDate(oldCaseMetadata.getCreatedDate());
|
||||
newCaseMetadata.setCreatedByVersion(oldCaseMetadata.getCreatedByVersion());
|
||||
|
||||
// At this point the import has been finished successfully so we can delete the original case
|
||||
// (if requested). This *should* be fairly safe - at this point we know there was an autopsy file
|
||||
|
||||
@@ -1,814 +0,0 @@
|
||||
/*
|
||||
* Autopsy Forensic Browser
|
||||
*
|
||||
* Copyright 2012-2015 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;
|
||||
|
||||
import java.io.*;
|
||||
import java.text.DateFormat;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
import java.util.logging.Level;
|
||||
import javax.swing.JOptionPane;
|
||||
import javax.swing.JPanel;
|
||||
import javax.xml.parsers.*;
|
||||
import javax.xml.transform.*;
|
||||
import javax.xml.transform.dom.*;
|
||||
import javax.xml.transform.stream.*;
|
||||
import org.openide.util.NbBundle;
|
||||
import org.sleuthkit.autopsy.casemodule.Case.CaseType;
|
||||
import org.sleuthkit.autopsy.core.RuntimeProperties;
|
||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||
import org.w3c.dom.*;
|
||||
import org.xml.sax.SAXException;
|
||||
|
||||
/**
|
||||
*
|
||||
* This class is used to create, access, and modify the XML configuration file,
|
||||
* where we store the information about the case and image(s). This class uses
|
||||
* the document handler to store the information about the case. The document
|
||||
* handler will be created / opened when the case configuration file is created/
|
||||
* opened.
|
||||
*
|
||||
* @author jantonius
|
||||
*/
|
||||
class XMLCaseManagement implements CaseConfigFileInterface {
|
||||
|
||||
final static String XSDFILE = "CaseSchema.xsd"; //NON-NLS
|
||||
final static String TOP_ROOT_NAME = "AutopsyCase"; //NON-NLS
|
||||
final static String CASE_ROOT_NAME = "Case"; //NON-NLS
|
||||
// general metadata about the case file
|
||||
final static String NAME = "Name"; //NON-NLS
|
||||
final static String NUMBER = "Number"; //NON-NLS
|
||||
final static String EXAMINER = "Examiner"; //NON-NLS
|
||||
final static String CREATED_DATE_NAME = "CreatedDate"; //NON-NLS
|
||||
final static String MODIFIED_DATE_NAME = "ModifiedDate"; //NON-NLS
|
||||
final static String SCHEMA_VERSION_NAME = "SchemaVersion"; //NON-NLS
|
||||
final static String AUTOPSY_CRVERSION_NAME = "AutopsyCreatedVersion"; //NON-NLS
|
||||
final static String AUTOPSY_MVERSION_NAME = "AutopsySavedVersion"; //NON-NLS
|
||||
final static String CASE_TEXT_INDEX_NAME = "TextIndexName"; //NON-NLS
|
||||
// folders inside case directory
|
||||
final static String LOG_FOLDER_NAME = "LogFolder"; //NON-NLS
|
||||
final static String LOG_FOLDER_RELPATH = "Log"; //NON-NLS
|
||||
final static String TEMP_FOLDER_NAME = "TempFolder"; //NON-NLS
|
||||
final static String TEMP_FOLDER_RELPATH = "Temp"; //NON-NLS
|
||||
final static String EXPORT_FOLDER_NAME = "ExportFolder"; //NON-NLS
|
||||
final static String EXPORT_FOLDER_RELPATH = "Export"; //NON-NLS
|
||||
final static String CACHE_FOLDER_NAME = "CacheFolder"; //NON-NLS
|
||||
final static String CACHE_FOLDER_RELPATH = "Cache"; //NON-NLS
|
||||
final static String CASE_TYPE = "CaseType"; //NON-NLS
|
||||
final static String DATABASE_NAME = "DatabaseName"; //NON-NLS
|
||||
// folders attribute
|
||||
final static String RELATIVE_NAME = "Relative"; // relevant path info NON-NLS
|
||||
// folder attr values
|
||||
final static String RELATIVE_TRUE = "true"; // if it's a relative path NON-NLS
|
||||
final static String RELATIVE_FALSE = "false"; // if it's not a relative path NON-NLS
|
||||
// the document
|
||||
private Document doc;
|
||||
// general info
|
||||
private final DateFormat dateFormat = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss (z)");
|
||||
private String caseDirPath; // case directory path
|
||||
private String caseName; // case name
|
||||
private String caseNumber; // case number
|
||||
private String examiner; // examiner name
|
||||
private final String schemaVersion = "1.0";
|
||||
private final String autopsySavedVersion;
|
||||
private CaseType caseType; // The type of case: local or shared
|
||||
private String dbName; // The name of the database
|
||||
private String textIndexName; // The name of the index where extracted text is stored.
|
||||
|
||||
// for error handling
|
||||
private JPanel caller;
|
||||
private final String className = this.getClass().toString();
|
||||
private static final Logger logger = Logger.getLogger(XMLCaseManagement.class.getName());
|
||||
|
||||
/**
|
||||
* The constructor
|
||||
*/
|
||||
public XMLCaseManagement() {
|
||||
autopsySavedVersion = System.getProperty("netbeans.buildnumber");
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the case directory path of the case directory on the local variable
|
||||
*
|
||||
* @param givenPath the new path to be stored as case directory path
|
||||
*/
|
||||
private void setCaseDirPath(String givenPath) {
|
||||
caseDirPath = givenPath; // change this to change the xml file if needed
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the case Name on the XML configuration file
|
||||
*
|
||||
* @param givenCaseName the new case name to be set
|
||||
*/
|
||||
@Override
|
||||
public void setCaseName(String givenCaseName) throws CaseActionException {
|
||||
// change this to change the xml file if needed
|
||||
Element nameElement = (Element) getCaseElement().getElementsByTagName(NAME).item(0);
|
||||
nameElement.setTextContent(givenCaseName);
|
||||
doc.normalize();
|
||||
|
||||
// edit the modified data
|
||||
String newDate = dateFormat.format(new Date());
|
||||
Element rootEl = getRootElement();
|
||||
rootEl.getElementsByTagName(MODIFIED_DATE_NAME).item(0).setTextContent(newDate);
|
||||
|
||||
writeFile();
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the case number on the XML configuration file
|
||||
*
|
||||
* @param givenCaseNumber the new case number to be set
|
||||
*/
|
||||
@Override
|
||||
public void setCaseNumber(String givenCaseNumber) throws CaseActionException {
|
||||
// change this to change the xml file if needed
|
||||
Element nameElement = (Element) getCaseElement().getElementsByTagName(NUMBER).item(0);
|
||||
nameElement.setTextContent(String.valueOf(givenCaseNumber));
|
||||
doc.normalize();
|
||||
|
||||
// edit the modified data
|
||||
String newDate = dateFormat.format(new Date());
|
||||
Element rootEl = getRootElement();
|
||||
rootEl.getElementsByTagName(MODIFIED_DATE_NAME).item(0).setTextContent(newDate);
|
||||
|
||||
writeFile();
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the created date on the XML configuration file. This method is for
|
||||
* preserving the created date when converting a case from single-user to
|
||||
* multi-user.
|
||||
*
|
||||
* @param createdDate the date the case was originally created
|
||||
*
|
||||
* @throws org.sleuthkit.autopsy.casemodule.CaseActionException
|
||||
*/
|
||||
public void setCreatedDate(String createdDate) throws CaseActionException {
|
||||
String newDate = dateFormat.format(new Date());
|
||||
Element rootEl = getRootElement();
|
||||
rootEl.getElementsByTagName(CREATED_DATE_NAME).item(0).setTextContent(createdDate);
|
||||
rootEl.getElementsByTagName(MODIFIED_DATE_NAME).item(0).setTextContent(newDate);
|
||||
writeFile();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the examiner on the XML configuration file
|
||||
*
|
||||
* @param givenExaminer the new examiner to be set
|
||||
*/
|
||||
@Override
|
||||
public void setCaseExaminer(String givenExaminer) throws CaseActionException {
|
||||
// change this to change the xml file if needed
|
||||
Element nameElement = (Element) getCaseElement().getElementsByTagName(EXAMINER).item(0);
|
||||
nameElement.setTextContent(givenExaminer);
|
||||
doc.normalize();
|
||||
|
||||
// edit the modified data
|
||||
String newDate = dateFormat.format(new Date());
|
||||
Element rootEl = getRootElement();
|
||||
rootEl.getElementsByTagName(MODIFIED_DATE_NAME).item(0).setTextContent(newDate);
|
||||
|
||||
writeFile();
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the case name internally (on local variable in this class)
|
||||
*
|
||||
* @param givenCaseName the new case name
|
||||
*/
|
||||
private void setName(String givenCaseName) {
|
||||
caseName = givenCaseName; // change this to change the xml file if needed
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the case number internally (on local variable in this class)
|
||||
*
|
||||
* @param givenCaseNumber the new case number
|
||||
*/
|
||||
private void setNumber(String givenCaseNumber) {
|
||||
caseNumber = givenCaseNumber; // change this to change the xml file if needed
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the case type internally (on local variable in this class)
|
||||
*
|
||||
* @param givenCaseType the new case type
|
||||
*/
|
||||
private void setCaseType(CaseType givenCaseType) {
|
||||
caseType = givenCaseType; // change this to change the xml file if needed
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the case Type from the document handler. Defaults to local if it
|
||||
* can't figure it out.
|
||||
*
|
||||
* @return caseType from the document handler
|
||||
*/
|
||||
public CaseType getCaseType() {
|
||||
if (doc == null) {
|
||||
return CaseType.SINGLE_USER_CASE;
|
||||
} else {
|
||||
if (getCaseElement().getElementsByTagName(CASE_TYPE).getLength() > 0) {
|
||||
Element nameElement = (Element) getCaseElement().getElementsByTagName(CASE_TYPE).item(0);
|
||||
return CaseType.fromString(nameElement.getTextContent());
|
||||
} else {
|
||||
return CaseType.SINGLE_USER_CASE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the database name internally (on local variable in this class)
|
||||
*
|
||||
* @param givenDbName the new db name
|
||||
*/
|
||||
private void setDatabaseName(String givenDbName) {
|
||||
dbName = givenDbName; // change this to change the xml file if needed
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the database name from the document handler
|
||||
*
|
||||
* @return the database name
|
||||
*/
|
||||
public String getDatabaseName() {
|
||||
if (doc == null) {
|
||||
return "";
|
||||
} else {
|
||||
if (getCaseElement().getElementsByTagName(DATABASE_NAME).getLength() > 0) {
|
||||
Element nameElement = (Element) getCaseElement().getElementsByTagName(DATABASE_NAME).item(0);
|
||||
return nameElement.getTextContent();
|
||||
} else {
|
||||
return ""; /// couldn't find one, so return a blank name
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the text index name internally (on local variable in this class)
|
||||
*
|
||||
* @param textIndexName the new name for the index where extracted text is
|
||||
* stored for the case.
|
||||
*/
|
||||
private void setTextIndexName(String textIndexName) {
|
||||
this.textIndexName = textIndexName; // change this to change the xml file if needed
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the name of the index where extracted text is stored.
|
||||
*
|
||||
* @return the index name
|
||||
*/
|
||||
public String getTextIndexName() {
|
||||
if (doc == null) {
|
||||
return "";
|
||||
} else {
|
||||
if (getCaseElement().getElementsByTagName(CASE_TEXT_INDEX_NAME).getLength() > 0) {
|
||||
Element nameElement = (Element) getCaseElement().getElementsByTagName(CASE_TEXT_INDEX_NAME).item(0);
|
||||
return nameElement.getTextContent();
|
||||
} else {
|
||||
return ""; /// couldn't find one, so return a blank index name
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the examiner name internally (on local variable in this class)
|
||||
*
|
||||
* @param givenExaminer the new examiner
|
||||
*/
|
||||
private void setExaminer(String givenExaminer) {
|
||||
examiner = givenExaminer; // change this to change the xml file if needed
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the case Name from the document handler
|
||||
*
|
||||
* @return caseName the case name from the document handler
|
||||
*/
|
||||
@Override
|
||||
public String getCaseName() {
|
||||
if (doc == null) {
|
||||
return "";
|
||||
} else {
|
||||
Element nameElement = (Element) getCaseElement().getElementsByTagName(NAME).item(0);
|
||||
String result = nameElement.getTextContent();
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the case Number from the document handler
|
||||
*
|
||||
* @return caseNumber the case number from the document handler
|
||||
*/
|
||||
@Override
|
||||
public String getCaseNumber() {
|
||||
if (doc == null) {
|
||||
return "";
|
||||
} else {
|
||||
Element numberElement = (Element) getCaseElement().getElementsByTagName(NUMBER).item(0);
|
||||
String result = "-1";
|
||||
if (numberElement != null) {
|
||||
result = numberElement.getTextContent();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the examiner from the document handler
|
||||
*
|
||||
* @return examiner the examiner from the document handler
|
||||
*/
|
||||
@Override
|
||||
public String getCaseExaminer() {
|
||||
if (doc == null) {
|
||||
return "";
|
||||
} else {
|
||||
Element examinerElement = (Element) getCaseElement().getElementsByTagName(EXAMINER).item(0);
|
||||
String result = "";
|
||||
if (examinerElement != null) {
|
||||
result = examinerElement.getTextContent();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the case directory path that's stored in this class
|
||||
*
|
||||
* @return caseDirPath the case directory path
|
||||
*/
|
||||
public String getCaseDirectory() {
|
||||
if (doc == null) {
|
||||
return "";
|
||||
} else {
|
||||
return caseDirPath;
|
||||
}
|
||||
// Note: change this to get the case name from the xml file if needed
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the Root Element from the document handler
|
||||
*
|
||||
* @return rootElement the root element on the document handler
|
||||
*/
|
||||
private Element getRootElement() {
|
||||
if (doc != null) {
|
||||
return doc.getDocumentElement();
|
||||
} else {
|
||||
return null; // should throw error or exception
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the created Date from the document handler
|
||||
*
|
||||
* @return createdDate the creation date of this case
|
||||
*/
|
||||
public String getCreatedDate() {
|
||||
if (doc != null) {
|
||||
Element crDateElement = (Element) getRootElement().getElementsByTagName(CREATED_DATE_NAME).item(0);
|
||||
return crDateElement.getTextContent();
|
||||
} else {
|
||||
return ""; // should throw error or exception
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the Modified Date from the document handler
|
||||
*
|
||||
* @return modifiedDate the modification date of this case
|
||||
*/
|
||||
protected String getModifiedDate() {
|
||||
if (doc != null) {
|
||||
Element mDateElement = (Element) getRootElement().getElementsByTagName(MODIFIED_DATE_NAME).item(0);
|
||||
return mDateElement.getTextContent();
|
||||
} else {
|
||||
return ""; // should throw error or exception
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the Autopsy Created Version from the document handler
|
||||
*
|
||||
* @return createdVersion the version of autopsy when this case was created
|
||||
*/
|
||||
protected String getCreatedVersion() {
|
||||
if (doc != null) {
|
||||
Element crVerElement = (Element) getRootElement().getElementsByTagName(AUTOPSY_CRVERSION_NAME).item(0);
|
||||
return crVerElement.getTextContent();
|
||||
} else {
|
||||
return ""; // should throw error or exception
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the Autopsy Saved Version from the document handler
|
||||
*
|
||||
* @return savedVersion the latest version of autopsy when this case is
|
||||
* saved
|
||||
*/
|
||||
protected String getSavedVersion() {
|
||||
if (doc != null) {
|
||||
Element mVerElement = (Element) getRootElement().getElementsByTagName(AUTOPSY_MVERSION_NAME).item(0);
|
||||
return mVerElement.getTextContent();
|
||||
} else {
|
||||
return ""; // should throw error or exception
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the Schema Version from the document handler
|
||||
*
|
||||
* @return schemaVersion the schema version of this XML configuration file
|
||||
*/
|
||||
protected String getSchemaVersion() {
|
||||
if (doc != null) {
|
||||
Element schemaVerElement = (Element) getRootElement().getElementsByTagName(SCHEMA_VERSION_NAME).item(0);
|
||||
return schemaVerElement.getTextContent();
|
||||
} else {
|
||||
return ""; // should throw error or exception
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the Case Element from the document handler
|
||||
*
|
||||
* @return caseElement the "Case" element
|
||||
*/
|
||||
private Element getCaseElement() {
|
||||
if (doc != null) {
|
||||
return (Element) doc.getElementsByTagName(CASE_ROOT_NAME).item(0);
|
||||
} else {
|
||||
return null; // should throw error or exception
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the full path to the log directory
|
||||
*
|
||||
* @return logDir the full path of the "Log" directory
|
||||
*/
|
||||
protected String getLogDir() {
|
||||
if (doc != null) {
|
||||
Element logElement = (Element) getCaseElement().getElementsByTagName(LOG_FOLDER_NAME).item(0);
|
||||
if (logElement.getAttribute(RELATIVE_NAME).equals(RELATIVE_TRUE)) {
|
||||
return caseDirPath + File.separator + logElement.getTextContent();
|
||||
} else {
|
||||
return logElement.getTextContent();
|
||||
}
|
||||
} else {
|
||||
return ""; // should throw error or exception
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the full path to the temp directory
|
||||
*
|
||||
* @return tempDir the full path of the "Temp" directory
|
||||
*/
|
||||
protected String getTempDir() {
|
||||
if (doc != null) {
|
||||
Element tempElement = (Element) getCaseElement().getElementsByTagName(TEMP_FOLDER_NAME).item(0);
|
||||
if (tempElement.getAttribute(RELATIVE_NAME).equals(RELATIVE_TRUE)) {
|
||||
return caseDirPath + File.separator + tempElement.getTextContent();
|
||||
} else {
|
||||
return tempElement.getTextContent();
|
||||
}
|
||||
} else {
|
||||
return ""; // should throw error or exception
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the full path to the Export directory
|
||||
*
|
||||
* @return exportDir the full path of the "Export" directory
|
||||
*/
|
||||
protected String getExportDir() {
|
||||
if (doc != null) {
|
||||
Element exportElement = (Element) getCaseElement().getElementsByTagName(EXPORT_FOLDER_NAME).item(0);
|
||||
if (exportElement.getAttribute(RELATIVE_NAME).equals(RELATIVE_TRUE)) {
|
||||
return caseDirPath + File.separator + exportElement.getTextContent();
|
||||
} else {
|
||||
return exportElement.getTextContent();
|
||||
}
|
||||
} else {
|
||||
return ""; // should throw error or exception
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the full path to the Cache directory
|
||||
*
|
||||
* @return cacheDir the full path of the "Cache" directory
|
||||
*/
|
||||
protected String getCacheDir() {
|
||||
if (doc != null) {
|
||||
Element cacheElement = (Element) getCaseElement().getElementsByTagName(CACHE_FOLDER_NAME).item(0);
|
||||
if (cacheElement.getAttribute(RELATIVE_NAME).equals(RELATIVE_TRUE)) {
|
||||
return caseDirPath + File.separator + cacheElement.getTextContent();
|
||||
} else {
|
||||
return cacheElement.getTextContent();
|
||||
}
|
||||
} else {
|
||||
return ""; // should throw error or exception
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize the basic values for a new case management file. Note: this is
|
||||
* the schema version 1.0
|
||||
*
|
||||
* @param dirPath case directory path
|
||||
* @param caseName the name of the config file to be located in the
|
||||
* case directory
|
||||
* @param examiner examiner for the case (optional, can be empty string
|
||||
* @param caseNumber case number (optional), can be empty
|
||||
* @param dbName the name of the database. Could be a local path,
|
||||
* could be a Postgre db name.
|
||||
* @param textIndexName The name of the index where extracted text is
|
||||
* stored.
|
||||
*/
|
||||
public void create(String dirPath, String caseName, String examiner, String caseNumber, CaseType caseType, String dbName, String textIndexName) throws CaseActionException {
|
||||
clear(); // clear the previous data
|
||||
|
||||
// set the case Name and Directory and the parent directory
|
||||
setCaseDirPath(dirPath);
|
||||
setName(caseName);
|
||||
setExaminer(examiner);
|
||||
setNumber(caseNumber);
|
||||
setCaseType(caseType);
|
||||
setDatabaseName(dbName);
|
||||
setTextIndexName(textIndexName);
|
||||
DocumentBuilder docBuilder;
|
||||
DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
|
||||
|
||||
// throw an error here
|
||||
try {
|
||||
docBuilder = docFactory.newDocumentBuilder();
|
||||
} catch (ParserConfigurationException ex) {
|
||||
clear();
|
||||
throw new CaseActionException(
|
||||
NbBundle.getMessage(this.getClass(), "XMLCaseManagement.create.exception.msg"), ex);
|
||||
}
|
||||
|
||||
doc = docBuilder.newDocument();
|
||||
Element rootElement = doc.createElement(TOP_ROOT_NAME); // <AutopsyCase> ... </AutopsyCase>
|
||||
doc.appendChild(rootElement);
|
||||
|
||||
Element crDateElement = doc.createElement(CREATED_DATE_NAME); // <CreatedDate> ... </CreatedDate>
|
||||
crDateElement.appendChild(doc.createTextNode(dateFormat.format(new Date())));
|
||||
rootElement.appendChild(crDateElement);
|
||||
|
||||
Element mDateElement = doc.createElement(MODIFIED_DATE_NAME); // <ModifedDate> ... </ModifedDate>
|
||||
mDateElement.appendChild(doc.createTextNode(dateFormat.format(new Date())));
|
||||
rootElement.appendChild(mDateElement);
|
||||
|
||||
Element autVerElement = doc.createElement(AUTOPSY_CRVERSION_NAME); // <AutopsyVersion> ... </AutopsyVersion>
|
||||
autVerElement.appendChild(doc.createTextNode(autopsySavedVersion));
|
||||
rootElement.appendChild(autVerElement);
|
||||
|
||||
Element autSavedVerElement = doc.createElement(AUTOPSY_MVERSION_NAME); // <AutopsySavedVersion> ... </AutopsySavedVersion>
|
||||
autSavedVerElement.appendChild(doc.createTextNode(autopsySavedVersion));
|
||||
rootElement.appendChild(autSavedVerElement);
|
||||
|
||||
Element schVerElement = doc.createElement(SCHEMA_VERSION_NAME); // <SchemaVersion> ... </SchemaVersion>
|
||||
schVerElement.appendChild(doc.createTextNode(schemaVersion));
|
||||
rootElement.appendChild(schVerElement);
|
||||
|
||||
Element caseElement = doc.createElement(CASE_ROOT_NAME); // <Case> ... </Case>
|
||||
rootElement.appendChild(caseElement);
|
||||
|
||||
Element nameElement = doc.createElement(NAME); // <Name> ... </Name>
|
||||
nameElement.appendChild(doc.createTextNode(caseName));
|
||||
caseElement.appendChild(nameElement);
|
||||
|
||||
Element numberElement = doc.createElement(NUMBER); // <Number> ... </Number>
|
||||
numberElement.appendChild(doc.createTextNode(String.valueOf(caseNumber)));
|
||||
caseElement.appendChild(numberElement);
|
||||
|
||||
Element examinerElement = doc.createElement(EXAMINER); // <Examiner> ... </Examiner>
|
||||
examinerElement.appendChild(doc.createTextNode(examiner));
|
||||
caseElement.appendChild(examinerElement);
|
||||
|
||||
Element exportElement = doc.createElement(EXPORT_FOLDER_NAME); // <ExportFolder> ... </ExportFolder>
|
||||
exportElement.appendChild(doc.createTextNode(EXPORT_FOLDER_RELPATH));
|
||||
exportElement.setAttribute(RELATIVE_NAME, "true"); //NON-NLS
|
||||
caseElement.appendChild(exportElement);
|
||||
|
||||
Element logElement = doc.createElement(LOG_FOLDER_NAME); // <LogFolder> ... </LogFolder>
|
||||
logElement.appendChild(doc.createTextNode(LOG_FOLDER_RELPATH));
|
||||
logElement.setAttribute(RELATIVE_NAME, "true"); //NON-NLS
|
||||
caseElement.appendChild(logElement);
|
||||
|
||||
Element tempElement = doc.createElement(TEMP_FOLDER_NAME); // <TempFolder> ... </TempFolder>
|
||||
tempElement.appendChild(doc.createTextNode(TEMP_FOLDER_RELPATH));
|
||||
tempElement.setAttribute(RELATIVE_NAME, "true"); //NON-NLS
|
||||
caseElement.appendChild(tempElement);
|
||||
|
||||
Element cacheElement = doc.createElement(CACHE_FOLDER_NAME); // <CacheFolder> ... </CacheFolder>
|
||||
cacheElement.appendChild(doc.createTextNode(CACHE_FOLDER_RELPATH));
|
||||
cacheElement.setAttribute(RELATIVE_NAME, "true"); //NON-NLS
|
||||
caseElement.appendChild(cacheElement);
|
||||
|
||||
Element typeElement = doc.createElement(CASE_TYPE); // <CaseType> ... </CaseType>
|
||||
typeElement.appendChild(doc.createTextNode(caseType.toString()));
|
||||
caseElement.appendChild(typeElement);
|
||||
|
||||
Element dbNameElement = doc.createElement(DATABASE_NAME); // <DatabaseName> ... </DatabaseName>
|
||||
dbNameElement.appendChild(doc.createTextNode(dbName));
|
||||
caseElement.appendChild(dbNameElement);
|
||||
|
||||
Element indexNameElement = doc.createElement(CASE_TEXT_INDEX_NAME); // <TextIndexName> ... </TextIndexName>
|
||||
indexNameElement.appendChild(doc.createTextNode(textIndexName));
|
||||
caseElement.appendChild(indexNameElement);
|
||||
|
||||
// write more code if needed ...
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes the case management file to disk (from document handler to .aut
|
||||
* file)
|
||||
*
|
||||
*/
|
||||
@Override
|
||||
public void writeFile() throws CaseActionException {
|
||||
if (doc == null || caseName.equals("")) {
|
||||
throw new CaseActionException(
|
||||
NbBundle.getMessage(this.getClass(), "XMLCaseManagement.writeFile.exception.noCase.msg"));
|
||||
}
|
||||
|
||||
// Prepare the DOM document for writing
|
||||
Source source = new DOMSource(doc);
|
||||
|
||||
// Prepare the data for the output file
|
||||
StringWriter sw = new StringWriter();
|
||||
Result result = new StreamResult(sw);
|
||||
|
||||
// Write the DOM document to the file
|
||||
Transformer xformer;// = TransformerFactory.newInstance().newTransformer();
|
||||
TransformerFactory tfactory = TransformerFactory.newInstance();
|
||||
|
||||
try {
|
||||
xformer = tfactory.newTransformer();
|
||||
} catch (TransformerConfigurationException ex) {
|
||||
logger.log(Level.SEVERE, "Could not setup tranformer and write case file"); //NON-NLS
|
||||
throw new CaseActionException(
|
||||
NbBundle.getMessage(this.getClass(), "XMLCaseManagement.writeFile.exception.errWriteToFile.msg"), ex);
|
||||
}
|
||||
|
||||
//Setup indenting to "pretty print"
|
||||
xformer.setOutputProperty(OutputKeys.INDENT, "yes"); //NON-NLS
|
||||
xformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "2"); //NON-NLS
|
||||
|
||||
try {
|
||||
xformer.transform(source, result);
|
||||
} catch (TransformerException ex) {
|
||||
logger.log(Level.SEVERE, "Could not run tranformer and write case file"); //NON-NLS
|
||||
throw new CaseActionException(
|
||||
NbBundle.getMessage(this.getClass(), "XMLCaseManagement.writeFile.exception.errWriteToFile.msg"), ex);
|
||||
}
|
||||
|
||||
// preparing the output file
|
||||
String xmlString = sw.toString();
|
||||
File file = new File(caseDirPath + File.separator + caseName + ".aut");
|
||||
|
||||
// write the file
|
||||
try {
|
||||
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file)));
|
||||
bw.write(xmlString);
|
||||
bw.flush();
|
||||
bw.close();
|
||||
} catch (IOException ex) {
|
||||
logger.log(Level.SEVERE, "Error writing to case file"); //NON-NLS
|
||||
throw new CaseActionException(
|
||||
NbBundle.getMessage(this.getClass(), "XMLCaseManagement.writeFile.exception.errWriteToFile.msg"), ex);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Opens the configuration file and load the document handler Note: this is
|
||||
* for the schema version 1.0
|
||||
*
|
||||
* @param conFilePath the path of the XML case configuration file path
|
||||
*/
|
||||
@Override
|
||||
public void open(String conFilePath) throws CaseActionException {
|
||||
clear();
|
||||
File file = new File(conFilePath);
|
||||
|
||||
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
|
||||
DocumentBuilder db;
|
||||
try {
|
||||
db = dbf.newDocumentBuilder();
|
||||
doc = db.parse(file);
|
||||
} catch (ParserConfigurationException | SAXException | IOException ex) {
|
||||
throw new CaseActionException(
|
||||
NbBundle.getMessage(this.getClass(), "XMLCaseManagement.open.exception.errReadXMLFile.msg",
|
||||
conFilePath), ex);
|
||||
}
|
||||
|
||||
doc.getDocumentElement().normalize();
|
||||
doc.getDocumentElement().normalize();
|
||||
|
||||
// TODO: Restore later
|
||||
// if (!XMLUtil.xmlIsValid(doc, XMLCaseManagement.class, XSDFILE)) {
|
||||
// logger.log(Level.WARNING, "Could not validate against [" + XSDFILE + "], results may not accurate"); //NON-NLS
|
||||
// }
|
||||
Element rootEl = doc.getDocumentElement();
|
||||
String rootName = rootEl.getNodeName();
|
||||
|
||||
// check if it's the autopsy case, if not, throws an error
|
||||
if (!rootName.equals(TOP_ROOT_NAME)) {
|
||||
// throw an error ...
|
||||
clear();
|
||||
if (RuntimeProperties.coreComponentsAreActive()) {
|
||||
|
||||
JOptionPane.showMessageDialog(caller,
|
||||
NbBundle.getMessage(this.getClass(),
|
||||
"XMLCaseManagement.open.msgDlg.notAutCase.msg",
|
||||
file.getName(), className),
|
||||
NbBundle.getMessage(this.getClass(),
|
||||
"XMLCaseManagement.open.msgDlg.notAutCase.title"),
|
||||
JOptionPane.ERROR_MESSAGE);
|
||||
}
|
||||
} else {
|
||||
/*
|
||||
* Autopsy Created Version
|
||||
*/
|
||||
String createdVersion = getCreatedVersion(); // get the created version
|
||||
|
||||
// check if it has the same autopsy version as the current one
|
||||
if (!createdVersion.equals(autopsySavedVersion)) {
|
||||
// if not the same version, update the saved version in the xml to the current version
|
||||
getRootElement().getElementsByTagName(AUTOPSY_MVERSION_NAME).item(0).setTextContent(autopsySavedVersion);
|
||||
}
|
||||
|
||||
/*
|
||||
* Schema Version
|
||||
*/
|
||||
String schemaVer = getSchemaVersion();
|
||||
// check if it has the same schema version as the current one
|
||||
if (!schemaVer.equals(schemaVersion)) {
|
||||
// do something here if not the same version
|
||||
// ... @Override
|
||||
}
|
||||
|
||||
// set the case Directory and Name
|
||||
setCaseDirPath(file.getParent());
|
||||
String fullFileName = file.getName();
|
||||
String fileName = fullFileName.substring(0, fullFileName.lastIndexOf(".")); // remove the extension
|
||||
setName(fileName);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* When user wants to close the case. This method writes any changes to the
|
||||
* XML case configuration file, closes it and the document handler, and
|
||||
* clears all the local variables / fields.
|
||||
*
|
||||
*/
|
||||
@Override
|
||||
public void close() throws CaseActionException {
|
||||
writeFile(); // write any changes to xml
|
||||
clear();
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear the internal structures / variables
|
||||
*/
|
||||
private void clear() {
|
||||
doc = null;
|
||||
caseDirPath = "";
|
||||
caseName = "";
|
||||
caseNumber = "";
|
||||
examiner = "";
|
||||
caseType = CaseType.SINGLE_USER_CASE;
|
||||
dbName = "";
|
||||
textIndexName = "";
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* Sleuth Kit Data Model
|
||||
*
|
||||
* Copyright 2011-2015 Basis Technology Corp.
|
||||
* Copyright 2011-2016 Basis Technology Corp.
|
||||
* Contact: carrier <at> sleuthkit <dot> org
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
@@ -21,7 +21,6 @@ package org.sleuthkit.autopsy.casemodule.services;
|
||||
import java.io.Closeable;
|
||||
import java.io.IOException;
|
||||
import org.openide.util.Lookup;
|
||||
import org.openide.util.NbBundle;
|
||||
import org.sleuthkit.autopsy.casemodule.Case;
|
||||
import org.sleuthkit.autopsy.keywordsearchservice.KeywordSearchService;
|
||||
import org.sleuthkit.datamodel.BlackboardArtifact;
|
||||
@@ -30,87 +29,102 @@ import org.sleuthkit.datamodel.TskCoreException;
|
||||
import org.sleuthkit.datamodel.TskDataException;
|
||||
|
||||
/**
|
||||
* Provides utility methods for blackboard artifact indexing.
|
||||
* Represents the blackboard, a place where artifacts and their attributes are
|
||||
* posted.
|
||||
*
|
||||
* NOTE: This API of this class is under development.
|
||||
*/
|
||||
public final class Blackboard implements Closeable {
|
||||
|
||||
/**
|
||||
* Index the text associated with the given artifact.
|
||||
* Indexes the text associated with the an artifact.
|
||||
*
|
||||
* @param artifact The artifact to be indexed.
|
||||
*
|
||||
* @throws
|
||||
* org.sleuthkit.autopsy.casemodule.services.Blackboard.BlackboardException
|
||||
* @throws BlackboardException If there is a problem indexing the artifact.
|
||||
*/
|
||||
public void indexArtifact(BlackboardArtifact artifact) throws BlackboardException {
|
||||
KeywordSearchService searchService = Lookup.getDefault().lookup(KeywordSearchService.class);
|
||||
if (null == searchService) {
|
||||
throw new BlackboardException(NbBundle.getMessage(this.getClass(), "Blackboard.keywordSearchNotFound.exception.msg"));
|
||||
throw new BlackboardException("Keyword search service not found");
|
||||
}
|
||||
|
||||
try {
|
||||
searchService.indexArtifact(artifact);
|
||||
} catch (TskCoreException ex) {
|
||||
throw new BlackboardException(NbBundle.getMessage(this.getClass(), "Blackboard.unableToIndexArtifact.exception.msg"), ex);
|
||||
throw new BlackboardException("Error indexing artifact", ex);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a new artifact type based upon the parameters given
|
||||
* Gets an artifact type, creating it if it does not already exist. Use this
|
||||
* method to define custom artifact types.
|
||||
*
|
||||
* @param typeName The name of the new artifact type
|
||||
* @param displayName The name displayed for the new attribute type
|
||||
* @return A type object representing the artifact type added
|
||||
* @throws
|
||||
* org.sleuthkit.autopsy.casemodule.services.Blackboard.BlackboardException
|
||||
* @param typeName The type name of the artifact type.
|
||||
* @param displayName The display name of the artifact type.
|
||||
*
|
||||
* @return A type object representing the artifact type.
|
||||
*
|
||||
* @throws BlackboardBlackboardException If there is a problem getting or
|
||||
* adding the artifact type.
|
||||
*/
|
||||
public BlackboardArtifact.Type addArtifactType(String typeName, String displayName) throws BlackboardException {
|
||||
public BlackboardArtifact.Type getOrAddArtifactType(String typeName, String displayName) throws BlackboardException {
|
||||
try {
|
||||
return Case.getCurrentCase().getSleuthkitCase().addBlackboardArtifactType(typeName, displayName);
|
||||
} catch (TskCoreException | TskDataException ex) {
|
||||
throw new BlackboardException("New artifact type could not be added", ex);
|
||||
} catch (TskDataException typeExistsEx) {
|
||||
try {
|
||||
return Case.getCurrentCase().getSleuthkitCase().getArtifactType(typeName);
|
||||
} catch (TskCoreException ex) {
|
||||
throw new BlackboardException("Failed to get or add artifact type", ex);
|
||||
}
|
||||
} catch (TskCoreException ex) {
|
||||
throw new BlackboardException("Failed to get or add artifact type", ex);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a new attribute type based upon the parameters given
|
||||
* Gets an attribute type, creating it if it does not already exist. Use
|
||||
* this method to define custom attribute types.
|
||||
*
|
||||
* @param attrTypeString The type name of the attribute type
|
||||
* @param valueType The type of any attribute of this type's value
|
||||
* @param displayName The name displayed for the new attribute type
|
||||
* @throws
|
||||
* org.sleuthkit.autopsy.casemodule.services.Blackboard.BlackboardException
|
||||
* @param typeName The type name of the attribute type.
|
||||
* @param valueType The value type of the attribute type.
|
||||
* @param displayName The display name of the attribute type.
|
||||
*
|
||||
* @return A type object representing the attribute type.
|
||||
*
|
||||
* @throws BlackboardBlackboardException If there is a problem getting or
|
||||
* adding the attribute type.
|
||||
*/
|
||||
public BlackboardAttribute.Type addAttributeType(String attrTypeString, BlackboardAttribute.TSK_BLACKBOARD_ATTRIBUTE_VALUE_TYPE valueType, String displayName) throws BlackboardException {
|
||||
public BlackboardAttribute.Type getOrAddAttributeType(String typeName, BlackboardAttribute.TSK_BLACKBOARD_ATTRIBUTE_VALUE_TYPE valueType, String displayName) throws BlackboardException {
|
||||
try {
|
||||
return Case.getCurrentCase().getSleuthkitCase().addArtifactAttributeType(attrTypeString, valueType, displayName);
|
||||
} catch (TskDataException ex) {
|
||||
throw new BlackboardException("New attribute type could not be added", ex);
|
||||
return Case.getCurrentCase().getSleuthkitCase().addArtifactAttributeType(typeName, valueType, displayName);
|
||||
} catch (TskDataException typeExistsEx) {
|
||||
try {
|
||||
return Case.getCurrentCase().getSleuthkitCase().getAttributeType(typeName);
|
||||
} catch (TskCoreException ex) {
|
||||
throw new BlackboardException("Failed to get or add attribute type", ex);
|
||||
}
|
||||
} catch (TskCoreException ex) {
|
||||
throw new BlackboardException("New attribute type could not be added", ex);
|
||||
throw new BlackboardException("Failed to get or add attribute type", ex);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Cloese this blackboard and releases any resources associated with it.
|
||||
* @throws IOException
|
||||
*/
|
||||
@Override
|
||||
public void close() throws IOException {
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides a system exception for the Keyword Search package.
|
||||
* A blackboard exception.
|
||||
*/
|
||||
public static final class BlackboardException extends Exception {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* Constructs a new exception with null as its message.
|
||||
*/
|
||||
public BlackboardException() {
|
||||
super();
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new exception with the specified message.
|
||||
* Constructs a blackboard exception with the specified message.
|
||||
*
|
||||
* @param message The message.
|
||||
*/
|
||||
@@ -119,10 +133,11 @@ public final class Blackboard implements Closeable {
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new exception with the specified message and cause.
|
||||
* Constructs a blackboard exception with the specified message and
|
||||
* cause.
|
||||
*
|
||||
* @param message The message.
|
||||
* @param cause The cause.
|
||||
* @param cause The cause.
|
||||
*/
|
||||
public BlackboardException(String message, Throwable cause) {
|
||||
super(message, cause);
|
||||
|
||||
@@ -19,6 +19,4 @@ TagsManager.addContentTag.noCaseWarning=Failed to publish new content tag event.
|
||||
TagsManager.deleteContentTag.noCaseWarning=Failed to publish content tag deleted event. There is no case open.
|
||||
TagsManager.addBlackboardArtifactTag.noCaseWarning=Failed to publish new blackboard artifact tag event. There is no case open.
|
||||
TagsManager.deleteBlackboardArtifactTag.noCaseWarning=Failed to publish blackboard artifact tag deleted event. There is no case open.
|
||||
Blackboard.keywordSearchNotFound.exception.msg=Keyword search service not found.
|
||||
Blackboard.unableToIndexArtifact.exception.msg=Unable to index blackboard artifact
|
||||
Blackboard.unableToIndexArtifact.error.msg=Unable to index blackboard artifact {0}
|
||||
|
||||
@@ -1,24 +1,22 @@
|
||||
FileManager.findFiles.exception.msg=FileManager\u3092\u9589\u3058\u305F\u5F8C\u306B\u4F7F\u7528\u3092\u8A66\u307F\u307E\u3057\u305F\u3002
|
||||
FileManager.findFiles2.exception.msg=FileManager\u3092\u9589\u3058\u305F\u5F8C\u306B\u4F7F\u7528\u3092\u8A66\u307F\u307E\u3057\u305F\u3002
|
||||
FileManager.findFiles3.exception.msg=FileManager\u3092\u9589\u3058\u305F\u5F8C\u306B\u4F7F\u7528\u3092\u8A66\u307F\u307E\u3057\u305F\u3002
|
||||
FileManager.openFiles.exception.msg=FileManager\u3092\u9589\u3058\u305F\u5F8C\u306B\u4F7F\u7528\u3092\u8A66\u307F\u307E\u3057\u305F\u3002
|
||||
FileManager.addDerivedFile.exception.msg=FileManager\u3092\u9589\u3058\u305F\u5F8C\u306B\u4F7F\u7528\u3092\u8A66\u307F\u307E\u3057\u305F\u3002
|
||||
FileManager.addCarvedFile.exception.msg=FileManager\u3092\u9589\u3058\u305F\u5F8C\u306B\u4F7F\u7528\u3092\u8A66\u307F\u307E\u3057\u305F\u3002
|
||||
FileManager.addLocalFilesDirs.exception.notReadable.msg=\u8FFD\u52A0\u3059\u308B\u30ED\u30FC\u30AB\u30EB\u30D5\u30A1\u30A4\u30EB\uFF0F\u30C7\u30A3\u30EC\u30AF\u30C8\u30EA\u306E\u4E2D\u306B\u8AAD\u307F\u53D6\u308C\u306A\u3044\u3082\u306E\u304C\uFF11\u500B\u3042\u308A\u307E\u3059\uFF1A{0}\u3001\u30D5\u30A1\u30A4\u30EB\u304C\u8FFD\u52A0\u3055\u308C\u308B\u524D\u306B\u51E6\u7406\u3092\u4E2D\u6B62\u3057\u307E\u3059
|
||||
FileManager.addLocalFilesDirs.exception.cantAdd.msg=\u30ED\u30FC\u30AB\u30EB\u30D5\u30A1\u30A4\u30EB\uFF0F\u30C7\u30A3\u30EC\u30AF\u30C8\u30EA\u306E\uFF11\u500B\u306F\u8FFD\u52A0\u3067\u304D\u307E\u305B\u3093\u3067\u3057\u305F\uFF1A{0}
|
||||
FileManager.addLocalFileSetRootDir.exception.errCreateDir.msg=\u30ED\u30FC\u30AB\u30EB\u30D5\u30A1\u30A4\u30EB\u30BB\u30C3\u30C8\u30C7\u30A3\u30EC\u30AF\u30C8\u30EA\u3092\u4F5C\u6210\u4E2D\u306B\u30A8\u30E9\u30FC\u304C\u8D77\u3053\u308A\u307E\u3057\u305F\uFF1A {0}
|
||||
FileManager.addLocalDirInt.exception.closed.msg=FileManager\u3092\u9589\u3058\u305F\u5F8C\u306B\u4F7F\u7528\u3092\u8A66\u307F\u307E\u3057\u305F\u3002
|
||||
FileManager.addLocalDirInt.exception.doesntExist.msg=\u5B58\u5728\u3057\u306A\u3044\u30ED\u30FC\u30AB\u30EB\u30C7\u30A3\u30EC\u30AF\u30C8\u30EA\u306E\u8FFD\u52A0\u3092\u8A66\u307F\u307E\u3057\u305F\: {0}
|
||||
FileManager.addLocalDirInt.exception.notReadable.msg=\u8AAD\u307F\u53D6\u308A\u3067\u304D\u306A\u3044\u30ED\u30FC\u30AB\u30EB\u30C7\u30A3\u30EC\u30AF\u30C8\u30EA\u306E\u8FFD\u52A0\u3092\u8A66\u307F\u307E\u3057\u305F\: {0}
|
||||
FileManager.addLocalDirInt2.exception.closed.msg=FileManager\u3092\u9589\u3058\u305F\u5F8C\u306B\u4F7F\u7528\u3092\u8A66\u307F\u307E\u3057\u305F\u3002
|
||||
TagsManager.addContentTag.exception.beginByteOffsetOOR.msg=beginByteOffset \= {0} \u30B3\u30F3\u30C6\u30F3\u30C4\u30B5\u30A4\u30BA\u7BC4\u56F2(0 - {1})\u306E\u5916\u3067\u3059
|
||||
TagsManager.addContentTag.exception.endByteOffsetOOR.msg=endByteOffset \= {0} \u30B3\u30F3\u30C6\u30F3\u30C4\u30B5\u30A4\u30BA\u7BC4\u56F2(0 - {1})\u306E\u5916\u3067\u3059
|
||||
FileManager.findFiles.exception.msg=FileManager\u3092\u9589\u3058\u305f\u5f8c\u306b\u4f7f\u7528\u3092\u8a66\u307f\u307e\u3057\u305f\u3002
|
||||
FileManager.findFiles2.exception.msg=FileManager\u3092\u9589\u3058\u305f\u5f8c\u306b\u4f7f\u7528\u3092\u8a66\u307f\u307e\u3057\u305f\u3002
|
||||
FileManager.findFiles3.exception.msg=FileManager\u3092\u9589\u3058\u305f\u5f8c\u306b\u4f7f\u7528\u3092\u8a66\u307f\u307e\u3057\u305f\u3002
|
||||
FileManager.openFiles.exception.msg=FileManager\u3092\u9589\u3058\u305f\u5f8c\u306b\u4f7f\u7528\u3092\u8a66\u307f\u307e\u3057\u305f\u3002
|
||||
FileManager.addDerivedFile.exception.msg=FileManager\u3092\u9589\u3058\u305f\u5f8c\u306b\u4f7f\u7528\u3092\u8a66\u307f\u307e\u3057\u305f\u3002
|
||||
FileManager.addCarvedFile.exception.msg=FileManager\u3092\u9589\u3058\u305f\u5f8c\u306b\u4f7f\u7528\u3092\u8a66\u307f\u307e\u3057\u305f\u3002
|
||||
FileManager.addLocalFilesDirs.exception.notReadable.msg=\u8ffd\u52a0\u3059\u308b\u30ed\u30fc\u30ab\u30eb\u30d5\u30a1\u30a4\u30eb\uff0f\u30c7\u30a3\u30ec\u30af\u30c8\u30ea\u306e\u4e2d\u306b\u8aad\u307f\u53d6\u308c\u306a\u3044\u3082\u306e\u304c\uff11\u500b\u3042\u308a\u307e\u3059\uff1a{0}\u3001\u30d5\u30a1\u30a4\u30eb\u304c\u8ffd\u52a0\u3055\u308c\u308b\u524d\u306b\u51e6\u7406\u3092\u4e2d\u6b62\u3057\u307e\u3059
|
||||
FileManager.addLocalFilesDirs.exception.cantAdd.msg=\u30ed\u30fc\u30ab\u30eb\u30d5\u30a1\u30a4\u30eb\uff0f\u30c7\u30a3\u30ec\u30af\u30c8\u30ea\u306e\uff11\u500b\u306f\u8ffd\u52a0\u3067\u304d\u307e\u305b\u3093\u3067\u3057\u305f\uff1a{0}
|
||||
FileManager.addLocalFileSetRootDir.exception.errCreateDir.msg=\u30ed\u30fc\u30ab\u30eb\u30d5\u30a1\u30a4\u30eb\u30bb\u30c3\u30c8\u30c7\u30a3\u30ec\u30af\u30c8\u30ea\u3092\u4f5c\u6210\u4e2d\u306b\u30a8\u30e9\u30fc\u304c\u8d77\u3053\u308a\u307e\u3057\u305f\uff1a {0}
|
||||
FileManager.addLocalDirInt.exception.closed.msg=FileManager\u3092\u9589\u3058\u305f\u5f8c\u306b\u4f7f\u7528\u3092\u8a66\u307f\u307e\u3057\u305f\u3002
|
||||
FileManager.addLocalDirInt.exception.doesntExist.msg=\u5b58\u5728\u3057\u306a\u3044\u30ed\u30fc\u30ab\u30eb\u30c7\u30a3\u30ec\u30af\u30c8\u30ea\u306e\u8ffd\u52a0\u3092\u8a66\u307f\u307e\u3057\u305f\: {0}
|
||||
FileManager.addLocalDirInt.exception.notReadable.msg=\u8aad\u307f\u53d6\u308a\u3067\u304d\u306a\u3044\u30ed\u30fc\u30ab\u30eb\u30c7\u30a3\u30ec\u30af\u30c8\u30ea\u306e\u8ffd\u52a0\u3092\u8a66\u307f\u307e\u3057\u305f\: {0}
|
||||
FileManager.addLocalDirInt2.exception.closed.msg=FileManager\u3092\u9589\u3058\u305f\u5f8c\u306b\u4f7f\u7528\u3092\u8a66\u307f\u307e\u3057\u305f\u3002
|
||||
TagsManager.addContentTag.exception.beginByteOffsetOOR.msg=beginByteOffset \= {0} \u30b3\u30f3\u30c6\u30f3\u30c4\u30b5\u30a4\u30ba\u7bc4\u56f2(0 - {1})\u306e\u5916\u3067\u3059
|
||||
TagsManager.addContentTag.exception.endByteOffsetOOR.msg=endByteOffset \= {0} \u30b3\u30f3\u30c6\u30f3\u30c4\u30b5\u30a4\u30ba\u7bc4\u56f2(0 - {1})\u306e\u5916\u3067\u3059
|
||||
TagsManager.addContentTag.exception.endLTbegin.msg=endByteOffset < beginByteOffset
|
||||
TagsManager.predefTagNames.bookmark.text=\u30D6\u30C3\u30AF\u30DE\u30FC\u30AF
|
||||
TagsManager.addContentTag.noCaseWarning=\u65B0\u3057\u3044\u30BF\u30B0\u30A4\u30D9\u30F3\u30C8\u3092\u30D1\u30D6\u30EA\u30C3\u30B7\u30E5\u3067\u304D\u307E\u305B\u3093\u3067\u3057\u305F\u3002\u958B\u3044\u3066\u3044\u308B\u30B1\u30FC\u30B9\u304C\u3042\u308A\u307E\u305B\u3093\u3002
|
||||
TagsManager.deleteContentTag.noCaseWarning=\u524A\u9664\u3055\u308C\u305F\u30A4\u30D9\u30F3\u30C8\u306E\u30BF\u30B0\u306E\u30B3\u30F3\u30C6\u30F3\u30C4\u3092\u30D1\u30D6\u30EA\u30C3\u30B7\u30E5\u3067\u304D\u307E\u305B\u3093\u3067\u3057\u305F\u3002\u958B\u3044\u3066\u3044\u308B\u30B1\u30FC\u30B9\u304C\u3042\u308A\u307E\u305B\u3093\u3002
|
||||
TagsManager.addBlackboardArtifactTag.noCaseWarning=\u30A4\u30D9\u30F3\u30C8\u306E\u30BF\u30B0\u306E\u65B0\u3057\u3044blackboard\u30A2\u30FC\u30C6\u30A3\u30D5\u30A1\u30AF\u30C8\u3092\u30D1\u30D6\u30EA\u30C3\u30B7\u30E5\u3067\u304D\u307E\u305B\u3093\u3067\u3057\u305F\u3002\u958B\u3044\u3066\u3044\u308B\u30B1\u30FC\u30B9\u304C\u3042\u308A\u307E\u305B\u3093\u3002
|
||||
TagsManager.deleteBlackboardArtifactTag.noCaseWarning=\u524A\u9664\u3055\u308C\u305F\u30A4\u30D9\u30F3\u30C8\u306E\u30BF\u30B0\u306E\u65B0\u3057\u3044blackboard\u30A2\u30FC\u30C6\u30A3\u30D5\u30A1\u30AF\u30C8\u3092\u30D1\u30D6\u30EA\u30C3\u30B7\u30E5\u3067\u304D\u307E\u305B\u3093\u3067\u3057\u305F\u3002\u958B\u3044\u3066\u3044\u308B\u30B1\u30FC\u30B9\u304C\u3042\u308A\u307E\u305B\u3093\u3002
|
||||
Blackboard.keywordSearchNotFound.exception.msg=\u30AD\u30FC\u30EF\u30FC\u30C9\u691C\u7D22\u30B5\u30FC\u30D3\u30B9\u304C\u898B\u3064\u304B\u308A\u307E\u305B\u3093\u3067\u3057\u305F\u3002
|
||||
Blackboard.unableToIndexArtifact.exception.msg=blackboard\u30A2\u30FC\u30C6\u30A3\u30D5\u30A1\u30AF\u30C8\u3092\u30A4\u30F3\u30C7\u30C3\u30AF\u30B9\u3067\u304D\u307E\u305B\u3093\u3067\u3057\u305F\u3002
|
||||
Blackboard.unableToIndexArtifact.error.msg=blackboard\u30A2\u30FC\u30C6\u30A3\u30D5\u30A1\u30AF\u30C8{0}\u3092\u30A4\u30F3\u30C7\u30C3\u30AF\u30B9\u3067\u304D\u307E\u305B\u3093\u3067\u3057\u305F\u3002
|
||||
TagsManager.predefTagNames.bookmark.text=\u30d6\u30c3\u30af\u30de\u30fc\u30af
|
||||
TagsManager.addContentTag.noCaseWarning=\u65b0\u3057\u3044\u30bf\u30b0\u30a4\u30d9\u30f3\u30c8\u3092\u30d1\u30d6\u30ea\u30c3\u30b7\u30e5\u3067\u304d\u307e\u305b\u3093\u3067\u3057\u305f\u3002\u958b\u3044\u3066\u3044\u308b\u30b1\u30fc\u30b9\u304c\u3042\u308a\u307e\u305b\u3093\u3002
|
||||
TagsManager.deleteContentTag.noCaseWarning=\u524a\u9664\u3055\u308c\u305f\u30a4\u30d9\u30f3\u30c8\u306e\u30bf\u30b0\u306e\u30b3\u30f3\u30c6\u30f3\u30c4\u3092\u30d1\u30d6\u30ea\u30c3\u30b7\u30e5\u3067\u304d\u307e\u305b\u3093\u3067\u3057\u305f\u3002\u958b\u3044\u3066\u3044\u308b\u30b1\u30fc\u30b9\u304c\u3042\u308a\u307e\u305b\u3093\u3002
|
||||
TagsManager.addBlackboardArtifactTag.noCaseWarning=\u30a4\u30d9\u30f3\u30c8\u306e\u30bf\u30b0\u306e\u65b0\u3057\u3044blackboard\u30a2\u30fc\u30c6\u30a3\u30d5\u30a1\u30af\u30c8\u3092\u30d1\u30d6\u30ea\u30c3\u30b7\u30e5\u3067\u304d\u307e\u305b\u3093\u3067\u3057\u305f\u3002\u958b\u3044\u3066\u3044\u308b\u30b1\u30fc\u30b9\u304c\u3042\u308a\u307e\u305b\u3093\u3002
|
||||
TagsManager.deleteBlackboardArtifactTag.noCaseWarning=\u524a\u9664\u3055\u308c\u305f\u30a4\u30d9\u30f3\u30c8\u306e\u30bf\u30b0\u306e\u65b0\u3057\u3044blackboard\u30a2\u30fc\u30c6\u30a3\u30d5\u30a1\u30af\u30c8\u3092\u30d1\u30d6\u30ea\u30c3\u30b7\u30e5\u3067\u304d\u307e\u305b\u3093\u3067\u3057\u305f\u3002\u958b\u3044\u3066\u3044\u308b\u30b1\u30fc\u30b9\u304c\u3042\u308a\u307e\u305b\u3093\u3002
|
||||
Blackboard.unableToIndexArtifact.error.msg=blackboard\u30a2\u30fc\u30c6\u30a3\u30d5\u30a1\u30af\u30c8{0}\u3092\u30a4\u30f3\u30c7\u30c3\u30af\u30b9\u3067\u304d\u307e\u305b\u3093\u3067\u3057\u305f\u3002
|
||||
@@ -3,9 +3,13 @@
|
||||
<Form version="1.5" maxVersion="1.8" type="org.netbeans.modules.form.forminfo.JDialogFormInfo">
|
||||
<Properties>
|
||||
<Property name="defaultCloseOperation" type="int" value="2"/>
|
||||
<Property name="iconImage" type="java.awt.Image" editor="org.netbeans.modules.form.ComponentChooserEditor">
|
||||
<ComponentRef name="default"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<SyntheticProperties>
|
||||
<SyntheticProperty name="formSizePolicy" type="int" value="1"/>
|
||||
<SyntheticProperty name="generateCenter" type="boolean" value="false"/>
|
||||
</SyntheticProperties>
|
||||
<AuxValues>
|
||||
<AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="1"/>
|
||||
|
||||
@@ -27,7 +27,7 @@ Format_OperatingSystem_Value={0} version {1} running on {2}
|
||||
LBL_Copyright=<div style\="font-size\: 12pt; font-family\: Verdana, 'Verdana CE', Arial, 'Arial CE', 'Lucida Grande CE', lucida, 'Helvetica CE', sans-serif; ">Autopsy™ is a digital forensics platform based on The Sleuth Kit™ and other tools. <br><ul><li>General Information: <a style\="color\: \#1E2A60;" href\="http\://www.sleuthkit.org">http\://www.sleuthkit.org</a>.</li><li>Training: <a style\="color\: \#1E2A60;" href\="http://www.basistech.com/autopsy-training">http://www.basistech.com/autopsy-training</a></li><li>Commercial Support: <a style\="color\: \#1E2A60;" href\="http://www.basistech.com/digital-forensics/autopsy/support/">http://www.basistech.com/digital-forensics/autopsy/support/</a></li></ul>Copyright © 2003-2016. </div>
|
||||
URL_ON_IMG=http://www.sleuthkit.org/
|
||||
|
||||
URL_ON_HELP=http://sleuthkit.org/autopsy/docs/user-docs/4.0/
|
||||
URL_ON_HELP=http://sleuthkit.org/autopsy/docs/user-docs/4.1/
|
||||
|
||||
FILE_FOR_LOCAL_HELP=file:///
|
||||
INDEX_FOR_LOCAL_HELP=/docs/index.html
|
||||
|
||||
@@ -35,6 +35,7 @@ import org.openide.util.Lookup;
|
||||
import org.openide.windows.WindowManager;
|
||||
import org.sleuthkit.autopsy.casemodule.Case;
|
||||
import org.sleuthkit.autopsy.casemodule.CaseActionException;
|
||||
import org.sleuthkit.autopsy.casemodule.CaseMetadata;
|
||||
import org.sleuthkit.autopsy.casemodule.OpenFromArguments;
|
||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||
|
||||
@@ -78,7 +79,7 @@ public class Installer extends ModuleInstall {
|
||||
if (processor instanceof OpenFromArguments) {
|
||||
OpenFromArguments argsProcessor = (OpenFromArguments) processor;
|
||||
final String caseFile = argsProcessor.getDefaultArg();
|
||||
if (caseFile != null && !caseFile.equals("") && caseFile.endsWith(".aut") && new File(caseFile).exists()) { //NON-NLS
|
||||
if (caseFile != null && !caseFile.equals("") && caseFile.endsWith(CaseMetadata.getFileExtension()) && new File(caseFile).exists()) { //NON-NLS
|
||||
new Thread(() -> {
|
||||
try {
|
||||
Case.open(caseFile);
|
||||
|
||||
@@ -26,10 +26,12 @@ import java.util.concurrent.ExecutionException;
|
||||
import java.util.logging.Level;
|
||||
import javax.swing.SwingWorker;
|
||||
import javax.swing.Timer;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.netbeans.api.progress.ProgressHandle;
|
||||
import org.netbeans.api.progress.ProgressHandleFactory;
|
||||
import org.openide.nodes.FilterNode;
|
||||
import org.openide.nodes.Node;
|
||||
import org.openide.util.NbBundle;
|
||||
import org.sleuthkit.autopsy.coreutils.ImageUtils;
|
||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||
import org.sleuthkit.datamodel.Content;
|
||||
@@ -58,14 +60,12 @@ class ThumbnailViewNode extends FilterNode {
|
||||
|
||||
@Override
|
||||
public String getDisplayName() {
|
||||
if (super.getDisplayName().length() > 15) {
|
||||
return super.getDisplayName().substring(0, 15).concat("...");
|
||||
} else {
|
||||
return super.getDisplayName();
|
||||
}
|
||||
return StringUtils.abbreviate(super.getDisplayName(), 18);
|
||||
}
|
||||
|
||||
@Override
|
||||
@NbBundle.Messages({"# {0} - file name",
|
||||
"ThumbnailViewNode.progressHandle.text=Generating thumbnail for {0}"})
|
||||
public Image getIcon(int type) {
|
||||
Image icon = null;
|
||||
|
||||
@@ -82,7 +82,7 @@ class ThumbnailViewNode extends FilterNode {
|
||||
}
|
||||
if (swingWorker == null || swingWorker.isDone()) {
|
||||
swingWorker = new SwingWorker<Image, Object>() {
|
||||
final private ProgressHandle progressHandle = ProgressHandleFactory.createHandle("generating thumbnail for video file " + content.getName());
|
||||
final private ProgressHandle progressHandle = ProgressHandleFactory.createHandle(Bundle.ThumbnailViewNode_progressHandle_text(content.getName()));
|
||||
|
||||
@Override
|
||||
protected Image doInBackground() throws Exception {
|
||||
@@ -97,7 +97,7 @@ class ThumbnailViewNode extends FilterNode {
|
||||
iconCache = new SoftReference<>(super.get());
|
||||
fireIconChange();
|
||||
} catch (InterruptedException | ExecutionException ex) {
|
||||
Logger.getLogger(ThumbnailViewNode.class.getName()).log(Level.SEVERE, "Error getting thumbnail icon", ex); //NON-NLS
|
||||
Logger.getLogger(ThumbnailViewNode.class.getName()).log(Level.SEVERE, "Error getting thumbnail icon for " + content.getName(), ex); //NON-NLS
|
||||
} finally {
|
||||
progressHandle.finish();
|
||||
if (timer != null) {
|
||||
|
||||
@@ -90,26 +90,21 @@ public final class Logger extends java.util.logging.Logger {
|
||||
fileHandler.setFormatter(new Formatter() {
|
||||
@Override
|
||||
public String format(LogRecord record) {
|
||||
if (record.getThrown() != null) {
|
||||
String stackTrace = ""; //NON-NLS
|
||||
Throwable thrown = record.getThrown();
|
||||
String stackTrace = ""; //NON-NLS
|
||||
while (thrown != null) {
|
||||
stackTrace += thrown.toString() + "\n";
|
||||
for (StackTraceElement traceElem : record.getThrown().getStackTrace()) {
|
||||
stackTrace += "\t" + traceElem.toString() + "\n"; //NON-NLS
|
||||
}
|
||||
return (new Timestamp(record.getMillis())).toString() + " " //NON-NLS
|
||||
+ record.getSourceClassName() + " " //NON-NLS
|
||||
+ record.getSourceMethodName() + "\n" //NON-NLS
|
||||
+ record.getLevel() + ": " //NON-NLS
|
||||
+ this.formatMessage(record) + "\n" //NON-NLS
|
||||
+ record.getThrown().toString() + ":\n" //NON-NLS
|
||||
+ stackTrace
|
||||
+ "\n"; //NON-NLS
|
||||
} else {
|
||||
return (new Timestamp(record.getMillis())).toString() + " " //NON-NLS
|
||||
+ record.getSourceClassName() + " " //NON-NLS
|
||||
+ record.getSourceMethodName() + "\n" //NON-NLS
|
||||
+ record.getLevel() + ": " //NON-NLS
|
||||
+ this.formatMessage(record) + "\n"; //NON-NLS
|
||||
thrown = thrown.getCause();
|
||||
}
|
||||
return (new Timestamp(record.getMillis())).toString() + " " //NON-NLS
|
||||
+ record.getSourceClassName() + " " //NON-NLS
|
||||
+ record.getSourceMethodName() + "\n" //NON-NLS
|
||||
+ record.getLevel() + ": " //NON-NLS
|
||||
+ this.formatMessage(record) + "\n" //NON-NLS
|
||||
+ stackTrace;
|
||||
}
|
||||
});
|
||||
return fileHandler;
|
||||
|
||||
@@ -23,7 +23,7 @@ IngestJob.progress.fileIngest.displayName=Analyzing files from {0}
|
||||
IngestJob.progress.fileIngest.cancelMessage=Waiting for {0} on {1}
|
||||
IngestJob.progress.cancelling={0} (Cancelling...)
|
||||
IngestJob.cancellationDialog.title=Cancel Ingest
|
||||
IngestDialog.title.text=Ingest Modules
|
||||
IngestDialog.title.text=Run Ingest Modules
|
||||
IngestDialog.startButton.title=Start
|
||||
IngestDialog.closeButton.title=Close
|
||||
IngestManager.moduleErr=Module Error
|
||||
@@ -85,9 +85,6 @@ DataSourceIngestCancellationPanel.cancelCurrentModuleRadioButton.text=Cancel cur
|
||||
FileIngestCancellationPanel.cancelIngestJobRadioButton.text=Cancel data source ingest and file ingest
|
||||
FileIngestCancellationPanel.cancelFileIngestRadioButton.text=Cancel file ingest only
|
||||
DataSourceIngestCancellationPanel.cancelAllModulesRadioButton.text=Cancel all ingest modules
|
||||
IngestJobSettingsPanel.advancedButton.actionCommand=Advanced
|
||||
IngestJobSettingsPanel.advancedButton.text=Advanced
|
||||
IngestJobSettingsPanel.descriptionLabel.text=
|
||||
IngestProgressSnapshotPanel.SnapshotsTableModel.colNames.jobID=Job ID
|
||||
IngestJobTableModel.colName.jobID=Job ID
|
||||
IngestJobTableModel.colName.dataSource=Data Source
|
||||
@@ -117,3 +114,8 @@ IngestJob.cancelReason.ingestModStartFail.text=Ingest modules startup failed
|
||||
IngestJob.cancelReason.outOfDiskSpace.text=Out of disk space
|
||||
IngestJob.cancelReason.servicesDown.text=Services Down
|
||||
IngestJob.cancelReason.caseClosed.text=Case closed
|
||||
IngestJobSettingsPanel.globalSettingsButton.text=Global Settings
|
||||
gest
|
||||
IngestJobSettingsPanel.globalSettingsButton.actionCommand=Advanced
|
||||
IngestJobSettingsPanel.globalSettingsButton.text=Global Settings
|
||||
IngestJobSettingsPanel.descriptionLabel.text=dummmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy texxxxxxxxxxxxxxxttttttttttttttttttttttttttttttttttttttttttt
|
||||
|
||||
@@ -68,8 +68,6 @@ IngestProgressSnapshotDialog.title.text=\u30a4\u30f3\u30b8\u30a7\u30b9\u30c8\u30
|
||||
IngestProgressSnapshotPanel.closeButton.text=\u9589\u3058\u308b
|
||||
IngestProgressSnapshotPanel.refreshButton.text=\u30ea\u30d5\u30ec\u30c3\u30b7\u30e5
|
||||
IngestProgressSnapshotPanel.SnapshotsTableModel.colNames.activity=\u30a2\u30af\u30c6\u30a3\u30d3\u30c6\u30a3
|
||||
IngestJobSettingsPanel.advancedButton.actionCommand=\u30a2\u30c9\u30d0\u30f3\u30b9
|
||||
IngestJobSettingsPanel.advancedButton.text=\u30a2\u30c9\u30d0\u30f3\u30b9
|
||||
ModuleTableModel.colName.duration=\u6240\u8981\u6642\u9593
|
||||
IngestJob.cancellationDialog.title=\u30a4\u30f3\u30b8\u30a7\u30b9\u30c8\u3092\u30ad\u30e3\u30f3\u30bb\u30eb
|
||||
IngestJobSettings.missingModule.warning=\u4ee5\u524d\u306b\u8aad\u307f\u8fbc\u3093\u3060{0}\u30e2\u30b8\u30e5\u30fc\u30eb\u304c\u898b\u3064\u304b\u308a\u307e\u305b\u3093\u3067\u3057\u305f\u3002
|
||||
@@ -113,3 +111,5 @@ IngestJob.cancelReason.cancelledByUser.text=\u30e6\u30fc\u30b6\u30fc\u304c\u30ad
|
||||
IngestJob.cancelReason.ingestModStartFail.text=\u30a4\u30f3\u30b8\u30a7\u30b9\u30c8\u30e2\u30b8\u30e5\u30fc\u30eb\u306e\u8d77\u52d5\u306b\u5931\u6557
|
||||
IngestJob.cancelReason.outOfDiskSpace.text=\u30c7\u30a3\u30b9\u30af\u30b9\u30da\u30fc\u30b9\u304c\u8db3\u308a\u307e\u305b\u3093
|
||||
IngestJob.cancelReason.caseClosed.text=\u30b1\u30fc\u30b9\u3092\u9589\u3058\u307e\u3057\u305f
|
||||
IngestJobSettingsPanel.globalSettingsButton.actionCommand=\u30a2\u30c9\u30d0\u30f3\u30b9
|
||||
IngestJobSettingsPanel.globalSettingsButton.text=\u30a2\u30c9\u30d0\u30f3\u30b9
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* Autopsy Forensic Browser
|
||||
*
|
||||
* Copyright 2014 Basis Technology Corp.
|
||||
* Copyright 2011-2016 Basis Technology Corp.
|
||||
* Contact: carrier <at> sleuthkit <dot> org
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
@@ -288,7 +288,7 @@ final class DataSourceIngestJob {
|
||||
String getExecutionContext() {
|
||||
return this.settings.getExecutionContext();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Gets the data source to be ingested by this job.
|
||||
*
|
||||
@@ -379,38 +379,45 @@ final class DataSourceIngestJob {
|
||||
private List<IngestModuleError> startUpIngestPipelines() {
|
||||
List<IngestModuleError> errors = new ArrayList<>();
|
||||
|
||||
// Start up the first stage data source ingest pipeline.
|
||||
/*
|
||||
* Start the data-source-level ingest module pipelines.
|
||||
*/
|
||||
errors.addAll(this.firstStageDataSourceIngestPipeline.startUp());
|
||||
|
||||
// Start up the second stage data source ingest pipeline.
|
||||
errors.addAll(this.secondStageDataSourceIngestPipeline.startUp());
|
||||
|
||||
// Start up the file ingest pipelines (one per file ingest thread).
|
||||
for (FileIngestPipeline pipeline : this.fileIngestPipelinesQueue) {
|
||||
errors.addAll(pipeline.startUp());
|
||||
if (!errors.isEmpty()) {
|
||||
// If there are start up errors, the ingest job will not proceed
|
||||
// and the errors will ultimately be reported to the user for
|
||||
// possible remedy so shut down the pipelines now that an
|
||||
// attempt has been made to start up the data source ingest
|
||||
// pipeline and at least one copy of the file ingest pipeline.
|
||||
// pipeline. There is no need to complete starting up all of the
|
||||
// file ingest pipeline copies since any additional start up
|
||||
// errors are likely redundant.
|
||||
while (!this.fileIngestPipelinesQueue.isEmpty()) {
|
||||
pipeline = this.fileIngestPipelinesQueue.poll();
|
||||
if (pipeline.isRunning()) {
|
||||
List<IngestModuleError> shutDownErrors = pipeline.shutDown();
|
||||
if (!shutDownErrors.isEmpty()) {
|
||||
logIngestModuleErrors(shutDownErrors);
|
||||
/*
|
||||
* If the data-source-level ingest pipelines were successfully started,
|
||||
* start the Start the file-level ingest pipelines (one per file ingest
|
||||
* thread).
|
||||
*/
|
||||
if (errors.isEmpty()) {
|
||||
for (FileIngestPipeline pipeline : this.fileIngestPipelinesQueue) {
|
||||
errors.addAll(pipeline.startUp());
|
||||
if (!errors.isEmpty()) {
|
||||
/*
|
||||
* If there are start up errors, the ingest job will not
|
||||
* proceed, so shut down any file ingest pipelines that did
|
||||
* start up.
|
||||
*/
|
||||
while (!this.fileIngestPipelinesQueue.isEmpty()) {
|
||||
FileIngestPipeline startedPipeline = this.fileIngestPipelinesQueue.poll();
|
||||
if (startedPipeline.isRunning()) {
|
||||
List<IngestModuleError> shutDownErrors = startedPipeline.shutDown();
|
||||
if (!shutDownErrors.isEmpty()) {
|
||||
/*
|
||||
* The start up errors will ultimately be
|
||||
* reported to the user for possible remedy, but
|
||||
* the shut down errors are logged here.
|
||||
*/
|
||||
logIngestModuleErrors(shutDownErrors);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
logIngestModuleErrors(errors);
|
||||
return errors;
|
||||
}
|
||||
|
||||
|
||||
@@ -10,10 +10,10 @@
|
||||
<Dimension value="[5750, 3000]"/>
|
||||
</Property>
|
||||
<Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||
<Dimension value="[522, 257]"/>
|
||||
<Dimension value="[0, 0]"/>
|
||||
</Property>
|
||||
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||
<Dimension value="[575, 300]"/>
|
||||
<Dimension value="[625, 450]"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<AuxValues>
|
||||
@@ -31,11 +31,11 @@
|
||||
<Layout>
|
||||
<DimensionLayout dim="0">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Group type="102" alignment="0" attributes="0">
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Group type="102" attributes="0">
|
||||
<EmptySpace min="-2" max="-2" attributes="0"/>
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Group type="102" alignment="1" attributes="0">
|
||||
<Component id="modulesScrollPane" max="32767" attributes="1"/>
|
||||
<Group type="102" attributes="0">
|
||||
<Component id="modulesScrollPane" pref="271" max="32767" attributes="1"/>
|
||||
<EmptySpace min="-2" pref="10" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<Group type="102" alignment="0" attributes="0">
|
||||
@@ -48,33 +48,33 @@
|
||||
<Component id="jButtonDeselectAll" min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
<EmptySpace pref="30" max="32767" attributes="0"/>
|
||||
<EmptySpace min="-2" pref="32" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
<Component id="jPanel1" pref="310" max="32767" attributes="0"/>
|
||||
<EmptySpace min="-2" max="-2" attributes="0"/>
|
||||
<Component id="jPanel1" pref="324" max="32767" attributes="0"/>
|
||||
<EmptySpace 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" max="-2" attributes="0"/>
|
||||
<Group type="102" attributes="0">
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Group type="102" attributes="0">
|
||||
<Component id="jPanel1" pref="278" max="32767" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<Group type="102" attributes="0">
|
||||
<Group type="102" alignment="0" attributes="0">
|
||||
<Component id="modulesScrollPane" max="32767" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Group type="103" groupAlignment="3" attributes="0">
|
||||
<Component id="jButtonDeselectAll" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="jButtonSelectAll" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<EmptySpace min="-2" max="-2" attributes="0"/>
|
||||
<Component id="processUnallocCheckbox" min="-2" pref="23" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<Group type="102" alignment="1" attributes="0">
|
||||
<Component id="jPanel1" pref="428" max="32767" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
</Group>
|
||||
</Group>
|
||||
@@ -90,6 +90,9 @@
|
||||
</LineBorder>
|
||||
</Border>
|
||||
</Property>
|
||||
<Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||
<Dimension value="[0, 0]"/>
|
||||
</Property>
|
||||
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||
<Dimension value="[160, 160]"/>
|
||||
</Property>
|
||||
@@ -129,50 +132,49 @@
|
||||
<DimensionLayout dim="0">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Component id="jSeparator2" alignment="1" max="32767" attributes="0"/>
|
||||
<Group type="102" alignment="1" attributes="0">
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Group type="103" groupAlignment="1" attributes="0">
|
||||
<Component id="jScrollPane1" max="32767" attributes="0"/>
|
||||
<Group type="102" attributes="0">
|
||||
<Component id="descriptionLabel" min="-2" pref="203" max="-2" attributes="0"/>
|
||||
<EmptySpace max="32767" attributes="0"/>
|
||||
<Component id="advancedButton" min="-2" max="-2" attributes="0"/>
|
||||
<Group type="102" alignment="0" attributes="0">
|
||||
<EmptySpace min="-2" max="-2" attributes="0"/>
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Component id="descriptionLabel" pref="302" max="32767" attributes="0"/>
|
||||
<Component id="jScrollPane1" alignment="1" max="32767" attributes="0"/>
|
||||
<Group type="102" alignment="1" attributes="0">
|
||||
<EmptySpace min="0" pref="0" max="32767" attributes="0"/>
|
||||
<Component id="globalSettingsButton" min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<EmptySpace min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
<DimensionLayout dim="1">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Group type="102" alignment="1" attributes="0">
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="jScrollPane1" pref="211" max="32767" attributes="0"/>
|
||||
<EmptySpace type="unrelated" max="-2" attributes="0"/>
|
||||
<EmptySpace min="-2" max="-2" attributes="0"/>
|
||||
<Component id="jScrollPane1" pref="330" max="32767" attributes="0"/>
|
||||
<EmptySpace min="-2" pref="18" max="-2" attributes="0"/>
|
||||
<Component id="jSeparator2" min="-2" pref="2" max="-2" attributes="0"/>
|
||||
<EmptySpace min="-2" pref="8" max="-2" attributes="0"/>
|
||||
<Component id="descriptionLabel" min="-2" pref="20" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Component id="descriptionLabel" min="-2" pref="24" max="-2" attributes="0"/>
|
||||
<Component id="advancedButton" alignment="0" min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="globalSettingsButton" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace min="-2" pref="8" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
</Layout>
|
||||
<SubComponents>
|
||||
<Component class="javax.swing.JButton" name="advancedButton">
|
||||
<Component class="javax.swing.JButton" name="globalSettingsButton">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/ingest/Bundle.properties" key="IngestJobSettingsPanel.advancedButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/ingest/Bundle.properties" key="IngestJobSettingsPanel.globalSettingsButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
<Property name="actionCommand" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/ingest/Bundle.properties" key="IngestJobSettingsPanel.advancedButton.actionCommand" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/ingest/Bundle.properties" key="IngestJobSettingsPanel.globalSettingsButton.actionCommand" 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="advancedButtonActionPerformed"/>
|
||||
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="globalSettingsButtonActionPerformed"/>
|
||||
</Events>
|
||||
</Component>
|
||||
<Component class="javax.swing.JSeparator" name="jSeparator2">
|
||||
@@ -196,7 +198,12 @@
|
||||
|
||||
<Layout class="org.netbeans.modules.form.compat2.layouts.support.JScrollPaneSupportLayout"/>
|
||||
<SubComponents>
|
||||
<Container class="javax.swing.JPanel" name="simplePanel">
|
||||
<Container class="javax.swing.JPanel" name="ingestSettingsPanel">
|
||||
<Properties>
|
||||
<Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||
<Dimension value="[0, 300]"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
|
||||
<Layout class="org.netbeans.modules.form.compat2.layouts.DesignBoxLayout">
|
||||
<Property name="axis" type="int" value="3"/>
|
||||
|
||||
@@ -25,6 +25,7 @@ import java.awt.event.WindowAdapter;
|
||||
import java.awt.event.WindowEvent;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.JTable;
|
||||
import javax.swing.ListSelectionModel;
|
||||
import javax.swing.event.ListSelectionEvent;
|
||||
@@ -32,6 +33,7 @@ import javax.swing.event.ListSelectionListener;
|
||||
import javax.swing.table.AbstractTableModel;
|
||||
import javax.swing.table.DefaultTableCellRenderer;
|
||||
import javax.swing.table.TableColumn;
|
||||
import org.openide.util.NbBundle.Messages;
|
||||
import org.sleuthkit.autopsy.corecomponents.AdvancedConfigurationDialog;
|
||||
|
||||
/**
|
||||
@@ -78,6 +80,7 @@ public final class IngestJobSettingsPanel extends javax.swing.JPanel {
|
||||
return this.settings;
|
||||
}
|
||||
|
||||
@Messages({"IngestJobSettingsPanel.noPerRunSettings=The selected module has no per-run settings."})
|
||||
private void customizeComponents() {
|
||||
modulesTable.setModel(new IngestModulesTableModel());
|
||||
modulesTable.setTableHeader(null);
|
||||
@@ -108,19 +111,21 @@ public final class IngestJobSettingsPanel extends javax.swing.JPanel {
|
||||
if (!listSelectionModel.isSelectionEmpty()) {
|
||||
int index = listSelectionModel.getMinSelectionIndex();
|
||||
selectedModule = modules.get(index);
|
||||
simplePanel.removeAll();
|
||||
ingestSettingsPanel.removeAll();
|
||||
if (null != selectedModule.getModuleSettingsPanel()) {
|
||||
simplePanel.add(selectedModule.getModuleSettingsPanel());
|
||||
ingestSettingsPanel.add(selectedModule.getModuleSettingsPanel());
|
||||
} else {
|
||||
ingestSettingsPanel.add(new JLabel(Bundle.IngestJobSettingsPanel_noPerRunSettings()));
|
||||
}
|
||||
simplePanel.revalidate();
|
||||
simplePanel.repaint();
|
||||
advancedButton.setEnabled(null != selectedModule.getGlobalSettingsPanel());
|
||||
ingestSettingsPanel.revalidate();
|
||||
ingestSettingsPanel.repaint();
|
||||
globalSettingsButton.setEnabled(null != selectedModule.getGlobalSettingsPanel());
|
||||
descriptionLabel.setText(selectedModule.getDescription());
|
||||
descriptionLabel.setToolTipText(selectedModule.getDescription());
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
modulesTable.setRowSelectionInterval(0, 0);
|
||||
processUnallocCheckbox.setSelected(this.settings.getProcessUnallocatedSpace());
|
||||
}
|
||||
|
||||
@@ -137,20 +142,21 @@ public final class IngestJobSettingsPanel extends javax.swing.JPanel {
|
||||
modulesScrollPane = new javax.swing.JScrollPane();
|
||||
modulesTable = new javax.swing.JTable();
|
||||
jPanel1 = new javax.swing.JPanel();
|
||||
advancedButton = new javax.swing.JButton();
|
||||
globalSettingsButton = new javax.swing.JButton();
|
||||
jSeparator2 = new javax.swing.JSeparator();
|
||||
descriptionLabel = new javax.swing.JLabel();
|
||||
jScrollPane1 = new javax.swing.JScrollPane();
|
||||
simplePanel = new javax.swing.JPanel();
|
||||
ingestSettingsPanel = new javax.swing.JPanel();
|
||||
jButtonSelectAll = new javax.swing.JButton();
|
||||
jButtonDeselectAll = new javax.swing.JButton();
|
||||
processUnallocCheckbox = new javax.swing.JCheckBox();
|
||||
|
||||
setMaximumSize(new java.awt.Dimension(5750, 3000));
|
||||
setMinimumSize(new java.awt.Dimension(522, 257));
|
||||
setPreferredSize(new java.awt.Dimension(575, 300));
|
||||
setMinimumSize(new java.awt.Dimension(0, 0));
|
||||
setPreferredSize(new java.awt.Dimension(625, 450));
|
||||
|
||||
modulesScrollPane.setBorder(javax.swing.BorderFactory.createLineBorder(new java.awt.Color(160, 160, 160)));
|
||||
modulesScrollPane.setMinimumSize(new java.awt.Dimension(0, 0));
|
||||
modulesScrollPane.setPreferredSize(new java.awt.Dimension(160, 160));
|
||||
|
||||
modulesTable.setBackground(new java.awt.Color(240, 240, 240));
|
||||
@@ -169,12 +175,12 @@ public final class IngestJobSettingsPanel extends javax.swing.JPanel {
|
||||
jPanel1.setBorder(javax.swing.BorderFactory.createLineBorder(new java.awt.Color(160, 160, 160)));
|
||||
jPanel1.setPreferredSize(new java.awt.Dimension(338, 257));
|
||||
|
||||
advancedButton.setText(org.openide.util.NbBundle.getMessage(IngestJobSettingsPanel.class, "IngestJobSettingsPanel.advancedButton.text")); // NOI18N
|
||||
advancedButton.setActionCommand(org.openide.util.NbBundle.getMessage(IngestJobSettingsPanel.class, "IngestJobSettingsPanel.advancedButton.actionCommand")); // NOI18N
|
||||
advancedButton.setEnabled(false);
|
||||
advancedButton.addActionListener(new java.awt.event.ActionListener() {
|
||||
globalSettingsButton.setText(org.openide.util.NbBundle.getMessage(IngestJobSettingsPanel.class, "IngestJobSettingsPanel.globalSettingsButton.text")); // NOI18N
|
||||
globalSettingsButton.setActionCommand(org.openide.util.NbBundle.getMessage(IngestJobSettingsPanel.class, "IngestJobSettingsPanel.globalSettingsButton.actionCommand")); // NOI18N
|
||||
globalSettingsButton.setEnabled(false);
|
||||
globalSettingsButton.addActionListener(new java.awt.event.ActionListener() {
|
||||
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||
advancedButtonActionPerformed(evt);
|
||||
globalSettingsButtonActionPerformed(evt);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -183,36 +189,37 @@ public final class IngestJobSettingsPanel extends javax.swing.JPanel {
|
||||
jScrollPane1.setBorder(null);
|
||||
jScrollPane1.setPreferredSize(new java.awt.Dimension(250, 180));
|
||||
|
||||
simplePanel.setLayout(new javax.swing.BoxLayout(simplePanel, javax.swing.BoxLayout.PAGE_AXIS));
|
||||
jScrollPane1.setViewportView(simplePanel);
|
||||
ingestSettingsPanel.setMinimumSize(new java.awt.Dimension(0, 300));
|
||||
ingestSettingsPanel.setLayout(new javax.swing.BoxLayout(ingestSettingsPanel, javax.swing.BoxLayout.PAGE_AXIS));
|
||||
jScrollPane1.setViewportView(ingestSettingsPanel);
|
||||
|
||||
javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1);
|
||||
jPanel1.setLayout(jPanel1Layout);
|
||||
jPanel1Layout.setHorizontalGroup(
|
||||
jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addComponent(jSeparator2, javax.swing.GroupLayout.Alignment.TRAILING)
|
||||
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel1Layout.createSequentialGroup()
|
||||
.addGroup(jPanel1Layout.createSequentialGroup()
|
||||
.addContainerGap()
|
||||
.addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
|
||||
.addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
||||
.addGroup(jPanel1Layout.createSequentialGroup()
|
||||
.addComponent(descriptionLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 203, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
||||
.addComponent(advancedButton)))
|
||||
.addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addComponent(descriptionLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 302, Short.MAX_VALUE)
|
||||
.addComponent(jScrollPane1, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
||||
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel1Layout.createSequentialGroup()
|
||||
.addGap(0, 0, Short.MAX_VALUE)
|
||||
.addComponent(globalSettingsButton)))
|
||||
.addContainerGap())
|
||||
);
|
||||
jPanel1Layout.setVerticalGroup(
|
||||
jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel1Layout.createSequentialGroup()
|
||||
.addContainerGap()
|
||||
.addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 211, Short.MAX_VALUE)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
|
||||
.addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 330, Short.MAX_VALUE)
|
||||
.addGap(18, 18, 18)
|
||||
.addComponent(jSeparator2, javax.swing.GroupLayout.PREFERRED_SIZE, 2, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||
.addGap(8, 8, 8)
|
||||
.addComponent(descriptionLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 20, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addComponent(descriptionLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 24, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||
.addComponent(advancedButton))
|
||||
.addContainerGap())
|
||||
.addComponent(globalSettingsButton)
|
||||
.addGap(8, 8, 8))
|
||||
);
|
||||
|
||||
jButtonSelectAll.setText(org.openide.util.NbBundle.getMessage(IngestJobSettingsPanel.class, "IngestJobSettingsPanel.jButtonSelectAll.text")); // NOI18N
|
||||
@@ -244,8 +251,8 @@ public final class IngestJobSettingsPanel extends javax.swing.JPanel {
|
||||
.addGroup(layout.createSequentialGroup()
|
||||
.addContainerGap()
|
||||
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
|
||||
.addComponent(modulesScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
||||
.addGroup(layout.createSequentialGroup()
|
||||
.addComponent(modulesScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, 271, Short.MAX_VALUE)
|
||||
.addGap(10, 10, 10))
|
||||
.addGroup(layout.createSequentialGroup()
|
||||
.addGap(24, 24, 24)
|
||||
@@ -255,8 +262,8 @@ public final class IngestJobSettingsPanel extends javax.swing.JPanel {
|
||||
.addComponent(jButtonSelectAll, javax.swing.GroupLayout.PREFERRED_SIZE, 86, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||
.addGap(18, 18, 18)
|
||||
.addComponent(jButtonDeselectAll)))
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 30, Short.MAX_VALUE)))
|
||||
.addComponent(jPanel1, javax.swing.GroupLayout.DEFAULT_SIZE, 310, Short.MAX_VALUE)
|
||||
.addGap(32, 32, 32)))
|
||||
.addComponent(jPanel1, javax.swing.GroupLayout.DEFAULT_SIZE, 324, Short.MAX_VALUE)
|
||||
.addContainerGap())
|
||||
);
|
||||
layout.setVerticalGroup(
|
||||
@@ -264,9 +271,6 @@ public final class IngestJobSettingsPanel extends javax.swing.JPanel {
|
||||
.addGroup(layout.createSequentialGroup()
|
||||
.addContainerGap()
|
||||
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGroup(layout.createSequentialGroup()
|
||||
.addComponent(jPanel1, javax.swing.GroupLayout.DEFAULT_SIZE, 278, Short.MAX_VALUE)
|
||||
.addContainerGap())
|
||||
.addGroup(layout.createSequentialGroup()
|
||||
.addComponent(modulesScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
@@ -274,11 +278,14 @@ public final class IngestJobSettingsPanel extends javax.swing.JPanel {
|
||||
.addComponent(jButtonDeselectAll)
|
||||
.addComponent(jButtonSelectAll))
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(processUnallocCheckbox, javax.swing.GroupLayout.PREFERRED_SIZE, 23, javax.swing.GroupLayout.PREFERRED_SIZE))))
|
||||
.addComponent(processUnallocCheckbox, javax.swing.GroupLayout.PREFERRED_SIZE, 23, javax.swing.GroupLayout.PREFERRED_SIZE))
|
||||
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
|
||||
.addComponent(jPanel1, javax.swing.GroupLayout.DEFAULT_SIZE, 428, Short.MAX_VALUE)
|
||||
.addContainerGap())))
|
||||
);
|
||||
}// </editor-fold>//GEN-END:initComponents
|
||||
|
||||
private void advancedButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_advancedButtonActionPerformed
|
||||
private void globalSettingsButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_globalSettingsButtonActionPerformed
|
||||
final AdvancedConfigurationDialog dialog = new AdvancedConfigurationDialog();
|
||||
|
||||
dialog.addApplyButtonListener(new ActionListener() {
|
||||
@@ -299,7 +306,7 @@ public final class IngestJobSettingsPanel extends javax.swing.JPanel {
|
||||
});
|
||||
|
||||
dialog.display(selectedModule.getGlobalSettingsPanel());
|
||||
}//GEN-LAST:event_advancedButtonActionPerformed
|
||||
}//GEN-LAST:event_globalSettingsButtonActionPerformed
|
||||
|
||||
private void jButtonSelectAllActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButtonSelectAllActionPerformed
|
||||
SelectAllModules(true);
|
||||
@@ -321,8 +328,9 @@ public final class IngestJobSettingsPanel extends javax.swing.JPanel {
|
||||
}
|
||||
|
||||
// Variables declaration - do not modify//GEN-BEGIN:variables
|
||||
private javax.swing.JButton advancedButton;
|
||||
private javax.swing.JLabel descriptionLabel;
|
||||
private javax.swing.JButton globalSettingsButton;
|
||||
private javax.swing.JPanel ingestSettingsPanel;
|
||||
private javax.swing.JButton jButtonDeselectAll;
|
||||
private javax.swing.JButton jButtonSelectAll;
|
||||
private javax.swing.JPanel jPanel1;
|
||||
@@ -331,7 +339,6 @@ public final class IngestJobSettingsPanel extends javax.swing.JPanel {
|
||||
private javax.swing.JScrollPane modulesScrollPane;
|
||||
private javax.swing.JTable modulesTable;
|
||||
private javax.swing.JCheckBox processUnallocCheckbox;
|
||||
private javax.swing.JPanel simplePanel;
|
||||
private javax.swing.ButtonGroup timeGroup;
|
||||
// End of variables declaration//GEN-END:variables
|
||||
|
||||
|
||||
@@ -556,9 +556,9 @@ public class IngestManager {
|
||||
this.jobsById.remove(job.getId());
|
||||
}
|
||||
for (IngestModuleError error : errors) {
|
||||
logger.log(Level.SEVERE, String.format("Error starting %s ingest module", error.getModuleDisplayName()), error.getModuleError()); //NON-NLS
|
||||
logger.log(Level.SEVERE, String.format("Error starting %s ingest module for job %d", error.getModuleDisplayName(), job.getId()), error.getModuleError()); //NON-NLS
|
||||
}
|
||||
IngestManager.logger.log(Level.INFO, "Ingest job {0} could not be started", job.getId()); //NON-NLS
|
||||
IngestManager.logger.log(Level.SEVERE, "Ingest job {0} could not be started", job.getId()); //NON-NLS
|
||||
if (RuntimeProperties.coreComponentsAreActive()) {
|
||||
EventQueue.invokeLater(new Runnable() {
|
||||
|
||||
|
||||
@@ -20,20 +20,25 @@ package org.sleuthkit.autopsy.ingest;
|
||||
|
||||
import java.awt.BorderLayout;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.FlowLayout;
|
||||
import java.awt.Toolkit;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.awt.event.WindowAdapter;
|
||||
import java.awt.event.WindowEvent;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import javax.swing.BorderFactory;
|
||||
import javax.swing.BoxLayout;
|
||||
import javax.swing.JButton;
|
||||
import javax.swing.JDialog;
|
||||
import javax.swing.JFrame;
|
||||
import javax.swing.JOptionPane;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.border.EmptyBorder;
|
||||
import org.openide.util.NbBundle;
|
||||
import org.openide.windows.WindowManager;
|
||||
import org.sleuthkit.autopsy.ingest.IngestJobSettings.IngestType;
|
||||
import org.sleuthkit.datamodel.Content;
|
||||
import org.sleuthkit.datamodel.Directory;
|
||||
@@ -49,7 +54,6 @@ public final class RunIngestModulesDialog extends JDialog {
|
||||
private static final long serialVersionUID = 1L;
|
||||
private static final String TITLE = NbBundle.getMessage(RunIngestModulesDialog.class, "IngestDialog.title.text");
|
||||
private final IngestType ingestType;
|
||||
private static Dimension DIMENSIONS = new Dimension(500, 300);
|
||||
private final List<Content> dataSources = new ArrayList<>();
|
||||
private IngestJobSettingsPanel ingestJobSettingsPanel;
|
||||
|
||||
@@ -75,7 +79,7 @@ public final class RunIngestModulesDialog extends JDialog {
|
||||
* @param dataSources The data sources to be processed.
|
||||
*/
|
||||
public RunIngestModulesDialog(List<Content> dataSources) {
|
||||
this(new JFrame(TITLE), TITLE, true, dataSources);
|
||||
this((JFrame) WindowManager.getDefault().getMainWindow(), TITLE, true, dataSources);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -98,11 +102,7 @@ public final class RunIngestModulesDialog extends JDialog {
|
||||
/**
|
||||
* Center the dialog.
|
||||
*/
|
||||
Dimension screenDimension = Toolkit.getDefaultToolkit().getScreenSize();
|
||||
setSize(DIMENSIONS);
|
||||
int width = this.getSize().width;
|
||||
int height = this.getSize().height;
|
||||
setLocation((screenDimension.width - width) / 2, (screenDimension.height - height) / 2);
|
||||
Dimension screenDimension = Toolkit.getDefaultToolkit().getScreenSize();;
|
||||
|
||||
/**
|
||||
* Get the default or saved ingest job settings for this context and use
|
||||
@@ -111,7 +111,8 @@ public final class RunIngestModulesDialog extends JDialog {
|
||||
IngestJobSettings ingestJobSettings = new IngestJobSettings(RunIngestModulesDialog.class.getCanonicalName(), this.ingestType);
|
||||
RunIngestModulesDialog.showWarnings(ingestJobSettings);
|
||||
this.ingestJobSettingsPanel = new IngestJobSettingsPanel(ingestJobSettings);
|
||||
add(this.ingestJobSettingsPanel, BorderLayout.PAGE_START);
|
||||
setPreferredSize(this.ingestJobSettingsPanel.getPreferredSize());
|
||||
add(this.ingestJobSettingsPanel, BorderLayout.CENTER);
|
||||
|
||||
// Add a start ingest button.
|
||||
JButton startButton = new JButton(NbBundle.getMessage(this.getClass(), "IngestDialog.startButton.title"));
|
||||
@@ -133,12 +134,13 @@ public final class RunIngestModulesDialog extends JDialog {
|
||||
|
||||
// Put the buttons in their own panel, under the settings panel.
|
||||
JPanel buttonPanel = new JPanel();
|
||||
buttonPanel.setLayout(new BoxLayout(buttonPanel, BoxLayout.LINE_AXIS));
|
||||
buttonPanel.add(new javax.swing.Box.Filler(new Dimension(10, 10), new Dimension(10, 10), new Dimension(10, 10)));
|
||||
buttonPanel.setLayout(new FlowLayout(FlowLayout.TRAILING));
|
||||
buttonPanel.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 5));
|
||||
buttonPanel.add(startButton);
|
||||
buttonPanel.add(new javax.swing.Box.Filler(new Dimension(10, 10), new Dimension(10, 10), new Dimension(10, 10)));
|
||||
buttonPanel.add(new javax.swing.Box.Filler(new Dimension(5, 10), new Dimension(5, 10), new Dimension(5, 10)));
|
||||
buttonPanel.add(closeButton);
|
||||
add(buttonPanel, BorderLayout.LINE_START);
|
||||
|
||||
add(buttonPanel, BorderLayout.SOUTH);
|
||||
|
||||
/**
|
||||
* Add a handler for when the dialog window is closed directly,
|
||||
@@ -154,8 +156,10 @@ public final class RunIngestModulesDialog extends JDialog {
|
||||
/**
|
||||
* Show the dialog.
|
||||
*/
|
||||
int width = this.getPreferredSize().width;
|
||||
int height = this.getPreferredSize().height;
|
||||
setLocation((screenDimension.width - width) / 2, (screenDimension.height - height) / 2);
|
||||
pack();
|
||||
setResizable(false);
|
||||
setVisible(true);
|
||||
}
|
||||
|
||||
@@ -196,7 +200,7 @@ public final class RunIngestModulesDialog extends JDialog {
|
||||
JOptionPane.showMessageDialog(null, warningMessage.toString());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Constructs a dialog box that allows a user to configure and execute
|
||||
* analysis of one or more data sources with ingest modules.
|
||||
@@ -236,5 +240,5 @@ public final class RunIngestModulesDialog extends JDialog {
|
||||
this.dataSources.clear();
|
||||
this.dataSources.addAll(dataSources);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
<Component id="skipNoExtCheckBox" alignment="0" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="skipKnownFiles" alignment="0" min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<EmptySpace min="0" pref="138" max="32767" attributes="0"/>
|
||||
<EmptySpace min="0" pref="10" max="32767" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
|
||||
@@ -93,7 +93,7 @@ final class FileExtMismatchModuleSettingsPanel extends IngestModuleIngestJobSett
|
||||
.addComponent(skipTextPlain)
|
||||
.addComponent(skipNoExtCheckBox)
|
||||
.addComponent(skipKnownFiles))
|
||||
.addGap(0, 138, Short.MAX_VALUE))
|
||||
.addGap(0, 10, Short.MAX_VALUE))
|
||||
);
|
||||
layout.setVerticalGroup(
|
||||
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
|
||||
@@ -0,0 +1,58 @@
|
||||
/*
|
||||
* Autopsy Forensic Browser
|
||||
*
|
||||
* Copyright 2011-2016 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.modules.filetypeid;
|
||||
|
||||
import org.sleuthkit.autopsy.ingest.IngestModuleIngestJobSettings;
|
||||
|
||||
/**
|
||||
* Ingest job options for the file type identifier ingest module instances.
|
||||
*
|
||||
* @deprecated This class is obsolete (files are no longer skipped for any
|
||||
* reason by file typing) but it is retained for backwards compatibility because
|
||||
* it was erroneously made part of the public API and so that old settings files
|
||||
* can be deserialized successfully (and ignored).
|
||||
*/
|
||||
@Deprecated
|
||||
public class FileTypeIdModuleSettings implements IngestModuleIngestJobSettings {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
private boolean skipKnownFiles = true;
|
||||
private final boolean skipSmallFiles = false; // No longer used.
|
||||
|
||||
FileTypeIdModuleSettings() {
|
||||
}
|
||||
|
||||
FileTypeIdModuleSettings(boolean skipKnownFiles) {
|
||||
this.skipKnownFiles = skipKnownFiles;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getVersionNumber() {
|
||||
return serialVersionUID;
|
||||
}
|
||||
|
||||
void setSkipKnownFiles(boolean enabled) {
|
||||
skipKnownFiles = enabled;
|
||||
}
|
||||
|
||||
boolean skipKnownFiles() {
|
||||
return skipKnownFiles;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -26,7 +26,7 @@
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Group type="102" attributes="0">
|
||||
<Component id="knownHashDbsLabel" min="-2" pref="272" max="-2" attributes="0"/>
|
||||
<EmptySpace min="0" pref="0" max="32767" attributes="0"/>
|
||||
<EmptySpace min="0" pref="18" max="32767" attributes="0"/>
|
||||
</Group>
|
||||
<Component id="knownBadHashDbsLabel" max="32767" attributes="0"/>
|
||||
<Group type="102" attributes="0">
|
||||
@@ -47,15 +47,15 @@
|
||||
<Group type="102" alignment="0" attributes="0">
|
||||
<EmptySpace min="-2" pref="2" max="-2" attributes="0"/>
|
||||
<Component id="knownHashDbsLabel" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="jScrollPane1" min="-2" pref="58" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<EmptySpace min="-2" max="-2" attributes="0"/>
|
||||
<Component id="jScrollPane1" pref="54" max="32767" attributes="0"/>
|
||||
<EmptySpace type="unrelated" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="knownBadHashDbsLabel" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace min="-2" max="-2" attributes="0"/>
|
||||
<Component id="jScrollPane2" pref="53" max="32767" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="jScrollPane2" min="-2" pref="58" max="-2" attributes="0"/>
|
||||
<EmptySpace max="32767" attributes="0"/>
|
||||
<Component id="alwaysCalcHashesCheckbox" min="-2" pref="35" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="alwaysCalcHashesCheckbox" min="-2" pref="27" max="-2" attributes="0"/>
|
||||
<EmptySpace min="0" pref="0" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
@@ -120,9 +120,6 @@
|
||||
<Property name="verticalAlignment" type="int" value="1"/>
|
||||
<Property name="verticalTextPosition" type="int" value="1"/>
|
||||
</Properties>
|
||||
<Events>
|
||||
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="alwaysCalcHashesCheckboxActionPerformed"/>
|
||||
</Events>
|
||||
</Component>
|
||||
<Container class="javax.swing.JScrollPane" name="jScrollPane2">
|
||||
<Properties>
|
||||
|
||||
@@ -321,7 +321,7 @@ public final class HashLookupModuleSettingsPanel extends IngestModuleIngestJobSe
|
||||
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGroup(layout.createSequentialGroup()
|
||||
.addComponent(knownHashDbsLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 272, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||
.addGap(0, 0, Short.MAX_VALUE))
|
||||
.addGap(0, 18, Short.MAX_VALUE))
|
||||
.addComponent(knownBadHashDbsLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
||||
.addGroup(layout.createSequentialGroup()
|
||||
.addGap(10, 10, 10)
|
||||
@@ -337,14 +337,14 @@ public final class HashLookupModuleSettingsPanel extends IngestModuleIngestJobSe
|
||||
.addGap(2, 2, 2)
|
||||
.addComponent(knownHashDbsLabel)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 58, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 54, Short.MAX_VALUE)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
|
||||
.addComponent(knownBadHashDbsLabel)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(jScrollPane2, javax.swing.GroupLayout.PREFERRED_SIZE, 58, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
||||
.addComponent(alwaysCalcHashesCheckbox, javax.swing.GroupLayout.PREFERRED_SIZE, 35, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||
.addContainerGap())
|
||||
.addComponent(jScrollPane2, javax.swing.GroupLayout.DEFAULT_SIZE, 53, Short.MAX_VALUE)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(alwaysCalcHashesCheckbox, javax.swing.GroupLayout.PREFERRED_SIZE, 27, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||
.addGap(0, 0, 0))
|
||||
);
|
||||
}// </editor-fold>//GEN-END:initComponents
|
||||
|
||||
|
||||
@@ -23,7 +23,6 @@ import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
import java.util.logging.Level;
|
||||
import javafx.beans.Observable;
|
||||
@@ -150,11 +149,7 @@ public final class FilteredEventsModel {
|
||||
final ZoomParams zoomParams = requestedZoomParamters.get();
|
||||
|
||||
if (zoomParams != null) {
|
||||
if (zoomParams.getTypeZoomLevel().equals(requestedTypeZoom.get()) == false
|
||||
|| zoomParams.getDescriptionLOD().equals(requestedLOD.get()) == false
|
||||
|| zoomParams.getFilter().equals(requestedFilter.get()) == false
|
||||
|| Objects.equals(zoomParams.getTimeRange(), requestedTimeRange.get()) == false) {
|
||||
|
||||
synchronized (FilteredEventsModel.this) {
|
||||
requestedTypeZoom.set(zoomParams.getTypeZoomLevel());
|
||||
requestedFilter.set(zoomParams.getFilter());
|
||||
requestedTimeRange.set(zoomParams.getTimeRange());
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* Autopsy Forensic Browser
|
||||
*
|
||||
* Copyright 2014-15 Basis Technology Corp.
|
||||
* Copyright 2014-16 Basis Technology Corp.
|
||||
* Contact: carrier <at> sleuthkit <dot> org
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
@@ -33,10 +33,7 @@ import javafx.collections.ObservableList;
|
||||
* a {@link CompoundFilter} uses listeners to enforce the following
|
||||
* relationships between it and its sub-filters:
|
||||
* <ol>
|
||||
* <le>if a filter becomes active, and all its sub-filters were inactive, make
|
||||
* them all active</le>
|
||||
* <le>if a filter becomes inactive and all its sub-filters were active, make
|
||||
* them all inactive</le>
|
||||
* <le>if a filter becomes inactive disable all of its subfilters</le>
|
||||
* <le>if a sub-filter changes active state set the parent filter active if any
|
||||
* of its sub-filters are active.</le>
|
||||
* </ol>
|
||||
@@ -93,9 +90,7 @@ public abstract class CompoundFilter<SubFilterType extends Filter> extends Abstr
|
||||
for (int i = 0; i < oneFilter.getSubFilters().size(); i++) {
|
||||
final SubFilterType subFilter = oneFilter.getSubFilters().get(i);
|
||||
final SubFilterType otherSubFilter = otherFilter.getSubFilters().get(i);
|
||||
if (subFilter.equals(otherSubFilter) == false
|
||||
|| subFilter.isDisabled() != otherSubFilter.isDisabled()
|
||||
|| subFilter.isSelected() != otherSubFilter.isSelected()) {
|
||||
if (subFilter.equals(otherSubFilter) == false) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* Autopsy Forensic Browser
|
||||
*
|
||||
* Copyright 2015 Basis Technology Corp.
|
||||
* Copyright 2015-16 Basis Technology Corp.
|
||||
* Contact: carrier <at> sleuthkit <dot> org
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
@@ -37,6 +37,7 @@ public class DataSourcesFilter extends UnionFilter<DataSourceFilter> {
|
||||
public DataSourcesFilter copyOf() {
|
||||
final DataSourcesFilter filterCopy = new DataSourcesFilter();
|
||||
filterCopy.setSelected(isSelected());
|
||||
filterCopy.setDisabled(isDisabled());
|
||||
//add a copy of each subfilter
|
||||
this.getSubFilters().forEach((DataSourceFilter t) -> {
|
||||
filterCopy.addSubFilter(t.copyOf());
|
||||
@@ -87,7 +88,7 @@ public class DataSourcesFilter extends UnionFilter<DataSourceFilter> {
|
||||
}
|
||||
final DataSourcesFilter other = (DataSourcesFilter) obj;
|
||||
|
||||
if (isSelected() != other.isSelected()) {
|
||||
if (isActive() != other.isActive()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,20 @@
|
||||
/*
|
||||
* To change this license header, choose License Headers in Project Properties.
|
||||
* To change this template file, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
* Autopsy Forensic Browser
|
||||
*
|
||||
* Copyright 2015-16 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.timeline.filters;
|
||||
|
||||
@@ -30,6 +43,7 @@ public class HashHitsFilter extends UnionFilter<HashSetFilter> {
|
||||
public HashHitsFilter copyOf() {
|
||||
HashHitsFilter filterCopy = new HashHitsFilter();
|
||||
filterCopy.setSelected(isSelected());
|
||||
filterCopy.setDisabled(isDisabled());
|
||||
//add a copy of each subfilter
|
||||
this.getSubFilters().forEach((HashSetFilter t) -> {
|
||||
filterCopy.addSubFilter(t.copyOf());
|
||||
@@ -65,7 +79,7 @@ public class HashHitsFilter extends UnionFilter<HashSetFilter> {
|
||||
}
|
||||
final HashHitsFilter other = (HashHitsFilter) obj;
|
||||
|
||||
if (isSelected() != other.isSelected()) {
|
||||
if (isActive() != other.isActive()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,20 @@
|
||||
/*
|
||||
* To change this license header, choose License Headers in Project Properties.
|
||||
* To change this template file, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
* Autopsy Forensic Browser
|
||||
*
|
||||
* Copyright 2015-16 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.timeline.filters;
|
||||
|
||||
@@ -31,6 +44,7 @@ public class TagsFilter extends UnionFilter<TagNameFilter> {
|
||||
public TagsFilter copyOf() {
|
||||
TagsFilter filterCopy = new TagsFilter();
|
||||
filterCopy.setSelected(isSelected());
|
||||
filterCopy.setDisabled(isDisabled());
|
||||
//add a copy of each subfilter
|
||||
this.getSubFilters().forEach((TagNameFilter t) -> {
|
||||
filterCopy.addSubFilter(t.copyOf());
|
||||
@@ -66,7 +80,7 @@ public class TagsFilter extends UnionFilter<TagNameFilter> {
|
||||
}
|
||||
final TagsFilter other = (TagsFilter) obj;
|
||||
|
||||
if (isSelected() != other.isSelected()) {
|
||||
if (isActive() != other.isActive()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* Autopsy Forensic Browser
|
||||
*
|
||||
* Copyright 2013-15 Basis Technology Corp.
|
||||
* Copyright 2013-16 Basis Technology Corp.
|
||||
* Contact: carrier <at> sleuthkit <dot> org
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
@@ -126,7 +126,7 @@ public class TypeFilter extends UnionFilter<TypeFilter> {
|
||||
}
|
||||
final TypeFilter other = (TypeFilter) obj;
|
||||
|
||||
if (isSelected() != other.isSelected()) {
|
||||
if (isActive() != other.isActive()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* Autopsy Forensic Browser
|
||||
*
|
||||
* Copyright 2014-15 Basis Technology Corp.
|
||||
* Copyright 2014-16 Basis Technology Corp.
|
||||
* Contact: carrier <at> sleuthkit <dot> org
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* Autopsy Forensic Browser
|
||||
*
|
||||
* Copyright 2011-2015 Basis Technology Corp.
|
||||
* Copyright 2011-2016 Basis Technology Corp.
|
||||
* Contact: carrier <at> sleuthkit <dot> org
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
@@ -22,12 +22,14 @@ import java.beans.PropertyChangeEvent;
|
||||
import java.beans.PropertyChangeListener;
|
||||
import java.beans.PropertyChangeSupport;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.logging.FileHandler;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
import java.util.logging.SimpleFormatter;
|
||||
import org.openide.util.NbBundle;
|
||||
import org.sleuthkit.autopsy.casemodule.Case;
|
||||
import org.sleuthkit.autopsy.core.RuntimeProperties;
|
||||
import org.sleuthkit.autopsy.coreutils.MessageNotifyUtil;
|
||||
import org.sleuthkit.autopsy.coreutils.PlatformUtil;
|
||||
import org.sleuthkit.autopsy.keywordsearch.KeywordSearchResultFactory.BlackboardResultWriter;
|
||||
@@ -110,33 +112,60 @@ public class KeywordSearch {
|
||||
}
|
||||
|
||||
/**
|
||||
* Listener to swap cores when the case changes
|
||||
* Listener to create/open and close Solr cores when cases are
|
||||
* created/opened and closed.
|
||||
*/
|
||||
static class CaseChangeListener implements PropertyChangeListener {
|
||||
|
||||
@Override
|
||||
public void propertyChange(PropertyChangeEvent evt) {
|
||||
/*
|
||||
* TODO (AUT-2081): There is a Solr core unloading bug, fixed in
|
||||
* Solr 5.4, that results in the co-existence of a core.properties
|
||||
* file and a core.properties.unloaded file in the core instance
|
||||
* directory when a core is closed/unloaded. When this happens,
|
||||
* subsequent core open/load attempts will fail. The workaround for
|
||||
* single-user cases is to close and reopen Autopsy so that a new
|
||||
* server instance gets spun up.
|
||||
*/
|
||||
if (evt.getPropertyName().equals(Case.Events.CURRENT_CASE.toString())) {
|
||||
if (null != evt.getOldValue()) {
|
||||
/*
|
||||
* A case is being closed.
|
||||
*/
|
||||
Case closedCase = (Case) evt.getOldValue();
|
||||
try {
|
||||
BlackboardResultWriter.stopAllWriters();
|
||||
Thread.sleep(2000); // TODO (RC): This is a fragile way to wait here.
|
||||
/*
|
||||
* TODO (AUT-2084): The following code
|
||||
* KeywordSearch.CaseChangeListener gambles that any
|
||||
* BlackboardResultWriters (SwingWorkers) will complete
|
||||
* in less than roughly two seconds
|
||||
*/
|
||||
Thread.sleep(2000);
|
||||
server.closeCore();
|
||||
} catch (Exception ex) {
|
||||
String caseName = closedCase.getName();
|
||||
logger.log(Level.SEVERE, String.format("Failed to close core for %s", caseName), ex); //NON-NLS
|
||||
MessageNotifyUtil.Notify.error(NbBundle.getMessage(KeywordSearch.class, "KeywordSearch.closeCore.notification.msg"), ex.getMessage());
|
||||
String caseId = Paths.get(closedCase.getCaseDirectory(), closedCase.getName()).toString();
|
||||
logger.log(Level.SEVERE, String.format("Failed to close core for %s", caseId), ex); //NON-NLS
|
||||
if (RuntimeProperties.coreComponentsAreActive()) {
|
||||
MessageNotifyUtil.Notify.error(NbBundle.getMessage(KeywordSearch.class, "KeywordSearch.closeCore.notification.msg"), ex.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (null != evt.getNewValue()) {
|
||||
/*
|
||||
* A case is being created/opened.
|
||||
*/
|
||||
Case openedCase = (Case) evt.getNewValue();
|
||||
try {
|
||||
server.openCoreForCase(openedCase);
|
||||
} catch (Exception ex) {
|
||||
String caseName = openedCase.getName();
|
||||
logger.log(Level.SEVERE, String.format("Failed to open or create core for %s", caseName), ex); //NON-NLS
|
||||
MessageNotifyUtil.Notify.error(NbBundle.getMessage(KeywordSearch.class, "KeywordSearch.openCore.notification.msg"), ex.getMessage());
|
||||
String caseId = Paths.get(openedCase.getCaseDirectory(), openedCase.getName()).toString();
|
||||
logger.log(Level.SEVERE, String.format("Failed to open or create core for %s", caseId), ex); //NON-NLS
|
||||
if (RuntimeProperties.coreComponentsAreActive()) {
|
||||
MessageNotifyUtil.Notify.error(NbBundle.getMessage(KeywordSearch.class, "KeywordSearch.openCore.notification.msg"), ex.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* Autopsy Forensic Browser
|
||||
*
|
||||
* Copyright 2011-2015 Basis Technology Corp.
|
||||
* Copyright 2011-2016 Basis Technology Corp.
|
||||
* Contact: carrier <at> sleuthkit <dot> org
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
@@ -66,14 +66,16 @@ import org.apache.solr.common.SolrException;
|
||||
import org.sleuthkit.autopsy.casemodule.Case.CaseType;
|
||||
import org.sleuthkit.autopsy.coreutils.UNCPathUtilities;
|
||||
import org.sleuthkit.autopsy.core.UserPreferences;
|
||||
import org.sleuthkit.autopsy.coreutils.MessageNotifyUtil;
|
||||
|
||||
/**
|
||||
* Handles for keeping track of a Solr server and its cores
|
||||
* Handles management of a either a local or centralized Solr server and its
|
||||
* cores.
|
||||
*/
|
||||
public class Server {
|
||||
|
||||
// field names that are used in SOLR schema
|
||||
/**
|
||||
* Solr document field names.
|
||||
*/
|
||||
public static enum Schema {
|
||||
|
||||
ID {
|
||||
@@ -148,6 +150,7 @@ public class Server {
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
public static final String HL_ANALYZE_CHARS_UNLIMITED = "500000"; //max 1MB in a chunk. use -1 for unlimited, but -1 option may not be supported (not documented)
|
||||
//max content size we can send to Solr
|
||||
public static final long MAX_CONTENT_SIZE = 1L * 1024 * 1024 * 1024;
|
||||
@@ -196,7 +199,7 @@ public class Server {
|
||||
*/
|
||||
Server() {
|
||||
initSettings();
|
||||
|
||||
|
||||
this.localSolrServer = new HttpSolrServer("http://localhost:" + currentSolrServerPort + "/solr"); //NON-NLS
|
||||
serverAction = new ServerAction();
|
||||
solrFolder = InstalledFileLocator.getDefault().locate("solr", Server.class.getPackage().getName(), false); //NON-NLS
|
||||
@@ -204,7 +207,7 @@ public class Server {
|
||||
|
||||
currentCoreLock = new ReentrantReadWriteLock(true);
|
||||
uncPathUtilities = new UNCPathUtilities();
|
||||
|
||||
|
||||
logger.log(Level.INFO, "Created Server instance"); //NON-NLS
|
||||
}
|
||||
|
||||
@@ -596,11 +599,13 @@ public class Server {
|
||||
* ** Convenience methods for use while we only open one case at a time ***
|
||||
*/
|
||||
/**
|
||||
* Opens or creates a core (index) for a case.
|
||||
* Creates/opens a Solr core (index) for a case.
|
||||
*
|
||||
* @param theCase the case for which the core is to be opened or created.
|
||||
* @param theCase The case for which the core is to be created/opened.
|
||||
*
|
||||
* @throws KeywordSearchModuleException
|
||||
*
|
||||
* @throws KeywordSearchModuleException If an error occurs while
|
||||
* creating/opening the core.
|
||||
*/
|
||||
void openCoreForCase(Case theCase) throws KeywordSearchModuleException {
|
||||
currentCoreLock.writeLock().lock();
|
||||
@@ -630,6 +635,15 @@ public class Server {
|
||||
currentCoreLock.writeLock().lock();
|
||||
try {
|
||||
if (null != currentCore) {
|
||||
/*
|
||||
* TODO (AUT-2081): There is a Solr core unloading bug, fixed in
|
||||
* Solr 5.4, that will result in the co-existence of a
|
||||
* core.properties file and a core.properties.unloaded file in
|
||||
* the core instance directory when the following code executes.
|
||||
* When this happens, subsequent open/load attempts will fail.
|
||||
* The workaround for single-user cases is to close and reopen
|
||||
* Autopsy so that a new server instance gets spun up.
|
||||
*/
|
||||
currentCore.close();
|
||||
currentCore = null;
|
||||
serverAction.putValue(CORE_EVT, CORE_EVT_STATES.STOPPED);
|
||||
@@ -655,7 +669,7 @@ public class Server {
|
||||
*
|
||||
* @return absolute path to index dir
|
||||
*/
|
||||
String getIndexDirPath(Case theCase) {
|
||||
String geCoreDataDirPath(Case theCase) {
|
||||
String indexDir = theCase.getModuleDirectory() + File.separator + "keywordsearch" + File.separator + "data"; //NON-NLS
|
||||
if (uncPathUtilities != null) {
|
||||
// if we can check for UNC paths, do so, otherwise just return the indexDir
|
||||
@@ -676,11 +690,14 @@ public class Server {
|
||||
* ** end single-case specific methods ***
|
||||
*/
|
||||
/**
|
||||
* Open a core for the given case
|
||||
* Creates/opens a Solr core (index) for a case.
|
||||
*
|
||||
* @param theCase the case to open core for
|
||||
* @param theCase The case for which the core is to be created/opened.
|
||||
*
|
||||
* @return
|
||||
* @return An object representing the created/opened core.
|
||||
*
|
||||
* @throws KeywordSearchModuleException If an error occurs while
|
||||
* creating/opening the core.
|
||||
*/
|
||||
private Core openCore(Case theCase) throws KeywordSearchModuleException {
|
||||
try {
|
||||
@@ -692,11 +709,12 @@ public class Server {
|
||||
currentSolrServer = new HttpSolrServer("http://" + host + ":" + port + "/solr"); //NON-NLS
|
||||
}
|
||||
connectToSolrServer(currentSolrServer);
|
||||
|
||||
} catch (SolrServerException | IOException ex) {
|
||||
throw new KeywordSearchModuleException(NbBundle.getMessage(Server.class, "Server.connect.exception.msg"), ex);
|
||||
}
|
||||
|
||||
String dataDir = getIndexDirPath(theCase);
|
||||
String dataDir = geCoreDataDirPath(theCase);
|
||||
String coreName = theCase.getTextIndexName();
|
||||
return this.openCore(coreName.isEmpty() ? DEFAULT_CORE_NAME : coreName, new File(dataDir), theCase.getCaseType());
|
||||
}
|
||||
@@ -1050,12 +1068,17 @@ public class Server {
|
||||
}
|
||||
|
||||
/**
|
||||
* Open a new core
|
||||
* Creates/opens a Solr core (index) for a case.
|
||||
*
|
||||
* @param coreName name to refer to the core by in Solr
|
||||
* @param dataDir directory to load/store the core data from/to
|
||||
* @param coreName The core name.
|
||||
* @param dataDir The data directory for the core.
|
||||
* @param caseType The type of the case (single-user or multi-user) for
|
||||
* which the core is being created/opened.
|
||||
*
|
||||
* @return new core
|
||||
* @return An object representing the created/opened core.
|
||||
*
|
||||
* @throws KeywordSearchModuleException If an error occurs while
|
||||
* creating/opening the core.
|
||||
*/
|
||||
private Core openCore(String coreName, File dataDir, CaseType caseType) throws KeywordSearchModuleException {
|
||||
|
||||
@@ -1064,14 +1087,25 @@ public class Server {
|
||||
dataDir.mkdirs();
|
||||
}
|
||||
|
||||
//handle a possible scenario when server process might not be fully started
|
||||
if (!this.isRunning()) {
|
||||
logger.log(Level.WARNING, "Core open requested, but server not yet running"); //NON-NLS
|
||||
throw new KeywordSearchModuleException(
|
||||
NbBundle.getMessage(this.getClass(), "Server.openCore.exception.msg"));
|
||||
logger.log(Level.SEVERE, "Core create/open requested, but server not yet running"); //NON-NLS
|
||||
throw new KeywordSearchModuleException(NbBundle.getMessage(this.getClass(), "Server.openCore.exception.msg"));
|
||||
}
|
||||
|
||||
if (!coreExistsOnServer(coreName)) {
|
||||
if (!coreIsLoaded(coreName)) {
|
||||
/*
|
||||
* The core either does not exist or it is not loaded. Make a
|
||||
* request that will cause the core to be created if it does not
|
||||
* exist or loaded if it already exists.
|
||||
*
|
||||
* TODO (AUT-2081): There is a Solr core unloading bug, fixed in
|
||||
* Solr 5.4, that results in the co-existence of a
|
||||
* core.properties file and a core.properties.unloaded file in
|
||||
* the core instance directory when a core is unloaded. When
|
||||
* this happens, this code will fail. The workaround for
|
||||
* single-user cases is to close and reopen Autopsy so that a
|
||||
* new server instance gets spun up.
|
||||
*/
|
||||
CoreAdminRequest.Create createCoreRequest = new CoreAdminRequest.Create();
|
||||
createCoreRequest.setDataDir(dataDir.getAbsolutePath());
|
||||
createCoreRequest.setCoreName(coreName);
|
||||
@@ -1088,8 +1122,7 @@ public class Server {
|
||||
return new Core(coreName, caseType);
|
||||
|
||||
} catch (SolrServerException | SolrException | IOException ex) {
|
||||
throw new KeywordSearchModuleException(
|
||||
NbBundle.getMessage(this.getClass(), "Server.openCore.exception.cantOpen.msg"), ex);
|
||||
throw new KeywordSearchModuleException(NbBundle.getMessage(this.getClass(), "Server.openCore.exception.cantOpen.msg"), ex);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1106,17 +1139,19 @@ public class Server {
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines whether or not a Solr core instance exists on the current Solr
|
||||
* server.
|
||||
* Determines whether or not a particular Solr core exists and is loaded.
|
||||
*
|
||||
* @param coreName the name of the core.
|
||||
* @param coreName The name of the core.
|
||||
*
|
||||
* @return true or false.
|
||||
* @return True if the core exists and is loaded, false if the core does not
|
||||
* exist or is not loaded
|
||||
*
|
||||
* @throws SolrServerException
|
||||
* @throws IOException
|
||||
* @throws SolrServerException If there is a problem communicating with the
|
||||
* Solr server.
|
||||
* @throws IOException If there is a problem communicating with the
|
||||
* Solr server.
|
||||
*/
|
||||
private boolean coreExistsOnServer(String coreName) throws SolrServerException, IOException {
|
||||
private boolean coreIsLoaded(String coreName) throws SolrServerException, IOException {
|
||||
CoreAdminResponse response = CoreAdminRequest.getStatus(coreName, currentSolrServer);
|
||||
return response.getCoreStatus(coreName).get("instanceDir") != null; //NON-NLS
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
Improvements:
|
||||
- VMWare virtual machine files (vmdk) and Microsoft Virtual Hard Drives (vhd) can be added as data sources.
|
||||
- New core ingest module detects vmdk and vhd files embedded in other data sources and adds them as data sources.
|
||||
- Text associated with artifacts posted to the blackboard is indexed and searched for keywords.
|
||||
- Custom (user-defined) blackboard artifact and attribute types displayed in UI and included reports.
|
||||
- File size and MIME type conditions can be specified for interesting files rules.
|
||||
- File size and MIME type conditions can be specified for file search by attributes.
|
||||
|
||||
@@ -277,8 +277,8 @@ class SearchEngineURLQueryAnalyzer extends Extract {
|
||||
int totalQueries = 0;
|
||||
try {
|
||||
//from blackboard_artifacts
|
||||
Collection<BlackboardArtifact> listArtifacts = currentCase.getSleuthkitCase().getMatchingArtifacts("WHERE (artifact_type_id = '" + ARTIFACT_TYPE.TSK_WEB_BOOKMARK.getTypeID() //NON-NLS
|
||||
+ "' OR artifact_type_id = '" + ARTIFACT_TYPE.TSK_WEB_HISTORY.getTypeID() + "') "); //List of every 'web_history' and 'bookmark' artifact NON-NLS
|
||||
Collection<BlackboardArtifact> listArtifacts = currentCase.getSleuthkitCase().getMatchingArtifacts("WHERE (blackboard_artifacts.artifact_type_id = '" + ARTIFACT_TYPE.TSK_WEB_BOOKMARK.getTypeID() //NON-NLS
|
||||
+ "' OR blackboard_artifacts.artifact_type_id = '" + ARTIFACT_TYPE.TSK_WEB_HISTORY.getTypeID() + "') "); //List of every 'web_history' and 'bookmark' artifact NON-NLS
|
||||
logger.log(Level.INFO, "Processing {0} blackboard artifacts.", listArtifacts.size()); //NON-NLS
|
||||
|
||||
for (BlackboardArtifact artifact : listArtifacts) {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#Updated by build script
|
||||
#Mon, 22 Feb 2016 16:37:47 -0500
|
||||
#Wed, 06 Apr 2016 23:58:02 -0400
|
||||
LBL_splash_window_title=Starting Autopsy
|
||||
SPLASH_HEIGHT=314
|
||||
SPLASH_WIDTH=538
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#Updated by build script
|
||||
#Mon, 22 Feb 2016 16:37:47 -0500
|
||||
#Wed, 06 Apr 2016 23:58:02 -0400
|
||||
CTL_MainWindow_Title=Autopsy 4.1.0
|
||||
CTL_MainWindow_Title_No_Project=Autopsy 4.1.0
|
||||
|
||||
@@ -38,7 +38,7 @@ PROJECT_NAME = "Autopsy User Documentation"
|
||||
# could be handy for archiving the generated documentation or if some version
|
||||
# control system is used.
|
||||
|
||||
PROJECT_NUMBER = 4.0
|
||||
PROJECT_NUMBER = 4.1
|
||||
|
||||
# Using the PROJECT_BRIEF tag one can provide an optional one line description
|
||||
# for a project that appears at the top of each page and should give viewer a
|
||||
@@ -1025,7 +1025,7 @@ GENERATE_HTML = YES
|
||||
# The default directory is: html.
|
||||
# This tag requires that the tag GENERATE_HTML is set to YES.
|
||||
|
||||
HTML_OUTPUT = 4.0
|
||||
HTML_OUTPUT = 4.1
|
||||
|
||||
# The HTML_FILE_EXTENSION tag can be used to specify the file extension for each
|
||||
# generated HTML page (for example: .htm, .php, .asp).
|
||||
|
||||
|
Before Width: | Height: | Size: 20 KiB After Width: | Height: | Size: 48 KiB |
|
Before Width: | Height: | Size: 48 KiB After Width: | Height: | Size: 51 KiB |
|
Before Width: | Height: | Size: 21 KiB After Width: | Height: | Size: 48 KiB |
|
Before Width: | Height: | Size: 38 KiB After Width: | Height: | Size: 52 KiB |
|
Before Width: | Height: | Size: 44 KiB After Width: | Height: | Size: 40 KiB |
@@ -4,7 +4,7 @@
|
||||
Overview
|
||||
-----
|
||||
|
||||
This is the User's Guide for the <a href="http://www.sleuthkit.org/autopsy/">open source Autopsy platform</a>. Autopsy allows you to examine a hard drive or mobile device and recover evidence from it. This guide should help you with using Autopsy. The <a href="http://www.sleuthkit.org/autopsy/docs/api-docs/4.0/"> developer's guide</a> will help you develop your own Autopsy modules.
|
||||
This is the User's Guide for the <a href="http://www.sleuthkit.org/autopsy/">open source Autopsy platform</a>. Autopsy allows you to examine a hard drive or mobile device and recover evidence from it. This guide should help you with using Autopsy. The <a href="http://www.sleuthkit.org/autopsy/docs/api-docs/4.1/"> developer's guide</a> will help you develop your own Autopsy modules.
|
||||
|
||||
Autopsy 4 (and 3) are a complete rewrite from Autopsy 2, and none of this document is relevant to Autopsy 2.
|
||||
|
||||
|
||||
@@ -38,7 +38,7 @@ PROJECT_NAME = "Autopsy"
|
||||
# could be handy for archiving the generated documentation or if some version
|
||||
# control system is used.
|
||||
|
||||
PROJECT_NUMBER = 4.0
|
||||
PROJECT_NUMBER = 4.1
|
||||
|
||||
# Using the PROJECT_BRIEF tag one can provide an optional one line description
|
||||
# for a project that appears at the top of each page and should give viewer a
|
||||
@@ -1063,7 +1063,7 @@ GENERATE_HTML = YES
|
||||
# The default directory is: html.
|
||||
# This tag requires that the tag GENERATE_HTML is set to YES.
|
||||
|
||||
HTML_OUTPUT = api-docs/4.0/
|
||||
HTML_OUTPUT = api-docs/4.1/
|
||||
|
||||
# The HTML_FILE_EXTENSION tag can be used to specify the file extension for each
|
||||
# generated HTML page (for example: .htm, .php, .asp).
|
||||
|
||||