mirror of
https://github.com/overcuriousity/autopsy-flatpak.git
synced 2025-07-13 08:26:15 +00:00
Merge remote-tracking branch 'upstream/develop' into aut-1885
This commit is contained in:
commit
ca35916ed2
@ -2,7 +2,7 @@ Manifest-Version: 1.0
|
|||||||
OpenIDE-Module: org.sleuthkit.autopsy.core/10
|
OpenIDE-Module: org.sleuthkit.autopsy.core/10
|
||||||
OpenIDE-Module-Localizing-Bundle: org/sleuthkit/autopsy/core/Bundle.properties
|
OpenIDE-Module-Localizing-Bundle: org/sleuthkit/autopsy/core/Bundle.properties
|
||||||
OpenIDE-Module-Layer: org/sleuthkit/autopsy/core/layer.xml
|
OpenIDE-Module-Layer: org/sleuthkit/autopsy/core/layer.xml
|
||||||
OpenIDE-Module-Implementation-Version: 15
|
OpenIDE-Module-Implementation-Version: 16
|
||||||
OpenIDE-Module-Requires: org.openide.windows.WindowManager
|
OpenIDE-Module-Requires: org.openide.windows.WindowManager
|
||||||
AutoUpdate-Show-In-Client: true
|
AutoUpdate-Show-In-Client: true
|
||||||
AutoUpdate-Essential-Module: true
|
AutoUpdate-Essential-Module: true
|
||||||
|
@ -21,5 +21,5 @@ nbm.homepage=http://www.sleuthkit.org/
|
|||||||
nbm.module.author=Brian Carrier
|
nbm.module.author=Brian Carrier
|
||||||
nbm.needs.restart=true
|
nbm.needs.restart=true
|
||||||
source.reference.metadata-extractor-2.8.1.jar=release/modules/ext/metadata-extractor-2.8.1-src.zip!/Source/
|
source.reference.metadata-extractor-2.8.1.jar=release/modules/ext/metadata-extractor-2.8.1-src.zip!/Source/
|
||||||
spec.version.base=10.4
|
spec.version.base=10.5
|
||||||
|
|
||||||
|
@ -177,7 +177,7 @@
|
|||||||
<compile-dependency/>
|
<compile-dependency/>
|
||||||
<run-dependency>
|
<run-dependency>
|
||||||
<release-version>3</release-version>
|
<release-version>3</release-version>
|
||||||
<specification-version>1.0</specification-version>
|
<specification-version>1.1</specification-version>
|
||||||
</run-dependency>
|
</run-dependency>
|
||||||
</dependency>
|
</dependency>
|
||||||
</module-dependencies>
|
</module-dependencies>
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* Autopsy Forensic Browser
|
* Autopsy Forensic Browser
|
||||||
*
|
*
|
||||||
* Copyright 2013 Basis Technology Corp.
|
* Copyright 2011-2016 Basis Technology Corp.
|
||||||
* Contact: carrier <at> sleuthkit <dot> org
|
* Contact: carrier <at> sleuthkit <dot> org
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
@ -40,6 +40,7 @@ import org.sleuthkit.datamodel.TskCoreException;
|
|||||||
|
|
||||||
public class GetTagNameAndCommentDialog extends JDialog {
|
public class GetTagNameAndCommentDialog extends JDialog {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
private static final String NO_TAG_NAMES_MESSAGE = NbBundle.getMessage(GetTagNameAndCommentDialog.class,
|
private static final String NO_TAG_NAMES_MESSAGE = NbBundle.getMessage(GetTagNameAndCommentDialog.class,
|
||||||
"GetTagNameAndCommentDialog.noTags");
|
"GetTagNameAndCommentDialog.noTags");
|
||||||
private final HashMap<String, TagName> tagNames = new HashMap<>();
|
private final HashMap<String, TagName> tagNames = new HashMap<>();
|
||||||
@ -47,8 +48,8 @@ public class GetTagNameAndCommentDialog extends JDialog {
|
|||||||
|
|
||||||
public static class TagNameAndComment {
|
public static class TagNameAndComment {
|
||||||
|
|
||||||
private TagName tagName;
|
private final TagName tagName;
|
||||||
private String comment;
|
private final String comment;
|
||||||
|
|
||||||
private TagNameAndComment(TagName tagName, String comment) {
|
private TagNameAndComment(TagName tagName, String comment) {
|
||||||
this.tagName = tagName;
|
this.tagName = tagName;
|
||||||
@ -67,8 +68,7 @@ public class GetTagNameAndCommentDialog extends JDialog {
|
|||||||
/**
|
/**
|
||||||
* Show the Tag Name and Comment Dialog and return the TagNameAndContent
|
* Show the Tag Name and Comment Dialog and return the TagNameAndContent
|
||||||
* chosen by the user. The dialog will be centered with the main autopsy
|
* chosen by the user. The dialog will be centered with the main autopsy
|
||||||
* window as its owner. To set another window as the owner use {@link #doDialog(java.awt.Window)
|
* window as its owner.
|
||||||
* }
|
|
||||||
*
|
*
|
||||||
* @return a TagNameAndComment instance containing the TagName selected by
|
* @return a TagNameAndComment instance containing the TagName selected by
|
||||||
* the user and the entered comment, or null if the user canceled
|
* the user and the entered comment, or null if the user canceled
|
||||||
|
@ -35,6 +35,7 @@ import org.openide.util.HelpCtx;
|
|||||||
import org.sleuthkit.datamodel.Content;
|
import org.sleuthkit.datamodel.Content;
|
||||||
import org.sleuthkit.autopsy.corecomponentinterfaces.DataSourceProcessorCallback;
|
import org.sleuthkit.autopsy.corecomponentinterfaces.DataSourceProcessorCallback;
|
||||||
import org.sleuthkit.autopsy.corecomponentinterfaces.DataSourceProcessor;
|
import org.sleuthkit.autopsy.corecomponentinterfaces.DataSourceProcessor;
|
||||||
|
import org.sleuthkit.autopsy.coreutils.PlatformUtil;
|
||||||
import org.sleuthkit.autopsy.ingest.IngestJobSettings;
|
import org.sleuthkit.autopsy.ingest.IngestJobSettings;
|
||||||
import org.sleuthkit.autopsy.ingest.IngestJobSettingsPanel;
|
import org.sleuthkit.autopsy.ingest.IngestJobSettingsPanel;
|
||||||
import org.sleuthkit.autopsy.ingest.IngestManager;
|
import org.sleuthkit.autopsy.ingest.IngestManager;
|
||||||
@ -271,7 +272,10 @@ class AddImageWizardIngestConfigPanel implements WizardDescriptor.Panel<WizardDe
|
|||||||
cleanupTask.disable();
|
cleanupTask.disable();
|
||||||
|
|
||||||
// Get attention for the process finish
|
// Get attention for the process finish
|
||||||
|
// this caused a crash on OS X
|
||||||
|
if (PlatformUtil.isWindowsOS() == true) {
|
||||||
java.awt.Toolkit.getDefaultToolkit().beep(); //BEEP!
|
java.awt.Toolkit.getDefaultToolkit().beep(); //BEEP!
|
||||||
|
}
|
||||||
AddImageWizardAddingProgressVisual panel = progressPanel.getComponent();
|
AddImageWizardAddingProgressVisual panel = progressPanel.getComponent();
|
||||||
if (panel != null) {
|
if (panel != null) {
|
||||||
Window w = SwingUtilities.getWindowAncestor(panel);
|
Window w = SwingUtilities.getWindowAncestor(panel);
|
||||||
|
@ -252,5 +252,6 @@ SingleUserCaseConverter.CanNotOpenDatabase=Unable to open database
|
|||||||
CloseCaseWhileIngesting.Warning=Ingest is running. Are you sure you want to close the case?
|
CloseCaseWhileIngesting.Warning=Ingest is running. Are you sure you want to close the case?
|
||||||
CloseCaseWhileIngesting.Warning.title=Warning\: This will close the current case
|
CloseCaseWhileIngesting.Warning.title=Warning\: This will close the current case
|
||||||
CasePropertiesForm.imagesTable.columnModel.title1=Remove
|
CasePropertiesForm.imagesTable.columnModel.title1=Remove
|
||||||
|
|
||||||
CasePropertiesForm.imagesTable.columnModel.title0=Path
|
CasePropertiesForm.imagesTable.columnModel.title0=Path
|
||||||
|
LocalFilesPanel.jButton1.text=Change
|
||||||
|
LocalFilesPanel.displayNameLabel.text=Logical File Set Display Name: Default
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* Autopsy Forensic Browser
|
* Autopsy Forensic Browser
|
||||||
*
|
*
|
||||||
* Copyright 2011-2015 Basis Technology Corp.
|
* Copyright 2011-2016 Basis Technology Corp.
|
||||||
* Contact: carrier <at> sleuthkit <dot> org
|
* Contact: carrier <at> sleuthkit <dot> org
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
@ -711,16 +711,14 @@ public class Case implements SleuthkitCase.ErrorObserver {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Adds the image to the current case after it has been added to the DB.
|
* Adds an image to the current case after it has been added to the DB.
|
||||||
* Sends out event and reopens windows if needed.
|
* Sends out event and reopens windows if needed.
|
||||||
*
|
*
|
||||||
* @param imgPaths the paths of the image that being added
|
* @param imgPath The path of the image file.
|
||||||
* @param imgId the ID of the image that being added
|
* @param imgId The ID of the image.
|
||||||
* @param timeZone the timeZone of the image where it's added
|
* @param timeZone The time zone of the image.
|
||||||
*
|
*
|
||||||
* @deprecated As of release 4.0, replaced by {@link #notifyAddingDataSource(java.util.UUID) and
|
* @deprecated As of release 4.0
|
||||||
* {@link #notifyDataSourceAdded(org.sleuthkit.datamodel.Content, java.util.UUID) and
|
|
||||||
* {@link #notifyFailedAddingDataSource(java.util.UUID)}
|
|
||||||
*/
|
*/
|
||||||
@Deprecated
|
@Deprecated
|
||||||
public Image addImage(String imgPath, long imgId, String timeZone) throws CaseActionException {
|
public Image addImage(String imgPath, long imgId, String timeZone) throws CaseActionException {
|
||||||
|
@ -190,9 +190,9 @@ public class LocalDiskDSProcessor implements DataSourceProcessor {
|
|||||||
* Sets the configuration of the data source processor without using the
|
* Sets the configuration of the data source processor without using the
|
||||||
* configuration panel.
|
* configuration panel.
|
||||||
*
|
*
|
||||||
* @param imagePath Path to the image file.
|
* @param drivePath Path to the local drive.
|
||||||
* @param timeZone The time zone to use when processing dates
|
* @param timeZone The time zone to use when processing dates
|
||||||
* and times for the image, obtained from
|
* and times for the local drive, obtained from
|
||||||
* java.util.TimeZone.getID.
|
* java.util.TimeZone.getID.
|
||||||
* @param ignoreFatOrphanFiles Whether to parse orphans if the image has a
|
* @param ignoreFatOrphanFiles Whether to parse orphans if the image has a
|
||||||
* FAT filesystem.
|
* FAT filesystem.
|
||||||
|
@ -43,7 +43,6 @@ public class LocalFilesDSProcessor implements DataSourceProcessor {
|
|||||||
* TODO: Remove the setDataSourceOptionsCalled flag and the settings fields
|
* TODO: Remove the setDataSourceOptionsCalled flag and the settings fields
|
||||||
* when the deprecated method setDataSourceOptions is removed.
|
* when the deprecated method setDataSourceOptions is removed.
|
||||||
*/
|
*/
|
||||||
private String deviceId;
|
|
||||||
private List<String> localFilePaths;
|
private List<String> localFilePaths;
|
||||||
private boolean setDataSourceOptionsCalled;
|
private boolean setDataSourceOptionsCalled;
|
||||||
|
|
||||||
@ -123,10 +122,9 @@ public class LocalFilesDSProcessor implements DataSourceProcessor {
|
|||||||
@Override
|
@Override
|
||||||
public void run(DataSourceProcessorProgressMonitor progressMonitor, DataSourceProcessorCallback callback) {
|
public void run(DataSourceProcessorProgressMonitor progressMonitor, DataSourceProcessorCallback callback) {
|
||||||
if (!setDataSourceOptionsCalled) {
|
if (!setDataSourceOptionsCalled) {
|
||||||
deviceId = UUID.randomUUID().toString();
|
|
||||||
localFilePaths = Arrays.asList(configPanel.getContentPaths().split(LocalFilesPanel.FILES_SEP));
|
localFilePaths = Arrays.asList(configPanel.getContentPaths().split(LocalFilesPanel.FILES_SEP));
|
||||||
}
|
}
|
||||||
run(deviceId, "", localFilePaths, progressMonitor, callback);
|
run(UUID.randomUUID().toString(), configPanel.getFileSetName(), localFilePaths, progressMonitor, callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -194,7 +192,8 @@ public class LocalFilesDSProcessor implements DataSourceProcessor {
|
|||||||
*/
|
*/
|
||||||
@Deprecated
|
@Deprecated
|
||||||
public void setDataSourceOptions(String paths) {
|
public void setDataSourceOptions(String paths) {
|
||||||
this.localFilePaths = Arrays.asList(configPanel.getContentPaths().split(LocalFilesPanel.FILES_SEP));
|
//LocalFilesPanel.FILES_SEP is currently ","
|
||||||
|
this.localFilePaths = Arrays.asList(paths.split(LocalFilesPanel.FILES_SEP));
|
||||||
setDataSourceOptionsCalled = true;
|
setDataSourceOptionsCalled = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -47,21 +47,30 @@
|
|||||||
<Layout>
|
<Layout>
|
||||||
<DimensionLayout dim="0">
|
<DimensionLayout dim="0">
|
||||||
<Group type="103" groupAlignment="0" attributes="0">
|
<Group type="103" groupAlignment="0" attributes="0">
|
||||||
<Group type="102" alignment="0" attributes="0">
|
<Group type="102" alignment="1" attributes="0">
|
||||||
|
<Group type="103" groupAlignment="0" attributes="0">
|
||||||
|
<Group type="102" attributes="0">
|
||||||
<Component id="infoLabel" min="-2" max="-2" attributes="0"/>
|
<Component id="infoLabel" min="-2" max="-2" attributes="0"/>
|
||||||
<EmptySpace min="0" pref="0" max="32767" attributes="0"/>
|
<EmptySpace min="0" pref="0" max="32767" attributes="0"/>
|
||||||
</Group>
|
</Group>
|
||||||
<Group type="102" alignment="1" attributes="0">
|
<Component id="jScrollPane2" pref="389" max="32767" attributes="0"/>
|
||||||
<Component id="jScrollPane2" pref="353" max="32767" attributes="0"/>
|
</Group>
|
||||||
<EmptySpace max="-2" attributes="0"/>
|
<EmptySpace max="-2" attributes="0"/>
|
||||||
<Group type="103" groupAlignment="0" max="-2" attributes="0">
|
<Group type="103" groupAlignment="0" max="-2" attributes="0">
|
||||||
<Component id="selectButton" max="32767" attributes="0"/>
|
<Component id="selectButton" max="32767" attributes="0"/>
|
||||||
<Component id="clearButton" max="32767" attributes="0"/>
|
<Component id="clearButton" pref="69" max="32767" attributes="0"/>
|
||||||
</Group>
|
</Group>
|
||||||
<EmptySpace min="-2" pref="2" max="-2" attributes="0"/>
|
<EmptySpace min="-2" pref="2" max="-2" attributes="0"/>
|
||||||
</Group>
|
</Group>
|
||||||
<Group type="102" alignment="0" attributes="0">
|
<Group type="102" attributes="0">
|
||||||
|
<Group type="103" groupAlignment="0" attributes="0">
|
||||||
<Component id="errorLabel" min="-2" max="-2" attributes="0"/>
|
<Component id="errorLabel" min="-2" max="-2" attributes="0"/>
|
||||||
|
<Group type="102" attributes="0">
|
||||||
|
<Component id="displayNameLabel" min="-2" max="-2" attributes="0"/>
|
||||||
|
<EmptySpace type="unrelated" max="-2" attributes="0"/>
|
||||||
|
<Component id="jButton1" min="-2" max="-2" attributes="0"/>
|
||||||
|
</Group>
|
||||||
|
</Group>
|
||||||
<EmptySpace max="32767" attributes="0"/>
|
<EmptySpace max="32767" attributes="0"/>
|
||||||
</Group>
|
</Group>
|
||||||
</Group>
|
</Group>
|
||||||
@ -70,17 +79,23 @@
|
|||||||
<Group type="103" groupAlignment="0" attributes="0">
|
<Group type="103" groupAlignment="0" attributes="0">
|
||||||
<Group type="102" alignment="0" attributes="0">
|
<Group type="102" alignment="0" attributes="0">
|
||||||
<Component id="infoLabel" min="-2" max="-2" attributes="0"/>
|
<Component id="infoLabel" min="-2" max="-2" attributes="0"/>
|
||||||
<EmptySpace min="-2" pref="5" max="-2" attributes="0"/>
|
<EmptySpace max="-2" attributes="0"/>
|
||||||
<Group type="103" groupAlignment="0" max="-2" attributes="0">
|
<Group type="103" groupAlignment="1" attributes="0">
|
||||||
<Component id="jScrollPane2" min="-2" pref="82" max="-2" attributes="0"/>
|
|
||||||
<Group type="102" attributes="0">
|
<Group type="102" attributes="0">
|
||||||
<Component id="selectButton" min="-2" max="-2" attributes="0"/>
|
<Component id="selectButton" min="-2" max="-2" attributes="0"/>
|
||||||
<EmptySpace max="32767" attributes="0"/>
|
<EmptySpace min="-2" pref="36" max="-2" attributes="0"/>
|
||||||
<Component id="clearButton" min="-2" max="-2" attributes="0"/>
|
<Component id="clearButton" min="-2" max="-2" attributes="0"/>
|
||||||
</Group>
|
</Group>
|
||||||
|
<Component id="jScrollPane2" min="-2" pref="82" max="-2" attributes="0"/>
|
||||||
</Group>
|
</Group>
|
||||||
<EmptySpace max="-2" attributes="0"/>
|
<EmptySpace type="separate" max="-2" attributes="0"/>
|
||||||
|
<Group type="103" groupAlignment="3" attributes="0">
|
||||||
|
<Component id="jButton1" alignment="3" min="-2" pref="20" max="-2" attributes="0"/>
|
||||||
|
<Component id="displayNameLabel" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||||
|
</Group>
|
||||||
|
<EmptySpace min="-2" pref="13" max="-2" attributes="0"/>
|
||||||
<Component id="errorLabel" min="-2" max="-2" attributes="0"/>
|
<Component id="errorLabel" min="-2" max="-2" attributes="0"/>
|
||||||
|
<EmptySpace min="-2" pref="7" max="-2" attributes="0"/>
|
||||||
</Group>
|
</Group>
|
||||||
</Group>
|
</Group>
|
||||||
</DimensionLayout>
|
</DimensionLayout>
|
||||||
@ -151,5 +166,22 @@
|
|||||||
</Property>
|
</Property>
|
||||||
</Properties>
|
</Properties>
|
||||||
</Component>
|
</Component>
|
||||||
|
<Component class="javax.swing.JButton" name="jButton1">
|
||||||
|
<Properties>
|
||||||
|
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||||
|
<ResourceString bundle="org/sleuthkit/autopsy/casemodule/Bundle.properties" key="LocalFilesPanel.jButton1.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||||
|
</Property>
|
||||||
|
</Properties>
|
||||||
|
<Events>
|
||||||
|
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="jButton1ActionPerformed"/>
|
||||||
|
</Events>
|
||||||
|
</Component>
|
||||||
|
<Component class="javax.swing.JLabel" name="displayNameLabel">
|
||||||
|
<Properties>
|
||||||
|
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||||
|
<ResourceString bundle="org/sleuthkit/autopsy/casemodule/Bundle.properties" key="LocalFilesPanel.displayNameLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||||
|
</Property>
|
||||||
|
</Properties>
|
||||||
|
</Component>
|
||||||
</SubComponents>
|
</SubComponents>
|
||||||
</Form>
|
</Form>
|
||||||
|
@ -18,6 +18,7 @@
|
|||||||
*/
|
*/
|
||||||
package org.sleuthkit.autopsy.casemodule;
|
package org.sleuthkit.autopsy.casemodule;
|
||||||
|
|
||||||
|
import java.awt.Dialog;
|
||||||
import java.beans.PropertyChangeListener;
|
import java.beans.PropertyChangeListener;
|
||||||
import java.beans.PropertyChangeSupport;
|
import java.beans.PropertyChangeSupport;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
@ -32,6 +33,10 @@ import org.openide.util.NbBundle;
|
|||||||
import org.sleuthkit.autopsy.corecomponentinterfaces.DataSourceProcessor;
|
import org.sleuthkit.autopsy.corecomponentinterfaces.DataSourceProcessor;
|
||||||
import org.sleuthkit.autopsy.coreutils.MessageNotifyUtil;
|
import org.sleuthkit.autopsy.coreutils.MessageNotifyUtil;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
|
import javax.swing.JOptionPane;
|
||||||
|
import org.openide.DialogDescriptor;
|
||||||
|
import org.openide.DialogDisplayer;
|
||||||
|
import org.openide.NotifyDescriptor;
|
||||||
import org.sleuthkit.autopsy.casemodule.Case.CaseType;
|
import org.sleuthkit.autopsy.casemodule.Case.CaseType;
|
||||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||||
import org.sleuthkit.autopsy.coreutils.PathValidator;
|
import org.sleuthkit.autopsy.coreutils.PathValidator;
|
||||||
@ -47,6 +52,7 @@ class LocalFilesPanel extends JPanel {
|
|||||||
private static LocalFilesPanel instance;
|
private static LocalFilesPanel instance;
|
||||||
public static final String FILES_SEP = ",";
|
public static final String FILES_SEP = ",";
|
||||||
private static final Logger logger = Logger.getLogger(LocalFilesPanel.class.getName());
|
private static final Logger logger = Logger.getLogger(LocalFilesPanel.class.getName());
|
||||||
|
private String displayName = "";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates new form LocalFilesPanel
|
* Creates new form LocalFilesPanel
|
||||||
@ -67,6 +73,7 @@ class LocalFilesPanel extends JPanel {
|
|||||||
localFileChooser.setMultiSelectionEnabled(true);
|
localFileChooser.setMultiSelectionEnabled(true);
|
||||||
errorLabel.setVisible(false);
|
errorLabel.setVisible(false);
|
||||||
selectedPaths.setText("");
|
selectedPaths.setText("");
|
||||||
|
this.displayNameLabel.setText(NbBundle.getMessage(this.getClass(), "LocalFilesPanel.displayNameLabel.text"));
|
||||||
}
|
}
|
||||||
|
|
||||||
//@Override
|
//@Override
|
||||||
@ -137,6 +144,8 @@ class LocalFilesPanel extends JPanel {
|
|||||||
selectedPaths.setText("");
|
selectedPaths.setText("");
|
||||||
enableNext = false;
|
enableNext = false;
|
||||||
errorLabel.setVisible(false);
|
errorLabel.setVisible(false);
|
||||||
|
displayName = "";
|
||||||
|
this.displayNameLabel.setText(NbBundle.getMessage(this.getClass(), "LocalFilesPanel.displayNameLabel.text"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -157,6 +166,10 @@ class LocalFilesPanel extends JPanel {
|
|||||||
pcs.removePropertyChangeListener(pcl);
|
pcs.removePropertyChangeListener(pcl);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String getFileSetName() {
|
||||||
|
return this.displayName;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return NbBundle.getMessage(this.getClass(), "LocalFilesDSProcessor.toString.text");
|
return NbBundle.getMessage(this.getClass(), "LocalFilesDSProcessor.toString.text");
|
||||||
@ -180,6 +193,8 @@ class LocalFilesPanel extends JPanel {
|
|||||||
jScrollPane2 = new javax.swing.JScrollPane();
|
jScrollPane2 = new javax.swing.JScrollPane();
|
||||||
selectedPaths = new javax.swing.JTextArea();
|
selectedPaths = new javax.swing.JTextArea();
|
||||||
errorLabel = new javax.swing.JLabel();
|
errorLabel = new javax.swing.JLabel();
|
||||||
|
jButton1 = new javax.swing.JButton();
|
||||||
|
displayNameLabel = new javax.swing.JLabel();
|
||||||
|
|
||||||
localFileChooser.setApproveButtonText(org.openide.util.NbBundle.getMessage(LocalFilesPanel.class, "LocalFilesPanel.localFileChooser.approveButtonText")); // NOI18N
|
localFileChooser.setApproveButtonText(org.openide.util.NbBundle.getMessage(LocalFilesPanel.class, "LocalFilesPanel.localFileChooser.approveButtonText")); // NOI18N
|
||||||
localFileChooser.setApproveButtonToolTipText(org.openide.util.NbBundle.getMessage(LocalFilesPanel.class, "LocalFilesPanel.localFileChooser.approveButtonToolTipText")); // NOI18N
|
localFileChooser.setApproveButtonToolTipText(org.openide.util.NbBundle.getMessage(LocalFilesPanel.class, "LocalFilesPanel.localFileChooser.approveButtonToolTipText")); // NOI18N
|
||||||
@ -218,37 +233,57 @@ class LocalFilesPanel extends JPanel {
|
|||||||
errorLabel.setForeground(new java.awt.Color(255, 0, 0));
|
errorLabel.setForeground(new java.awt.Color(255, 0, 0));
|
||||||
org.openide.awt.Mnemonics.setLocalizedText(errorLabel, org.openide.util.NbBundle.getMessage(LocalFilesPanel.class, "LocalFilesPanel.errorLabel.text")); // NOI18N
|
org.openide.awt.Mnemonics.setLocalizedText(errorLabel, org.openide.util.NbBundle.getMessage(LocalFilesPanel.class, "LocalFilesPanel.errorLabel.text")); // NOI18N
|
||||||
|
|
||||||
|
org.openide.awt.Mnemonics.setLocalizedText(jButton1, org.openide.util.NbBundle.getMessage(LocalFilesPanel.class, "LocalFilesPanel.jButton1.text")); // NOI18N
|
||||||
|
jButton1.addActionListener(new java.awt.event.ActionListener() {
|
||||||
|
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||||
|
jButton1ActionPerformed(evt);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
org.openide.awt.Mnemonics.setLocalizedText(displayNameLabel, org.openide.util.NbBundle.getMessage(LocalFilesPanel.class, "LocalFilesPanel.displayNameLabel.text")); // NOI18N
|
||||||
|
|
||||||
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
|
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
|
||||||
this.setLayout(layout);
|
this.setLayout(layout);
|
||||||
layout.setHorizontalGroup(
|
layout.setHorizontalGroup(
|
||||||
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||||
|
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
|
||||||
|
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||||
.addGroup(layout.createSequentialGroup()
|
.addGroup(layout.createSequentialGroup()
|
||||||
.addComponent(infoLabel)
|
.addComponent(infoLabel)
|
||||||
.addGap(0, 0, Short.MAX_VALUE))
|
.addGap(0, 0, Short.MAX_VALUE))
|
||||||
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
|
.addComponent(jScrollPane2, javax.swing.GroupLayout.DEFAULT_SIZE, 389, Short.MAX_VALUE))
|
||||||
.addComponent(jScrollPane2, javax.swing.GroupLayout.DEFAULT_SIZE, 353, Short.MAX_VALUE)
|
|
||||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||||
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
|
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
|
||||||
.addComponent(selectButton, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
.addComponent(selectButton, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
||||||
.addComponent(clearButton, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
|
.addComponent(clearButton, javax.swing.GroupLayout.DEFAULT_SIZE, 69, Short.MAX_VALUE))
|
||||||
.addGap(2, 2, 2))
|
.addGap(2, 2, 2))
|
||||||
.addGroup(layout.createSequentialGroup()
|
.addGroup(layout.createSequentialGroup()
|
||||||
|
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||||
.addComponent(errorLabel)
|
.addComponent(errorLabel)
|
||||||
|
.addGroup(layout.createSequentialGroup()
|
||||||
|
.addComponent(displayNameLabel)
|
||||||
|
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
|
||||||
|
.addComponent(jButton1)))
|
||||||
.addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
|
.addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
|
||||||
);
|
);
|
||||||
layout.setVerticalGroup(
|
layout.setVerticalGroup(
|
||||||
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||||
.addGroup(layout.createSequentialGroup()
|
.addGroup(layout.createSequentialGroup()
|
||||||
.addComponent(infoLabel)
|
.addComponent(infoLabel)
|
||||||
.addGap(5, 5, 5)
|
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||||
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
|
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
|
||||||
.addComponent(jScrollPane2, javax.swing.GroupLayout.PREFERRED_SIZE, 82, javax.swing.GroupLayout.PREFERRED_SIZE)
|
|
||||||
.addGroup(layout.createSequentialGroup()
|
.addGroup(layout.createSequentialGroup()
|
||||||
.addComponent(selectButton)
|
.addComponent(selectButton)
|
||||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
.addGap(36, 36, 36)
|
||||||
.addComponent(clearButton)))
|
.addComponent(clearButton))
|
||||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
.addComponent(jScrollPane2, javax.swing.GroupLayout.PREFERRED_SIZE, 82, javax.swing.GroupLayout.PREFERRED_SIZE))
|
||||||
.addComponent(errorLabel))
|
.addGap(18, 18, 18)
|
||||||
|
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
|
||||||
|
.addComponent(jButton1, javax.swing.GroupLayout.PREFERRED_SIZE, 20, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||||
|
.addComponent(displayNameLabel))
|
||||||
|
.addGap(13, 13, 13)
|
||||||
|
.addComponent(errorLabel)
|
||||||
|
.addGap(7, 7, 7))
|
||||||
);
|
);
|
||||||
}// </editor-fold>//GEN-END:initComponents
|
}// </editor-fold>//GEN-END:initComponents
|
||||||
|
|
||||||
@ -291,10 +326,20 @@ class LocalFilesPanel extends JPanel {
|
|||||||
|
|
||||||
}//GEN-LAST:event_clearButtonActionPerformed
|
}//GEN-LAST:event_clearButtonActionPerformed
|
||||||
|
|
||||||
|
private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButton1ActionPerformed
|
||||||
|
String displayName = JOptionPane.showInputDialog("New Display Name: ");
|
||||||
|
if (displayName != null && !displayName.equals("")) {
|
||||||
|
this.displayName = displayName;
|
||||||
|
this.displayNameLabel.setText("Display Name: " + this.displayName);
|
||||||
|
}
|
||||||
|
}//GEN-LAST:event_jButton1ActionPerformed
|
||||||
|
|
||||||
// Variables declaration - do not modify//GEN-BEGIN:variables
|
// Variables declaration - do not modify//GEN-BEGIN:variables
|
||||||
private javax.swing.JButton clearButton;
|
private javax.swing.JButton clearButton;
|
||||||
|
private javax.swing.JLabel displayNameLabel;
|
||||||
private javax.swing.JLabel errorLabel;
|
private javax.swing.JLabel errorLabel;
|
||||||
private javax.swing.JLabel infoLabel;
|
private javax.swing.JLabel infoLabel;
|
||||||
|
private javax.swing.JButton jButton1;
|
||||||
private javax.swing.JScrollPane jScrollPane1;
|
private javax.swing.JScrollPane jScrollPane1;
|
||||||
private javax.swing.JScrollPane jScrollPane2;
|
private javax.swing.JScrollPane jScrollPane2;
|
||||||
private javax.swing.JTextArea jTextArea1;
|
private javax.swing.JTextArea jTextArea1;
|
||||||
|
@ -156,9 +156,6 @@ class OpenRecentCasePanel extends javax.swing.JPanel {
|
|||||||
|
|
||||||
private static final long serialVersionUID = 1L;
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
/**
|
|
||||||
* @inheritDoc
|
|
||||||
*/
|
|
||||||
@Override
|
@Override
|
||||||
public int getRowCount() {
|
public int getRowCount() {
|
||||||
int count = 0;
|
int count = 0;
|
||||||
@ -170,17 +167,11 @@ class OpenRecentCasePanel extends javax.swing.JPanel {
|
|||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @inheritDoc
|
|
||||||
*/
|
|
||||||
@Override
|
@Override
|
||||||
public int getColumnCount() {
|
public int getColumnCount() {
|
||||||
return 2;
|
return 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @inheritDoc
|
|
||||||
*/
|
|
||||||
@Override
|
@Override
|
||||||
public String getColumnName(int column) {
|
public String getColumnName(int column) {
|
||||||
String colName = null;
|
String colName = null;
|
||||||
@ -197,9 +188,6 @@ class OpenRecentCasePanel extends javax.swing.JPanel {
|
|||||||
return colName;
|
return colName;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @inheritDoc
|
|
||||||
*/
|
|
||||||
@Override
|
@Override
|
||||||
public Object getValueAt(int rowIndex, int columnIndex) {
|
public Object getValueAt(int rowIndex, int columnIndex) {
|
||||||
Object ret = null;
|
Object ret = null;
|
||||||
@ -217,17 +205,11 @@ class OpenRecentCasePanel extends javax.swing.JPanel {
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @inheritDoc
|
|
||||||
*/
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isCellEditable(int rowIndex, int columnIndex) {
|
public boolean isCellEditable(int rowIndex, int columnIndex) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @inheritDoc
|
|
||||||
*/
|
|
||||||
@Override
|
@Override
|
||||||
public void setValueAt(Object aValue, int rowIndex, int columnIndex) {
|
public void setValueAt(Object aValue, int rowIndex, int columnIndex) {
|
||||||
}
|
}
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
*
|
*
|
||||||
* Autopsy Forensic Browser
|
* Autopsy Forensic Browser
|
||||||
*
|
*
|
||||||
* Copyright 2012 Basis Technology Corp.
|
* Copyright 2011-2016 Basis Technology Corp.
|
||||||
*
|
*
|
||||||
* Copyright 2012 42six Solutions.
|
* Copyright 2012 42six Solutions.
|
||||||
* Contact: aebadirad <at> 42six <dot> com
|
* Contact: aebadirad <at> 42six <dot> com
|
||||||
@ -512,6 +512,7 @@ public class FileManager implements Closeable {
|
|||||||
* Helper (internal) method to recursively add contents of a folder. Node
|
* Helper (internal) method to recursively add contents of a folder. Node
|
||||||
* passed in can be a file or directory. Children of directories are added.
|
* passed in can be a file or directory. Children of directories are added.
|
||||||
*
|
*
|
||||||
|
* @param trans A case database transaction.
|
||||||
* @param parentVd Dir that is the parent of localFile
|
* @param parentVd Dir that is the parent of localFile
|
||||||
* @param localFile File/Dir that we are adding
|
* @param localFile File/Dir that we are adding
|
||||||
* @param addProgressUpdater notifier to receive progress notifications on
|
* @param addProgressUpdater notifier to receive progress notifications on
|
||||||
@ -569,6 +570,7 @@ public class FileManager implements Closeable {
|
|||||||
* @param parentFile parent file object container (such as virtual
|
* @param parentFile parent file object container (such as virtual
|
||||||
* directory, another local file, or fscontent File),
|
* directory, another local file, or fscontent File),
|
||||||
* @param localFile File that we are adding
|
* @param localFile File that we are adding
|
||||||
|
* @param trans A case database transaction.
|
||||||
*
|
*
|
||||||
* @return newly created local file object added to the database
|
* @return newly created local file object added to the database
|
||||||
*
|
*
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* Autopsy Forensic Browser
|
* Autopsy Forensic Browser
|
||||||
*
|
*
|
||||||
* Copyright 2011-2013 Basis Technology Corp.
|
* Copyright 2011-2016 Basis Technology Corp.
|
||||||
* Contact: carrier <at> sleuthkit <dot> org
|
* Contact: carrier <at> sleuthkit <dot> org
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
@ -385,7 +385,7 @@ public class DataContentViewerHex extends javax.swing.JPanel implements DataCont
|
|||||||
/**
|
/**
|
||||||
* Sets the DataView (The tabbed panel) by offset
|
* Sets the DataView (The tabbed panel) by offset
|
||||||
*
|
*
|
||||||
* @param page Page to display (1-based counting)
|
* @param offset Page to display (1-based counting)
|
||||||
*/
|
*/
|
||||||
private void setDataViewByOffset(long offset) {
|
private void setDataViewByOffset(long offset) {
|
||||||
if (this.dataSource == null) {
|
if (this.dataSource == null) {
|
||||||
|
@ -22,8 +22,6 @@ import java.awt.CardLayout;
|
|||||||
import java.awt.Component;
|
import java.awt.Component;
|
||||||
import java.awt.Dimension;
|
import java.awt.Dimension;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.SortedSet;
|
|
||||||
import java.util.TreeSet;
|
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
import org.openide.nodes.Node;
|
import org.openide.nodes.Node;
|
||||||
import org.openide.util.NbBundle;
|
import org.openide.util.NbBundle;
|
||||||
@ -47,7 +45,6 @@ public class DataContentViewerMedia extends javax.swing.JPanel implements DataCo
|
|||||||
//UI
|
//UI
|
||||||
private final MediaViewVideoPanel videoPanel;
|
private final MediaViewVideoPanel videoPanel;
|
||||||
private final boolean videoPanelInited;
|
private final boolean videoPanelInited;
|
||||||
private final SortedSet<String> videoExtensions; // get them from the panel
|
|
||||||
private final MediaViewImagePanel imagePanel;
|
private final MediaViewImagePanel imagePanel;
|
||||||
private final boolean imagePanelInited;
|
private final boolean imagePanelInited;
|
||||||
|
|
||||||
@ -64,7 +61,6 @@ public class DataContentViewerMedia extends javax.swing.JPanel implements DataCo
|
|||||||
// get the right panel for our platform
|
// get the right panel for our platform
|
||||||
videoPanel = MediaViewVideoPanel.createVideoPanel();
|
videoPanel = MediaViewVideoPanel.createVideoPanel();
|
||||||
videoPanelInited = videoPanel.isInited();
|
videoPanelInited = videoPanel.isInited();
|
||||||
videoExtensions = new TreeSet<>(videoPanel.getExtensionsList());
|
|
||||||
|
|
||||||
imagePanel = new MediaViewImagePanel();
|
imagePanel = new MediaViewImagePanel();
|
||||||
imagePanelInited = imagePanel.isInited();
|
imagePanelInited = imagePanel.isInited();
|
||||||
|
@ -18,6 +18,7 @@
|
|||||||
*/
|
*/
|
||||||
package org.sleuthkit.autopsy.corecomponents;
|
package org.sleuthkit.autopsy.corecomponents;
|
||||||
|
|
||||||
|
import com.google.common.io.Files;
|
||||||
import java.awt.Dimension;
|
import java.awt.Dimension;
|
||||||
import java.awt.Image;
|
import java.awt.Image;
|
||||||
import java.awt.image.BufferedImage;
|
import java.awt.image.BufferedImage;
|
||||||
@ -680,6 +681,7 @@ public class GstVideoPanel extends MediaViewVideoPanel {
|
|||||||
progressLabel.setText(NbBundle.getMessage(this.getClass(), "GstVideoPanel.progress.buffering"));
|
progressLabel.setText(NbBundle.getMessage(this.getClass(), "GstVideoPanel.progress.buffering"));
|
||||||
progress.start(100);
|
progress.start(100);
|
||||||
try {
|
try {
|
||||||
|
Files.createParentDirs(tempFile);
|
||||||
return ContentUtils.writeToFile(sourceFile, tempFile, progress, this, true);
|
return ContentUtils.writeToFile(sourceFile, tempFile, progress, this, true);
|
||||||
} catch (IOException ex) {
|
} catch (IOException ex) {
|
||||||
logger.log(Level.WARNING, "Error buffering file", ex); //NON-NLS
|
logger.log(Level.WARNING, "Error buffering file", ex); //NON-NLS
|
||||||
|
@ -28,7 +28,9 @@ import java.util.TreeSet;
|
|||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
import javax.swing.JPanel;
|
import javax.swing.JPanel;
|
||||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||||
|
import org.sleuthkit.autopsy.modules.filetypeid.FileTypeDetector;
|
||||||
import org.sleuthkit.datamodel.AbstractFile;
|
import org.sleuthkit.datamodel.AbstractFile;
|
||||||
|
import org.sleuthkit.datamodel.TskCoreException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Video viewer part of the Media View layered pane. Uses different engines
|
* Video viewer part of the Media View layered pane. Uses different engines
|
||||||
@ -131,18 +133,38 @@ public abstract class MediaViewVideoPanel extends JPanel implements FrameCapture
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isSupported(AbstractFile file) {
|
public boolean isSupported(AbstractFile file) {
|
||||||
/*
|
|
||||||
* TODO (AUT-2042): Is this the logic we want?
|
|
||||||
*/
|
|
||||||
String extension = file.getNameExtension();
|
String extension = file.getNameExtension();
|
||||||
|
/**
|
||||||
|
* Although it seems too restrictive, requiring both a supported
|
||||||
|
* extension and a supported MIME type prevents two undesirable
|
||||||
|
* behaviors:
|
||||||
|
*
|
||||||
|
* 1) Until AUT-1766 and AUT-1801 are fixed, we incorrectly identify all
|
||||||
|
* iff files as audio/aiff. This means that if this panel went with the
|
||||||
|
* looser 'mime type OR extension' criteria we use for images, then this
|
||||||
|
* panel would attempt (and fail) to display all iff files, even non
|
||||||
|
* audio ones.
|
||||||
|
*
|
||||||
|
* 2) The looser criteria means we are less confident about the files we
|
||||||
|
* are potentialy sending to GStreamer on 32bit jvms. We are less
|
||||||
|
* comfortable with the error handling for GStreamer, and don't want to
|
||||||
|
* send it files which might cause it trouble.
|
||||||
|
*/
|
||||||
if (AUDIO_EXTENSIONS.contains("." + extension) || getExtensionsList().contains("." + extension)) {
|
if (AUDIO_EXTENSIONS.contains("." + extension) || getExtensionsList().contains("." + extension)) {
|
||||||
SortedSet<String> mimeTypes = new TreeSet<>(getMimeTypes());
|
SortedSet<String> mimeTypes = new TreeSet<>(getMimeTypes());
|
||||||
String mimeType = file.getMIMEType();
|
try {
|
||||||
|
String mimeType = new FileTypeDetector().detect(file);
|
||||||
if (nonNull(mimeType)) {
|
if (nonNull(mimeType)) {
|
||||||
return mimeTypes.contains(mimeType);
|
return mimeTypes.contains(mimeType);
|
||||||
} else {
|
|
||||||
return getExtensionsList().contains("." + extension);
|
|
||||||
}
|
}
|
||||||
|
} catch (FileTypeDetector.FileTypeDetectorInitException | TskCoreException ex) {
|
||||||
|
logger.log(Level.WARNING, "Failed to look up mimetype for " + file.getName() + " using FileTypeDetector. Fallingback on AbstractFile.isMimeType", ex);
|
||||||
|
if (!mimeTypes.isEmpty() && file.isMimeType(mimeTypes) == AbstractFile.MimeMatchEnum.TRUE) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return getExtensionsList().contains("." + extension);
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,20 @@
|
|||||||
/*
|
/*
|
||||||
* To change this license header, choose License Headers in Project Properties.
|
* Autopsy Forensic Browser
|
||||||
* To change this template file, choose Tools | Templates
|
*
|
||||||
* and open the template in the editor.
|
* Copyright 2013-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.corecomponents;
|
package org.sleuthkit.autopsy.corecomponents;
|
||||||
|
|
||||||
@ -467,7 +480,8 @@ public final class MultiUserSettingsPanel extends javax.swing.JPanel {
|
|||||||
/**
|
/**
|
||||||
* Enables/disables the multi-user settings, based upon input provided
|
* Enables/disables the multi-user settings, based upon input provided
|
||||||
*
|
*
|
||||||
* @param enabled true means enable, false means disable
|
* @param textFields The text fields to enable/disable.
|
||||||
|
* @param enabled True means enable, false means disable.
|
||||||
*/
|
*/
|
||||||
private static void enableMultiUserComponents(Collection<JTextField> textFields, boolean enabled) {
|
private static void enableMultiUserComponents(Collection<JTextField> textFields, boolean enabled) {
|
||||||
for (JTextField textField : textFields) {
|
for (JTextField textField : textFields) {
|
||||||
|
@ -132,7 +132,7 @@ class ThumbnailViewChildren extends Children.Keys<Integer> {
|
|||||||
return new Node[]{pageNode};
|
return new Node[]{pageNode};
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean isSupported(Node node) {
|
static boolean isSupported(Node node) {
|
||||||
if (node != null) {
|
if (node != null) {
|
||||||
Content content = node.getLookup().lookup(Content.class);
|
Content content = node.getLookup().lookup(Content.class);
|
||||||
if (content != null) {
|
if (content != null) {
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* Autopsy Forensic Browser
|
* Autopsy Forensic Browser
|
||||||
*
|
*
|
||||||
* Copyright 2013-2014 Basis Technology Corp.
|
* Copyright 2011-2016 Basis Technology Corp.
|
||||||
* Contact: carrier <at> sleuthkit <dot> org
|
* Contact: carrier <at> sleuthkit <dot> org
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
@ -96,9 +96,6 @@ public final class ExecUtil {
|
|||||||
this.startTimeInSeconds = (new Date().getTime()) / 1000;
|
this.startTimeInSeconds = (new Date().getTime()) / 1000;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @inheritDoc
|
|
||||||
*/
|
|
||||||
@Override
|
@Override
|
||||||
public boolean shouldTerminateProcess() {
|
public boolean shouldTerminateProcess() {
|
||||||
long currentTimeInSeconds = (new Date().getTime()) / 1000;
|
long currentTimeInSeconds = (new Date().getTime()) / 1000;
|
||||||
@ -120,9 +117,6 @@ public final class ExecUtil {
|
|||||||
*/
|
*/
|
||||||
public static int execute(ProcessBuilder processBuilder) throws SecurityException, IOException {
|
public static int execute(ProcessBuilder processBuilder) throws SecurityException, IOException {
|
||||||
return ExecUtil.execute(processBuilder, 30, TimeUnit.DAYS, new ProcessTerminator() {
|
return ExecUtil.execute(processBuilder, 30, TimeUnit.DAYS, new ProcessTerminator() {
|
||||||
/**
|
|
||||||
* @inheritDoc
|
|
||||||
*/
|
|
||||||
@Override
|
@Override
|
||||||
public boolean shouldTerminateProcess() {
|
public boolean shouldTerminateProcess() {
|
||||||
return false;
|
return false;
|
||||||
|
@ -32,10 +32,10 @@ import java.io.InputStream;
|
|||||||
import java.nio.file.Paths;
|
import java.nio.file.Paths;
|
||||||
import java.text.MessageFormat;
|
import java.text.MessageFormat;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
import java.util.Collection;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Objects;
|
|
||||||
import static java.util.Objects.nonNull;
|
import static java.util.Objects.nonNull;
|
||||||
import java.util.SortedSet;
|
import java.util.SortedSet;
|
||||||
import java.util.TreeSet;
|
import java.util.TreeSet;
|
||||||
@ -78,7 +78,7 @@ public class ImageUtils {
|
|||||||
/**
|
/**
|
||||||
* save thumbnails to disk as this format
|
* save thumbnails to disk as this format
|
||||||
*/
|
*/
|
||||||
private static final String FORMAT = "png"; //NON-NLS //NOI18N
|
private static final String FORMAT = "png"; //NON-NLS
|
||||||
|
|
||||||
public static final int ICON_SIZE_SMALL = 50;
|
public static final int ICON_SIZE_SMALL = 50;
|
||||||
public static final int ICON_SIZE_MEDIUM = 100;
|
public static final int ICON_SIZE_MEDIUM = 100;
|
||||||
@ -86,12 +86,11 @@ public class ImageUtils {
|
|||||||
|
|
||||||
private static final BufferedImage DEFAULT_THUMBNAIL;
|
private static final BufferedImage DEFAULT_THUMBNAIL;
|
||||||
|
|
||||||
private static final String IMAGE_GIF_MIME = "image/gif"; //NOI18N NON-NLS
|
private static final List<String> GIF_EXTENSION_LIST = Arrays.asList("gif");
|
||||||
private static final SortedSet<String> GIF_MIME_SET = ImmutableSortedSet.copyOf(new String[]{IMAGE_GIF_MIME});
|
private static final SortedSet<String> GIF_MIME_SET = ImmutableSortedSet.copyOf(new String[]{"image/gif"});
|
||||||
|
|
||||||
private static final List<String> SUPPORTED_IMAGE_EXTENSIONS;
|
private static final List<String> SUPPORTED_IMAGE_EXTENSIONS;
|
||||||
private static final SortedSet<String> SUPPORTED_IMAGE_MIME_TYPES;
|
private static final SortedSet<String> SUPPORTED_IMAGE_MIME_TYPES;
|
||||||
private static final List<String> CONDITIONAL_MIME_TYPES = Arrays.asList("audio/x-aiff", "application/octet-stream"); //NOI18N NON-NLS
|
|
||||||
|
|
||||||
private static final boolean openCVLoaded;
|
private static final boolean openCVLoaded;
|
||||||
|
|
||||||
@ -99,9 +98,9 @@ public class ImageUtils {
|
|||||||
ImageIO.scanForPlugins();
|
ImageIO.scanForPlugins();
|
||||||
BufferedImage tempImage;
|
BufferedImage tempImage;
|
||||||
try {
|
try {
|
||||||
tempImage = ImageIO.read(ImageUtils.class.getResourceAsStream("/org/sleuthkit/autopsy/images/file-icon.png"));//NON-NLS //NOI18N
|
tempImage = ImageIO.read(ImageUtils.class.getResourceAsStream("/org/sleuthkit/autopsy/images/file-icon.png"));//NON-NLS
|
||||||
} catch (IOException ex) {
|
} catch (IOException ex) {
|
||||||
LOGGER.log(Level.SEVERE, "Failed to load default icon.", ex); //NOI18N NON-NLS
|
LOGGER.log(Level.SEVERE, "Failed to load default icon.", ex); //NON-NLS
|
||||||
tempImage = null;
|
tempImage = null;
|
||||||
}
|
}
|
||||||
DEFAULT_THUMBNAIL = tempImage;
|
DEFAULT_THUMBNAIL = tempImage;
|
||||||
@ -110,23 +109,22 @@ public class ImageUtils {
|
|||||||
boolean openCVLoadedTemp;
|
boolean openCVLoadedTemp;
|
||||||
try {
|
try {
|
||||||
System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
|
System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
|
||||||
if (System.getProperty("os.arch").equals("amd64") || System.getProperty("os.arch").equals("x86_64")) { //NOI18N NON-NLS
|
if (System.getProperty("os.arch").equals("amd64") || System.getProperty("os.arch").equals("x86_64")) { //NON-NLS
|
||||||
System.loadLibrary("opencv_ffmpeg248_64"); //NOI18N NON-NLS
|
System.loadLibrary("opencv_ffmpeg248_64"); //NON-NLS
|
||||||
} else {
|
} else {
|
||||||
System.loadLibrary("opencv_ffmpeg248"); //NOI18N NON-NLS
|
System.loadLibrary("opencv_ffmpeg248"); //NON-NLS
|
||||||
}
|
}
|
||||||
|
|
||||||
openCVLoadedTemp = true;
|
openCVLoadedTemp = true;
|
||||||
} catch (UnsatisfiedLinkError e) {
|
} catch (UnsatisfiedLinkError e) {
|
||||||
openCVLoadedTemp = false;
|
openCVLoadedTemp = false;
|
||||||
LOGGER.log(Level.SEVERE, "OpenCV Native code library failed to load", e); //NOI18N NON-NLS
|
LOGGER.log(Level.SEVERE, "OpenCV Native code library failed to load", e); //NON-NLS
|
||||||
//TODO: show warning bubble
|
//TODO: show warning bubble
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
openCVLoaded = openCVLoadedTemp;
|
openCVLoaded = openCVLoadedTemp;
|
||||||
SUPPORTED_IMAGE_EXTENSIONS = Arrays.asList(ImageIO.getReaderFileSuffixes());
|
SUPPORTED_IMAGE_EXTENSIONS = Arrays.asList(ImageIO.getReaderFileSuffixes());
|
||||||
|
|
||||||
SUPPORTED_IMAGE_MIME_TYPES = new TreeSet<>(Arrays.asList(ImageIO.getReaderMIMETypes()));
|
SUPPORTED_IMAGE_MIME_TYPES = new TreeSet<>(Arrays.asList(ImageIO.getReaderMIMETypes()));
|
||||||
/*
|
/*
|
||||||
* special cases and variants that we support, but don't get registered
|
* special cases and variants that we support, but don't get registered
|
||||||
@ -137,8 +135,8 @@ public class ImageUtils {
|
|||||||
"image/x-ms-bmp", //NON-NLS
|
"image/x-ms-bmp", //NON-NLS
|
||||||
"image/x-portable-graymap", //NON-NLS
|
"image/x-portable-graymap", //NON-NLS
|
||||||
"image/x-portable-bitmap", //NON-NLS
|
"image/x-portable-bitmap", //NON-NLS
|
||||||
"application/x-123")); //TODO: is this correct? -jm //NOI18N NON-NLS
|
"application/x-123")); //TODO: is this correct? -jm //NON-NLS
|
||||||
SUPPORTED_IMAGE_MIME_TYPES.removeIf("application/octet-stream"::equals); //NOI18N NON-NLS
|
SUPPORTED_IMAGE_MIME_TYPES.removeIf("application/octet-stream"::equals); //NON-NLS
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -151,7 +149,7 @@ public class ImageUtils {
|
|||||||
*/
|
*/
|
||||||
private static final Executor imageSaver
|
private static final Executor imageSaver
|
||||||
= Executors.newSingleThreadExecutor(new BasicThreadFactory.Builder()
|
= Executors.newSingleThreadExecutor(new BasicThreadFactory.Builder()
|
||||||
.namingPattern("icon saver-%d").build()); //NOI18N NON-NLS
|
.namingPattern("thumbnail-saver-%d").build()); //NON-NLS
|
||||||
|
|
||||||
public static List<String> getSupportedImageExtensions() {
|
public static List<String> getSupportedImageExtensions() {
|
||||||
return Collections.unmodifiableList(SUPPORTED_IMAGE_EXTENSIONS);
|
return Collections.unmodifiableList(SUPPORTED_IMAGE_EXTENSIONS);
|
||||||
@ -163,20 +161,7 @@ public class ImageUtils {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the default thumbnail, which is the icon for a file. Used when we can
|
* Get the default thumbnail, which is the icon for a file. Used when we can
|
||||||
* not generate content based thumbnail.
|
* not generate a content based thumbnail.
|
||||||
*
|
|
||||||
* @return
|
|
||||||
*
|
|
||||||
* @deprecated use {@link #getDefaultThumbnail() } instead.
|
|
||||||
*/
|
|
||||||
@Deprecated
|
|
||||||
public static Image getDefaultIcon() {
|
|
||||||
return getDefaultThumbnail();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the default thumbnail, which is the icon for a file. Used when we can
|
|
||||||
* not generate content based thumbnail.
|
|
||||||
*
|
*
|
||||||
* @return the default thumbnail
|
* @return the default thumbnail
|
||||||
*/
|
*/
|
||||||
@ -196,9 +181,6 @@ public class ImageUtils {
|
|||||||
*/
|
*/
|
||||||
public static boolean thumbnailSupported(Content content) {
|
public static boolean thumbnailSupported(Content content) {
|
||||||
|
|
||||||
if (content.getSize() == 0) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (!(content instanceof AbstractFile)) {
|
if (!(content instanceof AbstractFile)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -206,79 +188,84 @@ public class ImageUtils {
|
|||||||
|
|
||||||
return VideoUtils.isVideoThumbnailSupported(file)
|
return VideoUtils.isVideoThumbnailSupported(file)
|
||||||
|| isImageThumbnailSupported(file);
|
|| isImageThumbnailSupported(file);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* is the file an image that we can read and generate a thumbnail for
|
* Is the file an image that we can read and generate a thumbnail for?
|
||||||
*
|
*
|
||||||
* @param file
|
* @param file the AbstractFile to test
|
||||||
*
|
*
|
||||||
* @return true if the file is an image we can read and generate thumbnail
|
* @return true if the file is an image we can read and generate thumbnail
|
||||||
* for.
|
* for.
|
||||||
*/
|
*/
|
||||||
public static boolean isImageThumbnailSupported(AbstractFile file) {
|
public static boolean isImageThumbnailSupported(AbstractFile file) {
|
||||||
return isMediaThumbnailSupported(file, SUPPORTED_IMAGE_MIME_TYPES, SUPPORTED_IMAGE_EXTENSIONS, CONDITIONAL_MIME_TYPES)
|
return isMediaThumbnailSupported(file, "image/", SUPPORTED_IMAGE_MIME_TYPES, SUPPORTED_IMAGE_EXTENSIONS) || hasImageFileHeader(file);//NON-NLS
|
||||||
|| hasImageFileHeader(file);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Checks the MIME type of a file to determine whether it is a GIF. If the
|
* Checks the MIME type and/or extension of a file to determine whether it
|
||||||
* MIME type is not known, checks for a "gif" extension.
|
* is a GIF.
|
||||||
*
|
*
|
||||||
* @param file The file to be checked.
|
* @param file the AbstractFile to test
|
||||||
*
|
*
|
||||||
* @return True or false
|
* @return true if the file is a gif
|
||||||
*/
|
*/
|
||||||
public static boolean isGIF(AbstractFile file) {
|
public static boolean isGIF(AbstractFile file) {
|
||||||
String mimeType = file.getMIMEType();
|
return isMediaThumbnailSupported(file, null, GIF_MIME_SET, GIF_EXTENSION_LIST);
|
||||||
if (nonNull(mimeType)) {
|
|
||||||
return IMAGE_GIF_MIME.equalsIgnoreCase(mimeType);
|
|
||||||
} else {
|
|
||||||
return "gif".equalsIgnoreCase(file.getNameExtension()); //NOI18N
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check if a file is "supported" by checking its mimetype and extension
|
* Check if making a thumbnail for the given file is supported by checking
|
||||||
|
* its extension and/or MIME type against the supplied collections.
|
||||||
*
|
*
|
||||||
* //TODO: this should move to a better place. Should ImageUtils and
|
* //TODO: this should move to a better place. Should ImageUtils and
|
||||||
* VideoUtils both implement/extend some base interface/abstract class. That
|
* VideoUtils both implement/extend some base interface/abstract class. That
|
||||||
* would be the natural place to put this.
|
* would be the natural place to put this.
|
||||||
*
|
*
|
||||||
* @param file
|
* @param file the AbstractFile to test
|
||||||
* @param supportedMimeTypes a set of mimetypes that the could have to be
|
* @param mimeTypePrefix a MIME 'top-level type name' such as "image/",
|
||||||
* supported
|
* including the "/". In addition to the list of
|
||||||
* @param supportedExtension a set of extensions a file could have to be
|
* supported MIME types, any type that starts with
|
||||||
* supported if the mime lookup fails or is
|
* this prefix will be regarded as supported
|
||||||
* inconclusive
|
* @param supportedMimeTypes a collection of mimetypes that are supported
|
||||||
* @param conditionalMimes a set of mimetypes that a file could have to be
|
* @param supportedExtension a collection of extensions that are supported
|
||||||
* supoprted if it also has a supported extension
|
|
||||||
*
|
*
|
||||||
* @return true if a thumbnail can be generated for the given file based on
|
* @return true if a thumbnail can be generated for the given file based on
|
||||||
* the given lists of supported mimetype and extensions
|
* the given MIME type prefix and lists of supported MIME types and
|
||||||
|
* extensions
|
||||||
*/
|
*/
|
||||||
static boolean isMediaThumbnailSupported(AbstractFile file, final SortedSet<String> supportedMimeTypes, final List<String> supportedExtension, List<String> conditionalMimes) {
|
static boolean isMediaThumbnailSupported(AbstractFile file, String mimeTypePrefix, final Collection<String> supportedMimeTypes, final List<String> supportedExtension) {
|
||||||
if (file.getSize() == 0) {
|
if (false == file.isFile() || file.getSize() <= 0) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
String mimeType = file.getMIMEType();
|
|
||||||
String extension = file.getNameExtension();
|
String extension = file.getNameExtension();
|
||||||
if (nonNull(mimeType)) {
|
|
||||||
return supportedMimeTypes.contains(mimeType)
|
if (StringUtils.isNotBlank(extension) && supportedExtension.contains(extension)) {
|
||||||
|| (conditionalMimes.contains(mimeType.toLowerCase())
|
return true;
|
||||||
&& supportedExtension.contains(extension));
|
|
||||||
} else {
|
} else {
|
||||||
return StringUtils.isNotBlank(extension) && supportedExtension.contains(extension);
|
try {
|
||||||
|
String mimeType = getFileTypeDetector().detect(file);
|
||||||
|
if (StringUtils.isNotBlank(mimeTypePrefix) && mimeType.startsWith(mimeTypePrefix)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return supportedMimeTypes.contains(mimeType);
|
||||||
|
} catch (FileTypeDetectorInitException | TskCoreException ex) {
|
||||||
|
LOGGER.log(Level.SEVERE, "Error determining MIME type of " + getContentPathSafe(file), ex);//NON-NLS
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* returns a lazily instatiated FileTypeDetector
|
* //TODO: AUT-2057 this FileTypeDetector needs to be recreated when the
|
||||||
|
* user adds new user defined file types.
|
||||||
|
*
|
||||||
|
* get a FileTypeDetector
|
||||||
*
|
*
|
||||||
* @return a FileTypeDetector
|
* @return a FileTypeDetector
|
||||||
*
|
*
|
||||||
* @throws FileTypeDetectorInitException if a initializing the
|
* @throws FileTypeDetectorInitException if initializing the
|
||||||
* FileTypeDetector failed.
|
* FileTypeDetector failed.
|
||||||
*/
|
*/
|
||||||
synchronized private static FileTypeDetector getFileTypeDetector() throws FileTypeDetector.FileTypeDetectorInitException {
|
synchronized private static FileTypeDetector getFileTypeDetector() throws FileTypeDetector.FileTypeDetectorInitException {
|
||||||
@ -292,27 +279,8 @@ public class ImageUtils {
|
|||||||
* Get a thumbnail of a specified size for the given image. Generates the
|
* Get a thumbnail of a specified size for the given image. Generates the
|
||||||
* thumbnail if it is not already cached.
|
* thumbnail if it is not already cached.
|
||||||
*
|
*
|
||||||
* @param content
|
* @param content the content to generate a thumbnail for
|
||||||
* @param iconSize
|
* @param iconSize the size (one side of a square) in pixels to generate
|
||||||
*
|
|
||||||
* @return a thumbnail for the given image or a default one if there was a
|
|
||||||
* problem making a thumbnail.
|
|
||||||
*
|
|
||||||
* @deprecated use {@link #getThumbnail(org.sleuthkit.datamodel.Content, int)
|
|
||||||
* } instead.
|
|
||||||
*/
|
|
||||||
@Nonnull
|
|
||||||
@Deprecated
|
|
||||||
public static BufferedImage getIcon(Content content, int iconSize) {
|
|
||||||
return getThumbnail(content, iconSize);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get a thumbnail of a specified size for the given image. Generates the
|
|
||||||
* thumbnail if it is not already cached.
|
|
||||||
*
|
|
||||||
* @param content
|
|
||||||
* @param iconSize
|
|
||||||
*
|
*
|
||||||
* @return a thumbnail for the given image or a default one if there was a
|
* @return a thumbnail for the given image or a default one if there was a
|
||||||
* problem making a thumbnail.
|
* problem making a thumbnail.
|
||||||
@ -334,34 +302,13 @@ public class ImageUtils {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Get a thumbnail of a specified size for the given image. Generates the
|
|
||||||
* thumbnail if it is not already cached.
|
|
||||||
*
|
|
||||||
* @param content
|
|
||||||
* @param iconSize
|
|
||||||
*
|
|
||||||
* @return File object for cached image. Is guaranteed to exist, as long as
|
|
||||||
* there was not an error generating or saving the thumbnail.
|
|
||||||
*
|
|
||||||
* @deprecated use {@link #getCachedThumbnailFile(org.sleuthkit.datamodel.Content, int)
|
|
||||||
* } instead.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
@Nullable
|
|
||||||
@Deprecated
|
|
||||||
public static File getIconFile(Content content, int iconSize) {
|
|
||||||
return getCachedThumbnailFile(content, iconSize);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* Get a thumbnail of a specified size for the given image. Generates the
|
* Get a thumbnail of a specified size for the given image. Generates the
|
||||||
* thumbnail if it is not already cached.
|
* thumbnail if it is not already cached.
|
||||||
*
|
*
|
||||||
* @param content
|
* @param content the content to generate a thumbnail for
|
||||||
* @param iconSize
|
* @param iconSize the size (one side of a square) in pixels to generate
|
||||||
*
|
*
|
||||||
* @return File object for cached image. Is guaranteed to exist, as long as
|
* @return File object for cached image. Is guaranteed to exist, as long as
|
||||||
* there was not an error generating or saving the thumbnail.
|
* there was not an error generating or saving the thumbnail.
|
||||||
@ -373,26 +320,10 @@ public class ImageUtils {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get a file object for where the cached icon should exist. The returned
|
* Get the location of the cached thumbnail for a file with the given fileID
|
||||||
* file may not exist.
|
* as a java {@link File}. The returned File may not exist on disk yet.
|
||||||
*
|
*
|
||||||
* @param id
|
* @param fileID the fileID to get the cached thumbnail location for
|
||||||
*
|
|
||||||
* @return
|
|
||||||
*
|
|
||||||
* @deprecated use {@link #getCachedThumbnailLocation(long) } instead
|
|
||||||
*/
|
|
||||||
@Deprecated
|
|
||||||
|
|
||||||
public static File getFile(long id) {
|
|
||||||
return getCachedThumbnailLocation(id);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get a file object for where the cached thumbnail should exist. The
|
|
||||||
* returned file may not exist.
|
|
||||||
*
|
|
||||||
* @param fileID
|
|
||||||
*
|
*
|
||||||
* @return a File object representing the location of the cached thumbnail.
|
* @return a File object representing the location of the cached thumbnail.
|
||||||
* This file may not actually exist(yet). Returns null if there was
|
* This file may not actually exist(yet). Returns null if there was
|
||||||
@ -401,19 +332,18 @@ public class ImageUtils {
|
|||||||
private static File getCachedThumbnailLocation(long fileID) {
|
private static File getCachedThumbnailLocation(long fileID) {
|
||||||
try {
|
try {
|
||||||
String cacheDirectory = Case.getCurrentCase().getCacheDirectory();
|
String cacheDirectory = Case.getCurrentCase().getCacheDirectory();
|
||||||
return Paths.get(cacheDirectory, "thumbnails", fileID + ".png").toFile(); //NOI18N NON-NLS
|
return Paths.get(cacheDirectory, "thumbnails", fileID + ".png").toFile(); //NON-NLS
|
||||||
} catch (IllegalStateException e) {
|
} catch (IllegalStateException e) {
|
||||||
LOGGER.log(Level.WARNING, "Could not get cached thumbnail location. No case is open."); //NON-NLS
|
LOGGER.log(Level.WARNING, "Could not get cached thumbnail location. No case is open."); //NON-NLS
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Do a direct check to see if the given file has an image file header.
|
* Do a direct check to see if the given file has an image file header.
|
||||||
* NOTE: Currently only jpeg and png are supported.
|
* NOTE: Currently only jpeg and png are supported.
|
||||||
*
|
*
|
||||||
* @param file
|
* @param file the AbstractFile to check
|
||||||
*
|
*
|
||||||
* @return true if the given file has one of the supported image headers.
|
* @return true if the given file has one of the supported image headers.
|
||||||
*/
|
*/
|
||||||
@ -424,7 +354,7 @@ public class ImageUtils {
|
|||||||
/**
|
/**
|
||||||
* Check if the given file is a jpeg based on header.
|
* Check if the given file is a jpeg based on header.
|
||||||
*
|
*
|
||||||
* @param file
|
* @param file the AbstractFile to check
|
||||||
*
|
*
|
||||||
* @return true if jpeg file, false otherwise
|
* @return true if jpeg file, false otherwise
|
||||||
*/
|
*/
|
||||||
@ -449,7 +379,7 @@ public class ImageUtils {
|
|||||||
/**
|
/**
|
||||||
* Check if the given file is a png based on header.
|
* Check if the given file is a png based on header.
|
||||||
*
|
*
|
||||||
* @param file
|
* @param file the AbstractFile to check
|
||||||
*
|
*
|
||||||
* @return true if png file, false otherwise
|
* @return true if png file, false otherwise
|
||||||
*/
|
*/
|
||||||
@ -481,7 +411,7 @@ public class ImageUtils {
|
|||||||
|
|
||||||
if (bytesRead != buffLength) {
|
if (bytesRead != buffLength) {
|
||||||
//ignore if can't read the first few bytes, not an image
|
//ignore if can't read the first few bytes, not an image
|
||||||
throw new TskCoreException("Could not read " + buffLength + " bytes from " + file.getName()); //NOI18N
|
throw new TskCoreException("Could not read " + buffLength + " bytes from " + file.getName());//NON-NLS
|
||||||
}
|
}
|
||||||
return fileHeaderBuffer;
|
return fileHeaderBuffer;
|
||||||
}
|
}
|
||||||
@ -498,7 +428,7 @@ public class ImageUtils {
|
|||||||
*/
|
*/
|
||||||
static public int getImageWidth(AbstractFile file) throws IOException {
|
static public int getImageWidth(AbstractFile file) throws IOException {
|
||||||
return getImageProperty(file,
|
return getImageProperty(file,
|
||||||
"ImageIO could not determine width of {0}: ", //NOI18N NON-NLS
|
"ImageIO could not determine width of {0}: ", //NON-NLS
|
||||||
imageReader -> imageReader.getWidth(0)
|
imageReader -> imageReader.getWidth(0)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -515,7 +445,7 @@ public class ImageUtils {
|
|||||||
*/
|
*/
|
||||||
static public int getImageHeight(AbstractFile file) throws IOException {
|
static public int getImageHeight(AbstractFile file) throws IOException {
|
||||||
return getImageProperty(file,
|
return getImageProperty(file,
|
||||||
"ImageIO could not determine height of {0}: ", //NOI18N NON-NLS
|
"ImageIO could not determine height of {0}: ", //NON-NLS
|
||||||
imageReader -> imageReader.getHeight(0)
|
imageReader -> imageReader.getHeight(0)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -537,7 +467,7 @@ public class ImageUtils {
|
|||||||
/**
|
/**
|
||||||
* Private template method designed to be used as the implementation of
|
* Private template method designed to be used as the implementation of
|
||||||
* public methods that pull particular (usually meta-)data out of a image
|
* public methods that pull particular (usually meta-)data out of a image
|
||||||
* file. ./**
|
* file.
|
||||||
*
|
*
|
||||||
* @param <T> the type of the property to be retrieved.
|
* @param <T> the type of the property to be retrieved.
|
||||||
* @param file the file to extract the data from
|
* @param file the file to extract the data from
|
||||||
@ -598,8 +528,9 @@ public class ImageUtils {
|
|||||||
* but is not started automatically. Clients are responsible for running the
|
* but is not started automatically. Clients are responsible for running the
|
||||||
* task, monitoring its progress, and using its result.
|
* task, monitoring its progress, and using its result.
|
||||||
*
|
*
|
||||||
* @param file the file to create a thumbnail for
|
* @param file The file to create a thumbnail for.
|
||||||
* @param iconSize the size of the thumbnail
|
* @param iconSize The size of the thumbnail.
|
||||||
|
* @param defaultOnFailure Whether or not to default on failure.
|
||||||
*
|
*
|
||||||
* @return a new Task that returns a thumbnail as its result.
|
* @return a new Task that returns a thumbnail as its result.
|
||||||
*/
|
*/
|
||||||
@ -612,7 +543,7 @@ public class ImageUtils {
|
|||||||
*/
|
*/
|
||||||
static private class GetThumbnailTask extends ReadImageTaskBase {
|
static private class GetThumbnailTask extends ReadImageTaskBase {
|
||||||
|
|
||||||
private static final String FAILED_TO_READ_IMAGE_FOR_THUMBNAIL_GENERATION = "Failed to read {0} for thumbnail generation."; //NOI18N NON-NLS
|
private static final String FAILED_TO_READ_IMAGE_FOR_THUMBNAIL_GENERATION = "Failed to read {0} for thumbnail generation."; //NON-NLS
|
||||||
|
|
||||||
private final int iconSize;
|
private final int iconSize;
|
||||||
private final File cacheFile;
|
private final File cacheFile;
|
||||||
@ -646,7 +577,7 @@ public class ImageUtils {
|
|||||||
return SwingFXUtils.toFXImage(cachedThumbnail, null);
|
return SwingFXUtils.toFXImage(cachedThumbnail, null);
|
||||||
}
|
}
|
||||||
} catch (Exception ex) {
|
} catch (Exception ex) {
|
||||||
LOGGER.log(Level.WARNING, "ImageIO had a problem reading the cached thumbnail for {0}: " + ex.toString(), ImageUtils.getContentPathSafe(file)); //NOI18N NON-NLS
|
LOGGER.log(Level.WARNING, "ImageIO had a problem reading the cached thumbnail for {0}: " + ex.toString(), ImageUtils.getContentPathSafe(file)); //NON-NLS
|
||||||
cacheFile.delete(); //since we can't read the file we might as well delete it.
|
cacheFile.delete(); //since we can't read the file we might as well delete it.
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -666,7 +597,7 @@ public class ImageUtils {
|
|||||||
if (defaultOnFailure) {
|
if (defaultOnFailure) {
|
||||||
thumbnail = DEFAULT_THUMBNAIL;
|
thumbnail = DEFAULT_THUMBNAIL;
|
||||||
} else {
|
} else {
|
||||||
throw new IIOException("Failed to generate a thumbnail for " + getContentPathSafe(file));
|
throw new IIOException("Failed to generate a thumbnail for " + getContentPathSafe(file));//NON-NLS
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -686,7 +617,7 @@ public class ImageUtils {
|
|||||||
thumbnail = ScalrWrapper.resizeFast(bufferedImage, iconSize);
|
thumbnail = ScalrWrapper.resizeFast(bufferedImage, iconSize);
|
||||||
} catch (IllegalArgumentException | OutOfMemoryError e) {
|
} catch (IllegalArgumentException | OutOfMemoryError e) {
|
||||||
// if resizing does not work due to extreme aspect ratio or oom, crop the image instead.
|
// if resizing does not work due to extreme aspect ratio or oom, crop the image instead.
|
||||||
LOGGER.log(Level.WARNING, "Cropping {0}, because it could not be scaled: " + e.toString(), ImageUtils.getContentPathSafe(file)); //NOI18N NON-NLS
|
LOGGER.log(Level.WARNING, "Cropping {0}, because it could not be scaled: " + e.toString(), ImageUtils.getContentPathSafe(file)); //NON-NLS
|
||||||
|
|
||||||
final int height = bufferedImage.getHeight();
|
final int height = bufferedImage.getHeight();
|
||||||
final int width = bufferedImage.getWidth();
|
final int width = bufferedImage.getWidth();
|
||||||
@ -696,11 +627,11 @@ public class ImageUtils {
|
|||||||
try {
|
try {
|
||||||
thumbnail = ScalrWrapper.cropImage(bufferedImage, cropWidth, cropHeight);
|
thumbnail = ScalrWrapper.cropImage(bufferedImage, cropWidth, cropHeight);
|
||||||
} catch (Exception cropException) {
|
} catch (Exception cropException) {
|
||||||
LOGGER.log(Level.WARNING, "Could not crop {0}: " + cropException.toString(), ImageUtils.getContentPathSafe(file)); //NOI18N NON-NLS
|
LOGGER.log(Level.WARNING, "Could not crop {0}: " + cropException.toString(), ImageUtils.getContentPathSafe(file)); //NON-NLS
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
LOGGER.log(Level.WARNING, "Could not scale {0}: " + e.toString(), ImageUtils.getContentPathSafe(file)); //NOI18N NON-NLS
|
LOGGER.log(Level.WARNING, "Could not scale {0}: " + e.toString(), ImageUtils.getContentPathSafe(file)); //NON-NLS
|
||||||
throw e;
|
throw e;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -733,7 +664,7 @@ public class ImageUtils {
|
|||||||
}
|
}
|
||||||
ImageIO.write(thumbnail, FORMAT, cacheFile);
|
ImageIO.write(thumbnail, FORMAT, cacheFile);
|
||||||
} catch (IllegalArgumentException | IOException ex) {
|
} catch (IllegalArgumentException | IOException ex) {
|
||||||
LOGGER.log(Level.WARNING, "Could not write thumbnail for {0}: " + ex.toString(), ImageUtils.getContentPathSafe(file)); //NOI18N NON-NLS
|
LOGGER.log(Level.WARNING, "Could not write thumbnail for {0}: " + ex.toString(), ImageUtils.getContentPathSafe(file)); //NON-NLS
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -745,7 +676,8 @@ public class ImageUtils {
|
|||||||
*
|
*
|
||||||
* Note: the returned task is suitable for running in a background thread,
|
* Note: the returned task is suitable for running in a background thread,
|
||||||
* but is not started automatically. Clients are responsible for running the
|
* but is not started automatically. Clients are responsible for running the
|
||||||
* task, monitoring its progress, and using its result.
|
* task, monitoring its progress, and using its result(including testing for
|
||||||
|
* null).
|
||||||
*
|
*
|
||||||
* @param file the file to read as an Image
|
* @param file the file to read as an Image
|
||||||
*
|
*
|
||||||
@ -779,7 +711,7 @@ public class ImageUtils {
|
|||||||
*/
|
*/
|
||||||
static private abstract class ReadImageTaskBase extends Task<javafx.scene.image.Image> implements IIOReadProgressListener {
|
static private abstract class ReadImageTaskBase extends Task<javafx.scene.image.Image> implements IIOReadProgressListener {
|
||||||
|
|
||||||
private static final String IMAGEIO_COULD_NOT_READ_UNSUPPORTE_OR_CORRUPT = "ImageIO could not read {0}. It may be unsupported or corrupt"; //NOI18N NON-NLS
|
private static final String IMAGEIO_COULD_NOT_READ_UNSUPPORTE_OR_CORRUPT = "ImageIO could not read {0}. It may be unsupported or corrupt"; //NON-NLS
|
||||||
final AbstractFile file;
|
final AbstractFile file;
|
||||||
// private ImageReader reader;
|
// private ImageReader reader;
|
||||||
|
|
||||||
@ -815,7 +747,7 @@ public class ImageUtils {
|
|||||||
try {
|
try {
|
||||||
bufferedImage = imageReader.read(0, param); //should always be same bufferedImage object
|
bufferedImage = imageReader.read(0, param); //should always be same bufferedImage object
|
||||||
} catch (IOException iOException) {
|
} catch (IOException iOException) {
|
||||||
LOGGER.log(Level.WARNING, IMAGEIO_COULD_NOT_READ_UNSUPPORTE_OR_CORRUPT + ": " + iOException.toString(), ImageUtils.getContentPathSafe(file)); //NOI18N
|
LOGGER.log(Level.WARNING, IMAGEIO_COULD_NOT_READ_UNSUPPORTE_OR_CORRUPT + ": " + iOException.toString(), ImageUtils.getContentPathSafe(file)); //NON-NLS
|
||||||
} finally {
|
} finally {
|
||||||
imageReader.removeIIOReadProgressListener(ReadImageTaskBase.this);
|
imageReader.removeIIOReadProgressListener(ReadImageTaskBase.this);
|
||||||
}
|
}
|
||||||
@ -901,15 +833,85 @@ public class ImageUtils {
|
|||||||
*
|
*
|
||||||
* @param content
|
* @param content
|
||||||
*
|
*
|
||||||
* @return
|
* @return the unique path for the content, or if that fails, just the name.
|
||||||
*/
|
*/
|
||||||
static String getContentPathSafe(Content content) {
|
static String getContentPathSafe(Content content) {
|
||||||
try {
|
try {
|
||||||
return content.getUniquePath();
|
return content.getUniquePath();
|
||||||
} catch (TskCoreException tskCoreException) {
|
} catch (TskCoreException tskCoreException) {
|
||||||
String contentName = content.getName();
|
String contentName = content.getName();
|
||||||
LOGGER.log(Level.SEVERE, "Failed to get unique path for " + contentName, tskCoreException); //NOI18N NON-NLS
|
LOGGER.log(Level.SEVERE, "Failed to get unique path for " + contentName, tskCoreException); //NON-NLS
|
||||||
return contentName;
|
return contentName;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the default thumbnail, which is the icon for a file. Used when we can
|
||||||
|
* not generate content based thumbnail.
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*
|
||||||
|
* @deprecated use {@link #getDefaultThumbnail() } instead.
|
||||||
|
*/
|
||||||
|
@Deprecated
|
||||||
|
public static Image getDefaultIcon() {
|
||||||
|
return getDefaultThumbnail();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a file object for where the cached icon should exist. The returned
|
||||||
|
* file may not exist.
|
||||||
|
*
|
||||||
|
* @param id
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*
|
||||||
|
* @deprecated use {@link #getCachedThumbnailLocation(long) } instead
|
||||||
|
*/
|
||||||
|
@Deprecated
|
||||||
|
|
||||||
|
public static File getFile(long id) {
|
||||||
|
return getCachedThumbnailLocation(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a thumbnail of a specified size for the given image. Generates the
|
||||||
|
* thumbnail if it is not already cached.
|
||||||
|
*
|
||||||
|
* @param content
|
||||||
|
* @param iconSize
|
||||||
|
*
|
||||||
|
* @return a thumbnail for the given image or a default one if there was a
|
||||||
|
* problem making a thumbnail.
|
||||||
|
*
|
||||||
|
* @deprecated use {@link #getThumbnail(org.sleuthkit.datamodel.Content, int)
|
||||||
|
* } instead.
|
||||||
|
*/
|
||||||
|
@Nonnull
|
||||||
|
@Deprecated
|
||||||
|
public static BufferedImage getIcon(Content content, int iconSize) {
|
||||||
|
return getThumbnail(content, iconSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a thumbnail of a specified size for the given image. Generates the
|
||||||
|
* thumbnail if it is not already cached.
|
||||||
|
*
|
||||||
|
* @param content
|
||||||
|
* @param iconSize
|
||||||
|
*
|
||||||
|
* @return File object for cached image. Is guaranteed to exist, as long as
|
||||||
|
* there was not an error generating or saving the thumbnail.
|
||||||
|
*
|
||||||
|
* @deprecated use {@link #getCachedThumbnailFile(org.sleuthkit.datamodel.Content, int)
|
||||||
|
* } instead.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
@Nullable
|
||||||
|
@Deprecated
|
||||||
|
public static File getIconFile(Content content, int iconSize) {
|
||||||
|
return getCachedThumbnailFile(content, iconSize);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* Autopsy Forensic Browser
|
* Autopsy Forensic Browser
|
||||||
*
|
*
|
||||||
* Copyright 2012 Basis Technology Corp.
|
* Copyright 2011-2016 Basis Technology Corp.
|
||||||
* Contact: carrier <at> sleuthkit <dot> org
|
* Contact: carrier <at> sleuthkit <dot> org
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
@ -25,14 +25,12 @@ import java.util.ArrayList;
|
|||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
|
||||||
import org.sleuthkit.autopsy.coreutils.LnkEnums.CommonCLSIDS;
|
import org.sleuthkit.autopsy.coreutils.LnkEnums.CommonCLSIDS;
|
||||||
import org.sleuthkit.autopsy.coreutils.LnkEnums.DriveType;
|
import org.sleuthkit.autopsy.coreutils.LnkEnums.DriveType;
|
||||||
import org.sleuthkit.autopsy.coreutils.LnkEnums.NetworkProviderType;
|
import org.sleuthkit.autopsy.coreutils.LnkEnums.NetworkProviderType;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
* Parse lnk files using documentation from:
|
||||||
* @author dfickling Parse lnk files using documentation from
|
|
||||||
* http://msdn.microsoft.com/en-us/library/dd871305(v=prot.13).aspx
|
* http://msdn.microsoft.com/en-us/library/dd871305(v=prot.13).aspx
|
||||||
* http://msdn.microsoft.com/en-us/library/windows/desktop/cc144090(v=vs.85).aspx#unknown_74413
|
* http://msdn.microsoft.com/en-us/library/windows/desktop/cc144090(v=vs.85).aspx#unknown_74413
|
||||||
* http://blog.0x01000000.org/2010/08/10/lnk-parsing-youre-doing-it-wrong-i/
|
* http://blog.0x01000000.org/2010/08/10/lnk-parsing-youre-doing-it-wrong-i/
|
||||||
@ -67,12 +65,12 @@ public class JLnkParser {
|
|||||||
int showCommand = bb.getInt();
|
int showCommand = bb.getInt();
|
||||||
short hotkey = bb.getShort();
|
short hotkey = bb.getShort();
|
||||||
bb.get(new byte[10]); // reserved (???)
|
bb.get(new byte[10]); // reserved (???)
|
||||||
List<String> linkTargetIdList = new ArrayList<String>();
|
List<String> linkTargetIdList = new ArrayList<>();
|
||||||
if ((linkFlags & LnkEnums.LinkFlags.HasLinkTargetIDList.getFlag())
|
if ((linkFlags & LnkEnums.LinkFlags.HasLinkTargetIDList.getFlag())
|
||||||
== LnkEnums.LinkFlags.HasLinkTargetIDList.getFlag()) {
|
== LnkEnums.LinkFlags.HasLinkTargetIDList.getFlag()) {
|
||||||
int idListSize = bb.getShort();
|
int idListSize = bb.getShort();
|
||||||
int bytesRead = 0;
|
int bytesRead = 0;
|
||||||
List<byte[]> linkTargetIdListBytes = new ArrayList<byte[]>();
|
List<byte[]> linkTargetIdListBytes = new ArrayList<>();
|
||||||
while (true) {
|
while (true) {
|
||||||
short itemIdSize = bb.getShort();
|
short itemIdSize = bb.getShort();
|
||||||
if (itemIdSize == 0) {
|
if (itemIdSize == 0) {
|
||||||
@ -82,7 +80,7 @@ public class JLnkParser {
|
|||||||
byte[] theArray = new byte[itemIdSize - 2];
|
byte[] theArray = new byte[itemIdSize - 2];
|
||||||
bb.get(theArray); // an idlist data object
|
bb.get(theArray); // an idlist data object
|
||||||
linkTargetIdListBytes.add(theArray);
|
linkTargetIdListBytes.add(theArray);
|
||||||
bytesRead = bytesRead + itemIdSize;
|
bytesRead += itemIdSize;
|
||||||
}
|
}
|
||||||
linkTargetIdList = parseLinkTargetIdList(linkTargetIdListBytes);
|
linkTargetIdList = parseLinkTargetIdList(linkTargetIdListBytes);
|
||||||
}
|
}
|
||||||
@ -272,7 +270,7 @@ public class JLnkParser {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private List<String> parseLinkTargetIdList(List<byte[]> idList) {
|
private List<String> parseLinkTargetIdList(List<byte[]> idList) {
|
||||||
List<String> ret = new ArrayList<String>();
|
List<String> ret = new ArrayList<>();
|
||||||
if (!idList.isEmpty()) {
|
if (!idList.isEmpty()) {
|
||||||
CommonCLSIDS clsid = CommonCLSIDS.valueOf(Arrays.copyOfRange(idList.remove(0), 2, 18));
|
CommonCLSIDS clsid = CommonCLSIDS.valueOf(Arrays.copyOfRange(idList.remove(0), 2, 18));
|
||||||
switch (clsid) {
|
switch (clsid) {
|
||||||
@ -295,7 +293,7 @@ public class JLnkParser {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private List<String> parsePathElements(List<byte[]> idList) {
|
private List<String> parsePathElements(List<byte[]> idList) {
|
||||||
List<String> ret = new ArrayList<String>();
|
List<String> ret = new ArrayList<>();
|
||||||
for (byte[] pathElement : idList) {
|
for (byte[] pathElement : idList) {
|
||||||
ByteBuffer bb = ByteBuffer.wrap(pathElement);
|
ByteBuffer bb = ByteBuffer.wrap(pathElement);
|
||||||
bb.order(ByteOrder.LITTLE_ENDIAN);
|
bb.order(ByteOrder.LITTLE_ENDIAN);
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* Autopsy Forensic Browser
|
* Autopsy Forensic Browser
|
||||||
*
|
*
|
||||||
* Copyright 2015 Basis Technology Corp.
|
* Copyright 2011-2016 Basis Technology Corp.
|
||||||
* Contact: carrier <at> sleuthkit <dot> org
|
* Contact: carrier <at> sleuthkit <dot> org
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
@ -60,7 +60,8 @@ public class UNCPathUtilities {
|
|||||||
/**
|
/**
|
||||||
* This method converts a passed in path to UNC if it is not already UNC.
|
* This method converts a passed in path to UNC if it is not already UNC.
|
||||||
* The UNC path will end up in one of the following two forms:
|
* The UNC path will end up in one of the following two forms:
|
||||||
* \\hostname\somefolder\otherfolder or \\IP_ADDRESS\somefolder\otherfolder
|
* "\\hostname\somefolder\otherfolder" or
|
||||||
|
* "\\IP_ADDRESS\somefolder\otherfolder"
|
||||||
*
|
*
|
||||||
* This is accomplished by checking the mapped drives list the operating
|
* This is accomplished by checking the mapped drives list the operating
|
||||||
* system maintains and substituting where required. If the drive of the
|
* system maintains and substituting where required. If the drive of the
|
||||||
@ -167,9 +168,10 @@ public class UNCPathUtilities {
|
|||||||
/**
|
/**
|
||||||
* Takes a UNC path that may have an IP address in it and converts it to
|
* Takes a UNC path that may have an IP address in it and converts it to
|
||||||
* hostname, if it can resolve the hostname. Given
|
* hostname, if it can resolve the hostname. Given
|
||||||
* \\10.11.12.13\some\folder, the result will be \\TEDS_COMPUTER\some\folder
|
* "\\10.11.12.13\some\folder", the result will be
|
||||||
* if the IP address 10.11.12.13 belongs to a machine with the hostname
|
* "\\TEDS_COMPUTER\some\folder" if the IP address 10.11.12.13 belongs to a
|
||||||
* TEDS_COMPUTER and the local machine is able to resolve the hostname.
|
* machine with the hostname TEDS_COMPUTER and the local machine is able to
|
||||||
|
* resolve the hostname.
|
||||||
*
|
*
|
||||||
* @param inputPath the path to convert to a hostname UNC path
|
* @param inputPath the path to convert to a hostname UNC path
|
||||||
*
|
*
|
||||||
@ -186,9 +188,10 @@ public class UNCPathUtilities {
|
|||||||
/**
|
/**
|
||||||
* Takes a UNC path that may have an IP address in it and converts it to
|
* Takes a UNC path that may have an IP address in it and converts it to
|
||||||
* hostname, if it can resolve the hostname. Given
|
* hostname, if it can resolve the hostname. Given
|
||||||
* \\10.11.12.13\some\folder, the result will be \\TEDS_COMPUTER\some\folder
|
* "\\10.11.12.13\some\folder", the result will be
|
||||||
* if the IP address 10.11.12.13 belongs to a machine with the hostname
|
* "\\TEDS_COMPUTER\some\folder" if the IP address 10.11.12.13 belongs to a
|
||||||
* TEDS_COMPUTER and the local machine is able to resolve the hostname.
|
* machine with the hostname TEDS_COMPUTER and the local machine is able to
|
||||||
|
* resolve the hostname.
|
||||||
*
|
*
|
||||||
* @param inputPath a String of the path to convert to a hostname UNC path
|
* @param inputPath a String of the path to convert to a hostname UNC path
|
||||||
*
|
*
|
||||||
@ -263,6 +266,11 @@ public class UNCPathUtilities {
|
|||||||
*/
|
*/
|
||||||
synchronized private Map<String, String> getMappedDrives() {
|
synchronized private Map<String, String> getMappedDrives() {
|
||||||
Map<String, String> driveMap = new HashMap<>();
|
Map<String, String> driveMap = new HashMap<>();
|
||||||
|
|
||||||
|
if (PlatformUtil.isWindowsOS() == false) {
|
||||||
|
return driveMap;
|
||||||
|
}
|
||||||
|
|
||||||
File mappedDrive = Paths.get(System.getenv(TEMP_FOLDER), nameString + MAPPED_DRIVES).toFile();
|
File mappedDrive = Paths.get(System.getenv(TEMP_FOLDER), nameString + MAPPED_DRIVES).toFile();
|
||||||
try {
|
try {
|
||||||
Files.deleteIfExists(mappedDrive.toPath());
|
Files.deleteIfExists(mappedDrive.toPath());
|
||||||
|
@ -60,10 +60,17 @@ public class VideoUtils {
|
|||||||
"flm", "tmv", "4xm"); //NON-NLS
|
"flm", "tmv", "4xm"); //NON-NLS
|
||||||
|
|
||||||
private static final SortedSet<String> SUPPORTED_VIDEO_MIME_TYPES = new TreeSet<>(
|
private static final SortedSet<String> SUPPORTED_VIDEO_MIME_TYPES = new TreeSet<>(
|
||||||
Arrays.asList("application/x-shockwave-flash", "video/x-m4v", "video/x-flv", "video/quicktime", "video/avi", "video/msvideo", "video/x-msvideo", //NON-NLS
|
Arrays.asList("application/x-shockwave-flash",
|
||||||
"video/mp4", "video/x-ms-wmv", "video/mpeg", "video/asf")); //NON-NLS
|
"video/x-m4v",
|
||||||
|
"video/x-flv",
|
||||||
private static final List<String> CONDITIONAL_MIME_TYPES = Arrays.asList("application/octet-stream"); //NON-NLS
|
"video/quicktime",
|
||||||
|
"video/avi",
|
||||||
|
"video/msvideo",
|
||||||
|
"video/x-msvideo", //NON-NLS
|
||||||
|
"video/mp4",
|
||||||
|
"video/x-ms-wmv",
|
||||||
|
"video/mpeg",
|
||||||
|
"video/asf")); //NON-NLS
|
||||||
|
|
||||||
public static List<String> getSupportedVideoExtensions() {
|
public static List<String> getSupportedVideoExtensions() {
|
||||||
return SUPPORTED_VIDEO_EXTENSIONS;
|
return SUPPORTED_VIDEO_EXTENSIONS;
|
||||||
@ -89,7 +96,7 @@ public class VideoUtils {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static boolean isVideoThumbnailSupported(AbstractFile file) {
|
public static boolean isVideoThumbnailSupported(AbstractFile file) {
|
||||||
return isMediaThumbnailSupported(file, SUPPORTED_VIDEO_MIME_TYPES, SUPPORTED_VIDEO_EXTENSIONS, CONDITIONAL_MIME_TYPES);
|
return isMediaThumbnailSupported(file, "video/", SUPPORTED_VIDEO_MIME_TYPES, SUPPORTED_VIDEO_EXTENSIONS);
|
||||||
}
|
}
|
||||||
|
|
||||||
@NbBundle.Messages({"# {0} - file name",
|
@NbBundle.Messages({"# {0} - file name",
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* Autopsy Forensic Browser
|
* Autopsy Forensic Browser
|
||||||
*
|
*
|
||||||
* Copyright 2011-2013 Basis Technology Corp.
|
* Copyright 2011-2016 Basis Technology Corp.
|
||||||
* Contact: carrier <at> sleuthkit <dot> org
|
* Contact: carrier <at> sleuthkit <dot> org
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
@ -50,6 +50,7 @@ public class ArtifactStringContent implements StringContent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@SuppressWarnings("deprecation")
|
||||||
public String getString() {
|
public String getString() {
|
||||||
if (stringContent.isEmpty()) {
|
if (stringContent.isEmpty()) {
|
||||||
try {
|
try {
|
||||||
|
@ -286,25 +286,19 @@ public class BlackboardArtifactNode extends DisplayableItemNode {
|
|||||||
* are put
|
* are put
|
||||||
* @param artifact to extract properties from
|
* @param artifact to extract properties from
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings("deprecation") // TODO: Remove this when TSK_TAGGED_ARTIFACT rows are removed in a database upgrade.
|
@SuppressWarnings("deprecation")
|
||||||
private void fillPropertyMap(Map<String, Object> map, BlackboardArtifact artifact) {
|
private void fillPropertyMap(Map<String, Object> map, BlackboardArtifact artifact) {
|
||||||
try {
|
try {
|
||||||
for (BlackboardAttribute attribute : artifact.getAttributes()) {
|
for (BlackboardAttribute attribute : artifact.getAttributes()) {
|
||||||
final int attributeTypeID = attribute.getAttributeTypeID();
|
final int attributeTypeID = attribute.getAttributeType().getTypeID();
|
||||||
//skip some internal attributes that user shouldn't see
|
//skip some internal attributes that user shouldn't see
|
||||||
if (attributeTypeID == ATTRIBUTE_TYPE.TSK_PATH_ID.getTypeID()
|
if (attributeTypeID == ATTRIBUTE_TYPE.TSK_PATH_ID.getTypeID()
|
||||||
|| attributeTypeID == ATTRIBUTE_TYPE.TSK_TAGGED_ARTIFACT.getTypeID()
|
|| attributeTypeID == ATTRIBUTE_TYPE.TSK_TAGGED_ARTIFACT.getTypeID()
|
||||||
|| attributeTypeID == ATTRIBUTE_TYPE.TSK_ASSOCIATED_ARTIFACT.getTypeID()
|
|| attributeTypeID == ATTRIBUTE_TYPE.TSK_ASSOCIATED_ARTIFACT.getTypeID()
|
||||||
|| attributeTypeID == ATTRIBUTE_TYPE.TSK_SET_NAME.getTypeID()) {
|
|| attributeTypeID == ATTRIBUTE_TYPE.TSK_SET_NAME.getTypeID()) {
|
||||||
} else if (attributeTypeID == ATTRIBUTE_TYPE.TSK_DATETIME.getTypeID()
|
continue;
|
||||||
|| attributeTypeID == ATTRIBUTE_TYPE.TSK_DATETIME_ACCESSED.getTypeID()
|
} else if (attribute.getAttributeType().getValueType() == BlackboardAttribute.TSK_BLACKBOARD_ATTRIBUTE_VALUE_TYPE.DATETIME) {
|
||||||
|| attributeTypeID == ATTRIBUTE_TYPE.TSK_DATETIME_CREATED.getTypeID()
|
map.put(attribute.getAttributeType().getDisplayName(), ContentUtils.getStringTime(attribute.getValueLong(), associated));
|
||||||
|| attributeTypeID == ATTRIBUTE_TYPE.TSK_DATETIME_MODIFIED.getTypeID()
|
|
||||||
|| attributeTypeID == ATTRIBUTE_TYPE.TSK_DATETIME_RCVD.getTypeID()
|
|
||||||
|| attributeTypeID == ATTRIBUTE_TYPE.TSK_DATETIME_SENT.getTypeID()
|
|
||||||
|| attributeTypeID == ATTRIBUTE_TYPE.TSK_DATETIME_START.getTypeID()
|
|
||||||
|| attributeTypeID == ATTRIBUTE_TYPE.TSK_DATETIME_END.getTypeID()) {
|
|
||||||
map.put(attribute.getAttributeTypeDisplayName(), ContentUtils.getStringTime(attribute.getValueLong(), associated));
|
|
||||||
} else if (artifact.getArtifactTypeID() == ARTIFACT_TYPE.TSK_TOOL_OUTPUT.getTypeID()
|
} else if (artifact.getArtifactTypeID() == ARTIFACT_TYPE.TSK_TOOL_OUTPUT.getTypeID()
|
||||||
&& attributeTypeID == ATTRIBUTE_TYPE.TSK_TEXT.getTypeID()) {
|
&& attributeTypeID == ATTRIBUTE_TYPE.TSK_TEXT.getTypeID()) {
|
||||||
/*
|
/*
|
||||||
@ -318,9 +312,9 @@ public class BlackboardArtifactNode extends DisplayableItemNode {
|
|||||||
if (value.length() > 512) {
|
if (value.length() > 512) {
|
||||||
value = value.substring(0, 512);
|
value = value.substring(0, 512);
|
||||||
}
|
}
|
||||||
map.put(attribute.getAttributeTypeDisplayName(), value);
|
map.put(attribute.getAttributeType().getDisplayName(), value);
|
||||||
} else {
|
} else {
|
||||||
map.put(attribute.getAttributeTypeDisplayName(), attribute.getDisplayString());
|
map.put(attribute.getAttributeType().getDisplayName(), attribute.getDisplayString());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (TskException ex) {
|
} catch (TskException ex) {
|
||||||
|
@ -210,29 +210,17 @@ public class ExtractedContent implements AutopsyVisitableItem {
|
|||||||
|
|
||||||
// these are shown in other parts of the UI tree
|
// these are shown in other parts of the UI tree
|
||||||
doNotShow.add(new BlackboardArtifact.Type(
|
doNotShow.add(new BlackboardArtifact.Type(
|
||||||
BlackboardArtifact.ARTIFACT_TYPE.TSK_GEN_INFO.getTypeID(),
|
BlackboardArtifact.ARTIFACT_TYPE.TSK_GEN_INFO));
|
||||||
BlackboardArtifact.ARTIFACT_TYPE.TSK_GEN_INFO.getLabel(),
|
|
||||||
BlackboardArtifact.ARTIFACT_TYPE.TSK_GEN_INFO.getDisplayName()));
|
|
||||||
doNotShow.add(new BlackboardArtifact.Type(
|
doNotShow.add(new BlackboardArtifact.Type(
|
||||||
BlackboardArtifact.ARTIFACT_TYPE.TSK_EMAIL_MSG.getTypeID(),
|
BlackboardArtifact.ARTIFACT_TYPE.TSK_EMAIL_MSG));
|
||||||
BlackboardArtifact.ARTIFACT_TYPE.TSK_EMAIL_MSG.getLabel(),
|
|
||||||
BlackboardArtifact.ARTIFACT_TYPE.TSK_EMAIL_MSG.getDisplayName()));
|
|
||||||
doNotShow.add(new BlackboardArtifact.Type(
|
doNotShow.add(new BlackboardArtifact.Type(
|
||||||
BlackboardArtifact.ARTIFACT_TYPE.TSK_HASHSET_HIT.getTypeID(),
|
BlackboardArtifact.ARTIFACT_TYPE.TSK_HASHSET_HIT));
|
||||||
BlackboardArtifact.ARTIFACT_TYPE.TSK_HASHSET_HIT.getLabel(),
|
|
||||||
BlackboardArtifact.ARTIFACT_TYPE.TSK_HASHSET_HIT.getDisplayName()));
|
|
||||||
doNotShow.add(new BlackboardArtifact.Type(
|
doNotShow.add(new BlackboardArtifact.Type(
|
||||||
BlackboardArtifact.ARTIFACT_TYPE.TSK_KEYWORD_HIT.getTypeID(),
|
BlackboardArtifact.ARTIFACT_TYPE.TSK_KEYWORD_HIT));
|
||||||
BlackboardArtifact.ARTIFACT_TYPE.TSK_KEYWORD_HIT.getLabel(),
|
|
||||||
BlackboardArtifact.ARTIFACT_TYPE.TSK_KEYWORD_HIT.getDisplayName()));
|
|
||||||
doNotShow.add(new BlackboardArtifact.Type(
|
doNotShow.add(new BlackboardArtifact.Type(
|
||||||
BlackboardArtifact.ARTIFACT_TYPE.TSK_INTERESTING_FILE_HIT.getTypeID(),
|
BlackboardArtifact.ARTIFACT_TYPE.TSK_INTERESTING_FILE_HIT));
|
||||||
BlackboardArtifact.ARTIFACT_TYPE.TSK_INTERESTING_FILE_HIT.getLabel(),
|
|
||||||
BlackboardArtifact.ARTIFACT_TYPE.TSK_INTERESTING_FILE_HIT.getDisplayName()));
|
|
||||||
doNotShow.add(new BlackboardArtifact.Type(
|
doNotShow.add(new BlackboardArtifact.Type(
|
||||||
BlackboardArtifact.ARTIFACT_TYPE.TSK_INTERESTING_ARTIFACT_HIT.getTypeID(),
|
BlackboardArtifact.ARTIFACT_TYPE.TSK_INTERESTING_ARTIFACT_HIT));
|
||||||
BlackboardArtifact.ARTIFACT_TYPE.TSK_INTERESTING_ARTIFACT_HIT.getLabel(),
|
|
||||||
BlackboardArtifact.ARTIFACT_TYPE.TSK_INTERESTING_ARTIFACT_HIT.getDisplayName()));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private final PropertyChangeListener pcl = (PropertyChangeEvent evt) -> {
|
private final PropertyChangeListener pcl = (PropertyChangeEvent evt) -> {
|
||||||
|
@ -21,6 +21,7 @@ package org.sleuthkit.autopsy.datamodel;
|
|||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import javax.swing.Action;
|
import javax.swing.Action;
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.openide.util.NbBundle;
|
import org.openide.util.NbBundle;
|
||||||
import org.sleuthkit.autopsy.actions.AddContentTagAction;
|
import org.sleuthkit.autopsy.actions.AddContentTagAction;
|
||||||
import org.sleuthkit.autopsy.coreutils.ContextMenuExtensionPoint;
|
import org.sleuthkit.autopsy.coreutils.ContextMenuExtensionPoint;
|
||||||
@ -110,70 +111,52 @@ public class FileNode extends AbstractFsContentNode<AbstractFile> {
|
|||||||
// file based off it's extension
|
// file based off it's extension
|
||||||
static String getIconForFileType(AbstractFile file) {
|
static String getIconForFileType(AbstractFile file) {
|
||||||
// Get the name, extension
|
// Get the name, extension
|
||||||
String name = file.getName();
|
String ext = file.getNameExtension();
|
||||||
int dotIndex = name.lastIndexOf(".");
|
|
||||||
if (dotIndex == -1) {
|
|
||||||
return "org/sleuthkit/autopsy/images/file-icon.png"; //NON-NLS
|
|
||||||
}
|
|
||||||
String ext = name.substring(dotIndex).toLowerCase();
|
|
||||||
|
|
||||||
// Images
|
if (StringUtils.isBlank(ext)) {
|
||||||
for (String s : FileTypeExtensions.getImageExtensions()) {
|
return "org/sleuthkit/autopsy/images/file-icon.png"; //NON-NLS
|
||||||
if (ImageUtils.thumbnailSupported(file) || ext.equals(s)) {
|
} else {
|
||||||
|
ext = "." + ext;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ImageUtils.isImageThumbnailSupported(file)
|
||||||
|
|| FileTypeExtensions.getImageExtensions().contains(ext)) {
|
||||||
return "org/sleuthkit/autopsy/images/image-file.png"; //NON-NLS
|
return "org/sleuthkit/autopsy/images/image-file.png"; //NON-NLS
|
||||||
}
|
}
|
||||||
}
|
|
||||||
// Videos
|
// Videos
|
||||||
for (String s : FileTypeExtensions.getVideoExtensions()) {
|
if (FileTypeExtensions.getVideoExtensions().contains(ext)) {
|
||||||
if (ext.equals(s)) {
|
|
||||||
return "org/sleuthkit/autopsy/images/video-file.png"; //NON-NLS
|
return "org/sleuthkit/autopsy/images/video-file.png"; //NON-NLS
|
||||||
}
|
}
|
||||||
}
|
|
||||||
// Audio Files
|
// Audio Files
|
||||||
for (String s : FileTypeExtensions.getAudioExtensions()) {
|
if (FileTypeExtensions.getAudioExtensions().contains(ext)) {
|
||||||
if (ext.equals(s)) {
|
|
||||||
return "org/sleuthkit/autopsy/images/audio-file.png"; //NON-NLS
|
return "org/sleuthkit/autopsy/images/audio-file.png"; //NON-NLS
|
||||||
}
|
}
|
||||||
}
|
|
||||||
// Documents
|
// Documents
|
||||||
for (String s : FileTypeExtensions.getDocumentExtensions()) {
|
if (FileTypeExtensions.getDocumentExtensions().contains(ext)) {
|
||||||
if (ext.equals(s)) {
|
|
||||||
return "org/sleuthkit/autopsy/images/doc-file.png"; //NON-NLS
|
return "org/sleuthkit/autopsy/images/doc-file.png"; //NON-NLS
|
||||||
}
|
}
|
||||||
}
|
|
||||||
// Executables / System Files
|
// Executables / System Files
|
||||||
for (String s : FileTypeExtensions.getExecutableExtensions()) {
|
if (FileTypeExtensions.getExecutableExtensions().contains(ext)) {
|
||||||
if (ext.equals(s)) {
|
|
||||||
return "org/sleuthkit/autopsy/images/exe-file.png"; //NON-NLS
|
return "org/sleuthkit/autopsy/images/exe-file.png"; //NON-NLS
|
||||||
}
|
}
|
||||||
}
|
|
||||||
// Text Files
|
// Text Files
|
||||||
for (String s : FileTypeExtensions.getTextExtensions()) {
|
if (FileTypeExtensions.getTextExtensions().contains(ext)) {
|
||||||
if (ext.equals(s)) {
|
|
||||||
return "org/sleuthkit/autopsy/images/text-file.png"; //NON-NLS
|
return "org/sleuthkit/autopsy/images/text-file.png"; //NON-NLS
|
||||||
}
|
}
|
||||||
}
|
|
||||||
// Web Files
|
// Web Files
|
||||||
for (String s : FileTypeExtensions.getWebExtensions()) {
|
if (FileTypeExtensions.getWebExtensions().contains(ext)) {
|
||||||
if (ext.equals(s)) {
|
|
||||||
return "org/sleuthkit/autopsy/images/web-file.png"; //NON-NLS
|
return "org/sleuthkit/autopsy/images/web-file.png"; //NON-NLS
|
||||||
}
|
}
|
||||||
}
|
|
||||||
// PDFs
|
// PDFs
|
||||||
for (String s : FileTypeExtensions.getPDFExtensions()) {
|
if (FileTypeExtensions.getPDFExtensions().contains(ext)) {
|
||||||
if (ext.equals(s)) {
|
|
||||||
return "org/sleuthkit/autopsy/images/pdf-file.png"; //NON-NLS
|
return "org/sleuthkit/autopsy/images/pdf-file.png"; //NON-NLS
|
||||||
}
|
}
|
||||||
}
|
|
||||||
// Archives
|
// Archives
|
||||||
for (String s : FileTypeExtensions.getArchiveExtensions()) {
|
if (FileTypeExtensions.getArchiveExtensions().contains(ext)) {
|
||||||
if (ext.equals(s)) {
|
|
||||||
return "org/sleuthkit/autopsy/images/archive-file.png"; //NON-NLS
|
return "org/sleuthkit/autopsy/images/archive-file.png"; //NON-NLS
|
||||||
}
|
}
|
||||||
}
|
|
||||||
// Else return the default
|
// Else return the default
|
||||||
return "org/sleuthkit/autopsy/images/file-icon.png"; //NON-NLS
|
return "org/sleuthkit/autopsy/images/file-icon.png"; //NON-NLS
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -55,7 +55,7 @@ public class VirtualDirectoryNode extends AbstractAbstractFileNode<VirtualDirect
|
|||||||
//set icon for name, special case for some built-ins
|
//set icon for name, special case for some built-ins
|
||||||
if (name.equals(VirtualDirectory.NAME_UNALLOC)) {
|
if (name.equals(VirtualDirectory.NAME_UNALLOC)) {
|
||||||
this.setIconBaseWithExtension("org/sleuthkit/autopsy/images/folder-icon-deleted.png"); //NON-NLS
|
this.setIconBaseWithExtension("org/sleuthkit/autopsy/images/folder-icon-deleted.png"); //NON-NLS
|
||||||
} else if (name.startsWith(LOGICAL_FILE_SET_PREFIX)) {
|
} else if (ld.isDataSource()) {
|
||||||
this.setIconBaseWithExtension("org/sleuthkit/autopsy/images/fileset-icon-16.png"); //NON-NLS
|
this.setIconBaseWithExtension("org/sleuthkit/autopsy/images/fileset-icon-16.png"); //NON-NLS
|
||||||
} else if (name.equals(VirtualDirectory.NAME_CARVED)) {
|
} else if (name.equals(VirtualDirectory.NAME_CARVED)) {
|
||||||
this.setIconBaseWithExtension("org/sleuthkit/autopsy/images/Folder-icon.png"); //TODO NON-NLS
|
this.setIconBaseWithExtension("org/sleuthkit/autopsy/images/Folder-icon.png"); //TODO NON-NLS
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* Autopsy Forensic Browser
|
* Autopsy Forensic Browser
|
||||||
*
|
*
|
||||||
* Copyright 2014 Basis Technology Corp.
|
* Copyright 2011-2016 Basis Technology Corp.
|
||||||
* Contact: carrier <at> sleuthkit <dot> org
|
* Contact: carrier <at> sleuthkit <dot> org
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
@ -26,7 +26,6 @@ import java.util.Collection;
|
|||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
import org.openide.util.Exceptions;
|
|
||||||
import org.openide.util.NbBundle;
|
import org.openide.util.NbBundle;
|
||||||
import org.sleuthkit.autopsy.casemodule.Case;
|
import org.sleuthkit.autopsy.casemodule.Case;
|
||||||
import org.sleuthkit.autopsy.casemodule.services.Blackboard;
|
import org.sleuthkit.autopsy.casemodule.services.Blackboard;
|
||||||
@ -34,7 +33,6 @@ import org.sleuthkit.autopsy.casemodule.services.FileManager;
|
|||||||
import org.sleuthkit.autopsy.coreutils.ErrorInfo;
|
import org.sleuthkit.autopsy.coreutils.ErrorInfo;
|
||||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||||
import org.sleuthkit.autopsy.coreutils.MessageNotifyUtil;
|
import org.sleuthkit.autopsy.coreutils.MessageNotifyUtil;
|
||||||
import org.sleuthkit.autopsy.ingest.IngestModule;
|
|
||||||
import org.sleuthkit.autopsy.ingest.IngestServices;
|
import org.sleuthkit.autopsy.ingest.IngestServices;
|
||||||
import org.sleuthkit.autopsy.ingest.ModuleContentEvent;
|
import org.sleuthkit.autopsy.ingest.ModuleContentEvent;
|
||||||
import org.sleuthkit.autopsy.ingest.ModuleDataEvent;
|
import org.sleuthkit.autopsy.ingest.ModuleDataEvent;
|
||||||
@ -72,8 +70,9 @@ public final class ExternalResultsImporter {
|
|||||||
* artifacts, derived files, reports)from the data source.
|
* artifacts, derived files, reports)from the data source.
|
||||||
*
|
*
|
||||||
* @return A collection of error messages, possibly empty. The error
|
* @return A collection of error messages, possibly empty. The error
|
||||||
* messages are already logged but are provided to allow the caller to
|
* messages are already logged but are provided to allow the caller
|
||||||
* provide additional user feedback via the Autopsy user interface.
|
* to provide additional user feedback via the Autopsy user
|
||||||
|
* interface.
|
||||||
*/
|
*/
|
||||||
public List<ErrorInfo> importResults(ExternalResults results) {
|
public List<ErrorInfo> importResults(ExternalResults results) {
|
||||||
blackboard = Case.getCurrentCase().getServices().getBlackboard();
|
blackboard = Case.getCurrentCase().getServices().getBlackboard();
|
||||||
@ -133,7 +132,7 @@ public final class ExternalResultsImporter {
|
|||||||
for (ExternalResults.Artifact artifactData : results.getArtifacts()) {
|
for (ExternalResults.Artifact artifactData : results.getArtifacts()) {
|
||||||
try {
|
try {
|
||||||
// Add the artifact to the case database.
|
// Add the artifact to the case database.
|
||||||
int artifactTypeId = caseDb.getArtifactTypeID(artifactData.getType());
|
int artifactTypeId = caseDb.getArtifactType(artifactData.getType()).getTypeID();
|
||||||
if (artifactTypeId == -1) {
|
if (artifactTypeId == -1) {
|
||||||
artifactTypeId = caseDb.addBlackboardArtifactType(artifactData.getType(), artifactData.getType()).getTypeID();
|
artifactTypeId = caseDb.addBlackboardArtifactType(artifactData.getType(), artifactData.getType()).getTypeID();
|
||||||
}
|
}
|
||||||
@ -216,13 +215,7 @@ public final class ExternalResultsImporter {
|
|||||||
ExternalResultsImporter.logger.log(Level.SEVERE, errorMessage);
|
ExternalResultsImporter.logger.log(Level.SEVERE, errorMessage);
|
||||||
this.errors.add(new ErrorInfo(ExternalResultsImporter.class.getName(), errorMessage));
|
this.errors.add(new ErrorInfo(ExternalResultsImporter.class.getName(), errorMessage));
|
||||||
}
|
}
|
||||||
} catch (TskCoreException ex) {
|
} catch (TskCoreException | TskDataException ex) {
|
||||||
String errorMessage = NbBundle.getMessage(this.getClass(),
|
|
||||||
"ExternalResultsImporter.importArtifacts.errMsg2.text",
|
|
||||||
artifactData.getType(), artifactData.getSourceFilePath());
|
|
||||||
ExternalResultsImporter.logger.log(Level.SEVERE, errorMessage, ex);
|
|
||||||
this.errors.add(new ErrorInfo(ExternalResultsImporter.class.getName(), errorMessage, ex));
|
|
||||||
} catch (TskDataException ex) {
|
|
||||||
String errorMessage = NbBundle.getMessage(this.getClass(),
|
String errorMessage = NbBundle.getMessage(this.getClass(),
|
||||||
"ExternalResultsImporter.importArtifacts.errMsg2.text",
|
"ExternalResultsImporter.importArtifacts.errMsg2.text",
|
||||||
artifactData.getType(), artifactData.getSourceFilePath());
|
artifactData.getType(), artifactData.getSourceFilePath());
|
||||||
@ -299,15 +292,6 @@ public final class ExternalResultsImporter {
|
|||||||
return relativePath;
|
return relativePath;
|
||||||
}
|
}
|
||||||
|
|
||||||
// private static boolean isStandardArtifactType(int artifactTypeId) {
|
|
||||||
// for (BlackboardArtifact.ARTIFACT_TYPE art : BlackboardArtifact.ARTIFACT_TYPE.values()) {
|
|
||||||
// if (art.getTypeID() == artifactTypeId) {
|
|
||||||
// return true;
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// return false;
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
private void recordError(String errorMessage) {
|
private void recordError(String errorMessage) {
|
||||||
ExternalResultsImporter.logger.log(Level.SEVERE, errorMessage);
|
ExternalResultsImporter.logger.log(Level.SEVERE, errorMessage);
|
||||||
this.errors.add(new ErrorInfo(this.getClass().getName(), errorMessage));
|
this.errors.add(new ErrorInfo(this.getClass().getName(), errorMessage));
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* Autopsy Forensic Browser
|
* Autopsy Forensic Browser
|
||||||
*
|
*
|
||||||
* Copyright 2014 Basis Technology Corp.
|
* Copyright 2011-2016 Basis Technology Corp.
|
||||||
* Contact: carrier <at> sleuthkit <dot> org
|
* Contact: carrier <at> sleuthkit <dot> org
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
@ -117,6 +117,7 @@ public final class ExternalResultsXMLParser implements ExternalResultsParser {
|
|||||||
/**
|
/**
|
||||||
* Constructor.
|
* Constructor.
|
||||||
*
|
*
|
||||||
|
* @param dataSource The data source for the results.
|
||||||
* @param resultsFilePath Full path of the results file to be parsed.
|
* @param resultsFilePath Full path of the results file to be parsed.
|
||||||
*/
|
*/
|
||||||
public ExternalResultsXMLParser(Content dataSource, String resultsFilePath) {
|
public ExternalResultsXMLParser(Content dataSource, String resultsFilePath) {
|
||||||
|
@ -18,7 +18,7 @@ DateSearchPanel.jLabel1.text=to
|
|||||||
DateSearchPanel.dateFromTextField.text=
|
DateSearchPanel.dateFromTextField.text=
|
||||||
DateSearchPanel.dateFromButtonCalendar.text=
|
DateSearchPanel.dateFromButtonCalendar.text=
|
||||||
NameSearchPanel.nameCheckBox.text=Name:
|
NameSearchPanel.nameCheckBox.text=Name:
|
||||||
NameSearchPanel.noteNameLabel.text=<html>*Note: Name match is case insensitive and matches<br/> any part of the file name. Regular expressions are<br/> not currently supported. </html>
|
NameSearchPanel.noteNameLabel.text=<html>*Note: Name match is case insensitive and matches any part of the file name. Regular expressions are not currently supported.</html>
|
||||||
NameSearchPanel.searchTextField.text=
|
NameSearchPanel.searchTextField.text=
|
||||||
SizeSearchPanel.sizeCheckBox.text=Size:
|
SizeSearchPanel.sizeCheckBox.text=Size:
|
||||||
NameSearchPanel.cutMenuItem.text=Cut
|
NameSearchPanel.cutMenuItem.text=Cut
|
||||||
@ -40,7 +40,6 @@ FileSearchPanel.custComp.label.text=Search for files that match the following cr
|
|||||||
FileSearchPanel.filterTitle.name=Name
|
FileSearchPanel.filterTitle.name=Name
|
||||||
FileSearchPanel.filterTitle.metadata=Metadata
|
FileSearchPanel.filterTitle.metadata=Metadata
|
||||||
FileSearchPanel.filterTitle.knownStatus=Known Status
|
FileSearchPanel.filterTitle.knownStatus=Known Status
|
||||||
FileSearchPanel.searchButton.text=Search
|
|
||||||
FileSearchPanel.search.results.title=File Search Results {0}
|
FileSearchPanel.search.results.title=File Search Results {0}
|
||||||
FileSearchPanel.search.results.pathText=Filename Search Results\:
|
FileSearchPanel.search.results.pathText=Filename Search Results\:
|
||||||
FileSearchPanel.search.results.msg=File Search\: {0} matches found
|
FileSearchPanel.search.results.msg=File Search\: {0} matches found
|
||||||
@ -54,3 +53,6 @@ SearchNode.getName.text=Search Result
|
|||||||
SizeSearchPanel.sizeCompareComboBox.equalTo=equal to
|
SizeSearchPanel.sizeCompareComboBox.equalTo=equal to
|
||||||
SizeSearchPanel.sizeCompareComboBox.greaterThan=greater than
|
SizeSearchPanel.sizeCompareComboBox.greaterThan=greater than
|
||||||
SizeSearchPanel.sizeCompareComboBox.lessThan=less than
|
SizeSearchPanel.sizeCompareComboBox.lessThan=less than
|
||||||
|
MimeTypePanel.jCheckBox1.text=MIME Type:
|
||||||
|
MimeTypePanel.jLabel1.text=*Note: Multiple MIME types can be selected
|
||||||
|
FileSearchPanel.searchButton.text=Search
|
||||||
|
@ -1,51 +1,50 @@
|
|||||||
OpenIDE-Module-Name=\u30D5\u30A1\u30A4\u30EB\u691C\u7D22
|
OpenIDE-Module-Name=\u30d5\u30a1\u30a4\u30eb\u691c\u7d22
|
||||||
KnownStatusSearchPanel.knownCheckBox.text=\u65E2\u77E5\u30B9\u30C6\u30FC\u30BF\u30B9\uFF1A
|
KnownStatusSearchPanel.knownCheckBox.text=\u65e2\u77e5\u30b9\u30c6\u30fc\u30bf\u30b9\uff1a
|
||||||
KnownStatusSearchPanel.knownBadOptionCheckBox.text=\u65E2\u77E5\u306E\u60AA\u8CEA
|
KnownStatusSearchPanel.knownBadOptionCheckBox.text=\u65e2\u77e5\u306e\u60aa\u8cea
|
||||||
KnownStatusSearchPanel.knownOptionCheckBox.text=\u65E2\u77E5\uFF08NSRL\u307E\u305F\u306F\u305D\u306E\u4ED6\uFF09
|
KnownStatusSearchPanel.knownOptionCheckBox.text=\u65e2\u77e5\uff08NSRL\u307e\u305f\u306f\u305d\u306e\u4ed6\uff09
|
||||||
KnownStatusSearchPanel.unknownOptionCheckBox.text=\u4E0D\u660E
|
KnownStatusSearchPanel.unknownOptionCheckBox.text=\u4e0d\u660e
|
||||||
DateSearchFilter.noneSelectedMsg.text=\u6700\u4F4E\u4E00\u3064\u306E\u30C7\u30FC\u30BF\u30BF\u30A4\u30D7\u3092\u9078\u629E\u3059\u308B\u5FC5\u8981\u304C\u3042\u308A\u307E\u3059\uFF01
|
DateSearchFilter.noneSelectedMsg.text=\u6700\u4f4e\u4e00\u3064\u306e\u30c7\u30fc\u30bf\u30bf\u30a4\u30d7\u3092\u9078\u629e\u3059\u308b\u5fc5\u8981\u304c\u3042\u308a\u307e\u3059\uff01
|
||||||
DateSearchPanel.dateCheckBox.text=\u65E5\u4ED8\uFF1A
|
DateSearchPanel.dateCheckBox.text=\u65e5\u4ed8\uff1a
|
||||||
DateSearchPanel.jLabel4.text=\u30BF\u30A4\u30E0\u30BE\u30FC\u30F3\uFF1A
|
DateSearchPanel.jLabel4.text=\u30bf\u30a4\u30e0\u30be\u30fc\u30f3\uff1a
|
||||||
DateSearchPanel.jLabel3.text=*\u65E5\u4ED8\u306E\u5F62\u5F0F\u306Fmm/dd/yyyy
|
DateSearchPanel.jLabel3.text=*\u65e5\u4ed8\u306e\u5f62\u5f0f\u306fmm/dd/yyyy
|
||||||
DateSearchPanel.jLabel2.text=*\u7A7A\u767D\u306E\u9805\u76EE\u306F\u300C\u5236\u9650\u306A\u3057\u300D\u3068\u3044\u3046\u610F\u5473\u3067\u3059
|
DateSearchPanel.jLabel2.text=*\u7a7a\u767d\u306e\u9805\u76ee\u306f\u300c\u5236\u9650\u306a\u3057\u300d\u3068\u3044\u3046\u610f\u5473\u3067\u3059
|
||||||
DateSearchPanel.createdCheckBox.text=\u4F5C\u6210\u6E08\u307F
|
DateSearchPanel.createdCheckBox.text=\u4f5c\u6210\u6e08\u307f
|
||||||
DateSearchPanel.accessedCheckBox.text=\u30A2\u30AF\u30BB\u30B9\u6E08\u307F
|
DateSearchPanel.accessedCheckBox.text=\u30a2\u30af\u30bb\u30b9\u6e08\u307f
|
||||||
DateSearchPanel.changedCheckBox.text=\u5909\u66F4\u6E08\u307F
|
DateSearchPanel.changedCheckBox.text=\u5909\u66f4\u6e08\u307f
|
||||||
DateSearchPanel.modifiedCheckBox.text=\u4FEE\u6B63\u6E08\u307F
|
DateSearchPanel.modifiedCheckBox.text=\u4fee\u6b63\u6e08\u307f
|
||||||
DateSearchPanel.jLabel1.text=to
|
DateSearchPanel.jLabel1.text=to
|
||||||
NameSearchPanel.nameCheckBox.text=\u540D\u524D\uFF1A
|
NameSearchPanel.nameCheckBox.text=\u540d\u524d\uff1a
|
||||||
NameSearchPanel.noteNameLabel.text=<html>*\u6CE8\u610F\uFF1A\u540D\u524D\u30DE\u30C3\u30C1\u306F\u5927\u6587\u5B57\u3068\u5C0F\u6587\u5B57\u3092\u533A\u5225\u3057\u307E\u3059\u3002\u307E\u305F\u3001<br/> \u30D5\u30A1\u30A4\u30EB\u540D\u306E\u3044\u304B\u306A\u308B\u90E8\u5206\u3082\u30DE\u30C3\u30C1\u3057\u307E\u3059\u3002\u6B63\u898F\u8868\u73FE\u306F<br/>\u73FE\u5728\u30B5\u30DD\u30FC\u30C8\u3055\u308C\u3066\u3044\u307E\u305B\u3093\u3002 </html>
|
NameSearchPanel.noteNameLabel.text=<html>*\u6ce8\u610f\uff1a\u540d\u524d\u30de\u30c3\u30c1\u306f\u5927\u6587\u5b57\u3068\u5c0f\u6587\u5b57\u3092\u533a\u5225\u3057\u307e\u3059\u3002\u307e\u305f\u3001<br/> \u30d5\u30a1\u30a4\u30eb\u540d\u306e\u3044\u304b\u306a\u308b\u90e8\u5206\u3082\u30de\u30c3\u30c1\u3057\u307e\u3059\u3002\u6b63\u898f\u8868\u73fe\u306f<br/>\u73fe\u5728\u30b5\u30dd\u30fc\u30c8\u3055\u308c\u3066\u3044\u307e\u305b\u3093\u3002 </html>
|
||||||
SizeSearchPanel.sizeCheckBox.text=\u30B5\u30A4\u30BA\uFF1A
|
SizeSearchPanel.sizeCheckBox.text=\u30b5\u30a4\u30ba\uff1a
|
||||||
NameSearchPanel.cutMenuItem.text=\u30AB\u30C3\u30C8
|
NameSearchPanel.cutMenuItem.text=\u30ab\u30c3\u30c8
|
||||||
NameSearchPanel.copyMenuItem.text=\u30B3\u30D4\u30FC
|
NameSearchPanel.copyMenuItem.text=\u30b3\u30d4\u30fc
|
||||||
NameSearchPanel.pasteMenuItem.text=\u8CBC\u308A\u4ED8\u3051
|
NameSearchPanel.pasteMenuItem.text=\u8cbc\u308a\u4ed8\u3051
|
||||||
NameSearchPanel.selectAllMenuItem.text=\u3059\u3079\u3066\u9078\u629E
|
NameSearchPanel.selectAllMenuItem.text=\u3059\u3079\u3066\u9078\u629e
|
||||||
SizeSearchPanel.selectAllMenuItem.text=\u3059\u3079\u3066\u9078\u629E
|
SizeSearchPanel.selectAllMenuItem.text=\u3059\u3079\u3066\u9078\u629e
|
||||||
SizeSearchPanel.pasteMenuItem.text=\u8CBC\u308A\u4ED8\u3051
|
SizeSearchPanel.pasteMenuItem.text=\u8cbc\u308a\u4ed8\u3051
|
||||||
SizeSearchPanel.copyMenuItem.text=\u30B3\u30D4\u30FC
|
SizeSearchPanel.copyMenuItem.text=\u30b3\u30d4\u30fc
|
||||||
SizeSearchPanel.cutMenuItem.text=\u30AB\u30C3\u30C8
|
SizeSearchPanel.cutMenuItem.text=\u30ab\u30c3\u30c8
|
||||||
DateSearchPanel.cutMenuItem.text=\u30AB\u30C3\u30C8
|
DateSearchPanel.cutMenuItem.text=\u30ab\u30c3\u30c8
|
||||||
DateSearchPanel.selectAllMenuItem.text=\u3059\u3079\u3066\u9078\u629E
|
DateSearchPanel.selectAllMenuItem.text=\u3059\u3079\u3066\u9078\u629e
|
||||||
DateSearchPanel.pasteMenuItem.text=\u8CBC\u308A\u4ED8\u3051
|
DateSearchPanel.pasteMenuItem.text=\u8cbc\u308a\u4ed8\u3051
|
||||||
DateSearchPanel.copyMenuItem.text=\u30B3\u30D4\u30FC
|
DateSearchPanel.copyMenuItem.text=\u30b3\u30d4\u30fc
|
||||||
FileSearchAction.getName.text=\u5C5E\u6027\u306B\u3088\u308B\u30D5\u30A1\u30A4\u30EB\u691C\u7D22
|
FileSearchAction.getName.text=\u5c5e\u6027\u306b\u3088\u308b\u30d5\u30a1\u30a4\u30eb\u691c\u7d22
|
||||||
FileSearchDialog.frame.title=\u5C5E\u6027\u306B\u3088\u308B\u30D5\u30A1\u30A4\u30EB\u691C\u7D22
|
FileSearchDialog.frame.title=\u5c5e\u6027\u306b\u3088\u308b\u30d5\u30a1\u30a4\u30eb\u691c\u7d22
|
||||||
FileSearchDialog.frame.msg=\u5C5E\u6027\u306B\u3088\u308B\u30D5\u30A1\u30A4\u30EB\u691C\u7D22
|
FileSearchDialog.frame.msg=\u5c5e\u6027\u306b\u3088\u308b\u30d5\u30a1\u30a4\u30eb\u691c\u7d22
|
||||||
FileSearchPanel.custComp.label.text=\u6B21\u306E\u6761\u4EF6\u306B\u4E00\u81F4\u3059\u308B\u30D5\u30A1\u30A4\u30EB\u3092\u691C\u7D22\uFF1A
|
FileSearchPanel.custComp.label.text=\u6b21\u306e\u6761\u4ef6\u306b\u4e00\u81f4\u3059\u308b\u30d5\u30a1\u30a4\u30eb\u3092\u691c\u7d22\uff1a
|
||||||
FileSearchPanel.filterTitle.name=\u540D\u524D
|
FileSearchPanel.filterTitle.name=\u540d\u524d
|
||||||
FileSearchPanel.filterTitle.metadata=\u30E1\u30BF\u30C7\u30FC\u30BF
|
FileSearchPanel.filterTitle.metadata=\u30e1\u30bf\u30c7\u30fc\u30bf
|
||||||
FileSearchPanel.filterTitle.knownStatus=\u65E2\u77E5\u30B9\u30C6\u30FC\u30BF\u30B9
|
FileSearchPanel.filterTitle.knownStatus=\u65e2\u77e5\u30b9\u30c6\u30fc\u30bf\u30b9
|
||||||
FileSearchPanel.searchButton.text=\u691C\u7D22
|
FileSearchPanel.search.results.title=\u30d5\u30a1\u30a4\u30eb\u691c\u7d22\u7d50\u679c{0}
|
||||||
FileSearchPanel.search.results.title=\u30D5\u30A1\u30A4\u30EB\u691C\u7D22\u7D50\u679C{0}
|
FileSearchPanel.search.results.pathText=\u30d5\u30a1\u30a4\u30eb\u540d\u691c\u7d22\u7d50\u679c\uff1a
|
||||||
FileSearchPanel.search.results.pathText=\u30D5\u30A1\u30A4\u30EB\u540D\u691C\u7D22\u7D50\u679C\uFF1A
|
FileSearchPanel.search.results.msg=\u30d5\u30a1\u30a4\u30eb\u691c\u7d22\uff1a{0}\u500b\u306e\u30de\u30c3\u30c1\u304c\u898b\u3064\u304b\u308a\u307e\u3057\u305f
|
||||||
FileSearchPanel.search.results.msg=\u30D5\u30A1\u30A4\u30EB\u691C\u7D22\uFF1A{0}\u500B\u306E\u30DE\u30C3\u30C1\u304C\u898B\u3064\u304B\u308A\u307E\u3057\u305F
|
FileSearchPanel.search.results.details=\u591a\u304f\u306e\u30de\u30c3\u30c1\u304c\u3042\u308b\u5834\u5408\u3001\u4e00\u90e8\u306e\u51e6\u7406\u306e\u30d1\u30d5\u30a9\u30fc\u30de\u30f3\u30b9\u306b\u5f71\u97ff\u3092\u4e0e\u3048\u308b\u304b\u3082\u3057\u308c\u307e\u305b\u3093
|
||||||
FileSearchPanel.search.results.details=\u591A\u304F\u306E\u30DE\u30C3\u30C1\u304C\u3042\u308B\u5834\u5408\u3001\u4E00\u90E8\u306E\u51E6\u7406\u306E\u30D1\u30D5\u30A9\u30FC\u30DE\u30F3\u30B9\u306B\u5F71\u97FF\u3092\u4E0E\u3048\u308B\u304B\u3082\u3057\u308C\u307E\u305B\u3093
|
FileSearchPanel.search.exception.noFilterSelected.msg=\u6700\u4f4e\uff11\u500b\u306e\u30d5\u30a3\u30eb\u30bf\u30fc\u3092\u9078\u629e\u3059\u308b\u5fc5\u8981\u304c\u3042\u308a\u307e\u3059\u3002
|
||||||
FileSearchPanel.search.exception.noFilterSelected.msg=\u6700\u4F4E\uFF11\u500B\u306E\u30D5\u30A3\u30EB\u30BF\u30FC\u3092\u9078\u629E\u3059\u308B\u5FC5\u8981\u304C\u3042\u308A\u307E\u3059\u3002
|
FileSearchPanel.search.validationErr.msg=\u30d0\u30ea\u30c7\u30fc\u30b7\u30e7\u30f3\u30a8\u30e9\u30fc\uff1a{0}
|
||||||
FileSearchPanel.search.validationErr.msg=\u30D0\u30EA\u30C7\u30FC\u30B7\u30E7\u30F3\u30A8\u30E9\u30FC\uFF1A{0}
|
FileSearchPanel.emptyWhereClause.text=\u7121\u52b9\u306a\u30aa\u30d7\u30b7\u30e7\u30f3\u3067\u3059\u3002\u8868\u793a\u3059\u308b\u3082\u306e\u304c\u3042\u308a\u307e\u305b\u3093\u3002
|
||||||
FileSearchPanel.emptyWhereClause.text=\u7121\u52B9\u306A\u30AA\u30D7\u30B7\u30E7\u30F3\u3067\u3059\u3002\u8868\u793A\u3059\u308B\u3082\u306E\u304C\u3042\u308A\u307E\u305B\u3093\u3002
|
KnownStatusSearchFilter.noneSelectedMsg.text=\u6700\u4f4e\uff11\u500b\u306e\u65e2\u77e5\u30b9\u30c6\u30fc\u30bf\u30b9\u3092\u9078\u629e\u3059\u308b\u5fc5\u8981\u304c\u3042\u308a\u307e\u3059\uff01
|
||||||
KnownStatusSearchFilter.noneSelectedMsg.text=\u6700\u4F4E\uFF11\u500B\u306E\u65E2\u77E5\u30B9\u30C6\u30FC\u30BF\u30B9\u3092\u9078\u629E\u3059\u308B\u5FC5\u8981\u304C\u3042\u308A\u307E\u3059\uFF01
|
NameSearchFilter.emptyNameMsg.text=\u540d\u524d\u691c\u7d22\u306b\u4f55\u304b\u8a18\u5165\u3057\u306a\u3051\u308c\u3070\u3044\u3051\u307e\u305b\u3093\u3002
|
||||||
NameSearchFilter.emptyNameMsg.text=\u540D\u524D\u691C\u7D22\u306B\u4F55\u304B\u8A18\u5165\u3057\u306A\u3051\u308C\u3070\u3044\u3051\u307E\u305B\u3093\u3002
|
SearchNode.getName.text=\u691c\u7d22\u7d50\u679c
|
||||||
SearchNode.getName.text=\u691C\u7D22\u7D50\u679C
|
SizeSearchPanel.sizeCompareComboBox.equalTo=\u4e0b\u8a18\u3068\u7b49\u3057\u3044
|
||||||
SizeSearchPanel.sizeCompareComboBox.equalTo=\u4E0B\u8A18\u3068\u7B49\u3057\u3044
|
SizeSearchPanel.sizeCompareComboBox.greaterThan=\u4e0b\u8a18\u3088\u308a\u5927\u304d\u3044
|
||||||
SizeSearchPanel.sizeCompareComboBox.greaterThan=\u4E0B\u8A18\u3088\u308A\u5927\u304D\u3044
|
SizeSearchPanel.sizeCompareComboBox.lessThan=\u4e0b\u8a18\u3088\u308a\u5c0f\u3055\u3044
|
||||||
SizeSearchPanel.sizeCompareComboBox.lessThan=\u4E0B\u8A18\u3088\u308A\u5C0F\u3055\u3044
|
|
||||||
|
@ -54,6 +54,8 @@
|
|||||||
<Layout>
|
<Layout>
|
||||||
<DimensionLayout dim="0">
|
<DimensionLayout dim="0">
|
||||||
<Group type="103" groupAlignment="0" attributes="0">
|
<Group type="103" groupAlignment="0" attributes="0">
|
||||||
|
<Group type="102" attributes="0">
|
||||||
|
<Group type="103" groupAlignment="0" max="-2" attributes="0">
|
||||||
<Group type="102" attributes="0">
|
<Group type="102" attributes="0">
|
||||||
<Component id="dateCheckBox" min="-2" max="-2" attributes="0"/>
|
<Component id="dateCheckBox" min="-2" max="-2" attributes="0"/>
|
||||||
<EmptySpace max="-2" attributes="0"/>
|
<EmptySpace max="-2" attributes="0"/>
|
||||||
@ -67,74 +69,79 @@
|
|||||||
<EmptySpace min="-2" pref="0" max="-2" attributes="0"/>
|
<EmptySpace min="-2" pref="0" max="-2" attributes="0"/>
|
||||||
<Component id="dateToButtonCalendar" min="-2" max="-2" attributes="0"/>
|
<Component id="dateToButtonCalendar" min="-2" max="-2" attributes="0"/>
|
||||||
</Group>
|
</Group>
|
||||||
<Group type="102" alignment="0" attributes="0">
|
<Group type="102" alignment="1" attributes="0">
|
||||||
<EmptySpace min="21" pref="21" max="21" attributes="0"/>
|
<EmptySpace max="-2" attributes="0"/>
|
||||||
<Group type="103" groupAlignment="0" attributes="0">
|
<Component id="jLabel2" min="-2" max="-2" attributes="0"/>
|
||||||
<Group type="102" alignment="0" attributes="0">
|
<EmptySpace max="32767" attributes="0"/>
|
||||||
<Group type="103" groupAlignment="0" attributes="0">
|
<Component id="jLabel3" min="-2" max="-2" attributes="0"/>
|
||||||
<Component id="changedCheckBox" alignment="0" min="-2" max="-2" attributes="0"/>
|
|
||||||
<Component id="modifiedCheckBox" alignment="0" min="-2" max="-2" attributes="0"/>
|
|
||||||
</Group>
|
|
||||||
<EmptySpace type="unrelated" max="-2" attributes="0"/>
|
|
||||||
<Group type="103" groupAlignment="0" attributes="0">
|
|
||||||
<Component id="accessedCheckBox" min="-2" max="-2" attributes="0"/>
|
|
||||||
<Component id="createdCheckBox" alignment="0" min="-2" max="-2" attributes="0"/>
|
|
||||||
</Group>
|
</Group>
|
||||||
</Group>
|
</Group>
|
||||||
|
<EmptySpace pref="26" max="32767" attributes="0"/>
|
||||||
|
</Group>
|
||||||
|
<Group type="102" alignment="1" attributes="0">
|
||||||
|
<EmptySpace min="0" pref="0" max="32767" attributes="0"/>
|
||||||
|
<Group type="103" groupAlignment="0" attributes="0">
|
||||||
<Group type="102" alignment="0" attributes="0">
|
<Group type="102" alignment="0" attributes="0">
|
||||||
<Component id="jLabel4" min="-2" max="-2" attributes="0"/>
|
<Component id="jLabel4" min="-2" max="-2" attributes="0"/>
|
||||||
<EmptySpace max="-2" attributes="0"/>
|
<EmptySpace max="-2" attributes="0"/>
|
||||||
<Component id="timeZoneComboBox" min="-2" pref="193" max="-2" attributes="0"/>
|
<Component id="timeZoneComboBox" min="-2" pref="193" max="-2" attributes="0"/>
|
||||||
</Group>
|
</Group>
|
||||||
<Group type="102" alignment="0" attributes="0">
|
<Group type="102" alignment="0" attributes="0">
|
||||||
<EmptySpace min="21" pref="21" max="21" attributes="0"/>
|
<Component id="modifiedCheckBox" min="-2" max="-2" attributes="0"/>
|
||||||
<Group type="103" groupAlignment="0" attributes="0">
|
<EmptySpace min="-2" pref="6" max="-2" attributes="0"/>
|
||||||
<Component id="jLabel3" alignment="0" min="-2" max="-2" attributes="0"/>
|
<Component id="accessedCheckBox" min="-2" max="-2" attributes="0"/>
|
||||||
<Component id="jLabel2" alignment="0" min="-2" max="-2" attributes="0"/>
|
<EmptySpace max="-2" attributes="0"/>
|
||||||
</Group>
|
<Component id="createdCheckBox" min="-2" max="-2" attributes="0"/>
|
||||||
|
<EmptySpace max="-2" attributes="0"/>
|
||||||
|
<Component id="changedCheckBox" min="-2" max="-2" attributes="0"/>
|
||||||
</Group>
|
</Group>
|
||||||
</Group>
|
</Group>
|
||||||
|
<EmptySpace min="-2" pref="33" max="-2" attributes="0"/>
|
||||||
</Group>
|
</Group>
|
||||||
</Group>
|
</Group>
|
||||||
</DimensionLayout>
|
</DimensionLayout>
|
||||||
<DimensionLayout dim="1">
|
<DimensionLayout dim="1">
|
||||||
<Group type="103" groupAlignment="0" attributes="0">
|
<Group type="103" groupAlignment="0" attributes="0">
|
||||||
<Group type="102" alignment="0" attributes="0">
|
<Group type="102" alignment="0" attributes="0">
|
||||||
<Group type="103" groupAlignment="0" attributes="0">
|
<Group type="103" groupAlignment="0" max="-2" attributes="0">
|
||||||
|
<Group type="102" alignment="0" attributes="0">
|
||||||
<Group type="103" groupAlignment="3" attributes="0">
|
<Group type="103" groupAlignment="3" attributes="0">
|
||||||
<Component id="dateCheckBox" alignment="3" min="-2" max="-2" attributes="0"/>
|
<Component id="dateCheckBox" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||||
<Component id="dateFromTextField" alignment="3" min="-2" max="-2" attributes="0"/>
|
<Component id="dateFromTextField" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||||
</Group>
|
</Group>
|
||||||
|
<EmptySpace min="-2" pref="18" max="-2" attributes="0"/>
|
||||||
|
</Group>
|
||||||
|
<Group type="102" alignment="0" attributes="0">
|
||||||
|
<Group type="103" groupAlignment="0" attributes="0">
|
||||||
<Component id="dateToButtonCalendar" alignment="0" min="-2" max="-2" attributes="0"/>
|
<Component id="dateToButtonCalendar" alignment="0" min="-2" max="-2" attributes="0"/>
|
||||||
<Group type="103" alignment="0" groupAlignment="3" attributes="0">
|
<Group type="103" alignment="0" groupAlignment="3" attributes="0">
|
||||||
<Component id="jLabel1" alignment="3" min="-2" max="-2" attributes="0"/>
|
<Component id="jLabel1" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||||
<Component id="dateToTextField" alignment="3" min="-2" max="-2" attributes="0"/>
|
<Component id="dateToTextField" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||||
</Group>
|
</Group>
|
||||||
<Component id="dateFromButtonCalendar" min="-2" max="-2" attributes="0"/>
|
<Component id="dateFromButtonCalendar" alignment="0" min="-2" max="-2" attributes="0"/>
|
||||||
|
</Group>
|
||||||
|
<EmptySpace max="32767" attributes="0"/>
|
||||||
|
<Group type="103" groupAlignment="3" attributes="0">
|
||||||
|
<Component id="jLabel3" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||||
|
<Component id="jLabel2" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||||
|
</Group>
|
||||||
|
<EmptySpace max="-2" attributes="0"/>
|
||||||
|
</Group>
|
||||||
</Group>
|
</Group>
|
||||||
<EmptySpace min="-2" pref="4" max="-2" attributes="0"/>
|
|
||||||
<Group type="103" groupAlignment="3" attributes="0">
|
<Group type="103" groupAlignment="3" attributes="0">
|
||||||
<Component id="jLabel4" alignment="3" min="-2" max="-2" attributes="0"/>
|
<Component id="jLabel4" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||||
<Component id="timeZoneComboBox" alignment="3" min="-2" max="-2" attributes="0"/>
|
<Component id="timeZoneComboBox" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||||
</Group>
|
</Group>
|
||||||
<EmptySpace type="unrelated" max="-2" attributes="0"/>
|
<EmptySpace type="unrelated" max="-2" attributes="0"/>
|
||||||
<Group type="103" groupAlignment="1" attributes="0">
|
<Group type="103" groupAlignment="0" attributes="0">
|
||||||
<Group type="102" alignment="1" attributes="0">
|
<Component id="modifiedCheckBox" alignment="1" min="-2" max="-2" attributes="0"/>
|
||||||
<Component id="modifiedCheckBox" min="-2" max="-2" attributes="0"/>
|
<Group type="103" alignment="1" groupAlignment="3" attributes="0">
|
||||||
<EmptySpace max="-2" attributes="0"/>
|
<Component id="accessedCheckBox" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||||
<Component id="changedCheckBox" min="-2" max="-2" attributes="0"/>
|
<Component id="createdCheckBox" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||||
|
<Component id="changedCheckBox" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||||
</Group>
|
</Group>
|
||||||
<Group type="102" alignment="1" attributes="0">
|
|
||||||
<Component id="accessedCheckBox" min="-2" max="-2" attributes="0"/>
|
|
||||||
<EmptySpace min="23" pref="23" max="23" attributes="0"/>
|
|
||||||
</Group>
|
</Group>
|
||||||
<Component id="createdCheckBox" alignment="1" min="-2" max="-2" attributes="0"/>
|
<EmptySpace min="0" pref="0" max="-2" attributes="0"/>
|
||||||
</Group>
|
|
||||||
<EmptySpace type="unrelated" max="-2" attributes="0"/>
|
|
||||||
<Component id="jLabel2" min="-2" max="-2" attributes="0"/>
|
|
||||||
<EmptySpace max="-2" attributes="0"/>
|
|
||||||
<Component id="jLabel3" min="-2" max="-2" attributes="0"/>
|
|
||||||
<EmptySpace max="32767" attributes="0"/>
|
|
||||||
</Group>
|
</Group>
|
||||||
</Group>
|
</Group>
|
||||||
</DimensionLayout>
|
</DimensionLayout>
|
||||||
@ -188,6 +195,9 @@
|
|||||||
</Component>
|
</Component>
|
||||||
<Component class="javax.swing.JLabel" name="jLabel3">
|
<Component class="javax.swing.JLabel" name="jLabel3">
|
||||||
<Properties>
|
<Properties>
|
||||||
|
<Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor">
|
||||||
|
<Font name="Tahoma" size="10" style="0"/>
|
||||||
|
</Property>
|
||||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||||
<ResourceString bundle="org/sleuthkit/autopsy/filesearch/Bundle.properties" key="DateSearchPanel.jLabel3.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
<ResourceString bundle="org/sleuthkit/autopsy/filesearch/Bundle.properties" key="DateSearchPanel.jLabel3.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||||
</Property>
|
</Property>
|
||||||
@ -208,6 +218,9 @@
|
|||||||
</Component>
|
</Component>
|
||||||
<Component class="javax.swing.JLabel" name="jLabel2">
|
<Component class="javax.swing.JLabel" name="jLabel2">
|
||||||
<Properties>
|
<Properties>
|
||||||
|
<Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor">
|
||||||
|
<Font name="Tahoma" size="10" style="0"/>
|
||||||
|
</Property>
|
||||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||||
<ResourceString bundle="org/sleuthkit/autopsy/filesearch/Bundle.properties" key="DateSearchPanel.jLabel2.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
<ResourceString bundle="org/sleuthkit/autopsy/filesearch/Bundle.properties" key="DateSearchPanel.jLabel2.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||||
</Property>
|
</Property>
|
||||||
|
@ -74,7 +74,6 @@ class DateSearchPanel extends javax.swing.JPanel {
|
|||||||
copyMenuItem.addActionListener(actList);
|
copyMenuItem.addActionListener(actList);
|
||||||
pasteMenuItem.addActionListener(actList);
|
pasteMenuItem.addActionListener(actList);
|
||||||
selectAllMenuItem.addActionListener(actList);
|
selectAllMenuItem.addActionListener(actList);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
JCheckBox getAccessedCheckBox() {
|
JCheckBox getAccessedCheckBox() {
|
||||||
@ -172,6 +171,7 @@ class DateSearchPanel extends javax.swing.JPanel {
|
|||||||
|
|
||||||
dateCheckBox.setText(org.openide.util.NbBundle.getMessage(DateSearchPanel.class, "DateSearchPanel.dateCheckBox.text")); // NOI18N
|
dateCheckBox.setText(org.openide.util.NbBundle.getMessage(DateSearchPanel.class, "DateSearchPanel.dateCheckBox.text")); // NOI18N
|
||||||
|
|
||||||
|
jLabel3.setFont(new java.awt.Font("Tahoma", 0, 10)); // NOI18N
|
||||||
jLabel3.setText(org.openide.util.NbBundle.getMessage(DateSearchPanel.class, "DateSearchPanel.jLabel3.text")); // NOI18N
|
jLabel3.setText(org.openide.util.NbBundle.getMessage(DateSearchPanel.class, "DateSearchPanel.jLabel3.text")); // NOI18N
|
||||||
|
|
||||||
dateFromTextField.setText(org.openide.util.NbBundle.getMessage(DateSearchPanel.class, "DateSearchPanel.dateFromTextField.text")); // NOI18N
|
dateFromTextField.setText(org.openide.util.NbBundle.getMessage(DateSearchPanel.class, "DateSearchPanel.dateFromTextField.text")); // NOI18N
|
||||||
@ -181,6 +181,7 @@ class DateSearchPanel extends javax.swing.JPanel {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
jLabel2.setFont(new java.awt.Font("Tahoma", 0, 10)); // NOI18N
|
||||||
jLabel2.setText(org.openide.util.NbBundle.getMessage(DateSearchPanel.class, "DateSearchPanel.jLabel2.text")); // NOI18N
|
jLabel2.setText(org.openide.util.NbBundle.getMessage(DateSearchPanel.class, "DateSearchPanel.jLabel2.text")); // NOI18N
|
||||||
|
|
||||||
modifiedCheckBox.setSelected(true);
|
modifiedCheckBox.setSelected(true);
|
||||||
@ -213,6 +214,8 @@ class DateSearchPanel extends javax.swing.JPanel {
|
|||||||
this.setLayout(layout);
|
this.setLayout(layout);
|
||||||
layout.setHorizontalGroup(
|
layout.setHorizontalGroup(
|
||||||
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||||
|
.addGroup(layout.createSequentialGroup()
|
||||||
|
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
|
||||||
.addGroup(layout.createSequentialGroup()
|
.addGroup(layout.createSequentialGroup()
|
||||||
.addComponent(dateCheckBox)
|
.addComponent(dateCheckBox)
|
||||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||||
@ -225,58 +228,61 @@ class DateSearchPanel extends javax.swing.JPanel {
|
|||||||
.addComponent(dateToTextField, javax.swing.GroupLayout.PREFERRED_SIZE, 92, javax.swing.GroupLayout.PREFERRED_SIZE)
|
.addComponent(dateToTextField, javax.swing.GroupLayout.PREFERRED_SIZE, 92, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||||
.addGap(0, 0, 0)
|
.addGap(0, 0, 0)
|
||||||
.addComponent(dateToButtonCalendar, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
|
.addComponent(dateToButtonCalendar, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
|
||||||
.addGroup(layout.createSequentialGroup()
|
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
|
||||||
.addGap(21, 21, 21)
|
.addContainerGap()
|
||||||
|
.addComponent(jLabel2)
|
||||||
|
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
||||||
|
.addComponent(jLabel3)))
|
||||||
|
.addContainerGap(26, Short.MAX_VALUE))
|
||||||
|
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
|
||||||
|
.addGap(0, 0, Short.MAX_VALUE)
|
||||||
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||||
.addGroup(layout.createSequentialGroup()
|
|
||||||
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
|
||||||
.addComponent(changedCheckBox)
|
|
||||||
.addComponent(modifiedCheckBox))
|
|
||||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
|
|
||||||
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
|
||||||
.addComponent(accessedCheckBox)
|
|
||||||
.addComponent(createdCheckBox)))
|
|
||||||
.addGroup(layout.createSequentialGroup()
|
.addGroup(layout.createSequentialGroup()
|
||||||
.addComponent(jLabel4)
|
.addComponent(jLabel4)
|
||||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||||
.addComponent(timeZoneComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, 193, javax.swing.GroupLayout.PREFERRED_SIZE))
|
.addComponent(timeZoneComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, 193, javax.swing.GroupLayout.PREFERRED_SIZE))
|
||||||
.addGroup(layout.createSequentialGroup()
|
.addGroup(layout.createSequentialGroup()
|
||||||
.addGap(21, 21, 21)
|
.addComponent(modifiedCheckBox)
|
||||||
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
.addGap(6, 6, 6)
|
||||||
.addComponent(jLabel3)
|
.addComponent(accessedCheckBox)
|
||||||
.addComponent(jLabel2)))))
|
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||||
|
.addComponent(createdCheckBox)
|
||||||
|
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||||
|
.addComponent(changedCheckBox)))
|
||||||
|
.addGap(33, 33, 33))
|
||||||
);
|
);
|
||||||
layout.setVerticalGroup(
|
layout.setVerticalGroup(
|
||||||
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||||
.addGroup(layout.createSequentialGroup()
|
.addGroup(layout.createSequentialGroup()
|
||||||
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
|
||||||
|
.addGroup(layout.createSequentialGroup()
|
||||||
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
|
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
|
||||||
.addComponent(dateCheckBox)
|
.addComponent(dateCheckBox)
|
||||||
.addComponent(dateFromTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
|
.addComponent(dateFromTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
|
||||||
|
.addGap(18, 18, 18))
|
||||||
|
.addGroup(layout.createSequentialGroup()
|
||||||
|
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||||
.addComponent(dateToButtonCalendar, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
|
.addComponent(dateToButtonCalendar, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||||
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
|
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
|
||||||
.addComponent(jLabel1)
|
.addComponent(jLabel1)
|
||||||
.addComponent(dateToTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
|
.addComponent(dateToTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
|
||||||
.addComponent(dateFromButtonCalendar, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
|
.addComponent(dateFromButtonCalendar, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
|
||||||
.addGap(4, 4, 4)
|
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
||||||
|
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
|
||||||
|
.addComponent(jLabel3)
|
||||||
|
.addComponent(jLabel2))
|
||||||
|
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)))
|
||||||
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
|
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
|
||||||
.addComponent(jLabel4)
|
.addComponent(jLabel4)
|
||||||
.addComponent(timeZoneComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
|
.addComponent(timeZoneComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
|
||||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
|
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
|
||||||
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
|
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||||
.addGroup(layout.createSequentialGroup()
|
.addComponent(modifiedCheckBox, javax.swing.GroupLayout.Alignment.TRAILING)
|
||||||
.addComponent(modifiedCheckBox)
|
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
|
||||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
|
||||||
.addComponent(changedCheckBox))
|
|
||||||
.addGroup(layout.createSequentialGroup()
|
|
||||||
.addComponent(accessedCheckBox)
|
.addComponent(accessedCheckBox)
|
||||||
.addGap(23, 23, 23))
|
.addComponent(createdCheckBox)
|
||||||
.addComponent(createdCheckBox))
|
.addComponent(changedCheckBox)))
|
||||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
|
.addGap(0, 0, 0))
|
||||||
.addComponent(jLabel2)
|
|
||||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
|
||||||
.addComponent(jLabel3)
|
|
||||||
.addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
|
|
||||||
);
|
);
|
||||||
}// </editor-fold>//GEN-END:initComponents
|
}// </editor-fold>//GEN-END:initComponents
|
||||||
|
|
||||||
|
@ -1,6 +1,11 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8" ?>
|
<?xml version="1.0" encoding="UTF-8" ?>
|
||||||
|
|
||||||
<Form version="1.4" maxVersion="1.7" type="org.netbeans.modules.form.forminfo.JPanelFormInfo">
|
<Form version="1.4" maxVersion="1.7" type="org.netbeans.modules.form.forminfo.JPanelFormInfo">
|
||||||
|
<Properties>
|
||||||
|
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||||
|
<Dimension value="[300, 300]"/>
|
||||||
|
</Property>
|
||||||
|
</Properties>
|
||||||
<AuxValues>
|
<AuxValues>
|
||||||
<AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="1"/>
|
<AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="1"/>
|
||||||
<AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/>
|
<AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/>
|
||||||
@ -16,13 +21,48 @@
|
|||||||
<Layout>
|
<Layout>
|
||||||
<DimensionLayout dim="0">
|
<DimensionLayout dim="0">
|
||||||
<Group type="103" groupAlignment="0" attributes="0">
|
<Group type="103" groupAlignment="0" attributes="0">
|
||||||
<EmptySpace min="0" pref="300" max="32767" attributes="0"/>
|
<Component id="filterPanel" alignment="0" max="32767" attributes="0"/>
|
||||||
|
<Group type="102" alignment="1" attributes="0">
|
||||||
|
<EmptySpace max="32767" attributes="0"/>
|
||||||
|
<Component id="searchButton" min="-2" max="-2" attributes="0"/>
|
||||||
|
<EmptySpace max="-2" attributes="0"/>
|
||||||
|
</Group>
|
||||||
</Group>
|
</Group>
|
||||||
</DimensionLayout>
|
</DimensionLayout>
|
||||||
<DimensionLayout dim="1">
|
<DimensionLayout dim="1">
|
||||||
<Group type="103" groupAlignment="0" attributes="0">
|
<Group type="103" groupAlignment="0" attributes="0">
|
||||||
<EmptySpace min="0" pref="376" max="32767" attributes="0"/>
|
<Group type="102" alignment="0" attributes="0">
|
||||||
|
<Component id="filterPanel" max="32767" attributes="0"/>
|
||||||
|
<EmptySpace min="0" pref="0" max="-2" attributes="0"/>
|
||||||
|
<Component id="searchButton" min="-2" max="-2" attributes="0"/>
|
||||||
|
<EmptySpace max="-2" attributes="0"/>
|
||||||
|
</Group>
|
||||||
</Group>
|
</Group>
|
||||||
</DimensionLayout>
|
</DimensionLayout>
|
||||||
</Layout>
|
</Layout>
|
||||||
|
<SubComponents>
|
||||||
|
<Container class="javax.swing.JPanel" name="filterPanel">
|
||||||
|
<Properties>
|
||||||
|
<Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor">
|
||||||
|
<Border info="org.netbeans.modules.form.compat2.border.EmptyBorderInfo">
|
||||||
|
<EmptyBorder bottom="10" left="10" right="10" top="10"/>
|
||||||
|
</Border>
|
||||||
|
</Property>
|
||||||
|
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||||
|
<Dimension value="[300, 400]"/>
|
||||||
|
</Property>
|
||||||
|
</Properties>
|
||||||
|
|
||||||
|
<Layout class="org.netbeans.modules.form.compat2.layouts.DesignBoxLayout">
|
||||||
|
<Property name="axis" type="int" value="1"/>
|
||||||
|
</Layout>
|
||||||
|
</Container>
|
||||||
|
<Component class="javax.swing.JButton" name="searchButton">
|
||||||
|
<Properties>
|
||||||
|
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||||
|
<ResourceString bundle="org/sleuthkit/autopsy/filesearch/Bundle.properties" key="FileSearchPanel.searchButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||||
|
</Property>
|
||||||
|
</Properties>
|
||||||
|
</Component>
|
||||||
|
</SubComponents>
|
||||||
</Form>
|
</Form>
|
||||||
|
@ -60,8 +60,7 @@ import org.sleuthkit.datamodel.TskCoreException;
|
|||||||
*/
|
*/
|
||||||
class FileSearchPanel extends javax.swing.JPanel {
|
class FileSearchPanel extends javax.swing.JPanel {
|
||||||
|
|
||||||
private List<FilterArea> filterAreas = new ArrayList<FilterArea>();
|
private final List<FilterArea> filterAreas = new ArrayList<>();
|
||||||
private JButton searchButton;
|
|
||||||
private static int resultWindowCount = 0; //keep track of result windows so they get unique names
|
private static int resultWindowCount = 0; //keep track of result windows so they get unique names
|
||||||
private static final String EMPTY_WHERE_CLAUSE = NbBundle.getMessage(DateSearchFilter.class, "FileSearchPanel.emptyWhereClause.text");
|
private static final String EMPTY_WHERE_CLAUSE = NbBundle.getMessage(DateSearchFilter.class, "FileSearchPanel.emptyWhereClause.text");
|
||||||
|
|
||||||
@ -79,14 +78,6 @@ class FileSearchPanel extends javax.swing.JPanel {
|
|||||||
*/
|
*/
|
||||||
private void customizeComponents() {
|
private void customizeComponents() {
|
||||||
|
|
||||||
this.setLayout(new BorderLayout());
|
|
||||||
|
|
||||||
JPanel filterPanel = new JPanel();
|
|
||||||
filterPanel.setLayout(new BoxLayout(filterPanel, BoxLayout.Y_AXIS));
|
|
||||||
filterPanel.setBorder(new EmptyBorder(10, 10, 10, 10));
|
|
||||||
|
|
||||||
this.add(filterPanel, BorderLayout.CENTER);
|
|
||||||
|
|
||||||
JLabel label = new JLabel(NbBundle.getMessage(this.getClass(), "FileSearchPanel.custComp.label.text"));
|
JLabel label = new JLabel(NbBundle.getMessage(this.getClass(), "FileSearchPanel.custComp.label.text"));
|
||||||
label.setAlignmentX(Component.LEFT_ALIGNMENT);
|
label.setAlignmentX(Component.LEFT_ALIGNMENT);
|
||||||
label.setBorder(new EmptyBorder(0, 0, 10, 0));
|
label.setBorder(new EmptyBorder(0, 0, 10, 0));
|
||||||
@ -95,8 +86,9 @@ class FileSearchPanel extends javax.swing.JPanel {
|
|||||||
// Create and add filter areas
|
// Create and add filter areas
|
||||||
this.filterAreas.add(new FilterArea(NbBundle.getMessage(this.getClass(), "FileSearchPanel.filterTitle.name"), new NameSearchFilter()));
|
this.filterAreas.add(new FilterArea(NbBundle.getMessage(this.getClass(), "FileSearchPanel.filterTitle.name"), new NameSearchFilter()));
|
||||||
|
|
||||||
List<FileSearchFilter> metadataFilters = new ArrayList<FileSearchFilter>();
|
List<FileSearchFilter> metadataFilters = new ArrayList<>();
|
||||||
metadataFilters.add(new SizeSearchFilter());
|
metadataFilters.add(new SizeSearchFilter());
|
||||||
|
metadataFilters.add(new MimeTypeFilter());
|
||||||
metadataFilters.add(new DateSearchFilter());
|
metadataFilters.add(new DateSearchFilter());
|
||||||
this.filterAreas.add(new FilterArea(NbBundle.getMessage(this.getClass(), "FileSearchPanel.filterTitle.metadata"), metadataFilters));
|
this.filterAreas.add(new FilterArea(NbBundle.getMessage(this.getClass(), "FileSearchPanel.filterTitle.metadata"), metadataFilters));
|
||||||
|
|
||||||
@ -108,11 +100,6 @@ class FileSearchPanel extends javax.swing.JPanel {
|
|||||||
filterPanel.add(fa);
|
filterPanel.add(fa);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create and add search button
|
|
||||||
this.searchButton = new JButton(NbBundle.getMessage(this.getClass(), "FileSearchPanel.searchButton.text"));
|
|
||||||
this.searchButton.setAlignmentX(Component.LEFT_ALIGNMENT);
|
|
||||||
filterPanel.add(searchButton);
|
|
||||||
|
|
||||||
addListenerToAll(new ActionListener() {
|
addListenerToAll(new ActionListener() {
|
||||||
@Override
|
@Override
|
||||||
public void actionPerformed(ActionEvent e) {
|
public void actionPerformed(ActionEvent e) {
|
||||||
@ -234,7 +221,7 @@ class FileSearchPanel extends javax.swing.JPanel {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private Collection<FileSearchFilter> getFilters() {
|
private Collection<FileSearchFilter> getFilters() {
|
||||||
Collection<FileSearchFilter> filters = new ArrayList<FileSearchFilter>();
|
Collection<FileSearchFilter> filters = new ArrayList<>();
|
||||||
|
|
||||||
for (FilterArea fa : this.filterAreas) {
|
for (FilterArea fa : this.filterAreas) {
|
||||||
filters.addAll(fa.getFilters());
|
filters.addAll(fa.getFilters());
|
||||||
@ -244,7 +231,7 @@ class FileSearchPanel extends javax.swing.JPanel {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private Collection<FileSearchFilter> getEnabledFilters() {
|
private Collection<FileSearchFilter> getEnabledFilters() {
|
||||||
Collection<FileSearchFilter> enabledFilters = new ArrayList<FileSearchFilter>();
|
Collection<FileSearchFilter> enabledFilters = new ArrayList<>();
|
||||||
|
|
||||||
for (FileSearchFilter f : this.getFilters()) {
|
for (FileSearchFilter f : this.getFilters()) {
|
||||||
if (f.isEnabled()) {
|
if (f.isEnabled()) {
|
||||||
@ -273,17 +260,38 @@ class FileSearchPanel extends javax.swing.JPanel {
|
|||||||
// <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
|
// <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
|
||||||
private void initComponents() {
|
private void initComponents() {
|
||||||
|
|
||||||
|
filterPanel = new javax.swing.JPanel();
|
||||||
|
searchButton = new javax.swing.JButton();
|
||||||
|
|
||||||
|
setPreferredSize(new java.awt.Dimension(300, 300));
|
||||||
|
|
||||||
|
filterPanel.setBorder(javax.swing.BorderFactory.createEmptyBorder(10, 10, 10, 10));
|
||||||
|
filterPanel.setPreferredSize(new java.awt.Dimension(300, 400));
|
||||||
|
filterPanel.setLayout(new javax.swing.BoxLayout(filterPanel, javax.swing.BoxLayout.Y_AXIS));
|
||||||
|
|
||||||
|
searchButton.setText(org.openide.util.NbBundle.getMessage(FileSearchPanel.class, "FileSearchPanel.searchButton.text")); // NOI18N
|
||||||
|
|
||||||
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
|
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
|
||||||
this.setLayout(layout);
|
this.setLayout(layout);
|
||||||
layout.setHorizontalGroup(
|
layout.setHorizontalGroup(
|
||||||
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||||
.addGap(0, 300, Short.MAX_VALUE)
|
.addComponent(filterPanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
||||||
|
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
|
||||||
|
.addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
||||||
|
.addComponent(searchButton)
|
||||||
|
.addContainerGap())
|
||||||
);
|
);
|
||||||
layout.setVerticalGroup(
|
layout.setVerticalGroup(
|
||||||
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||||
.addGap(0, 376, Short.MAX_VALUE)
|
.addGroup(layout.createSequentialGroup()
|
||||||
|
.addComponent(filterPanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
||||||
|
.addGap(0, 0, 0)
|
||||||
|
.addComponent(searchButton)
|
||||||
|
.addContainerGap())
|
||||||
);
|
);
|
||||||
}// </editor-fold>//GEN-END:initComponents
|
}// </editor-fold>//GEN-END:initComponents
|
||||||
// Variables declaration - do not modify//GEN-BEGIN:variables
|
// Variables declaration - do not modify//GEN-BEGIN:variables
|
||||||
|
private javax.swing.JPanel filterPanel;
|
||||||
|
private javax.swing.JButton searchButton;
|
||||||
// End of variables declaration//GEN-END:variables
|
// End of variables declaration//GEN-END:variables
|
||||||
}
|
}
|
||||||
|
@ -92,20 +92,22 @@ class FilterArea extends JPanel {
|
|||||||
filtersPanel = new JPanel();
|
filtersPanel = new JPanel();
|
||||||
filtersPanel.setAlignmentX(Component.LEFT_ALIGNMENT);
|
filtersPanel.setAlignmentX(Component.LEFT_ALIGNMENT);
|
||||||
|
|
||||||
BoxLayout filtersPanelLayout = new BoxLayout(filtersPanel, BoxLayout.Y_AXIS);
|
BoxLayout filtersPanelLayout = new BoxLayout(this, BoxLayout.Y_AXIS);
|
||||||
filtersPanel.setLayout(filtersPanelLayout);
|
this.setLayout(filtersPanelLayout);
|
||||||
|
|
||||||
for (FileSearchFilter f : filters) {
|
for (int i = 0; i < filters.size(); i++) {
|
||||||
|
FileSearchFilter f = filters.get(i);
|
||||||
JComponent filterComponent = f.getComponent();
|
JComponent filterComponent = f.getComponent();
|
||||||
filterComponent.setAlignmentX(Component.LEFT_ALIGNMENT);
|
filterComponent.setAlignmentX(Component.LEFT_ALIGNMENT);
|
||||||
filterComponent.setBorder(new EmptyBorder(0, 0, 20, 0));
|
if (i != filters.size() - 1) {
|
||||||
filtersPanel.add(filterComponent);
|
filterComponent.setBorder(new EmptyBorder(0, 0, 15, 0));
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
this.add(filtersPanel);
|
filterComponent.setBorder(new EmptyBorder(0, 0, 18, 0));
|
||||||
|
}
|
||||||
BoxLayout layout = new BoxLayout(this, BoxLayout.Y_AXIS);
|
this.add(filterComponent);
|
||||||
this.setLayout(layout);
|
}
|
||||||
|
this.setAlignmentX(Component.LEFT_ALIGNMENT);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void refresh() {
|
private void refresh() {
|
||||||
|
@ -15,16 +15,21 @@
|
|||||||
|
|
||||||
<Layout>
|
<Layout>
|
||||||
<DimensionLayout dim="0">
|
<DimensionLayout dim="0">
|
||||||
|
<Group type="103" groupAlignment="0" attributes="0">
|
||||||
|
<Group type="102" attributes="0">
|
||||||
<Group type="103" groupAlignment="0" attributes="0">
|
<Group type="103" groupAlignment="0" attributes="0">
|
||||||
<Component id="knownCheckBox" alignment="0" min="-2" max="-2" attributes="0"/>
|
<Component id="knownCheckBox" alignment="0" min="-2" max="-2" attributes="0"/>
|
||||||
<Group type="102" alignment="0" attributes="0">
|
<Group type="102" alignment="0" attributes="0">
|
||||||
<EmptySpace min="21" pref="21" max="21" attributes="0"/>
|
<EmptySpace min="21" pref="21" max="21" attributes="0"/>
|
||||||
<Group type="103" groupAlignment="0" attributes="0">
|
<Component id="unknownOptionCheckBox" min="-2" max="-2" attributes="0"/>
|
||||||
<Component id="knownBadOptionCheckBox" alignment="0" min="-2" max="-2" attributes="0"/>
|
<EmptySpace max="-2" attributes="0"/>
|
||||||
<Component id="unknownOptionCheckBox" alignment="0" min="-2" max="-2" attributes="0"/>
|
<Component id="knownOptionCheckBox" min="-2" max="-2" attributes="0"/>
|
||||||
<Component id="knownOptionCheckBox" alignment="0" min="-2" max="-2" attributes="0"/>
|
<EmptySpace max="-2" attributes="0"/>
|
||||||
|
<Component id="knownBadOptionCheckBox" min="-2" max="-2" attributes="0"/>
|
||||||
</Group>
|
</Group>
|
||||||
</Group>
|
</Group>
|
||||||
|
<EmptySpace pref="28" max="32767" attributes="0"/>
|
||||||
|
</Group>
|
||||||
</Group>
|
</Group>
|
||||||
</DimensionLayout>
|
</DimensionLayout>
|
||||||
<DimensionLayout dim="1">
|
<DimensionLayout dim="1">
|
||||||
@ -32,11 +37,11 @@
|
|||||||
<Group type="102" alignment="0" attributes="0">
|
<Group type="102" alignment="0" attributes="0">
|
||||||
<Component id="knownCheckBox" min="-2" max="-2" attributes="0"/>
|
<Component id="knownCheckBox" min="-2" max="-2" attributes="0"/>
|
||||||
<EmptySpace type="unrelated" max="-2" attributes="0"/>
|
<EmptySpace type="unrelated" max="-2" attributes="0"/>
|
||||||
<Component id="unknownOptionCheckBox" min="-2" max="-2" attributes="0"/>
|
<Group type="103" groupAlignment="3" attributes="0">
|
||||||
<EmptySpace max="-2" attributes="0"/>
|
<Component id="unknownOptionCheckBox" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||||
<Component id="knownOptionCheckBox" min="-2" max="-2" attributes="0"/>
|
<Component id="knownOptionCheckBox" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||||
<EmptySpace max="-2" attributes="0"/>
|
<Component id="knownBadOptionCheckBox" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||||
<Component id="knownBadOptionCheckBox" min="-2" max="-2" attributes="0"/>
|
</Group>
|
||||||
</Group>
|
</Group>
|
||||||
</Group>
|
</Group>
|
||||||
</DimensionLayout>
|
</DimensionLayout>
|
||||||
|
@ -89,24 +89,27 @@ class KnownStatusSearchPanel extends javax.swing.JPanel {
|
|||||||
this.setLayout(layout);
|
this.setLayout(layout);
|
||||||
layout.setHorizontalGroup(
|
layout.setHorizontalGroup(
|
||||||
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||||
|
.addGroup(layout.createSequentialGroup()
|
||||||
|
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||||
.addComponent(knownCheckBox)
|
.addComponent(knownCheckBox)
|
||||||
.addGroup(layout.createSequentialGroup()
|
.addGroup(layout.createSequentialGroup()
|
||||||
.addGap(21, 21, 21)
|
.addGap(21, 21, 21)
|
||||||
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
|
||||||
.addComponent(knownBadOptionCheckBox)
|
|
||||||
.addComponent(unknownOptionCheckBox)
|
.addComponent(unknownOptionCheckBox)
|
||||||
.addComponent(knownOptionCheckBox)))
|
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||||
|
.addComponent(knownOptionCheckBox)
|
||||||
|
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||||
|
.addComponent(knownBadOptionCheckBox)))
|
||||||
|
.addContainerGap(28, Short.MAX_VALUE))
|
||||||
);
|
);
|
||||||
layout.setVerticalGroup(
|
layout.setVerticalGroup(
|
||||||
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||||
.addGroup(layout.createSequentialGroup()
|
.addGroup(layout.createSequentialGroup()
|
||||||
.addComponent(knownCheckBox)
|
.addComponent(knownCheckBox)
|
||||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
|
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
|
||||||
|
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
|
||||||
.addComponent(unknownOptionCheckBox)
|
.addComponent(unknownOptionCheckBox)
|
||||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
|
||||||
.addComponent(knownOptionCheckBox)
|
.addComponent(knownOptionCheckBox)
|
||||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
.addComponent(knownBadOptionCheckBox)))
|
||||||
.addComponent(knownBadOptionCheckBox))
|
|
||||||
);
|
);
|
||||||
}// </editor-fold>//GEN-END:initComponents
|
}// </editor-fold>//GEN-END:initComponents
|
||||||
|
|
||||||
|
44
Core/src/org/sleuthkit/autopsy/filesearch/MimeTypeFilter.java
Executable file
44
Core/src/org/sleuthkit/autopsy/filesearch/MimeTypeFilter.java
Executable file
@ -0,0 +1,44 @@
|
|||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
package org.sleuthkit.autopsy.filesearch;
|
||||||
|
|
||||||
|
import java.awt.event.ActionListener;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Filter by mime type used in filter areas of file search by attribute.
|
||||||
|
*/
|
||||||
|
class MimeTypeFilter extends AbstractFileSearchFilter<MimeTypePanel> {
|
||||||
|
|
||||||
|
public MimeTypeFilter(MimeTypePanel component) {
|
||||||
|
super(component);
|
||||||
|
}
|
||||||
|
public MimeTypeFilter() {
|
||||||
|
this(new MimeTypePanel());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isEnabled() {
|
||||||
|
return this.getComponent().isSelected() &&
|
||||||
|
!this.getComponent().getMimeTypesSelected().isEmpty();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getPredicate() throws FilterValidationException {
|
||||||
|
String predicate = "";
|
||||||
|
for(String mimeType : this.getComponent().getMimeTypesSelected()) {
|
||||||
|
predicate += "mime_type = '" + mimeType + "' OR ";
|
||||||
|
}
|
||||||
|
if(predicate.length() > 3) {
|
||||||
|
predicate = predicate.substring(0, predicate.length() - 3);
|
||||||
|
}
|
||||||
|
return predicate;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void addActionListener(ActionListener l) {
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
98
Core/src/org/sleuthkit/autopsy/filesearch/MimeTypePanel.form
Executable file
98
Core/src/org/sleuthkit/autopsy/filesearch/MimeTypePanel.form
Executable file
@ -0,0 +1,98 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8" ?>
|
||||||
|
|
||||||
|
<Form version="1.5" maxVersion="1.9" type="org.netbeans.modules.form.forminfo.JPanelFormInfo">
|
||||||
|
<Properties>
|
||||||
|
<Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||||
|
<Dimension value="[150, 150]"/>
|
||||||
|
</Property>
|
||||||
|
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||||
|
<Dimension value="[100, 100]"/>
|
||||||
|
</Property>
|
||||||
|
</Properties>
|
||||||
|
<AuxValues>
|
||||||
|
<AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="1"/>
|
||||||
|
<AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/>
|
||||||
|
<AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/>
|
||||||
|
<AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="true"/>
|
||||||
|
<AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="true"/>
|
||||||
|
<AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/>
|
||||||
|
<AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/>
|
||||||
|
<AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/>
|
||||||
|
<AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/>
|
||||||
|
</AuxValues>
|
||||||
|
|
||||||
|
<Layout>
|
||||||
|
<DimensionLayout dim="0">
|
||||||
|
<Group type="103" groupAlignment="0" attributes="0">
|
||||||
|
<Group type="102" alignment="0" attributes="0">
|
||||||
|
<Component id="jCheckBox1" min="-2" max="-2" attributes="0"/>
|
||||||
|
<EmptySpace min="0" pref="0" max="32767" attributes="0"/>
|
||||||
|
</Group>
|
||||||
|
<Group type="102" attributes="0">
|
||||||
|
<EmptySpace max="-2" attributes="0"/>
|
||||||
|
<Group type="103" groupAlignment="0" attributes="0">
|
||||||
|
<Component id="jScrollPane1" pref="0" max="32767" attributes="0"/>
|
||||||
|
<Group type="102" alignment="0" attributes="0">
|
||||||
|
<Component id="jLabel1" min="-2" pref="246" max="-2" attributes="0"/>
|
||||||
|
<EmptySpace min="0" pref="0" max="32767" attributes="0"/>
|
||||||
|
</Group>
|
||||||
|
</Group>
|
||||||
|
<EmptySpace max="-2" attributes="0"/>
|
||||||
|
</Group>
|
||||||
|
</Group>
|
||||||
|
</DimensionLayout>
|
||||||
|
<DimensionLayout dim="1">
|
||||||
|
<Group type="103" groupAlignment="0" attributes="0">
|
||||||
|
<Group type="102" alignment="1" attributes="0">
|
||||||
|
<Component id="jCheckBox1" min="-2" max="-2" attributes="0"/>
|
||||||
|
<EmptySpace max="-2" attributes="0"/>
|
||||||
|
<Component id="jScrollPane1" pref="106" max="32767" attributes="0"/>
|
||||||
|
<EmptySpace max="-2" attributes="0"/>
|
||||||
|
<Component id="jLabel1" min="-2" max="-2" attributes="0"/>
|
||||||
|
<EmptySpace min="0" pref="0" max="-2" attributes="0"/>
|
||||||
|
</Group>
|
||||||
|
</Group>
|
||||||
|
</DimensionLayout>
|
||||||
|
</Layout>
|
||||||
|
<SubComponents>
|
||||||
|
<Container class="javax.swing.JScrollPane" name="jScrollPane1">
|
||||||
|
<AuxValues>
|
||||||
|
<AuxValue name="autoScrollPane" type="java.lang.Boolean" value="true"/>
|
||||||
|
</AuxValues>
|
||||||
|
|
||||||
|
<Layout class="org.netbeans.modules.form.compat2.layouts.support.JScrollPaneSupportLayout"/>
|
||||||
|
<SubComponents>
|
||||||
|
<Component class="javax.swing.JList" name="jList1">
|
||||||
|
<Properties>
|
||||||
|
<Property name="model" type="javax.swing.ListModel" editor="org.netbeans.modules.form.RADConnectionPropertyEditor">
|
||||||
|
<Connection code="new javax.swing.AbstractListModel<String>() {
 String[] strings = getMimeTypeArray();
 public int getSize() { return strings.length; }
 public String getElementAt(int i) { return strings[i]; }
}" type="code"/>
|
||||||
|
</Property>
|
||||||
|
<Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||||
|
<Dimension value="[0, 200]"/>
|
||||||
|
</Property>
|
||||||
|
</Properties>
|
||||||
|
<AuxValues>
|
||||||
|
<AuxValue name="JavaCodeGenerator_TypeParameters" type="java.lang.String" value="<String>"/>
|
||||||
|
</AuxValues>
|
||||||
|
</Component>
|
||||||
|
</SubComponents>
|
||||||
|
</Container>
|
||||||
|
<Component class="javax.swing.JCheckBox" name="jCheckBox1">
|
||||||
|
<Properties>
|
||||||
|
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||||
|
<ResourceString bundle="org/sleuthkit/autopsy/filesearch/Bundle.properties" key="MimeTypePanel.jCheckBox1.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||||
|
</Property>
|
||||||
|
</Properties>
|
||||||
|
</Component>
|
||||||
|
<Component class="javax.swing.JLabel" name="jLabel1">
|
||||||
|
<Properties>
|
||||||
|
<Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor">
|
||||||
|
<Font name="Tahoma" size="10" style="0"/>
|
||||||
|
</Property>
|
||||||
|
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||||
|
<ResourceString bundle="org/sleuthkit/autopsy/filesearch/Bundle.properties" key="MimeTypePanel.jLabel1.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||||
|
</Property>
|
||||||
|
</Properties>
|
||||||
|
</Component>
|
||||||
|
</SubComponents>
|
||||||
|
</Form>
|
138
Core/src/org/sleuthkit/autopsy/filesearch/MimeTypePanel.java
Executable file
138
Core/src/org/sleuthkit/autopsy/filesearch/MimeTypePanel.java
Executable file
@ -0,0 +1,138 @@
|
|||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
package org.sleuthkit.autopsy.filesearch;
|
||||||
|
|
||||||
|
import java.awt.event.ActionListener;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.SortedSet;
|
||||||
|
import java.util.logging.Level;
|
||||||
|
import org.sleuthkit.autopsy.modules.filetypeid.FileTypeDetector;
|
||||||
|
import org.apache.tika.mime.MediaType;
|
||||||
|
import org.apache.tika.mime.MimeTypes;
|
||||||
|
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author oliver
|
||||||
|
*/
|
||||||
|
public class MimeTypePanel extends javax.swing.JPanel {
|
||||||
|
|
||||||
|
private static final SortedSet<MediaType> mediaTypes = MimeTypes.getDefaultMimeTypes().getMediaTypeRegistry().getTypes();
|
||||||
|
private static final Logger logger = Logger.getLogger(MimeTypePanel.class.getName());
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates new form MimeTypePanel
|
||||||
|
*/
|
||||||
|
public MimeTypePanel() {
|
||||||
|
initComponents();
|
||||||
|
}
|
||||||
|
|
||||||
|
private String[] getMimeTypeArray() {
|
||||||
|
Set<String> fileTypesCollated = new HashSet<>();
|
||||||
|
for (MediaType mediaType : mediaTypes) {
|
||||||
|
fileTypesCollated.add(mediaType.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
FileTypeDetector fileTypeDetector;
|
||||||
|
try {
|
||||||
|
fileTypeDetector = new FileTypeDetector();
|
||||||
|
List<String> userDefinedFileTypes = fileTypeDetector.getUserDefinedTypes();
|
||||||
|
fileTypesCollated.addAll(userDefinedFileTypes);
|
||||||
|
|
||||||
|
} catch (FileTypeDetector.FileTypeDetectorInitException ex) {
|
||||||
|
logger.log(Level.SEVERE, "Unable to get user defined file types", ex);
|
||||||
|
}
|
||||||
|
|
||||||
|
List<String> toSort = new ArrayList<>(fileTypesCollated);
|
||||||
|
toSort.sort((String string1, String string2) -> {
|
||||||
|
int result = String.CASE_INSENSITIVE_ORDER.compare(string1, string2);
|
||||||
|
if (result == 0) {
|
||||||
|
result = string1.compareTo(string2);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
});
|
||||||
|
String[] mimeTypeArray = new String[toSort.size()];
|
||||||
|
return toSort.toArray(mimeTypeArray);
|
||||||
|
}
|
||||||
|
|
||||||
|
List<String> getMimeTypesSelected() {
|
||||||
|
return this.jList1.getSelectedValuesList();
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean isSelected() {
|
||||||
|
return this.jCheckBox1.isSelected();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method is called from within the constructor to initialize the form.
|
||||||
|
* WARNING: Do NOT modify this code. The content of this method is always
|
||||||
|
* regenerated by the Form Editor.
|
||||||
|
*/
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
// <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
|
||||||
|
private void initComponents() {
|
||||||
|
|
||||||
|
jScrollPane1 = new javax.swing.JScrollPane();
|
||||||
|
jList1 = new javax.swing.JList<String>();
|
||||||
|
jCheckBox1 = new javax.swing.JCheckBox();
|
||||||
|
jLabel1 = new javax.swing.JLabel();
|
||||||
|
|
||||||
|
setMinimumSize(new java.awt.Dimension(150, 150));
|
||||||
|
setPreferredSize(new java.awt.Dimension(100, 100));
|
||||||
|
|
||||||
|
jList1.setModel(new javax.swing.AbstractListModel<String>() {
|
||||||
|
String[] strings = getMimeTypeArray();
|
||||||
|
public int getSize() { return strings.length; }
|
||||||
|
public String getElementAt(int i) { return strings[i]; }
|
||||||
|
});
|
||||||
|
jList1.setMinimumSize(new java.awt.Dimension(0, 200));
|
||||||
|
jScrollPane1.setViewportView(jList1);
|
||||||
|
|
||||||
|
org.openide.awt.Mnemonics.setLocalizedText(jCheckBox1, org.openide.util.NbBundle.getMessage(MimeTypePanel.class, "MimeTypePanel.jCheckBox1.text")); // NOI18N
|
||||||
|
|
||||||
|
jLabel1.setFont(new java.awt.Font("Tahoma", 0, 10)); // NOI18N
|
||||||
|
org.openide.awt.Mnemonics.setLocalizedText(jLabel1, org.openide.util.NbBundle.getMessage(MimeTypePanel.class, "MimeTypePanel.jLabel1.text")); // NOI18N
|
||||||
|
|
||||||
|
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
|
||||||
|
this.setLayout(layout);
|
||||||
|
layout.setHorizontalGroup(
|
||||||
|
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||||
|
.addGroup(layout.createSequentialGroup()
|
||||||
|
.addComponent(jCheckBox1)
|
||||||
|
.addGap(0, 0, Short.MAX_VALUE))
|
||||||
|
.addGroup(layout.createSequentialGroup()
|
||||||
|
.addContainerGap()
|
||||||
|
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||||
|
.addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 0, Short.MAX_VALUE)
|
||||||
|
.addGroup(layout.createSequentialGroup()
|
||||||
|
.addComponent(jLabel1, javax.swing.GroupLayout.PREFERRED_SIZE, 246, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||||
|
.addGap(0, 0, Short.MAX_VALUE)))
|
||||||
|
.addContainerGap())
|
||||||
|
);
|
||||||
|
layout.setVerticalGroup(
|
||||||
|
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||||
|
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
|
||||||
|
.addComponent(jCheckBox1)
|
||||||
|
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||||
|
.addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 106, Short.MAX_VALUE)
|
||||||
|
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||||
|
.addComponent(jLabel1)
|
||||||
|
.addGap(0, 0, 0))
|
||||||
|
);
|
||||||
|
}// </editor-fold>//GEN-END:initComponents
|
||||||
|
|
||||||
|
|
||||||
|
// Variables declaration - do not modify//GEN-BEGIN:variables
|
||||||
|
private javax.swing.JCheckBox jCheckBox1;
|
||||||
|
private javax.swing.JLabel jLabel1;
|
||||||
|
private javax.swing.JList<String> jList1;
|
||||||
|
private javax.swing.JScrollPane jScrollPane1;
|
||||||
|
// End of variables declaration//GEN-END:variables
|
||||||
|
}
|
@ -55,18 +55,16 @@
|
|||||||
<DimensionLayout dim="0">
|
<DimensionLayout dim="0">
|
||||||
<Group type="103" groupAlignment="0" attributes="0">
|
<Group type="103" groupAlignment="0" attributes="0">
|
||||||
<Group type="102" alignment="0" attributes="0">
|
<Group type="102" alignment="0" attributes="0">
|
||||||
<Component id="nameCheckBox" min="-2" max="-2" attributes="0"/>
|
<EmptySpace min="0" pref="0" max="-2" attributes="0"/>
|
||||||
<Group type="103" groupAlignment="0" max="-2" attributes="0">
|
<Group type="103" groupAlignment="1" attributes="0">
|
||||||
|
<Component id="noteNameLabel" min="-2" pref="296" max="-2" attributes="0"/>
|
||||||
<Group type="102" attributes="0">
|
<Group type="102" attributes="0">
|
||||||
<EmptySpace min="-2" pref="12" max="-2" attributes="0"/>
|
<Component id="nameCheckBox" min="-2" max="-2" attributes="0"/>
|
||||||
<Component id="noteNameLabel" min="-2" max="-2" attributes="0"/>
|
|
||||||
<EmptySpace max="-2" attributes="0"/>
|
<EmptySpace max="-2" attributes="0"/>
|
||||||
</Group>
|
<Component id="searchTextField" min="-2" pref="247" max="-2" attributes="0"/>
|
||||||
<Group type="102" attributes="1">
|
|
||||||
<EmptySpace max="-2" attributes="0"/>
|
|
||||||
<Component id="searchTextField" max="32767" attributes="0"/>
|
|
||||||
</Group>
|
</Group>
|
||||||
</Group>
|
</Group>
|
||||||
|
<EmptySpace min="0" pref="0" max="-2" attributes="0"/>
|
||||||
</Group>
|
</Group>
|
||||||
</Group>
|
</Group>
|
||||||
</DimensionLayout>
|
</DimensionLayout>
|
||||||
@ -79,6 +77,7 @@
|
|||||||
</Group>
|
</Group>
|
||||||
<EmptySpace max="-2" attributes="0"/>
|
<EmptySpace max="-2" attributes="0"/>
|
||||||
<Component id="noteNameLabel" min="-2" max="-2" attributes="0"/>
|
<Component id="noteNameLabel" min="-2" max="-2" attributes="0"/>
|
||||||
|
<EmptySpace min="0" pref="0" max="32767" attributes="0"/>
|
||||||
</Group>
|
</Group>
|
||||||
</Group>
|
</Group>
|
||||||
</DimensionLayout>
|
</DimensionLayout>
|
||||||
@ -121,6 +120,15 @@
|
|||||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||||
<ResourceString bundle="org/sleuthkit/autopsy/filesearch/Bundle.properties" key="NameSearchPanel.noteNameLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
<ResourceString bundle="org/sleuthkit/autopsy/filesearch/Bundle.properties" key="NameSearchPanel.noteNameLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||||
</Property>
|
</Property>
|
||||||
|
<Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||||
|
<Dimension value="[250, 30]"/>
|
||||||
|
</Property>
|
||||||
|
<Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||||
|
<Dimension value="[250, 30]"/>
|
||||||
|
</Property>
|
||||||
|
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||||
|
<Dimension value="[250, 30]"/>
|
||||||
|
</Property>
|
||||||
</Properties>
|
</Properties>
|
||||||
</Component>
|
</Component>
|
||||||
</SubComponents>
|
</SubComponents>
|
||||||
|
@ -121,21 +121,23 @@ class NameSearchPanel extends javax.swing.JPanel {
|
|||||||
|
|
||||||
noteNameLabel.setFont(noteNameLabel.getFont().deriveFont(noteNameLabel.getFont().getStyle() & ~java.awt.Font.BOLD, 10));
|
noteNameLabel.setFont(noteNameLabel.getFont().deriveFont(noteNameLabel.getFont().getStyle() & ~java.awt.Font.BOLD, 10));
|
||||||
noteNameLabel.setText(org.openide.util.NbBundle.getMessage(NameSearchPanel.class, "NameSearchPanel.noteNameLabel.text")); // NOI18N
|
noteNameLabel.setText(org.openide.util.NbBundle.getMessage(NameSearchPanel.class, "NameSearchPanel.noteNameLabel.text")); // NOI18N
|
||||||
|
noteNameLabel.setMaximumSize(new java.awt.Dimension(250, 30));
|
||||||
|
noteNameLabel.setMinimumSize(new java.awt.Dimension(250, 30));
|
||||||
|
noteNameLabel.setPreferredSize(new java.awt.Dimension(250, 30));
|
||||||
|
|
||||||
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
|
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
|
||||||
this.setLayout(layout);
|
this.setLayout(layout);
|
||||||
layout.setHorizontalGroup(
|
layout.setHorizontalGroup(
|
||||||
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||||
|
.addGroup(layout.createSequentialGroup()
|
||||||
|
.addGap(0, 0, 0)
|
||||||
|
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
|
||||||
|
.addComponent(noteNameLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 296, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||||
.addGroup(layout.createSequentialGroup()
|
.addGroup(layout.createSequentialGroup()
|
||||||
.addComponent(nameCheckBox)
|
.addComponent(nameCheckBox)
|
||||||
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
|
|
||||||
.addGroup(layout.createSequentialGroup()
|
|
||||||
.addGap(12, 12, 12)
|
|
||||||
.addComponent(noteNameLabel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
|
|
||||||
.addContainerGap())
|
|
||||||
.addGroup(layout.createSequentialGroup()
|
|
||||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||||
.addComponent(searchTextField))))
|
.addComponent(searchTextField, javax.swing.GroupLayout.PREFERRED_SIZE, 247, javax.swing.GroupLayout.PREFERRED_SIZE)))
|
||||||
|
.addGap(0, 0, 0))
|
||||||
);
|
);
|
||||||
layout.setVerticalGroup(
|
layout.setVerticalGroup(
|
||||||
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||||
@ -144,7 +146,8 @@ class NameSearchPanel extends javax.swing.JPanel {
|
|||||||
.addComponent(nameCheckBox)
|
.addComponent(nameCheckBox)
|
||||||
.addComponent(searchTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
|
.addComponent(searchTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
|
||||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||||
.addComponent(noteNameLabel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
|
.addComponent(noteNameLabel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||||
|
.addGap(0, 0, Short.MAX_VALUE))
|
||||||
);
|
);
|
||||||
}// </editor-fold>//GEN-END:initComponents
|
}// </editor-fold>//GEN-END:initComponents
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* Autopsy Forensic Browser
|
* Autopsy Forensic Browser
|
||||||
*
|
*
|
||||||
* Copyright 2014 Basis Technology Corp.
|
* Copyright 2011-2016 Basis Technology Corp.
|
||||||
* Contact: carrier <at> sleuthkit <dot> org
|
* Contact: carrier <at> sleuthkit <dot> org
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
@ -69,9 +69,6 @@ public final class DataSourceIngestModuleProcessTerminator implements ProcessTer
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @inheritDoc
|
|
||||||
*/
|
|
||||||
@Override
|
@Override
|
||||||
public boolean shouldTerminateProcess() {
|
public boolean shouldTerminateProcess() {
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* Autopsy Forensic Browser
|
* Autopsy Forensic Browser
|
||||||
*
|
*
|
||||||
* Copyright 2014-2015 Basis Technology Corp.
|
* Copyright 2011-2016 Basis Technology Corp.
|
||||||
* Contact: carrier <at> sleuthkit <dot> org
|
* Contact: carrier <at> sleuthkit <dot> org
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
@ -195,17 +195,11 @@ final class DataSourceIngestPipeline {
|
|||||||
return this.processingStartTime;
|
return this.processingStartTime;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @inheritDoc
|
|
||||||
*/
|
|
||||||
@Override
|
@Override
|
||||||
public void startUp(IngestJobContext context) throws IngestModuleException {
|
public void startUp(IngestJobContext context) throws IngestModuleException {
|
||||||
this.module.startUp(context);
|
this.module.startUp(context);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @inheritDoc
|
|
||||||
*/
|
|
||||||
@Override
|
@Override
|
||||||
public IngestModule.ProcessResult process(Content dataSource, DataSourceIngestModuleProgress statusHelper) {
|
public IngestModule.ProcessResult process(Content dataSource, DataSourceIngestModuleProgress statusHelper) {
|
||||||
this.processingStartTime = new Date();
|
this.processingStartTime = new Date();
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* Autopsy Forensic Browser
|
* Autopsy Forensic Browser
|
||||||
*
|
*
|
||||||
* Copyright 2014 Basis Technology Corp.
|
* Copyright 2011-2016 Basis Technology Corp.
|
||||||
* Contact: carrier <at> sleuthkit <dot> org
|
* Contact: carrier <at> sleuthkit <dot> org
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
@ -68,9 +68,6 @@ public final class FileIngestModuleProcessTerminator implements ProcessTerminato
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @inheritDoc
|
|
||||||
*/
|
|
||||||
@Override
|
@Override
|
||||||
public boolean shouldTerminateProcess() {
|
public boolean shouldTerminateProcess() {
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* Autopsy Forensic Browser
|
* Autopsy Forensic Browser
|
||||||
*
|
*
|
||||||
* Copyright 2011-2014 Basis Technology Corp.
|
* Copyright 2011-2016 Basis Technology Corp.
|
||||||
* Contact: carrier <at> sleuthkit <dot> org
|
* Contact: carrier <at> sleuthkit <dot> org
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
@ -168,12 +168,9 @@ public class IngestMessage {
|
|||||||
return hash;
|
return hash;
|
||||||
}
|
}
|
||||||
|
|
||||||
//factory methods
|
|
||||||
/**
|
/**
|
||||||
* Create a message of specified type
|
* Create a message of specified type
|
||||||
*
|
*
|
||||||
* @param ID ID of the message, unique in the context of module
|
|
||||||
* that generated it
|
|
||||||
* @param messageType message type
|
* @param messageType message type
|
||||||
* @param source originating module
|
* @param source originating module
|
||||||
* @param subject message subject to be displayed
|
* @param subject message subject to be displayed
|
||||||
@ -210,8 +207,6 @@ public class IngestMessage {
|
|||||||
/**
|
/**
|
||||||
* Create error message
|
* Create error message
|
||||||
*
|
*
|
||||||
* @param ID ID of the message, unique in the context of module
|
|
||||||
* that generated it
|
|
||||||
* @param source originating module
|
* @param source originating module
|
||||||
* @param subject message subject to be displayed
|
* @param subject message subject to be displayed
|
||||||
* @param detailsHtml html formatted detailed message (without leading and
|
* @param detailsHtml html formatted detailed message (without leading and
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* Autopsy Forensic Browser
|
* Autopsy Forensic Browser
|
||||||
*
|
*
|
||||||
* Copyright 2014 Basis Technology Corp.
|
* Copyright 2011-2016 Basis Technology Corp.
|
||||||
* Contact: carrier <at> sleuthkit <dot> org
|
* Contact: carrier <at> sleuthkit <dot> org
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* Autopsy Forensic Browser
|
* Autopsy Forensic Browser
|
||||||
*
|
*
|
||||||
* Copyright 2014 Basis Technology Corp.
|
* Copyright 2011-2016 Basis Technology Corp.
|
||||||
* Contact: carrier <at> sleuthkit <dot> org
|
* Contact: carrier <at> sleuthkit <dot> org
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
@ -58,7 +58,7 @@ public class ModuleDataEvent extends ChangeEvent {
|
|||||||
*/
|
*/
|
||||||
public ModuleDataEvent(String moduleName, ARTIFACT_TYPE artifactType) {
|
public ModuleDataEvent(String moduleName, ARTIFACT_TYPE artifactType) {
|
||||||
super(artifactType);
|
super(artifactType);
|
||||||
this.blackboardArtifactType = new BlackboardArtifact.Type(artifactType.getTypeID(), artifactType.getLabel(), artifactType.getDisplayName());
|
this.blackboardArtifactType = new BlackboardArtifact.Type(artifactType);
|
||||||
this.moduleName = moduleName;
|
this.moduleName = moduleName;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* Autopsy Forensic Browser
|
* Autopsy Forensic Browser
|
||||||
*
|
*
|
||||||
* Copyright 2015 Basis Technology Corp.
|
* Copyright 2011-2016 Basis Technology Corp.
|
||||||
* Contact: carrier <at> sleuthkit <dot> org
|
* Contact: carrier <at> sleuthkit <dot> org
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
@ -45,7 +45,7 @@ public final class ContentChangedEvent extends AutopsyEvent implements Serializa
|
|||||||
* Constructs a event to be published when new content is added to a case or
|
* Constructs a event to be published when new content is added to a case or
|
||||||
* there is a change a recorded attribute of existing content.
|
* there is a change a recorded attribute of existing content.
|
||||||
*
|
*
|
||||||
* @param contentEvent A ModuleContentEvent object containing the data
|
* @param eventData A ModuleContentEvent object containing the data
|
||||||
* associated with the content addition or change.
|
* associated with the content addition or change.
|
||||||
*/
|
*/
|
||||||
public ContentChangedEvent(ModuleContentEvent eventData) {
|
public ContentChangedEvent(ModuleContentEvent eventData) {
|
||||||
|
@ -43,7 +43,6 @@ FileExtMismatchSettingsPanel.mimeRemoveErrLabel.text=\
|
|||||||
FileExtMismatchSettingsPanel.extRemoveErrLabel.text=\
|
FileExtMismatchSettingsPanel.extRemoveErrLabel.text=\
|
||||||
FileExtMismatchSettingsPanel.mimeErrLabel.text=\
|
FileExtMismatchSettingsPanel.mimeErrLabel.text=\
|
||||||
FileExtMismatchSettingsPanel.removeTypeButton.text=Remove Selected Type
|
FileExtMismatchSettingsPanel.removeTypeButton.text=Remove Selected Type
|
||||||
FileExtMismatchSettingsPanel.saveButton.text=Save Configuration
|
|
||||||
FileExtMismatchSettingsPanel.jLabel1.text=File Types:
|
FileExtMismatchSettingsPanel.jLabel1.text=File Types:
|
||||||
FileExtMismatchSettingsPanel.userExtTextField.text=
|
FileExtMismatchSettingsPanel.userExtTextField.text=
|
||||||
FileExtMismatchSettingsPanel.addExtButton.text=Add Extension
|
FileExtMismatchSettingsPanel.addExtButton.text=Add Extension
|
||||||
|
@ -38,7 +38,6 @@ FileExtMismatchModuleSettingsPanel.skipNoExtCheckBox.text=\u62e1\u5f35\u5b50\u30
|
|||||||
FileExtMismatchSettingsPanel.addTypeButton.text=\u30bf\u30a4\u30d7\u3092\u8ffd\u52a0
|
FileExtMismatchSettingsPanel.addTypeButton.text=\u30bf\u30a4\u30d7\u3092\u8ffd\u52a0
|
||||||
FileExtMismatchSettingsPanel.extHeaderLabel.text=\u8a31\u53ef\u3059\u308b\u62e1\u5f35\u5b50\uff1a
|
FileExtMismatchSettingsPanel.extHeaderLabel.text=\u8a31\u53ef\u3059\u308b\u62e1\u5f35\u5b50\uff1a
|
||||||
FileExtMismatchSettingsPanel.removeTypeButton.text=\u9078\u629e\u3057\u305f\u30bf\u30a4\u30d7\u3092\u524a\u9664
|
FileExtMismatchSettingsPanel.removeTypeButton.text=\u9078\u629e\u3057\u305f\u30bf\u30a4\u30d7\u3092\u524a\u9664
|
||||||
FileExtMismatchSettingsPanel.saveButton.text=\u8a2d\u5b9a\u3092\u4fdd\u5b58
|
|
||||||
FileExtMismatchSettingsPanel.jLabel1.text=\u30d5\u30a1\u30a4\u30eb\u30bf\u30a4\u30d7\uff1a
|
FileExtMismatchSettingsPanel.jLabel1.text=\u30d5\u30a1\u30a4\u30eb\u30bf\u30a4\u30d7\uff1a
|
||||||
FileExtMismatchSettingsPanel.addExtButton.text=\u62e1\u5f35\u5b50\u3092\u8ffd\u52a0
|
FileExtMismatchSettingsPanel.addExtButton.text=\u62e1\u5f35\u5b50\u3092\u8ffd\u52a0
|
||||||
FileExtMismatchSettingsPanel.removeExtButton.text=\u9078\u629e\u3057\u305f\u62e1\u5f35\u5b50\u3092\u524a\u9664
|
FileExtMismatchSettingsPanel.removeExtButton.text=\u9078\u629e\u3057\u305f\u62e1\u5f35\u5b50\u3092\u524a\u9664
|
||||||
|
@ -46,13 +46,10 @@
|
|||||||
<Group type="102" attributes="0">
|
<Group type="102" attributes="0">
|
||||||
<EmptySpace max="-2" attributes="0"/>
|
<EmptySpace max="-2" attributes="0"/>
|
||||||
<Group type="103" groupAlignment="0" attributes="0">
|
<Group type="103" groupAlignment="0" attributes="0">
|
||||||
<Component id="jSplitPane1" pref="667" max="32767" attributes="0"/>
|
<Component id="jSplitPane1" max="32767" attributes="0"/>
|
||||||
<Group type="102" alignment="1" attributes="0">
|
<Group type="102" alignment="1" attributes="0">
|
||||||
<EmptySpace min="0" pref="0" max="32767" attributes="0"/>
|
<EmptySpace min="0" pref="0" max="32767" attributes="0"/>
|
||||||
<Group type="103" groupAlignment="0" attributes="0">
|
<Component id="saveMsgLabel" min="-2" pref="145" max="-2" attributes="0"/>
|
||||||
<Component id="saveButton" alignment="1" min="-2" max="-2" attributes="0"/>
|
|
||||||
<Component id="saveMsgLabel" alignment="1" min="-2" pref="145" max="-2" attributes="0"/>
|
|
||||||
</Group>
|
|
||||||
</Group>
|
</Group>
|
||||||
</Group>
|
</Group>
|
||||||
<EmptySpace max="-2" attributes="0"/>
|
<EmptySpace max="-2" attributes="0"/>
|
||||||
@ -63,9 +60,7 @@
|
|||||||
<Group type="103" groupAlignment="0" attributes="0">
|
<Group type="103" groupAlignment="0" attributes="0">
|
||||||
<Group type="102" attributes="0">
|
<Group type="102" attributes="0">
|
||||||
<EmptySpace max="-2" attributes="0"/>
|
<EmptySpace max="-2" attributes="0"/>
|
||||||
<Component id="jSplitPane1" min="-2" max="-2" attributes="0"/>
|
<Component id="jSplitPane1" min="-2" pref="466" max="-2" attributes="0"/>
|
||||||
<EmptySpace type="unrelated" max="-2" attributes="0"/>
|
|
||||||
<Component id="saveButton" min="-2" max="-2" attributes="0"/>
|
|
||||||
<EmptySpace max="-2" attributes="0"/>
|
<EmptySpace max="-2" attributes="0"/>
|
||||||
<Component id="saveMsgLabel" min="-2" max="-2" attributes="0"/>
|
<Component id="saveMsgLabel" min="-2" max="-2" attributes="0"/>
|
||||||
<EmptySpace max="-2" attributes="0"/>
|
<EmptySpace max="-2" attributes="0"/>
|
||||||
@ -74,20 +69,6 @@
|
|||||||
</DimensionLayout>
|
</DimensionLayout>
|
||||||
</Layout>
|
</Layout>
|
||||||
<SubComponents>
|
<SubComponents>
|
||||||
<Component class="javax.swing.JButton" name="saveButton">
|
|
||||||
<Properties>
|
|
||||||
<Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor">
|
|
||||||
<Image iconType="3" name="/org/sleuthkit/autopsy/modules/fileextmismatch/save16.png"/>
|
|
||||||
</Property>
|
|
||||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
|
||||||
<ResourceString bundle="org/sleuthkit/autopsy/modules/fileextmismatch/Bundle.properties" key="FileExtMismatchSettingsPanel.saveButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
|
||||||
</Property>
|
|
||||||
<Property name="enabled" type="boolean" value="false"/>
|
|
||||||
</Properties>
|
|
||||||
<Events>
|
|
||||||
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="saveButtonActionPerformed"/>
|
|
||||||
</Events>
|
|
||||||
</Component>
|
|
||||||
<Container class="javax.swing.JSplitPane" name="jSplitPane1">
|
<Container class="javax.swing.JSplitPane" name="jSplitPane1">
|
||||||
<Properties>
|
<Properties>
|
||||||
<Property name="dividerLocation" type="int" value="430"/>
|
<Property name="dividerLocation" type="int" value="430"/>
|
||||||
@ -146,7 +127,7 @@
|
|||||||
<Component id="removeTypeButton" min="-2" max="-2" attributes="0"/>
|
<Component id="removeTypeButton" min="-2" max="-2" attributes="0"/>
|
||||||
<EmptySpace max="-2" attributes="0"/>
|
<EmptySpace max="-2" attributes="0"/>
|
||||||
<Component id="mimeRemoveErrLabel" min="-2" max="-2" attributes="0"/>
|
<Component id="mimeRemoveErrLabel" min="-2" max="-2" attributes="0"/>
|
||||||
<EmptySpace pref="47" max="32767" attributes="0"/>
|
<EmptySpace pref="83" max="32767" attributes="0"/>
|
||||||
</Group>
|
</Group>
|
||||||
</Group>
|
</Group>
|
||||||
</DimensionLayout>
|
</DimensionLayout>
|
||||||
|
@ -143,7 +143,6 @@ final class FileExtMismatchSettingsPanel extends IngestModuleGlobalSettingsPanel
|
|||||||
|
|
||||||
jScrollPane1 = new javax.swing.JScrollPane();
|
jScrollPane1 = new javax.swing.JScrollPane();
|
||||||
jPanel1 = new javax.swing.JPanel();
|
jPanel1 = new javax.swing.JPanel();
|
||||||
saveButton = new javax.swing.JButton();
|
|
||||||
jSplitPane1 = new javax.swing.JSplitPane();
|
jSplitPane1 = new javax.swing.JSplitPane();
|
||||||
mimePanel = new javax.swing.JPanel();
|
mimePanel = new javax.swing.JPanel();
|
||||||
jLabel1 = new javax.swing.JLabel();
|
jLabel1 = new javax.swing.JLabel();
|
||||||
@ -167,15 +166,6 @@ final class FileExtMismatchSettingsPanel extends IngestModuleGlobalSettingsPanel
|
|||||||
|
|
||||||
jPanel1.setPreferredSize(new java.awt.Dimension(687, 450));
|
jPanel1.setPreferredSize(new java.awt.Dimension(687, 450));
|
||||||
|
|
||||||
saveButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/modules/fileextmismatch/save16.png"))); // NOI18N NON-NLS
|
|
||||||
saveButton.setText(org.openide.util.NbBundle.getMessage(FileExtMismatchSettingsPanel.class, "FileExtMismatchSettingsPanel.saveButton.text")); // NOI18N
|
|
||||||
saveButton.setEnabled(false);
|
|
||||||
saveButton.addActionListener(new java.awt.event.ActionListener() {
|
|
||||||
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
|
||||||
saveButtonActionPerformed(evt);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
jSplitPane1.setDividerLocation(430);
|
jSplitPane1.setDividerLocation(430);
|
||||||
|
|
||||||
jLabel1.setText(org.openide.util.NbBundle.getMessage(FileExtMismatchSettingsPanel.class, "FileExtMismatchSettingsPanel.jLabel1.text")); // NOI18N
|
jLabel1.setText(org.openide.util.NbBundle.getMessage(FileExtMismatchSettingsPanel.class, "FileExtMismatchSettingsPanel.jLabel1.text")); // NOI18N
|
||||||
@ -247,7 +237,7 @@ final class FileExtMismatchSettingsPanel extends IngestModuleGlobalSettingsPanel
|
|||||||
.addComponent(removeTypeButton)
|
.addComponent(removeTypeButton)
|
||||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||||
.addComponent(mimeRemoveErrLabel)
|
.addComponent(mimeRemoveErrLabel)
|
||||||
.addContainerGap(47, Short.MAX_VALUE))
|
.addContainerGap(83, Short.MAX_VALUE))
|
||||||
);
|
);
|
||||||
|
|
||||||
jSplitPane1.setLeftComponent(mimePanel);
|
jSplitPane1.setLeftComponent(mimePanel);
|
||||||
@ -336,21 +326,17 @@ final class FileExtMismatchSettingsPanel extends IngestModuleGlobalSettingsPanel
|
|||||||
.addGroup(jPanel1Layout.createSequentialGroup()
|
.addGroup(jPanel1Layout.createSequentialGroup()
|
||||||
.addContainerGap()
|
.addContainerGap()
|
||||||
.addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
.addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||||
.addComponent(jSplitPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 667, Short.MAX_VALUE)
|
.addComponent(jSplitPane1)
|
||||||
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel1Layout.createSequentialGroup()
|
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel1Layout.createSequentialGroup()
|
||||||
.addGap(0, 0, Short.MAX_VALUE)
|
.addGap(0, 0, Short.MAX_VALUE)
|
||||||
.addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
.addComponent(saveMsgLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 145, javax.swing.GroupLayout.PREFERRED_SIZE)))
|
||||||
.addComponent(saveButton, javax.swing.GroupLayout.Alignment.TRAILING)
|
|
||||||
.addComponent(saveMsgLabel, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.PREFERRED_SIZE, 145, javax.swing.GroupLayout.PREFERRED_SIZE))))
|
|
||||||
.addContainerGap())
|
.addContainerGap())
|
||||||
);
|
);
|
||||||
jPanel1Layout.setVerticalGroup(
|
jPanel1Layout.setVerticalGroup(
|
||||||
jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||||
.addGroup(jPanel1Layout.createSequentialGroup()
|
.addGroup(jPanel1Layout.createSequentialGroup()
|
||||||
.addContainerGap()
|
.addContainerGap()
|
||||||
.addComponent(jSplitPane1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
|
.addComponent(jSplitPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 466, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
|
|
||||||
.addComponent(saveButton)
|
|
||||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||||
.addComponent(saveMsgLabel)
|
.addComponent(saveMsgLabel)
|
||||||
.addContainerGap())
|
.addContainerGap())
|
||||||
@ -416,10 +402,6 @@ final class FileExtMismatchSettingsPanel extends IngestModuleGlobalSettingsPanel
|
|||||||
setIsModified();
|
setIsModified();
|
||||||
}//GEN-LAST:event_addExtButtonActionPerformed
|
}//GEN-LAST:event_addExtButtonActionPerformed
|
||||||
|
|
||||||
private void saveButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_saveButtonActionPerformed
|
|
||||||
store();
|
|
||||||
}//GEN-LAST:event_saveButtonActionPerformed
|
|
||||||
|
|
||||||
private void addTypeButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_addTypeButtonActionPerformed
|
private void addTypeButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_addTypeButtonActionPerformed
|
||||||
String newMime = userTypeTextField.getText();
|
String newMime = userTypeTextField.getText();
|
||||||
if (newMime.isEmpty()) {
|
if (newMime.isEmpty()) {
|
||||||
@ -555,7 +537,6 @@ final class FileExtMismatchSettingsPanel extends IngestModuleGlobalSettingsPanel
|
|||||||
extErrorLabel.setText(" ");
|
extErrorLabel.setText(" ");
|
||||||
|
|
||||||
saveMsgLabel.setText(NbBundle.getMessage(this.getClass(), "FileExtMismatchConfigPanel.store.msg"));
|
saveMsgLabel.setText(NbBundle.getMessage(this.getClass(), "FileExtMismatchConfigPanel.store.msg"));
|
||||||
saveButton.setEnabled(false);
|
|
||||||
} else {
|
} else {
|
||||||
//error
|
//error
|
||||||
JOptionPane.showMessageDialog(this,
|
JOptionPane.showMessageDialog(this,
|
||||||
@ -582,7 +563,6 @@ final class FileExtMismatchSettingsPanel extends IngestModuleGlobalSettingsPanel
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void setIsModified() {
|
private void setIsModified() {
|
||||||
saveButton.setEnabled(true);
|
|
||||||
saveMsgLabel.setText(" ");
|
saveMsgLabel.setText(" ");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -592,18 +572,7 @@ final class FileExtMismatchSettingsPanel extends IngestModuleGlobalSettingsPanel
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void ok() {
|
public void ok() {
|
||||||
// if data is unsaved
|
|
||||||
if (saveButton.isEnabled()) {
|
|
||||||
int choice = JOptionPane.showConfirmDialog(this,
|
|
||||||
NbBundle.getMessage(this.getClass(),
|
|
||||||
"FileExtMismatchConfigPanel.ok.confDlg.msg"),
|
|
||||||
NbBundle.getMessage(this.getClass(),
|
|
||||||
"FileExtMismatchConfigPanel.confDlg.title"),
|
|
||||||
JOptionPane.YES_NO_OPTION);
|
|
||||||
if (choice == JOptionPane.YES_OPTION) {
|
|
||||||
store();
|
store();
|
||||||
}
|
|
||||||
}
|
|
||||||
clearErrLabels();
|
clearErrLabels();
|
||||||
load(); // The next time this panel is opened, we want it to be fresh
|
load(); // The next time this panel is opened, we want it to be fresh
|
||||||
}
|
}
|
||||||
@ -631,7 +600,6 @@ final class FileExtMismatchSettingsPanel extends IngestModuleGlobalSettingsPanel
|
|||||||
private javax.swing.JTable mimeTable;
|
private javax.swing.JTable mimeTable;
|
||||||
private javax.swing.JButton removeExtButton;
|
private javax.swing.JButton removeExtButton;
|
||||||
private javax.swing.JButton removeTypeButton;
|
private javax.swing.JButton removeTypeButton;
|
||||||
private javax.swing.JButton saveButton;
|
|
||||||
private javax.swing.JLabel saveMsgLabel;
|
private javax.swing.JLabel saveMsgLabel;
|
||||||
private javax.swing.JTextField userExtTextField;
|
private javax.swing.JTextField userExtTextField;
|
||||||
private javax.swing.JTextField userTypeTextField;
|
private javax.swing.JTextField userTypeTextField;
|
||||||
|
@ -18,6 +18,7 @@
|
|||||||
*/
|
*/
|
||||||
package org.sleuthkit.autopsy.modules.filetypeid;
|
package org.sleuthkit.autopsy.modules.filetypeid;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
import java.nio.charset.StandardCharsets;
|
import java.nio.charset.StandardCharsets;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
@ -31,8 +32,9 @@ import org.sleuthkit.datamodel.TskCoreException;
|
|||||||
* <p>
|
* <p>
|
||||||
* Thread-safe (immutable).
|
* Thread-safe (immutable).
|
||||||
*/
|
*/
|
||||||
class FileType {
|
class FileType implements Serializable {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
private final String mimeType;
|
private final String mimeType;
|
||||||
private final Signature signature;
|
private final Signature signature;
|
||||||
private final String interestingFilesSetName;
|
private final String interestingFilesSetName;
|
||||||
@ -114,9 +116,10 @@ class FileType {
|
|||||||
public boolean equals(Object other) {
|
public boolean equals(Object other) {
|
||||||
if (other != null && other instanceof FileType) {
|
if (other != null && other instanceof FileType) {
|
||||||
FileType that = (FileType) other;
|
FileType that = (FileType) other;
|
||||||
if(this.getMimeType().equals(that.getMimeType()) && this.getSignature().equals(that.getSignature()))
|
if (this.getMimeType().equals(that.getMimeType()) && this.getSignature().equals(that.getSignature())) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -134,14 +137,16 @@ class FileType {
|
|||||||
* <p>
|
* <p>
|
||||||
* Thread-safe (immutable).
|
* Thread-safe (immutable).
|
||||||
*/
|
*/
|
||||||
static class Signature {
|
static class Signature implements Serializable {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
private static final Logger logger = Logger.getLogger(Signature.class.getName());
|
private static final Logger logger = Logger.getLogger(Signature.class.getName());
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The way the signature byte sequence should be interpreted.
|
* The way the signature byte sequence should be interpreted.
|
||||||
*/
|
*/
|
||||||
enum Type {
|
enum Type {
|
||||||
|
|
||||||
RAW, ASCII
|
RAW, ASCII
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -156,8 +161,8 @@ class FileType {
|
|||||||
*
|
*
|
||||||
* @param signatureBytes The signature bytes.
|
* @param signatureBytes The signature bytes.
|
||||||
* @param offset The offset of the signature bytes.
|
* @param offset The offset of the signature bytes.
|
||||||
* @param type The type of data in the byte array. Impacts
|
* @param type The type of data in the byte array. Impacts how
|
||||||
* how it is displayed to the user in the UI.
|
* it is displayed to the user in the UI.
|
||||||
*/
|
*/
|
||||||
Signature(final byte[] signatureBytes, long offset, Type type) {
|
Signature(final byte[] signatureBytes, long offset, Type type) {
|
||||||
this.signatureBytes = Arrays.copyOf(signatureBytes, signatureBytes.length);
|
this.signatureBytes = Arrays.copyOf(signatureBytes, signatureBytes.length);
|
||||||
@ -167,8 +172,8 @@ class FileType {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a file signature consisting of an ASCII string at a
|
* Creates a file signature consisting of an ASCII string at a specific
|
||||||
* specific offset within a file.
|
* offset within a file.
|
||||||
*
|
*
|
||||||
* @param signatureString The ASCII string
|
* @param signatureString The ASCII string
|
||||||
* @param offset The offset of the signature bytes.
|
* @param offset The offset of the signature bytes.
|
||||||
@ -204,7 +209,8 @@ class FileType {
|
|||||||
* @param offset The offset of the signature bytes.
|
* @param offset The offset of the signature bytes.
|
||||||
* @param type The type of data in the byte array. Impacts
|
* @param type The type of data in the byte array. Impacts
|
||||||
* how it is displayed to the user in the UI.
|
* how it is displayed to the user in the UI.
|
||||||
* @param isRelativeToStart Determines whether this signature is relative to start.
|
* @param isRelativeToStart Determines whether this signature is
|
||||||
|
* relative to start.
|
||||||
*/
|
*/
|
||||||
Signature(final byte[] signatureBytes, long offset, Type type, boolean isRelativeToStart) {
|
Signature(final byte[] signatureBytes, long offset, Type type, boolean isRelativeToStart) {
|
||||||
this.signatureBytes = Arrays.copyOf(signatureBytes, signatureBytes.length);
|
this.signatureBytes = Arrays.copyOf(signatureBytes, signatureBytes.length);
|
||||||
@ -214,12 +220,13 @@ class FileType {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a file signature consisting of an ASCII string at a
|
* Creates a file signature consisting of an ASCII string at a specific
|
||||||
* specific offset within a file.
|
* offset within a file.
|
||||||
*
|
*
|
||||||
* @param signatureString The ASCII string
|
* @param signatureString The ASCII string
|
||||||
* @param offset The offset of the signature bytes.
|
* @param offset The offset of the signature bytes.
|
||||||
* @param isRelativeToStart Determines whether this signature is relative to start.
|
* @param isRelativeToStart Determines whether this signature is
|
||||||
|
* relative to start.
|
||||||
*/
|
*/
|
||||||
Signature(String signatureString, long offset, boolean isRelativeToStart) {
|
Signature(String signatureString, long offset, boolean isRelativeToStart) {
|
||||||
this.signatureBytes = signatureString.getBytes(StandardCharsets.US_ASCII);
|
this.signatureBytes = signatureString.getBytes(StandardCharsets.US_ASCII);
|
||||||
@ -236,7 +243,8 @@ class FileType {
|
|||||||
*
|
*
|
||||||
* @param signatureBytes The signature bytes.
|
* @param signatureBytes The signature bytes.
|
||||||
* @param offset The offset of the signature bytes.
|
* @param offset The offset of the signature bytes.
|
||||||
* @param isRelativeToStart Determines whether this signature is relative to start.
|
* @param isRelativeToStart Determines whether this signature is
|
||||||
|
* relative to start.
|
||||||
*/
|
*/
|
||||||
Signature(final byte[] signatureBytes, long offset, boolean isRelativeToStart) {
|
Signature(final byte[] signatureBytes, long offset, boolean isRelativeToStart) {
|
||||||
this.signatureBytes = Arrays.copyOf(signatureBytes, signatureBytes.length);
|
this.signatureBytes = Arrays.copyOf(signatureBytes, signatureBytes.length);
|
||||||
@ -289,8 +297,9 @@ class FileType {
|
|||||||
return false; // File is too small, offset lies outside file.
|
return false; // File is too small, offset lies outside file.
|
||||||
}
|
}
|
||||||
long actualOffset = offset;
|
long actualOffset = offset;
|
||||||
if(!isRelativeToStart)
|
if (!isRelativeToStart) {
|
||||||
actualOffset = file.getSize() - 1 - offset;
|
actualOffset = file.getSize() - 1 - offset;
|
||||||
|
}
|
||||||
if (file.getSize() < (actualOffset + signatureBytes.length)) {
|
if (file.getSize() < (actualOffset + signatureBytes.length)) {
|
||||||
return false; /// too small, can't contain this signature
|
return false; /// too small, can't contain this signature
|
||||||
}
|
}
|
||||||
@ -315,9 +324,10 @@ class FileType {
|
|||||||
Signature that = (Signature) other;
|
Signature that = (Signature) other;
|
||||||
if (Arrays.equals(this.getSignatureBytes(), that.getSignatureBytes())
|
if (Arrays.equals(this.getSignatureBytes(), that.getSignatureBytes())
|
||||||
&& this.getOffset() == that.getOffset()
|
&& this.getOffset() == that.getOffset()
|
||||||
&& this.getType().equals(that.getType()))
|
&& this.getType().equals(that.getType())) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -133,48 +133,20 @@ public class FileTypeDetector {
|
|||||||
* Gets the MIME type of a file, detecting it if it is not already known. If
|
* Gets the MIME type of a file, detecting it if it is not already known. If
|
||||||
* detection is necessary, the result is added to the case database.
|
* detection is necessary, the result is added to the case database.
|
||||||
*
|
*
|
||||||
* IMPORTANT: This method should not be called except by ingest modules; all
|
* IMPORTANT: This method should only be called by ingest modules. All
|
||||||
* other clients should call AbstractFile.getMIMEType, and may call
|
* other clients should call AbstractFile.getMIMEType, and may call
|
||||||
* FileTypeDetector.detect, if AbstractFile.getMIMEType returns null.
|
* FileTypeDetector.detect, if AbstractFile.getMIMEType returns null.
|
||||||
*
|
*
|
||||||
* @param file The file.
|
* @param file The file.
|
||||||
*
|
*
|
||||||
* @return A MIME type name.
|
* @return A MIME type name. If file type could not be detected or results
|
||||||
|
* were uncertain, octet-stream is returned.
|
||||||
*
|
*
|
||||||
* @throws TskCoreException if detection is required and there is a problem
|
* @throws TskCoreException if detection is required and there is a problem
|
||||||
* writing the result to the case database.
|
* writing the result to the case database.
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings("deprecation")
|
|
||||||
public String getFileType(AbstractFile file) throws TskCoreException {
|
public String getFileType(AbstractFile file) throws TskCoreException {
|
||||||
String mimeType = file.getMIMEType();
|
return detect(file, true);
|
||||||
if (null != mimeType) {
|
|
||||||
return mimeType;
|
|
||||||
}
|
|
||||||
|
|
||||||
mimeType = detect(file);
|
|
||||||
Case.getCurrentCase().getSleuthkitCase().setFileMIMEType(file, mimeType);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Add the file type attribute to the general info artifact. Note that
|
|
||||||
* no property change is fired for this blackboard posting because
|
|
||||||
* general info artifacts are different from other artifacts, e.g., they
|
|
||||||
* are not displayed in the results tree.
|
|
||||||
*
|
|
||||||
* SPECIAL NOTE: Adding a file type attribute to the general info
|
|
||||||
* artifact is meant to be replaced by the use of the MIME type field of
|
|
||||||
* the AbstractFile class (tsk_files.mime_type in the case database).
|
|
||||||
* The attribute is still added here to support backward compatibility,
|
|
||||||
* but it introduces a check-then-act race condition that can lead to
|
|
||||||
* duplicate attributes. Various mitigation strategies were considered.
|
|
||||||
* It was decided to go with the policy that this method would not be
|
|
||||||
* called outside of ingest (see note in method docs), at least until
|
|
||||||
* such time as the attribute is no longer created.
|
|
||||||
*/
|
|
||||||
BlackboardArtifact getInfoArt = file.getGenInfoArtifact();
|
|
||||||
BlackboardAttribute batt = new BlackboardAttribute(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_FILE_TYPE_SIG, FileTypeIdModuleFactory.getModuleName(), mimeType);
|
|
||||||
getInfoArt.addAttribute(batt);
|
|
||||||
|
|
||||||
return mimeType;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -186,9 +158,39 @@ public class FileTypeDetector {
|
|||||||
* @return A MIME type name. If file type could not be detected or results
|
* @return A MIME type name. If file type could not be detected or results
|
||||||
* were uncertain, octet-stream is returned.
|
* were uncertain, octet-stream is returned.
|
||||||
*
|
*
|
||||||
* @throws TskCoreException
|
* @throws TskCoreException If there is a problem writing the result to the
|
||||||
|
* case database.
|
||||||
*/
|
*/
|
||||||
public String detect(AbstractFile file) throws TskCoreException {
|
public String detect(AbstractFile file) throws TskCoreException {
|
||||||
|
return detect(file, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Detects the MIME type of a file. The result is saved to the case database
|
||||||
|
* only if the add to case dastabase flag is set.
|
||||||
|
*
|
||||||
|
* @param file The file to test.
|
||||||
|
* @param addToCaseDb Whether the MIME type should be added to the case
|
||||||
|
* database. This flag is part of a partial workaround
|
||||||
|
* for a check-then-act-race condition (see notes in
|
||||||
|
* comments for details).
|
||||||
|
*
|
||||||
|
* @return A MIME type name. If file type could not be detected or results
|
||||||
|
* were uncertain, octet-stream is returned.
|
||||||
|
*
|
||||||
|
* @throws TskCoreException If there is a problem writing the result to the
|
||||||
|
* case database.
|
||||||
|
*/
|
||||||
|
private String detect(AbstractFile file, boolean addToCaseDb) throws TskCoreException {
|
||||||
|
/*
|
||||||
|
* Check to see if the file has already been typed. This is the "check"
|
||||||
|
* part of a check-then-act race condition (see note below).
|
||||||
|
*/
|
||||||
|
String mimeType = file.getMIMEType();
|
||||||
|
if (null != mimeType) {
|
||||||
|
return mimeType;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Mark non-regular files (refer to TskData.TSK_FS_META_TYPE_ENUM),
|
* Mark non-regular files (refer to TskData.TSK_FS_META_TYPE_ENUM),
|
||||||
* zero-sized files, unallocated space, and unused blocks (refer to
|
* zero-sized files, unallocated space, and unused blocks (refer to
|
||||||
@ -198,18 +200,21 @@ public class FileTypeDetector {
|
|||||||
|| (file.getType() == TskData.TSK_DB_FILES_TYPE_ENUM.UNALLOC_BLOCKS)
|
|| (file.getType() == TskData.TSK_DB_FILES_TYPE_ENUM.UNALLOC_BLOCKS)
|
||||||
|| (file.getType() == TskData.TSK_DB_FILES_TYPE_ENUM.UNUSED_BLOCKS)
|
|| (file.getType() == TskData.TSK_DB_FILES_TYPE_ENUM.UNUSED_BLOCKS)
|
||||||
|| (file.getType() == TskData.TSK_DB_FILES_TYPE_ENUM.VIRTUAL_DIR)) {
|
|| (file.getType() == TskData.TSK_DB_FILES_TYPE_ENUM.VIRTUAL_DIR)) {
|
||||||
return MimeTypes.OCTET_STREAM;
|
mimeType = MimeTypes.OCTET_STREAM;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Give precedence to user-defined types.
|
* If the file is a regular file, give precedence to user-defined types.
|
||||||
*/
|
*/
|
||||||
String mimeType = detectUserDefinedType(file);
|
|
||||||
if (null == mimeType) {
|
if (null == mimeType) {
|
||||||
|
mimeType = detectUserDefinedType(file, addToCaseDb);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The file does not match a user-defined type. Send the initial
|
* If the file does not match a user-defined type, send the initial
|
||||||
* bytes to Tika.
|
* bytes to Tika.
|
||||||
*/
|
*/
|
||||||
|
if (null == mimeType) {
|
||||||
try {
|
try {
|
||||||
byte buf[];
|
byte buf[];
|
||||||
int len = file.read(buffer, 0, BUFFER_SIZE);
|
int len = file.read(buffer, 0, BUFFER_SIZE);
|
||||||
@ -237,25 +242,63 @@ public class FileTypeDetector {
|
|||||||
mimeType = MimeTypes.OCTET_STREAM;
|
mimeType = MimeTypes.OCTET_STREAM;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If adding the result to the case database, do so now.
|
||||||
|
*
|
||||||
|
* NOTE: This condtional is a way to deal with the check-then-act race
|
||||||
|
* condition created by the gap between querying the MIME type and
|
||||||
|
* recording it. It is not really a problem for the mime_type column of
|
||||||
|
* the tsk_files table, but it can lead to duplicate blackboard posts,
|
||||||
|
* and the posts are required to maintain backward compatibility.
|
||||||
|
* Various mitigation strategies were considered. It was decided to go
|
||||||
|
* with the policy that only ingest modules are allowed to add file
|
||||||
|
* types to the case database, at least until such time as file types
|
||||||
|
* are no longer posted to the blackboard. Of course, this is not a
|
||||||
|
* perfect solution. It's not really enforceable for community
|
||||||
|
* contributed plug ins and it does not handle the unlikely but possible
|
||||||
|
* scenario of multiple processes typing the same file for a multi-user
|
||||||
|
* case.
|
||||||
|
*/
|
||||||
|
if (addToCaseDb) {
|
||||||
|
/*
|
||||||
|
* Add the MIME type to the files table in the case database.
|
||||||
|
*/
|
||||||
|
Case.getCurrentCase().getSleuthkitCase().setFileMIMEType(file, mimeType);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Post to the blackboard, adding the file type attribute to the
|
||||||
|
* general info artifact. A property change is not fired for this
|
||||||
|
* posting because general info artifacts are different from other
|
||||||
|
* artifacts, e.g., they are not displayed in the results tree.
|
||||||
|
*/
|
||||||
|
BlackboardArtifact getInfoArt = file.getGenInfoArtifact();
|
||||||
|
@SuppressWarnings("deprecation")
|
||||||
|
BlackboardAttribute batt = new BlackboardAttribute(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_FILE_TYPE_SIG, FileTypeIdModuleFactory.getModuleName(), mimeType);
|
||||||
|
getInfoArt.addAttribute(batt);
|
||||||
|
}
|
||||||
|
|
||||||
return mimeType;
|
return mimeType;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Determines whether or not the a file matches a user-defined or Autopsy
|
* Determines whether or not the a file matches a user-defined or Autopsy
|
||||||
* predefined file type. If a match is found and the file type definition
|
* predefined file type. If postToBlackBoard is true, and a match is found,
|
||||||
* calls for an alert on a match, an interesting file hit artifact is posted
|
* and the file type definition calls for an alert on a match, an
|
||||||
* to the blackboard.
|
* interesting file hit artifact is posted to the blackboard.
|
||||||
*
|
*
|
||||||
* @param file The file to test.
|
* @param file The file to test.
|
||||||
|
* @param postToBlackBoard Whether an interesting file hit could be posted
|
||||||
|
* to the blackboard.
|
||||||
*
|
*
|
||||||
* @return The file type name string or null, if no match is detected.
|
* @return The file type name string or null, if no match is detected.
|
||||||
*
|
*
|
||||||
* @throws TskCoreException
|
* @throws TskCoreException
|
||||||
*/
|
*/
|
||||||
private String detectUserDefinedType(AbstractFile file) throws TskCoreException {
|
private String detectUserDefinedType(AbstractFile file, boolean postToBlackBoard) throws TskCoreException {
|
||||||
for (FileType fileType : userDefinedFileTypes) {
|
for (FileType fileType : userDefinedFileTypes) {
|
||||||
if (fileType.matches(file)) {
|
if (fileType.matches(file)) {
|
||||||
if (fileType.alertOnMatch()) {
|
if (postToBlackBoard && fileType.alertOnMatch()) {
|
||||||
/*
|
/*
|
||||||
* Create an interesting file hit artifact.
|
* Create an interesting file hit artifact.
|
||||||
*/
|
*/
|
||||||
|
@ -19,7 +19,9 @@
|
|||||||
package org.sleuthkit.autopsy.modules.filetypeid;
|
package org.sleuthkit.autopsy.modules.filetypeid;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
import java.io.FileInputStream;
|
||||||
import java.io.FileNotFoundException;
|
import java.io.FileNotFoundException;
|
||||||
|
import java.io.FileOutputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.UnsupportedEncodingException;
|
import java.io.UnsupportedEncodingException;
|
||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
@ -27,6 +29,7 @@ import java.nio.file.Paths;
|
|||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
|
import javax.persistence.PersistenceException;
|
||||||
import javax.xml.parsers.ParserConfigurationException;
|
import javax.xml.parsers.ParserConfigurationException;
|
||||||
import org.w3c.dom.Document;
|
import org.w3c.dom.Document;
|
||||||
import org.w3c.dom.Element;
|
import org.w3c.dom.Element;
|
||||||
@ -34,10 +37,13 @@ import org.w3c.dom.NodeList;
|
|||||||
import javax.xml.bind.DatatypeConverter;
|
import javax.xml.bind.DatatypeConverter;
|
||||||
import javax.xml.transform.TransformerException;
|
import javax.xml.transform.TransformerException;
|
||||||
import org.openide.util.NbBundle;
|
import org.openide.util.NbBundle;
|
||||||
|
import org.openide.util.io.NbObjectInputStream;
|
||||||
|
import org.openide.util.io.NbObjectOutputStream;
|
||||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||||
import org.sleuthkit.autopsy.coreutils.PlatformUtil;
|
import org.sleuthkit.autopsy.coreutils.PlatformUtil;
|
||||||
import org.sleuthkit.autopsy.coreutils.XMLUtil;
|
import org.sleuthkit.autopsy.coreutils.XMLUtil;
|
||||||
import org.sleuthkit.autopsy.modules.filetypeid.FileType.Signature;
|
import org.sleuthkit.autopsy.modules.filetypeid.FileType.Signature;
|
||||||
|
import org.sleuthkit.datamodel.TskCoreException;
|
||||||
import org.w3c.dom.Node;
|
import org.w3c.dom.Node;
|
||||||
import org.xml.sax.SAXException;
|
import org.xml.sax.SAXException;
|
||||||
|
|
||||||
@ -59,7 +65,8 @@ import org.xml.sax.SAXException;
|
|||||||
final class UserDefinedFileTypesManager {
|
final class UserDefinedFileTypesManager {
|
||||||
|
|
||||||
private static final Logger logger = Logger.getLogger(UserDefinedFileTypesManager.class.getName());
|
private static final Logger logger = Logger.getLogger(UserDefinedFileTypesManager.class.getName());
|
||||||
private static final String USER_DEFINED_TYPE_DEFINITIONS_FILE = "UserFileTypeDefinitions.xml"; //NON-NLS
|
private static final String USER_DEFINED_TYPES_XML_FILE = "UserFileTypeDefinitions.xml"; //NON-NLS
|
||||||
|
private static final String USER_DEFINED_TYPES_SERIALIZATION_FILE = "UserFileTypeDefinitions.settings";
|
||||||
private static final String FILE_TYPES_TAG_NAME = "FileTypes"; //NON-NLS
|
private static final String FILE_TYPES_TAG_NAME = "FileTypes"; //NON-NLS
|
||||||
private static final String FILE_TYPE_TAG_NAME = "FileType"; //NON-NLS
|
private static final String FILE_TYPE_TAG_NAME = "FileType"; //NON-NLS
|
||||||
private static final String MIME_TYPE_TAG_NAME = "MimeType"; //NON-NLS
|
private static final String MIME_TYPE_TAG_NAME = "MimeType"; //NON-NLS
|
||||||
@ -246,12 +253,19 @@ final class UserDefinedFileTypesManager {
|
|||||||
*/
|
*/
|
||||||
private void loadUserDefinedFileTypes() throws UserDefinedFileTypesException {
|
private void loadUserDefinedFileTypes() throws UserDefinedFileTypesException {
|
||||||
try {
|
try {
|
||||||
String filePath = getFileTypeDefinitionsFilePath(USER_DEFINED_TYPE_DEFINITIONS_FILE);
|
File serialized = new File(getFileTypeDefinitionsFilePath(USER_DEFINED_TYPES_SERIALIZATION_FILE));
|
||||||
File file = new File(filePath);
|
if (serialized.exists()) {
|
||||||
if (file.exists() && file.canRead()) {
|
for (FileType fileType : readFileTypesSerialized()) {
|
||||||
for (FileType fileType : XmlReader.readFileTypes(filePath)) {
|
|
||||||
addUserDefinedFileType(fileType);
|
addUserDefinedFileType(fileType);
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
String filePath = getFileTypeDefinitionsFilePath(USER_DEFINED_TYPES_XML_FILE);
|
||||||
|
File xmlFile = new File(filePath);
|
||||||
|
if (xmlFile.exists()) {
|
||||||
|
for (FileType fileType : XMLDefinitionsReader.readFileTypes(filePath)) {
|
||||||
|
addUserDefinedFileType(fileType);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
} catch (IOException | ParserConfigurationException | SAXException ex) {
|
} catch (IOException | ParserConfigurationException | SAXException ex) {
|
||||||
@ -282,14 +296,8 @@ final class UserDefinedFileTypesManager {
|
|||||||
* types.
|
* types.
|
||||||
*/
|
*/
|
||||||
synchronized void setUserDefinedFileTypes(List<FileType> newFileTypes) throws UserDefinedFileTypesException {
|
synchronized void setUserDefinedFileTypes(List<FileType> newFileTypes) throws UserDefinedFileTypesException {
|
||||||
try {
|
String filePath = getFileTypeDefinitionsFilePath(USER_DEFINED_TYPES_SERIALIZATION_FILE);
|
||||||
String filePath = getFileTypeDefinitionsFilePath(USER_DEFINED_TYPE_DEFINITIONS_FILE);
|
writeFileTypes(newFileTypes, filePath);
|
||||||
XmlWriter.writeFileTypes(newFileTypes, filePath);
|
|
||||||
} catch (ParserConfigurationException | FileNotFoundException | UnsupportedEncodingException | TransformerException ex) {
|
|
||||||
throwUserDefinedFileTypesException(ex, "UserDefinedFileTypesManager.saveFileTypes.errorMessage");
|
|
||||||
} catch (IOException ex) {
|
|
||||||
throwUserDefinedFileTypesException(ex, "UserDefinedFileTypesManager.saveFileTypes.errorMessage");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -305,13 +313,7 @@ final class UserDefinedFileTypesManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Provides a mechanism for writing a set of file type definitions to an XML
|
* Writes a set of file types to a file.
|
||||||
* file.
|
|
||||||
*/
|
|
||||||
private static class XmlWriter {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Writes a set of file type definitions to an XML file.
|
|
||||||
*
|
*
|
||||||
* @param fileTypes A collection of file types.
|
* @param fileTypes A collection of file types.
|
||||||
* @param filePath The path to the destination file.
|
* @param filePath The path to the destination file.
|
||||||
@ -322,110 +324,41 @@ final class UserDefinedFileTypesManager {
|
|||||||
* @throws UnsupportedEncodingException
|
* @throws UnsupportedEncodingException
|
||||||
* @throws TransformerException
|
* @throws TransformerException
|
||||||
*/
|
*/
|
||||||
private static void writeFileTypes(List<FileType> fileTypes, String filePath) throws ParserConfigurationException, IOException, FileNotFoundException, UnsupportedEncodingException, TransformerException {
|
private static void writeFileTypes(List<FileType> fileTypes, String filePath) throws UserDefinedFileTypesException {
|
||||||
Document doc = XMLUtil.createDocument();
|
try (NbObjectOutputStream out = new NbObjectOutputStream(new FileOutputStream(filePath))) {
|
||||||
Element fileTypesElem = doc.createElement(FILE_TYPES_TAG_NAME);
|
UserDefinedFileTypesSettings settings = new UserDefinedFileTypesSettings(fileTypes);
|
||||||
doc.appendChild(fileTypesElem);
|
out.writeObject(settings);
|
||||||
for (FileType fileType : fileTypes) {
|
} catch (IOException ex) {
|
||||||
Element fileTypeElem = XmlWriter.createFileTypeElement(fileType, doc);
|
throw new UserDefinedFileTypesException(String.format("Failed to write settings to %s", filePath), ex);
|
||||||
fileTypesElem.appendChild(fileTypeElem);
|
|
||||||
}
|
|
||||||
XMLUtil.saveDocument(doc, ENCODING_FOR_XML_FILE, filePath);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates an XML representation of a file type.
|
|
||||||
*
|
|
||||||
* @param fileType The file type object.
|
|
||||||
* @param doc The WC3 DOM object to use to create the XML.
|
|
||||||
*
|
|
||||||
* @return An XML element.
|
|
||||||
*/
|
|
||||||
private static Element createFileTypeElement(FileType fileType, Document doc) {
|
|
||||||
Element fileTypeElem = doc.createElement(FILE_TYPE_TAG_NAME);
|
|
||||||
XmlWriter.addMimeTypeElement(fileType, fileTypeElem, doc);
|
|
||||||
XmlWriter.addSignatureElement(fileType, fileTypeElem, doc);
|
|
||||||
XmlWriter.addInterestingFilesSetElement(fileType, fileTypeElem, doc);
|
|
||||||
XmlWriter.addAlertAttribute(fileType, fileTypeElem);
|
|
||||||
return fileTypeElem;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Add a MIME type child element to a file type XML element.
|
|
||||||
*
|
|
||||||
* @param fileType The file type to use as a content source.
|
|
||||||
* @param fileTypeElem The parent file type element.
|
|
||||||
* @param doc The WC3 DOM object to use to create the XML.
|
|
||||||
*/
|
|
||||||
private static void addMimeTypeElement(FileType fileType, Element fileTypeElem, Document doc) {
|
|
||||||
Element typeNameElem = doc.createElement(MIME_TYPE_TAG_NAME);
|
|
||||||
typeNameElem.setTextContent(fileType.getMimeType());
|
|
||||||
fileTypeElem.appendChild(typeNameElem);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Add a signature child element to a file type XML element.
|
|
||||||
*
|
|
||||||
* @param fileType The file type to use as a content source.
|
|
||||||
* @param fileTypeElem The parent file type element.
|
|
||||||
* @param doc The WC3 DOM object to use to create the XML.
|
|
||||||
*/
|
|
||||||
private static void addSignatureElement(FileType fileType, Element fileTypeElem, Document doc) {
|
|
||||||
Signature signature = fileType.getSignature();
|
|
||||||
Element signatureElem = doc.createElement(SIGNATURE_TAG_NAME);
|
|
||||||
|
|
||||||
Element bytesElem = doc.createElement(BYTES_TAG_NAME);
|
|
||||||
bytesElem.setTextContent(DatatypeConverter.printHexBinary(signature.getSignatureBytes()));
|
|
||||||
signatureElem.appendChild(bytesElem);
|
|
||||||
|
|
||||||
Element offsetElem = doc.createElement(OFFSET_TAG_NAME);
|
|
||||||
offsetElem.setTextContent(DatatypeConverter.printLong(signature.getOffset()));
|
|
||||||
offsetElem.setAttribute(RELATIVE_ATTRIBUTE, String.valueOf(signature.isRelativeToStart()));
|
|
||||||
signatureElem.appendChild(offsetElem);
|
|
||||||
|
|
||||||
signatureElem.setAttribute(SIGNATURE_TYPE_ATTRIBUTE, signature.getType().toString());
|
|
||||||
fileTypeElem.appendChild(signatureElem);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Add an interesting files set element to a file type XML element.
|
|
||||||
*
|
|
||||||
* @param fileType The file type to use as a content source.
|
|
||||||
* @param fileTypeElem The parent file type element.
|
|
||||||
* @param doc The WC3 DOM object to use to create the XML.
|
|
||||||
*/
|
|
||||||
private static void addInterestingFilesSetElement(FileType fileType, Element fileTypeElem, Document doc) {
|
|
||||||
if (!fileType.getFilesSetName().isEmpty()) {
|
|
||||||
Element filesSetElem = doc.createElement(INTERESTING_FILES_SET_TAG_NAME);
|
|
||||||
filesSetElem.setTextContent(fileType.getFilesSetName());
|
|
||||||
fileTypeElem.appendChild(filesSetElem);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add an alert attribute to a file type XML element.
|
* Reads the file types
|
||||||
*
|
*
|
||||||
* @param fileType The file type to use as a content source.
|
* @param filePath the file path where the file types are to be read
|
||||||
* @param fileTypeElem The parent file type element.
|
*
|
||||||
|
* @return the file types
|
||||||
|
*
|
||||||
|
* @throws ParserConfigurationException If the file cannot be read
|
||||||
*/
|
*/
|
||||||
private static void addAlertAttribute(FileType fileType, Element fileTypeElem) {
|
private static List<FileType> readFileTypesSerialized() throws UserDefinedFileTypesException {
|
||||||
fileTypeElem.setAttribute(ALERT_ATTRIBUTE, Boolean.toString(fileType.alertOnMatch()));
|
File serializedDefs = new File(getFileTypeDefinitionsFilePath(USER_DEFINED_TYPES_SERIALIZATION_FILE));
|
||||||
|
try {
|
||||||
|
try (NbObjectInputStream in = new NbObjectInputStream(new FileInputStream(serializedDefs))) {
|
||||||
|
UserDefinedFileTypesSettings filesSetsSettings = (UserDefinedFileTypesSettings) in.readObject();
|
||||||
|
return filesSetsSettings.getUserDefinedFileTypes();
|
||||||
}
|
}
|
||||||
|
} catch (IOException | ClassNotFoundException ex) {
|
||||||
/**
|
throw new UserDefinedFileTypesException("Couldn't read serialized settings.", ex);
|
||||||
* Private constructor suppresses creation of instanmces of this utility
|
|
||||||
* class.
|
|
||||||
*/
|
|
||||||
private XmlWriter() {
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Provides a mechanism for reading a set of file type definitions from an
|
* Provides a mechanism for reading a set of file type definitions from an
|
||||||
* XML file.
|
* XML file.
|
||||||
*/
|
*/
|
||||||
private static class XmlReader {
|
private static class XMLDefinitionsReader {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Reads a set of file type definitions from an XML file.
|
* Reads a set of file type definitions from an XML file.
|
||||||
@ -434,7 +367,7 @@ final class UserDefinedFileTypesManager {
|
|||||||
*
|
*
|
||||||
* @return A collection of file types read from the XML file.
|
* @return A collection of file types read from the XML file.
|
||||||
*/
|
*/
|
||||||
private static List<FileType> readFileTypes(String filePath) throws IOException, ParserConfigurationException, SAXException {
|
private static List<FileType> readFileTypes(String filePath) throws IOException, SAXException, ParserConfigurationException {
|
||||||
List<FileType> fileTypes = new ArrayList<>();
|
List<FileType> fileTypes = new ArrayList<>();
|
||||||
/*
|
/*
|
||||||
* RC: Commenting out the loadDocument overload that validates
|
* RC: Commenting out the loadDocument overload that validates
|
||||||
@ -453,7 +386,7 @@ final class UserDefinedFileTypesManager {
|
|||||||
NodeList fileTypeElems = fileTypesElem.getElementsByTagName(FILE_TYPE_TAG_NAME);
|
NodeList fileTypeElems = fileTypesElem.getElementsByTagName(FILE_TYPE_TAG_NAME);
|
||||||
for (int i = 0; i < fileTypeElems.getLength(); ++i) {
|
for (int i = 0; i < fileTypeElems.getLength(); ++i) {
|
||||||
Element fileTypeElem = (Element) fileTypeElems.item(i);
|
Element fileTypeElem = (Element) fileTypeElems.item(i);
|
||||||
FileType fileType = XmlReader.parseFileType(fileTypeElem);
|
FileType fileType = XMLDefinitionsReader.parseFileType(fileTypeElem);
|
||||||
fileTypes.add(fileType);
|
fileTypes.add(fileType);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -472,10 +405,10 @@ final class UserDefinedFileTypesManager {
|
|||||||
* @throws NumberFormatException
|
* @throws NumberFormatException
|
||||||
*/
|
*/
|
||||||
private static FileType parseFileType(Element fileTypeElem) throws IllegalArgumentException, NumberFormatException {
|
private static FileType parseFileType(Element fileTypeElem) throws IllegalArgumentException, NumberFormatException {
|
||||||
String mimeType = XmlReader.parseMimeType(fileTypeElem);
|
String mimeType = XMLDefinitionsReader.parseMimeType(fileTypeElem);
|
||||||
Signature signature = XmlReader.parseSignature(fileTypeElem);
|
Signature signature = XMLDefinitionsReader.parseSignature(fileTypeElem);
|
||||||
String filesSetName = XmlReader.parseInterestingFilesSet(fileTypeElem);
|
String filesSetName = XMLDefinitionsReader.parseInterestingFilesSet(fileTypeElem);
|
||||||
boolean alert = XmlReader.parseAlert(fileTypeElem);
|
boolean alert = XMLDefinitionsReader.parseAlert(fileTypeElem);
|
||||||
return new FileType(mimeType, signature, filesSetName, alert);
|
return new FileType(mimeType, signature, filesSetName, alert);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -573,7 +506,7 @@ final class UserDefinedFileTypesManager {
|
|||||||
* Private constructor suppresses creation of instanmces of this utility
|
* Private constructor suppresses creation of instanmces of this utility
|
||||||
* class.
|
* class.
|
||||||
*/
|
*/
|
||||||
private XmlReader() {
|
private XMLDefinitionsReader() {
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,45 @@
|
|||||||
|
/*
|
||||||
|
* 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 java.io.Serializable;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Settings object for user defined file types
|
||||||
|
*/
|
||||||
|
class UserDefinedFileTypesSettings implements Serializable {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
private List<FileType> userDefinedFileTypes;
|
||||||
|
|
||||||
|
UserDefinedFileTypesSettings(List<FileType> userDefinedFileTypes) {
|
||||||
|
this.userDefinedFileTypes = userDefinedFileTypes;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the list of file types contained within the settings
|
||||||
|
*
|
||||||
|
* @return the userDefinedFileTypes
|
||||||
|
*/
|
||||||
|
public List<FileType> getUserDefinedFileTypes() {
|
||||||
|
return userDefinedFileTypes;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -14,8 +14,8 @@ ArtifactSelectionDialog.selectAllButton.text=Select All
|
|||||||
ReportGenerationPanel.closeButton.text=Close
|
ReportGenerationPanel.closeButton.text=Close
|
||||||
ReportProgressPanel.reportLabel.text=reportLabel
|
ReportProgressPanel.reportLabel.text=reportLabel
|
||||||
ReportProgressPanel.pathLabel.text=pathLabel
|
ReportProgressPanel.pathLabel.text=pathLabel
|
||||||
ReportProgressPanel.separationLabel.text=-
|
ReportProgressPanel.separationLabel.text=:
|
||||||
ReportProgressPanel.processingLabel.text=processingLabel
|
ReportProgressPanel.statusMessageLabel.text=processingLabel
|
||||||
ReportGenerationPanel.titleLabel.text=Report Generation Progress
|
ReportGenerationPanel.titleLabel.text=Report Generation Progress
|
||||||
ReportVisualPanel2.taggedResultsRadioButton.text=Tagged Results
|
ReportVisualPanel2.taggedResultsRadioButton.text=Tagged Results
|
||||||
ReportVisualPanel2.allResultsRadioButton.text=All Results
|
ReportVisualPanel2.allResultsRadioButton.text=All Results
|
||||||
|
@ -1,247 +1,246 @@
|
|||||||
OpenIDE-Module-Name=\u30EC\u30DD\u30FC\u30C8
|
OpenIDE-Module-Name=\u30ec\u30dd\u30fc\u30c8
|
||||||
CTL_ReportWizardAction=\u30EC\u30DD\u30FC\u30C8\u3092\u5B9F\u884C
|
CTL_ReportWizardAction=\u30ec\u30dd\u30fc\u30c8\u3092\u5b9f\u884c
|
||||||
ArtifactSelectionDialog.titleLabel.text=\u3069\u306E\u30A2\u30FC\u30C6\u30A3\u30D5\u30A1\u30AF\u30C8\u306B\u3064\u3044\u3066\u30EC\u30DD\u30FC\u30C8\u3059\u308B\u304B\u9078\u629E\u3057\u3066\u4E0B\u3055\u3044\uFF1A
|
ArtifactSelectionDialog.titleLabel.text=\u3069\u306e\u30a2\u30fc\u30c6\u30a3\u30d5\u30a1\u30af\u30c8\u306b\u3064\u3044\u3066\u30ec\u30dd\u30fc\u30c8\u3059\u308b\u304b\u9078\u629e\u3057\u3066\u4e0b\u3055\u3044\uff1a
|
||||||
ArtifactSelectionDialog.okButton.text=OK
|
ArtifactSelectionDialog.okButton.text=OK
|
||||||
ReportVisualPanel1.reportModulesLabel.text=\u30EC\u30DD\u30FC\u30C8\u30E2\u30B8\u30E5\u30FC\u30EB\uFF1A
|
ReportVisualPanel1.reportModulesLabel.text=\u30ec\u30dd\u30fc\u30c8\u30e2\u30b8\u30e5\u30fc\u30eb\uff1a
|
||||||
DefaultReportConfigurationPanel.infoLabel.text=\u3053\u306E\u30EC\u30DD\u30FC\u30C8\u306F\u6B21\u306E\u30B9\u30AF\u30EA\u30FC\u30F3\u3067\u8A2D\u5B9A\u3055\u308C\u307E\u3059\u3002
|
DefaultReportConfigurationPanel.infoLabel.text=\u3053\u306e\u30ec\u30dd\u30fc\u30c8\u306f\u6b21\u306e\u30b9\u30af\u30ea\u30fc\u30f3\u3067\u8a2d\u5b9a\u3055\u308c\u307e\u3059\u3002
|
||||||
ReportVisualPanel2.dataLabel.text=\u3069\u306E\u30C7\u30FC\u30BF\u306B\u3064\u3044\u3066\u30EC\u30DD\u30FC\u30C8\u3059\u308B\u304B\u9078\u629E\u3057\u3066\u4E0B\u3055\u3044\uFF1A
|
ReportVisualPanel2.dataLabel.text=\u3069\u306e\u30c7\u30fc\u30bf\u306b\u3064\u3044\u3066\u30ec\u30dd\u30fc\u30c8\u3059\u308b\u304b\u9078\u629e\u3057\u3066\u4e0b\u3055\u3044\uff1a
|
||||||
ReportVisualPanel2.deselectAllButton.text=\u5168\u3066\u9078\u629E\u89E3\u9664
|
ReportVisualPanel2.deselectAllButton.text=\u5168\u3066\u9078\u629e\u89e3\u9664
|
||||||
ReportVisualPanel2.selectAllButton.text=\u5168\u3066\u9078\u629E
|
ReportVisualPanel2.selectAllButton.text=\u5168\u3066\u9078\u629e
|
||||||
ReportVisualPanel2.advancedButton.text=\u30C7\u30FC\u30BF\u30BF\u30A4\u30D7
|
ReportVisualPanel2.advancedButton.text=\u30c7\u30fc\u30bf\u30bf\u30a4\u30d7
|
||||||
ArtifactSelectionDialog.deselectAllButton.text=\u5168\u3066\u9078\u629E\u89E3\u9664
|
ArtifactSelectionDialog.deselectAllButton.text=\u5168\u3066\u9078\u629e\u89e3\u9664
|
||||||
ArtifactSelectionDialog.selectAllButton.text=\u5168\u3066\u9078\u629E
|
ArtifactSelectionDialog.selectAllButton.text=\u5168\u3066\u9078\u629e
|
||||||
ReportGenerationPanel.closeButton.text=\u9589\u3058\u308B
|
ReportGenerationPanel.closeButton.text=\u9589\u3058\u308b
|
||||||
ReportProgressPanel.reportLabel.text=\u30EC\u30DD\u30FC\u30C8\u30E9\u30D9\u30EB
|
ReportProgressPanel.reportLabel.text=\u30ec\u30dd\u30fc\u30c8\u30e9\u30d9\u30eb
|
||||||
ReportProgressPanel.pathLabel.text=\u30D1\u30B9\u30E9\u30D9\u30EB
|
ReportProgressPanel.pathLabel.text=\u30d1\u30b9\u30e9\u30d9\u30eb
|
||||||
ReportProgressPanel.separationLabel.text=-
|
ReportProgressPanel.separationLabel.text=:
|
||||||
ReportProgressPanel.processingLabel.text=\u30D7\u30ED\u30BB\u30B7\u30F3\u30B0\u30E9\u30D9\u30EB
|
ReportProgressPanel.statusMessageLabel.text=\u30d7\u30ed\u30bb\u30b7\u30f3\u30b0\u30e9\u30d9\u30eb
|
||||||
ReportGenerationPanel.titleLabel.text=\u30EC\u30DD\u30FC\u30C8\u751F\u6210\u30D7\u30ED\u30B0\u30EC\u30B9
|
ReportGenerationPanel.titleLabel.text=\u30ec\u30dd\u30fc\u30c8\u751f\u6210\u30d7\u30ed\u30b0\u30ec\u30b9
|
||||||
ReportVisualPanel2.taggedResultsRadioButton.text=\u30BF\u30B0\u3055\u308C\u305F\u7D50\u679C
|
ReportVisualPanel2.taggedResultsRadioButton.text=\u30bf\u30b0\u3055\u308c\u305f\u7d50\u679c
|
||||||
ReportVisualPanel2.allResultsRadioButton.text=\u5168\u3066\u306E\u7D50\u679C
|
ReportVisualPanel2.allResultsRadioButton.text=\u5168\u3066\u306e\u7d50\u679c
|
||||||
ReportWizardFileOptionsVisualPanel.selectAllButton.text=\u5168\u3066\u9078\u629E
|
ReportWizardFileOptionsVisualPanel.selectAllButton.text=\u5168\u3066\u9078\u629e
|
||||||
ReportWizardFileOptionsVisualPanel.deselectAllButton.text=\u5168\u3066\u9078\u629E\u89E3\u9664
|
ReportWizardFileOptionsVisualPanel.deselectAllButton.text=\u5168\u3066\u9078\u629e\u89e3\u9664
|
||||||
ReportWizardFileOptionsVisualPanel.jLabel1.text=\u30D5\u30A1\u30A4\u30EB\u30EC\u30DD\u30FC\u30C8\u306B\u542B\u3081\u308B\u30A2\u30A4\u30C6\u30E0\u3092\u9078\u629E\u3057\u3066\u4E0B\u3055\u3044\uFF1A
|
ReportWizardFileOptionsVisualPanel.jLabel1.text=\u30d5\u30a1\u30a4\u30eb\u30ec\u30dd\u30fc\u30c8\u306b\u542b\u3081\u308b\u30a2\u30a4\u30c6\u30e0\u3092\u9078\u629e\u3057\u3066\u4e0b\u3055\u3044\uff1a
|
||||||
ArtifactSelectionDialog.dlgTitle.text=\u30A2\u30C9\u30D0\u30F3\u30B9\u30A2\u30FC\u30C6\u30A3\u30D5\u30A1\u30AF\u30C8\u9078\u629E
|
ArtifactSelectionDialog.dlgTitle.text=\u30a2\u30c9\u30d0\u30f3\u30b9\u30a2\u30fc\u30c6\u30a3\u30d5\u30a1\u30af\u30c8\u9078\u629e
|
||||||
FileReportDataTypes.filename.text=\u540D\u524D
|
FileReportDataTypes.filename.text=\u540d\u524d
|
||||||
FileReportDataTypes.fileExt.text=\u30D5\u30A1\u30A4\u30EB\u62E1\u5F35\u5B50
|
FileReportDataTypes.fileExt.text=\u30d5\u30a1\u30a4\u30eb\u62e1\u5f35\u5b50
|
||||||
FileReportDataTypes.fileType.text=\u30D5\u30A1\u30A4\u30EB\u30BF\u30A4\u30D7
|
FileReportDataTypes.fileType.text=\u30d5\u30a1\u30a4\u30eb\u30bf\u30a4\u30d7
|
||||||
FileReportDataTypes.isDel.text=\u306F\u524A\u9664\u3055\u308C\u307E\u3057\u305F
|
FileReportDataTypes.isDel.text=\u306f\u524a\u9664\u3055\u308c\u307e\u3057\u305f
|
||||||
FileReportDataTypes.aTime.text=\u6700\u5F8C\u306E\u30A2\u30AF\u30BB\u30B9
|
FileReportDataTypes.aTime.text=\u6700\u5f8c\u306e\u30a2\u30af\u30bb\u30b9
|
||||||
FileReportDataTypes.crTime.text=\u4F5C\u6210\u3055\u308C\u305F\u30D5\u30A1\u30A4\u30EB
|
FileReportDataTypes.crTime.text=\u4f5c\u6210\u3055\u308c\u305f\u30d5\u30a1\u30a4\u30eb
|
||||||
FileReportDataTypes.mTime.text=\u6700\u5F8C\u306E\u4FEE\u6B63
|
FileReportDataTypes.mTime.text=\u6700\u5f8c\u306e\u4fee\u6b63
|
||||||
FileReportDataTypes.size.text=\u30B5\u30A4\u30BA
|
FileReportDataTypes.size.text=\u30b5\u30a4\u30ba
|
||||||
FileReportDataTypes.address.text=\u30A2\u30C9\u30EC\u30B9
|
FileReportDataTypes.address.text=\u30a2\u30c9\u30ec\u30b9
|
||||||
FileReportDataTypes.hash.text=\u30CF\u30C3\u30B7\u30E5\u5024
|
FileReportDataTypes.hash.text=\u30cf\u30c3\u30b7\u30e5\u5024
|
||||||
FileReportDataTypes.knownStatus.text=\u65E2\u77E5\u30B9\u30C6\u30FC\u30BF\u30B9
|
FileReportDataTypes.knownStatus.text=\u65e2\u77e5\u30b9\u30c6\u30fc\u30bf\u30b9
|
||||||
FileReportDataTypes.perms.text=\u30D1\u30FC\u30DF\u30C3\u30B7\u30E7\u30F3
|
FileReportDataTypes.perms.text=\u30d1\u30fc\u30df\u30c3\u30b7\u30e7\u30f3
|
||||||
FileReportDataTypes.path.text=\u30D5\u30EB\u30D1\u30B9
|
FileReportDataTypes.path.text=\u30d5\u30eb\u30d1\u30b9
|
||||||
FileReportText.getName.text=\u30D5\u30A1\u30A4\u30EB - \u30C6\u30AD\u30B9\u30C8
|
FileReportText.getName.text=\u30d5\u30a1\u30a4\u30eb - \u30c6\u30ad\u30b9\u30c8
|
||||||
FileReportText.getDesc.text=\u30B1\u30FC\u30B9\u306E\u500B\u5225\u30D5\u30A1\u30A4\u30EB\u306B\u3064\u3044\u3066\u306E\u60C5\u5831\u3092\u6301\u3064\u3001\u30BF\u30D6\u533A\u5207\u308A\u30C6\u30AD\u30B9\u30C8\u30D5\u30A1\u30A4\u30EB\u3002
|
FileReportText.getDesc.text=\u30b1\u30fc\u30b9\u306e\u500b\u5225\u30d5\u30a1\u30a4\u30eb\u306b\u3064\u3044\u3066\u306e\u60c5\u5831\u3092\u6301\u3064\u3001\u30bf\u30d6\u533a\u5207\u308a\u30c6\u30ad\u30b9\u30c8\u30d5\u30a1\u30a4\u30eb\u3002
|
||||||
ReportBodyFile.progress.querying=\u30D5\u30A1\u30A4\u30EB\u306E\u30AF\u30A8\u30EA\u3092\u5B9F\u884C\u4E2D\u2026
|
ReportBodyFile.progress.querying=\u30d5\u30a1\u30a4\u30eb\u306e\u30af\u30a8\u30ea\u3092\u5b9f\u884c\u4e2d\u2026
|
||||||
ReportBodyFile.ingestWarning.text=\u8B66\u544A\u3001\u30A4\u30F3\u30B8\u30A7\u30B9\u30C8\u30B5\u30FC\u30D3\u30B9\u304C\u5B8C\u4E86\u3059\u308B\u524D\u306B\u30EC\u30DD\u30FC\u30C8\u304C\u5B9F\u884C\u3055\u308C\u307E\u3057\u305F\uFF01
|
ReportBodyFile.ingestWarning.text=\u8b66\u544a\u3001\u30a4\u30f3\u30b8\u30a7\u30b9\u30c8\u30b5\u30fc\u30d3\u30b9\u304c\u5b8c\u4e86\u3059\u308b\u524d\u306b\u30ec\u30dd\u30fc\u30c8\u304c\u5b9f\u884c\u3055\u308c\u307e\u3057\u305f\uff01
|
||||||
ReportBodyFile.progress.loading=\u30D5\u30A1\u30A4\u30EB\u306E\u8AAD\u307F\u8FBC\u307F\u4E2D\u2026
|
ReportBodyFile.progress.loading=\u30d5\u30a1\u30a4\u30eb\u306e\u8aad\u307f\u8fbc\u307f\u4e2d\u2026
|
||||||
ReportBodyFile.progress.processing={0}\u3092\u51E6\u7406\u4E2D\u2026
|
ReportBodyFile.progress.processing={0}\u3092\u51e6\u7406\u4e2d\u2026
|
||||||
ReportBodyFile.getName.text=TSK\u30DC\u30C7\u30A3\u30D5\u30A1\u30A4\u30EB
|
ReportBodyFile.getName.text=TSK\u30dc\u30c7\u30a3\u30d5\u30a1\u30a4\u30eb
|
||||||
ReportBodyFile.getDesc.text=\u5404\u30D5\u30A1\u30A4\u30EB\u306EMAC\u30BF\u30A4\u30E0\u3092\u542B\u3080\u3001\u30DC\u30C7\u30A3\u30D5\u30A1\u30A4\u30EB\u5F62\u5F0F\u30EC\u30DD\u30FC\u30C8\u3002\u30BF\u30A4\u30E0\u30E9\u30A4\u30F3\u30D3\u30E5\u30FC\u306B\u3053\u306E\u5F62\u5F0F\u3092\u4F7F\u7528\u3067\u304D\u307E\u3059\u3002
|
ReportBodyFile.getDesc.text=\u5404\u30d5\u30a1\u30a4\u30eb\u306eMAC\u30bf\u30a4\u30e0\u3092\u542b\u3080\u3001\u30dc\u30c7\u30a3\u30d5\u30a1\u30a4\u30eb\u5f62\u5f0f\u30ec\u30dd\u30fc\u30c8\u3002\u30bf\u30a4\u30e0\u30e9\u30a4\u30f3\u30d3\u30e5\u30fc\u306b\u3053\u306e\u5f62\u5f0f\u3092\u4f7f\u7528\u3067\u304d\u307e\u3059\u3002
|
||||||
ReportBodyFile.getFilePath.text=BodyFile.txt
|
ReportBodyFile.getFilePath.text=BodyFile.txt
|
||||||
ReportBranding.defaultReportTitle.text=Autopsy\u30D5\u30A9\u30EC\u30F3\u30B8\u30C3\u30AF\u30EC\u30DD\u30FC\u30C8
|
ReportBranding.defaultReportTitle.text=Autopsy\u30d5\u30a9\u30ec\u30f3\u30b8\u30c3\u30af\u30ec\u30dd\u30fc\u30c8
|
||||||
ReportBranding.defaultReportFooter.text=Autopsy\u30AA\u30FC\u30D7\u30F3\u30BD\u30FC\u30B9\u30FB\u30C7\u30B8\u30BF\u30EB\u30FB\u30D5\u30A9\u30EC\u30F3\u30B8\u30C3\u30AF\u30FB\u30D7\u30E9\u30C3\u30C8\u30D5\u30A9\u30FC\u30E0\u306B\u3088\u308A\u63D0\u4F9B - www.sleuthkit.org
|
ReportBranding.defaultReportFooter.text=Autopsy\u30aa\u30fc\u30d7\u30f3\u30bd\u30fc\u30b9\u30fb\u30c7\u30b8\u30bf\u30eb\u30fb\u30d5\u30a9\u30ec\u30f3\u30b8\u30c3\u30af\u30fb\u30d7\u30e9\u30c3\u30c8\u30d5\u30a9\u30fc\u30e0\u306b\u3088\u308a\u63d0\u4f9b - www.sleuthkit.org
|
||||||
ReportExcel.numAartifacts.text=\u30A2\u30FC\u30C6\u30A3\u30D5\u30A1\u30AF\u30C8\u6570\uFF1A
|
ReportExcel.numAartifacts.text=\u30a2\u30fc\u30c6\u30a3\u30d5\u30a1\u30af\u30c8\u6570\uff1a
|
||||||
ReportExcel.getName.text=\u7D50\u679C - Excel
|
ReportExcel.getName.text=\u7d50\u679c - Excel
|
||||||
ReportExcel.getDesc.text=\u7D50\u679C\u306B\u95A2\u3059\u308B\u30EC\u30DD\u30FC\u30C8\u3002Excel(XLS)\u30D5\u30A9\u30FC\u30DE\u30C3\u30C8\u3067\u30A2\u30A4\u30C6\u30E0\u306E\u30BF\u30B0\u4ED8\u3051\u304C\u3055\u308C\u3066\u3044\u307E\u3059\u3002
|
ReportExcel.getDesc.text=\u7d50\u679c\u306b\u95a2\u3059\u308b\u30ec\u30dd\u30fc\u30c8\u3002Excel(XLS)\u30d5\u30a9\u30fc\u30de\u30c3\u30c8\u3067\u30a2\u30a4\u30c6\u30e0\u306e\u30bf\u30b0\u4ed8\u3051\u304c\u3055\u308c\u3066\u3044\u307e\u3059\u3002
|
||||||
ReportExcel.sheetName.text=\u30B5\u30DE\u30EA\u30FC
|
ReportExcel.sheetName.text=\u30b5\u30de\u30ea\u30fc
|
||||||
ReportExcel.cellVal.summary=\u30B5\u30DE\u30EA\u30FC
|
ReportExcel.cellVal.summary=\u30b5\u30de\u30ea\u30fc
|
||||||
ReportExcel.cellVal.caseName=\u30B1\u30FC\u30B9\u540D\uFF1A
|
ReportExcel.cellVal.caseName=\u30b1\u30fc\u30b9\u540d\uff1a
|
||||||
ReportExcel.cellVal.caseNum=\u30B1\u30FC\u30B9\u756A\u53F7\uFF1A
|
ReportExcel.cellVal.caseNum=\u30b1\u30fc\u30b9\u756a\u53f7\uff1a
|
||||||
ReportExcel.cellVal.examiner=\u8ABF\u67FB\u62C5\u5F53\u8005\uFF1A
|
ReportExcel.cellVal.examiner=\u8abf\u67fb\u62c5\u5f53\u8005\uff1a
|
||||||
ReportExcel.cellVal.numImages=\u30A4\u30E1\u30FC\u30B8\u6570\uFF1A
|
ReportExcel.cellVal.numImages=\u30a4\u30e1\u30fc\u30b8\u6570\uff1a
|
||||||
ReportGenerationPanel.confDlg.sureToClose.msg=\u3053\u306E\u30C0\u30A4\u30A2\u30ED\u30B0\u3092\u672C\u5F53\u306B\u9589\u3058\u307E\u3059\u304B\uFF1F\n\u5168\u3066\u306E\u30EC\u30DD\u30FC\u30C8\u304C\u30AD\u30E3\u30F3\u30BB\u30EB\u3055\u308C\u307E\u3059\u3002
|
ReportGenerationPanel.confDlg.sureToClose.msg=\u3053\u306e\u30c0\u30a4\u30a2\u30ed\u30b0\u3092\u672c\u5f53\u306b\u9589\u3058\u307e\u3059\u304b\uff1f\n\u5168\u3066\u306e\u30ec\u30dd\u30fc\u30c8\u304c\u30ad\u30e3\u30f3\u30bb\u30eb\u3055\u308c\u307e\u3059\u3002
|
||||||
ReportGenerationPanel.confDlg.title.closing=\u9589\u3058\u3066\u3044\u307E\u3059
|
ReportGenerationPanel.confDlg.title.closing=\u9589\u3058\u3066\u3044\u307e\u3059
|
||||||
ReportGenerator.displayProgress.title.text=\u30EC\u30DD\u30FC\u30C8\u751F\u6210\u30D7\u30ED\u30B0\u30EC\u30B9\u2026
|
ReportGenerator.displayProgress.title.text=\u30ec\u30dd\u30fc\u30c8\u751f\u6210\u30d7\u30ed\u30b0\u30ec\u30b9\u2026
|
||||||
ReportGenerator.progress.queryingDb.text=\u30C7\u30FC\u30BF\u30D9\u30FC\u30B9\u306E\u30AF\u30A8\u30EA\u3092\u5B9F\u884C\u4E2D\u2026
|
ReportGenerator.progress.queryingDb.text=\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u306e\u30af\u30a8\u30ea\u3092\u5b9f\u884c\u4e2d\u2026
|
||||||
ReportGenerator.progress.processingFile.text={0}\u3092\u51E6\u7406\u4E2D
|
ReportGenerator.progress.processingFile.text={0}\u3092\u51e6\u7406\u4e2d
|
||||||
ReportGenerator.artifactTable.taggedResults.text=\u6B21\u306E\u4E2D\u306E\u4E00\u3064\u3067\u30BF\u30B0\u3055\u308C\u305F\u7D50\u679C\u304C\u542B\u307E\u308C\u3066\u3044\u307E\u3059\uFF1A
|
ReportGenerator.artifactTable.taggedResults.text=\u6b21\u306e\u4e2d\u306e\u4e00\u3064\u3067\u30bf\u30b0\u3055\u308c\u305f\u7d50\u679c\u304c\u542b\u307e\u308c\u3066\u3044\u307e\u3059\uff1a
|
||||||
ReportGenerator.progress.processing={0}\u3092\u51E6\u7406\u4E2D\u2026
|
ReportGenerator.progress.processing={0}\u3092\u51e6\u7406\u4e2d\u2026
|
||||||
ReportGenerator.msgShow.skippingArtType.title=\u30A2\u30FC\u30C6\u30A3\u30D5\u30A1\u30AF\u30C8\u30BF\u30A4\u30D7{0}\u3092\u30EC\u30DD\u30FC\u30C8\u3067\u30B9\u30AD\u30C3\u30D7\u3057\u3066\u3044\u307E\u3059
|
ReportGenerator.msgShow.skippingArtType.title=\u30a2\u30fc\u30c6\u30a3\u30d5\u30a1\u30af\u30c8\u30bf\u30a4\u30d7{0}\u3092\u30ec\u30dd\u30fc\u30c8\u3067\u30b9\u30ad\u30c3\u30d7\u3057\u3066\u3044\u307e\u3059
|
||||||
ReportGenerator.msgShow.skippingArtType.msg=\u30EC\u30DD\u30FC\u30C8\u751F\u6210\u3059\u308B\u306E\u306B\u4E0D\u660E\u306A\u30B3\u30E9\u30E0
|
ReportGenerator.msgShow.skippingArtType.msg=\u30ec\u30dd\u30fc\u30c8\u751f\u6210\u3059\u308b\u306e\u306b\u4e0d\u660e\u306a\u30b3\u30e9\u30e0
|
||||||
ReportGenerator.msgShow.skippingArtRow.title=\u30BF\u30A4\u30D7{0}\u306E\u30A2\u30FC\u30C6\u30A3\u30D5\u30A1\u30AF\u30C8\u884C\u3092\u30EC\u30DD\u30FC\u30C8\u3067\u30B9\u30AD\u30C3\u30D7\u3057\u3066\u3044\u307E\u3059
|
ReportGenerator.msgShow.skippingArtRow.title=\u30bf\u30a4\u30d7{0}\u306e\u30a2\u30fc\u30c6\u30a3\u30d5\u30a1\u30af\u30c8\u884c\u3092\u30ec\u30dd\u30fc\u30c8\u3067\u30b9\u30ad\u30c3\u30d7\u3057\u3066\u3044\u307e\u3059
|
||||||
ReportGenerator.msgShow.skippingArtRow.msg=\u30EC\u30DD\u30FC\u30C8\u751F\u6210\u3059\u308B\u306E\u306B\u4E0D\u660E\u306A\u30B3\u30E9\u30E0
|
ReportGenerator.msgShow.skippingArtRow.msg=\u30ec\u30dd\u30fc\u30c8\u751f\u6210\u3059\u308b\u306e\u306b\u4e0d\u660e\u306a\u30b3\u30e9\u30e0
|
||||||
ReportGenerator.makeContTagTab.taggedFiles.msg=\u306E\u4E2D\u306E\u4E00\u3064\u3067\u30BF\u30B0\u3055\u308C\u305F\u7D50\u679C\u304C\u542B\u307E\u308C\u3066\u3044\u307E\u3059\uFF1A
|
ReportGenerator.makeContTagTab.taggedFiles.msg=\u306e\u4e2d\u306e\u4e00\u3064\u3067\u30bf\u30b0\u3055\u308c\u305f\u7d50\u679c\u304c\u542b\u307e\u308c\u3066\u3044\u307e\u3059\uff1a
|
||||||
ReportGenerator.makeBbArtTagTab.taggedRes.msg=\u3053\u306E\u30EC\u30DD\u30FC\u30C8\u306B\u306F\u6B21\u3067\u30BF\u30B0\u3055\u308C\u305F\u7D50\u679C\u3057\u304B\u542B\u307E\u308C\u307E\u305B\u3093\uFF1A
|
ReportGenerator.makeBbArtTagTab.taggedRes.msg=\u3053\u306e\u30ec\u30dd\u30fc\u30c8\u306b\u306f\u6b21\u3067\u30bf\u30b0\u3055\u308c\u305f\u7d50\u679c\u3057\u304b\u542b\u307e\u308c\u307e\u305b\u3093\uff1a
|
||||||
ReportGenerator.tagTable.header.resultType=\u7D50\u679C\u30BF\u30A4\u30D7
|
ReportGenerator.tagTable.header.resultType=\u7d50\u679c\u30bf\u30a4\u30d7
|
||||||
ReportGenerator.tagTable.header.tag=\u30BF\u30B0
|
ReportGenerator.tagTable.header.tag=\u30bf\u30b0
|
||||||
ReportGenerator.tagTable.header.comment=\u30B3\u30E1\u30F3\u30C8
|
ReportGenerator.tagTable.header.comment=\u30b3\u30e1\u30f3\u30c8
|
||||||
ReportGenerator.tagTable.header.srcFile=\u30BD\u30FC\u30B9\u30D5\u30A1\u30A4\u30EB
|
ReportGenerator.tagTable.header.srcFile=\u30bd\u30fc\u30b9\u30d5\u30a1\u30a4\u30eb
|
||||||
ReportGenerator.progress.createdThumb.text=\u30B5\u30E0\u30CD\u30A4\u30EB\u3092\u4F5C\u6210\u4E2D\u2026
|
ReportGenerator.progress.createdThumb.text=\u30b5\u30e0\u30cd\u30a4\u30eb\u3092\u4f5c\u6210\u4e2d\u2026
|
||||||
ReportGenerator.thumbnailTable.name=\u30B5\u30E0\u30CD\u30A4\u30EB
|
ReportGenerator.thumbnailTable.name=\u30b5\u30e0\u30cd\u30a4\u30eb
|
||||||
ReportGenerator.thumbnailTable.desc=\u30BF\u30B0\u3055\u308C\u305F\u30D5\u30A1\u30A4\u30EB\u3084\u7D50\u679C\u306B\u95A2\u9023\u3059\u308B\u30A4\u30E1\u30FC\u30B8\u306E\u30B5\u30E0\u30CD\u30A4\u30EB\u304C\u542B\u307E\u308C\u307E\u3059\u3002
|
ReportGenerator.thumbnailTable.desc=\u30bf\u30b0\u3055\u308c\u305f\u30d5\u30a1\u30a4\u30eb\u3084\u7d50\u679c\u306b\u95a2\u9023\u3059\u308b\u30a4\u30e1\u30fc\u30b8\u306e\u30b5\u30e0\u30cd\u30a4\u30eb\u304c\u542b\u307e\u308c\u307e\u3059\u3002
|
||||||
ReportGenerator.writeKwHits.userSrchs=\u30E6\u30FC\u30B6\u691C\u7D22
|
ReportGenerator.writeKwHits.userSrchs=\u30e6\u30fc\u30b6\u691c\u7d22
|
||||||
ReportGenerator.progress.processingList={0} ({1})\u3092\u51E6\u7406\u4E2D\u2026
|
ReportGenerator.progress.processingList={0} ({1})\u3092\u51e6\u7406\u4e2d\u2026
|
||||||
ReportGenerator.artTableColHdr.url=URL
|
ReportGenerator.artTableColHdr.url=URL
|
||||||
ReportGenerator.artTableColHdr.title=\u30BF\u30A4\u30C8\u30EB
|
ReportGenerator.artTableColHdr.title=\u30bf\u30a4\u30c8\u30eb
|
||||||
ReportGenerator.artTableColHdr.dateCreated=\u4F5C\u6210\u65E5\u4ED8
|
ReportGenerator.artTableColHdr.dateCreated=\u4f5c\u6210\u65e5\u4ed8
|
||||||
ReportGenerator.artTableColHdr.program=\u30D7\u30ED\u30B0\u30E9\u30E0
|
ReportGenerator.artTableColHdr.program=\u30d7\u30ed\u30b0\u30e9\u30e0
|
||||||
ReportGenerator.artTableColHdr.srcFile=\u30BD\u30FC\u30B9\u30D5\u30A1\u30A4\u30EB
|
ReportGenerator.artTableColHdr.srcFile=\u30bd\u30fc\u30b9\u30d5\u30a1\u30a4\u30eb
|
||||||
ReportGenerator.artTableColHdr.dateTime=\u65E5\u4ED8\uFF0F\u6642\u523B
|
ReportGenerator.artTableColHdr.dateTime=\u65e5\u4ed8\uff0f\u6642\u523b
|
||||||
ReportGenerator.artTableColHdr.name=\u540D\u524D
|
ReportGenerator.artTableColHdr.name=\u540d\u524d
|
||||||
ReportGenerator.artTableColHdr.value=\u30D0\u30EA\u30E5\u30FC
|
ReportGenerator.artTableColHdr.value=\u30d0\u30ea\u30e5\u30fc
|
||||||
ReportGenerator.artTableColHdr.dateAccessed=\u30A2\u30AF\u30BB\u30B9\u65E5\u4ED8
|
ReportGenerator.artTableColHdr.dateAccessed=\u30a2\u30af\u30bb\u30b9\u65e5\u4ed8
|
||||||
ReportGenerator.artTableColHdr.referrer=\u30EA\u30D5\u30A1\u30E9
|
ReportGenerator.artTableColHdr.referrer=\u30ea\u30d5\u30a1\u30e9
|
||||||
ReportGenerator.artTableColHdr.dest=\u30C7\u30B9\u30C6\u30A3\u30CD\u30FC\u30B7\u30E7\u30F3
|
ReportGenerator.artTableColHdr.dest=\u30c7\u30b9\u30c6\u30a3\u30cd\u30fc\u30b7\u30e7\u30f3
|
||||||
ReportGenerator.artTableColHdr.sourceUrl=\u30BD\u30FC\u30B9URL
|
ReportGenerator.artTableColHdr.sourceUrl=\u30bd\u30fc\u30b9URL
|
||||||
ReportGenerator.artTableColHdr.path=\u30D1\u30B9
|
ReportGenerator.artTableColHdr.path=\u30d1\u30b9
|
||||||
ReportGenerator.artTableColHdr.progName=\u30D7\u30ED\u30B0\u30E9\u30E0\u540D
|
ReportGenerator.artTableColHdr.progName=\u30d7\u30ed\u30b0\u30e9\u30e0\u540d
|
||||||
ReportGenerator.artTableColHdr.instDateTime=\u30A4\u30F3\u30B9\u30C8\u30FC\u30EB\u65E5\u4ED8\uFF0F\u6642\u523B
|
ReportGenerator.artTableColHdr.instDateTime=\u30a4\u30f3\u30b9\u30c8\u30fc\u30eb\u65e5\u4ed8\uff0f\u6642\u523b
|
||||||
ReportGenerator.artTableColHdr.preview=\u30D7\u30EC\u30D3\u30E5\u30FC
|
ReportGenerator.artTableColHdr.preview=\u30d7\u30ec\u30d3\u30e5\u30fc
|
||||||
ReportGenerator.artTableColHdr.file=\u30D5\u30A1\u30A4\u30EB
|
ReportGenerator.artTableColHdr.file=\u30d5\u30a1\u30a4\u30eb
|
||||||
ReportGenerator.artTableColHdr.size=\u30B5\u30A4\u30BA
|
ReportGenerator.artTableColHdr.size=\u30b5\u30a4\u30ba
|
||||||
ReportGenerator.artTableColHdr.deviceId=\u6A5F\u5668ID
|
ReportGenerator.artTableColHdr.deviceId=\u6a5f\u5668ID
|
||||||
ReportGenerator.artTableColHdr.text=\u30C6\u30AD\u30B9\u30C8
|
ReportGenerator.artTableColHdr.text=\u30c6\u30ad\u30b9\u30c8
|
||||||
ReportGenerator.artTableColHdr.domain=\u30C9\u30E1\u30A4\u30F3
|
ReportGenerator.artTableColHdr.domain=\u30c9\u30e1\u30a4\u30f3
|
||||||
ReportGenerator.artTableColHdr.devManufacturer=\u6A5F\u5668\u30E1\u30FC\u30AB\u30FC
|
ReportGenerator.artTableColHdr.devManufacturer=\u6a5f\u5668\u30e1\u30fc\u30ab\u30fc
|
||||||
ReportGenerator.artTableColHdr.devModel=\u6A5F\u5668\u30E2\u30C7\u30EB
|
ReportGenerator.artTableColHdr.devModel=\u6a5f\u5668\u30e2\u30c7\u30eb
|
||||||
ReportGenerator.artTableColHdr.personName=\u4EBA\u540D
|
ReportGenerator.artTableColHdr.personName=\u4eba\u540d
|
||||||
ReportGenerator.artTableColHdr.phoneNumber=\u96FB\u8A71\u756A\u53F7
|
ReportGenerator.artTableColHdr.phoneNumber=\u96fb\u8a71\u756a\u53f7
|
||||||
ReportGenerator.artTableColHdr.phoneNumHome=\u96FB\u8A71\u756A\u53F7\uFF08\u81EA\u5B85\uFF09
|
ReportGenerator.artTableColHdr.phoneNumHome=\u96fb\u8a71\u756a\u53f7\uff08\u81ea\u5b85\uff09
|
||||||
ReportGenerator.artTableColHdr.phoneNumOffice=\u96FB\u8A71\u756A\u53F7\uFF08\u4F1A\u793E\uFF09
|
ReportGenerator.artTableColHdr.phoneNumOffice=\u96fb\u8a71\u756a\u53f7\uff08\u4f1a\u793e\uff09
|
||||||
ReportGenerator.artTableColHdr.phoneNumMobile=\u96FB\u8A71\u756A\u53F7\uFF08\u643A\u5E2F\uFF09
|
ReportGenerator.artTableColHdr.phoneNumMobile=\u96fb\u8a71\u756a\u53f7\uff08\u643a\u5e2f\uff09
|
||||||
ReportGenerator.artTableColHdr.email=Email
|
ReportGenerator.artTableColHdr.email=Email
|
||||||
ReportGenerator.artTableColHdr.msgType=\u30E1\u30C3\u30BB\u30FC\u30B8\u30BF\u30A4\u30D7
|
ReportGenerator.artTableColHdr.msgType=\u30e1\u30c3\u30bb\u30fc\u30b8\u30bf\u30a4\u30d7
|
||||||
ReportGenerator.artTableColHdr.latitude=\u7DEF\u5EA6
|
ReportGenerator.artTableColHdr.latitude=\u7def\u5ea6
|
||||||
ReportGenerator.artTableColHdr.longitude=\u7D4C\u5EA6
|
ReportGenerator.artTableColHdr.longitude=\u7d4c\u5ea6
|
||||||
ReportGenerator.artTableColHdr.dateTaken=\u64AE\u5F71\u65E5\u4ED8
|
ReportGenerator.artTableColHdr.dateTaken=\u64ae\u5f71\u65e5\u4ed8
|
||||||
ReportGenerator.artTableColHdr.subject=\u30B5\u30D6\u30B8\u30A7\u30AF\u30C8
|
ReportGenerator.artTableColHdr.subject=\u30b5\u30d6\u30b8\u30a7\u30af\u30c8
|
||||||
ReportGenerator.artTableColHdr.calendarEntryType=\u30AB\u30EC\u30F3\u30C0\u30FC\u30A8\u30F3\u30C8\u30EA\u30BF\u30A4\u30D7
|
ReportGenerator.artTableColHdr.calendarEntryType=\u30ab\u30ec\u30f3\u30c0\u30fc\u30a8\u30f3\u30c8\u30ea\u30bf\u30a4\u30d7
|
||||||
ReportGenerator.artTableColHdr.description=\u8AAC\u660E
|
ReportGenerator.artTableColHdr.description=\u8aac\u660e
|
||||||
ReportGenerator.artTableColHdr.startDateTime=\u958B\u59CB\u65E5\u4ED8\uFF0F\u6642\u523B
|
ReportGenerator.artTableColHdr.startDateTime=\u958b\u59cb\u65e5\u4ed8\uff0f\u6642\u523b
|
||||||
ReportGenerator.artTableColHdr.shortCut=\u30B7\u30E7\u30FC\u30C8\u30AB\u30C3\u30C8
|
ReportGenerator.artTableColHdr.shortCut=\u30b7\u30e7\u30fc\u30c8\u30ab\u30c3\u30c8
|
||||||
ReportGenerator.artTableColHdr.endDateTime=\u4FEE\u4E86\u65E5\u4ED8\uFF0F\u6642\u523B
|
ReportGenerator.artTableColHdr.endDateTime=\u4fee\u4e86\u65e5\u4ed8\uff0f\u6642\u523b
|
||||||
ReportGenerator.artTableColHdr.location=\u30ED\u30B1\u30FC\u30B7\u30E7\u30F3
|
ReportGenerator.artTableColHdr.location=\u30ed\u30b1\u30fc\u30b7\u30e7\u30f3
|
||||||
ReportGenerator.artTableColHdr.deviceName=\u6A5F\u5668\u540D
|
ReportGenerator.artTableColHdr.deviceName=\u6a5f\u5668\u540d
|
||||||
ReportGenerator.artTableColHdr.deviceAddress=\u6A5F\u5668\u30A2\u30C9\u30EC\u30B9
|
ReportGenerator.artTableColHdr.deviceAddress=\u6a5f\u5668\u30a2\u30c9\u30ec\u30b9
|
||||||
ReportGenerator.artTableColHdr.altitude=\u6A19\u9AD8
|
ReportGenerator.artTableColHdr.altitude=\u6a19\u9ad8
|
||||||
ReportGenerator.artTableColHdr.locationAddress=\u30ED\u30B1\u30FC\u30B7\u30E7\u30F3\u30A2\u30C9\u30EC\u30B9
|
ReportGenerator.artTableColHdr.locationAddress=\u30ed\u30b1\u30fc\u30b7\u30e7\u30f3\u30a2\u30c9\u30ec\u30b9
|
||||||
ReportGenerator.artTableColHdr.category=\u30AB\u30C6\u30B4\u30EA\u30FC
|
ReportGenerator.artTableColHdr.category=\u30ab\u30c6\u30b4\u30ea\u30fc
|
||||||
ReportGenerator.artTableColHdr.userId=\u30E6\u30FC\u30B6ID
|
ReportGenerator.artTableColHdr.userId=\u30e6\u30fc\u30b6ID
|
||||||
ReportGenerator.artTableColHdr.password=\u30D1\u30B9\u30EF\u30FC\u30C9
|
ReportGenerator.artTableColHdr.password=\u30d1\u30b9\u30ef\u30fc\u30c9
|
||||||
ReportGenerator.artTableColHdr.replytoAddress=\u8FD4\u4FE1\u30A2\u30C9\u30EC\u30B9
|
ReportGenerator.artTableColHdr.replytoAddress=\u8fd4\u4fe1\u30a2\u30c9\u30ec\u30b9
|
||||||
ReportGenerator.artTableColHdr.mailServer=\u30E1\u30FC\u30EB\u30B5\u30FC\u30D0
|
ReportGenerator.artTableColHdr.mailServer=\u30e1\u30fc\u30eb\u30b5\u30fc\u30d0
|
||||||
ReportGenerator.artTableColHdr.tags=\u30BF\u30B0
|
ReportGenerator.artTableColHdr.tags=\u30bf\u30b0
|
||||||
ReportHTML.addThumbRows.dataType.title=\u30BF\u30B0\u4ED8\u3051\u3055\u308C\u305F\u30A4\u30E1\u30FC\u30B8 - {0}
|
ReportHTML.addThumbRows.dataType.title=\u30bf\u30b0\u4ed8\u3051\u3055\u308c\u305f\u30a4\u30e1\u30fc\u30b8 - {0}
|
||||||
ReportHTML.addThumbRows.dataType.msg=\u30A4\u30E1\u30FC\u30B8\u3092\u542B\u3080\u30BF\u30B0\u4ED8\u3051\u3055\u308C\u305F\u7D50\u679C\u304A\u3088\u3073\u30B3\u30F3\u30C6\u30F3\u30C4\u3002
|
ReportHTML.addThumbRows.dataType.msg=\u30a4\u30e1\u30fc\u30b8\u3092\u542b\u3080\u30bf\u30b0\u4ed8\u3051\u3055\u308c\u305f\u7d50\u679c\u304a\u3088\u3073\u30b3\u30f3\u30c6\u30f3\u30c4\u3002
|
||||||
ReportHTML.thumbLink.tags=\u30BF\u30B0\uFF1A
|
ReportHTML.thumbLink.tags=\u30bf\u30b0\uff1a
|
||||||
ReportHTML.getName.text=\u7D50\u679C - HTML
|
ReportHTML.getName.text=\u7d50\u679c - HTML
|
||||||
ReportHTML.getDesc.text=HTML\u5F62\u5F0F\u306E\u7D50\u679C\u304A\u3088\u3073\u30BF\u30B0\u4ED8\u3051\u3055\u308C\u305F\u30A2\u30A4\u30C6\u30E0\u306E\u30EC\u30DD\u30FC\u30C8
|
ReportHTML.getDesc.text=HTML\u5f62\u5f0f\u306e\u7d50\u679c\u304a\u3088\u3073\u30bf\u30b0\u4ed8\u3051\u3055\u308c\u305f\u30a2\u30a4\u30c6\u30e0\u306e\u30ec\u30dd\u30fc\u30c8
|
||||||
ReportHTML.writeIndex.title=\u30B1\u30FC\u30B9{0}\u306EAutopsy\u30EC\u30DD\u30FC\u30C8
|
ReportHTML.writeIndex.title=\u30b1\u30fc\u30b9{0}\u306eAutopsy\u30ec\u30dd\u30fc\u30c8
|
||||||
ReportHTML.writeNav.title=\u30EC\u30DD\u30FC\u30C8\u30CA\u30D3\u30B2\u30FC\u30B7\u30E7\u30F3
|
ReportHTML.writeNav.title=\u30ec\u30dd\u30fc\u30c8\u30ca\u30d3\u30b2\u30fc\u30b7\u30e7\u30f3
|
||||||
ReportHTML.writeNav.h1=\u30EC\u30DD\u30FC\u30C8\u30CA\u30D3\u30B2\u30FC\u30B7\u30E7\u30F3
|
ReportHTML.writeNav.h1=\u30ec\u30dd\u30fc\u30c8\u30ca\u30d3\u30b2\u30fc\u30b7\u30e7\u30f3
|
||||||
ReportHTML.writeNav.summary=\u30B1\u30FC\u30B9\u30B5\u30DE\u30EA\u30FC
|
ReportHTML.writeNav.summary=\u30b1\u30fc\u30b9\u30b5\u30de\u30ea\u30fc
|
||||||
ReportHTML.writeSum.title=\u30B1\u30FC\u30B9\u30B5\u30DE\u30EA\u30FC
|
ReportHTML.writeSum.title=\u30b1\u30fc\u30b9\u30b5\u30de\u30ea\u30fc
|
||||||
ReportHTML.writeSum.caseName=\u30B1\u30FC\u30B9\uFF1A
|
ReportHTML.writeSum.caseName=\u30b1\u30fc\u30b9\uff1a
|
||||||
ReportHTML.writeSum.caseNum=\u30B1\u30FC\u30B9\u756A\u53F7\uFF1A
|
ReportHTML.writeSum.caseNum=\u30b1\u30fc\u30b9\u756a\u53f7\uff1a
|
||||||
ReportHTML.writeSum.examiner=\u8ABF\u67FB\u62C5\u5F53\u8005\uFF1A
|
ReportHTML.writeSum.examiner=\u8abf\u67fb\u62c5\u5f53\u8005\uff1a
|
||||||
ReportHTML.writeSum.numImages=\u30A4\u30E1\u30FC\u30B8\u6570\uFF1A
|
ReportHTML.writeSum.numImages=\u30a4\u30e1\u30fc\u30b8\u6570\uff1a
|
||||||
ReportHTML.writeSum.path=\u30D1\u30B9\uFF1A
|
ReportHTML.writeSum.path=\u30d1\u30b9\uff1a
|
||||||
ReportProgressPanel.start.cancelButton.text=\u30AD\u30E3\u30F3\u30BB\u30EB
|
ReportProgressPanel.start.cancelButton.text=\u30ad\u30e3\u30f3\u30bb\u30eb
|
||||||
ReportProgressPanel.complete.processLbl.text=\u5B8C\u4E86
|
ReportProgressPanel.complete.processLbl.text=\u5b8c\u4e86
|
||||||
ReportProgressPanel.complete.cancelButton.text=\u5B8C\u4E86
|
ReportProgressPanel.complete.cancelButton.text=\u5b8c\u4e86
|
||||||
ReportProgressPanel.cancel.cancelButton.toolTipText=\u30AD\u30E3\u30F3\u30BB\u30EB\u3055\u308C\u307E\u3057\u305F
|
ReportProgressPanel.cancel.cancelButton.toolTipText=\u30ad\u30e3\u30f3\u30bb\u30eb\u3055\u308c\u307e\u3057\u305f
|
||||||
ReportWizardAction.actionName.text=\u30EC\u30DD\u30FC\u30C8\u3092\u751F\u6210
|
ReportWizardAction.actionName.text=\u30ec\u30dd\u30fc\u30c8\u3092\u751f\u6210
|
||||||
ReportWizardAction.reportWiz.title=\u30EC\u30DD\u30FC\u30C8\u3092\u751F\u6210
|
ReportWizardAction.reportWiz.title=\u30ec\u30dd\u30fc\u30c8\u3092\u751f\u6210
|
||||||
ReportWizardAction.toolBarButton.text=\u30EC\u30DD\u30FC\u30C8\u3092\u751F\u6210
|
ReportWizardAction.toolBarButton.text=\u30ec\u30dd\u30fc\u30c8\u3092\u751f\u6210
|
||||||
ReportWizardPanel1.nextButton.text=\u6B21 >
|
ReportWizardPanel1.nextButton.text=\u6b21 >
|
||||||
ReportWizardPanel2.nextButton.text=\u6B21 >
|
ReportWizardPanel2.nextButton.text=\u6b21 >
|
||||||
ReportGenerator.artTableColHdr.direction=\u65B9\u5411
|
ReportGenerator.artTableColHdr.direction=\u65b9\u5411
|
||||||
ReportGenerator.artTableColHdr.fromEmail=\u9001\u4FE1\u5143E\u30E1\u30FC\u30EB
|
ReportGenerator.artTableColHdr.fromEmail=\u9001\u4fe1\u5143E\u30e1\u30fc\u30eb
|
||||||
ReportGenerator.artTableColHdr.toEmail=\u9001\u4FE1\u5148E\u30E1\u30FC\u30EB
|
ReportGenerator.artTableColHdr.toEmail=\u9001\u4fe1\u5148E\u30e1\u30fc\u30eb
|
||||||
ReportGenerator.artTableColHdr.fromPhoneNum=\u767A\u4FE1\u8005\u96FB\u8A71\u756A\u53F7
|
ReportGenerator.artTableColHdr.fromPhoneNum=\u767a\u4fe1\u8005\u96fb\u8a71\u756a\u53f7
|
||||||
ReportGenerator.artTableColHdr.toPhoneNum=\u7740\u4FE1\u8005\u96FB\u8A71\u756A\u53F7
|
ReportGenerator.artTableColHdr.toPhoneNum=\u7740\u4fe1\u8005\u96fb\u8a71\u756a\u53f7
|
||||||
ReportGenerator.artTableColHdr.appName=\u30A2\u30D7\u30EA\u30B1\u30FC\u30B7\u30E7\u30F3\u540D
|
ReportGenerator.artTableColHdr.appName=\u30a2\u30d7\u30ea\u30b1\u30fc\u30b7\u30e7\u30f3\u540d
|
||||||
ReportGenerator.artTableColHdr.appPath=\u30A2\u30D7\u30EA\u30B1\u30FC\u30B7\u30E7\u30F3\u30D1\u30B9
|
ReportGenerator.artTableColHdr.appPath=\u30a2\u30d7\u30ea\u30b1\u30fc\u30b7\u30e7\u30f3\u30d1\u30b9
|
||||||
ReportHTML.writeIndex.noFrames.msg=\u4F7F\u7528\u3057\u3066\u3044\u308B\u30D6\u30E9\u30A6\u30B6\u306F\u5F0A\u793E\u306E\u30D5\u30EC\u30FC\u30E0\u30BB\u30C3\u30C8\u30A2\u30C3\u30D7\u3068\u306E\u4E92\u63DB\u6027\u304C\u3042\u308A\u307E\u305B\u3093\u3002
|
ReportHTML.writeIndex.noFrames.msg=\u4f7f\u7528\u3057\u3066\u3044\u308b\u30d6\u30e9\u30a6\u30b6\u306f\u5f0a\u793e\u306e\u30d5\u30ec\u30fc\u30e0\u30bb\u30c3\u30c8\u30a2\u30c3\u30d7\u3068\u306e\u4e92\u63db\u6027\u304c\u3042\u308a\u307e\u305b\u3093\u3002
|
||||||
ReportHTML.writeIndex.noFrames.seeNav=\u30A2\u30FC\u30C6\u30A3\u30D5\u30A1\u30AF\u30C8\u30EA\u30F3\u30AF\u306F\u4E0B\u8A18\u306E\u30CA\u30D3\u30B2\u30FC\u30B7\u30E7\u30F3\u30DA\u30FC\u30B8</a>\u3092\u3054\u89A7\u4E0B\u3055\u3044<a href\="nav.html">
|
ReportHTML.writeIndex.noFrames.seeNav=\u30a2\u30fc\u30c6\u30a3\u30d5\u30a1\u30af\u30c8\u30ea\u30f3\u30af\u306f\u4e0b\u8a18\u306e\u30ca\u30d3\u30b2\u30fc\u30b7\u30e7\u30f3\u30da\u30fc\u30b8</a>\u3092\u3054\u89a7\u4e0b\u3055\u3044<a href\="nav.html">
|
||||||
ReportHTML.writeIndex.seeSum=\u307E\u305F\u3001\u30B1\u30FC\u30B9\u30B5\u30DE\u30EA\u30FC\u306F\u4E0B\u8A18\u306E\u30B5\u30DE\u30EA\u30FC\u30DA\u30FC\u30B8</a>\u3092\u3054\u89A7\u4E0B\u3055\u3044\u3002<a href\="summary.html">
|
ReportHTML.writeIndex.seeSum=\u307e\u305f\u3001\u30b1\u30fc\u30b9\u30b5\u30de\u30ea\u30fc\u306f\u4e0b\u8a18\u306e\u30b5\u30de\u30ea\u30fc\u30da\u30fc\u30b8</a>\u3092\u3054\u89a7\u4e0b\u3055\u3044\u3002<a href\="summary.html">
|
||||||
ReportHTML.writeSum.warningMsg=<span>\u8B66\u544A\u3001\u30A4\u30F3\u30B8\u30A7\u30B9\u30C8\u30B5\u30FC\u30D3\u30B9\u304C\u5B8C\u4E86\u3059\u308B\u524D\u306B\u30EC\u30DD\u30FC\u30C8\u304C\u5B9F\u884C\u3055\u308C\u307E\u3057\u305F\uFF01</span>
|
ReportHTML.writeSum.warningMsg=<span>\u8b66\u544a\u3001\u30a4\u30f3\u30b8\u30a7\u30b9\u30c8\u30b5\u30fc\u30d3\u30b9\u304c\u5b8c\u4e86\u3059\u308b\u524d\u306b\u30ec\u30dd\u30fc\u30c8\u304c\u5b9f\u884c\u3055\u308c\u307e\u3057\u305f\uff01</span>
|
||||||
ReportHTML.writeSum.noExaminer=<i>\u8ABF\u67FB\u62C5\u5F53\u8005\u7121\u3057</i>
|
ReportHTML.writeSum.noExaminer=<i>\u8abf\u67fb\u62c5\u5f53\u8005\u7121\u3057</i>
|
||||||
ReportHTML.writeSum.imageInfoHeading=<h2>\u30A4\u30E1\u30FC\u30B8\u60C5\u5831\uFF1A</h2>
|
ReportHTML.writeSum.imageInfoHeading=<h2>\u30a4\u30e1\u30fc\u30b8\u60c5\u5831\uff1a</h2>
|
||||||
ReportHTML.writeSum.timezone=\u30BF\u30A4\u30E0\u30BE\u30FC\u30F3\uFF1A
|
ReportHTML.writeSum.timezone=\u30bf\u30a4\u30e0\u30be\u30fc\u30f3\uff1a
|
||||||
ReportProgressPanel.progress.queuing=\u30AD\u30E5\u30FC\u30A4\u30F3\u30B0\u2026
|
ReportProgressPanel.progress.queuing=\u30ad\u30e5\u30fc\u30a4\u30f3\u30b0\u2026
|
||||||
ReportProgressPanel.initPathLabel.noFile=<html><u>\u30EC\u30DD\u30FC\u30C8\u30D5\u30A1\u30A4\u30EB\u7121\u3057</u></html>
|
ReportProgressPanel.initPathLabel.noFile=<html><u>\u30ec\u30dd\u30fc\u30c8\u30d5\u30a1\u30a4\u30eb\u7121\u3057</u></html>
|
||||||
ReportProgressPanel.start.progress.text=\u30EC\u30DD\u30FC\u30C8\u958B\u59CB\u4E2D\u2026
|
ReportProgressPanel.start.progress.text=\u30ec\u30dd\u30fc\u30c8\u958b\u59cb\u4e2d\u2026
|
||||||
ReportProgressPanel.cancel.procLbl.text=\u30AD\u30E3\u30F3\u30BB\u30EB\u3055\u308C\u307E\u3057\u305F
|
ReportProgressPanel.cancel.procLbl.text=\u30ad\u30e3\u30f3\u30bb\u30eb\u3055\u308c\u307e\u3057\u305f
|
||||||
ReportVisualPanel1.getName.text=\u30EC\u30DD\u30FC\u30C8\u30E2\u30B8\u30E5\u30FC\u30EB\u306E\u9078\u629E\u304A\u3088\u3073\u8A2D\u5B9A
|
ReportVisualPanel1.getName.text=\u30ec\u30dd\u30fc\u30c8\u30e2\u30b8\u30e5\u30fc\u30eb\u306e\u9078\u629e\u304a\u3088\u3073\u8a2d\u5b9a
|
||||||
ReportVisualPanel2.getName.text=\u30A2\u30FC\u30C6\u30A3\u30D5\u30A1\u30AF\u30C8\u30EC\u30DD\u30FC\u30C8\u3092\u8A2D\u5B9A
|
ReportVisualPanel2.getName.text=\u30a2\u30fc\u30c6\u30a3\u30d5\u30a1\u30af\u30c8\u30ec\u30dd\u30fc\u30c8\u3092\u8a2d\u5b9a
|
||||||
ReportWizardFileOptionsPanel.finishButton.text=\u7D42\u4E86
|
ReportWizardFileOptionsPanel.finishButton.text=\u7d42\u4e86
|
||||||
ReportWizardFileOptionsVisualPanel.getName.text=\u30D5\u30A1\u30A4\u30EB\u30EC\u30DD\u30FC\u30C8\u3092\u8A2D\u5B9A
|
ReportWizardFileOptionsVisualPanel.getName.text=\u30d5\u30a1\u30a4\u30eb\u30ec\u30dd\u30fc\u30c8\u3092\u8a2d\u5b9a
|
||||||
ReportWizardPanel1.finishButton.text=\u7D42\u4E86
|
ReportWizardPanel1.finishButton.text=\u7d42\u4e86
|
||||||
ReportWizardPanel2.finishButton.text=\u7D42\u4E86
|
ReportWizardPanel2.finishButton.text=\u7d42\u4e86
|
||||||
ReportHTML.writeSum.reportGenOn.text={0}\u306BHTML\u30EC\u30DD\u30FC\u30C8\u306F\u751F\u6210\u3055\u308C\u307E\u3057\u305F
|
ReportHTML.writeSum.reportGenOn.text={0}\u306bHTML\u30ec\u30dd\u30fc\u30c8\u306f\u751f\u6210\u3055\u308c\u307e\u3057\u305f
|
||||||
ReportHTML.writeSum.noCaseNum=<i>\u30B1\u30FC\u30B9\u756A\u53F7\u304C\u3042\u308A\u307E\u305B\u3093</i>
|
ReportHTML.writeSum.noCaseNum=<i>\u30b1\u30fc\u30b9\u756a\u53f7\u304c\u3042\u308a\u307e\u305b\u3093</i>
|
||||||
ReportGenerator.errors.reportErrorTitle=\u30EC\u30DD\u30FC\u30C8\u751F\u6210\u4E2D\u306B\u30A8\u30E9\u30FC\u304C\u767A\u751F\u3057\u307E\u3057\u305F
|
ReportGenerator.errors.reportErrorTitle=\u30ec\u30dd\u30fc\u30c8\u751f\u6210\u4e2d\u306b\u30a8\u30e9\u30fc\u304c\u767a\u751f\u3057\u307e\u3057\u305f
|
||||||
ReportGenerator.errors.reportErrorText=\u30EC\u30DD\u30FC\u30C8\u751F\u6210\u4E2D\u306B\u30A8\u30E9\u30FC\u304C\u767A\u751F\u3057\u307E\u3057\u305F\uFF1A
|
ReportGenerator.errors.reportErrorText=\u30ec\u30dd\u30fc\u30c8\u751f\u6210\u4e2d\u306b\u30a8\u30e9\u30fc\u304c\u767a\u751f\u3057\u307e\u3057\u305f\uff1a
|
||||||
ReportKML.getDesc.text=\u95A2\u9023\u30D5\u30A1\u30A4\u30EB\u306E\u5EA7\u6A19\u3092\u542B\u3080KML\u30D5\u30A9\u30FC\u30DE\u30C3\u30C8\u306E\u30EC\u30DD\u30FC\u30C8\u3002\u3053\u306E\u30D5\u30A9\u30FC\u30DE\u30C3\u30C8\u306FGoogle Earth\u30D3\u30E5\u30FC\u306B\u4F7F\u7528\u3067\u304D\u307E\u3059\u3002
|
ReportKML.getDesc.text=\u95a2\u9023\u30d5\u30a1\u30a4\u30eb\u306e\u5ea7\u6a19\u3092\u542b\u3080KML\u30d5\u30a9\u30fc\u30de\u30c3\u30c8\u306e\u30ec\u30dd\u30fc\u30c8\u3002\u3053\u306e\u30d5\u30a9\u30fc\u30de\u30c3\u30c8\u306fGoogle Earth\u30d3\u30e5\u30fc\u306b\u4f7f\u7528\u3067\u304d\u307e\u3059\u3002
|
||||||
ReportKML.getName.text=Google Earth/KML
|
ReportKML.getName.text=Google Earth/KML
|
||||||
ReportKML.progress.loading=\u30D5\u30A1\u30A4\u30EB\u306E\u8AAD\u307F\u8FBC\u307F\u4E2D\u2026
|
ReportKML.progress.loading=\u30d5\u30a1\u30a4\u30eb\u306e\u8aad\u307f\u8fbc\u307f\u4e2d\u2026
|
||||||
ReportKML.progress.querying=\u30D5\u30A1\u30A4\u30EB\u306E\u30AF\u30A8\u30EA\u3092\u5B9F\u884C\u4E2D\u2026
|
ReportKML.progress.querying=\u30d5\u30a1\u30a4\u30eb\u306e\u30af\u30a8\u30ea\u3092\u5b9f\u884c\u4e2d\u2026
|
||||||
ReportBodyFile.generateReport.srcModuleName.text=TSK\u30DC\u30C7\u30A3\u30D5\u30A1\u30A4\u30EB
|
ReportBodyFile.generateReport.srcModuleName.text=TSK\u30dc\u30c7\u30a3\u30d5\u30a1\u30a4\u30eb
|
||||||
ReportExcel.endReport.srcModuleName.text=Excel\u30EC\u30DD\u30FC\u30C8
|
ReportExcel.endReport.srcModuleName.text=Excel\u30ec\u30dd\u30fc\u30c8
|
||||||
ReportGenerator.artTableColHdr.extension.text=\u62E1\u5F35\u5B50
|
ReportGenerator.artTableColHdr.extension.text=\u62e1\u5f35\u5b50
|
||||||
ReportGenerator.artTableColHdr.mimeType.text=MIME\u30BF\u30A4\u30D7
|
ReportGenerator.artTableColHdr.mimeType.text=MIME\u30bf\u30a4\u30d7
|
||||||
ReportHTML.writeIndex.srcModuleName.text=HTML\u30EC\u30DD\u30FC\u30C8
|
ReportHTML.writeIndex.srcModuleName.text=HTML\u30ec\u30dd\u30fc\u30c8
|
||||||
ReportKML.genReport.srcModuleName.text=KML\u30EC\u30DD\u30FC\u30C8
|
ReportKML.genReport.srcModuleName.text=KML\u30ec\u30dd\u30fc\u30c8
|
||||||
ReportGenerator.artTableColHdr.associatedArtifact=\u95A2\u4FC2\u3059\u308B\u30A2\u30FC\u30C6\u30A3\u30D5\u30A1\u30AF\u30C8
|
ReportGenerator.artTableColHdr.associatedArtifact=\u95a2\u4fc2\u3059\u308b\u30a2\u30fc\u30c6\u30a3\u30d5\u30a1\u30af\u30c8
|
||||||
ReportGenerator.artTableColHdr.count=\u30AB\u30A6\u30F3\u30C8
|
ReportGenerator.artTableColHdr.count=\u30ab\u30a6\u30f3\u30c8
|
||||||
ReportGenerator.artTableColHdr.devMake=\u6A5F\u5668\u578B\u540D
|
ReportGenerator.artTableColHdr.devMake=\u6a5f\u5668\u578b\u540d
|
||||||
ReportGenerator.artTableColHdr.latitudeEnd=\u5230\u7740\u7DEF\u5EA6
|
ReportGenerator.artTableColHdr.latitudeEnd=\u5230\u7740\u7def\u5ea6
|
||||||
ReportGenerator.artTableColHdr.latitudeStart=\u51FA\u767A\u7DEF\u5EA6
|
ReportGenerator.artTableColHdr.latitudeStart=\u51fa\u767a\u7def\u5ea6
|
||||||
ReportGenerator.artTableColHdr.localPath=\u30ED\u30FC\u30AB\u30EB\u30D1\u30B9
|
ReportGenerator.artTableColHdr.localPath=\u30ed\u30fc\u30ab\u30eb\u30d1\u30b9
|
||||||
ReportGenerator.artTableColHdr.longitudeEnd=\u5230\u7740\u7D4C\u5EA6
|
ReportGenerator.artTableColHdr.longitudeEnd=\u5230\u7740\u7d4c\u5ea6
|
||||||
ReportGenerator.artTableColHdr.longitudeStart=\u51FA\u767A\u7D4C\u5EA6
|
ReportGenerator.artTableColHdr.longitudeStart=\u51fa\u767a\u7d4c\u5ea6
|
||||||
ReportGenerator.artTableColHdr.osInstallDate.text=\u30A4\u30F3\u30B9\u30C8\u30FC\u30EB\u65E5\u4ED8
|
ReportGenerator.artTableColHdr.osInstallDate.text=\u30a4\u30f3\u30b9\u30c8\u30fc\u30eb\u65e5\u4ed8
|
||||||
ReportGenerator.artTableColHdr.osName.text=\u30AA\u30DA\u30EC\u30FC\u30C6\u30A3\u30F3\u30B0\u30B7\u30B9\u30C6\u30E0\u540D
|
ReportGenerator.artTableColHdr.osName.text=\u30aa\u30da\u30ec\u30fc\u30c6\u30a3\u30f3\u30b0\u30b7\u30b9\u30c6\u30e0\u540d
|
||||||
ReportGenerator.artTableColHdr.processorArchitecture.text=\u30D7\u30ED\u30BB\u30C3\u30B5\u30A2\u30FC\u30AD\u30C6\u30AF\u30C1\u30E3
|
ReportGenerator.artTableColHdr.processorArchitecture.text=\u30d7\u30ed\u30bb\u30c3\u30b5\u30a2\u30fc\u30ad\u30c6\u30af\u30c1\u30e3
|
||||||
ReportGenerator.artTableColHdr.readStatus=\u8AAD\u307F\u53D6\u308A\u4E2D\u30B9\u30C6\u30FC\u30BF\u30B9
|
ReportGenerator.artTableColHdr.readStatus=\u8aad\u307f\u53d6\u308a\u4e2d\u30b9\u30c6\u30fc\u30bf\u30b9
|
||||||
ReportGenerator.artTableColHdr.remotePath=\u30EA\u30E2\u30FC\u30C8\u30D1\u30B9
|
ReportGenerator.artTableColHdr.remotePath=\u30ea\u30e2\u30fc\u30c8\u30d1\u30b9
|
||||||
ReportGenerator.artTableColHdr.tskDateTimeRcvd=\u53D7\u4FE1\u65E5
|
ReportGenerator.artTableColHdr.tskDateTimeRcvd=\u53d7\u4fe1\u65e5
|
||||||
ReportGenerator.artTableColHdr.tskDateTimeSent=\u9001\u4FE1\u65E5
|
ReportGenerator.artTableColHdr.tskDateTimeSent=\u9001\u4fe1\u65e5
|
||||||
ReportGenerator.artTableColHdr.tskEmailBcc=E-Mail BCC
|
ReportGenerator.artTableColHdr.tskEmailBcc=E-Mail BCC
|
||||||
ReportGenerator.artTableColHdr.tskEmailCc=E-Mail CC
|
ReportGenerator.artTableColHdr.tskEmailCc=E-Mail CC
|
||||||
ReportGenerator.artTableColHdr.tskEmailFrom=E-Mail\u9001\u4FE1\u5143
|
ReportGenerator.artTableColHdr.tskEmailFrom=E-Mail\u9001\u4fe1\u5143
|
||||||
ReportGenerator.artTableColHdr.tskEmailTo=E-Mail\u9001\u4FE1\u5148
|
ReportGenerator.artTableColHdr.tskEmailTo=E-Mail\u9001\u4fe1\u5148
|
||||||
ReportGenerator.artTableColHdr.tskGpsRouteCategory=\u30AB\u30C6\u30B4\u30EA
|
ReportGenerator.artTableColHdr.tskGpsRouteCategory=\u30ab\u30c6\u30b4\u30ea
|
||||||
ReportGenerator.artTableColHdr.tskInterestingFilesCategory=\u30EB\u30FC\u30EB
|
ReportGenerator.artTableColHdr.tskInterestingFilesCategory=\u30eb\u30fc\u30eb
|
||||||
ReportGenerator.artTableColHdr.tskMsgId=\u30E1\u30C3\u30BB\u30FC\u30B8ID
|
ReportGenerator.artTableColHdr.tskMsgId=\u30e1\u30c3\u30bb\u30fc\u30b8ID
|
||||||
ReportGenerator.artTableColHdr.tskPath=\u30D1\u30B9
|
ReportGenerator.artTableColHdr.tskPath=\u30d1\u30b9
|
||||||
ReportGenerator.artTableColHdr.tskSetName=\u30BB\u30C3\u30C8\u540D
|
ReportGenerator.artTableColHdr.tskSetName=\u30bb\u30c3\u30c8\u540d
|
||||||
ReportGenerator.artTableColHdr.tskSubject=\u30B5\u30D6\u30B8\u30A7\u30AF\u30C8
|
ReportGenerator.artTableColHdr.tskSubject=\u30b5\u30d6\u30b8\u30a7\u30af\u30c8
|
||||||
ReportGenerator.artTableColHdr.urlDomainDecoded=URL\u30C9\u30E1\u30A4\u30F3
|
ReportGenerator.artTableColHdr.urlDomainDecoded=URL\u30c9\u30e1\u30a4\u30f3
|
||||||
ReportGenerator.artTableColHdr.userName=\u30E6\u30FC\u30B6\u540D
|
ReportGenerator.artTableColHdr.userName=\u30e6\u30fc\u30b6\u540d
|
||||||
ReportGenerator.errList.coreExceptionWhileGenRptRow=\u30A2\u30FC\u30C6\u30A3\u30D5\u30A1\u30AF\u30C8\u30EC\u30DD\u30FC\u30C8\u7528\u30ED\u30FC\u30C7\u30FC\u30BF\u306E\u751F\u6210\u4E2D\u306B\u30B3\u30A2\u30A8\u30AF\u30BB\u30D7\u30B7\u30E7\u30F3\uFF08\u4F8B\u5916\uFF09\u304C\u691C\u51FA\u3055\u308C\u307E\u3057\u305F
|
ReportGenerator.errList.coreExceptionWhileGenRptRow=\u30a2\u30fc\u30c6\u30a3\u30d5\u30a1\u30af\u30c8\u30ec\u30dd\u30fc\u30c8\u7528\u30ed\u30fc\u30c7\u30fc\u30bf\u306e\u751f\u6210\u4e2d\u306b\u30b3\u30a2\u30a8\u30af\u30bb\u30d7\u30b7\u30e7\u30f3\uff08\u4f8b\u5916\uff09\u304c\u691c\u51fa\u3055\u308c\u307e\u3057\u305f
|
||||||
ReportGenerator.errList.errGetContentFromBBArtifact=Blackboard\u30A2\u30FC\u30C6\u30A3\u30D5\u30A1\u30AF\u30C8\u304B\u3089\u30EC\u30DD\u30FC\u30C8\u7528\u306E\u30B3\u30F3\u30C6\u30F3\u30C4\u3092\u53D6\u5F97\u4E2D\u306B\u30A8\u30E9\u30FC\u304C\u767A\u751F\u3057\u307E\u3057\u305F\u3002
|
ReportGenerator.errList.errGetContentFromBBArtifact=Blackboard\u30a2\u30fc\u30c6\u30a3\u30d5\u30a1\u30af\u30c8\u304b\u3089\u30ec\u30dd\u30fc\u30c8\u7528\u306e\u30b3\u30f3\u30c6\u30f3\u30c4\u3092\u53d6\u5f97\u4e2d\u306b\u30a8\u30e9\u30fc\u304c\u767a\u751f\u3057\u307e\u3057\u305f\u3002
|
||||||
ReportGenerator.errList.failedGetAbstractFileByID=ID\u306B\u57FA\u3065\u304D\u30A2\u30D6\u30B9\u30C8\u30E9\u30AF\u30C8\u30D5\u30A1\u30A4\u30EB\u3092\u53D6\u5F97\u3059\u308B\u306E\u3092\u5931\u6557\u3057\u307E\u3057\u305F
|
ReportGenerator.errList.failedGetAbstractFileByID=ID\u306b\u57fa\u3065\u304d\u30a2\u30d6\u30b9\u30c8\u30e9\u30af\u30c8\u30d5\u30a1\u30a4\u30eb\u3092\u53d6\u5f97\u3059\u308b\u306e\u3092\u5931\u6557\u3057\u307e\u3057\u305f
|
||||||
ReportGenerator.errList.failedGetBBArtifacts=\u30EC\u30DD\u30FC\u30C8\u751F\u6210\u4E2D\u306BBlackboard\u30A2\u30FC\u30C6\u30A3\u30D5\u30A1\u30AF\u30C8\u306E\u53D6\u5F97\u306B\u5931\u6557\u3057\u307E\u3057\u305F\u3002
|
ReportGenerator.errList.failedGetBBArtifacts=\u30ec\u30dd\u30fc\u30c8\u751f\u6210\u4e2d\u306bBlackboard\u30a2\u30fc\u30c6\u30a3\u30d5\u30a1\u30af\u30c8\u306e\u53d6\u5f97\u306b\u5931\u6557\u3057\u307e\u3057\u305f\u3002
|
||||||
ReportGenerator.errList.failedGetBBArtifactTags=Blackboard\u30A2\u30FC\u30C6\u30A3\u30D5\u30A1\u30AF\u30C8\u30BF\u30B0\u306E\u53D6\u5F97\u306B\u5931\u6557\u3057\u307E\u3057\u305F\u3002
|
ReportGenerator.errList.failedGetBBArtifactTags=Blackboard\u30a2\u30fc\u30c6\u30a3\u30d5\u30a1\u30af\u30c8\u30bf\u30b0\u306e\u53d6\u5f97\u306b\u5931\u6557\u3057\u307e\u3057\u305f\u3002
|
||||||
ReportGenerator.errList.failedGetBBAttribs=\u30EC\u30DD\u30FC\u30C8\u751F\u6210\u4E2D\u306BBlackboard\u5C5E\u6027\u306E\u53D6\u5F97\u306B\u5931\u6557\u3057\u307E\u3057\u305F\u3002
|
ReportGenerator.errList.failedGetBBAttribs=\u30ec\u30dd\u30fc\u30c8\u751f\u6210\u4e2d\u306bBlackboard\u5c5e\u6027\u306e\u53d6\u5f97\u306b\u5931\u6557\u3057\u307e\u3057\u305f\u3002
|
||||||
ReportGenerator.errList.failedGetContentTags=\u30B3\u30F3\u30C6\u30F3\u30C4\u30BF\u30B0\u306E\u53D6\u5F97\u306B\u5931\u6557\u3057\u307E\u3057\u305F\u3002
|
ReportGenerator.errList.failedGetContentTags=\u30b3\u30f3\u30c6\u30f3\u30c4\u30bf\u30b0\u306e\u53d6\u5f97\u306b\u5931\u6557\u3057\u307e\u3057\u305f\u3002
|
||||||
ReportGenerator.errList.failedMakeRptFolder=\u30EC\u30DD\u30FC\u30C8\u30D5\u30A9\u30EB\u30C0\u306E\u4F5C\u6210\u306B\u5931\u6557\u3057\u307E\u3057\u305F\u3002\u30EC\u30DD\u30FC\u30C8\u751F\u6210\u304C\u3067\u304D\u306A\u3044\u304B\u3082\u3057\u308C\u307E\u305B\u3093\u3002
|
ReportGenerator.errList.failedMakeRptFolder=\u30ec\u30dd\u30fc\u30c8\u30d5\u30a9\u30eb\u30c0\u306e\u4f5c\u6210\u306b\u5931\u6557\u3057\u307e\u3057\u305f\u3002\u30ec\u30dd\u30fc\u30c8\u751f\u6210\u304c\u3067\u304d\u306a\u3044\u304b\u3082\u3057\u308c\u307e\u305b\u3093\u3002
|
||||||
ReportGenerator.errList.failedQueryHashsetHits=\u30CF\u30C3\u30B7\u30E5\u30BB\u30C3\u30C8\u30D2\u30C3\u30C8\u3092\u30AF\u30A8\u30EA\u3059\u308B\u306E\u306B\u5931\u6557\u3057\u307E\u3057\u305F\u3002
|
ReportGenerator.errList.failedQueryHashsetHits=\u30cf\u30c3\u30b7\u30e5\u30bb\u30c3\u30c8\u30d2\u30c3\u30c8\u3092\u30af\u30a8\u30ea\u3059\u308b\u306e\u306b\u5931\u6557\u3057\u307e\u3057\u305f\u3002
|
||||||
ReportGenerator.errList.failedQueryHashsetLists=\u30CF\u30C3\u30B7\u30E5\u30BB\u30C3\u30C8\u30EA\u30B9\u30C8\u3092\u30AF\u30A8\u30EA\u3059\u308B\u306E\u306B\u5931\u6557\u3057\u307E\u3057\u305F\u3002
|
ReportGenerator.errList.failedQueryHashsetLists=\u30cf\u30c3\u30b7\u30e5\u30bb\u30c3\u30c8\u30ea\u30b9\u30c8\u3092\u30af\u30a8\u30ea\u3059\u308b\u306e\u306b\u5931\u6557\u3057\u307e\u3057\u305f\u3002
|
||||||
ReportGenerator.errList.failedQueryKWLists=\u30AD\u30FC\u30EF\u30FC\u30C9\u30EA\u30B9\u30C8\u3092\u30AF\u30A8\u30EA\u3059\u308B\u306E\u306B\u5931\u6557\u3057\u307E\u3057\u305F\u3002
|
ReportGenerator.errList.failedQueryKWLists=\u30ad\u30fc\u30ef\u30fc\u30c9\u30ea\u30b9\u30c8\u3092\u30af\u30a8\u30ea\u3059\u308b\u306e\u306b\u5931\u6557\u3057\u307e\u3057\u305f\u3002
|
||||||
ReportGenerator.errList.failedQueryKWs=\u30AD\u30FC\u30EF\u30FC\u30C9\u3092\u30AF\u30A8\u30EA\u3059\u308B\u306E\u306B\u5931\u6557\u3057\u307E\u3057\u305F\u3002
|
ReportGenerator.errList.failedQueryKWs=\u30ad\u30fc\u30ef\u30fc\u30c9\u3092\u30af\u30a8\u30ea\u3059\u308b\u306e\u306b\u5931\u6557\u3057\u307e\u3057\u305f\u3002
|
||||||
ReportGenerator.htmlOutput.header.comment=\u30B3\u30E1\u30F3\u30C8
|
ReportGenerator.htmlOutput.header.comment=\u30b3\u30e1\u30f3\u30c8
|
||||||
ReportGenerator.htmlOutput.header.file=\u30D5\u30A1\u30A4\u30EB
|
ReportGenerator.htmlOutput.header.file=\u30d5\u30a1\u30a4\u30eb
|
||||||
ReportGenerator.htmlOutput.header.hash=\u30CF\u30C3\u30B7\u30E5
|
ReportGenerator.htmlOutput.header.hash=\u30cf\u30c3\u30b7\u30e5
|
||||||
ReportGenerator.htmlOutput.header.size=\u30B5\u30A4\u30BA\uFF08\u30D0\u30A4\u30C8\uFF09
|
ReportGenerator.htmlOutput.header.size=\u30b5\u30a4\u30ba\uff08\u30d0\u30a4\u30c8\uff09
|
||||||
ReportGenerator.htmlOutput.header.tag=\u30BF\u30B0
|
ReportGenerator.htmlOutput.header.tag=\u30bf\u30b0
|
||||||
ReportGenerator.htmlOutput.header.timeAccessed=\u30A2\u30AF\u30BB\u30B9\u65E5\u6642
|
ReportGenerator.htmlOutput.header.timeAccessed=\u30a2\u30af\u30bb\u30b9\u65e5\u6642
|
||||||
ReportGenerator.htmlOutput.header.timeChanged=\u5909\u66F4\u65E5\u6642
|
ReportGenerator.htmlOutput.header.timeCreated=\u4f5c\u6210\u65e5\u6642
|
||||||
ReportGenerator.htmlOutput.header.timeCreated=\u4F5C\u6210\u65E5\u6642
|
ReportGenerator.htmlOutput.header.timeModified=\u4fee\u6b63\u65e5\u6642
|
||||||
ReportGenerator.htmlOutput.header.timeModified=\u4FEE\u6B63\u65E5\u6642
|
ReportGenerator.notifyErr.errsDuringRptGen=\u30ec\u30dd\u30fc\u30c8\u751f\u6210\u4e2d\u306e\u30a8\u30e9\u30fc\uff1a
|
||||||
ReportGenerator.notifyErr.errsDuringRptGen=\u30EC\u30DD\u30FC\u30C8\u751F\u6210\u4E2D\u306E\u30A8\u30E9\u30FC\uFF1A
|
ReportGenerator.errList.failedGetAbstractFileFromID=ID\u306b\u57fa\u3065\u304d\u30a2\u30d6\u30b9\u30c8\u30e9\u30af\u30c8\u30d5\u30a1\u30a4\u30eb\u3092\u53d6\u5f97\u3059\u308b\u306e\u3092\u5931\u6557\u3057\u307e\u3057\u305f
|
||||||
ReportGenerator.errList.failedGetAbstractFileFromID=ID\u306B\u57FA\u3065\u304D\u30A2\u30D6\u30B9\u30C8\u30E9\u30AF\u30C8\u30D5\u30A1\u30A4\u30EB\u3092\u53D6\u5F97\u3059\u308B\u306E\u3092\u5931\u6557\u3057\u307E\u3057\u305F
|
ReportKML.getFilePath.text=\u30ec\u30dd\u30fc\u30c8KML.kml
|
||||||
ReportKML.getFilePath.text=\u30EC\u30DD\u30FC\u30C8KML.kml
|
ReportVisualPanel1.invalidModuleWarning=\u7121\u52b9\u306a\u30ec\u30dd\u30fc\u30c8\u30e2\u30b8\u30e5\u30fc\u30eb({0})\u306b\u906d\u9047\u3057\u307e\u3057\u305f
|
||||||
ReportVisualPanel1.invalidModuleWarning=\u7121\u52B9\u306A\u30EC\u30DD\u30FC\u30C8\u30E2\u30B8\u30E5\u30FC\u30EB({0})\u306B\u906D\u9047\u3057\u307E\u3057\u305F
|
ReportGenerationPanel.confDlg.cancelReport.msg=\u672c\u5f53\u306b\u30ec\u30dd\u30fc\u30c8\u3092\u30ad\u30e3\u30f3\u30bb\u30eb\u3057\u307e\u3059\u304b\uff1f
|
||||||
ReportGenerationPanel.confDlg.cancelReport.msg=\u672C\u5F53\u306B\u30EC\u30DD\u30FC\u30C8\u3092\u30AD\u30E3\u30F3\u30BB\u30EB\u3057\u307E\u3059\u304B\uFF1F
|
ReportProgressPanel.complete.processLb2.text=\u5b8c\u4e86\u3057\u307e\u3057\u305f\u304c\u3001\u30a8\u30e9\u30fc\u304c\u767a\u751f\u3057\u307e\u3057\u305f
|
||||||
ReportProgressPanel.complete.processLb2.text=\u5B8C\u4E86\u3057\u307E\u3057\u305F\u304C\u3001\u30A8\u30E9\u30FC\u304C\u767A\u751F\u3057\u307E\u3057\u305F
|
ReportGenerationPanel.cancelButton.actionCommand=\u30ad\u30e3\u30f3\u30bb\u30eb
|
||||||
ReportGenerationPanel.cancelButton.actionCommand=\u30AD\u30E3\u30F3\u30BB\u30EB
|
ReportGenerationPanel.cancelButton.text=\u30ad\u30e3\u30f3\u30bb\u30eb
|
||||||
ReportGenerationPanel.cancelButton.text=\u30AD\u30E3\u30F3\u30BB\u30EB
|
|
@ -26,22 +26,16 @@
|
|||||||
<Layout>
|
<Layout>
|
||||||
<DimensionLayout dim="0">
|
<DimensionLayout dim="0">
|
||||||
<Group type="103" groupAlignment="0" attributes="0">
|
<Group type="103" groupAlignment="0" attributes="0">
|
||||||
<Component id="optionSeparator" alignment="0" 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="reportScrollPane" max="32767" attributes="0"/>
|
|
||||||
<Component id="titleSeparator" alignment="0" max="32767" attributes="0"/>
|
|
||||||
<Group type="102" alignment="0" attributes="0">
|
<Group type="102" alignment="0" attributes="0">
|
||||||
<Component id="titleLabel" min="-2" max="-2" attributes="0"/>
|
<EmptySpace min="-2" max="-2" attributes="0"/>
|
||||||
<EmptySpace min="0" pref="522" max="32767" attributes="0"/>
|
<Group type="103" groupAlignment="0" attributes="0">
|
||||||
</Group>
|
|
||||||
<Group type="102" alignment="1" attributes="0">
|
<Group type="102" alignment="1" attributes="0">
|
||||||
<EmptySpace min="0" pref="546" max="32767" attributes="0"/>
|
<EmptySpace min="0" pref="546" max="32767" attributes="0"/>
|
||||||
<Component id="cancelButton" min="-2" max="-2" attributes="0"/>
|
<Component id="cancelButton" min="-2" max="-2" attributes="0"/>
|
||||||
<EmptySpace type="unrelated" max="-2" attributes="0"/>
|
<EmptySpace type="unrelated" max="-2" attributes="0"/>
|
||||||
<Component id="closeButton" min="-2" max="-2" attributes="0"/>
|
<Component id="closeButton" min="-2" max="-2" attributes="0"/>
|
||||||
</Group>
|
</Group>
|
||||||
|
<Component id="reportPanel" alignment="0" pref="680" max="32767" attributes="0"/>
|
||||||
</Group>
|
</Group>
|
||||||
<EmptySpace max="-2" attributes="0"/>
|
<EmptySpace max="-2" attributes="0"/>
|
||||||
</Group>
|
</Group>
|
||||||
@ -51,19 +45,13 @@
|
|||||||
<Group type="103" groupAlignment="0" attributes="0">
|
<Group type="103" groupAlignment="0" attributes="0">
|
||||||
<Group type="102" alignment="0" attributes="0">
|
<Group type="102" alignment="0" attributes="0">
|
||||||
<EmptySpace max="-2" attributes="0"/>
|
<EmptySpace max="-2" attributes="0"/>
|
||||||
<Component id="titleLabel" min="-2" max="-2" attributes="0"/>
|
<Component id="reportPanel" pref="344" max="32767" attributes="0"/>
|
||||||
<EmptySpace min="0" pref="0" max="-2" attributes="0"/>
|
|
||||||
<Component id="titleSeparator" min="-2" max="-2" attributes="0"/>
|
|
||||||
<EmptySpace type="separate" max="-2" attributes="0"/>
|
|
||||||
<Component id="reportScrollPane" pref="290" max="32767" attributes="0"/>
|
|
||||||
<EmptySpace type="separate" max="-2" attributes="0"/>
|
|
||||||
<Component id="optionSeparator" min="-2" max="-2" attributes="0"/>
|
|
||||||
<EmptySpace type="unrelated" max="-2" attributes="0"/>
|
<EmptySpace type="unrelated" max="-2" attributes="0"/>
|
||||||
<Group type="103" groupAlignment="3" attributes="0">
|
<Group type="103" groupAlignment="3" attributes="0">
|
||||||
<Component id="closeButton" alignment="3" min="-2" max="-2" attributes="0"/>
|
<Component id="closeButton" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||||
<Component id="cancelButton" alignment="3" min="-2" max="-2" attributes="0"/>
|
<Component id="cancelButton" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||||
</Group>
|
</Group>
|
||||||
<EmptySpace max="-2" attributes="0"/>
|
<EmptySpace min="-2" max="-2" attributes="0"/>
|
||||||
</Group>
|
</Group>
|
||||||
</Group>
|
</Group>
|
||||||
</DimensionLayout>
|
</DimensionLayout>
|
||||||
@ -102,25 +90,6 @@
|
|||||||
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="cancelButtonActionPerformed"/>
|
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="cancelButtonActionPerformed"/>
|
||||||
</Events>
|
</Events>
|
||||||
</Component>
|
</Component>
|
||||||
<Container class="javax.swing.JScrollPane" name="reportScrollPane">
|
|
||||||
<Properties>
|
|
||||||
<Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor">
|
|
||||||
<Border info="org.netbeans.modules.form.compat2.border.LineBorderInfo">
|
|
||||||
<LineBorder>
|
|
||||||
<Color PropertyName="color" blue="b4" green="b4" id="Active Caption Border" palette="2" red="b4" type="palette"/>
|
|
||||||
</LineBorder>
|
|
||||||
</Border>
|
|
||||||
</Property>
|
|
||||||
<Property name="verticalScrollBarPolicy" type="int" value="22"/>
|
|
||||||
<Property name="font" type="java.awt.Font" editor="org.netbeans.modules.form.editors2.FontEditor">
|
|
||||||
<FontInfo relative="true">
|
|
||||||
<Font bold="false" component="reportScrollPane" property="font" relativeSize="false" size="11"/>
|
|
||||||
</FontInfo>
|
|
||||||
</Property>
|
|
||||||
</Properties>
|
|
||||||
|
|
||||||
<Layout class="org.netbeans.modules.form.compat2.layouts.support.JScrollPaneSupportLayout"/>
|
|
||||||
<SubComponents>
|
|
||||||
<Container class="javax.swing.JPanel" name="reportPanel">
|
<Container class="javax.swing.JPanel" name="reportPanel">
|
||||||
<Properties>
|
<Properties>
|
||||||
<Property name="font" type="java.awt.Font" editor="org.netbeans.modules.form.editors2.FontEditor">
|
<Property name="font" type="java.awt.Font" editor="org.netbeans.modules.form.editors2.FontEditor">
|
||||||
@ -136,43 +105,15 @@
|
|||||||
<Layout>
|
<Layout>
|
||||||
<DimensionLayout dim="0">
|
<DimensionLayout dim="0">
|
||||||
<Group type="103" groupAlignment="0" attributes="0">
|
<Group type="103" groupAlignment="0" attributes="0">
|
||||||
<EmptySpace min="0" pref="661" max="32767" attributes="0"/>
|
<EmptySpace min="0" pref="0" max="32767" attributes="0"/>
|
||||||
</Group>
|
</Group>
|
||||||
</DimensionLayout>
|
</DimensionLayout>
|
||||||
<DimensionLayout dim="1">
|
<DimensionLayout dim="1">
|
||||||
<Group type="103" groupAlignment="0" attributes="0">
|
<Group type="103" groupAlignment="0" attributes="0">
|
||||||
<EmptySpace min="0" pref="400" max="32767" attributes="0"/>
|
<EmptySpace min="0" pref="344" max="32767" attributes="0"/>
|
||||||
</Group>
|
</Group>
|
||||||
</DimensionLayout>
|
</DimensionLayout>
|
||||||
</Layout>
|
</Layout>
|
||||||
</Container>
|
</Container>
|
||||||
</SubComponents>
|
</SubComponents>
|
||||||
</Container>
|
|
||||||
<Component class="javax.swing.JLabel" name="titleLabel">
|
|
||||||
<Properties>
|
|
||||||
<Property name="font" type="java.awt.Font" editor="org.netbeans.modules.form.editors2.FontEditor">
|
|
||||||
<FontInfo relative="true">
|
|
||||||
<Font bold="true" component="titleLabel" property="font" relativeSize="false" size="11"/>
|
|
||||||
</FontInfo>
|
|
||||||
</Property>
|
|
||||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
|
||||||
<ResourceString bundle="org/sleuthkit/autopsy/report/Bundle.properties" key="ReportGenerationPanel.titleLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
|
||||||
</Property>
|
|
||||||
</Properties>
|
|
||||||
</Component>
|
|
||||||
<Component class="javax.swing.JSeparator" name="titleSeparator">
|
|
||||||
<Properties>
|
|
||||||
<Property name="foreground" type="java.awt.Color" editor="org.netbeans.beaninfo.editors.ColorEditor">
|
|
||||||
<Color blue="0" green="0" red="0" type="rgb"/>
|
|
||||||
</Property>
|
|
||||||
</Properties>
|
|
||||||
</Component>
|
|
||||||
<Component class="javax.swing.JSeparator" name="optionSeparator">
|
|
||||||
<Properties>
|
|
||||||
<Property name="foreground" type="java.awt.Color" editor="org.netbeans.beaninfo.editors.ColorEditor">
|
|
||||||
<Color blue="0" green="0" red="0" type="rgb"/>
|
|
||||||
</Property>
|
|
||||||
</Properties>
|
|
||||||
</Component>
|
|
||||||
</SubComponents>
|
|
||||||
</Form>
|
</Form>
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* Autopsy Forensic Browser
|
* Autopsy Forensic Browser
|
||||||
*
|
*
|
||||||
* Copyright 2012 Basis Technology Corp.
|
* Copyright 2011-2016 Basis Technology Corp.
|
||||||
* Contact: carrier <at> sleuthkit <dot> org
|
* Contact: carrier <at> sleuthkit <dot> org
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
@ -20,69 +20,89 @@ package org.sleuthkit.autopsy.report;
|
|||||||
|
|
||||||
import java.awt.*;
|
import java.awt.*;
|
||||||
import java.awt.event.ActionListener;
|
import java.awt.event.ActionListener;
|
||||||
|
import java.beans.PropertyChangeEvent;
|
||||||
import javax.swing.Box;
|
import javax.swing.Box;
|
||||||
import javax.swing.JOptionPane;
|
import javax.swing.JOptionPane;
|
||||||
|
import javax.swing.SwingUtilities;
|
||||||
|
|
||||||
import org.openide.util.NbBundle;
|
import org.openide.util.NbBundle;
|
||||||
import org.sleuthkit.autopsy.report.ReportProgressPanel.ReportStatus;
|
import org.sleuthkit.autopsy.report.ReportProgressPanel.ReportStatus;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A panel that displays a panel used by a report generation module to show
|
||||||
|
* progress. It provides OK and Cancel buttons.
|
||||||
|
*/
|
||||||
class ReportGenerationPanel extends javax.swing.JPanel {
|
class ReportGenerationPanel extends javax.swing.JPanel {
|
||||||
|
|
||||||
private GridBagConstraints c;
|
private static final long serialVersionUID = 1L;
|
||||||
ReportProgressPanel progressPanel;
|
private final GridBagConstraints constraints;
|
||||||
private Component glue;
|
private final Component glue;
|
||||||
private ActionListener actionListener;
|
private ActionListener actionListener;
|
||||||
|
ReportProgressPanel progressPanel;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates new form ReportGenerationPanel
|
* Constructs a panel that displays a panel used by a report generation
|
||||||
|
* module to show progress. It provides OK and Cancel buttons.
|
||||||
*/
|
*/
|
||||||
public ReportGenerationPanel() {
|
ReportGenerationPanel() {
|
||||||
initComponents();
|
initComponents();
|
||||||
customInit();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void customInit() {
|
|
||||||
reportPanel.setLayout(new GridBagLayout());
|
reportPanel.setLayout(new GridBagLayout());
|
||||||
c = new GridBagConstraints();
|
constraints = new GridBagConstraints();
|
||||||
c.fill = GridBagConstraints.BOTH;
|
constraints.fill = GridBagConstraints.BOTH;
|
||||||
c.gridx = 0;
|
constraints.gridx = 0;
|
||||||
c.gridy = 0;
|
constraints.gridy = 0;
|
||||||
c.weightx = 1.0;
|
constraints.weightx = 1.0;
|
||||||
glue = Box.createVerticalGlue();
|
glue = Box.createVerticalGlue();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add a ReportProgressPanel to this panel with the given report name and
|
* Adds a panel used by a report generation module to show progress to this
|
||||||
* path.
|
* panel.
|
||||||
*
|
*
|
||||||
* @param reportName report name
|
* @param reportName The report name.
|
||||||
* @param reportPath report path
|
* @param reportPath The report file path
|
||||||
*
|
*
|
||||||
* @return ReportProgressPanel progress panel to update
|
* @return The report generation progress panel.
|
||||||
|
*/
|
||||||
|
ReportProgressPanel addReport(String reportName, String reportPath) {
|
||||||
|
/*
|
||||||
|
* Remove the "glue."
|
||||||
*/
|
*/
|
||||||
public ReportProgressPanel addReport(String reportName, String reportPath) {
|
|
||||||
// Remove the glue
|
|
||||||
reportPanel.remove(glue);
|
reportPanel.remove(glue);
|
||||||
|
|
||||||
progressPanel = new ReportProgressPanel(reportName, reportPath);
|
progressPanel = new ReportProgressPanel(reportName, reportPath);
|
||||||
c.weighty = 0.0;
|
constraints.weighty = 0.0;
|
||||||
c.anchor = GridBagConstraints.NORTH;
|
constraints.anchor = GridBagConstraints.NORTH;
|
||||||
reportPanel.add(progressPanel, c);
|
reportPanel.add(progressPanel, constraints);
|
||||||
c.gridy++;
|
constraints.gridy++;
|
||||||
|
|
||||||
// Add the glue back to the bottom
|
/*
|
||||||
c.weighty = 1.0;
|
* Add the "glue" back to the bottom of the panel.
|
||||||
c.anchor = GridBagConstraints.PAGE_END;
|
*/
|
||||||
reportPanel.add(glue, c);
|
constraints.weighty = 1.0;
|
||||||
|
constraints.anchor = GridBagConstraints.PAGE_END;
|
||||||
|
reportPanel.add(glue, constraints);
|
||||||
|
|
||||||
// 80 px per progressPanel.
|
/*
|
||||||
|
* Use 80 pixels per progress panel. This is a leftover from when this
|
||||||
|
* panel used to show multiple report progress panels.
|
||||||
|
*/
|
||||||
reportPanel.setPreferredSize(new Dimension(600, 1 * 80));
|
reportPanel.setPreferredSize(new Dimension(600, 1 * 80));
|
||||||
reportPanel.repaint();
|
reportPanel.repaint();
|
||||||
|
progressPanel.addPropertyChangeListener((PropertyChangeEvent evt) -> {
|
||||||
|
String propName = evt.getPropertyName();
|
||||||
|
if (propName.equals(ReportProgressPanel.ReportStatus.COMPLETE.toString())
|
||||||
|
|| propName.equals(ReportProgressPanel.ReportStatus.CANCELED.toString())) {
|
||||||
|
SwingUtilities.invokeLater(() -> {
|
||||||
|
cancelButton.setEnabled(false);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
return progressPanel;
|
return progressPanel;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Close this panel and it's dialog if all reports are done.
|
* Closes this panel and its dialog if all reports are done.
|
||||||
*/
|
*/
|
||||||
void close() {
|
void close() {
|
||||||
boolean closeable = true;
|
boolean closeable = true;
|
||||||
@ -105,6 +125,15 @@ class ReportGenerationPanel extends javax.swing.JPanel {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds a close action listener to this panel.
|
||||||
|
*
|
||||||
|
* @param listener The listener to add.
|
||||||
|
*/
|
||||||
|
void addCloseAction(ActionListener listener) {
|
||||||
|
this.actionListener = listener;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This method is called from within the constructor to initialize the form.
|
* 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
|
* WARNING: Do NOT modify this code. The content of this method is always
|
||||||
@ -116,11 +145,7 @@ class ReportGenerationPanel extends javax.swing.JPanel {
|
|||||||
|
|
||||||
closeButton = new javax.swing.JButton();
|
closeButton = new javax.swing.JButton();
|
||||||
cancelButton = new javax.swing.JButton();
|
cancelButton = new javax.swing.JButton();
|
||||||
reportScrollPane = new javax.swing.JScrollPane();
|
|
||||||
reportPanel = new javax.swing.JPanel();
|
reportPanel = new javax.swing.JPanel();
|
||||||
titleLabel = new javax.swing.JLabel();
|
|
||||||
titleSeparator = new javax.swing.JSeparator();
|
|
||||||
optionSeparator = new javax.swing.JSeparator();
|
|
||||||
|
|
||||||
setFont(getFont().deriveFont(getFont().getStyle() & ~java.awt.Font.BOLD, 11));
|
setFont(getFont().deriveFont(getFont().getStyle() & ~java.awt.Font.BOLD, 11));
|
||||||
setPreferredSize(new java.awt.Dimension(700, 400));
|
setPreferredSize(new java.awt.Dimension(700, 400));
|
||||||
@ -142,10 +167,6 @@ class ReportGenerationPanel extends javax.swing.JPanel {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
reportScrollPane.setBorder(javax.swing.BorderFactory.createLineBorder(java.awt.SystemColor.activeCaptionBorder));
|
|
||||||
reportScrollPane.setVerticalScrollBarPolicy(javax.swing.ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);
|
|
||||||
reportScrollPane.setFont(reportScrollPane.getFont().deriveFont(reportScrollPane.getFont().getStyle() & ~java.awt.Font.BOLD, 11));
|
|
||||||
|
|
||||||
reportPanel.setFont(reportPanel.getFont().deriveFont(reportPanel.getFont().getStyle() & ~java.awt.Font.BOLD, 11));
|
reportPanel.setFont(reportPanel.getFont().deriveFont(reportPanel.getFont().getStyle() & ~java.awt.Font.BOLD, 11));
|
||||||
reportPanel.setPreferredSize(new java.awt.Dimension(600, 400));
|
reportPanel.setPreferredSize(new java.awt.Dimension(600, 400));
|
||||||
|
|
||||||
@ -153,53 +174,33 @@ class ReportGenerationPanel extends javax.swing.JPanel {
|
|||||||
reportPanel.setLayout(reportPanelLayout);
|
reportPanel.setLayout(reportPanelLayout);
|
||||||
reportPanelLayout.setHorizontalGroup(
|
reportPanelLayout.setHorizontalGroup(
|
||||||
reportPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
reportPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||||
.addGap(0, 661, Short.MAX_VALUE)
|
.addGap(0, 0, Short.MAX_VALUE)
|
||||||
);
|
);
|
||||||
reportPanelLayout.setVerticalGroup(
|
reportPanelLayout.setVerticalGroup(
|
||||||
reportPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
reportPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||||
.addGap(0, 400, Short.MAX_VALUE)
|
.addGap(0, 344, Short.MAX_VALUE)
|
||||||
);
|
);
|
||||||
|
|
||||||
reportScrollPane.setViewportView(reportPanel);
|
|
||||||
|
|
||||||
titleLabel.setFont(titleLabel.getFont().deriveFont(titleLabel.getFont().getStyle() | java.awt.Font.BOLD, 11));
|
|
||||||
org.openide.awt.Mnemonics.setLocalizedText(titleLabel, org.openide.util.NbBundle.getMessage(ReportGenerationPanel.class, "ReportGenerationPanel.titleLabel.text")); // NOI18N
|
|
||||||
|
|
||||||
titleSeparator.setForeground(new java.awt.Color(0, 0, 0));
|
|
||||||
|
|
||||||
optionSeparator.setForeground(new java.awt.Color(0, 0, 0));
|
|
||||||
|
|
||||||
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
|
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
|
||||||
this.setLayout(layout);
|
this.setLayout(layout);
|
||||||
layout.setHorizontalGroup(
|
layout.setHorizontalGroup(
|
||||||
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||||
.addComponent(optionSeparator)
|
|
||||||
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
|
|
||||||
.addContainerGap()
|
|
||||||
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
|
|
||||||
.addComponent(reportScrollPane)
|
|
||||||
.addComponent(titleSeparator, javax.swing.GroupLayout.Alignment.LEADING)
|
|
||||||
.addGroup(javax.swing.GroupLayout.Alignment.LEADING, layout.createSequentialGroup()
|
|
||||||
.addComponent(titleLabel)
|
|
||||||
.addGap(0, 522, Short.MAX_VALUE))
|
|
||||||
.addGroup(layout.createSequentialGroup()
|
.addGroup(layout.createSequentialGroup()
|
||||||
|
.addContainerGap()
|
||||||
|
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||||
|
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
|
||||||
.addGap(0, 546, Short.MAX_VALUE)
|
.addGap(0, 546, Short.MAX_VALUE)
|
||||||
.addComponent(cancelButton)
|
.addComponent(cancelButton)
|
||||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
|
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
|
||||||
.addComponent(closeButton)))
|
.addComponent(closeButton))
|
||||||
|
.addComponent(reportPanel, javax.swing.GroupLayout.DEFAULT_SIZE, 680, Short.MAX_VALUE))
|
||||||
.addContainerGap())
|
.addContainerGap())
|
||||||
);
|
);
|
||||||
layout.setVerticalGroup(
|
layout.setVerticalGroup(
|
||||||
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||||
.addGroup(layout.createSequentialGroup()
|
.addGroup(layout.createSequentialGroup()
|
||||||
.addContainerGap()
|
.addContainerGap()
|
||||||
.addComponent(titleLabel)
|
.addComponent(reportPanel, javax.swing.GroupLayout.DEFAULT_SIZE, 344, Short.MAX_VALUE)
|
||||||
.addGap(0, 0, 0)
|
|
||||||
.addComponent(titleSeparator, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
|
|
||||||
.addGap(18, 18, 18)
|
|
||||||
.addComponent(reportScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, 290, Short.MAX_VALUE)
|
|
||||||
.addGap(18, 18, 18)
|
|
||||||
.addComponent(optionSeparator, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
|
|
||||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
|
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
|
||||||
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
|
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
|
||||||
.addComponent(closeButton)
|
.addComponent(closeButton)
|
||||||
@ -225,17 +226,10 @@ class ReportGenerationPanel extends javax.swing.JPanel {
|
|||||||
}
|
}
|
||||||
}//GEN-LAST:event_cancelButtonActionPerformed
|
}//GEN-LAST:event_cancelButtonActionPerformed
|
||||||
|
|
||||||
void addCloseAction(ActionListener l) {
|
|
||||||
this.actionListener = l;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Variables declaration - do not modify//GEN-BEGIN:variables
|
// Variables declaration - do not modify//GEN-BEGIN:variables
|
||||||
private javax.swing.JButton cancelButton;
|
private javax.swing.JButton cancelButton;
|
||||||
private javax.swing.JButton closeButton;
|
private javax.swing.JButton closeButton;
|
||||||
private javax.swing.JSeparator optionSeparator;
|
|
||||||
private javax.swing.JPanel reportPanel;
|
private javax.swing.JPanel reportPanel;
|
||||||
private javax.swing.JScrollPane reportScrollPane;
|
|
||||||
private javax.swing.JLabel titleLabel;
|
|
||||||
private javax.swing.JSeparator titleSeparator;
|
|
||||||
// End of variables declaration//GEN-END:variables
|
// End of variables declaration//GEN-END:variables
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -53,10 +53,12 @@ import javax.swing.SwingWorker;
|
|||||||
import org.openide.filesystems.FileUtil;
|
import org.openide.filesystems.FileUtil;
|
||||||
import org.openide.util.NbBundle;
|
import org.openide.util.NbBundle;
|
||||||
import org.sleuthkit.autopsy.casemodule.Case;
|
import org.sleuthkit.autopsy.casemodule.Case;
|
||||||
|
import org.sleuthkit.autopsy.core.UserPreferences;
|
||||||
import org.sleuthkit.autopsy.coreutils.EscapeUtil;
|
import org.sleuthkit.autopsy.coreutils.EscapeUtil;
|
||||||
import org.sleuthkit.autopsy.coreutils.ImageUtils;
|
import org.sleuthkit.autopsy.coreutils.ImageUtils;
|
||||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||||
import org.sleuthkit.autopsy.coreutils.MessageNotifyUtil;
|
import org.sleuthkit.autopsy.coreutils.MessageNotifyUtil;
|
||||||
|
import org.sleuthkit.autopsy.datamodel.ContentUtils;
|
||||||
import org.sleuthkit.autopsy.report.ReportProgressPanel.ReportStatus;
|
import org.sleuthkit.autopsy.report.ReportProgressPanel.ReportStatus;
|
||||||
import org.sleuthkit.datamodel.AbstractFile;
|
import org.sleuthkit.datamodel.AbstractFile;
|
||||||
import org.sleuthkit.datamodel.BlackboardArtifact;
|
import org.sleuthkit.datamodel.BlackboardArtifact;
|
||||||
@ -653,6 +655,18 @@ class ReportGenerator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
ArrayList<String> rowData = new ArrayList<>(Arrays.asList(tag.getName().getDisplayName(), fileName, tag.getComment()));
|
ArrayList<String> rowData = new ArrayList<>(Arrays.asList(tag.getName().getDisplayName(), fileName, tag.getComment()));
|
||||||
|
Content content = tag.getContent();
|
||||||
|
if (content instanceof AbstractFile) {
|
||||||
|
AbstractFile file = (AbstractFile) content;
|
||||||
|
|
||||||
|
// Add metadata about the file to HTML output
|
||||||
|
rowData.add(file.getMtimeAsDate());
|
||||||
|
rowData.add(file.getCtimeAsDate());
|
||||||
|
rowData.add(file.getAtimeAsDate());
|
||||||
|
rowData.add(file.getCrtimeAsDate());
|
||||||
|
rowData.add(Long.toString(file.getSize()));
|
||||||
|
rowData.add(file.getMd5Hash());
|
||||||
|
}
|
||||||
for (TableReportModule module : tableModules) {
|
for (TableReportModule module : tableModules) {
|
||||||
// @@@ This casting is a tricky little workaround to allow the HTML report module to slip in a content hyperlink.
|
// @@@ This casting is a tricky little workaround to allow the HTML report module to slip in a content hyperlink.
|
||||||
if (module instanceof ReportHTML) {
|
if (module instanceof ReportHTML) {
|
||||||
@ -684,6 +698,7 @@ class ReportGenerator {
|
|||||||
NbBundle.getMessage(this.getClass(), "ReportGenerator.errors.reportErrorTitle"),
|
NbBundle.getMessage(this.getClass(), "ReportGenerator.errors.reportErrorTitle"),
|
||||||
NbBundle.getMessage(this.getClass(), "ReportGenerator.errors.reportErrorText") + ex.getLocalizedMessage(),
|
NbBundle.getMessage(this.getClass(), "ReportGenerator.errors.reportErrorText") + ex.getLocalizedMessage(),
|
||||||
MessageNotifyUtil.MessageType.ERROR);
|
MessageNotifyUtil.MessageType.ERROR);
|
||||||
|
logger.log(Level.SEVERE, "failed to generate reports", ex.getCause()); //NON-NLS
|
||||||
logger.log(Level.SEVERE, "failed to generate reports", ex); //NON-NLS
|
logger.log(Level.SEVERE, "failed to generate reports", ex); //NON-NLS
|
||||||
} // catch and ignore if we were cancelled
|
} // catch and ignore if we were cancelled
|
||||||
catch (java.util.concurrent.CancellationException ex) {
|
catch (java.util.concurrent.CancellationException ex) {
|
||||||
@ -1759,11 +1774,10 @@ class ReportGenerator {
|
|||||||
*
|
*
|
||||||
* @return String unique path
|
* @return String unique path
|
||||||
*/
|
*/
|
||||||
private String getFileUniquePath(long objId) {
|
private String getFileUniquePath(Content content) {
|
||||||
try {
|
try {
|
||||||
AbstractFile af = skCase.getAbstractFileById(objId);
|
if (content != null) {
|
||||||
if (af != null) {
|
return content.getUniquePath();
|
||||||
return af.getUniquePath();
|
|
||||||
} else {
|
} else {
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
@ -1785,11 +1799,17 @@ class ReportGenerator {
|
|||||||
private List<BlackboardAttribute> attributes;
|
private List<BlackboardAttribute> attributes;
|
||||||
private HashSet<String> tags;
|
private HashSet<String> tags;
|
||||||
private List<String> rowData = null;
|
private List<String> rowData = null;
|
||||||
|
private Content content;
|
||||||
|
|
||||||
ArtifactData(BlackboardArtifact artifact, List<BlackboardAttribute> attrs, HashSet<String> tags) {
|
ArtifactData(BlackboardArtifact artifact, List<BlackboardAttribute> attrs, HashSet<String> tags) {
|
||||||
this.artifact = artifact;
|
this.artifact = artifact;
|
||||||
this.attributes = attrs;
|
this.attributes = attrs;
|
||||||
this.tags = tags;
|
this.tags = tags;
|
||||||
|
try {
|
||||||
|
this.content = Case.getCurrentCase().getSleuthkitCase().getContentById(artifact.getObjectID());
|
||||||
|
} catch (TskCoreException ex) {
|
||||||
|
logger.log(Level.SEVERE, "Could not get content from database");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public BlackboardArtifact getArtifact() {
|
public BlackboardArtifact getArtifact() {
|
||||||
@ -1812,6 +1832,13 @@ class ReportGenerator {
|
|||||||
return artifact.getObjectID();
|
return artifact.getObjectID();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the content
|
||||||
|
*/
|
||||||
|
public Content getContent() {
|
||||||
|
return content;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Compares ArtifactData objects by the first attribute they have in
|
* Compares ArtifactData objects by the first attribute they have in
|
||||||
* common in their List<BlackboardAttribute>. Should only be used on two
|
* common in their List<BlackboardAttribute>. Should only be used on two
|
||||||
@ -1881,8 +1908,8 @@ class ReportGenerator {
|
|||||||
|
|
||||||
List<String> orderedRowData = new ArrayList<>();
|
List<String> orderedRowData = new ArrayList<>();
|
||||||
if (ARTIFACT_TYPE.TSK_EXT_MISMATCH_DETECTED.getTypeID() == getArtifact().getArtifactTypeID()) {
|
if (ARTIFACT_TYPE.TSK_EXT_MISMATCH_DETECTED.getTypeID() == getArtifact().getArtifactTypeID()) {
|
||||||
AbstractFile file = skCase.getAbstractFileById(getObjectID());
|
if (content != null && content instanceof AbstractFile) {
|
||||||
if (file != null) {
|
AbstractFile file = (AbstractFile) content;
|
||||||
orderedRowData.add(file.getName());
|
orderedRowData.add(file.getName());
|
||||||
orderedRowData.add(file.getNameExtension());
|
orderedRowData.add(file.getNameExtension());
|
||||||
String mimeType = file.getMIMEType();
|
String mimeType = file.getMIMEType();
|
||||||
@ -1913,7 +1940,7 @@ class ReportGenerator {
|
|||||||
} else if (attr.getAttributeType().equals(new BlackboardAttribute.Type(ATTRIBUTE_TYPE.TSK_PATH))) {
|
} else if (attr.getAttributeType().equals(new BlackboardAttribute.Type(ATTRIBUTE_TYPE.TSK_PATH))) {
|
||||||
String pathToShow = attr.getDisplayString();
|
String pathToShow = attr.getDisplayString();
|
||||||
if (pathToShow.isEmpty()) {
|
if (pathToShow.isEmpty()) {
|
||||||
pathToShow = getFileUniquePath(getObjectID());
|
pathToShow = getFileUniquePath(content);
|
||||||
}
|
}
|
||||||
attributeDataArray[2] = pathToShow;
|
attributeDataArray[2] = pathToShow;
|
||||||
}
|
}
|
||||||
@ -1933,6 +1960,7 @@ class ReportGenerator {
|
|||||||
|
|
||||||
return orderedRowData;
|
return orderedRowData;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1999,7 +2027,11 @@ class ReportGenerator {
|
|||||||
List<BlackboardAttribute> attributes = artData.getAttributes();
|
List<BlackboardAttribute> attributes = artData.getAttributes();
|
||||||
for (BlackboardAttribute attribute : attributes) {
|
for (BlackboardAttribute attribute : attributes) {
|
||||||
if (attribute.getAttributeType().equals(this.attributeType)) {
|
if (attribute.getAttributeType().equals(this.attributeType)) {
|
||||||
|
if (attribute.getAttributeType().getValueType() != BlackboardAttribute.TSK_BLACKBOARD_ATTRIBUTE_VALUE_TYPE.DATETIME) {
|
||||||
return attribute.getDisplayString();
|
return attribute.getDisplayString();
|
||||||
|
} else {
|
||||||
|
return ContentUtils.getStringTime(attribute.getValueLong(), artData.getContent());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return "";
|
return "";
|
||||||
@ -2027,7 +2059,7 @@ class ReportGenerator {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getCellData(ArtifactData artData) {
|
public String getCellData(ArtifactData artData) {
|
||||||
return getFileUniquePath(artData.getObjectID());
|
return getFileUniquePath(artData.getContent());
|
||||||
/*else if (this.columnHeader.equals(NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.tags"))) {
|
/*else if (this.columnHeader.equals(NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.tags"))) {
|
||||||
return makeCommaSeparatedList(artData.getTags());
|
return makeCommaSeparatedList(artData.getTags());
|
||||||
}
|
}
|
||||||
|
@ -560,15 +560,6 @@ class ReportHTML implements TableReportModule {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
AbstractFile file = (AbstractFile) content;
|
AbstractFile file = (AbstractFile) content;
|
||||||
|
|
||||||
// Add metadata about the file to HTML output
|
|
||||||
row.add(file.getMtimeAsDate());
|
|
||||||
row.add(file.getCtimeAsDate());
|
|
||||||
row.add(file.getAtimeAsDate());
|
|
||||||
row.add(file.getCrtimeAsDate());
|
|
||||||
row.add(Long.toString(file.getSize()));
|
|
||||||
row.add(file.getMd5Hash());
|
|
||||||
|
|
||||||
// Add the hyperlink to the row. A column header for it was created in startTable().
|
// Add the hyperlink to the row. A column header for it was created in startTable().
|
||||||
StringBuilder localFileLink = new StringBuilder();
|
StringBuilder localFileLink = new StringBuilder();
|
||||||
// Don't make a local copy of the file if it is a directory or unallocated space.
|
// Don't make a local copy of the file if it is a directory or unallocated space.
|
||||||
|
@ -29,11 +29,8 @@
|
|||||||
<Group type="102" alignment="0" attributes="0">
|
<Group type="102" alignment="0" attributes="0">
|
||||||
<EmptySpace max="-2" attributes="0"/>
|
<EmptySpace max="-2" attributes="0"/>
|
||||||
<Group type="103" groupAlignment="0" attributes="0">
|
<Group type="103" groupAlignment="0" attributes="0">
|
||||||
<Component id="processingLabel" max="32767" attributes="0"/>
|
<Component id="statusMessageLabel" max="32767" attributes="0"/>
|
||||||
<Group type="102" alignment="0" attributes="0">
|
<Component id="reportProgressBar" alignment="0" max="32767" attributes="0"/>
|
||||||
<Component id="reportProgressBar" max="32767" attributes="0"/>
|
|
||||||
<EmptySpace min="-2" pref="58" max="-2" attributes="0"/>
|
|
||||||
</Group>
|
|
||||||
<Group type="102" alignment="0" attributes="0">
|
<Group type="102" alignment="0" attributes="0">
|
||||||
<Component id="reportLabel" min="-2" max="-2" attributes="0"/>
|
<Component id="reportLabel" min="-2" max="-2" attributes="0"/>
|
||||||
<EmptySpace max="-2" attributes="0"/>
|
<EmptySpace max="-2" attributes="0"/>
|
||||||
@ -49,17 +46,17 @@
|
|||||||
<DimensionLayout dim="1">
|
<DimensionLayout dim="1">
|
||||||
<Group type="103" groupAlignment="0" attributes="0">
|
<Group type="103" groupAlignment="0" attributes="0">
|
||||||
<Group type="102" alignment="0" attributes="0">
|
<Group type="102" alignment="0" attributes="0">
|
||||||
<EmptySpace max="-2" attributes="0"/>
|
<EmptySpace min="-2" max="-2" attributes="0"/>
|
||||||
<Component id="reportProgressBar" min="-2" pref="16" max="-2" attributes="0"/>
|
<Component id="reportProgressBar" min="-2" pref="16" max="-2" attributes="0"/>
|
||||||
<EmptySpace max="-2" attributes="0"/>
|
<EmptySpace min="-2" max="-2" attributes="0"/>
|
||||||
<Group type="103" groupAlignment="3" attributes="0">
|
<Group type="103" groupAlignment="3" attributes="0">
|
||||||
<Component id="reportLabel" alignment="3" min="-2" max="-2" attributes="0"/>
|
<Component id="reportLabel" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||||
<Component id="pathLabel" alignment="3" min="-2" max="-2" attributes="0"/>
|
<Component id="pathLabel" alignment="3" max="32767" attributes="0"/>
|
||||||
<Component id="separationLabel" alignment="3" min="-2" max="-2" attributes="0"/>
|
<Component id="separationLabel" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||||
</Group>
|
</Group>
|
||||||
<EmptySpace min="0" pref="0" max="-2" attributes="0"/>
|
<EmptySpace max="-2" attributes="0"/>
|
||||||
<Component id="processingLabel" min="-2" max="-2" attributes="0"/>
|
<Component id="statusMessageLabel" min="-2" max="-2" attributes="0"/>
|
||||||
<EmptySpace pref="20" max="32767" attributes="0"/>
|
<EmptySpace min="-2" pref="13" max="-2" attributes="0"/>
|
||||||
</Group>
|
</Group>
|
||||||
</Group>
|
</Group>
|
||||||
</DimensionLayout>
|
</DimensionLayout>
|
||||||
@ -96,18 +93,7 @@
|
|||||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||||
<ResourceString bundle="org/sleuthkit/autopsy/report/Bundle.properties" key="ReportProgressPanel.pathLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
<ResourceString bundle="org/sleuthkit/autopsy/report/Bundle.properties" key="ReportProgressPanel.pathLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||||
</Property>
|
</Property>
|
||||||
</Properties>
|
<Property name="verticalAlignment" type="int" value="1"/>
|
||||||
</Component>
|
|
||||||
<Component class="javax.swing.JLabel" name="processingLabel">
|
|
||||||
<Properties>
|
|
||||||
<Property name="font" type="java.awt.Font" editor="org.netbeans.modules.form.editors2.FontEditor">
|
|
||||||
<FontInfo relative="true">
|
|
||||||
<Font bold="false" component="processingLabel" italic="true" property="font" relativeSize="false" size="10"/>
|
|
||||||
</FontInfo>
|
|
||||||
</Property>
|
|
||||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
|
||||||
<ResourceString bundle="org/sleuthkit/autopsy/report/Bundle.properties" key="ReportProgressPanel.processingLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
|
||||||
</Property>
|
|
||||||
</Properties>
|
</Properties>
|
||||||
</Component>
|
</Component>
|
||||||
<Component class="javax.swing.JLabel" name="separationLabel">
|
<Component class="javax.swing.JLabel" name="separationLabel">
|
||||||
@ -122,5 +108,12 @@
|
|||||||
</Property>
|
</Property>
|
||||||
</Properties>
|
</Properties>
|
||||||
</Component>
|
</Component>
|
||||||
|
<Component class="javax.swing.JLabel" name="statusMessageLabel">
|
||||||
|
<Properties>
|
||||||
|
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||||
|
<ResourceString bundle="org/sleuthkit/autopsy/report/Bundle.properties" key="ReportProgressPanel.statusMessageLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||||
|
</Property>
|
||||||
|
</Properties>
|
||||||
|
</Component>
|
||||||
</SubComponents>
|
</SubComponents>
|
||||||
</Form>
|
</Form>
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* Autopsy Forensic Browser
|
* Autopsy Forensic Browser
|
||||||
*
|
*
|
||||||
* Copyright 2012 Basis Technology Corp.
|
* Copyright 2011-2016 Basis Technology Corp.
|
||||||
* Contact: carrier <at> sleuthkit <dot> org
|
* Contact: carrier <at> sleuthkit <dot> org
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
@ -19,22 +19,32 @@
|
|||||||
package org.sleuthkit.autopsy.report;
|
package org.sleuthkit.autopsy.report;
|
||||||
|
|
||||||
import org.openide.util.NbBundle;
|
import org.openide.util.NbBundle;
|
||||||
|
|
||||||
import java.awt.*;
|
import java.awt.*;
|
||||||
import java.awt.event.MouseEvent;
|
import java.awt.event.MouseEvent;
|
||||||
import java.awt.event.MouseListener;
|
import java.awt.event.MouseListener;
|
||||||
|
import java.beans.PropertyChangeListener;
|
||||||
|
import java.beans.PropertyChangeSupport;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A panel used by a report generation module to show progress.
|
||||||
|
*/
|
||||||
public class ReportProgressPanel extends javax.swing.JPanel {
|
public class ReportProgressPanel extends javax.swing.JPanel {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
private static final Logger logger = Logger.getLogger(ReportProgressPanel.class.getName());
|
private static final Logger logger = Logger.getLogger(ReportProgressPanel.class.getName());
|
||||||
private ReportStatus STATUS;
|
private static final Color GREEN = new Color(50, 205, 50);
|
||||||
|
private static final Color RED = new Color(178, 34, 34);
|
||||||
|
private final PropertyChangeSupport pcs = new PropertyChangeSupport(this);
|
||||||
|
private ReportStatus status;
|
||||||
|
|
||||||
// Enum to represent if a report is waiting,
|
/**
|
||||||
// running, done, or has been canceled
|
* Used by a report generation module to communicate report generation
|
||||||
|
* status to this panel and its listeners.
|
||||||
|
*/
|
||||||
public enum ReportStatus {
|
public enum ReportStatus {
|
||||||
|
|
||||||
QUEUING,
|
QUEUING,
|
||||||
@ -45,64 +55,60 @@ public class ReportProgressPanel extends javax.swing.JPanel {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates new form ReportProgressPanel
|
* Constructs a panel used by report generation module to show progress.
|
||||||
|
*
|
||||||
|
* @param reportName The name of the report being generated.
|
||||||
|
* @param reportPath The path to the report file.
|
||||||
*/
|
*/
|
||||||
public ReportProgressPanel(String reportName, String reportPath) {
|
public ReportProgressPanel(String reportName, String reportPath) {
|
||||||
initComponents();
|
initComponents();
|
||||||
customInit(reportName, reportPath);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void customInit(String reportName, String reportPath) {
|
|
||||||
reportProgressBar.setIndeterminate(true);
|
reportProgressBar.setIndeterminate(true);
|
||||||
reportProgressBar.setMaximum(100);
|
reportProgressBar.setMaximum(100);
|
||||||
|
|
||||||
reportLabel.setText(reportName);
|
reportLabel.setText(reportName);
|
||||||
processingLabel.setText(NbBundle.getMessage(this.getClass(), "ReportProgressPanel.progress.queuing"));
|
statusMessageLabel.setText(NbBundle.getMessage(this.getClass(), "ReportProgressPanel.progress.queuing"));
|
||||||
STATUS = ReportStatus.QUEUING;
|
status = ReportStatus.QUEUING;
|
||||||
|
if (null != reportPath) {
|
||||||
if (reportPath != null) {
|
|
||||||
pathLabel.setText("<html><u>" + shortenPath(reportPath) + "</u></html>"); //NON-NLS
|
pathLabel.setText("<html><u>" + shortenPath(reportPath) + "</u></html>"); //NON-NLS
|
||||||
pathLabel.setToolTipText(reportPath);
|
pathLabel.setToolTipText(reportPath);
|
||||||
|
String linkPath = reportPath;
|
||||||
// Add the "link" effect to the pathLabel
|
|
||||||
final String linkPath = reportPath;
|
|
||||||
pathLabel.addMouseListener(new MouseListener() {
|
pathLabel.addMouseListener(new MouseListener() {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void mouseClicked(MouseEvent e) {
|
public void mouseClicked(MouseEvent mouseEvent) {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void mousePressed(MouseEvent e) {
|
public void mousePressed(MouseEvent mouseEvent) {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void mouseReleased(MouseEvent e) {
|
public void mouseReleased(MouseEvent mouseEvent) {
|
||||||
File file = new File(linkPath);
|
File file = new File(linkPath);
|
||||||
try {
|
try {
|
||||||
Desktop.getDesktop().open(file);
|
Desktop.getDesktop().open(file);
|
||||||
} catch (IOException ex) {
|
} catch (IOException ioex) {
|
||||||
} catch (IllegalArgumentException ex) {
|
logger.log(Level.SEVERE, "Error opening report file", ioex);
|
||||||
|
} catch (IllegalArgumentException iaEx) {
|
||||||
|
logger.log(Level.SEVERE, "Error opening report file", iaEx);
|
||||||
try {
|
try {
|
||||||
// try to open the parent path if the file doens't exist
|
|
||||||
Desktop.getDesktop().open(file.getParentFile());
|
Desktop.getDesktop().open(file.getParentFile());
|
||||||
} catch (IOException ex1) {
|
} catch (IOException ioEx2) {
|
||||||
|
logger.log(Level.SEVERE, "Error opening report file parent", ioEx2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void mouseEntered(MouseEvent e) {
|
public void mouseEntered(MouseEvent e3) {
|
||||||
pathLabel.setForeground(Color.DARK_GRAY);
|
pathLabel.setForeground(Color.DARK_GRAY);
|
||||||
setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
|
setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void mouseExited(MouseEvent e) {
|
public void mouseExited(MouseEvent e4) {
|
||||||
pathLabel.setForeground(Color.BLACK);
|
pathLabel.setForeground(Color.BLACK);
|
||||||
setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
|
setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
|
||||||
}
|
}
|
||||||
|
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
pathLabel.setText(NbBundle.getMessage(this.getClass(), "ReportProgressPanel.initPathLabel.noFile"));
|
pathLabel.setText(NbBundle.getMessage(this.getClass(), "ReportProgressPanel.initPathLabel.noFile"));
|
||||||
@ -110,185 +116,196 @@ public class ReportProgressPanel extends javax.swing.JPanel {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return a shortened version of the given path.
|
* Adds a property change listener to this panel.
|
||||||
|
*
|
||||||
|
* @param listener The listener to be added.
|
||||||
*/
|
*/
|
||||||
private String shortenPath(String path) {
|
@Override
|
||||||
if (path.length() > 100) {
|
public void addPropertyChangeListener(PropertyChangeListener listener) {
|
||||||
path = path.substring(0, 10 + path.substring(10).indexOf(File.separator) + 1) + "..."
|
this.pcs.addPropertyChangeListener(listener);
|
||||||
+ path.substring((path.length() - 70) + path.substring(path.length() - 70).indexOf(File.separator));
|
|
||||||
}
|
|
||||||
return path;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return the current ReportStatus of this report.
|
* Removes a property change listener from this panel.
|
||||||
*
|
*
|
||||||
* @return ReportStatus status of this report
|
* @param listener The listener to be removed.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void removePropertyChangeListener(PropertyChangeListener listener) {
|
||||||
|
this.pcs.removePropertyChangeListener(listener);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the current status of the generation of the report.
|
||||||
|
*
|
||||||
|
* @return The report generation status as a ReportStatus enum.
|
||||||
*/
|
*/
|
||||||
public ReportStatus getStatus() {
|
public ReportStatus getStatus() {
|
||||||
return STATUS;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Start the JProgressBar for this report.
|
* Starts the progress bar component of this panel.
|
||||||
*
|
|
||||||
* Enables the cancelButton, updates the processingLabel, and changes this
|
|
||||||
* report's ReportStatus.
|
|
||||||
*/
|
*/
|
||||||
public void start() {
|
public void start() {
|
||||||
EventQueue.invokeLater(new Runnable() {
|
EventQueue.invokeLater(() -> {
|
||||||
@Override
|
statusMessageLabel.setText(NbBundle.getMessage(this.getClass(), "ReportProgressPanel.start.progress.text"));
|
||||||
public void run() {
|
status = ReportStatus.RUNNING;
|
||||||
processingLabel.setText(NbBundle.getMessage(this.getClass(), "ReportProgressPanel.start.progress.text"));
|
|
||||||
STATUS = ReportStatus.RUNNING;
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the maximum progress for this report's JProgressBar.
|
* Sets the maximum value of the progress bar component of this panel.
|
||||||
*
|
*
|
||||||
* @param max maximum progress for JProgressBar
|
* @param max The maximum value.
|
||||||
*/
|
*/
|
||||||
public void setMaximumProgress(final int max) {
|
public void setMaximumProgress(int max) {
|
||||||
EventQueue.invokeLater(new Runnable() {
|
EventQueue.invokeLater(() -> {
|
||||||
@Override
|
if (status != ReportStatus.CANCELED) {
|
||||||
public void run() {
|
|
||||||
if (STATUS != ReportStatus.CANCELED) {
|
|
||||||
reportProgressBar.setMaximum(max);
|
reportProgressBar.setMaximum(max);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Increment the JProgressBar for this report by one unit.
|
* Increments the current value of the progress bar component of this panel
|
||||||
|
* by one unit.
|
||||||
*/
|
*/
|
||||||
public void increment() {
|
public void increment() {
|
||||||
EventQueue.invokeLater(new Runnable() {
|
EventQueue.invokeLater(() -> {
|
||||||
@Override
|
if (status != ReportStatus.CANCELED) {
|
||||||
public void run() {
|
|
||||||
if (STATUS != ReportStatus.CANCELED) {
|
|
||||||
reportProgressBar.setValue(reportProgressBar.getValue() + 1);
|
reportProgressBar.setValue(reportProgressBar.getValue() + 1);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the value of the JProgressBar for this report.
|
* Sets the current value of the progress bar component of this panel.
|
||||||
*
|
*
|
||||||
* @param value value to be set at
|
* @param value The value to be set.
|
||||||
*/
|
*/
|
||||||
public void setProgress(final int value) {
|
public void setProgress(int value) {
|
||||||
EventQueue.invokeLater(new Runnable() {
|
EventQueue.invokeLater(() -> {
|
||||||
@Override
|
if (status != ReportStatus.CANCELED) {
|
||||||
public void run() {
|
|
||||||
if (STATUS != ReportStatus.CANCELED) {
|
|
||||||
reportProgressBar.setValue(value);
|
reportProgressBar.setValue(value);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Changes the status of the JProgressBar to be determinate or
|
* Changes the the progress bar component of this panel to be determinate or
|
||||||
* indeterminate.
|
* indeterminate.
|
||||||
*
|
*
|
||||||
* @param indeterminate sets the JProgressBar to be indeterminate if true,
|
* @param indeterminate True if the progress bar should be set to
|
||||||
* determinate otherwise
|
* indeterminate.
|
||||||
*/
|
*/
|
||||||
public void setIndeterminate(final boolean indeterminate) {
|
public void setIndeterminate(boolean indeterminate) {
|
||||||
EventQueue.invokeLater(new Runnable() {
|
EventQueue.invokeLater(() -> {
|
||||||
@Override
|
if (status != ReportStatus.CANCELED) {
|
||||||
public void run() {
|
|
||||||
if (STATUS != ReportStatus.CANCELED) {
|
|
||||||
reportProgressBar.setIndeterminate(indeterminate);
|
reportProgressBar.setIndeterminate(indeterminate);
|
||||||
}
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Changes the status message label component of this panel to show a given
|
||||||
|
* processing status message. For example, updateStatusLabel("Now processing
|
||||||
|
* files...") sets the label text to "Now processing files..."
|
||||||
|
*
|
||||||
|
* @param statusMessage String to use as label text.
|
||||||
|
*/
|
||||||
|
public void updateStatusLabel(String statusMessage) {
|
||||||
|
EventQueue.invokeLater(() -> {
|
||||||
|
if (status != ReportStatus.CANCELED) {
|
||||||
|
statusMessageLabel.setText(statusMessage);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Change the text of this report's status label. The text given will be the
|
* Makes the components of this panel indicate the final status of
|
||||||
* full text used. e.g. updateStatusLabel("Now processing files...") sets
|
* generation of the report.
|
||||||
* the label to "Now processing files..."
|
|
||||||
*
|
*
|
||||||
* @param status String to use as status
|
* @param reportStatus The final status, must be COMPLETE or ERROR.
|
||||||
*/
|
|
||||||
public void updateStatusLabel(final String status) {
|
|
||||||
EventQueue.invokeLater(new Runnable() {
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
if (STATUS != ReportStatus.CANCELED) {
|
|
||||||
processingLabel.setText(status);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Declare the report completed. This will fill the JProgressBar, update the
|
|
||||||
* cancelButton to completed, and disallow any cancellation of this report.
|
|
||||||
*
|
|
||||||
* @deprecated Use {@link #complete(ReportStatus)}
|
|
||||||
*/
|
|
||||||
@Deprecated
|
|
||||||
public void complete() {
|
|
||||||
complete(ReportStatus.COMPLETE);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Declare the report completed ands sets if completed successfully or with
|
|
||||||
* errors. This will fill the JProgressBar, update the cancelButton to
|
|
||||||
* completed, and disallow any cancellation of this report.
|
|
||||||
*
|
|
||||||
* @param reportStatus set to appropriate ResultStatus enum.
|
|
||||||
*/
|
*/
|
||||||
public void complete(ReportStatus reportStatus) {
|
public void complete(ReportStatus reportStatus) {
|
||||||
EventQueue.invokeLater(new Runnable() {
|
EventQueue.invokeLater(() -> {
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
// make sure we disable an indeterminate
|
|
||||||
reportProgressBar.setIndeterminate(false);
|
reportProgressBar.setIndeterminate(false);
|
||||||
|
if (status != ReportStatus.CANCELED) {
|
||||||
if (STATUS != ReportStatus.CANCELED) {
|
|
||||||
switch (reportStatus) {
|
switch (reportStatus) {
|
||||||
case COMPLETE: {
|
case COMPLETE: {
|
||||||
STATUS = ReportStatus.COMPLETE;
|
ReportStatus oldValue = status;
|
||||||
processingLabel.setForeground(Color.BLACK);
|
status = ReportStatus.COMPLETE;
|
||||||
processingLabel.setText(
|
statusMessageLabel.setForeground(Color.BLACK);
|
||||||
NbBundle.getMessage(this.getClass(), "ReportProgressPanel.complete.processLbl.text"));
|
statusMessageLabel.setText(NbBundle.getMessage(this.getClass(), "ReportProgressPanel.complete.processLbl.text"));
|
||||||
reportProgressBar.setValue(reportProgressBar.getMaximum());
|
reportProgressBar.setValue(reportProgressBar.getMaximum());
|
||||||
reportProgressBar.setStringPainted(true);
|
reportProgressBar.setStringPainted(true);
|
||||||
// set reportProgressBar color as green.
|
reportProgressBar.setForeground(GREEN);
|
||||||
reportProgressBar.setForeground(new Color(50, 205, 50));
|
|
||||||
reportProgressBar.setString("Complete"); //NON-NLS
|
reportProgressBar.setString("Complete"); //NON-NLS
|
||||||
|
pcs.firePropertyChange(ReportStatus.COMPLETE.toString(), oldValue, status);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case ERROR: {
|
case ERROR: {
|
||||||
STATUS = ReportStatus.ERROR;
|
ReportStatus oldValue = status;
|
||||||
processingLabel.setForeground(new Color(178, 34, 34));
|
status = ReportStatus.ERROR;
|
||||||
processingLabel.setText(
|
statusMessageLabel.setForeground(RED);
|
||||||
NbBundle.getMessage(this.getClass(), "ReportProgressPanel.complete.processLb2.text"));
|
statusMessageLabel.setText(NbBundle.getMessage(this.getClass(), "ReportProgressPanel.complete.processLb2.text"));
|
||||||
reportProgressBar.setValue(reportProgressBar.getMaximum());
|
reportProgressBar.setValue(reportProgressBar.getMaximum());
|
||||||
reportProgressBar.setStringPainted(true);
|
reportProgressBar.setStringPainted(true);
|
||||||
// set reportProgressBar color as red.
|
reportProgressBar.setForeground(RED);
|
||||||
reportProgressBar.setForeground(new Color(178, 34, 34));
|
|
||||||
reportProgressBar.setString("Error"); //NON-NLS
|
reportProgressBar.setString("Error"); //NON-NLS
|
||||||
|
pcs.firePropertyChange(ReportStatus.COMPLETE.toString(), oldValue, status);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
// add finer grained result codes here.
|
|
||||||
default: {
|
default: {
|
||||||
logger.log(Level.SEVERE, "Invalid ReportStatus code {0}", reportStatus); //NON-NLS
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
});
|
});
|
||||||
// Do something with the button to change the icon and make not clickable
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Makes the components of this panel indicate generation of the report was
|
||||||
|
* cancelled.
|
||||||
|
*/
|
||||||
|
void cancel() {
|
||||||
|
switch (status) {
|
||||||
|
case COMPLETE:
|
||||||
|
break;
|
||||||
|
case CANCELED:
|
||||||
|
break;
|
||||||
|
case ERROR:
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
ReportStatus oldValue = status;
|
||||||
|
status = ReportStatus.CANCELED;
|
||||||
|
reportProgressBar.setIndeterminate(false);
|
||||||
|
reportProgressBar.setValue(0);
|
||||||
|
reportProgressBar.setStringPainted(true);
|
||||||
|
reportProgressBar.setForeground(RED); // Red
|
||||||
|
reportProgressBar.setString("Cancelled"); //NON-NLS
|
||||||
|
pcs.firePropertyChange(ReportStatus.CANCELED.toString(), oldValue, status);
|
||||||
|
statusMessageLabel.setForeground(RED);
|
||||||
|
statusMessageLabel.setText(NbBundle.getMessage(this.getClass(), "ReportProgressPanel.cancel.procLbl.text"));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets a shortened version of a file path.
|
||||||
|
*
|
||||||
|
* @param path The path to shorten.
|
||||||
|
*
|
||||||
|
* @return The shortened path.
|
||||||
|
*/
|
||||||
|
private String shortenPath(String path) {
|
||||||
|
if (path.length() > 100) {
|
||||||
|
return path.substring(0, 10 + path.substring(10).indexOf(File.separator) + 1) + "..."
|
||||||
|
+ path.substring((path.length() - 70) + path.substring(path.length() - 70).indexOf(File.separator));
|
||||||
|
} else {
|
||||||
|
return path;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -303,8 +320,8 @@ public class ReportProgressPanel extends javax.swing.JPanel {
|
|||||||
reportProgressBar = new javax.swing.JProgressBar();
|
reportProgressBar = new javax.swing.JProgressBar();
|
||||||
reportLabel = new javax.swing.JLabel();
|
reportLabel = new javax.swing.JLabel();
|
||||||
pathLabel = new javax.swing.JLabel();
|
pathLabel = new javax.swing.JLabel();
|
||||||
processingLabel = new javax.swing.JLabel();
|
|
||||||
separationLabel = new javax.swing.JLabel();
|
separationLabel = new javax.swing.JLabel();
|
||||||
|
statusMessageLabel = new javax.swing.JLabel();
|
||||||
|
|
||||||
setFont(getFont().deriveFont(getFont().getStyle() & ~java.awt.Font.BOLD, 11));
|
setFont(getFont().deriveFont(getFont().getStyle() & ~java.awt.Font.BOLD, 11));
|
||||||
setMinimumSize(new java.awt.Dimension(486, 68));
|
setMinimumSize(new java.awt.Dimension(486, 68));
|
||||||
@ -316,13 +333,13 @@ public class ReportProgressPanel extends javax.swing.JPanel {
|
|||||||
|
|
||||||
pathLabel.setFont(pathLabel.getFont().deriveFont(pathLabel.getFont().getStyle() & ~java.awt.Font.BOLD, 11));
|
pathLabel.setFont(pathLabel.getFont().deriveFont(pathLabel.getFont().getStyle() & ~java.awt.Font.BOLD, 11));
|
||||||
org.openide.awt.Mnemonics.setLocalizedText(pathLabel, org.openide.util.NbBundle.getMessage(ReportProgressPanel.class, "ReportProgressPanel.pathLabel.text")); // NOI18N
|
org.openide.awt.Mnemonics.setLocalizedText(pathLabel, org.openide.util.NbBundle.getMessage(ReportProgressPanel.class, "ReportProgressPanel.pathLabel.text")); // NOI18N
|
||||||
|
pathLabel.setVerticalAlignment(javax.swing.SwingConstants.TOP);
|
||||||
processingLabel.setFont(processingLabel.getFont().deriveFont((processingLabel.getFont().getStyle() | java.awt.Font.ITALIC) & ~java.awt.Font.BOLD, 10));
|
|
||||||
org.openide.awt.Mnemonics.setLocalizedText(processingLabel, org.openide.util.NbBundle.getMessage(ReportProgressPanel.class, "ReportProgressPanel.processingLabel.text")); // NOI18N
|
|
||||||
|
|
||||||
separationLabel.setFont(separationLabel.getFont().deriveFont(separationLabel.getFont().getStyle() & ~java.awt.Font.BOLD, 11));
|
separationLabel.setFont(separationLabel.getFont().deriveFont(separationLabel.getFont().getStyle() & ~java.awt.Font.BOLD, 11));
|
||||||
org.openide.awt.Mnemonics.setLocalizedText(separationLabel, org.openide.util.NbBundle.getMessage(ReportProgressPanel.class, "ReportProgressPanel.separationLabel.text")); // NOI18N
|
org.openide.awt.Mnemonics.setLocalizedText(separationLabel, org.openide.util.NbBundle.getMessage(ReportProgressPanel.class, "ReportProgressPanel.separationLabel.text")); // NOI18N
|
||||||
|
|
||||||
|
org.openide.awt.Mnemonics.setLocalizedText(statusMessageLabel, org.openide.util.NbBundle.getMessage(ReportProgressPanel.class, "ReportProgressPanel.statusMessageLabel.text")); // NOI18N
|
||||||
|
|
||||||
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
|
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
|
||||||
this.setLayout(layout);
|
this.setLayout(layout);
|
||||||
layout.setHorizontalGroup(
|
layout.setHorizontalGroup(
|
||||||
@ -330,10 +347,8 @@ public class ReportProgressPanel extends javax.swing.JPanel {
|
|||||||
.addGroup(layout.createSequentialGroup()
|
.addGroup(layout.createSequentialGroup()
|
||||||
.addContainerGap()
|
.addContainerGap()
|
||||||
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||||
.addComponent(processingLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
.addComponent(statusMessageLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
||||||
.addGroup(layout.createSequentialGroup()
|
|
||||||
.addComponent(reportProgressBar, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
.addComponent(reportProgressBar, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
||||||
.addGap(58, 58, 58))
|
|
||||||
.addGroup(layout.createSequentialGroup()
|
.addGroup(layout.createSequentialGroup()
|
||||||
.addComponent(reportLabel)
|
.addComponent(reportLabel)
|
||||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||||
@ -350,45 +365,32 @@ public class ReportProgressPanel extends javax.swing.JPanel {
|
|||||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||||
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
|
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
|
||||||
.addComponent(reportLabel)
|
.addComponent(reportLabel)
|
||||||
.addComponent(pathLabel)
|
.addComponent(pathLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
||||||
.addComponent(separationLabel))
|
.addComponent(separationLabel))
|
||||||
.addGap(0, 0, 0)
|
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||||
.addComponent(processingLabel)
|
.addComponent(statusMessageLabel)
|
||||||
.addContainerGap(20, Short.MAX_VALUE))
|
.addGap(13, 13, 13))
|
||||||
);
|
);
|
||||||
}// </editor-fold>//GEN-END:initComponents
|
}// </editor-fold>//GEN-END:initComponents
|
||||||
|
|
||||||
/**
|
|
||||||
* Cancels the current report, based on it's status. If the report is
|
|
||||||
* complete or has already been completed, nothing happens.
|
|
||||||
*/
|
|
||||||
void cancel() {
|
|
||||||
switch (STATUS) {
|
|
||||||
case COMPLETE:
|
|
||||||
break;
|
|
||||||
case CANCELED:
|
|
||||||
break;
|
|
||||||
case ERROR:
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
STATUS = ReportStatus.CANCELED;
|
|
||||||
reportProgressBar.setIndeterminate(false);
|
|
||||||
reportProgressBar.setValue(0);
|
|
||||||
reportProgressBar.setStringPainted(true);
|
|
||||||
// set reportProgressBar color as red.
|
|
||||||
reportProgressBar.setForeground(new Color(178, 34, 34));
|
|
||||||
reportProgressBar.setString("Cancelled"); //NON-NLS
|
|
||||||
processingLabel.setForeground(new Color(178, 34, 34));
|
|
||||||
processingLabel.setText(NbBundle.getMessage(this.getClass(), "ReportProgressPanel.cancel.procLbl.text"));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Variables declaration - do not modify//GEN-BEGIN:variables
|
// Variables declaration - do not modify//GEN-BEGIN:variables
|
||||||
private javax.swing.JLabel pathLabel;
|
private javax.swing.JLabel pathLabel;
|
||||||
private javax.swing.JLabel processingLabel;
|
|
||||||
private javax.swing.JLabel reportLabel;
|
private javax.swing.JLabel reportLabel;
|
||||||
private javax.swing.JProgressBar reportProgressBar;
|
private javax.swing.JProgressBar reportProgressBar;
|
||||||
private javax.swing.JLabel separationLabel;
|
private javax.swing.JLabel separationLabel;
|
||||||
|
private javax.swing.JLabel statusMessageLabel;
|
||||||
// End of variables declaration//GEN-END:variables
|
// End of variables declaration//GEN-END:variables
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Makes the components of this panel indicate the generation of the report
|
||||||
|
* is completed.
|
||||||
|
*
|
||||||
|
* @deprecated Use {@link #complete(ReportStatus)}
|
||||||
|
*/
|
||||||
|
@Deprecated
|
||||||
|
public void complete() {
|
||||||
|
complete(ReportStatus.COMPLETE);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
CTL_MakeTimeline="Timeline"
|
CTL_MakeTimeline=Timeline
|
||||||
CTL_TimeLineTopComponentAction=TimeLineTopComponent
|
CTL_TimeLineTopComponentAction=TimeLineTopComponent
|
||||||
CTL_TimeLineTopComponent=Timeline Window
|
CTL_TimeLineTopComponent=Timeline Window
|
||||||
HINT_TimeLineTopComponent=This is a Timeline window
|
HINT_TimeLineTopComponent=This is a Timeline window
|
||||||
@ -24,7 +24,5 @@ TimelinePanel.jButton7.text=3d
|
|||||||
TimelinePanel.jButton2.text=1m
|
TimelinePanel.jButton2.text=1m
|
||||||
TimelinePanel.jButton3.text=3m
|
TimelinePanel.jButton3.text=3m
|
||||||
TimelinePanel.jButton4.text=2w
|
TimelinePanel.jButton4.text=2w
|
||||||
OpenTimelineAction.title=Timeline
|
|
||||||
OpenTimeLineAction.msgdlg.text=Could not create timeline, there are no data sources.
|
|
||||||
ProgressWindow.progressHeader.text=\
|
ProgressWindow.progressHeader.text=\
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* Autopsy Forensic Browser
|
* Autopsy Forensic Browser
|
||||||
*
|
*
|
||||||
* Copyright 2013 Basis Technology Corp.
|
* Copyright 2013-16 Basis Technology Corp.
|
||||||
* Contact: carrier <at> sleuthkit <dot> org
|
* Contact: carrier <at> sleuthkit <dot> org
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
@ -18,8 +18,8 @@
|
|||||||
*/
|
*/
|
||||||
package org.sleuthkit.autopsy.timeline;
|
package org.sleuthkit.autopsy.timeline;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
import javax.swing.JOptionPane;
|
|
||||||
import org.openide.awt.ActionID;
|
import org.openide.awt.ActionID;
|
||||||
import org.openide.awt.ActionReference;
|
import org.openide.awt.ActionReference;
|
||||||
import org.openide.awt.ActionReferences;
|
import org.openide.awt.ActionReferences;
|
||||||
@ -27,10 +27,10 @@ import org.openide.awt.ActionRegistration;
|
|||||||
import org.openide.util.HelpCtx;
|
import org.openide.util.HelpCtx;
|
||||||
import org.openide.util.NbBundle;
|
import org.openide.util.NbBundle;
|
||||||
import org.openide.util.actions.CallableSystemAction;
|
import org.openide.util.actions.CallableSystemAction;
|
||||||
import org.openide.windows.WindowManager;
|
|
||||||
import org.sleuthkit.autopsy.casemodule.Case;
|
import org.sleuthkit.autopsy.casemodule.Case;
|
||||||
import org.sleuthkit.autopsy.core.Installer;
|
import org.sleuthkit.autopsy.core.Installer;
|
||||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||||
|
import org.sleuthkit.autopsy.coreutils.MessageNotifyUtil;
|
||||||
import org.sleuthkit.autopsy.coreutils.ThreadConfined;
|
import org.sleuthkit.autopsy.coreutils.ThreadConfined;
|
||||||
|
|
||||||
@ActionID(category = "Tools", id = "org.sleuthkit.autopsy.timeline.Timeline")
|
@ActionID(category = "Tools", id = "org.sleuthkit.autopsy.timeline.Timeline")
|
||||||
@ -58,35 +58,39 @@ public class OpenTimelineAction extends CallableSystemAction {
|
|||||||
return Case.isCaseOpen() && fxInited;// && Case.getCurrentCase().hasData();
|
return Case.isCaseOpen() && fxInited;// && Case.getCurrentCase().hasData();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@NbBundle.Messages({
|
||||||
|
"OpenTimelineAction.settingsErrorMessage=Failed to initialize timeline settings.",
|
||||||
|
"OpenTimeLineAction.msgdlg.text=Could not create timeline, there are no data sources."})
|
||||||
@Override
|
@Override
|
||||||
@ThreadConfined(type = ThreadConfined.ThreadType.AWT)
|
@ThreadConfined(type = ThreadConfined.ThreadType.AWT)
|
||||||
public void performAction() {
|
public void performAction() {
|
||||||
//check case
|
try {
|
||||||
if (!Case.isCaseOpen()) {
|
Case currentCase = Case.getCurrentCase();
|
||||||
return;
|
|
||||||
}
|
|
||||||
final Case currentCase = Case.getCurrentCase();
|
|
||||||
|
|
||||||
if (currentCase.hasData() == false) {
|
if (currentCase.hasData() == false) {
|
||||||
JOptionPane.showMessageDialog(WindowManager.getDefault().getMainWindow(),
|
MessageNotifyUtil.Message.info(Bundle.OpenTimeLineAction_msgdlg_text());
|
||||||
NbBundle.getMessage(this.getClass(), "OpenTimeLineAction.msgdlg.text"));
|
|
||||||
LOGGER.log(Level.INFO, "Could not create timeline, there are no data sources.");// NON-NLS
|
LOGGER.log(Level.INFO, "Could not create timeline, there are no data sources.");// NON-NLS
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
try {
|
||||||
if (timeLineController == null) {
|
if (timeLineController == null) {
|
||||||
timeLineController = new TimeLineController(currentCase);
|
timeLineController = new TimeLineController(currentCase);
|
||||||
} else if (timeLineController.getAutopsyCase() != currentCase) {
|
} else if (timeLineController.getAutopsyCase() != currentCase) {
|
||||||
timeLineController.closeTimeLine();
|
timeLineController.shutDownTimeLine();
|
||||||
timeLineController = new TimeLineController(currentCase);
|
timeLineController = new TimeLineController(currentCase);
|
||||||
}
|
}
|
||||||
|
|
||||||
timeLineController.openTimeLine();
|
timeLineController.openTimeLine();
|
||||||
|
} catch (IOException iOException) {
|
||||||
|
MessageNotifyUtil.Message.error(Bundle.OpenTimelineAction_settingsErrorMessage());
|
||||||
|
LOGGER.log(Level.SEVERE, "Failed to initialize per case timeline settings.", iOException);
|
||||||
|
}
|
||||||
|
} catch (IllegalStateException e) {
|
||||||
|
//there is no case... Do nothing.
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getName() {
|
public String getName() {
|
||||||
return NbBundle.getMessage(TimeLineTopComponent.class, "OpenTimelineAction.title");
|
return NbBundle.getMessage(OpenTimelineAction.class, "CTL_MakeTimeline");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -0,0 +1,177 @@
|
|||||||
|
/*
|
||||||
|
* Autopsy Forensic Browser
|
||||||
|
*
|
||||||
|
* Copyright 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.timeline;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.io.OutputStream;
|
||||||
|
import java.nio.file.Files;
|
||||||
|
import java.nio.file.Path;
|
||||||
|
import java.nio.file.Paths;
|
||||||
|
import java.util.Objects;
|
||||||
|
import java.util.Properties;
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
import org.sleuthkit.autopsy.casemodule.Case;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provides access to per-case timeline properties (key-value store).
|
||||||
|
*/
|
||||||
|
class PerCaseTimelineProperties {
|
||||||
|
|
||||||
|
private static final String STALE_KEY = "stale"; //NON-NLS
|
||||||
|
private static final String WAS_INGEST_RUNNING_KEY = "was_ingest_running"; // NON-NLS
|
||||||
|
|
||||||
|
private final Case autoCase;
|
||||||
|
private final Path propertiesPath;
|
||||||
|
|
||||||
|
PerCaseTimelineProperties(Case c) {
|
||||||
|
Objects.requireNonNull(c, "Case must not be null");
|
||||||
|
this.autoCase = c;
|
||||||
|
propertiesPath = Paths.get(autoCase.getModuleDirectory(), "Timeline", "timeline.properties"); //NON-NLS
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Is the DB stale, i.e. does it need to be updated because new datasources
|
||||||
|
* (eg) have been added to the case.
|
||||||
|
*
|
||||||
|
* @return true if the db is stale
|
||||||
|
*
|
||||||
|
* @throws IOException if there is a problem reading the state from disk
|
||||||
|
*/
|
||||||
|
public synchronized boolean isDBStale() throws IOException {
|
||||||
|
|
||||||
|
String stale = getProperty(STALE_KEY);
|
||||||
|
return StringUtils.isBlank(stale) ? true : Boolean.valueOf(stale);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* record the state of the events db as stale(true) or not stale(false).
|
||||||
|
*
|
||||||
|
* @param stale the new state of the event db. true for stale, false for not
|
||||||
|
* stale.
|
||||||
|
*
|
||||||
|
* @throws IOException if there was a problem writing the state to disk.
|
||||||
|
*/
|
||||||
|
public synchronized void setDbStale(Boolean stale) throws IOException {
|
||||||
|
setProperty(STALE_KEY, stale.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Was ingest running the last time the database was updated?
|
||||||
|
*
|
||||||
|
* @return true if ingest was running the last time the db was updated
|
||||||
|
*
|
||||||
|
* @throws IOException if there was a problem reading from disk
|
||||||
|
*/
|
||||||
|
public synchronized boolean wasIngestRunning() throws IOException {
|
||||||
|
String stale = getProperty(WAS_INGEST_RUNNING_KEY);
|
||||||
|
return StringUtils.isBlank(stale) ? true : Boolean.valueOf(stale);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* record whether ingest was running during the last time the database was
|
||||||
|
* updated
|
||||||
|
*
|
||||||
|
* @param ingestRunning true if ingest was running
|
||||||
|
*
|
||||||
|
* @throws IOException if there was a problem writing to disk
|
||||||
|
*/
|
||||||
|
public synchronized void setIngestRunning(Boolean ingestRunning) throws IOException {
|
||||||
|
setProperty(WAS_INGEST_RUNNING_KEY, ingestRunning.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a {@link Path} to the properties file. If the file does not exist, it
|
||||||
|
* will be created.
|
||||||
|
*
|
||||||
|
* @return the Path to the properties file.
|
||||||
|
*
|
||||||
|
* @throws IOException if there was a problem creating the properties file
|
||||||
|
*/
|
||||||
|
private synchronized Path getPropertiesPath() throws IOException {
|
||||||
|
|
||||||
|
if (!Files.exists(propertiesPath)) {
|
||||||
|
Path parent = propertiesPath.getParent();
|
||||||
|
Files.createDirectories(parent);
|
||||||
|
Files.createFile(propertiesPath);
|
||||||
|
}
|
||||||
|
return propertiesPath;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the property with the given key.
|
||||||
|
*
|
||||||
|
* @param propertyKey - The property key to get the value for.
|
||||||
|
*
|
||||||
|
* @return - the value associated with the property.
|
||||||
|
*
|
||||||
|
* @throws IOException if there was a problem reading the property from disk
|
||||||
|
*/
|
||||||
|
private synchronized String getProperty(String propertyKey) throws IOException {
|
||||||
|
return getProperties().getProperty(propertyKey);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the given property to the given value.
|
||||||
|
*
|
||||||
|
* @param propertyKey - The key of the property to be modified.
|
||||||
|
* @param propertyValue - the value to set the property to.
|
||||||
|
*
|
||||||
|
* @throws IOException if there was a problem writing the property to disk
|
||||||
|
*/
|
||||||
|
private synchronized void setProperty(String propertyKey, String propertyValue) throws IOException {
|
||||||
|
Path propertiesFile = getPropertiesPath();
|
||||||
|
Properties props = getProperties(propertiesFile);
|
||||||
|
props.setProperty(propertyKey, propertyValue);
|
||||||
|
|
||||||
|
try (OutputStream fos = Files.newOutputStream(propertiesFile)) {
|
||||||
|
props.store(fos, ""); //NON-NLS
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a {@link Properties} object used to store the timeline properties.
|
||||||
|
*
|
||||||
|
* @return a properties object
|
||||||
|
*
|
||||||
|
* @throws IOException if there was a problem reading the .properties file
|
||||||
|
*/
|
||||||
|
private synchronized Properties getProperties() throws IOException {
|
||||||
|
return getProperties(getPropertiesPath());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets a {@link Properties} object populated form the given .properties
|
||||||
|
* file.
|
||||||
|
*
|
||||||
|
* @param propertiesFile a path to the .properties file to load
|
||||||
|
*
|
||||||
|
* @return a properties object
|
||||||
|
*
|
||||||
|
* @throws IOException if there was a problem reading the .properties file
|
||||||
|
*/
|
||||||
|
private synchronized Properties getProperties(final Path propertiesFile) throws IOException {
|
||||||
|
try (InputStream inputStream = Files.newInputStream(propertiesFile)) {
|
||||||
|
Properties props = new Properties();
|
||||||
|
props.load(inputStream);
|
||||||
|
return props;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* Autopsy Forensic Browser
|
* Autopsy Forensic Browser
|
||||||
*
|
*
|
||||||
* Copyright 2015 Basis Technology Corp.
|
* Copyright 2015-16 Basis Technology Corp.
|
||||||
* Contact: carrier <at> sleuthkit <dot> org
|
* Contact: carrier <at> sleuthkit <dot> org
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
@ -61,9 +61,9 @@ public class PromptDialogManager {
|
|||||||
static {
|
static {
|
||||||
Image x = null;
|
Image x = null;
|
||||||
try {
|
try {
|
||||||
x = new Image(new URL("nbresloc:/org/netbeans/core/startup/frame.gif").openStream()); //NOI18N
|
x = new Image(new URL("nbresloc:/org/netbeans/core/startup/frame.gif").openStream()); //NON-NLS
|
||||||
} catch (IOException ex) {
|
} catch (IOException ex) {
|
||||||
LOGGER.log(Level.WARNING, "Failed to load branded icon for progress dialog.", ex); //NOI18N NON-NLS
|
LOGGER.log(Level.WARNING, "Failed to load branded icon for progress dialog.", ex); //NON-NLS
|
||||||
}
|
}
|
||||||
LOGO = x;
|
LOGO = x;
|
||||||
}
|
}
|
||||||
@ -75,6 +75,12 @@ public class PromptDialogManager {
|
|||||||
this.controller = controller;
|
this.controller = controller;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* bring the currently managed dialog (if there is one) to the front
|
||||||
|
*
|
||||||
|
* @return true if a dialog was brought to the front, or false of there is
|
||||||
|
* no currently managed open dialog
|
||||||
|
*/
|
||||||
@ThreadConfined(type = ThreadConfined.ThreadType.JFX)
|
@ThreadConfined(type = ThreadConfined.ThreadType.JFX)
|
||||||
boolean bringCurrentDialogToFront() {
|
boolean bringCurrentDialogToFront() {
|
||||||
if (currentDialog != null && currentDialog.isShowing()) {
|
if (currentDialog != null && currentDialog.isShowing()) {
|
||||||
@ -86,11 +92,12 @@ public class PromptDialogManager {
|
|||||||
|
|
||||||
@NbBundle.Messages({"PromptDialogManager.progressDialog.title=Populating Timeline Data"})
|
@NbBundle.Messages({"PromptDialogManager.progressDialog.title=Populating Timeline Data"})
|
||||||
@ThreadConfined(type = ThreadConfined.ThreadType.JFX)
|
@ThreadConfined(type = ThreadConfined.ThreadType.JFX)
|
||||||
public void showProgressDialog(CancellationProgressTask<?> task) {
|
void showProgressDialog(CancellationProgressTask<?> task) {
|
||||||
currentDialog = new ProgressDialog(task);
|
currentDialog = new ProgressDialog(task);
|
||||||
currentDialog.headerTextProperty().bind(task.titleProperty());
|
currentDialog.initModality(Modality.NONE);
|
||||||
setDialogIcons(currentDialog);
|
|
||||||
currentDialog.setTitle(Bundle.PromptDialogManager_progressDialog_title());
|
currentDialog.setTitle(Bundle.PromptDialogManager_progressDialog_title());
|
||||||
|
setDialogIcons(currentDialog);
|
||||||
|
currentDialog.headerTextProperty().bind(task.titleProperty());
|
||||||
|
|
||||||
DialogPane dialogPane = currentDialog.getDialogPane();
|
DialogPane dialogPane = currentDialog.getDialogPane();
|
||||||
dialogPane.setPrefSize(400, 200); //override autosizing which fails for some reason
|
dialogPane.setPrefSize(400, 200); //override autosizing which fails for some reason
|
||||||
@ -98,6 +105,8 @@ public class PromptDialogManager {
|
|||||||
//co-ordinate task cancelation and dialog hiding.
|
//co-ordinate task cancelation and dialog hiding.
|
||||||
task.setOnCancelled(cancelled -> currentDialog.close());
|
task.setOnCancelled(cancelled -> currentDialog.close());
|
||||||
task.setOnSucceeded(succeeded -> currentDialog.close());
|
task.setOnSucceeded(succeeded -> currentDialog.close());
|
||||||
|
task.setOnFailed(failed -> currentDialog.close());
|
||||||
|
|
||||||
dialogPane.getButtonTypes().setAll(ButtonType.CANCEL);
|
dialogPane.getButtonTypes().setAll(ButtonType.CANCEL);
|
||||||
final Node cancelButton = dialogPane.lookupButton(ButtonType.CANCEL);
|
final Node cancelButton = dialogPane.lookupButton(ButtonType.CANCEL);
|
||||||
cancelButton.disableProperty().bind(task.cancellableProperty().not());
|
cancelButton.disableProperty().bind(task.cancellableProperty().not());
|
||||||
@ -115,14 +124,7 @@ public class PromptDialogManager {
|
|||||||
|
|
||||||
@ThreadConfined(type = ThreadConfined.ThreadType.JFX)
|
@ThreadConfined(type = ThreadConfined.ThreadType.JFX)
|
||||||
static private void setDialogIcons(Dialog<?> dialog) {
|
static private void setDialogIcons(Dialog<?> dialog) {
|
||||||
Stage stage = (Stage) dialog.getDialogPane().getScene().getWindow();
|
((Stage) dialog.getDialogPane().getScene().getWindow()).getIcons().setAll(LOGO);
|
||||||
stage.getIcons().setAll(LOGO);
|
|
||||||
}
|
|
||||||
|
|
||||||
@ThreadConfined(type = ThreadConfined.ThreadType.JFX)
|
|
||||||
static private void setDialogTitle(Dialog<?> dialog) {
|
|
||||||
Stage stage = (Stage) dialog.getDialogPane().getScene().getWindow();
|
|
||||||
stage.setTitle(Bundle.Timeline_confirmation_dialogs_title());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -139,7 +141,7 @@ public class PromptDialogManager {
|
|||||||
currentDialog.initModality(Modality.APPLICATION_MODAL);
|
currentDialog.initModality(Modality.APPLICATION_MODAL);
|
||||||
currentDialog.setHeaderText(Bundle.PromptDialogManager_confirmDuringIngest_headerText());
|
currentDialog.setHeaderText(Bundle.PromptDialogManager_confirmDuringIngest_headerText());
|
||||||
setDialogIcons(currentDialog);
|
setDialogIcons(currentDialog);
|
||||||
setDialogTitle(currentDialog);
|
currentDialog.setTitle(Bundle.Timeline_confirmation_dialogs_title());
|
||||||
|
|
||||||
return currentDialog.showAndWait().map(SHOW_TIMELINE::equals).orElse(false);
|
return currentDialog.showAndWait().map(SHOW_TIMELINE::equals).orElse(false);
|
||||||
}
|
}
|
||||||
@ -152,7 +154,7 @@ public class PromptDialogManager {
|
|||||||
currentDialog.initModality(Modality.APPLICATION_MODAL);
|
currentDialog.initModality(Modality.APPLICATION_MODAL);
|
||||||
currentDialog.setHeaderText(Bundle.PromptDialogManager_rebuildPrompt_headerText());
|
currentDialog.setHeaderText(Bundle.PromptDialogManager_rebuildPrompt_headerText());
|
||||||
setDialogIcons(currentDialog);
|
setDialogIcons(currentDialog);
|
||||||
setDialogTitle(currentDialog);
|
currentDialog.setTitle(Bundle.Timeline_confirmation_dialogs_title());
|
||||||
|
|
||||||
DialogPane dialogPane = currentDialog.getDialogPane();
|
DialogPane dialogPane = currentDialog.getDialogPane();
|
||||||
ListView<String> listView = new ListView<>(FXCollections.observableArrayList(rebuildReasons));
|
ListView<String> listView = new ListView<>(FXCollections.observableArrayList(rebuildReasons));
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* Autopsy Forensic Browser
|
* Autopsy Forensic Browser
|
||||||
*
|
*
|
||||||
* Copyright 2014-2015 Basis Technology Corp.
|
* Copyright 2014-2016 Basis Technology Corp.
|
||||||
* Contact: carrier <at> sleuthkit <dot> org
|
* Contact: carrier <at> sleuthkit <dot> org
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
@ -21,8 +21,7 @@ package org.sleuthkit.autopsy.timeline;
|
|||||||
import java.awt.HeadlessException;
|
import java.awt.HeadlessException;
|
||||||
import java.beans.PropertyChangeEvent;
|
import java.beans.PropertyChangeEvent;
|
||||||
import java.beans.PropertyChangeListener;
|
import java.beans.PropertyChangeListener;
|
||||||
import java.sql.ResultSet;
|
import java.io.IOException;
|
||||||
import java.sql.SQLException;
|
|
||||||
import java.time.ZoneId;
|
import java.time.ZoneId;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
@ -31,9 +30,10 @@ import java.util.TimeZone;
|
|||||||
import java.util.concurrent.ExecutionException;
|
import java.util.concurrent.ExecutionException;
|
||||||
import java.util.concurrent.ExecutorService;
|
import java.util.concurrent.ExecutorService;
|
||||||
import java.util.concurrent.Executors;
|
import java.util.concurrent.Executors;
|
||||||
|
import java.util.function.Consumer;
|
||||||
|
import java.util.function.Function;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
import javafx.application.Platform;
|
import javafx.application.Platform;
|
||||||
import javafx.beans.InvalidationListener;
|
|
||||||
import javafx.beans.Observable;
|
import javafx.beans.Observable;
|
||||||
import javafx.beans.property.ReadOnlyBooleanProperty;
|
import javafx.beans.property.ReadOnlyBooleanProperty;
|
||||||
import javafx.beans.property.ReadOnlyBooleanWrapper;
|
import javafx.beans.property.ReadOnlyBooleanWrapper;
|
||||||
@ -49,7 +49,6 @@ import javafx.collections.FXCollections;
|
|||||||
import javafx.collections.ObservableList;
|
import javafx.collections.ObservableList;
|
||||||
import javafx.concurrent.Task;
|
import javafx.concurrent.Task;
|
||||||
import javafx.concurrent.Worker;
|
import javafx.concurrent.Worker;
|
||||||
import javafx.scene.control.Dialog;
|
|
||||||
import javax.annotation.concurrent.GuardedBy;
|
import javax.annotation.concurrent.GuardedBy;
|
||||||
import javax.annotation.concurrent.Immutable;
|
import javax.annotation.concurrent.Immutable;
|
||||||
import javax.swing.SwingUtilities;
|
import javax.swing.SwingUtilities;
|
||||||
@ -83,9 +82,6 @@ import org.sleuthkit.autopsy.timeline.utils.IntervalUtils;
|
|||||||
import org.sleuthkit.autopsy.timeline.zooming.DescriptionLoD;
|
import org.sleuthkit.autopsy.timeline.zooming.DescriptionLoD;
|
||||||
import org.sleuthkit.autopsy.timeline.zooming.EventTypeZoomLevel;
|
import org.sleuthkit.autopsy.timeline.zooming.EventTypeZoomLevel;
|
||||||
import org.sleuthkit.autopsy.timeline.zooming.ZoomParams;
|
import org.sleuthkit.autopsy.timeline.zooming.ZoomParams;
|
||||||
import org.sleuthkit.datamodel.SleuthkitCase;
|
|
||||||
import org.sleuthkit.datamodel.SleuthkitCase.CaseDbQuery;
|
|
||||||
import org.sleuthkit.datamodel.TskCoreException;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Controller in the MVC design along with model = {@link FilteredEventsModel}
|
* Controller in the MVC design along with model = {@link FilteredEventsModel}
|
||||||
@ -139,9 +135,6 @@ public class TimeLineController {
|
|||||||
|
|
||||||
private final ReadOnlyStringWrapper status = new ReadOnlyStringWrapper();
|
private final ReadOnlyStringWrapper status = new ReadOnlyStringWrapper();
|
||||||
|
|
||||||
@ThreadConfined(type = ThreadConfined.ThreadType.JFX)
|
|
||||||
private Dialog<?> currentDialog;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* status is a string that will be displayed in the status bar as a kind of
|
* status is a string that will be displayed in the status bar as a kind of
|
||||||
* user hint/information when it is not empty
|
* user hint/information when it is not empty
|
||||||
@ -156,12 +149,13 @@ public class TimeLineController {
|
|||||||
status.set(string);
|
status.set(string);
|
||||||
}
|
}
|
||||||
private final Case autoCase;
|
private final Case autoCase;
|
||||||
|
private final PerCaseTimelineProperties perCaseTimelineProperties;
|
||||||
|
|
||||||
@ThreadConfined(type = ThreadConfined.ThreadType.JFX)
|
@ThreadConfined(type = ThreadConfined.ThreadType.JFX)
|
||||||
private final ObservableList<DescriptionFilter> quickHideMaskFilters = FXCollections.observableArrayList();
|
private final ObservableList<DescriptionFilter> quickHideFilters = FXCollections.observableArrayList();
|
||||||
|
|
||||||
public ObservableList<DescriptionFilter> getQuickHideFilters() {
|
public ObservableList<DescriptionFilter> getQuickHideFilters() {
|
||||||
return quickHideMaskFilters;
|
return quickHideFilters;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -219,13 +213,12 @@ public class TimeLineController {
|
|||||||
@GuardedBy("this")
|
@GuardedBy("this")
|
||||||
private final ReadOnlyObjectWrapper<ZoomParams> currentParams = new ReadOnlyObjectWrapper<>();
|
private final ReadOnlyObjectWrapper<ZoomParams> currentParams = new ReadOnlyObjectWrapper<>();
|
||||||
|
|
||||||
//all members should be access with the intrinsict lock of this object held
|
|
||||||
//selected events (ie shown in the result viewer)
|
//selected events (ie shown in the result viewer)
|
||||||
@GuardedBy("this")
|
@GuardedBy("this")
|
||||||
private final ObservableList<Long> selectedEventIDs = FXCollections.<Long>synchronizedObservableList(FXCollections.<Long>observableArrayList());
|
private final ObservableList<Long> selectedEventIDs = FXCollections.<Long>synchronizedObservableList(FXCollections.<Long>observableArrayList());
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return an unmodifiable list of the selected event ids
|
* @return a list of the selected event ids
|
||||||
*/
|
*/
|
||||||
synchronized public ObservableList<Long> getSelectedEventIDs() {
|
synchronized public ObservableList<Long> getSelectedEventIDs() {
|
||||||
return selectedEventIDs;
|
return selectedEventIDs;
|
||||||
@ -241,14 +234,8 @@ public class TimeLineController {
|
|||||||
return selectedTimeRange.getReadOnlyProperty();
|
return selectedTimeRange.getReadOnlyProperty();
|
||||||
}
|
}
|
||||||
|
|
||||||
public ReadOnlyBooleanProperty getNewEventsFlag() {
|
public ReadOnlyBooleanProperty eventsDBStaleProperty() {
|
||||||
return newEventsFlag.getReadOnlyProperty();
|
return eventsDBStale.getReadOnlyProperty();
|
||||||
}
|
|
||||||
|
|
||||||
private final ReadOnlyBooleanWrapper needsHistogramRebuild = new ReadOnlyBooleanWrapper(false);
|
|
||||||
|
|
||||||
public ReadOnlyBooleanProperty getNeedsHistogramRebuild() {
|
|
||||||
return needsHistogramRebuild.getReadOnlyProperty();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
synchronized public ReadOnlyBooleanProperty getCanAdvance() {
|
synchronized public ReadOnlyBooleanProperty getCanAdvance() {
|
||||||
@ -258,28 +245,26 @@ public class TimeLineController {
|
|||||||
synchronized public ReadOnlyBooleanProperty getCanRetreat() {
|
synchronized public ReadOnlyBooleanProperty getCanRetreat() {
|
||||||
return historyManager.getCanRetreat();
|
return historyManager.getCanRetreat();
|
||||||
}
|
}
|
||||||
private final ReadOnlyBooleanWrapper newEventsFlag = new ReadOnlyBooleanWrapper(false);
|
private final ReadOnlyBooleanWrapper eventsDBStale = new ReadOnlyBooleanWrapper(true);
|
||||||
|
|
||||||
private final PromptDialogManager promptDialogManager = new PromptDialogManager(this);
|
private final PromptDialogManager promptDialogManager = new PromptDialogManager(this);
|
||||||
|
|
||||||
public TimeLineController(Case autoCase) {
|
public TimeLineController(Case autoCase) throws IOException {
|
||||||
this.autoCase = autoCase;
|
this.autoCase = autoCase;
|
||||||
|
this.perCaseTimelineProperties = new PerCaseTimelineProperties(autoCase);
|
||||||
|
eventsDBStale.set(perCaseTimelineProperties.isDBStale());
|
||||||
|
eventsRepository = new EventsRepository(autoCase, currentParams.getReadOnlyProperty());
|
||||||
/*
|
/*
|
||||||
* as the history manager's current state changes, modify the tags
|
* as the history manager's current state changes, modify the tags
|
||||||
* filter to be in sync, and expose that as propery from
|
* filter to be in sync, and expose that as propery from
|
||||||
* TimeLineController. Do we need to do this with datasource or hash hit
|
* TimeLineController. Do we need to do this with datasource or hash hit
|
||||||
* filters?
|
* filters?
|
||||||
*/
|
*/
|
||||||
historyManager.currentState().addListener(new InvalidationListener() {
|
historyManager.currentState().addListener((Observable observable) -> {
|
||||||
public void invalidated(Observable observable) {
|
|
||||||
ZoomParams historyManagerParams = historyManager.getCurrentState();
|
ZoomParams historyManagerParams = historyManager.getCurrentState();
|
||||||
eventsRepository.syncTagsFilter(historyManagerParams.getFilter().getTagsFilter());
|
eventsRepository.syncTagsFilter(historyManagerParams.getFilter().getTagsFilter());
|
||||||
currentParams.set(historyManagerParams);
|
currentParams.set(historyManagerParams);
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
eventsRepository = new EventsRepository(autoCase, currentParams.getReadOnlyProperty());
|
|
||||||
filteredEvents = eventsRepository.getEventsModel();
|
filteredEvents = eventsRepository.getEventsModel();
|
||||||
|
|
||||||
InitialZoomState = new ZoomParams(filteredEvents.getSpanningInterval(),
|
InitialZoomState = new ZoomParams(filteredEvents.getSpanningInterval(),
|
||||||
@ -306,54 +291,52 @@ public class TimeLineController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* rebuld the repo.
|
* rebuild the repo using the given repo builder (expected to be a member
|
||||||
|
* reference to {@link EventsRepository#rebuildRepository(java.util.function.Consumer)
|
||||||
|
* } or {@link EventsRepository#rebuildTags(java.util.function.Consumer) })
|
||||||
|
* and display the ui when it is done.
|
||||||
*
|
*
|
||||||
* @return False if the repo was not rebuilt because because the user
|
* @param repoBuilder
|
||||||
* aborted after prompt about ingest running. True if the repo was
|
|
||||||
* rebuilt.
|
|
||||||
*/
|
*/
|
||||||
@ThreadConfined(type = ThreadConfined.ThreadType.JFX)
|
@ThreadConfined(type = ThreadConfined.ThreadType.JFX)
|
||||||
void rebuildRepo() {
|
private void rebuildRepoHelper(Function<Consumer<Worker.State>, CancellationProgressTask<?>> repoBuilder) {
|
||||||
SwingUtilities.invokeLater(this::closeTimelineWindow);
|
SwingUtilities.invokeLater(this::closeTimelineWindow);
|
||||||
final CancellationProgressTask<?> rebuildRepository = eventsRepository.rebuildRepository();
|
boolean ingestRunning = IngestManager.getInstance().isIngestRunning();
|
||||||
rebuildRepository.stateProperty().addListener((stateProperty, oldState, newSate) -> {
|
final CancellationProgressTask<?> rebuildRepository = repoBuilder.apply(newSate -> {
|
||||||
|
setIngestRunning(ingestRunning);
|
||||||
//this will be on JFX thread
|
//this will be on JFX thread
|
||||||
if (newSate == Worker.State.SUCCEEDED) {
|
switch (newSate) {
|
||||||
//TODO: this looks hacky. what is going on? should this be an event?
|
case SUCCEEDED:
|
||||||
needsHistogramRebuild.set(true);
|
setEventsDBStale(false);
|
||||||
needsHistogramRebuild.set(false);
|
|
||||||
SwingUtilities.invokeLater(TimeLineController.this::showWindow);
|
SwingUtilities.invokeLater(TimeLineController.this::showWindow);
|
||||||
|
|
||||||
//TODO: should this be an event?
|
|
||||||
newEventsFlag.set(false);
|
|
||||||
historyManager.reset(filteredEvents.zoomParametersProperty().get());
|
historyManager.reset(filteredEvents.zoomParametersProperty().get());
|
||||||
TimeLineController.this.showFullRange();
|
TimeLineController.this.showFullRange();
|
||||||
|
break;
|
||||||
|
case FAILED:
|
||||||
|
case CANCELLED:
|
||||||
|
setEventsDBStale(true);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
promptDialogManager.showProgressDialog(rebuildRepository);
|
promptDialogManager.showProgressDialog(rebuildRepository);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* rebuld the entire repo.
|
||||||
|
*/
|
||||||
|
@ThreadConfined(type = ThreadConfined.ThreadType.JFX)
|
||||||
|
void rebuildRepo() {
|
||||||
|
rebuildRepoHelper(eventsRepository::rebuildRepository);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Since tags might have changed while TimeLine wasn't listening, drop the
|
* Since tags might have changed while TimeLine wasn't listening, drop the
|
||||||
* tags table and rebuild it by querying for all the tags and inserting them
|
* tags table and rebuild it by querying for all the tags and inserting them
|
||||||
* in to the TimeLine DB.
|
* in to the TimeLine DB.
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
@ThreadConfined(type = ThreadConfined.ThreadType.JFX)
|
@ThreadConfined(type = ThreadConfined.ThreadType.JFX)
|
||||||
void rebuildTagsTable() {
|
void rebuildTagsTable() {
|
||||||
|
rebuildRepoHelper(eventsRepository::rebuildTags);
|
||||||
SwingUtilities.invokeLater(this::closeTimelineWindow);
|
|
||||||
CancellationProgressTask<?> rebuildTags = eventsRepository.rebuildTags();
|
|
||||||
rebuildTags.stateProperty().addListener((stateProperty, oldState, newSate) -> {
|
|
||||||
//this will be on JFX thread
|
|
||||||
if (newSate == Worker.State.SUCCEEDED) {
|
|
||||||
SwingUtilities.invokeLater(TimeLineController.this::showWindow);
|
|
||||||
showFullRange();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
promptDialogManager.showProgressDialog(rebuildTags);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ThreadConfined(type = ThreadConfined.ThreadType.AWT)
|
@ThreadConfined(type = ThreadConfined.ThreadType.AWT)
|
||||||
@ -370,7 +353,7 @@ public class TimeLineController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@ThreadConfined(type = ThreadConfined.ThreadType.AWT)
|
@ThreadConfined(type = ThreadConfined.ThreadType.AWT)
|
||||||
public void closeTimeLine() {
|
public void shutDownTimeLine() {
|
||||||
if (mainFrame != null) {
|
if (mainFrame != null) {
|
||||||
listeningToAutopsy = false;
|
listeningToAutopsy = false;
|
||||||
IngestManager.getInstance().removeIngestModuleEventListener(ingestModuleListener);
|
IngestManager.getInstance().removeIngestModuleEventListener(ingestModuleListener);
|
||||||
@ -409,7 +392,7 @@ public class TimeLineController {
|
|||||||
/*
|
/*
|
||||||
* if the repo was not rebuilt at minimum rebuild the tags which
|
* if the repo was not rebuilt at minimum rebuild the tags which
|
||||||
* may have been updated without our knowing it, since we
|
* may have been updated without our knowing it, since we
|
||||||
* can't/aren't checking them. This should at elast be quick.
|
* can't/aren't checking them. This should at least be quick.
|
||||||
* //TODO: can we check the tags to see if we need to do this?
|
* //TODO: can we check the tags to see if we need to do this?
|
||||||
*/
|
*/
|
||||||
if (checkAndPromptForRebuild() == false) {
|
if (checkAndPromptForRebuild() == false) {
|
||||||
@ -425,7 +408,7 @@ public class TimeLineController {
|
|||||||
@ThreadConfined(type = ThreadConfined.ThreadType.JFX)
|
@ThreadConfined(type = ThreadConfined.ThreadType.JFX)
|
||||||
private boolean checkAndPromptForRebuild() {
|
private boolean checkAndPromptForRebuild() {
|
||||||
//if the repo is empty just (r)ebuild it with out asking, they can always cancel part way through;
|
//if the repo is empty just (r)ebuild it with out asking, they can always cancel part way through;
|
||||||
if (eventsRepository.getLastObjID() == -1) {
|
if (eventsRepository.countAllEvents() == 0) {
|
||||||
rebuildRepo();
|
rebuildRepo();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -440,7 +423,6 @@ public class TimeLineController {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("deprecation") // TODO (EUR-733): Do not use SleuthkitCase.getLastObjectId
|
|
||||||
@ThreadConfined(type = ThreadConfined.ThreadType.ANY)
|
@ThreadConfined(type = ThreadConfined.ThreadType.ANY)
|
||||||
@NbBundle.Messages({"TimeLineController.errorTitle=Timeline error.",
|
@NbBundle.Messages({"TimeLineController.errorTitle=Timeline error.",
|
||||||
"TimeLineController.outOfDate.errorMessage=Error determing if the timeline is out of date. We will assume it should be updated. See the logs for more details.",
|
"TimeLineController.outOfDate.errorMessage=Error determing if the timeline is out of date. We will assume it should be updated. See the logs for more details.",
|
||||||
@ -450,23 +432,23 @@ public class TimeLineController {
|
|||||||
"TimeLineController.rebuildReasons.incompleteOldSchema=The Timeline events database was previously populated without incomplete information: Some features may be unavailable or non-functional unless you update the events database."})
|
"TimeLineController.rebuildReasons.incompleteOldSchema=The Timeline events database was previously populated without incomplete information: Some features may be unavailable or non-functional unless you update the events database."})
|
||||||
private ArrayList<String> getRebuildReasons() {
|
private ArrayList<String> getRebuildReasons() {
|
||||||
ArrayList<String> rebuildReasons = new ArrayList<>();
|
ArrayList<String> rebuildReasons = new ArrayList<>();
|
||||||
|
|
||||||
|
try {
|
||||||
//if ingest was running during last rebuild, prompt to rebuild
|
//if ingest was running during last rebuild, prompt to rebuild
|
||||||
if (eventsRepository.getWasIngestRunning()) {
|
if (perCaseTimelineProperties.wasIngestRunning()) {
|
||||||
rebuildReasons.add(Bundle.TimeLineController_rebuildReasons_ingestWasRunning());
|
rebuildReasons.add(Bundle.TimeLineController_rebuildReasons_ingestWasRunning());
|
||||||
}
|
}
|
||||||
final SleuthkitCase sleuthkitCase = autoCase.getSleuthkitCase();
|
|
||||||
try {
|
} catch (IOException ex) {
|
||||||
//if the last artifact and object ids don't match between skc and tldb, prompt to rebuild
|
LOGGER.log(Level.SEVERE, "Error determing the state of the timeline db. We will assume the it is out of date.", ex); // NON-NLS
|
||||||
if (sleuthkitCase.getLastObjectId() != eventsRepository.getLastObjID()
|
|
||||||
|| getCaseLastArtifactID(sleuthkitCase) != eventsRepository.getLastArtfactID()) {
|
|
||||||
rebuildReasons.add(Bundle.TimeLineController_rebuildReasons_outOfDate());
|
|
||||||
}
|
|
||||||
} catch (TskCoreException ex) {
|
|
||||||
LOGGER.log(Level.SEVERE, "Error determing last object id from sleutkit case. We will assume the timeline is out of date.", ex); // NON-NLS
|
|
||||||
MessageNotifyUtil.Notify.error(Bundle.TimeLineController_errorTitle(),
|
MessageNotifyUtil.Notify.error(Bundle.TimeLineController_errorTitle(),
|
||||||
Bundle.TimeLineController_outOfDate_errorMessage());
|
Bundle.TimeLineController_outOfDate_errorMessage());
|
||||||
rebuildReasons.add(Bundle.TimeLineController_rebuildReasons_outOfDateError());
|
rebuildReasons.add(Bundle.TimeLineController_rebuildReasons_outOfDateError());
|
||||||
}
|
}
|
||||||
|
//if the events db is stale, prompt to rebuild
|
||||||
|
if (isEventsDBStale()) {
|
||||||
|
rebuildReasons.add(Bundle.TimeLineController_rebuildReasons_outOfDate());
|
||||||
|
}
|
||||||
// if the TLDB schema has been upgraded since last time TL ran, prompt for rebuild
|
// if the TLDB schema has been upgraded since last time TL ran, prompt for rebuild
|
||||||
if (eventsRepository.hasNewColumns() == false) {
|
if (eventsRepository.hasNewColumns() == false) {
|
||||||
rebuildReasons.add(Bundle.TimeLineController_rebuildReasons_incompleteOldSchema());
|
rebuildReasons.add(Bundle.TimeLineController_rebuildReasons_incompleteOldSchema());
|
||||||
@ -474,21 +456,6 @@ public class TimeLineController {
|
|||||||
return rebuildReasons;
|
return rebuildReasons;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static long getCaseLastArtifactID(final SleuthkitCase sleuthkitCase) {
|
|
||||||
//TODO: push this into sleuthkitCase
|
|
||||||
long caseLastArtfId = -1;
|
|
||||||
String query = "select Max(artifact_id) as max_id from blackboard_artifacts"; // NON-NLS //NOI18N
|
|
||||||
try (CaseDbQuery dbQuery = sleuthkitCase.executeQuery(query)) {
|
|
||||||
ResultSet resultSet = dbQuery.getResultSet();
|
|
||||||
while (resultSet.next()) {
|
|
||||||
caseLastArtfId = resultSet.getLong("max_id"); // NON-NLS //NOI18N
|
|
||||||
}
|
|
||||||
} catch (TskCoreException | SQLException ex) {
|
|
||||||
LOGGER.log(Level.SEVERE, "Error getting last artifact id: ", ex); // NON-NLS //NOI18N
|
|
||||||
}
|
|
||||||
return caseLastArtfId;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* request a time range the same length as the given period and centered
|
* request a time range the same length as the given period and centered
|
||||||
* around the middle of the currently selected range
|
* around the middle of the currently selected range
|
||||||
@ -752,6 +719,38 @@ public class TimeLineController {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* is the events db out of date
|
||||||
|
*
|
||||||
|
* @return true if the events db is out of date , false otherwise
|
||||||
|
*/
|
||||||
|
public boolean isEventsDBStale() {
|
||||||
|
return eventsDBStale.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param stale the value of stale
|
||||||
|
*/
|
||||||
|
private void setEventsDBStale(final Boolean stale) {
|
||||||
|
eventsDBStale.set(stale);
|
||||||
|
try {
|
||||||
|
perCaseTimelineProperties.setDbStale(stale);
|
||||||
|
} catch (IOException ex) {
|
||||||
|
MessageNotifyUtil.Notify.error("Timeline", "Failed to mark the timeline db as " + (stale ? "" : "not ") + "stale. Some results may be out of date or missing.");
|
||||||
|
LOGGER.log(Level.SEVERE, "Error marking the timeline db as stale.", ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setIngestRunning(boolean ingestRunning) {
|
||||||
|
try {
|
||||||
|
perCaseTimelineProperties.setIngestRunning(ingestRunning);
|
||||||
|
} catch (IOException ex) {
|
||||||
|
MessageNotifyUtil.Notify.error("Timeline", "Failed to mark the timeline db as populated while ingest was" + (ingestRunning ? "" : "not ") + "running. Some results may be out of date or missing.");
|
||||||
|
LOGGER.log(Level.SEVERE, "Error marking the ingest state while the timeline db was populated.", ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private class AutopsyIngestModuleListener implements PropertyChangeListener {
|
private class AutopsyIngestModuleListener implements PropertyChangeListener {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -773,12 +772,10 @@ public class TimeLineController {
|
|||||||
|
|
||||||
switch (IngestManager.IngestModuleEvent.valueOf(evt.getPropertyName())) {
|
switch (IngestManager.IngestModuleEvent.valueOf(evt.getPropertyName())) {
|
||||||
case CONTENT_CHANGED:
|
case CONTENT_CHANGED:
|
||||||
case DATA_ADDED:
|
|
||||||
break;
|
break;
|
||||||
|
case DATA_ADDED:
|
||||||
case FILE_DONE:
|
case FILE_DONE:
|
||||||
Platform.runLater(() -> {
|
Platform.runLater(() -> setEventsDBStale(true));
|
||||||
newEventsFlag.set(true);
|
|
||||||
});
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -804,32 +801,26 @@ public class TimeLineController {
|
|||||||
public void propertyChange(PropertyChangeEvent evt) {
|
public void propertyChange(PropertyChangeEvent evt) {
|
||||||
switch (Case.Events.valueOf(evt.getPropertyName())) {
|
switch (Case.Events.valueOf(evt.getPropertyName())) {
|
||||||
case BLACKBOARD_ARTIFACT_TAG_ADDED:
|
case BLACKBOARD_ARTIFACT_TAG_ADDED:
|
||||||
executor.submit(() -> {
|
executor.submit(() -> filteredEvents.handleArtifactTagAdded((BlackBoardArtifactTagAddedEvent) evt));
|
||||||
filteredEvents.handleArtifactTagAdded((BlackBoardArtifactTagAddedEvent) evt);
|
|
||||||
});
|
|
||||||
break;
|
break;
|
||||||
case BLACKBOARD_ARTIFACT_TAG_DELETED:
|
case BLACKBOARD_ARTIFACT_TAG_DELETED:
|
||||||
executor.submit(() -> {
|
executor.submit(() -> filteredEvents.handleArtifactTagDeleted((BlackBoardArtifactTagDeletedEvent) evt));
|
||||||
filteredEvents.handleArtifactTagDeleted((BlackBoardArtifactTagDeletedEvent) evt);
|
|
||||||
});
|
|
||||||
break;
|
break;
|
||||||
case CONTENT_TAG_ADDED:
|
case CONTENT_TAG_ADDED:
|
||||||
executor.submit(() -> {
|
executor.submit(() -> filteredEvents.handleContentTagAdded((ContentTagAddedEvent) evt));
|
||||||
filteredEvents.handleContentTagAdded((ContentTagAddedEvent) evt);
|
|
||||||
});
|
|
||||||
break;
|
break;
|
||||||
case CONTENT_TAG_DELETED:
|
case CONTENT_TAG_DELETED:
|
||||||
executor.submit(() -> {
|
executor.submit(() -> filteredEvents.handleContentTagDeleted((ContentTagDeletedEvent) evt));
|
||||||
filteredEvents.handleContentTagDeleted((ContentTagDeletedEvent) evt);
|
|
||||||
});
|
|
||||||
break;
|
break;
|
||||||
case DATA_SOURCE_ADDED:
|
case DATA_SOURCE_ADDED:
|
||||||
|
Platform.runLater(() -> {
|
||||||
|
setEventsDBStale(true);
|
||||||
SwingUtilities.invokeLater(TimeLineController.this::confirmOutOfDateRebuildIfWindowOpen);
|
SwingUtilities.invokeLater(TimeLineController.this::confirmOutOfDateRebuildIfWindowOpen);
|
||||||
|
});
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CURRENT_CASE:
|
case CURRENT_CASE:
|
||||||
OpenTimelineAction.invalidateController();
|
OpenTimelineAction.invalidateController();
|
||||||
SwingUtilities.invokeLater(TimeLineController.this::closeTimeLine);
|
SwingUtilities.invokeLater(TimeLineController.this::shutDownTimeLine);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -42,7 +42,7 @@ import org.sleuthkit.datamodel.TskCoreException;
|
|||||||
public enum MiscTypes implements EventType, ArtifactEventType {
|
public enum MiscTypes implements EventType, ArtifactEventType {
|
||||||
|
|
||||||
MESSAGE(NbBundle.getMessage(MiscTypes.class, "MiscTypes.message.name"), "message.png", // NON-NLS
|
MESSAGE(NbBundle.getMessage(MiscTypes.class, "MiscTypes.message.name"), "message.png", // NON-NLS
|
||||||
TypeUtils.fromEnum(ARTIFACT_TYPE.TSK_MESSAGE),
|
new BlackboardArtifact.Type(ARTIFACT_TYPE.TSK_MESSAGE),
|
||||||
new BlackboardAttribute.Type(ATTRIBUTE_TYPE.TSK_DATETIME),
|
new BlackboardAttribute.Type(ATTRIBUTE_TYPE.TSK_DATETIME),
|
||||||
new AttributeExtractor(new BlackboardAttribute.Type(ATTRIBUTE_TYPE.TSK_MESSAGE_TYPE)),
|
new AttributeExtractor(new BlackboardAttribute.Type(ATTRIBUTE_TYPE.TSK_MESSAGE_TYPE)),
|
||||||
artf -> {
|
artf -> {
|
||||||
@ -56,7 +56,7 @@ public enum MiscTypes implements EventType, ArtifactEventType {
|
|||||||
},
|
},
|
||||||
new AttributeExtractor(new BlackboardAttribute.Type(ATTRIBUTE_TYPE.TSK_TEXT))),
|
new AttributeExtractor(new BlackboardAttribute.Type(ATTRIBUTE_TYPE.TSK_TEXT))),
|
||||||
GPS_ROUTE(NbBundle.getMessage(MiscTypes.class, "MiscTypes.GPSRoutes.name"), "gps-search.png", // NON-NLS
|
GPS_ROUTE(NbBundle.getMessage(MiscTypes.class, "MiscTypes.GPSRoutes.name"), "gps-search.png", // NON-NLS
|
||||||
TypeUtils.fromEnum(ARTIFACT_TYPE.TSK_GPS_ROUTE),
|
new BlackboardArtifact.Type(ARTIFACT_TYPE.TSK_GPS_ROUTE),
|
||||||
new BlackboardAttribute.Type(ATTRIBUTE_TYPE.TSK_DATETIME),
|
new BlackboardAttribute.Type(ATTRIBUTE_TYPE.TSK_DATETIME),
|
||||||
new AttributeExtractor(new BlackboardAttribute.Type(ATTRIBUTE_TYPE.TSK_PROG_NAME)),
|
new AttributeExtractor(new BlackboardAttribute.Type(ATTRIBUTE_TYPE.TSK_PROG_NAME)),
|
||||||
new AttributeExtractor(new BlackboardAttribute.Type(ATTRIBUTE_TYPE.TSK_LOCATION)),
|
new AttributeExtractor(new BlackboardAttribute.Type(ATTRIBUTE_TYPE.TSK_LOCATION)),
|
||||||
@ -68,7 +68,7 @@ public enum MiscTypes implements EventType, ArtifactEventType {
|
|||||||
return String.format("from %1$s %2$s to %3$s %4$s", stringValueOf(latStart), stringValueOf(longStart), stringValueOf(latEnd), stringValueOf(longEnd)); // NON-NLS
|
return String.format("from %1$s %2$s to %3$s %4$s", stringValueOf(latStart), stringValueOf(longStart), stringValueOf(latEnd), stringValueOf(longEnd)); // NON-NLS
|
||||||
}),
|
}),
|
||||||
GPS_TRACKPOINT(NbBundle.getMessage(MiscTypes.class, "MiscTypes.GPSTrackpoint.name"), "gps-trackpoint.png", // NON-NLS
|
GPS_TRACKPOINT(NbBundle.getMessage(MiscTypes.class, "MiscTypes.GPSTrackpoint.name"), "gps-trackpoint.png", // NON-NLS
|
||||||
TypeUtils.fromEnum(ARTIFACT_TYPE.TSK_GPS_TRACKPOINT),
|
new BlackboardArtifact.Type(ARTIFACT_TYPE.TSK_GPS_TRACKPOINT),
|
||||||
new BlackboardAttribute.Type(ATTRIBUTE_TYPE.TSK_DATETIME),
|
new BlackboardAttribute.Type(ATTRIBUTE_TYPE.TSK_DATETIME),
|
||||||
new AttributeExtractor(new BlackboardAttribute.Type(ATTRIBUTE_TYPE.TSK_PROG_NAME)),
|
new AttributeExtractor(new BlackboardAttribute.Type(ATTRIBUTE_TYPE.TSK_PROG_NAME)),
|
||||||
artf -> {
|
artf -> {
|
||||||
@ -78,13 +78,13 @@ public enum MiscTypes implements EventType, ArtifactEventType {
|
|||||||
},
|
},
|
||||||
EMPTY_EXTRACTOR),
|
EMPTY_EXTRACTOR),
|
||||||
CALL_LOG(NbBundle.getMessage(MiscTypes.class, "MiscTypes.Calls.name"), "calllog.png", // NON-NLS
|
CALL_LOG(NbBundle.getMessage(MiscTypes.class, "MiscTypes.Calls.name"), "calllog.png", // NON-NLS
|
||||||
TypeUtils.fromEnum(ARTIFACT_TYPE.TSK_CALLLOG),
|
new BlackboardArtifact.Type(ARTIFACT_TYPE.TSK_CALLLOG),
|
||||||
new BlackboardAttribute.Type(ATTRIBUTE_TYPE.TSK_DATETIME_START),
|
new BlackboardAttribute.Type(ATTRIBUTE_TYPE.TSK_DATETIME_START),
|
||||||
new AttributeExtractor(new BlackboardAttribute.Type(ATTRIBUTE_TYPE.TSK_NAME)),
|
new AttributeExtractor(new BlackboardAttribute.Type(ATTRIBUTE_TYPE.TSK_NAME)),
|
||||||
new AttributeExtractor(new BlackboardAttribute.Type(ATTRIBUTE_TYPE.TSK_PHONE_NUMBER)),
|
new AttributeExtractor(new BlackboardAttribute.Type(ATTRIBUTE_TYPE.TSK_PHONE_NUMBER)),
|
||||||
new AttributeExtractor(new BlackboardAttribute.Type(ATTRIBUTE_TYPE.TSK_DIRECTION))),
|
new AttributeExtractor(new BlackboardAttribute.Type(ATTRIBUTE_TYPE.TSK_DIRECTION))),
|
||||||
EMAIL(NbBundle.getMessage(MiscTypes.class, "MiscTypes.Email.name"), "mail-icon-16.png", // NON-NLS
|
EMAIL(NbBundle.getMessage(MiscTypes.class, "MiscTypes.Email.name"), "mail-icon-16.png", // NON-NLS
|
||||||
TypeUtils.fromEnum(ARTIFACT_TYPE.TSK_EMAIL_MSG),
|
new BlackboardArtifact.Type(ARTIFACT_TYPE.TSK_EMAIL_MSG),
|
||||||
new BlackboardAttribute.Type(ATTRIBUTE_TYPE.TSK_DATETIME_SENT),
|
new BlackboardAttribute.Type(ATTRIBUTE_TYPE.TSK_DATETIME_SENT),
|
||||||
artf -> {
|
artf -> {
|
||||||
final BlackboardAttribute emailFrom = getAttributeSafe(artf, new BlackboardAttribute.Type(ATTRIBUTE_TYPE.TSK_EMAIL_FROM));
|
final BlackboardAttribute emailFrom = getAttributeSafe(artf, new BlackboardAttribute.Type(ATTRIBUTE_TYPE.TSK_EMAIL_FROM));
|
||||||
@ -94,7 +94,7 @@ public enum MiscTypes implements EventType, ArtifactEventType {
|
|||||||
new AttributeExtractor(new BlackboardAttribute.Type(ATTRIBUTE_TYPE.TSK_SUBJECT)),
|
new AttributeExtractor(new BlackboardAttribute.Type(ATTRIBUTE_TYPE.TSK_SUBJECT)),
|
||||||
new AttributeExtractor(new BlackboardAttribute.Type(ATTRIBUTE_TYPE.TSK_EMAIL_CONTENT_PLAIN))),
|
new AttributeExtractor(new BlackboardAttribute.Type(ATTRIBUTE_TYPE.TSK_EMAIL_CONTENT_PLAIN))),
|
||||||
RECENT_DOCUMENTS(NbBundle.getMessage(MiscTypes.class, "MiscTypes.recentDocuments.name"), "recent_docs.png", // NON-NLS
|
RECENT_DOCUMENTS(NbBundle.getMessage(MiscTypes.class, "MiscTypes.recentDocuments.name"), "recent_docs.png", // NON-NLS
|
||||||
TypeUtils.fromEnum(ARTIFACT_TYPE.TSK_RECENT_OBJECT),
|
new BlackboardArtifact.Type(ARTIFACT_TYPE.TSK_RECENT_OBJECT),
|
||||||
new BlackboardAttribute.Type(ATTRIBUTE_TYPE.TSK_DATETIME),
|
new BlackboardAttribute.Type(ATTRIBUTE_TYPE.TSK_DATETIME),
|
||||||
new AttributeExtractor(new BlackboardAttribute.Type(ATTRIBUTE_TYPE.TSK_PATH)).andThen(
|
new AttributeExtractor(new BlackboardAttribute.Type(ATTRIBUTE_TYPE.TSK_PATH)).andThen(
|
||||||
(String t) -> (StringUtils.substringBeforeLast(StringUtils.substringBeforeLast(t, "\\"), "\\"))),
|
(String t) -> (StringUtils.substringBeforeLast(StringUtils.substringBeforeLast(t, "\\"), "\\"))),
|
||||||
@ -117,13 +117,13 @@ public enum MiscTypes implements EventType, ArtifactEventType {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
INSTALLED_PROGRAM(NbBundle.getMessage(MiscTypes.class, "MiscTypes.installedPrograms.name"), "programs.png", // NON-NLS
|
INSTALLED_PROGRAM(NbBundle.getMessage(MiscTypes.class, "MiscTypes.installedPrograms.name"), "programs.png", // NON-NLS
|
||||||
TypeUtils.fromEnum(ARTIFACT_TYPE.TSK_INSTALLED_PROG),
|
new BlackboardArtifact.Type(ARTIFACT_TYPE.TSK_INSTALLED_PROG),
|
||||||
new BlackboardAttribute.Type(ATTRIBUTE_TYPE.TSK_DATETIME),
|
new BlackboardAttribute.Type(ATTRIBUTE_TYPE.TSK_DATETIME),
|
||||||
new AttributeExtractor(new BlackboardAttribute.Type(ATTRIBUTE_TYPE.TSK_PROG_NAME)),
|
new AttributeExtractor(new BlackboardAttribute.Type(ATTRIBUTE_TYPE.TSK_PROG_NAME)),
|
||||||
EMPTY_EXTRACTOR,
|
EMPTY_EXTRACTOR,
|
||||||
EMPTY_EXTRACTOR),
|
EMPTY_EXTRACTOR),
|
||||||
EXIF(NbBundle.getMessage(MiscTypes.class, "MiscTypes.exif.name"), "camera-icon-16.png", // NON-NLS
|
EXIF(NbBundle.getMessage(MiscTypes.class, "MiscTypes.exif.name"), "camera-icon-16.png", // NON-NLS
|
||||||
TypeUtils.fromEnum(ARTIFACT_TYPE.TSK_METADATA_EXIF),
|
new BlackboardArtifact.Type(ARTIFACT_TYPE.TSK_METADATA_EXIF),
|
||||||
new BlackboardAttribute.Type(ATTRIBUTE_TYPE.TSK_DATETIME_CREATED),
|
new BlackboardAttribute.Type(ATTRIBUTE_TYPE.TSK_DATETIME_CREATED),
|
||||||
new AttributeExtractor(new BlackboardAttribute.Type(ATTRIBUTE_TYPE.TSK_DEVICE_MAKE)),
|
new AttributeExtractor(new BlackboardAttribute.Type(ATTRIBUTE_TYPE.TSK_DEVICE_MAKE)),
|
||||||
new AttributeExtractor(new BlackboardAttribute.Type(ATTRIBUTE_TYPE.TSK_DEVICE_MODEL)),
|
new AttributeExtractor(new BlackboardAttribute.Type(ATTRIBUTE_TYPE.TSK_DEVICE_MODEL)),
|
||||||
@ -139,7 +139,7 @@ public enum MiscTypes implements EventType, ArtifactEventType {
|
|||||||
return "error loading file name";
|
return "error loading file name";
|
||||||
}),
|
}),
|
||||||
DEVICES_ATTACHED(NbBundle.getMessage(MiscTypes.class, "MiscTypes.devicesAttached.name"), "usb_devices.png", // NON-NLS
|
DEVICES_ATTACHED(NbBundle.getMessage(MiscTypes.class, "MiscTypes.devicesAttached.name"), "usb_devices.png", // NON-NLS
|
||||||
TypeUtils.fromEnum(ARTIFACT_TYPE.TSK_DEVICE_ATTACHED),
|
new BlackboardArtifact.Type(ARTIFACT_TYPE.TSK_DEVICE_ATTACHED),
|
||||||
new BlackboardAttribute.Type(ATTRIBUTE_TYPE.TSK_DATETIME),
|
new BlackboardAttribute.Type(ATTRIBUTE_TYPE.TSK_DATETIME),
|
||||||
new AttributeExtractor(new BlackboardAttribute.Type(ATTRIBUTE_TYPE.TSK_DEVICE_MAKE)),
|
new AttributeExtractor(new BlackboardAttribute.Type(ATTRIBUTE_TYPE.TSK_DEVICE_MAKE)),
|
||||||
new AttributeExtractor(new BlackboardAttribute.Type(ATTRIBUTE_TYPE.TSK_DEVICE_MODEL)),
|
new AttributeExtractor(new BlackboardAttribute.Type(ATTRIBUTE_TYPE.TSK_DEVICE_MODEL)),
|
||||||
|
@ -1,35 +0,0 @@
|
|||||||
/*
|
|
||||||
* Autopsy Forensic Browser
|
|
||||||
*
|
|
||||||
* Copyright 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.timeline.datamodel.eventtype;
|
|
||||||
|
|
||||||
import org.sleuthkit.datamodel.BlackboardArtifact;
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
class TypeUtils {
|
|
||||||
|
|
||||||
//TODO: this will be unncessary once their is BlackboardArtifact.Type constructr that takes a BlackboardArtifact.ARTIFACT_TYPE
|
|
||||||
static BlackboardArtifact.Type fromEnum(BlackboardArtifact.ARTIFACT_TYPE type) {
|
|
||||||
return new BlackboardArtifact.Type(type.getTypeID(), type.getLabel(), type.getDisplayName());
|
|
||||||
}
|
|
||||||
|
|
||||||
private TypeUtils() {
|
|
||||||
}
|
|
||||||
}
|
|
@ -37,7 +37,7 @@ public enum WebTypes implements EventType, ArtifactEventType {
|
|||||||
|
|
||||||
WEB_DOWNLOADS(NbBundle.getMessage(WebTypes.class, "WebTypes.webDownloads.name"),
|
WEB_DOWNLOADS(NbBundle.getMessage(WebTypes.class, "WebTypes.webDownloads.name"),
|
||||||
"downloads.png", // NON-NLS
|
"downloads.png", // NON-NLS
|
||||||
TypeUtils.fromEnum(BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_DOWNLOAD),
|
new BlackboardArtifact.Type(BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_DOWNLOAD),
|
||||||
new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME_ACCESSED),
|
new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME_ACCESSED),
|
||||||
TopPrivateDomainExtractor.getInstance(),
|
TopPrivateDomainExtractor.getInstance(),
|
||||||
new AttributeExtractor(new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PATH)),
|
new AttributeExtractor(new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PATH)),
|
||||||
@ -61,7 +61,7 @@ public enum WebTypes implements EventType, ArtifactEventType {
|
|||||||
//TODO: review description separators
|
//TODO: review description separators
|
||||||
WEB_COOKIE(NbBundle.getMessage(WebTypes.class, "WebTypes.webCookies.name"),
|
WEB_COOKIE(NbBundle.getMessage(WebTypes.class, "WebTypes.webCookies.name"),
|
||||||
"cookies.png", // NON-NLS
|
"cookies.png", // NON-NLS
|
||||||
TypeUtils.fromEnum(BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_COOKIE),
|
new BlackboardArtifact.Type(BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_COOKIE),
|
||||||
new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME),
|
new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME),
|
||||||
TopPrivateDomainExtractor.getInstance(),
|
TopPrivateDomainExtractor.getInstance(),
|
||||||
new AttributeExtractor(new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_NAME)),
|
new AttributeExtractor(new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_NAME)),
|
||||||
@ -69,7 +69,7 @@ public enum WebTypes implements EventType, ArtifactEventType {
|
|||||||
//TODO: review description separators
|
//TODO: review description separators
|
||||||
WEB_BOOKMARK(NbBundle.getMessage(WebTypes.class, "WebTypes.webBookmarks.name"),
|
WEB_BOOKMARK(NbBundle.getMessage(WebTypes.class, "WebTypes.webBookmarks.name"),
|
||||||
"bookmarks.png", // NON-NLS
|
"bookmarks.png", // NON-NLS
|
||||||
TypeUtils.fromEnum(BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_BOOKMARK),
|
new BlackboardArtifact.Type(BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_BOOKMARK),
|
||||||
new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME_CREATED),
|
new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME_CREATED),
|
||||||
TopPrivateDomainExtractor.getInstance(),
|
TopPrivateDomainExtractor.getInstance(),
|
||||||
new AttributeExtractor(new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_URL)),
|
new AttributeExtractor(new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_URL)),
|
||||||
@ -77,7 +77,7 @@ public enum WebTypes implements EventType, ArtifactEventType {
|
|||||||
//TODO: review description separators
|
//TODO: review description separators
|
||||||
WEB_HISTORY(NbBundle.getMessage(WebTypes.class, "WebTypes.webHistory.name"),
|
WEB_HISTORY(NbBundle.getMessage(WebTypes.class, "WebTypes.webHistory.name"),
|
||||||
"history.png", // NON-NLS
|
"history.png", // NON-NLS
|
||||||
TypeUtils.fromEnum(BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_HISTORY),
|
new BlackboardArtifact.Type(BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_HISTORY),
|
||||||
new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME_ACCESSED),
|
new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME_ACCESSED),
|
||||||
TopPrivateDomainExtractor.getInstance(),
|
TopPrivateDomainExtractor.getInstance(),
|
||||||
new AttributeExtractor(new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_URL)),
|
new AttributeExtractor(new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_URL)),
|
||||||
@ -85,7 +85,7 @@ public enum WebTypes implements EventType, ArtifactEventType {
|
|||||||
//TODO: review description separators
|
//TODO: review description separators
|
||||||
WEB_SEARCH(NbBundle.getMessage(WebTypes.class, "WebTypes.webSearch.name"),
|
WEB_SEARCH(NbBundle.getMessage(WebTypes.class, "WebTypes.webSearch.name"),
|
||||||
"searchquery.png", // NON-NLS
|
"searchquery.png", // NON-NLS
|
||||||
TypeUtils.fromEnum(BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_SEARCH_QUERY),
|
new BlackboardArtifact.Type(BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_SEARCH_QUERY),
|
||||||
new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME_ACCESSED),
|
new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME_ACCESSED),
|
||||||
new AttributeExtractor(new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_TEXT)),
|
new AttributeExtractor(new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_TEXT)),
|
||||||
TopPrivateDomainExtractor.getInstance(),
|
TopPrivateDomainExtractor.getInstance(),
|
||||||
|
@ -84,28 +84,6 @@ import org.sqlite.SQLiteJDBCLoader;
|
|||||||
*/
|
*/
|
||||||
public class EventDB {
|
public class EventDB {
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* enum to represent keys stored in db_info table
|
|
||||||
*/
|
|
||||||
private enum DBInfoKey {
|
|
||||||
|
|
||||||
LAST_ARTIFACT_ID("last_artifact_id"), // NON-NLS
|
|
||||||
LAST_OBJECT_ID("last_object_id"), // NON-NLS
|
|
||||||
WAS_INGEST_RUNNING("was_ingest_running"); // NON-NLS
|
|
||||||
|
|
||||||
private final String keyName;
|
|
||||||
|
|
||||||
private DBInfoKey(String keyName) {
|
|
||||||
this.keyName = keyName;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return keyName;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static final org.sleuthkit.autopsy.coreutils.Logger LOGGER = Logger.getLogger(EventDB.class.getName());
|
private static final org.sleuthkit.autopsy.coreutils.Logger LOGGER = Logger.getLogger(EventDB.class.getName());
|
||||||
|
|
||||||
static {
|
static {
|
||||||
@ -142,14 +120,12 @@ public class EventDB {
|
|||||||
|
|
||||||
private final String dbPath;
|
private final String dbPath;
|
||||||
|
|
||||||
private PreparedStatement getDBInfoStmt;
|
|
||||||
private PreparedStatement getEventByIDStmt;
|
private PreparedStatement getEventByIDStmt;
|
||||||
private PreparedStatement getMaxTimeStmt;
|
private PreparedStatement getMaxTimeStmt;
|
||||||
private PreparedStatement getMinTimeStmt;
|
private PreparedStatement getMinTimeStmt;
|
||||||
private PreparedStatement getDataSourceIDsStmt;
|
private PreparedStatement getDataSourceIDsStmt;
|
||||||
private PreparedStatement getHashSetNamesStmt;
|
private PreparedStatement getHashSetNamesStmt;
|
||||||
private PreparedStatement insertRowStmt;
|
private PreparedStatement insertRowStmt;
|
||||||
private PreparedStatement recordDBInfoStmt;
|
|
||||||
private PreparedStatement insertHashSetStmt;
|
private PreparedStatement insertHashSetStmt;
|
||||||
private PreparedStatement insertHashHitStmt;
|
private PreparedStatement insertHashHitStmt;
|
||||||
private PreparedStatement insertTagStmt;
|
private PreparedStatement insertTagStmt;
|
||||||
@ -394,14 +370,6 @@ public class EventDB {
|
|||||||
return resultIDs;
|
return resultIDs;
|
||||||
}
|
}
|
||||||
|
|
||||||
long getLastArtfactID() {
|
|
||||||
return getDBInfo(DBInfoKey.LAST_ARTIFACT_ID, -1);
|
|
||||||
}
|
|
||||||
|
|
||||||
long getLastObjID() {
|
|
||||||
return getDBInfo(DBInfoKey.LAST_OBJECT_ID, -1);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* this relies on the fact that no tskObj has ID 0 but 0 is the default
|
* this relies on the fact that no tskObj has ID 0 but 0 is the default
|
||||||
* value for the datasource_id column in the events table.
|
* value for the datasource_id column in the events table.
|
||||||
@ -489,10 +457,6 @@ public class EventDB {
|
|||||||
return -1l;
|
return -1l;
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean getWasIngestRunning() {
|
|
||||||
return getDBInfo(DBInfoKey.WAS_INGEST_RUNNING, 0) != 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* create the table and indices if they don't already exist
|
* create the table and indices if they don't already exist
|
||||||
*
|
*
|
||||||
@ -614,8 +578,6 @@ public class EventDB {
|
|||||||
getMaxTimeStmt = prepareStatement("SELECT Max(time) AS max FROM events"); // NON-NLS
|
getMaxTimeStmt = prepareStatement("SELECT Max(time) AS max FROM events"); // NON-NLS
|
||||||
getMinTimeStmt = prepareStatement("SELECT Min(time) AS min FROM events"); // NON-NLS
|
getMinTimeStmt = prepareStatement("SELECT Min(time) AS min FROM events"); // NON-NLS
|
||||||
getEventByIDStmt = prepareStatement("SELECT * FROM events WHERE event_id = ?"); // NON-NLS
|
getEventByIDStmt = prepareStatement("SELECT * FROM events WHERE event_id = ?"); // NON-NLS
|
||||||
recordDBInfoStmt = prepareStatement("INSERT OR REPLACE INTO db_info (key, value) values (?, ?)"); // NON-NLS
|
|
||||||
getDBInfoStmt = prepareStatement("SELECT value FROM db_info WHERE key = ?"); // NON-NLS
|
|
||||||
insertHashSetStmt = prepareStatement("INSERT OR IGNORE INTO hash_sets (hash_set_name) values (?)"); //NON-NLS
|
insertHashSetStmt = prepareStatement("INSERT OR IGNORE INTO hash_sets (hash_set_name) values (?)"); //NON-NLS
|
||||||
selectHashSetStmt = prepareStatement("SELECT hash_set_id FROM hash_sets WHERE hash_set_name = ?"); //NON-NLS
|
selectHashSetStmt = prepareStatement("SELECT hash_set_id FROM hash_sets WHERE hash_set_name = ?"); //NON-NLS
|
||||||
insertHashHitStmt = prepareStatement("INSERT OR IGNORE INTO hash_set_hits (hash_set_id, event_id) values (?,?)"); //NON-NLS
|
insertHashHitStmt = prepareStatement("INSERT OR IGNORE INTO hash_set_hits (hash_set_id, event_id) values (?,?)"); //NON-NLS
|
||||||
@ -938,18 +900,6 @@ public class EventDB {
|
|||||||
return eventIDs;
|
return eventIDs;
|
||||||
}
|
}
|
||||||
|
|
||||||
void recordLastArtifactID(long lastArtfID) {
|
|
||||||
recordDBInfo(DBInfoKey.LAST_ARTIFACT_ID, lastArtfID);
|
|
||||||
}
|
|
||||||
|
|
||||||
void recordLastObjID(Long lastObjID) {
|
|
||||||
recordDBInfo(DBInfoKey.LAST_OBJECT_ID, lastObjID);
|
|
||||||
}
|
|
||||||
|
|
||||||
void recordWasIngestRunning(boolean wasIngestRunning) {
|
|
||||||
recordDBInfo(DBInfoKey.WAS_INGEST_RUNNING, (wasIngestRunning ? 1 : 0));
|
|
||||||
}
|
|
||||||
|
|
||||||
void rollBackTransaction(EventTransaction trans) {
|
void rollBackTransaction(EventTransaction trans) {
|
||||||
trans.rollback();
|
trans.rollback();
|
||||||
}
|
}
|
||||||
@ -983,8 +933,7 @@ public class EventDB {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
LOGGER.log(Level.INFO, String.format("sqlite-jdbc version %s loaded in %s mode", // NON-NLS
|
LOGGER.log(Level.INFO, String.format("sqlite-jdbc version %s loaded in %s mode", // NON-NLS
|
||||||
SQLiteJDBCLoader.getVersion(), SQLiteJDBCLoader.isNativeMode()
|
SQLiteJDBCLoader.getVersion(), SQLiteJDBCLoader.isNativeMode() ? "native" : "pure-java")); // NON-NLS
|
||||||
? "native" : "pure-java")); // NON-NLS
|
|
||||||
} catch (Exception exception) {
|
} catch (Exception exception) {
|
||||||
LOGGER.log(Level.SEVERE, "Failed to determine if sqlite-jdbc is loaded in native or pure-java mode.", exception); //NON-NLS
|
LOGGER.log(Level.SEVERE, "Failed to determine if sqlite-jdbc is loaded in native or pure-java mode.", exception); //NON-NLS
|
||||||
}
|
}
|
||||||
@ -1220,28 +1169,6 @@ public class EventDB {
|
|||||||
return useSubTypes ? "sub_type" : "base_type"; //NON-NLS
|
return useSubTypes ? "sub_type" : "base_type"; //NON-NLS
|
||||||
}
|
}
|
||||||
|
|
||||||
private long getDBInfo(DBInfoKey key, long defaultValue) {
|
|
||||||
DBLock.lock();
|
|
||||||
try {
|
|
||||||
getDBInfoStmt.setString(1, key.toString());
|
|
||||||
|
|
||||||
try (ResultSet rs = getDBInfoStmt.executeQuery()) {
|
|
||||||
long result = defaultValue;
|
|
||||||
while (rs.next()) {
|
|
||||||
result = rs.getLong("value"); // NON-NLS
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
} catch (SQLException ex) {
|
|
||||||
LOGGER.log(Level.SEVERE, "failed to read key: " + key + " from db_info", ex); // NON-NLS
|
|
||||||
} finally {
|
|
||||||
DBLock.unlock();
|
|
||||||
}
|
|
||||||
} catch (SQLException ex) {
|
|
||||||
LOGGER.log(Level.SEVERE, "failed to set key: " + key + " on getDBInfoStmt ", ex); // NON-NLS
|
|
||||||
}
|
|
||||||
|
|
||||||
return defaultValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
private PreparedStatement prepareStatement(String queryString) throws SQLException {
|
private PreparedStatement prepareStatement(String queryString) throws SQLException {
|
||||||
PreparedStatement prepareStatement = con.prepareStatement(queryString);
|
PreparedStatement prepareStatement = con.prepareStatement(queryString);
|
||||||
@ -1249,20 +1176,6 @@ public class EventDB {
|
|||||||
return prepareStatement;
|
return prepareStatement;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void recordDBInfo(DBInfoKey key, long value) {
|
|
||||||
DBLock.lock();
|
|
||||||
try {
|
|
||||||
recordDBInfoStmt.setString(1, key.toString());
|
|
||||||
recordDBInfoStmt.setLong(2, value);
|
|
||||||
recordDBInfoStmt.executeUpdate();
|
|
||||||
} catch (SQLException ex) {
|
|
||||||
LOGGER.log(Level.SEVERE, "failed to set dbinfo key: " + key + " value: " + value, ex); // NON-NLS
|
|
||||||
} finally {
|
|
||||||
DBLock.unlock();
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* inner class that can reference access database connection
|
* inner class that can reference access database connection
|
||||||
*/
|
*/
|
||||||
|
@ -35,6 +35,7 @@ import java.util.concurrent.ExecutionException;
|
|||||||
import java.util.concurrent.Executor;
|
import java.util.concurrent.Executor;
|
||||||
import java.util.concurrent.Executors;
|
import java.util.concurrent.Executors;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
import java.util.function.Consumer;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
import javafx.application.Platform;
|
import javafx.application.Platform;
|
||||||
@ -44,6 +45,7 @@ import javafx.beans.property.ReadOnlyObjectProperty;
|
|||||||
import javafx.collections.FXCollections;
|
import javafx.collections.FXCollections;
|
||||||
import javafx.collections.ObservableList;
|
import javafx.collections.ObservableList;
|
||||||
import javafx.collections.ObservableMap;
|
import javafx.collections.ObservableMap;
|
||||||
|
import javafx.concurrent.Worker;
|
||||||
import javax.swing.JOptionPane;
|
import javax.swing.JOptionPane;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.joda.time.Interval;
|
import org.joda.time.Interval;
|
||||||
@ -54,9 +56,7 @@ import org.sleuthkit.autopsy.casemodule.Case;
|
|||||||
import org.sleuthkit.autopsy.casemodule.services.TagsManager;
|
import org.sleuthkit.autopsy.casemodule.services.TagsManager;
|
||||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||||
import org.sleuthkit.autopsy.coreutils.ThreadConfined;
|
import org.sleuthkit.autopsy.coreutils.ThreadConfined;
|
||||||
import org.sleuthkit.autopsy.ingest.IngestManager;
|
|
||||||
import org.sleuthkit.autopsy.timeline.CancellationProgressTask;
|
import org.sleuthkit.autopsy.timeline.CancellationProgressTask;
|
||||||
import org.sleuthkit.autopsy.timeline.TimeLineController;
|
|
||||||
import org.sleuthkit.autopsy.timeline.datamodel.EventStripe;
|
import org.sleuthkit.autopsy.timeline.datamodel.EventStripe;
|
||||||
import org.sleuthkit.autopsy.timeline.datamodel.FilteredEventsModel;
|
import org.sleuthkit.autopsy.timeline.datamodel.FilteredEventsModel;
|
||||||
import org.sleuthkit.autopsy.timeline.datamodel.TimeLineEvent;
|
import org.sleuthkit.autopsy.timeline.datamodel.TimeLineEvent;
|
||||||
@ -168,7 +168,7 @@ public class EventsRepository {
|
|||||||
*/
|
*/
|
||||||
public Long getMaxTime() {
|
public Long getMaxTime() {
|
||||||
return maxCache.getUnchecked("max"); // NON-NLS
|
return maxCache.getUnchecked("max"); // NON-NLS
|
||||||
// return eventDB.getMaxTime();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -176,31 +176,7 @@ public class EventsRepository {
|
|||||||
*/
|
*/
|
||||||
public Long getMinTime() {
|
public Long getMinTime() {
|
||||||
return minCache.getUnchecked("min"); // NON-NLS
|
return minCache.getUnchecked("min"); // NON-NLS
|
||||||
// return eventDB.getMinTime();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void recordLastArtifactID(long lastArtfID) {
|
|
||||||
eventDB.recordLastArtifactID(lastArtfID);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void recordWasIngestRunning(Boolean wasIngestRunning) {
|
|
||||||
eventDB.recordWasIngestRunning(wasIngestRunning);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void recordLastObjID(Long lastObjID) {
|
|
||||||
eventDB.recordLastObjID(lastObjID);
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean getWasIngestRunning() {
|
|
||||||
return eventDB.getWasIngestRunning();
|
|
||||||
}
|
|
||||||
|
|
||||||
public Long getLastObjID() {
|
|
||||||
return eventDB.getLastObjID();
|
|
||||||
}
|
|
||||||
|
|
||||||
public long getLastArtfactID() {
|
|
||||||
return eventDB.getLastArtfactID();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public TimeLineEvent getEventById(Long eventID) {
|
public TimeLineEvent getEventById(Long eventID) {
|
||||||
@ -227,6 +203,10 @@ public class EventsRepository {
|
|||||||
return eventCountsCache.getUnchecked(params);
|
return eventCountsCache.getUnchecked(params);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
synchronized public int countAllEvents() {
|
||||||
|
return eventDB.countAllEvents();
|
||||||
|
}
|
||||||
|
|
||||||
private void invalidateCaches() {
|
private void invalidateCaches() {
|
||||||
minCache.invalidateAll();
|
minCache.invalidateAll();
|
||||||
maxCache.invalidateAll();
|
maxCache.invalidateAll();
|
||||||
@ -331,18 +311,6 @@ public class EventsRepository {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @param lastObjId the value of lastObjId
|
|
||||||
* @param lastArtfID the value of lastArtfID
|
|
||||||
* @param injestRunning the value of injestRunning
|
|
||||||
*/
|
|
||||||
public void recordDBPopulationState(final long lastObjId, final long lastArtfID, final Boolean injestRunning) {
|
|
||||||
recordLastObjID(lastObjId);
|
|
||||||
recordLastArtifactID(lastArtfID);
|
|
||||||
recordWasIngestRunning(injestRunning);
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean areFiltersEquivalent(RootFilter f1, RootFilter f2) {
|
public boolean areFiltersEquivalent(RootFilter f1, RootFilter f2) {
|
||||||
return SQLHelper.getSQLWhere(f1).equals(SQLHelper.getSQLWhere(f2));
|
return SQLHelper.getSQLWhere(f1).equals(SQLHelper.getSQLWhere(f2));
|
||||||
}
|
}
|
||||||
@ -352,27 +320,56 @@ public class EventsRepository {
|
|||||||
return dbWorker.isRunning();
|
return dbWorker.isRunning();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* rebuild the entire repo.
|
||||||
|
*
|
||||||
|
* @param onStateChange called when he background task changes state.
|
||||||
|
* Clients can use this to handle failure, or cleanup
|
||||||
|
* operations for example.
|
||||||
|
*
|
||||||
|
* @return the task that will rebuild the repo in a background thread. The
|
||||||
|
* task has already been started.
|
||||||
|
*/
|
||||||
@ThreadConfined(type = ThreadConfined.ThreadType.JFX)
|
@ThreadConfined(type = ThreadConfined.ThreadType.JFX)
|
||||||
public CancellationProgressTask<Void> rebuildRepository() {
|
public CancellationProgressTask<Void> rebuildRepository(Consumer<Worker.State> onStateChange) {
|
||||||
return rebuildRepository(DBPopulationMode.FULL);
|
return rebuildRepository(DBPopulationMode.FULL, onStateChange);
|
||||||
}
|
|
||||||
|
|
||||||
@ThreadConfined(type = ThreadConfined.ThreadType.JFX)
|
|
||||||
public CancellationProgressTask<Void> rebuildTags() {
|
|
||||||
return rebuildRepository(DBPopulationMode.TAGS_ONLY);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @param mode the value of mode
|
* drop and rebuild the tags in the repo.
|
||||||
|
*
|
||||||
|
* @param onStateChange called when he background task changes state.
|
||||||
|
* Clients can use this to handle failure, or cleanup
|
||||||
|
* operations for example.
|
||||||
|
*
|
||||||
|
* @return the task that will rebuild the repo in a background thread. The
|
||||||
|
* task has already been started.
|
||||||
*/
|
*/
|
||||||
@ThreadConfined(type = ThreadConfined.ThreadType.JFX)
|
@ThreadConfined(type = ThreadConfined.ThreadType.JFX)
|
||||||
private CancellationProgressTask<Void> rebuildRepository(final DBPopulationMode mode) {
|
public CancellationProgressTask<Void> rebuildTags(Consumer<Worker.State> onStateChange) {
|
||||||
|
return rebuildRepository(DBPopulationMode.TAGS_ONLY, onStateChange);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* rebuild the repo.
|
||||||
|
*
|
||||||
|
* @param mode the rebuild mode to use.
|
||||||
|
* @param onStateChange called when he background task changes state.
|
||||||
|
* Clients can use this to handle failure, or cleanup
|
||||||
|
* operations for example.
|
||||||
|
*
|
||||||
|
* @return the task that will rebuild the repo in a background thread. The
|
||||||
|
* task has already been started.
|
||||||
|
*/
|
||||||
|
@ThreadConfined(type = ThreadConfined.ThreadType.JFX)
|
||||||
|
private CancellationProgressTask<Void> rebuildRepository(final DBPopulationMode mode, Consumer<Worker.State> onStateChange) {
|
||||||
LOGGER.log(Level.INFO, "(re)starting {0} db population task", mode); //NON-NLS
|
LOGGER.log(Level.INFO, "(re)starting {0} db population task", mode); //NON-NLS
|
||||||
if (dbWorker != null) {
|
if (dbWorker != null) {
|
||||||
dbWorker.cancel();
|
dbWorker.cancel();
|
||||||
}
|
}
|
||||||
dbWorker = new DBPopulationWorker(mode);
|
dbWorker = new DBPopulationWorker(mode, onStateChange);
|
||||||
workerExecutor.execute(dbWorker);
|
workerExecutor.execute(dbWorker);
|
||||||
return dbWorker;
|
return dbWorker;
|
||||||
}
|
}
|
||||||
@ -437,10 +434,11 @@ public class EventsRepository {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
DBPopulationWorker(DBPopulationMode mode) {
|
DBPopulationWorker(DBPopulationMode mode, Consumer<Worker.State> onStateChange) {
|
||||||
skCase = autoCase.getSleuthkitCase();
|
skCase = autoCase.getSleuthkitCase();
|
||||||
tagsManager = autoCase.getServices().getTagsManager();
|
tagsManager = autoCase.getServices().getTagsManager();
|
||||||
this.dbPopulationMode = mode;
|
this.dbPopulationMode = mode;
|
||||||
|
this.stateProperty().addListener(stateObservable -> onStateChange.accept(getState()));
|
||||||
}
|
}
|
||||||
|
|
||||||
void restartProgressHandle(String title, String message, Double workDone, double total, Boolean cancellable) {
|
void restartProgressHandle(String title, String message, Double workDone, double total, Boolean cancellable) {
|
||||||
@ -470,11 +468,6 @@ public class EventsRepository {
|
|||||||
protected Void call() throws Exception {
|
protected Void call() throws Exception {
|
||||||
EventDB.EventTransaction trans = null;
|
EventDB.EventTransaction trans = null;
|
||||||
|
|
||||||
//save paramaters for recording later
|
|
||||||
long lastObjId = skCase.getLastObjectId();
|
|
||||||
long lastArtfID = TimeLineController.getCaseLastArtifactID(skCase);
|
|
||||||
boolean injestRunning = IngestManager.getInstance().isIngestRunning();
|
|
||||||
|
|
||||||
if (dbPopulationMode == DBPopulationMode.FULL) {
|
if (dbPopulationMode == DBPopulationMode.FULL) {
|
||||||
//drop old db, and add back MAC and artifact events
|
//drop old db, and add back MAC and artifact events
|
||||||
LOGGER.log(Level.INFO, "Beginning population of timeline db."); // NON-NLS
|
LOGGER.log(Level.INFO, "Beginning population of timeline db."); // NON-NLS
|
||||||
@ -513,9 +506,6 @@ public class EventsRepository {
|
|||||||
Platform.runLater(() -> cancellable.set(false));
|
Platform.runLater(() -> cancellable.set(false));
|
||||||
restartProgressHandle(Bundle.progressWindow_msg_commitingDb(), "", -1D, 1, false);
|
restartProgressHandle(Bundle.progressWindow_msg_commitingDb(), "", -1D, 1, false);
|
||||||
eventDB.commitTransaction(trans);
|
eventDB.commitTransaction(trans);
|
||||||
if (isCancelRequested() == false) {
|
|
||||||
recordDBPopulationState(lastObjId, lastArtfID, injestRunning);
|
|
||||||
}
|
|
||||||
|
|
||||||
eventDB.analyze();
|
eventDB.analyze();
|
||||||
populateFilterData(skCase);
|
populateFilterData(skCase);
|
||||||
|
@ -21,6 +21,7 @@ package org.sleuthkit.autopsy.timeline.filters;
|
|||||||
import javafx.beans.binding.Bindings;
|
import javafx.beans.binding.Bindings;
|
||||||
import javafx.beans.binding.BooleanBinding;
|
import javafx.beans.binding.BooleanBinding;
|
||||||
import javafx.beans.property.SimpleBooleanProperty;
|
import javafx.beans.property.SimpleBooleanProperty;
|
||||||
|
import javafx.beans.value.ObservableBooleanValue;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Base implementation of a {@link Filter}. Implements active property.
|
* Base implementation of a {@link Filter}. Implements active property.
|
||||||
@ -38,7 +39,7 @@ public abstract class AbstractFilter implements Filter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public SimpleBooleanProperty getDisabledProperty() {
|
public ObservableBooleanValue disabledProperty() {
|
||||||
return disabled;
|
return disabled;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -67,11 +68,11 @@ public abstract class AbstractFilter implements Filter {
|
|||||||
return "[" + (isSelected() ? "x" : " ") + "]"; // NON-NLS
|
return "[" + (isSelected() ? "x" : " ") + "]"; // NON-NLS
|
||||||
}
|
}
|
||||||
|
|
||||||
public final boolean isActive() {
|
public boolean isActive() {
|
||||||
return activeProperty.get();
|
return activeProperty.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
public final BooleanBinding activeProperty() {
|
public BooleanBinding activeProperty() {
|
||||||
return activeProperty;
|
return activeProperty;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -67,6 +67,13 @@ public abstract class CompoundFilter<SubFilterType extends Filter> extends Abstr
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
this.subFilters.setAll(subFilters);
|
this.subFilters.setAll(subFilters);
|
||||||
|
|
||||||
|
this.selectedProperty().addListener(activeProperty -> {
|
||||||
|
getSubFilters().forEach(subFilter -> subFilter.setDisabled(isActive() == false));
|
||||||
|
});
|
||||||
|
this.disabledProperty().addListener(activeProperty -> {
|
||||||
|
getSubFilters().forEach(subFilter -> subFilter.setDisabled(isActive() == false));
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private void addSubFilterListeners(List<? extends SubFilterType> newSubfilters) {
|
private void addSubFilterListeners(List<? extends SubFilterType> newSubfilters) {
|
||||||
|
@ -21,6 +21,7 @@ package org.sleuthkit.autopsy.timeline.filters;
|
|||||||
import java.util.Comparator;
|
import java.util.Comparator;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
import javafx.beans.binding.Bindings;
|
import javafx.beans.binding.Bindings;
|
||||||
|
import javafx.beans.value.ObservableBooleanValue;
|
||||||
import org.openide.util.NbBundle;
|
import org.openide.util.NbBundle;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -29,7 +30,6 @@ import org.openide.util.NbBundle;
|
|||||||
public class DataSourcesFilter extends UnionFilter<DataSourceFilter> {
|
public class DataSourcesFilter extends UnionFilter<DataSourceFilter> {
|
||||||
|
|
||||||
public DataSourcesFilter() {
|
public DataSourcesFilter() {
|
||||||
getDisabledProperty().bind(Bindings.size(getSubFilters()).lessThanOrEqualTo(1));
|
|
||||||
setSelected(false);
|
setSelected(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -69,7 +69,6 @@ public class DataSourcesFilter extends UnionFilter<DataSourceFilter> {
|
|||||||
.map(DataSourceFilter::getDataSourceID)
|
.map(DataSourceFilter::getDataSourceID)
|
||||||
.filter(t -> t == dataSourceFilter.getDataSourceID())
|
.filter(t -> t == dataSourceFilter.getDataSourceID())
|
||||||
.findAny().isPresent() == false) {
|
.findAny().isPresent() == false) {
|
||||||
dataSourceFilter.getDisabledProperty().bind(getDisabledProperty());
|
|
||||||
getSubFilters().add(dataSourceFilter);
|
getSubFilters().add(dataSourceFilter);
|
||||||
getSubFilters().sort(Comparator.comparing(DataSourceFilter::getDisplayName));
|
getSubFilters().sort(Comparator.comparing(DataSourceFilter::getDisplayName));
|
||||||
}
|
}
|
||||||
@ -100,4 +99,10 @@ public class DataSourcesFilter extends UnionFilter<DataSourceFilter> {
|
|||||||
public int hashCode() {
|
public int hashCode() {
|
||||||
return 9;
|
return 9;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ObservableBooleanValue disabledProperty() {
|
||||||
|
return Bindings.or(super.disabledProperty(), Bindings.size(getSubFilters()).lessThanOrEqualTo(1));
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -20,6 +20,7 @@ package org.sleuthkit.autopsy.timeline.filters;
|
|||||||
|
|
||||||
import javafx.beans.binding.BooleanBinding;
|
import javafx.beans.binding.BooleanBinding;
|
||||||
import javafx.beans.property.SimpleBooleanProperty;
|
import javafx.beans.property.SimpleBooleanProperty;
|
||||||
|
import javafx.beans.value.ObservableBooleanValue;
|
||||||
import javafx.collections.FXCollections;
|
import javafx.collections.FXCollections;
|
||||||
import javafx.collections.ObservableList;
|
import javafx.collections.ObservableList;
|
||||||
|
|
||||||
@ -77,7 +78,7 @@ public interface Filter {
|
|||||||
*/
|
*/
|
||||||
void setDisabled(Boolean act);
|
void setDisabled(Boolean act);
|
||||||
|
|
||||||
SimpleBooleanProperty getDisabledProperty();
|
ObservableBooleanValue disabledProperty();
|
||||||
|
|
||||||
boolean isDisabled();
|
boolean isDisabled();
|
||||||
|
|
||||||
|
@ -8,6 +8,7 @@ package org.sleuthkit.autopsy.timeline.filters;
|
|||||||
import java.util.Comparator;
|
import java.util.Comparator;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
import javafx.beans.binding.Bindings;
|
import javafx.beans.binding.Bindings;
|
||||||
|
import javafx.beans.value.ObservableBooleanValue;
|
||||||
import org.openide.util.NbBundle;
|
import org.openide.util.NbBundle;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -16,13 +17,12 @@ import org.openide.util.NbBundle;
|
|||||||
public class HashHitsFilter extends UnionFilter<HashSetFilter> {
|
public class HashHitsFilter extends UnionFilter<HashSetFilter> {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@NbBundle.Messages("hashHitsFilter.displayName.text=Only Hash Set Hits")
|
@NbBundle.Messages("hashHitsFilter.displayName.text=Hash Sets")
|
||||||
public String getDisplayName() {
|
public String getDisplayName() {
|
||||||
return Bundle.hashHitsFilter_displayName_text();
|
return Bundle.hashHitsFilter_displayName_text();
|
||||||
}
|
}
|
||||||
|
|
||||||
public HashHitsFilter() {
|
public HashHitsFilter() {
|
||||||
getDisabledProperty().bind(Bindings.size(getSubFilters()).lessThan(1));
|
|
||||||
setSelected(false);
|
setSelected(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -81,4 +81,9 @@ public class HashHitsFilter extends UnionFilter<HashSetFilter> {
|
|||||||
getSubFilters().sort(Comparator.comparing(HashSetFilter::getDisplayName));
|
getSubFilters().sort(Comparator.comparing(HashSetFilter::getDisplayName));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ObservableBooleanValue disabledProperty() {
|
||||||
|
return Bindings.or(super.disabledProperty(), Bindings.isEmpty(getSubFilters()));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -20,6 +20,7 @@ package org.sleuthkit.autopsy.timeline.filters;
|
|||||||
|
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
import javafx.beans.binding.BooleanBinding;
|
||||||
import javafx.collections.FXCollections;
|
import javafx.collections.FXCollections;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -108,4 +109,17 @@ public class RootFilter extends IntersectionFilter<Filter> {
|
|||||||
}
|
}
|
||||||
return areSubFiltersEqual(this, (CompoundFilter<Filter>) obj);
|
return areSubFiltersEqual(this, (CompoundFilter<Filter>) obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean isActive() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public BooleanBinding activeProperty() {
|
||||||
|
return new BooleanBinding() {
|
||||||
|
@Override
|
||||||
|
protected boolean computeValue() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -8,6 +8,7 @@ package org.sleuthkit.autopsy.timeline.filters;
|
|||||||
import java.util.Comparator;
|
import java.util.Comparator;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
import javafx.beans.binding.Bindings;
|
import javafx.beans.binding.Bindings;
|
||||||
|
import javafx.beans.value.ObservableBooleanValue;
|
||||||
import org.openide.util.NbBundle;
|
import org.openide.util.NbBundle;
|
||||||
import org.sleuthkit.datamodel.TagName;
|
import org.sleuthkit.datamodel.TagName;
|
||||||
|
|
||||||
@ -17,13 +18,12 @@ import org.sleuthkit.datamodel.TagName;
|
|||||||
public class TagsFilter extends UnionFilter<TagNameFilter> {
|
public class TagsFilter extends UnionFilter<TagNameFilter> {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@NbBundle.Messages("tagsFilter.displayName.text=Only Events Tagged")
|
@NbBundle.Messages("tagsFilter.displayName.text=Tags")
|
||||||
public String getDisplayName() {
|
public String getDisplayName() {
|
||||||
return Bundle.tagsFilter_displayName_text();
|
return Bundle.tagsFilter_displayName_text();
|
||||||
}
|
}
|
||||||
|
|
||||||
public TagsFilter() {
|
public TagsFilter() {
|
||||||
getDisabledProperty().bind(Bindings.size(getSubFilters()).lessThan(1));
|
|
||||||
setSelected(false);
|
setSelected(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -89,5 +89,8 @@ public class TagsFilter extends UnionFilter<TagNameFilter> {
|
|||||||
getSubFilters().sort(Comparator.comparing(TagNameFilter::getDisplayName));
|
getSubFilters().sort(Comparator.comparing(TagNameFilter::getDisplayName));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ObservableBooleanValue disabledProperty() {
|
||||||
|
return Bindings.or(super.disabledProperty(), Bindings.isEmpty(getSubFilters()));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -72,7 +72,7 @@ public class TypeFilter extends UnionFilter<TypeFilter> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@NbBundle.Messages("TypeFilter.displayName.text=Event Type Filter")
|
@NbBundle.Messages("TypeFilter.displayName.text=Event Type")
|
||||||
public String getDisplayName() {
|
public String getDisplayName() {
|
||||||
return (eventType == RootEventType.getInstance())
|
return (eventType == RootEventType.getInstance())
|
||||||
? Bundle.TypeFilter_displayName_text()
|
? Bundle.TypeFilter_displayName_text()
|
||||||
|
@ -74,8 +74,8 @@ public class StatusBar extends ToolBar {
|
|||||||
taskLabel.setVisible(false);
|
taskLabel.setVisible(false);
|
||||||
HBox.setHgrow(spacer, Priority.ALWAYS);
|
HBox.setHgrow(spacer, Priority.ALWAYS);
|
||||||
|
|
||||||
refreshLabel.visibleProperty().bind(this.controller.getNewEventsFlag());
|
refreshLabel.visibleProperty().bind(this.controller.eventsDBStaleProperty());
|
||||||
refreshLabel.managedProperty().bind(this.controller.getNewEventsFlag());
|
refreshLabel.managedProperty().bind(this.controller.eventsDBStaleProperty());
|
||||||
taskLabel.textProperty().bind(this.controller.taskTitleProperty());
|
taskLabel.textProperty().bind(this.controller.taskTitleProperty());
|
||||||
messageLabel.textProperty().bind(this.controller.taskMessageProperty());
|
messageLabel.textProperty().bind(this.controller.taskMessageProperty());
|
||||||
progressBar.progressProperty().bind(this.controller.taskProgressProperty());
|
progressBar.progressProperty().bind(this.controller.taskProgressProperty());
|
||||||
@ -83,6 +83,5 @@ public class StatusBar extends ToolBar {
|
|||||||
|
|
||||||
statusLabel.textProperty().bind(this.controller.getStatusProperty());
|
statusLabel.textProperty().bind(this.controller.getStatusProperty());
|
||||||
statusLabel.visibleProperty().bind(statusLabel.textProperty().isNotEmpty());
|
statusLabel.visibleProperty().bind(statusLabel.textProperty().isNotEmpty());
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -347,9 +347,9 @@ final public class VisualizationPanel extends BorderPane {
|
|||||||
refreshTimeUI(); //populate the viz
|
refreshTimeUI(); //populate the viz
|
||||||
|
|
||||||
//this should use an event(EventBus) , not this weird observable pattern
|
//this should use an event(EventBus) , not this weird observable pattern
|
||||||
controller.getNeedsHistogramRebuild().addListener((observable, oldValue, newValue) -> {
|
controller.eventsDBStaleProperty().addListener(staleProperty -> {
|
||||||
if (newValue) {
|
if (controller.isEventsDBStale()) {
|
||||||
refreshHistorgram();
|
Platform.runLater(VisualizationPanel.this::refreshHistorgram);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
refreshHistorgram();
|
refreshHistorgram();
|
||||||
|
@ -20,6 +20,7 @@ package org.sleuthkit.autopsy.timeline.ui.filtering;
|
|||||||
|
|
||||||
import java.util.function.Supplier;
|
import java.util.function.Supplier;
|
||||||
import javafx.beans.property.SimpleBooleanProperty;
|
import javafx.beans.property.SimpleBooleanProperty;
|
||||||
|
import javafx.beans.value.ObservableBooleanValue;
|
||||||
import javafx.scene.control.CheckBox;
|
import javafx.scene.control.CheckBox;
|
||||||
import javafx.scene.control.IndexedCell;
|
import javafx.scene.control.IndexedCell;
|
||||||
import org.sleuthkit.autopsy.timeline.filters.AbstractFilter;
|
import org.sleuthkit.autopsy.timeline.filters.AbstractFilter;
|
||||||
@ -29,7 +30,7 @@ class FilterCheckBoxCellFactory<X extends AbstractFilter> extends AbstractFXCell
|
|||||||
|
|
||||||
private final CheckBox checkBox = new CheckBox();
|
private final CheckBox checkBox = new CheckBox();
|
||||||
private SimpleBooleanProperty selectedProperty;
|
private SimpleBooleanProperty selectedProperty;
|
||||||
private SimpleBooleanProperty disabledProperty;
|
private ObservableBooleanValue disabledProperty;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void configureCell(IndexedCell<? extends X> cell, X item, boolean empty, Supplier<X> supplier) {
|
protected void configureCell(IndexedCell<? extends X> cell, X item, boolean empty, Supplier<X> supplier) {
|
||||||
@ -37,18 +38,17 @@ class FilterCheckBoxCellFactory<X extends AbstractFilter> extends AbstractFXCell
|
|||||||
checkBox.selectedProperty().unbindBidirectional(selectedProperty);
|
checkBox.selectedProperty().unbindBidirectional(selectedProperty);
|
||||||
}
|
}
|
||||||
if (disabledProperty != null) {
|
if (disabledProperty != null) {
|
||||||
checkBox.disableProperty().unbindBidirectional(disabledProperty);
|
checkBox.disableProperty().unbind();//disabledProperty);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (item == null) {
|
if (item == null) {
|
||||||
cell.setText(null);
|
|
||||||
cell.setGraphic(null);
|
cell.setGraphic(null);
|
||||||
} else {
|
} else {
|
||||||
cell.setText(item.getDisplayName());
|
checkBox.setText(item.getDisplayName());
|
||||||
selectedProperty = item.selectedProperty();
|
selectedProperty = item.selectedProperty();
|
||||||
checkBox.selectedProperty().bindBidirectional(selectedProperty);
|
checkBox.selectedProperty().bindBidirectional(selectedProperty);
|
||||||
disabledProperty = item.getDisabledProperty();
|
disabledProperty = item.disabledProperty();
|
||||||
checkBox.disableProperty().bindBidirectional(disabledProperty);
|
checkBox.disableProperty().bind(disabledProperty);
|
||||||
cell.setGraphic(checkBox);
|
cell.setGraphic(checkBox);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
Manifest-Version: 1.0
|
Manifest-Version: 1.0
|
||||||
OpenIDE-Module: org.sleuthkit.autopsy.corelibs/3
|
OpenIDE-Module: org.sleuthkit.autopsy.corelibs/3
|
||||||
|
OpenIDE-Module-Implementation-Version: 4
|
||||||
OpenIDE-Module-Localizing-Bundle: org/sleuthkit/autopsy/corelibs/Bundle.properties
|
OpenIDE-Module-Localizing-Bundle: org/sleuthkit/autopsy/corelibs/Bundle.properties
|
||||||
OpenIDE-Module-Specification-Version: 1.1
|
OpenIDE-Module-Specification-Version: 1.1
|
||||||
AutoUpdate-Show-In-Client: true
|
AutoUpdate-Show-In-Client: true
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
Manifest-Version: 1.0
|
Manifest-Version: 1.0
|
||||||
OpenIDE-Module: org.sleuthkit.autopsy.imagegallery/1
|
OpenIDE-Module: org.sleuthkit.autopsy.imagegallery/2
|
||||||
OpenIDE-Module-Implementation-Version: 1
|
OpenIDE-Module-Implementation-Version: 2
|
||||||
OpenIDE-Module-Localizing-Bundle: org/sleuthkit/autopsy/imagegallery/Bundle.properties
|
OpenIDE-Module-Localizing-Bundle: org/sleuthkit/autopsy/imagegallery/Bundle.properties
|
||||||
|
|
||||||
|
@ -5,4 +5,4 @@ license.file=LICENSE-2.0.txt
|
|||||||
nbm.homepage=http://www.sleuthkit.org/
|
nbm.homepage=http://www.sleuthkit.org/
|
||||||
nbm.needs.restart=true
|
nbm.needs.restart=true
|
||||||
project.license=imagegallery
|
project.license=imagegallery
|
||||||
spec.version.base=1.0
|
spec.version.base=2.0
|
||||||
|
@ -103,7 +103,7 @@
|
|||||||
<compile-dependency/>
|
<compile-dependency/>
|
||||||
<run-dependency>
|
<run-dependency>
|
||||||
<release-version>10</release-version>
|
<release-version>10</release-version>
|
||||||
<specification-version>10.0.11</specification-version>
|
<specification-version>10.5</specification-version>
|
||||||
</run-dependency>
|
</run-dependency>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
|
@ -23,16 +23,16 @@ import java.util.Arrays;
|
|||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import static java.util.Objects.isNull;
|
import static java.util.Objects.isNull;
|
||||||
import java.util.Optional;
|
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
import javax.imageio.ImageIO;
|
import javax.imageio.ImageIO;
|
||||||
import org.sleuthkit.autopsy.coreutils.ImageUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||||
import org.sleuthkit.autopsy.modules.filetypeid.FileTypeDetector;
|
import org.sleuthkit.autopsy.modules.filetypeid.FileTypeDetector;
|
||||||
import org.sleuthkit.datamodel.AbstractFile;
|
import org.sleuthkit.datamodel.AbstractFile;
|
||||||
|
import org.sleuthkit.datamodel.Content;
|
||||||
import org.sleuthkit.datamodel.TskCoreException;
|
import org.sleuthkit.datamodel.TskCoreException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -149,13 +149,13 @@ public enum FileTypeUtils {
|
|||||||
return Collections.unmodifiableSet(supportedExtensions);
|
return Collections.unmodifiableSet(supportedExtensions);
|
||||||
}
|
}
|
||||||
|
|
||||||
static synchronized FileTypeDetector getFileTypeDetector() {
|
static synchronized FileTypeDetector getFileTypeDetector() throws FileTypeDetector.FileTypeDetectorInitException {
|
||||||
|
/*
|
||||||
|
* TODO: EUR-740 recreate FileTypeDetector when the user creates new
|
||||||
|
* user defined file types
|
||||||
|
*/
|
||||||
if (isNull(FILE_TYPE_DETECTOR)) {
|
if (isNull(FILE_TYPE_DETECTOR)) {
|
||||||
try {
|
|
||||||
FILE_TYPE_DETECTOR = new FileTypeDetector();
|
FILE_TYPE_DETECTOR = new FileTypeDetector();
|
||||||
} catch (FileTypeDetector.FileTypeDetectorInitException ex) {
|
|
||||||
LOGGER.log(Level.SEVERE, "Failed to initialize File Type Detector, will fall back on extensions in some situations.", ex); //NON-NLS
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return FILE_TYPE_DETECTOR;
|
return FILE_TYPE_DETECTOR;
|
||||||
}
|
}
|
||||||
@ -169,24 +169,12 @@ public enum FileTypeUtils {
|
|||||||
*
|
*
|
||||||
* @return true if this file is supported or false if not
|
* @return true if this file is supported or false if not
|
||||||
*/
|
*/
|
||||||
public static boolean isDrawable(AbstractFile file) throws TskCoreException {
|
public static boolean isDrawable(AbstractFile file) throws TskCoreException, FileTypeDetector.FileTypeDetectorInitException {
|
||||||
return hasDrawableMimeType(file).orElseGet(() -> {
|
return hasDrawableMIMEType(file);
|
||||||
return FileTypeUtils.supportedExtensions.contains(file.getNameExtension().toLowerCase())
|
|
||||||
|| ImageUtils.isJpegFileHeader(file)
|
|
||||||
|| ImageUtils.isPngFileHeader(file);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
public static boolean isGIF(AbstractFile file) {
|
|
||||||
return ImageUtils.isGIF(file);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Optional<String> getMimeType(AbstractFile file) throws TskCoreException {
|
|
||||||
return Optional.ofNullable(file.getMIMEType());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static boolean isDrawableMimeType(String mimeType) {
|
static boolean isDrawableMimeType(String mimeType) {
|
||||||
if (isNull(mimeType)) {
|
if (StringUtils.isBlank(mimeType)) {
|
||||||
return false;
|
return false;
|
||||||
} else {
|
} else {
|
||||||
String mimeTypeLower = mimeType.toLowerCase();
|
String mimeTypeLower = mimeType.toLowerCase();
|
||||||
@ -197,6 +185,10 @@ public enum FileTypeUtils {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
*
|
||||||
|
* TODO: EUR-740 recreate FileTypeDetector when the user creates new user
|
||||||
|
* defined file types
|
||||||
|
*
|
||||||
* does the given file have drawable/supported mime type
|
* does the given file have drawable/supported mime type
|
||||||
*
|
*
|
||||||
* @param file
|
* @param file
|
||||||
@ -205,8 +197,9 @@ public enum FileTypeUtils {
|
|||||||
* type. False if a non image/video mimetype. empty Optional if a
|
* type. False if a non image/video mimetype. empty Optional if a
|
||||||
* mimetype could not be detected.
|
* mimetype could not be detected.
|
||||||
*/
|
*/
|
||||||
static Optional<Boolean> hasDrawableMimeType(AbstractFile file) throws TskCoreException {
|
static boolean hasDrawableMIMEType(AbstractFile file) throws TskCoreException, FileTypeDetector.FileTypeDetectorInitException {
|
||||||
return getMimeType(file).map(FileTypeUtils::isDrawableMimeType);
|
String mimeType = getFileTypeDetector().detect(file).toLowerCase();
|
||||||
|
return isDrawableMimeType(mimeType) || (mimeType.equals("audio/x-aiff") && "tiff".equalsIgnoreCase(file.getNameExtension()));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -218,16 +211,31 @@ public enum FileTypeUtils {
|
|||||||
* application/x-shockwave-flash, etc) or, if no mimetype is
|
* application/x-shockwave-flash, etc) or, if no mimetype is
|
||||||
* available, a video extension.
|
* available, a video extension.
|
||||||
*/
|
*/
|
||||||
public static boolean isVideoFile(AbstractFile file) {
|
public static boolean hasVideoMIMEType(AbstractFile file) {
|
||||||
try {
|
try {
|
||||||
return getMimeType(file)
|
String mimeType = getFileTypeDetector().detect(file).toLowerCase();
|
||||||
.map(String::toLowerCase)
|
return mimeType.startsWith("video/") || videoMimeTypes.contains(mimeType);
|
||||||
.map(mimeType
|
} catch (FileTypeDetector.FileTypeDetectorInitException | TskCoreException ex) {
|
||||||
-> mimeType.startsWith("video/")
|
LOGGER.log(Level.SEVERE, "Error determining MIME type of " + getContentPathSafe(file), ex);
|
||||||
|| videoMimeTypes.contains(mimeType))
|
return false;
|
||||||
.orElseGet(() -> FileTypeUtils.videoExtensions.contains(file.getNameExtension()));
|
}
|
||||||
} catch (TskCoreException ex) {
|
}
|
||||||
return FileTypeUtils.videoExtensions.contains(file.getNameExtension());
|
|
||||||
|
/**
|
||||||
|
* Get the unique path for the content, or if that fails, just return the
|
||||||
|
* name.
|
||||||
|
*
|
||||||
|
* @param content
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
static String getContentPathSafe(Content content) {
|
||||||
|
try {
|
||||||
|
return content.getUniquePath();
|
||||||
|
} catch (TskCoreException tskCoreException) {
|
||||||
|
String contentName = content.getName();
|
||||||
|
LOGGER.log(Level.SEVERE, "Failed to get unique path for " + contentName, tskCoreException); //NOI18N NON-NLS
|
||||||
|
return contentName;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -20,16 +20,13 @@ package org.sleuthkit.autopsy.imagegallery;
|
|||||||
|
|
||||||
import java.beans.PropertyChangeEvent;
|
import java.beans.PropertyChangeEvent;
|
||||||
import java.beans.PropertyChangeListener;
|
import java.beans.PropertyChangeListener;
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
import java.util.Optional;
|
|
||||||
import java.util.concurrent.BlockingQueue;
|
import java.util.concurrent.BlockingQueue;
|
||||||
import java.util.concurrent.Executor;
|
import java.util.concurrent.Executor;
|
||||||
import java.util.concurrent.Executors;
|
import java.util.concurrent.Executors;
|
||||||
import java.util.concurrent.LinkedBlockingQueue;
|
import java.util.concurrent.LinkedBlockingQueue;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
import java.util.stream.Collectors;
|
|
||||||
import javafx.application.Platform;
|
import javafx.application.Platform;
|
||||||
import javafx.beans.Observable;
|
import javafx.beans.Observable;
|
||||||
import javafx.beans.property.ReadOnlyBooleanProperty;
|
import javafx.beans.property.ReadOnlyBooleanProperty;
|
||||||
@ -79,14 +76,12 @@ import org.sleuthkit.autopsy.imagegallery.datamodel.grouping.GroupViewState;
|
|||||||
import org.sleuthkit.autopsy.imagegallery.gui.NoGroupsDialog;
|
import org.sleuthkit.autopsy.imagegallery.gui.NoGroupsDialog;
|
||||||
import org.sleuthkit.autopsy.imagegallery.gui.Toolbar;
|
import org.sleuthkit.autopsy.imagegallery.gui.Toolbar;
|
||||||
import org.sleuthkit.autopsy.ingest.IngestManager;
|
import org.sleuthkit.autopsy.ingest.IngestManager;
|
||||||
|
import org.sleuthkit.autopsy.modules.filetypeid.FileTypeDetector;
|
||||||
import org.sleuthkit.datamodel.AbstractFile;
|
import org.sleuthkit.datamodel.AbstractFile;
|
||||||
import org.sleuthkit.datamodel.Content;
|
import org.sleuthkit.datamodel.Content;
|
||||||
import org.sleuthkit.datamodel.FileSystem;
|
|
||||||
import org.sleuthkit.datamodel.Image;
|
|
||||||
import org.sleuthkit.datamodel.SleuthkitCase;
|
import org.sleuthkit.datamodel.SleuthkitCase;
|
||||||
import org.sleuthkit.datamodel.TskCoreException;
|
import org.sleuthkit.datamodel.TskCoreException;
|
||||||
import org.sleuthkit.datamodel.TskData;
|
import org.sleuthkit.datamodel.TskData;
|
||||||
import org.sleuthkit.datamodel.VirtualDirectory;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Connects different parts of ImageGallery together and is hub for flow of
|
* Connects different parts of ImageGallery together and is hub for flow of
|
||||||
@ -853,23 +848,15 @@ public final class ImageGalleryController implements Executor {
|
|||||||
if (known) {
|
if (known) {
|
||||||
taskDB.removeFile(f.getId(), tr); //remove known files
|
taskDB.removeFile(f.getId(), tr); //remove known files
|
||||||
} else {
|
} else {
|
||||||
Optional<String> mimeType = FileTypeUtils.getMimeType(f);
|
|
||||||
if (mimeType.isPresent()) {
|
try {
|
||||||
//mime type
|
if (FileTypeUtils.hasDrawableMIMEType(f)) { //supported mimetype => analyzed
|
||||||
if (FileTypeUtils.isDrawableMimeType(mimeType.get())) { //supported mimetype => analyzed
|
|
||||||
taskDB.updateFile(DrawableFile.create(f, true, false), tr);
|
taskDB.updateFile(DrawableFile.create(f, true, false), tr);
|
||||||
} else { //unsupported mimtype => analyzed but shouldn't include
|
} else { //unsupported mimtype => analyzed but shouldn't include
|
||||||
taskDB.removeFile(f.getId(), tr);
|
taskDB.removeFile(f.getId(), tr);
|
||||||
}
|
}
|
||||||
} else {
|
} catch (FileTypeDetector.FileTypeDetectorInitException ex) {
|
||||||
//no mime tyoe
|
throw new RuntimeException(ex);
|
||||||
if (FileTypeUtils.isDrawable(f)) {
|
|
||||||
//no mime type but supported => add as not analyzed
|
|
||||||
taskDB.insertFile(DrawableFile.create(f, false, false), tr);
|
|
||||||
} else {
|
|
||||||
//no mime type, not supported => remove ( should never get here)
|
|
||||||
taskDB.removeFile(f.getId(), tr);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -916,37 +903,8 @@ public final class ImageGalleryController implements Executor {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
List<AbstractFile> getFiles() throws TskCoreException {
|
List<AbstractFile> getFiles() throws TskCoreException {
|
||||||
if (dataSource instanceof Image) {
|
long datasourceID = dataSource.getDataSource().getId();
|
||||||
List<FileSystem> fileSystems = ((Image) dataSource).getFileSystems();
|
return tskCase.findAllFilesWhere("data_source_obj_id = " + datasourceID + " AND " + DRAWABLE_QUERY);
|
||||||
if (fileSystems.isEmpty()) {
|
|
||||||
/*
|
|
||||||
* no filesystems, don't bother with the initial population,
|
|
||||||
* just sort things out on file_done events
|
|
||||||
*/
|
|
||||||
progressHandle.finish();
|
|
||||||
return Collections.emptyList();
|
|
||||||
}
|
|
||||||
//use this clause to only grab files from the newly added filesystems.
|
|
||||||
String fsQuery = fileSystems.stream()
|
|
||||||
.map(fileSystem -> String.valueOf(fileSystem.getId()))
|
|
||||||
.collect(Collectors.joining(" OR fs_obj_id = ", "(fs_obj_id = ", ") ")); //NON-NLS
|
|
||||||
|
|
||||||
return tskCase.findAllFilesWhere(fsQuery + " AND " + DRAWABLE_QUERY); //NON-NLS
|
|
||||||
} else if (dataSource instanceof VirtualDirectory) {
|
|
||||||
/*
|
|
||||||
* fs_obj_id is set only for file system files, so we will match
|
|
||||||
* the VirtualDirectory's name in the parent path.
|
|
||||||
*
|
|
||||||
* TODO: A future database schema could probably make this
|
|
||||||
* cleaner. If we had a datasource_id column in the files table
|
|
||||||
* we could just match agains that.
|
|
||||||
*/
|
|
||||||
return tskCase.findAllFilesWhere(" parent_path LIKE '/" + dataSource.getName() + "/%' AND " + DRAWABLE_QUERY); //NON-NLS
|
|
||||||
} else {
|
|
||||||
String msg = "Uknown datasource type: " + dataSource.getClass().getName();
|
|
||||||
LOGGER.log(Level.SEVERE, msg);
|
|
||||||
throw new IllegalArgumentException(msg);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -1002,10 +960,11 @@ public final class ImageGalleryController implements Executor {
|
|||||||
//this file would have gotten scooped up in initial grab, but actually we don't need it
|
//this file would have gotten scooped up in initial grab, but actually we don't need it
|
||||||
queueDBWorkerTask(new RemoveFileTask(file, db));
|
queueDBWorkerTask(new RemoveFileTask(file, db));
|
||||||
}
|
}
|
||||||
} catch (TskCoreException ex) {
|
} catch (TskCoreException | FileTypeDetector.FileTypeDetectorInitException ex) {
|
||||||
//TODO: What to do here?
|
//TODO: What to do here?
|
||||||
LOGGER.log(Level.WARNING, "Unable to determine if file is drawable and not known. Not making any changes to DB", ex); //NON-NLS
|
LOGGER.log(Level.SEVERE, "Unable to determine if file is drawable and not known. Not making any changes to DB", ex); //NON-NLS
|
||||||
throw new RuntimeException(ex);
|
MessageNotifyUtil.Notify.error("Image Gallery Error",
|
||||||
|
"Unable to determine if file is drawable and not known. Not making any changes to DB. See the logs for details.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else { //TODO: keep track of what we missed for later
|
} else { //TODO: keep track of what we missed for later
|
||||||
|
@ -22,11 +22,11 @@ import java.nio.file.Path;
|
|||||||
import java.nio.file.Paths;
|
import java.nio.file.Paths;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import static org.apache.commons.lang3.StringUtils.isNotBlank;
|
import static org.apache.commons.lang3.StringUtils.isNotBlank;
|
||||||
|
|
||||||
import org.openide.util.NbBundle;
|
import org.openide.util.NbBundle;
|
||||||
import org.sleuthkit.autopsy.casemodule.Case;
|
import org.sleuthkit.autopsy.casemodule.Case;
|
||||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||||
import org.sleuthkit.autopsy.imagegallery.datamodel.DrawableDB;
|
import org.sleuthkit.autopsy.imagegallery.datamodel.DrawableDB;
|
||||||
|
import org.sleuthkit.autopsy.modules.filetypeid.FileTypeDetector;
|
||||||
import org.sleuthkit.datamodel.AbstractFile;
|
import org.sleuthkit.datamodel.AbstractFile;
|
||||||
import org.sleuthkit.datamodel.TskCoreException;
|
import org.sleuthkit.datamodel.TskCoreException;
|
||||||
import org.sleuthkit.datamodel.TskData;
|
import org.sleuthkit.datamodel.TskData;
|
||||||
@ -105,7 +105,7 @@ public class ImageGalleryModule {
|
|||||||
* @return true if the given {@link AbstractFile} is "drawable" and not
|
* @return true if the given {@link AbstractFile} is "drawable" and not
|
||||||
* 'known', else false
|
* 'known', else false
|
||||||
*/
|
*/
|
||||||
public static boolean isDrawableAndNotKnown(AbstractFile abstractFile) throws TskCoreException {
|
public static boolean isDrawableAndNotKnown(AbstractFile abstractFile) throws TskCoreException, FileTypeDetector.FileTypeDetectorInitException {
|
||||||
return (abstractFile.getKnown() != TskData.FileKnown.KNOWN) && FileTypeUtils.isDrawable(abstractFile);
|
return (abstractFile.getKnown() != TskData.FileKnown.KNOWN) && FileTypeUtils.isDrawable(abstractFile);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -126,7 +126,7 @@ public enum ThumbnailCache {
|
|||||||
*/
|
*/
|
||||||
private Image load(DrawableFile file) {
|
private Image load(DrawableFile file) {
|
||||||
|
|
||||||
if (FileTypeUtils.isGIF(file.getAbstractFile())) {
|
if (ImageUtils.isGIF(file.getAbstractFile())) {
|
||||||
//directly read gif to preserve potential animation,
|
//directly read gif to preserve potential animation,
|
||||||
//NOTE: not saved to disk!
|
//NOTE: not saved to disk!
|
||||||
return new Image(new BufferedInputStream(new ReadContentInputStream(file.getAbstractFile())), MAX_THUMBNAIL_SIZE, MAX_THUMBNAIL_SIZE, true, true);
|
return new Image(new BufferedInputStream(new ReadContentInputStream(file.getAbstractFile())), MAX_THUMBNAIL_SIZE, MAX_THUMBNAIL_SIZE, true, true);
|
||||||
|
@ -1176,8 +1176,7 @@ public final class DrawableDB {
|
|||||||
*/
|
*/
|
||||||
public boolean isVideoFile(AbstractFile f) {
|
public boolean isVideoFile(AbstractFile f) {
|
||||||
return isNull(f) ? false
|
return isNull(f) ? false
|
||||||
: videoFileMap.computeIfAbsent(f.getId(), id -> FileTypeUtils.isVideoFile(f));
|
: videoFileMap.computeIfAbsent(f.getId(), id -> FileTypeUtils.hasVideoMIMEType(f));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1242,8 +1241,8 @@ public final class DrawableDB {
|
|||||||
String fileIdsList = "(" + StringUtils.join(fileIDs, ",") + " )";
|
String fileIdsList = "(" + StringUtils.join(fileIDs, ",") + " )";
|
||||||
|
|
||||||
//count the fileids that are in the given list and don't have a non-zero category assigned to them.
|
//count the fileids that are in the given list and don't have a non-zero category assigned to them.
|
||||||
String name
|
String name =
|
||||||
= "SELECT COUNT(obj_id) FROM tsk_files where obj_id IN " + fileIdsList //NON-NLS
|
"SELECT COUNT(obj_id) FROM tsk_files where obj_id IN " + fileIdsList //NON-NLS
|
||||||
+ " AND obj_id NOT IN (SELECT obj_id FROM content_tags WHERE content_tags.tag_name_id IN " + catTagNameIDs + ")"; //NON-NLS
|
+ " AND obj_id NOT IN (SELECT obj_id FROM content_tags WHERE content_tags.tag_name_id IN " + catTagNameIDs + ")"; //NON-NLS
|
||||||
try (SleuthkitCase.CaseDbQuery executeQuery = controller.getSleuthKitCase().executeQuery(name);
|
try (SleuthkitCase.CaseDbQuery executeQuery = controller.getSleuthKitCase().executeQuery(name);
|
||||||
ResultSet resultSet = executeQuery.getResultSet();) {
|
ResultSet resultSet = executeQuery.getResultSet();) {
|
||||||
|
@ -60,7 +60,7 @@ public abstract class DrawableFile {
|
|||||||
private static final Logger LOGGER = Logger.getLogger(DrawableFile.class.getName());
|
private static final Logger LOGGER = Logger.getLogger(DrawableFile.class.getName());
|
||||||
|
|
||||||
public static DrawableFile create(AbstractFile abstractFileById, boolean analyzed) {
|
public static DrawableFile create(AbstractFile abstractFileById, boolean analyzed) {
|
||||||
return create(abstractFileById, analyzed, FileTypeUtils.isVideoFile(abstractFileById));
|
return create(abstractFileById, analyzed, FileTypeUtils.hasVideoMIMEType(abstractFileById));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user