Merged upstream/develop.

This commit is contained in:
Oliver Spohngellert 2016-06-22 08:58:01 -04:00
commit 4294885a63
203 changed files with 8355 additions and 5258 deletions

View File

@ -15,6 +15,22 @@
<specification-version>1.28.1</specification-version>
</run-dependency>
</dependency>
<dependency>
<code-name-base>org.netbeans.api.progress.compat8</code-name-base>
<build-prerequisite/>
<compile-dependency/>
<run-dependency>
<specification-version>1.46.1</specification-version>
</run-dependency>
</dependency>
<dependency>
<code-name-base>org.netbeans.api.progress.nb</code-name-base>
<build-prerequisite/>
<compile-dependency/>
<run-dependency>
<specification-version>1.46.1</specification-version>
</run-dependency>
</dependency>
<dependency>
<code-name-base>org.netbeans.core</code-name-base>
<build-prerequisite/>
@ -123,6 +139,22 @@
<specification-version>7.62.1</specification-version>
</run-dependency>
</dependency>
<dependency>
<code-name-base>org.openide.filesystems.compat8</code-name-base>
<build-prerequisite/>
<compile-dependency/>
<run-dependency>
<specification-version>9.7.1</specification-version>
</run-dependency>
</dependency>
<dependency>
<code-name-base>org.openide.filesystems.nb</code-name-base>
<build-prerequisite/>
<compile-dependency/>
<run-dependency>
<specification-version>9.7.1</specification-version>
</run-dependency>
</dependency>
<dependency>
<code-name-base>org.openide.modules</code-name-base>
<build-prerequisite/>
@ -163,6 +195,14 @@
<specification-version>8.15.1</specification-version>
</run-dependency>
</dependency>
<dependency>
<code-name-base>org.openide.util.ui</code-name-base>
<build-prerequisite/>
<compile-dependency/>
<run-dependency>
<specification-version>9.4.1</specification-version>
</run-dependency>
</dependency>
<dependency>
<code-name-base>org.openide.windows</code-name-base>
<build-prerequisite/>

View File

@ -1,15 +1,15 @@
/*
* Autopsy Forensic Browser
*
* Copyright 2013-2015 Basis Technology Corp.
*
* Copyright 2011-2016 Basis Technology Corp.
* Contact: carrier <at> sleuthkit <dot> org
*
*
* Licensed under the Apache License, Version 2.0 (the "License");
* 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.
@ -19,6 +19,7 @@
package org.sleuthkit.autopsy.actions;
import java.util.Collection;
import java.util.HashSet;
import java.util.logging.Level;
import javax.swing.JOptionPane;
import javax.swing.SwingUtilities;
@ -26,8 +27,8 @@ import org.openide.util.NbBundle;
import org.openide.util.Utilities;
import org.sleuthkit.autopsy.casemodule.Case;
import org.sleuthkit.autopsy.coreutils.Logger;
import org.sleuthkit.datamodel.TagName;
import org.sleuthkit.datamodel.BlackboardArtifact;
import org.sleuthkit.datamodel.TagName;
import org.sleuthkit.datamodel.TskCoreException;
/**
@ -38,7 +39,6 @@ public class AddBlackboardArtifactTagAction extends AddTagAction {
// This class is a singleton to support multi-selection of nodes, since
// org.openide.nodes.NodeOp.findActions(Node[] nodes) will only pick up an Action if every
// node in the array returns a reference to the same action object from Node.getActions(boolean).
private static AddBlackboardArtifactTagAction instance;
public static synchronized AddBlackboardArtifactTagAction getInstance() {
@ -63,7 +63,14 @@ public class AddBlackboardArtifactTagAction extends AddTagAction {
@Override
protected void addTag(TagName tagName, String comment) {
final Collection<? extends BlackboardArtifact> selectedArtifacts = Utilities.actionsGlobalContext().lookupAll(BlackboardArtifact.class);
/*
* The documentation for Lookup.lookupAll() explicitly says that the
* collection it returns may contain duplicates. Within this invocation
* of addTag(), we don't want to tag the same BlackboardArtifact more
* than once, so we dedupe the BlackboardArtifacts by stuffing them into
* a HashSet.
*/
final Collection<BlackboardArtifact> selectedArtifacts = new HashSet<>(Utilities.actionsGlobalContext().lookupAll(BlackboardArtifact.class));
new Thread(() -> {
for (BlackboardArtifact artifact : selectedArtifacts) {

View File

@ -1,15 +1,15 @@
/*
* Autopsy Forensic Browser
*
* Copyright 2013-2015 Basis Technology Corp.
*
* Copyright 2011-2016 Basis Technology Corp.
* Contact: carrier <at> sleuthkit <dot> org
*
*
* Licensed under the Apache License, Version 2.0 (the "License");
* 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.
@ -19,13 +19,13 @@
package org.sleuthkit.autopsy.actions;
import java.util.Collection;
import java.util.HashSet;
import java.util.logging.Level;
import javax.swing.JOptionPane;
import javax.swing.SwingUtilities;
import org.openide.util.NbBundle;
import org.openide.util.Utilities;
import org.sleuthkit.autopsy.casemodule.Case;
import org.sleuthkit.autopsy.casemodule.services.TagsManager;
import org.sleuthkit.autopsy.coreutils.Logger;
import org.sleuthkit.datamodel.AbstractFile;
import org.sleuthkit.datamodel.Content;
@ -40,7 +40,6 @@ public class AddContentTagAction extends AddTagAction {
// This class is a singleton to support multi-selection of nodes, since
// org.openide.nodes.NodeOp.findActions(Node[] nodes) will only pick up an Action if every
// node in the array returns a reference to the same action object from Node.getActions(boolean).
private static AddContentTagAction instance;
public static synchronized AddContentTagAction getInstance() {
@ -63,7 +62,13 @@ public class AddContentTagAction extends AddTagAction {
@Override
protected void addTag(TagName tagName, String comment) {
final Collection<? extends AbstractFile> selectedFiles = Utilities.actionsGlobalContext().lookupAll(AbstractFile.class);
/*
* The documentation for Lookup.lookupAll() explicitly says that the
* collection it returns may contain duplicates. Within this invocation
* of addTag(), we don't want to tag the same AbstractFile more than
* once, so we dedupe the AbstractFiles by stuffing them into a HashSet.
*/
final Collection<AbstractFile> selectedFiles = new HashSet<>(Utilities.actionsGlobalContext().lookupAll(AbstractFile.class));
new Thread(() -> {
for (AbstractFile file : selectedFiles) {

View File

@ -0,0 +1,51 @@
/*
* 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.actions;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.logging.Level;
import org.openide.LifecycleManager;
import org.openide.awt.ActionID;
import org.openide.awt.ActionReference;
import org.openide.awt.ActionRegistration;
import org.sleuthkit.autopsy.casemodule.Case;
import org.sleuthkit.autopsy.coreutils.Logger;
@ActionRegistration(displayName = "Exit", iconInMenu = true)
@ActionReference(path = "Menu/Case", position = 1000, separatorBefore = 999)
@ActionID(id = "org.sleuthkit.autopsy.casemodule.ExitAction", category = "Case")
final public class ExitAction implements ActionListener {
@Override
public void actionPerformed(ActionEvent e) {
try {
Case currentCase = Case.getCurrentCase();
if (currentCase != null) {
currentCase.closeCase();
}
} catch (Exception ex) {
Logger.getLogger(ExitAction.class.getName()).log(Level.SEVERE, "Had a problem closing the case.", ex); //NON-NLS
} finally {
LifecycleManager.getDefault().exit();
}
}
}

View File

@ -39,7 +39,7 @@ import org.sleuthkit.autopsy.coreutils.Logger;
*/
@ActionRegistration(
displayName = "#CTL_OpenOutputFolder", iconInMenu = true)
@ActionReference(path = "Menu/Help", position = 1850)
@ActionReference(path = "Menu/Tools", position = 1850, separatorBefore = 1849)
@ActionID(id = "org.sleuthkit.autopsy.actions.OpenOutputFolderAction", category = "Help")
public final class OpenOutputFolderAction extends CallableSystemAction {

View File

@ -4,7 +4,7 @@ CTL_CaseCloseAct=Close Case
CTL_CaseNewAction=New Case...
CTL_CasePropertiesAction=Case Properties...
CTL_OpenAction=Open Case...
Menu/File/OpenRecentCase=Open Recent Case
Menu/Case/OpenRecentCase=Open Recent Case
CTL_CaseDeleteAction=Delete Case
OpenIDE-Module-Name=Case
NewCaseVisualPanel1.jLabel1.text_1=Enter New Case Information:
@ -18,13 +18,8 @@ NewCaseVisualPanel1.caseDirTextField.text_1=
CasePropertiesForm.caseDirLabel.text=Case Directory:
CasePropertiesForm.crDateLabel.text=Created Date:
CasePropertiesForm.caseNameLabel.text=Case Name:
CasePropertiesForm.crDateTextField.text=
CasePropertiesForm.caseNameTextField.text=
CasePropertiesForm.updateCaseNameButton.text=Update
CasePropertiesForm.casePropLabel.text=Case Information
CasePropertiesForm.genInfoLabel.text=General Information
CasePropertiesForm.imgInfoLabel.text=Images Information
CasePropertiesForm.OKButton.text=OK
CasePropertiesForm.updateCaseNameButton.text=Update Name
CasePropertiesForm.deleteCaseButton.text=Delete Case
CueBannerPanel.autopsyLogo.text=
CueBannerPanel.createNewLabel.text=Create New Case
@ -38,8 +33,6 @@ OpenRecentCasePanel.cancelButton.text=Cancel
OpenRecentCasePanel.jLabel1.text=Recent Cases
CasePropertiesForm.caseNumberLabel.text=Case Number:
CasePropertiesForm.examinerLabel.text=Examiner:
CasePropertiesForm.caseNumberTextField.text=
CasePropertiesForm.examinerTextField.text=
NewCaseVisualPanel2.caseNumberTextField.text=
NewCaseVisualPanel2.examinerLabel.text=Examiner:
NewCaseVisualPanel2.caseNumberLabel.text=Case Number:
@ -231,9 +224,7 @@ NewCaseVisualPanel1.multiUserCaseRadioButton.text=Multi-user
NewCaseVisualPanel1.singleUserCaseRadioButton.text=Single-user
NewCaseVisualPanel1.caseTypeLabel.text=Case Type:
CasePropertiesForm.lbDbType.text=Case Type:
CasePropertiesForm.tbDbType.text=
CasePropertiesForm.lbDbName.text=Database Name:
CasePropertiesForm.tbDbName.text=
SingleUserCaseConverter.BadDatabaseFileName=Database file does not exist!
SingleUserCaseConverter.AlreadyMultiUser=Case is already multi-user!
SingleUserCaseConverter.NonUniqueDatabaseName=Database name not unique.
@ -245,3 +236,10 @@ CasePropertiesForm.imagesTable.columnModel.title1=Remove
CasePropertiesForm.imagesTable.columnModel.title0=Path
LocalFilesPanel.jButton1.text=Change
LocalFilesPanel.displayNameLabel.text=Logical File Set Display Name: Default
CaseInformationPanel.jPanel1.TabConstraints.tabTitle=tab1
CasePropertiesForm.caseNumberField.text=
CasePropertiesForm.examinerField.text=
CasePropertiesForm.crDateField.text=
CasePropertiesForm.caseDirField.text=
CasePropertiesForm.caseTypeField.text=
CasePropertiesForm.dbNameField.text=

View File

@ -4,7 +4,7 @@ CTL_CaseCloseAct=\u30b1\u30fc\u30b9\u3092\u9589\u3058\u308b
CTL_CaseNewAction=\u65b0\u898f\u30b1\u30fc\u30b9...
CTL_CasePropertiesAction=\u30b1\u30fc\u30b9\u30d7\u30ed\u30d1\u30c6\u30a3...
CTL_OpenAction=\u30b1\u30fc\u30b9\u3092\u958b\u304f...
Menu/File/OpenRecentCase=\u6700\u8fd1\u958b\u3044\u305f\u30b1\u30fc\u30b9\u3092\u958b\u304f
Menu/Case/OpenRecentCase=\u6700\u8fd1\u958b\u3044\u305f\u30b1\u30fc\u30b9\u3092\u958b\u304f
CTL_CaseDeleteAction=\u30b1\u30fc\u30b9\u3092\u524a\u9664
OpenIDE-Module-Name=\u30b1\u30fc\u30b9
NewCaseVisualPanel1.jLabel1.text_1=\u65b0\u898f\u30b1\u30fc\u30b9\u60c5\u5831\u3092\u5165\u529b\uff1a
@ -16,10 +16,6 @@ CasePropertiesForm.caseDirLabel.text=\u30b1\u30fc\u30b9\u30c7\u30a3\u30ec\u30af\
CasePropertiesForm.crDateLabel.text=\u4f5c\u6210\u65e5\uff1a
CasePropertiesForm.caseNameLabel.text=\u30b1\u30fc\u30b9\u540d\uff1a
CasePropertiesForm.updateCaseNameButton.text=\u66f4\u65b0
CasePropertiesForm.casePropLabel.text=\u30b1\u30fc\u30b9\u60c5\u5831
CasePropertiesForm.genInfoLabel.text=\u4e00\u822c\u60c5\u5831
CasePropertiesForm.imgInfoLabel.text=\u30a4\u30e1\u30fc\u30b8\u60c5\u5831
CasePropertiesForm.OKButton.text=OK
CasePropertiesForm.deleteCaseButton.text=\u30b1\u30fc\u30b9\u3092\u524a\u9664
CueBannerPanel.createNewLabel.text=\u65b0\u898f\u30b1\u30fc\u30b9\u3092\u4f5c\u6210
CueBannerPanel.openLabel.text=\u65e2\u5b58\u30b1\u30fc\u30b9\u3092\u958b\u304f

View File

@ -75,7 +75,7 @@ import org.sleuthkit.autopsy.events.AutopsyEventException;
import org.sleuthkit.autopsy.events.AutopsyEventPublisher;
import org.sleuthkit.autopsy.ingest.IngestJob;
import org.sleuthkit.autopsy.ingest.IngestManager;
import org.sleuthkit.autopsy.ingest.RunIngestAction;
import org.sleuthkit.autopsy.timeline.OpenTimelineAction;
import org.sleuthkit.datamodel.BlackboardArtifactTag;
import org.sleuthkit.datamodel.Content;
import org.sleuthkit.datamodel.ContentTag;
@ -1519,27 +1519,20 @@ public class Case implements SleuthkitCase.ErrorObserver {
if (RuntimeProperties.coreComponentsAreActive()) {
// enable these menus
CallableSystemAction.get(AddImageAction.class).setEnabled(true);
CallableSystemAction.get(CaseCloseAction.class).setEnabled(true);
CallableSystemAction.get(CasePropertiesAction.class).setEnabled(true);
CallableSystemAction.get(CaseDeleteAction.class).setEnabled(true); // Delete Case menu
CallableSystemAction.get(RunIngestAction.class).setEnabled(true);
if (toChangeTo.hasData()) {
// open all top components
SwingUtilities.invokeLater(() -> {
CoreComponentControl.openCoreWindows();
});
} else {
// close all top components
SwingUtilities.invokeLater(() -> {
CoreComponentControl.closeCoreWindows();
});
}
}
if (RuntimeProperties.coreComponentsAreActive()) {
SwingUtilities.invokeLater(() -> {
CallableSystemAction.get(AddImageAction.class).setEnabled(true);
CallableSystemAction.get(CaseCloseAction.class).setEnabled(true);
CallableSystemAction.get(CasePropertiesAction.class).setEnabled(true);
CallableSystemAction.get(CaseDeleteAction.class).setEnabled(true); // Delete Case menu
CallableSystemAction.get(OpenTimelineAction.class).setEnabled(true);
if (toChangeTo.hasData()) {
// open all top components
CoreComponentControl.openCoreWindows();
} else {
// close all top components
CoreComponentControl.closeCoreWindows();
}
updateMainWindowTitle(currentCase.getName());
});
} else {
@ -1550,9 +1543,9 @@ public class Case implements SleuthkitCase.ErrorObserver {
}
} else { // case is closed
if (RuntimeProperties.coreComponentsAreActive()) {
SwingUtilities.invokeLater(() -> {
if (RuntimeProperties.coreComponentsAreActive()) {
SwingUtilities.invokeLater(() -> {
// close all top components first
CoreComponentControl.closeCoreWindows();
@ -1561,16 +1554,11 @@ public class Case implements SleuthkitCase.ErrorObserver {
CallableSystemAction.get(CaseCloseAction.class).setEnabled(false); // Case Close menu
CallableSystemAction.get(CasePropertiesAction.class).setEnabled(false); // Case Properties menu
CallableSystemAction.get(CaseDeleteAction.class).setEnabled(false); // Delete Case menu
CallableSystemAction.get(RunIngestAction.class).setEnabled(false);
});
}
CallableSystemAction.get(OpenTimelineAction.class).setEnabled(false);
}
//clear pending notifications
SwingUtilities.invokeLater(() -> {
//clear pending notifications
MessageNotifyUtil.Notify.clear();
});
SwingUtilities.invokeLater(() -> {
Frame f = WindowManager.getDefault().getMainWindow();
f.setTitle(Case.getAppName()); // set the window name to just application name
});
@ -1666,7 +1654,7 @@ public class Case implements SleuthkitCase.ErrorObserver {
* Deletes reports from the case.
*
* @param reports Collection of Report to be deleted from the case.
* @param deleteFromDisk No longer supported - ignored.
* @param deleteFromDisk No longer supported - ignored.
*
* @throws TskCoreException
* @deprecated Use deleteReports(Collection<? extends Report> reports)
@ -1676,5 +1664,5 @@ public class Case implements SleuthkitCase.ErrorObserver {
public void deleteReports(Collection<? extends Report> reports, boolean deleteFromDisk) throws TskCoreException {
deleteReports(reports);
}
}
}

View File

@ -0,0 +1,63 @@
<?xml version="1.0" encoding="UTF-8" ?>
<Form version="1.5" maxVersion="1.9" type="org.netbeans.modules.form.forminfo.JPanelFormInfo">
<AuxValues>
<AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="1"/>
<AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/>
<AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/>
<AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="true"/>
<AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="true"/>
<AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/>
<AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/>
<AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/>
<AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/>
</AuxValues>
<Layout>
<DimensionLayout dim="0">
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" attributes="0">
<EmptySpace min="-2" pref="0" max="-2" attributes="0"/>
<Component id="jPanel1" max="32767" attributes="0"/>
<EmptySpace min="-2" pref="0" max="-2" attributes="0"/>
</Group>
</Group>
</DimensionLayout>
<DimensionLayout dim="1">
<Group type="103" groupAlignment="0" attributes="0">
<Component id="jPanel1" min="-2" max="-2" attributes="0"/>
</Group>
</DimensionLayout>
</Layout>
<SubComponents>
<Container class="javax.swing.JPanel" name="jPanel1">
<Layout>
<DimensionLayout dim="0">
<Group type="103" groupAlignment="0" attributes="0">
<Component id="tabbedPane" max="32767" attributes="0"/>
</Group>
</DimensionLayout>
<DimensionLayout dim="1">
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" alignment="1" attributes="0">
<Component id="tabbedPane" pref="228" max="32767" attributes="0"/>
<EmptySpace min="0" pref="0" max="-2" attributes="0"/>
</Group>
</Group>
</DimensionLayout>
</Layout>
<SubComponents>
<Container class="javax.swing.JTabbedPane" name="tabbedPane">
<Properties>
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[420, 200]"/>
</Property>
</Properties>
<Layout class="org.netbeans.modules.form.compat2.layouts.support.JTabbedPaneSupportLayout"/>
</Container>
</SubComponents>
</Container>
</SubComponents>
</Form>

View File

@ -0,0 +1,90 @@
/*
* 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.casemodule;
import java.util.Map;
import org.openide.util.NbBundle.Messages;
/**
*
* @author oliver
*/
public class CaseInformationPanel extends javax.swing.JPanel {
/**
* Creates new form CaseInformationPanel
*/
public CaseInformationPanel() {
initComponents();
customizeComponents();
}
@Messages({"CaseInformationPanel.caseDetails.header=Case Details"})
private void customizeComponents() {
try {
Case currentCase = Case.getCurrentCase();
String crDate = currentCase.getCreatedDate();
String caseDir = currentCase.getCaseDirectory();
// put the image paths information into hashmap
Map<Long, String> imgPaths = Case.getImagePaths(currentCase.getSleuthkitCase());
CasePropertiesForm cpf = new CasePropertiesForm(currentCase, crDate, caseDir, imgPaths);
cpf.setSize(cpf.getPreferredSize());
this.tabbedPane.addTab(Bundle.CaseInformationPanel_caseDetails_header(), cpf);
} catch (CaseMetadata.CaseMetadataException ex) {
//TOLOG
}
}
/**
* 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() {
jPanel1 = new javax.swing.JPanel();
tabbedPane = new javax.swing.JTabbedPane();
tabbedPane.setPreferredSize(new java.awt.Dimension(420, 200));
javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1);
jPanel1.setLayout(jPanel1Layout);
jPanel1Layout.setHorizontalGroup(
jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(tabbedPane, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
);
jPanel1Layout.setVerticalGroup(
jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel1Layout.createSequentialGroup()
.addComponent(tabbedPane, javax.swing.GroupLayout.DEFAULT_SIZE, 228, Short.MAX_VALUE)
.addGap(0, 0, 0))
);
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
this.setLayout(layout);
layout.setHorizontalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addGap(0, 0, 0)
.addComponent(jPanel1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addGap(0, 0, 0))
);
layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(jPanel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
);
}// </editor-fold>//GEN-END:initComponents
// Variables declaration - do not modify//GEN-BEGIN:variables
private javax.swing.JPanel jPanel1;
private javax.swing.JTabbedPane tabbedPane;
// End of variables declaration//GEN-END:variables
}

View File

@ -20,9 +20,6 @@ package org.sleuthkit.autopsy.casemodule;
import java.awt.Dimension;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Map;
import java.util.logging.Level;
import javax.swing.Action;
import javax.swing.JDialog;
@ -61,32 +58,16 @@ final class CasePropertiesAction extends CallableSystemAction {
// create the popUp window for it
String title = NbBundle.getMessage(this.getClass(), "CasePropertiesAction.window.title");
final JFrame frame = new JFrame(title);
popUpWindow = new JDialog(frame, title, true); // to make the popUp Window to be modal
// get the information that needed
Case currentCase = Case.getCurrentCase();
String crDate = currentCase.getCreatedDate();
String caseDir = currentCase.getCaseDirectory();
// put the image paths information into hashmap
Map<Long, String> imgPaths = Case.getImagePaths(currentCase.getSleuthkitCase());
popUpWindow = new JDialog(frame, title, false); // to make the popUp Window to be modal
// create the case properties form
CasePropertiesForm cpf = new CasePropertiesForm(currentCase, crDate, caseDir, imgPaths);
// add the command to close the window to the button on the Case Properties form / panel
cpf.setOKButtonActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
popUpWindow.dispose();
}
});
CaseInformationPanel caseInformationPanel = new CaseInformationPanel();
// add the case properties form / panel to the popup window
popUpWindow.add(cpf);
popUpWindow.add(caseInformationPanel);
popUpWindow.setResizable(true);
popUpWindow.pack();
popUpWindow.setResizable(false);
// set the location of the popUp Window on the center of the screen
Dimension screenDimension = Toolkit.getDefaultToolkit().getScreenSize();

View File

@ -33,437 +33,307 @@
<Layout>
<DimensionLayout dim="0">
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" attributes="0">
<EmptySpace max="-2" attributes="0"/>
<Group type="103" groupAlignment="0" attributes="0">
<Component id="casePropLabel" pref="440" max="32767" attributes="0"/>
<Component id="imagesTableScrollPane" alignment="0" pref="440" max="32767" attributes="0"/>
<Group type="102" alignment="0" attributes="0">
<Group type="103" groupAlignment="0" attributes="0">
<Component id="caseNameLabel" alignment="0" min="-2" max="-2" attributes="0"/>
<Component id="caseNumberLabel" alignment="0" min="-2" max="-2" attributes="0"/>
<Component id="examinerLabel" alignment="0" min="-2" max="-2" attributes="0"/>
<Component id="caseDirLabel" alignment="0" min="-2" max="-2" attributes="0"/>
<Component id="crDateLabel" alignment="0" min="-2" max="-2" attributes="0"/>
<Component id="lbDbType" alignment="0" min="-2" max="-2" attributes="0"/>
</Group>
<EmptySpace type="separate" max="-2" attributes="0"/>
<Group type="103" groupAlignment="0" attributes="0">
<Component id="caseNameTextField" alignment="0" pref="245" max="32767" attributes="1"/>
<Component id="caseNumberTextField" alignment="0" pref="245" max="32767" attributes="1"/>
<Component id="examinerTextField" alignment="0" pref="245" max="32767" attributes="1"/>
<Component id="crDateTextField" alignment="0" max="32767" attributes="1"/>
<Component id="jScrollPane2" alignment="0" max="32767" attributes="0"/>
<Component id="tbDbType" alignment="0" max="32767" attributes="0"/>
<Component id="tbDbName" alignment="0" max="32767" attributes="0"/>
</Group>
<EmptySpace type="unrelated" max="-2" attributes="0"/>
<Group type="103" groupAlignment="0" attributes="0">
<Component id="deleteCaseButton" max="32767" attributes="1"/>
<Component id="updateCaseNameButton" max="32767" attributes="1"/>
</Group>
</Group>
<Group type="102" attributes="0">
<Group type="103" groupAlignment="0" attributes="0">
<Component id="genInfoLabel" alignment="0" min="-2" max="-2" attributes="0"/>
<Component id="imgInfoLabel" alignment="0" min="-2" max="-2" attributes="0"/>
<Group type="102" alignment="0" attributes="0">
<EmptySpace min="-2" pref="181" max="-2" attributes="0"/>
<Component id="OKButton" min="-2" pref="78" max="-2" attributes="0"/>
</Group>
<Component id="lbDbName" alignment="0" min="-2" max="-2" attributes="0"/>
</Group>
<EmptySpace min="0" pref="0" max="32767" attributes="0"/>
</Group>
</Group>
<EmptySpace max="-2" attributes="0"/>
</Group>
<Component id="jPanel1" max="32767" attributes="0"/>
</Group>
</DimensionLayout>
<DimensionLayout dim="1">
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" alignment="0" attributes="0">
<EmptySpace max="-2" attributes="0"/>
<Component id="casePropLabel" min="-2" pref="33" max="-2" attributes="0"/>
<EmptySpace type="separate" max="-2" attributes="0"/>
<Component id="genInfoLabel" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Group type="103" groupAlignment="3" attributes="0">
<Component id="caseNameLabel" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="caseNameTextField" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="updateCaseNameButton" alignment="3" min="-2" max="-2" attributes="0"/>
</Group>
<EmptySpace max="-2" attributes="0"/>
<Group type="103" groupAlignment="3" attributes="0">
<Component id="caseNumberLabel" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="caseNumberTextField" alignment="3" min="-2" max="-2" attributes="0"/>
</Group>
<EmptySpace max="-2" attributes="0"/>
<Group type="103" groupAlignment="3" attributes="0">
<Component id="examinerLabel" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="examinerTextField" alignment="3" min="-2" max="-2" attributes="0"/>
</Group>
<EmptySpace max="-2" attributes="0"/>
<Group type="103" groupAlignment="3" attributes="0">
<Component id="crDateLabel" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="crDateTextField" alignment="3" min="-2" max="-2" attributes="0"/>
</Group>
<EmptySpace max="-2" attributes="0"/>
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" attributes="0">
<Group type="103" groupAlignment="0" attributes="0">
<Component id="jScrollPane2" min="-2" pref="40" max="-2" attributes="0"/>
<Component id="caseDirLabel" min="-2" pref="14" max="-2" attributes="0"/>
</Group>
<EmptySpace max="-2" attributes="0"/>
<Group type="103" groupAlignment="3" attributes="0">
<Component id="tbDbType" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="lbDbType" alignment="3" min="-2" max="-2" attributes="0"/>
</Group>
<EmptySpace max="-2" attributes="0"/>
<Group type="103" groupAlignment="3" attributes="0">
<Component id="lbDbName" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="tbDbName" alignment="3" min="-2" max="-2" attributes="0"/>
</Group>
<EmptySpace type="separate" max="-2" attributes="0"/>
<Component id="imgInfoLabel" min="-2" max="-2" attributes="0"/>
</Group>
<Group type="102" alignment="0" attributes="0">
<EmptySpace min="-2" pref="9" max="-2" attributes="0"/>
<Component id="deleteCaseButton" min="-2" max="-2" attributes="0"/>
</Group>
</Group>
<EmptySpace type="unrelated" max="-2" attributes="0"/>
<Component id="imagesTableScrollPane" min="-2" pref="170" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="OKButton" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
</Group>
<Component id="jPanel1" min="-2" max="-2" attributes="0"/>
</Group>
</DimensionLayout>
</Layout>
<SubComponents>
<Component class="javax.swing.JLabel" name="casePropLabel">
<Properties>
<Property name="font" type="java.awt.Font" editor="org.netbeans.modules.form.editors2.FontEditor">
<FontInfo relative="true">
<Font bold="true" component="casePropLabel" property="font" relativeSize="false" size="24"/>
</FontInfo>
</Property>
<Property name="horizontalAlignment" type="int" value="0"/>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/casemodule/Bundle.properties" key="CasePropertiesForm.casePropLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
</Component>
<Component class="javax.swing.JLabel" name="caseNameLabel">
<Properties>
<Property name="font" type="java.awt.Font" editor="org.netbeans.modules.form.editors2.FontEditor">
<FontInfo relative="true">
<Font bold="false" component="caseNameLabel" 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/casemodule/Bundle.properties" key="CasePropertiesForm.caseNameLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
</Component>
<Component class="javax.swing.JLabel" name="crDateLabel">
<Properties>
<Property name="font" type="java.awt.Font" editor="org.netbeans.modules.form.editors2.FontEditor">
<FontInfo relative="true">
<Font bold="false" component="crDateLabel" 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/casemodule/Bundle.properties" key="CasePropertiesForm.crDateLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
</Component>
<Component class="javax.swing.JLabel" name="caseDirLabel">
<Properties>
<Property name="font" type="java.awt.Font" editor="org.netbeans.modules.form.editors2.FontEditor">
<FontInfo relative="true">
<Font bold="false" component="caseDirLabel" 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/casemodule/Bundle.properties" key="CasePropertiesForm.caseDirLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
</Component>
<Component class="javax.swing.JTextField" name="crDateTextField">
<Properties>
<Property name="editable" type="boolean" value="false"/>
<Property name="font" type="java.awt.Font" editor="org.netbeans.modules.form.editors2.FontEditor">
<FontInfo relative="true">
<Font bold="false" component="crDateTextField" 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/casemodule/Bundle.properties" key="CasePropertiesForm.crDateTextField.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
</Component>
<Component class="javax.swing.JTextField" name="caseNameTextField">
<Properties>
<Property name="font" type="java.awt.Font" editor="org.netbeans.modules.form.editors2.FontEditor">
<FontInfo relative="true">
<Font bold="false" component="caseNameTextField" 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/casemodule/Bundle.properties" key="CasePropertiesForm.caseNameTextField.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
</Component>
<Component class="javax.swing.JButton" name="updateCaseNameButton">
<Properties>
<Property name="font" type="java.awt.Font" editor="org.netbeans.modules.form.editors2.FontEditor">
<FontInfo relative="true">
<Font bold="false" component="updateCaseNameButton" 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/casemodule/Bundle.properties" key="CasePropertiesForm.updateCaseNameButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="updateCaseNameButtonActionPerformed"/>
</Events>
</Component>
<Component class="javax.swing.JLabel" name="genInfoLabel">
<Properties>
<Property name="font" type="java.awt.Font" editor="org.netbeans.modules.form.editors2.FontEditor">
<FontInfo relative="true">
<Font bold="true" component="genInfoLabel" property="font" relativeSize="false" size="14"/>
</FontInfo>
</Property>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/casemodule/Bundle.properties" key="CasePropertiesForm.genInfoLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
</Component>
<Component class="javax.swing.JLabel" name="imgInfoLabel">
<Properties>
<Property name="font" type="java.awt.Font" editor="org.netbeans.modules.form.editors2.FontEditor">
<FontInfo relative="true">
<Font bold="true" component="imgInfoLabel" property="font" relativeSize="false" size="14"/>
</FontInfo>
</Property>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/casemodule/Bundle.properties" key="CasePropertiesForm.imgInfoLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
</Component>
<Component class="javax.swing.JButton" name="OKButton">
<Properties>
<Property name="font" type="java.awt.Font" editor="org.netbeans.modules.form.editors2.FontEditor">
<FontInfo relative="true">
<Font bold="false" component="OKButton" 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/casemodule/Bundle.properties" key="CasePropertiesForm.OKButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
</Component>
<Container class="javax.swing.JScrollPane" name="imagesTableScrollPane">
<Properties>
<Property name="font" type="java.awt.Font" editor="org.netbeans.modules.form.editors2.FontEditor">
<FontInfo relative="true">
<Font bold="false" component="imagesTableScrollPane" property="font" relativeSize="false" size="11"/>
</FontInfo>
</Property>
</Properties>
<AuxValues>
<AuxValue name="autoScrollPane" type="java.lang.Boolean" value="true"/>
</AuxValues>
<Container class="javax.swing.JPanel" name="jPanel1">
<Layout class="org.netbeans.modules.form.compat2.layouts.support.JScrollPaneSupportLayout"/>
<Layout>
<DimensionLayout dim="0">
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" attributes="0">
<EmptySpace min="-2" max="-2" attributes="0"/>
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" alignment="0" attributes="0">
<Group type="103" groupAlignment="0" attributes="0">
<Component id="lbDbName" min="-2" max="-2" attributes="0"/>
<Component id="lbDbType" alignment="0" min="-2" max="-2" attributes="0"/>
<Component id="caseDirLabel" alignment="0" min="-2" max="-2" attributes="0"/>
</Group>
<EmptySpace min="-2" max="-2" attributes="0"/>
<Group type="103" groupAlignment="0" attributes="0">
<Component id="caseDirField" max="32767" attributes="0"/>
<Component id="caseTypeField" max="32767" attributes="0"/>
<Component id="dbNameField" alignment="0" max="32767" attributes="0"/>
</Group>
</Group>
<Group type="102" alignment="0" attributes="0">
<Group type="103" groupAlignment="0" attributes="0">
<Component id="crDateLabel" min="-2" max="-2" attributes="0"/>
<Component id="examinerLabel" alignment="0" min="-2" max="-2" attributes="0"/>
<Component id="caseNumberLabel" alignment="0" min="-2" max="-2" attributes="0"/>
</Group>
<EmptySpace type="separate" min="-2" max="-2" attributes="0"/>
<Group type="103" groupAlignment="0" attributes="0">
<Component id="examinerField" max="32767" attributes="0"/>
<Component id="caseNumberField" alignment="0" max="32767" attributes="0"/>
<Group type="102" alignment="0" attributes="0">
<Component id="caseNameTextField" pref="243" max="32767" attributes="1"/>
<EmptySpace min="-2" max="-2" attributes="0"/>
<Component id="updateCaseNameButton" min="-2" pref="104" max="-2" attributes="1"/>
</Group>
<Component id="crDateField" alignment="0" max="32767" attributes="0"/>
</Group>
</Group>
<Group type="102" alignment="1" attributes="0">
<EmptySpace min="0" pref="0" max="32767" attributes="0"/>
<Component id="deleteCaseButton" min="-2" pref="106" max="-2" attributes="1"/>
</Group>
</Group>
<EmptySpace min="-2" max="-2" attributes="0"/>
</Group>
<Group type="103" rootIndex="1" groupAlignment="0" attributes="0">
<Group type="102" attributes="0">
<EmptySpace max="-2" attributes="0"/>
<Component id="caseNameLabel" min="-2" max="-2" attributes="0"/>
<EmptySpace pref="392" max="32767" attributes="0"/>
</Group>
</Group>
</Group>
</DimensionLayout>
<DimensionLayout dim="1">
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" alignment="1" attributes="0">
<EmptySpace max="-2" attributes="0"/>
<Group type="103" groupAlignment="3" attributes="0">
<Component id="caseNameTextField" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="updateCaseNameButton" alignment="3" min="-2" max="-2" attributes="0"/>
</Group>
<EmptySpace max="32767" attributes="0"/>
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" attributes="0">
<Component id="caseNumberField" min="-2" pref="14" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Group type="103" groupAlignment="1" attributes="0">
<Component id="examinerField" min="-2" pref="14" max="-2" attributes="0"/>
<Component id="examinerLabel" min="-2" max="-2" attributes="0"/>
</Group>
<EmptySpace max="-2" attributes="0"/>
<Group type="103" groupAlignment="0" attributes="0">
<Component id="crDateField" alignment="1" min="-2" pref="14" max="-2" attributes="0"/>
<Component id="crDateLabel" alignment="1" min="-2" max="-2" attributes="0"/>
</Group>
<EmptySpace max="-2" attributes="0"/>
<Group type="103" groupAlignment="0" max="-2" attributes="0">
<Component id="caseDirLabel" max="32767" attributes="0"/>
<Component id="caseDirField" max="32767" attributes="0"/>
</Group>
<EmptySpace max="-2" attributes="0"/>
<Group type="103" groupAlignment="3" attributes="0">
<Component id="caseTypeField" alignment="0" min="-2" pref="14" max="-2" attributes="0"/>
<Component id="lbDbType" alignment="3" min="-2" max="-2" attributes="0"/>
</Group>
<EmptySpace max="-2" attributes="0"/>
<Group type="103" groupAlignment="3" attributes="0">
<Component id="lbDbName" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="dbNameField" alignment="3" min="-2" pref="14" max="-2" attributes="0"/>
</Group>
</Group>
<Component id="caseNumberLabel" min="-2" max="-2" attributes="0"/>
</Group>
<EmptySpace min="-2" pref="10" max="-2" attributes="0"/>
<Component id="deleteCaseButton" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
</Group>
<Group type="103" rootIndex="1" groupAlignment="0" attributes="0">
<Group type="102" alignment="0" attributes="0">
<EmptySpace max="-2" attributes="0"/>
<Component id="caseNameLabel" min="-2" max="-2" attributes="0"/>
<EmptySpace pref="173" max="32767" attributes="0"/>
</Group>
</Group>
</Group>
</DimensionLayout>
</Layout>
<SubComponents>
<Component class="javax.swing.JTable" name="imagesTable">
<Component class="javax.swing.JLabel" name="caseNameLabel">
<Properties>
<Property name="font" type="java.awt.Font" editor="org.netbeans.modules.form.editors2.FontEditor">
<FontInfo relative="true">
<Font bold="false" component="imagesTable" property="font" relativeSize="false" size="11"/>
<Font bold="false" component="caseNameLabel" property="font" relativeSize="false" size="11"/>
</FontInfo>
</Property>
<Property name="model" type="javax.swing.table.TableModel" editor="org.netbeans.modules.form.editors2.TableModelEditor">
<Table columnCount="2" rowCount="0">
<Column editable="false" title="Path" type="java.lang.Object"/>
<Column editable="true" title="Remove" type="java.lang.Object"/>
</Table>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/casemodule/Bundle.properties" key="CasePropertiesForm.caseNameLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
<Property name="columnModel" type="javax.swing.table.TableColumnModel" editor="org.netbeans.modules.form.editors2.TableColumnModelEditor">
<TableColumnModel selectionModel="0">
<Column maxWidth="-1" minWidth="-1" prefWidth="-1" resizable="true">
<Title editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/casemodule/Bundle.properties" key="CasePropertiesForm.imagesTable.path" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Title>
<Editor/>
<Renderer/>
</Column>
<Column maxWidth="-1" minWidth="-1" prefWidth="-1" resizable="true">
<Title editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/casemodule/Bundle.properties" key="CasePropertiesForm.imagesTable.remove" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Title>
<Editor/>
<Renderer/>
</Column>
</TableColumnModel>
</Property>
<Property name="showHorizontalLines" type="boolean" value="false"/>
<Property name="showVerticalLines" type="boolean" value="false"/>
<Property name="tableHeader" type="javax.swing.table.JTableHeader" editor="org.netbeans.modules.form.editors2.JTableHeaderEditor">
<TableHeader reorderingAllowed="false" resizingAllowed="true"/>
</Property>
<Property name="updateSelectionOnSort" type="boolean" value="false"/>
</Properties>
</Component>
</SubComponents>
</Container>
<Container class="javax.swing.JScrollPane" name="jScrollPane2">
<Properties>
<Property name="font" type="java.awt.Font" editor="org.netbeans.modules.form.editors2.FontEditor">
<FontInfo relative="true">
<Font bold="false" component="jScrollPane2" property="font" relativeSize="false" size="11"/>
</FontInfo>
</Property>
</Properties>
<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.JTextArea" name="caseDirTextArea">
<Component class="javax.swing.JLabel" name="crDateLabel">
<Properties>
<Property name="editable" type="boolean" value="false"/>
<Property name="background" type="java.awt.Color" editor="org.netbeans.beaninfo.editors.ColorEditor">
<Color blue="f0" green="f0" red="f0" type="rgb"/>
<Property name="font" type="java.awt.Font" editor="org.netbeans.modules.form.editors2.FontEditor">
<FontInfo relative="true">
<Font bold="false" component="crDateLabel" 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/casemodule/Bundle.properties" key="CasePropertiesForm.crDateLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
</Component>
<Component class="javax.swing.JLabel" name="caseDirLabel">
<Properties>
<Property name="font" type="java.awt.Font" editor="org.netbeans.modules.form.editors2.FontEditor">
<FontInfo relative="true">
<Font bold="false" component="caseDirLabel" 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/casemodule/Bundle.properties" key="CasePropertiesForm.caseDirLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
</Component>
<Component class="javax.swing.JTextField" name="caseNameTextField">
<Properties>
<Property name="font" type="java.awt.Font" editor="org.netbeans.modules.form.editors2.FontEditor">
<FontInfo relative="true">
<Font bold="false" component="caseNameTextField" 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/casemodule/Bundle.properties" key="CasePropertiesForm.caseNameTextField.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="caseNameTextFieldActionPerformed"/>
</Events>
</Component>
<Component class="javax.swing.JButton" name="updateCaseNameButton">
<Properties>
<Property name="font" type="java.awt.Font" editor="org.netbeans.modules.form.editors2.FontEditor">
<FontInfo relative="true">
<Font bold="false" component="updateCaseNameButton" 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/casemodule/Bundle.properties" key="CasePropertiesForm.updateCaseNameButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="updateCaseNameButtonActionPerformed"/>
</Events>
</Component>
<Component class="javax.swing.JButton" name="deleteCaseButton">
<Properties>
<Property name="font" type="java.awt.Font" editor="org.netbeans.modules.form.editors2.FontEditor">
<FontInfo relative="true">
<Font bold="false" component="deleteCaseButton" 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/casemodule/Bundle.properties" key="CasePropertiesForm.deleteCaseButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="deleteCaseButtonActionPerformed"/>
</Events>
</Component>
<Component class="javax.swing.JLabel" name="caseNumberLabel">
<Properties>
<Property name="font" type="java.awt.Font" editor="org.netbeans.modules.form.editors2.FontEditor">
<FontInfo relative="true">
<Font bold="false" component="caseNumberLabel" 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/casemodule/Bundle.properties" key="CasePropertiesForm.caseNumberLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
</Component>
<Component class="javax.swing.JLabel" name="examinerLabel">
<Properties>
<Property name="font" type="java.awt.Font" editor="org.netbeans.modules.form.editors2.FontEditor">
<FontInfo relative="true">
<Font bold="false" component="examinerLabel" 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/casemodule/Bundle.properties" key="CasePropertiesForm.examinerLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
</Component>
<Component class="javax.swing.JLabel" name="lbDbType">
<Properties>
<Property name="font" type="java.awt.Font" editor="org.netbeans.modules.form.editors2.FontEditor">
<FontInfo relative="true">
<Font bold="false" component="lbDbType" 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/casemodule/Bundle.properties" key="CasePropertiesForm.lbDbType.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
</Component>
<Component class="javax.swing.JLabel" name="lbDbName">
<Properties>
<Property name="font" type="java.awt.Font" editor="org.netbeans.modules.form.editors2.FontEditor">
<FontInfo relative="true">
<Font bold="false" component="lbDbName" 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/casemodule/Bundle.properties" key="CasePropertiesForm.lbDbName.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
</Component>
<Component class="javax.swing.JLabel" name="caseNumberField">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/casemodule/Bundle.properties" key="CasePropertiesForm.caseNumberField.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
</Component>
<Component class="javax.swing.JLabel" name="examinerField">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/casemodule/Bundle.properties" key="CasePropertiesForm.examinerField.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
</Component>
<Component class="javax.swing.JLabel" name="crDateField">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/casemodule/Bundle.properties" key="CasePropertiesForm.crDateField.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
</Component>
<Component class="javax.swing.JLabel" name="caseDirField">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/casemodule/Bundle.properties" key="CasePropertiesForm.caseDirField.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
<Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[25, 14]"/>
</Property>
</Properties>
</Component>
<Component class="javax.swing.JLabel" name="dbNameField">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/casemodule/Bundle.properties" key="CasePropertiesForm.dbNameField.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
<Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[25, 14]"/>
</Property>
</Properties>
</Component>
<Component class="javax.swing.JLabel" name="caseTypeField">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/casemodule/Bundle.properties" key="CasePropertiesForm.caseTypeField.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
<Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[1, 0]"/>
</Property>
<Property name="columns" type="int" value="20"/>
<Property name="rows" type="int" value="1"/>
<Property name="requestFocusEnabled" type="boolean" value="false"/>
</Properties>
</Component>
</SubComponents>
</Container>
<Component class="javax.swing.JButton" name="deleteCaseButton">
<Properties>
<Property name="font" type="java.awt.Font" editor="org.netbeans.modules.form.editors2.FontEditor">
<FontInfo relative="true">
<Font bold="false" component="deleteCaseButton" 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/casemodule/Bundle.properties" key="CasePropertiesForm.deleteCaseButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="deleteCaseButtonActionPerformed"/>
</Events>
</Component>
<Component class="javax.swing.JLabel" name="caseNumberLabel">
<Properties>
<Property name="font" type="java.awt.Font" editor="org.netbeans.modules.form.editors2.FontEditor">
<FontInfo relative="true">
<Font bold="false" component="caseNumberLabel" 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/casemodule/Bundle.properties" key="CasePropertiesForm.caseNumberLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
</Component>
<Component class="javax.swing.JLabel" name="examinerLabel">
<Properties>
<Property name="font" type="java.awt.Font" editor="org.netbeans.modules.form.editors2.FontEditor">
<FontInfo relative="true">
<Font bold="false" component="examinerLabel" 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/casemodule/Bundle.properties" key="CasePropertiesForm.examinerLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
</Component>
<Component class="javax.swing.JTextField" name="caseNumberTextField">
<Properties>
<Property name="editable" type="boolean" value="false"/>
<Property name="font" type="java.awt.Font" editor="org.netbeans.modules.form.editors2.FontEditor">
<FontInfo relative="true">
<Font bold="false" component="caseNumberTextField" 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/casemodule/Bundle.properties" key="CasePropertiesForm.caseNumberTextField.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
</Component>
<Component class="javax.swing.JTextField" name="examinerTextField">
<Properties>
<Property name="editable" type="boolean" value="false"/>
<Property name="font" type="java.awt.Font" editor="org.netbeans.modules.form.editors2.FontEditor">
<FontInfo relative="true">
<Font bold="false" component="examinerTextField" 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/casemodule/Bundle.properties" key="CasePropertiesForm.examinerTextField.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
</Component>
<Component class="javax.swing.JLabel" name="lbDbType">
<Properties>
<Property name="font" type="java.awt.Font" editor="org.netbeans.modules.form.editors2.FontEditor">
<FontInfo relative="true">
<Font bold="false" component="lbDbType" 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/casemodule/Bundle.properties" key="CasePropertiesForm.lbDbType.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
</Component>
<Component class="javax.swing.JTextField" name="tbDbType">
<Properties>
<Property name="editable" type="boolean" value="false"/>
<Property name="font" type="java.awt.Font" editor="org.netbeans.modules.form.editors2.FontEditor">
<FontInfo relative="true">
<Font bold="false" component="tbDbType" 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/casemodule/Bundle.properties" key="CasePropertiesForm.tbDbType.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
</Component>
<Component class="javax.swing.JLabel" name="lbDbName">
<Properties>
<Property name="font" type="java.awt.Font" editor="org.netbeans.modules.form.editors2.FontEditor">
<FontInfo relative="true">
<Font bold="false" component="lbDbName" 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/casemodule/Bundle.properties" key="CasePropertiesForm.lbDbName.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
</Component>
<Component class="javax.swing.JTextField" name="tbDbName">
<Properties>
<Property name="editable" type="boolean" value="false"/>
<Property name="font" type="java.awt.Font" editor="org.netbeans.modules.form.editors2.FontEditor">
<FontInfo relative="true">
<Font bold="false" component="tbDbName" 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/casemodule/Bundle.properties" key="CasePropertiesForm.tbDbName.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
</Component>
</SubComponents>
</Form>

View File

@ -17,36 +17,33 @@
* limitations under the License.
*/
/*
/*
* CasePropertiesForm.java
*
* Created on Mar 14, 2011, 1:48:20 PM
*/
package org.sleuthkit.autopsy.casemodule;
import java.nio.file.Paths;
import java.awt.event.ActionListener;
import java.io.File;
import java.util.Map;
import java.util.logging.Level;
import org.openide.util.NbBundle;
import org.sleuthkit.autopsy.coreutils.Logger;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.table.DefaultTableModel;
import org.openide.DialogDescriptor;
import org.openide.DialogDisplayer;
import org.openide.NotifyDescriptor;
import org.openide.util.NbBundle;
import org.openide.util.actions.CallableSystemAction;
import org.sleuthkit.autopsy.coreutils.Logger;
/**
* The form where user can change / update the properties of the current case
* metadata.
*/
class CasePropertiesForm extends javax.swing.JPanel {
private static final long serialVersionUID = 1L;
private Case current = null;
private static JPanel caller; // panel for error
@ -55,15 +52,15 @@ class CasePropertiesForm extends javax.swing.JPanel {
private String shrinkPath(String path, int targetLength) {
if (path.length() > targetLength) {
String fill = "...";
int partsLength = targetLength - fill.length();
String front = path.substring(0, partsLength / 4);
int frontSep = front.lastIndexOf(File.separatorChar);
if (frontSep != -1) {
front = front.substring(0, frontSep + 1);
}
String back = path.substring(partsLength * 3 / 4);
int backSep = back.indexOf(File.separatorChar);
if (backSep != -1) {
@ -81,52 +78,35 @@ class CasePropertiesForm extends javax.swing.JPanel {
CasePropertiesForm(Case currentCase, String crDate, String caseDir, Map<Long, String> imgPaths) throws CaseMetadata.CaseMetadataException {
initComponents();
caseNameTextField.setText(currentCase.getName());
caseNumberTextField.setText(currentCase.getNumber());
examinerTextField.setText(currentCase.getExaminer());
crDateTextField.setText(crDate);
caseDirTextArea.setText(caseDir);
String caseNumber = currentCase.getNumber();
if (!caseNumber.equals("")) {
caseNumberField.setText(caseNumber);
} else {
caseNumberField.setText("N/A");
}
String examiner = currentCase.getExaminer();
if (!examiner.equals("")) {
examinerField.setText(examiner);
} else {
examinerField.setText("N/A");
}
crDateField.setText(crDate);
caseDirField.setText(caseDir);
current = currentCase;
CaseMetadata caseMetadata = currentCase.getCaseMetadata();
if (caseMetadata.getCaseType() == Case.CaseType.SINGLE_USER_CASE) {
tbDbName.setText(caseMetadata.getCaseDatabasePath());
dbNameField.setText(caseMetadata.getCaseDatabasePath());
} else {
tbDbName.setText(caseMetadata.getCaseDatabaseName());
dbNameField.setText(caseMetadata.getCaseDatabaseName());
}
Case.CaseType caseType = caseMetadata.getCaseType();
tbDbType.setText(caseType.getLocalizedDisplayName());
caseTypeField.setText(caseType.getLocalizedDisplayName());
if (caseType == Case.CaseType.SINGLE_USER_CASE) {
deleteCaseButton.setEnabled(true);
} else {
deleteCaseButton.setEnabled(false);
}
int totalImages = imgPaths.size();
// create the headers and add all the rows
// Header names are internationalized via the generated code, do not overwrite.
String[] headers = {imagesTable.getColumnName(0),
imagesTable.getColumnName(1)};
String[][] rows = new String[totalImages][];
int i = 0;
for (long key : imgPaths.keySet()) {
String path = imgPaths.get(key);
String shortenPath = shrinkPath(path, 70);
rows[i] = new String[]{shortenPath};
i++;
}
// create the table inside with the imgPaths information
DefaultTableModel model = new DefaultTableModel(rows, headers) {
@Override
// make the cells in the FileContentTable "read only"
public boolean isCellEditable(int row, int column) {
return false;
//return column == lastColumn; // make the last column (Remove button), only the editable
}
};
imagesTable.setModel(model);
}
/**
@ -149,38 +129,28 @@ class CasePropertiesForm extends javax.swing.JPanel {
jScrollPane1 = new javax.swing.JScrollPane();
jTextArea1 = new javax.swing.JTextArea();
casePropLabel = new javax.swing.JLabel();
jPanel1 = new javax.swing.JPanel();
caseNameLabel = new javax.swing.JLabel();
crDateLabel = new javax.swing.JLabel();
caseDirLabel = new javax.swing.JLabel();
crDateTextField = new javax.swing.JTextField();
caseNameTextField = new javax.swing.JTextField();
updateCaseNameButton = new javax.swing.JButton();
genInfoLabel = new javax.swing.JLabel();
imgInfoLabel = new javax.swing.JLabel();
OKButton = new javax.swing.JButton();
imagesTableScrollPane = new javax.swing.JScrollPane();
imagesTable = new javax.swing.JTable();
jScrollPane2 = new javax.swing.JScrollPane();
caseDirTextArea = new javax.swing.JTextArea();
deleteCaseButton = new javax.swing.JButton();
caseNumberLabel = new javax.swing.JLabel();
examinerLabel = new javax.swing.JLabel();
caseNumberTextField = new javax.swing.JTextField();
examinerTextField = new javax.swing.JTextField();
lbDbType = new javax.swing.JLabel();
tbDbType = new javax.swing.JTextField();
lbDbName = new javax.swing.JLabel();
tbDbName = new javax.swing.JTextField();
caseNumberField = new javax.swing.JLabel();
examinerField = new javax.swing.JLabel();
crDateField = new javax.swing.JLabel();
caseDirField = new javax.swing.JLabel();
dbNameField = new javax.swing.JLabel();
caseTypeField = new javax.swing.JLabel();
jTextArea1.setColumns(20);
jTextArea1.setRows(5);
jScrollPane1.setViewportView(jTextArea1);
casePropLabel.setFont(casePropLabel.getFont().deriveFont(casePropLabel.getFont().getStyle() | java.awt.Font.BOLD, 24));
casePropLabel.setHorizontalAlignment(javax.swing.SwingConstants.CENTER);
casePropLabel.setText(org.openide.util.NbBundle.getMessage(CasePropertiesForm.class, "CasePropertiesForm.casePropLabel.text")); // NOI18N
caseNameLabel.setFont(caseNameLabel.getFont().deriveFont(caseNameLabel.getFont().getStyle() & ~java.awt.Font.BOLD, 11));
caseNameLabel.setText(org.openide.util.NbBundle.getMessage(CasePropertiesForm.class, "CasePropertiesForm.caseNameLabel.text")); // NOI18N
@ -190,12 +160,13 @@ class CasePropertiesForm extends javax.swing.JPanel {
caseDirLabel.setFont(caseDirLabel.getFont().deriveFont(caseDirLabel.getFont().getStyle() & ~java.awt.Font.BOLD, 11));
caseDirLabel.setText(org.openide.util.NbBundle.getMessage(CasePropertiesForm.class, "CasePropertiesForm.caseDirLabel.text")); // NOI18N
crDateTextField.setEditable(false);
crDateTextField.setFont(crDateTextField.getFont().deriveFont(crDateTextField.getFont().getStyle() & ~java.awt.Font.BOLD, 11));
crDateTextField.setText(org.openide.util.NbBundle.getMessage(CasePropertiesForm.class, "CasePropertiesForm.crDateTextField.text")); // NOI18N
caseNameTextField.setFont(caseNameTextField.getFont().deriveFont(caseNameTextField.getFont().getStyle() & ~java.awt.Font.BOLD, 11));
caseNameTextField.setText(org.openide.util.NbBundle.getMessage(CasePropertiesForm.class, "CasePropertiesForm.caseNameTextField.text")); // NOI18N
caseNameTextField.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
caseNameTextFieldActionPerformed(evt);
}
});
updateCaseNameButton.setFont(updateCaseNameButton.getFont().deriveFont(updateCaseNameButton.getFont().getStyle() & ~java.awt.Font.BOLD, 11));
updateCaseNameButton.setText(org.openide.util.NbBundle.getMessage(CasePropertiesForm.class, "CasePropertiesForm.updateCaseNameButton.text")); // NOI18N
@ -205,53 +176,6 @@ class CasePropertiesForm extends javax.swing.JPanel {
}
});
genInfoLabel.setFont(genInfoLabel.getFont().deriveFont(genInfoLabel.getFont().getStyle() | java.awt.Font.BOLD, 14));
genInfoLabel.setText(org.openide.util.NbBundle.getMessage(CasePropertiesForm.class, "CasePropertiesForm.genInfoLabel.text")); // NOI18N
imgInfoLabel.setFont(imgInfoLabel.getFont().deriveFont(imgInfoLabel.getFont().getStyle() | java.awt.Font.BOLD, 14));
imgInfoLabel.setText(org.openide.util.NbBundle.getMessage(CasePropertiesForm.class, "CasePropertiesForm.imgInfoLabel.text")); // NOI18N
OKButton.setFont(OKButton.getFont().deriveFont(OKButton.getFont().getStyle() & ~java.awt.Font.BOLD, 11));
OKButton.setText(org.openide.util.NbBundle.getMessage(CasePropertiesForm.class, "CasePropertiesForm.OKButton.text")); // NOI18N
imagesTableScrollPane.setFont(imagesTableScrollPane.getFont().deriveFont(imagesTableScrollPane.getFont().getStyle() & ~java.awt.Font.BOLD, 11));
imagesTable.setFont(imagesTable.getFont().deriveFont(imagesTable.getFont().getStyle() & ~java.awt.Font.BOLD, 11));
imagesTable.setModel(new javax.swing.table.DefaultTableModel(
new Object [][] {
},
new String [] {
"Path", "Remove"
}
) {
boolean[] canEdit = new boolean [] {
false, true
};
public boolean isCellEditable(int rowIndex, int columnIndex) {
return canEdit [columnIndex];
}
});
imagesTable.setShowHorizontalLines(false);
imagesTable.setShowVerticalLines(false);
imagesTable.getTableHeader().setReorderingAllowed(false);
imagesTable.setUpdateSelectionOnSort(false);
imagesTableScrollPane.setViewportView(imagesTable);
if (imagesTable.getColumnModel().getColumnCount() > 0) {
imagesTable.getColumnModel().getColumn(0).setHeaderValue(org.openide.util.NbBundle.getMessage(CasePropertiesForm.class, "CasePropertiesForm.imagesTable.columnModel.title0")); // NOI18N
imagesTable.getColumnModel().getColumn(1).setHeaderValue(org.openide.util.NbBundle.getMessage(CasePropertiesForm.class, "CasePropertiesForm.imagesTable.columnModel.title1")); // NOI18N
}
jScrollPane2.setFont(jScrollPane2.getFont().deriveFont(jScrollPane2.getFont().getStyle() & ~java.awt.Font.BOLD, 11));
caseDirTextArea.setEditable(false);
caseDirTextArea.setBackground(new java.awt.Color(240, 240, 240));
caseDirTextArea.setColumns(20);
caseDirTextArea.setRows(1);
caseDirTextArea.setRequestFocusEnabled(false);
jScrollPane2.setViewportView(caseDirTextArea);
deleteCaseButton.setFont(deleteCaseButton.getFont().deriveFont(deleteCaseButton.getFont().getStyle() & ~java.awt.Font.BOLD, 11));
deleteCaseButton.setText(org.openide.util.NbBundle.getMessage(CasePropertiesForm.class, "CasePropertiesForm.deleteCaseButton.text")); // NOI18N
deleteCaseButton.addActionListener(new java.awt.event.ActionListener() {
@ -266,117 +190,119 @@ class CasePropertiesForm extends javax.swing.JPanel {
examinerLabel.setFont(examinerLabel.getFont().deriveFont(examinerLabel.getFont().getStyle() & ~java.awt.Font.BOLD, 11));
examinerLabel.setText(org.openide.util.NbBundle.getMessage(CasePropertiesForm.class, "CasePropertiesForm.examinerLabel.text")); // NOI18N
caseNumberTextField.setEditable(false);
caseNumberTextField.setFont(caseNumberTextField.getFont().deriveFont(caseNumberTextField.getFont().getStyle() & ~java.awt.Font.BOLD, 11));
caseNumberTextField.setText(org.openide.util.NbBundle.getMessage(CasePropertiesForm.class, "CasePropertiesForm.caseNumberTextField.text")); // NOI18N
examinerTextField.setEditable(false);
examinerTextField.setFont(examinerTextField.getFont().deriveFont(examinerTextField.getFont().getStyle() & ~java.awt.Font.BOLD, 11));
examinerTextField.setText(org.openide.util.NbBundle.getMessage(CasePropertiesForm.class, "CasePropertiesForm.examinerTextField.text")); // NOI18N
lbDbType.setFont(lbDbType.getFont().deriveFont(lbDbType.getFont().getStyle() & ~java.awt.Font.BOLD, 11));
lbDbType.setText(org.openide.util.NbBundle.getMessage(CasePropertiesForm.class, "CasePropertiesForm.lbDbType.text")); // NOI18N
tbDbType.setEditable(false);
tbDbType.setFont(tbDbType.getFont().deriveFont(tbDbType.getFont().getStyle() & ~java.awt.Font.BOLD, 11));
tbDbType.setText(org.openide.util.NbBundle.getMessage(CasePropertiesForm.class, "CasePropertiesForm.tbDbType.text")); // NOI18N
lbDbName.setFont(lbDbName.getFont().deriveFont(lbDbName.getFont().getStyle() & ~java.awt.Font.BOLD, 11));
lbDbName.setText(org.openide.util.NbBundle.getMessage(CasePropertiesForm.class, "CasePropertiesForm.lbDbName.text")); // NOI18N
tbDbName.setEditable(false);
tbDbName.setFont(tbDbName.getFont().deriveFont(tbDbName.getFont().getStyle() & ~java.awt.Font.BOLD, 11));
tbDbName.setText(org.openide.util.NbBundle.getMessage(CasePropertiesForm.class, "CasePropertiesForm.tbDbName.text")); // NOI18N
caseNumberField.setText(org.openide.util.NbBundle.getMessage(CasePropertiesForm.class, "CasePropertiesForm.caseNumberField.text")); // NOI18N
examinerField.setText(org.openide.util.NbBundle.getMessage(CasePropertiesForm.class, "CasePropertiesForm.examinerField.text")); // NOI18N
crDateField.setText(org.openide.util.NbBundle.getMessage(CasePropertiesForm.class, "CasePropertiesForm.crDateField.text")); // NOI18N
caseDirField.setText(org.openide.util.NbBundle.getMessage(CasePropertiesForm.class, "CasePropertiesForm.caseDirField.text")); // NOI18N
caseDirField.setMinimumSize(new java.awt.Dimension(25, 14));
dbNameField.setText(org.openide.util.NbBundle.getMessage(CasePropertiesForm.class, "CasePropertiesForm.dbNameField.text")); // NOI18N
dbNameField.setMinimumSize(new java.awt.Dimension(25, 14));
caseTypeField.setText(org.openide.util.NbBundle.getMessage(CasePropertiesForm.class, "CasePropertiesForm.caseTypeField.text")); // NOI18N
caseTypeField.setMaximumSize(new java.awt.Dimension(1, 0));
javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1);
jPanel1.setLayout(jPanel1Layout);
jPanel1Layout.setHorizontalGroup(
jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(jPanel1Layout.createSequentialGroup()
.addContainerGap()
.addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(jPanel1Layout.createSequentialGroup()
.addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(lbDbName)
.addComponent(lbDbType)
.addComponent(caseDirLabel))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(caseDirField, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addComponent(caseTypeField, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addComponent(dbNameField, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)))
.addGroup(jPanel1Layout.createSequentialGroup()
.addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(crDateLabel)
.addComponent(examinerLabel)
.addComponent(caseNumberLabel))
.addGap(18, 18, 18)
.addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(examinerField, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addComponent(caseNumberField, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addGroup(jPanel1Layout.createSequentialGroup()
.addComponent(caseNameTextField, javax.swing.GroupLayout.DEFAULT_SIZE, 243, Short.MAX_VALUE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(updateCaseNameButton, javax.swing.GroupLayout.PREFERRED_SIZE, 104, javax.swing.GroupLayout.PREFERRED_SIZE))
.addComponent(crDateField, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)))
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel1Layout.createSequentialGroup()
.addGap(0, 0, Short.MAX_VALUE)
.addComponent(deleteCaseButton, javax.swing.GroupLayout.PREFERRED_SIZE, 106, javax.swing.GroupLayout.PREFERRED_SIZE)))
.addContainerGap())
.addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(jPanel1Layout.createSequentialGroup()
.addContainerGap()
.addComponent(caseNameLabel)
.addContainerGap(392, Short.MAX_VALUE)))
);
jPanel1Layout.setVerticalGroup(
jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel1Layout.createSequentialGroup()
.addContainerGap()
.addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(caseNameTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(updateCaseNameButton))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(jPanel1Layout.createSequentialGroup()
.addComponent(caseNumberField, javax.swing.GroupLayout.PREFERRED_SIZE, 14, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
.addComponent(examinerField, javax.swing.GroupLayout.PREFERRED_SIZE, 14, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(examinerLabel))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(crDateField, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.PREFERRED_SIZE, 14, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(crDateLabel, javax.swing.GroupLayout.Alignment.TRAILING))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
.addComponent(caseDirLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addComponent(caseDirField, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(caseTypeField, javax.swing.GroupLayout.PREFERRED_SIZE, 14, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(lbDbType))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(lbDbName)
.addComponent(dbNameField, javax.swing.GroupLayout.PREFERRED_SIZE, 14, javax.swing.GroupLayout.PREFERRED_SIZE)))
.addComponent(caseNumberLabel))
.addGap(10, 10, 10)
.addComponent(deleteCaseButton)
.addContainerGap())
.addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(jPanel1Layout.createSequentialGroup()
.addContainerGap()
.addComponent(caseNameLabel)
.addContainerGap(173, Short.MAX_VALUE)))
);
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
this.setLayout(layout);
layout.setHorizontalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addContainerGap()
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(casePropLabel, javax.swing.GroupLayout.DEFAULT_SIZE, 440, Short.MAX_VALUE)
.addComponent(imagesTableScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, 440, Short.MAX_VALUE)
.addGroup(layout.createSequentialGroup()
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(caseNameLabel)
.addComponent(caseNumberLabel)
.addComponent(examinerLabel)
.addComponent(caseDirLabel)
.addComponent(crDateLabel)
.addComponent(lbDbType))
.addGap(18, 18, 18)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(caseNameTextField, javax.swing.GroupLayout.DEFAULT_SIZE, 245, Short.MAX_VALUE)
.addComponent(caseNumberTextField, javax.swing.GroupLayout.DEFAULT_SIZE, 245, Short.MAX_VALUE)
.addComponent(examinerTextField, javax.swing.GroupLayout.DEFAULT_SIZE, 245, Short.MAX_VALUE)
.addComponent(crDateTextField)
.addComponent(jScrollPane2)
.addComponent(tbDbType)
.addComponent(tbDbName))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(deleteCaseButton, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addComponent(updateCaseNameButton, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)))
.addGroup(layout.createSequentialGroup()
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(genInfoLabel)
.addComponent(imgInfoLabel)
.addGroup(layout.createSequentialGroup()
.addGap(181, 181, 181)
.addComponent(OKButton, javax.swing.GroupLayout.PREFERRED_SIZE, 78, javax.swing.GroupLayout.PREFERRED_SIZE))
.addComponent(lbDbName))
.addGap(0, 0, Short.MAX_VALUE)))
.addContainerGap())
.addComponent(jPanel1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
);
layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addContainerGap()
.addComponent(casePropLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 33, javax.swing.GroupLayout.PREFERRED_SIZE)
.addGap(18, 18, 18)
.addComponent(genInfoLabel)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(caseNameLabel)
.addComponent(caseNameTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(updateCaseNameButton))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(caseNumberLabel)
.addComponent(caseNumberTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(examinerLabel)
.addComponent(examinerTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(crDateLabel)
.addComponent(crDateTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(jScrollPane2, javax.swing.GroupLayout.PREFERRED_SIZE, 40, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(caseDirLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 14, javax.swing.GroupLayout.PREFERRED_SIZE))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(tbDbType, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(lbDbType))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(lbDbName)
.addComponent(tbDbName, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
.addGap(18, 18, 18)
.addComponent(imgInfoLabel))
.addGroup(layout.createSequentialGroup()
.addGap(9, 9, 9)
.addComponent(deleteCaseButton)))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
.addComponent(imagesTableScrollPane, javax.swing.GroupLayout.PREFERRED_SIZE, 170, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(OKButton)
.addContainerGap())
.addComponent(jPanel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
);
}// </editor-fold>//GEN-END:initComponents
@ -399,38 +325,36 @@ class CasePropertiesForm extends javax.swing.JPanel {
NbBundle.getMessage(this.getClass(),
"CasePropertiesForm.updateCaseName.msgDlg.empty.title"),
JOptionPane.ERROR_MESSAGE);
} else // check if case Name contain one of this following symbol:
// \ / : * ? " < > |
if (newCaseName.contains("\\") || newCaseName.contains("/") || newCaseName.contains(":")
|| newCaseName.contains("*") || newCaseName.contains("?") || newCaseName.contains("\"")
|| newCaseName.contains("<") || newCaseName.contains(">") || newCaseName.contains("|")) {
String errorMsg = NbBundle
.getMessage(this.getClass(), "CasePropertiesForm.updateCaseName.msgDlg.invalidSymbols.msg");
JOptionPane.showMessageDialog(caller, errorMsg,
NbBundle.getMessage(this.getClass(),
"CasePropertiesForm.updateCaseName.msgDlg.invalidSymbols.title"),
JOptionPane.ERROR_MESSAGE);
} else {
// check if case Name contain one of this following symbol:
// \ / : * ? " < > |
if (newCaseName.contains("\\") || newCaseName.contains("/") || newCaseName.contains(":")
|| newCaseName.contains("*") || newCaseName.contains("?") || newCaseName.contains("\"")
|| newCaseName.contains("<") || newCaseName.contains(">") || newCaseName.contains("|")) {
String errorMsg = NbBundle
.getMessage(this.getClass(), "CasePropertiesForm.updateCaseName.msgDlg.invalidSymbols.msg");
JOptionPane.showMessageDialog(caller, errorMsg,
NbBundle.getMessage(this.getClass(),
"CasePropertiesForm.updateCaseName.msgDlg.invalidSymbols.title"),
JOptionPane.ERROR_MESSAGE);
} else {
// ask for the confirmation first
String confMsg = NbBundle
.getMessage(this.getClass(), "CasePropertiesForm.updateCaseName.confMsg.msg", oldCaseName,
newCaseName);
NotifyDescriptor d = new NotifyDescriptor.Confirmation(confMsg,
NbBundle.getMessage(this.getClass(),
"CasePropertiesForm.updateCaseName.confMsg.title"),
NotifyDescriptor.YES_NO_OPTION, NotifyDescriptor.WARNING_MESSAGE);
d.setValue(NotifyDescriptor.NO_OPTION);
Object res = DialogDisplayer.getDefault().notify(d);
if (res != null && res == DialogDescriptor.YES_OPTION) {
// if user select "Yes"
String oldPath = current.getCaseMetadata().getFilePath().toString();
try {
current.updateCaseName(oldCaseName, oldPath, newCaseName, oldPath);
} catch (Exception ex) {
Logger.getLogger(CasePropertiesForm.class.getName()).log(Level.WARNING, "Error: problem updating case name.", ex); //NON-NLS
}
// ask for the confirmation first
String confMsg = NbBundle
.getMessage(this.getClass(), "CasePropertiesForm.updateCaseName.confMsg.msg", oldCaseName,
newCaseName);
NotifyDescriptor d = new NotifyDescriptor.Confirmation(confMsg,
NbBundle.getMessage(this.getClass(),
"CasePropertiesForm.updateCaseName.confMsg.title"),
NotifyDescriptor.YES_NO_OPTION, NotifyDescriptor.WARNING_MESSAGE);
d.setValue(NotifyDescriptor.NO_OPTION);
Object res = DialogDisplayer.getDefault().notify(d);
if (res != null && res == DialogDescriptor.YES_OPTION) {
// if user select "Yes"
String oldPath = current.getCaseMetadata().getFilePath().toString();
try {
current.updateCaseName(oldCaseName, oldPath, newCaseName, oldPath);
} catch (Exception ex) {
Logger.getLogger(CasePropertiesForm.class.getName()).log(Level.WARNING, "Error: problem updating case name.", ex); //NON-NLS
}
}
}
@ -441,40 +365,30 @@ class CasePropertiesForm extends javax.swing.JPanel {
CallableSystemAction.get(CaseDeleteAction.class).actionPerformed(evt);
}//GEN-LAST:event_deleteCaseButtonActionPerformed
/**
* Sets the listener for the OK button
*
* @param e The action listener
*/
public void setOKButtonActionListener(ActionListener e) {
OKButton.addActionListener(e);
}
private void caseNameTextFieldActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_caseNameTextFieldActionPerformed
// TODO add your handling code here:
}//GEN-LAST:event_caseNameTextFieldActionPerformed
// Variables declaration - do not modify//GEN-BEGIN:variables
private javax.swing.JButton OKButton;
private javax.swing.JLabel caseDirField;
private javax.swing.JLabel caseDirLabel;
private javax.swing.JTextArea caseDirTextArea;
private javax.swing.JLabel caseNameLabel;
private javax.swing.JTextField caseNameTextField;
private javax.swing.JLabel caseNumberField;
private javax.swing.JLabel caseNumberLabel;
private javax.swing.JTextField caseNumberTextField;
private javax.swing.JLabel casePropLabel;
private javax.swing.JLabel caseTypeField;
private javax.swing.JLabel crDateField;
private javax.swing.JLabel crDateLabel;
private javax.swing.JTextField crDateTextField;
private javax.swing.JLabel dbNameField;
private javax.swing.JButton deleteCaseButton;
private javax.swing.JLabel examinerField;
private javax.swing.JLabel examinerLabel;
private javax.swing.JTextField examinerTextField;
private javax.swing.JLabel genInfoLabel;
private javax.swing.JTable imagesTable;
private javax.swing.JScrollPane imagesTableScrollPane;
private javax.swing.JLabel imgInfoLabel;
private javax.swing.JPanel jPanel1;
private javax.swing.JScrollPane jScrollPane1;
private javax.swing.JScrollPane jScrollPane2;
private javax.swing.JTextArea jTextArea1;
private javax.swing.JLabel lbDbName;
private javax.swing.JLabel lbDbType;
private javax.swing.JTextField tbDbName;
private javax.swing.JTextField tbDbType;
private javax.swing.JButton updateCaseNameButton;
// End of variables declaration//GEN-END:variables

View File

@ -25,17 +25,30 @@ import org.sleuthkit.autopsy.casemodule.Case;
import org.sleuthkit.autopsy.keywordsearchservice.KeywordSearchService;
import org.sleuthkit.datamodel.BlackboardArtifact;
import org.sleuthkit.datamodel.BlackboardAttribute;
import org.sleuthkit.datamodel.SleuthkitCase;
import org.sleuthkit.datamodel.TskCoreException;
import org.sleuthkit.datamodel.TskDataException;
/**
* Represents the blackboard, a place where artifacts and their attributes are
* posted.
* A representation of the blackboard, a place where artifacts and their
* attributes are posted.
*
* NOTE: This API of this class is under development.
*/
public final class Blackboard implements Closeable {
private SleuthkitCase caseDb;
/**
* Constructs a representation of the blackboard, a place where artifacts
* and their attributes are posted.
*
* @param casedb The case database.
*/
Blackboard(SleuthkitCase casedb) {
this.caseDb = casedb;
}
/**
* Indexes the text associated with the an artifact.
*
@ -43,7 +56,10 @@ public final class Blackboard implements Closeable {
*
* @throws BlackboardException If there is a problem indexing the artifact.
*/
public void indexArtifact(BlackboardArtifact artifact) throws BlackboardException {
public synchronized void indexArtifact(BlackboardArtifact artifact) throws BlackboardException {
if (null == caseDb) {
throw new BlackboardException("Blackboard has been closed");
}
KeywordSearchService searchService = Lookup.getDefault().lookup(KeywordSearchService.class);
if (null == searchService) {
throw new BlackboardException("Keyword search service not found");
@ -67,12 +83,15 @@ public final class Blackboard implements Closeable {
* @throws BlackboardBlackboardException If there is a problem getting or
* adding the artifact type.
*/
public BlackboardArtifact.Type getOrAddArtifactType(String typeName, String displayName) throws BlackboardException {
public synchronized BlackboardArtifact.Type getOrAddArtifactType(String typeName, String displayName) throws BlackboardException {
if (null == caseDb) {
throw new BlackboardException("Blackboard has been closed");
}
try {
return Case.getCurrentCase().getSleuthkitCase().addBlackboardArtifactType(typeName, displayName);
return caseDb.addBlackboardArtifactType(typeName, displayName);
} catch (TskDataException typeExistsEx) {
try {
return Case.getCurrentCase().getSleuthkitCase().getArtifactType(typeName);
return caseDb.getArtifactType(typeName);
} catch (TskCoreException ex) {
throw new BlackboardException("Failed to get or add artifact type", ex);
}
@ -94,12 +113,15 @@ public final class Blackboard implements Closeable {
* @throws BlackboardBlackboardException If there is a problem getting or
* adding the attribute type.
*/
public BlackboardAttribute.Type getOrAddAttributeType(String typeName, BlackboardAttribute.TSK_BLACKBOARD_ATTRIBUTE_VALUE_TYPE valueType, String displayName) throws BlackboardException {
public synchronized BlackboardAttribute.Type getOrAddAttributeType(String typeName, BlackboardAttribute.TSK_BLACKBOARD_ATTRIBUTE_VALUE_TYPE valueType, String displayName) throws BlackboardException {
if (null == caseDb) {
throw new BlackboardException("Blackboard has been closed");
}
try {
return Case.getCurrentCase().getSleuthkitCase().addArtifactAttributeType(typeName, valueType, displayName);
return caseDb.addArtifactAttributeType(typeName, valueType, displayName);
} catch (TskDataException typeExistsEx) {
try {
return Case.getCurrentCase().getSleuthkitCase().getAttributeType(typeName);
return caseDb.getAttributeType(typeName);
} catch (TskCoreException ex) {
throw new BlackboardException("Failed to get or add attribute type", ex);
}
@ -109,13 +131,16 @@ public final class Blackboard implements Closeable {
}
/**
* Cloese this blackboard and releases any resources associated with it.
* @throws IOException
* Closes the blackboard.
*
* @throws IOException If there is a problem closing the blackboard.
*/
@Override
public void close() throws IOException {
public synchronized void close() throws IOException {
caseDb = null;
}
/**
* A blackboard exception.
*/

View File

@ -1,16 +1,3 @@
FileManager.findFiles.exception.msg=Attempted to use FileManager after it was closed.
FileManager.findFiles2.exception.msg=Attempted to use FileManager after it was closed.
FileManager.findFiles3.exception.msg=Attempted to use FileManager after it was closed.
FileManager.openFiles.exception.msg=Attempted to use FileManager after it was closed.
FileManager.addDerivedFile.exception.msg=Attempted to use FileManager after it was closed.
FileManager.addCarvedFile.exception.msg=Attempted to use FileManager after it was closed.
FileManager.addLocalFilesDirs.exception.notReadable.msg=One of the local files/dirs to add is not readable\: {0}, aborting the process before any files added
FileManager.addLocalFilesDirs.exception.cantAdd.msg=One of the local files/dirs could not be added\: {0}
FileManager.addLocalFileSetRootDir.exception.errCreateDir.msg=Error creating local file set dir\: {0}
FileManager.addLocalDirInt.exception.closed.msg=Attempted to use FileManager after it was closed.
FileManager.addLocalDirInt.exception.doesntExist.msg=Attempted to add a local dir that does not exist\: {0}
FileManager.addLocalDirInt.exception.notReadable.msg=Attempted to add a local dir that is not readable\: {0}
FileManager.addLocalDirInt2.exception.closed.msg=Attempted to use FileManager after it was closed.
TagsManager.addContentTag.exception.beginByteOffsetOOR.msg=beginByteOffset \= {0} out of content size range (0 - {1})
TagsManager.addContentTag.exception.endByteOffsetOOR.msg=endByteOffset \= {0} out of content size range (0 - {1})
TagsManager.addContentTag.exception.endLTbegin.msg=endByteOffset < beginByteOffset

View File

@ -1,16 +1,3 @@
FileManager.findFiles.exception.msg=FileManager\u3092\u9589\u3058\u305f\u5f8c\u306b\u4f7f\u7528\u3092\u8a66\u307f\u307e\u3057\u305f\u3002
FileManager.findFiles2.exception.msg=FileManager\u3092\u9589\u3058\u305f\u5f8c\u306b\u4f7f\u7528\u3092\u8a66\u307f\u307e\u3057\u305f\u3002
FileManager.findFiles3.exception.msg=FileManager\u3092\u9589\u3058\u305f\u5f8c\u306b\u4f7f\u7528\u3092\u8a66\u307f\u307e\u3057\u305f\u3002
FileManager.openFiles.exception.msg=FileManager\u3092\u9589\u3058\u305f\u5f8c\u306b\u4f7f\u7528\u3092\u8a66\u307f\u307e\u3057\u305f\u3002
FileManager.addDerivedFile.exception.msg=FileManager\u3092\u9589\u3058\u305f\u5f8c\u306b\u4f7f\u7528\u3092\u8a66\u307f\u307e\u3057\u305f\u3002
FileManager.addCarvedFile.exception.msg=FileManager\u3092\u9589\u3058\u305f\u5f8c\u306b\u4f7f\u7528\u3092\u8a66\u307f\u307e\u3057\u305f\u3002
FileManager.addLocalFilesDirs.exception.notReadable.msg=\u8ffd\u52a0\u3059\u308b\u30ed\u30fc\u30ab\u30eb\u30d5\u30a1\u30a4\u30eb\uff0f\u30c7\u30a3\u30ec\u30af\u30c8\u30ea\u306e\u4e2d\u306b\u8aad\u307f\u53d6\u308c\u306a\u3044\u3082\u306e\u304c\uff11\u500b\u3042\u308a\u307e\u3059\uff1a{0}\u3001\u30d5\u30a1\u30a4\u30eb\u304c\u8ffd\u52a0\u3055\u308c\u308b\u524d\u306b\u51e6\u7406\u3092\u4e2d\u6b62\u3057\u307e\u3059
FileManager.addLocalFilesDirs.exception.cantAdd.msg=\u30ed\u30fc\u30ab\u30eb\u30d5\u30a1\u30a4\u30eb\uff0f\u30c7\u30a3\u30ec\u30af\u30c8\u30ea\u306e\uff11\u500b\u306f\u8ffd\u52a0\u3067\u304d\u307e\u305b\u3093\u3067\u3057\u305f\uff1a{0}
FileManager.addLocalFileSetRootDir.exception.errCreateDir.msg=\u30ed\u30fc\u30ab\u30eb\u30d5\u30a1\u30a4\u30eb\u30bb\u30c3\u30c8\u30c7\u30a3\u30ec\u30af\u30c8\u30ea\u3092\u4f5c\u6210\u4e2d\u306b\u30a8\u30e9\u30fc\u304c\u8d77\u3053\u308a\u307e\u3057\u305f\uff1a {0}
FileManager.addLocalDirInt.exception.closed.msg=FileManager\u3092\u9589\u3058\u305f\u5f8c\u306b\u4f7f\u7528\u3092\u8a66\u307f\u307e\u3057\u305f\u3002
FileManager.addLocalDirInt.exception.doesntExist.msg=\u5b58\u5728\u3057\u306a\u3044\u30ed\u30fc\u30ab\u30eb\u30c7\u30a3\u30ec\u30af\u30c8\u30ea\u306e\u8ffd\u52a0\u3092\u8a66\u307f\u307e\u3057\u305f\: {0}
FileManager.addLocalDirInt.exception.notReadable.msg=\u8aad\u307f\u53d6\u308a\u3067\u304d\u306a\u3044\u30ed\u30fc\u30ab\u30eb\u30c7\u30a3\u30ec\u30af\u30c8\u30ea\u306e\u8ffd\u52a0\u3092\u8a66\u307f\u307e\u3057\u305f\: {0}
FileManager.addLocalDirInt2.exception.closed.msg=FileManager\u3092\u9589\u3058\u305f\u5f8c\u306b\u4f7f\u7528\u3092\u8a66\u307f\u307e\u3057\u305f\u3002
TagsManager.addContentTag.exception.beginByteOffsetOOR.msg=beginByteOffset \= {0} \u30b3\u30f3\u30c6\u30f3\u30c4\u30b5\u30a4\u30ba\u7bc4\u56f2(0 - {1})\u306e\u5916\u3067\u3059
TagsManager.addContentTag.exception.endByteOffsetOOR.msg=endByteOffset \= {0} \u30b3\u30f3\u30c6\u30f3\u30c4\u30b5\u30a4\u30ba\u7bc4\u56f2(0 - {1})\u306e\u5916\u3067\u3059
TagsManager.addContentTag.exception.endLTbegin.msg=endByteOffset < beginByteOffset

View File

@ -1,19 +1,19 @@
/*
*
* Autopsy Forensic Browser
*
*
* Copyright 2011-2016 Basis Technology Corp.
*
*
* Copyright 2012 42six Solutions.
* Contact: aebadirad <at> 42six <dot> com
* Project Contact/Architect: 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.
@ -25,10 +25,9 @@ package org.sleuthkit.autopsy.casemodule.services;
import java.io.Closeable;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.logging.Level;
import org.openide.util.NbBundle;
import org.sleuthkit.autopsy.coreutils.Logger;
import org.sleuthkit.autopsy.datamodel.VirtualDirectoryNode;
import org.sleuthkit.autopsy.ingest.IngestServices;
import org.sleuthkit.autopsy.ingest.ModuleContentEvent;
@ -36,67 +35,102 @@ import org.sleuthkit.datamodel.AbstractFile;
import org.sleuthkit.datamodel.Content;
import org.sleuthkit.datamodel.DerivedFile;
import org.sleuthkit.datamodel.LayoutFile;
import org.sleuthkit.datamodel.LocalFile;
import org.sleuthkit.datamodel.SleuthkitCase;
import org.sleuthkit.datamodel.SleuthkitCase.CaseDbTransaction;
import org.sleuthkit.datamodel.TskCoreException;
import org.sleuthkit.datamodel.TskFileRange;
import org.sleuthkit.datamodel.VirtualDirectory;
import org.sleuthkit.datamodel.CarvedFileContainer;
import org.sleuthkit.datamodel.LocalFilesDataSource;
import org.sleuthkit.datamodel.TskDataException;
import org.apache.commons.lang3.StringUtils;
import org.sleuthkit.datamodel.CarvingResult;
/**
* Abstraction to facilitate access to localFiles and directories.
* A manager that provides methods for retrieving files from the current case
* and for adding local files, carved files, and derived files to the current
* case.
*/
public class FileManager implements Closeable {
private SleuthkitCase tskCase;
private static final Logger logger = Logger.getLogger(FileManager.class.getName());
private volatile int curNumFileSets; //current number of filesets (root virt dir objects)
public FileManager(SleuthkitCase tskCase) {
this.tskCase = tskCase;
init();
}
private SleuthkitCase caseDb;
/**
* initialize the file manager for the case
* Constructs a manager that provides methods for retrieving files from the
* current case and for adding local files, carved files, and derived files
* to the current case.
*
* @param caseDb The case database.
*/
private synchronized void init() {
//get the number of local file sets in db
List<VirtualDirectory> virtRoots;
curNumFileSets = 0;
try {
virtRoots = tskCase.getVirtualDirectoryRoots();
for (VirtualDirectory vd : virtRoots) {
if (vd.getName().startsWith(VirtualDirectoryNode.LOGICAL_FILE_SET_PREFIX)) {
++curNumFileSets;
}
}
} catch (TskCoreException ex) {
logger.log(Level.SEVERE, "Error initializing FileManager and getting number of local file sets"); //NON-NLS
}
public FileManager(SleuthkitCase caseDb) {
this.caseDb = caseDb;
}
/**
* Finds a set of localFiles that meets the name criteria in all data
* sources in the current case.
* Finds all files with types that match one of a collection of MIME types.
*
* @param fileName Pattern of the name of the file or directory to match
* (case insensitive, used in LIKE SQL statement).
* @param mimeTypes The MIME types.
*
* @return a list of AbstractFile for localFiles/directories whose name
* matches the given fileName
* @return The files.
*
* @throws TskCoreException If there is a problem querying the case
* database.
*/
public synchronized List<AbstractFile> findFilesByMimeType(Collection<String> mimeTypes) throws TskCoreException {
if (null == caseDb) {
throw new TskCoreException("File manager has been closed");
}
return caseDb.findAllFilesWhere(createFileTypeInCondition(mimeTypes));
}
/**
* Finds all files in a given data source (image, local/logical files set,
* etc.) with types that match one of a collection of MIME types.
*
* @param dataSource The data source.
* @param mimeTypes The MIME types.
*
* @return The files.
*
* @throws TskCoreException If there is a problem querying the case
* database.
*/
public synchronized List<AbstractFile> findFilesByMimeType(Content dataSource, Collection<String> mimeTypes) throws TskCoreException {
if (null == caseDb) {
throw new TskCoreException("File manager has been closed");
}
return caseDb.findAllFilesWhere("data_source_obj_id = " + dataSource.getId() + " AND " + createFileTypeInCondition(mimeTypes));
}
/**
* Converts a list of MIME types into an SQL "mime_type IN" condition.
*
* @param mimeTypes The MIIME types.
*
* @return The condition string.
*/
private static String createFileTypeInCondition(Collection<String> mimeTypes) {
String types = StringUtils.join(mimeTypes, "', '");
return "mime_type IN ('" + types + "')";
}
/**
* Finds all files and directories with a given file name. The name search
* is for full or partial matches and is case insensitive (a case
* insensitive SQL LIKE clause is used to query the case database).
*
* @param fileName The full or partial file name.
*
* @return The matching files and directories.
*
* @throws TskCoreException if there is a problem querying the case
* database.
*/
public synchronized List<AbstractFile> findFiles(String fileName) throws TskCoreException {
List<AbstractFile> result = new ArrayList<>();
if (tskCase == null) {
throw new TskCoreException(NbBundle.getMessage(this.getClass(), "FileManager.findFiles.exception.msg"));
if (null == caseDb) {
throw new TskCoreException("File manager has been closed");
}
List<Content> dataSources = tskCase.getRootObjects();
List<AbstractFile> result = new ArrayList<>();
List<Content> dataSources = caseDb.getRootObjects();
for (Content dataSource : dataSources) {
result.addAll(findFiles(dataSource, fileName));
}
@ -104,290 +138,221 @@ public class FileManager implements Closeable {
}
/**
* Finds a set of localFiles that meets the name criteria in all data
* sources in the current case.
* Finds all files and directories with a given file name and parent file or
* directory name. The name searches are for full or partial matches and are
* case insensitive (a case insensitive SQL LIKE clause is used to query the
* case database).
*
* @param fileName Pattern of the name of the file or directory to match
* (case insensitive, used in LIKE SQL statement).
* @param dirName Pattern of the name of the parent directory to use as the
* root of the search (case insensitive, used in LIKE SQL
* statement).
* @param fileName The full or partial file name.
* @param parentName The full or partial parent file or directory name.
*
* @return a list of AbstractFile for localFiles/directories whose name
* matches fileName and whose parent directory contains dirName.
* @return The matching files and directories.
*
* @throws TskCoreException if there is a problem querying the case
* database.
*/
public synchronized List<AbstractFile> findFiles(String fileName, String dirName) throws TskCoreException {
List<AbstractFile> result = new ArrayList<>();
if (tskCase == null) {
throw new TskCoreException(NbBundle.getMessage(this.getClass(), "FileManager.findFiles2.exception.msg"));
public synchronized List<AbstractFile> findFiles(String fileName, String parentName) throws TskCoreException {
if (null == caseDb) {
throw new TskCoreException("File manager has been closed");
}
List<Content> dataSources = tskCase.getRootObjects();
List<AbstractFile> result = new ArrayList<>();
List<Content> dataSources = caseDb.getRootObjects();
for (Content dataSource : dataSources) {
result.addAll(findFiles(dataSource, fileName, dirName));
result.addAll(findFiles(dataSource, fileName, parentName));
}
return result;
}
/**
* Finds a set of localFiles that meets the name criteria in all data
* sources in the current case.
* Finds all files and directories with a given file name and parent file or
* directory. The name search is for full or partial matches and is case
* insensitive (a case insensitive SQL LIKE clause is used to query the case
* database).
*
* @param fileName Pattern of the name of the file or directory to match
* (case insensitive, used in LIKE SQL statement).
* @param parentFile Object of root/parent directory to restrict search to.
* @param fileName The full or partial file name.
* @param parent The parent file or directory.
*
* @return a list of AbstractFile for localFiles/directories whose name
* matches fileName and that were inside a directory described by
* parentFsContent.
* @return The matching files and directories.
*
* @throws TskCoreException if there is a problem querying the case
* database.
*/
public synchronized List<AbstractFile> findFiles(String fileName, AbstractFile parentFile) throws TskCoreException {
List<AbstractFile> result = new ArrayList<>();
if (tskCase == null) {
throw new TskCoreException(NbBundle.getMessage(this.getClass(), "FileManager.findFiles3.exception.msg"));
public synchronized List<AbstractFile> findFiles(String fileName, AbstractFile parent) throws TskCoreException {
if (null == caseDb) {
throw new TskCoreException("File manager has been closed");
}
List<Content> dataSources = tskCase.getRootObjects();
List<AbstractFile> result = new ArrayList<>();
List<Content> dataSources = caseDb.getRootObjects();
for (Content dataSource : dataSources) {
result.addAll(findFiles(dataSource, fileName, parentFile));
result.addAll(findFiles(dataSource, fileName, parent));
}
return result;
}
/**
* Finds a set of localFiles that meets the name criteria.
* Finds all files and directories with a given file name in a given data
* source (image, local/logical files set, etc.). The name search is for
* full or partial matches and is case insensitive (a case insensitive SQL
* LIKE clause is used to query the case database).
*
* @param dataSource Root data source to limit search results to (Image,
* VirtualDirectory, etc.).
* @param fileName Pattern of the name of the file or directory to match
* (case insensitive, used in LIKE SQL statement).
* @param dataSource The data source.
* @param fileName The full or partial file name.
*
* @return a list of AbstractFile for localFiles/directories whose name
* matches the given fileName
* @return The matching files and directories.
*
* @throws TskCoreException if there is a problem querying the case
* database.
*/
public synchronized List<AbstractFile> findFiles(Content dataSource, String fileName) throws TskCoreException {
if (tskCase == null) {
throw new TskCoreException(NbBundle.getMessage(this.getClass(), "FileManager.findFiles.exception.msg"));
if (null == caseDb) {
throw new TskCoreException("File manager has been closed");
}
return tskCase.findFiles(dataSource, fileName);
return caseDb.findFiles(dataSource, fileName);
}
/**
* Finds a set of localFiles that meets the name criteria.
* Finds all files and directories with a given file name and parent file or
* directory name in a given data source (image, local/logical files set,
* etc.). The name searches are for full or partial matches and are case
* insensitive (a case insensitive SQL LIKE clause is used to query the case
* database).
*
* @param dataSource Root data source to limit search results to (Image,
* VirtualDirectory, etc.).
* @param fileName Pattern of the name of the file or directory to match
* (case insensitive, used in LIKE SQL statement).
* @param dirName Pattern of the name of the parent directory to use as
* the root of the search (case insensitive, used in LIKE
* SQL statement).
* @param dataSource The data source.
* @param fileName The full or partial file name.
* @param parentName The full or partial parent file or directory name.
*
* @return a list of AbstractFile for localFiles/directories whose name
* matches fileName and whose parent directory contains dirName.
* @return The matching files and directories.
*
* @throws TskCoreException if there is a problem querying the case
* database.
*/
public synchronized List<AbstractFile> findFiles(Content dataSource, String fileName, String dirName) throws TskCoreException {
if (tskCase == null) {
throw new TskCoreException(NbBundle.getMessage(this.getClass(), "FileManager.findFiles2.exception.msg"));
public synchronized List<AbstractFile> findFiles(Content dataSource, String fileName, String parentName) throws TskCoreException {
if (null == caseDb) {
throw new TskCoreException("File manager has been closed");
}
return tskCase.findFiles(dataSource, fileName, dirName);
return caseDb.findFiles(dataSource, fileName, parentName);
}
/**
* Finds a set of localFiles that meets the name criteria.
* Finds all files and directories with a given file name and given parent
* file or directory in a given data source (image, local/logical files set,
* etc.). The name search is for full or partial matches and is case
* insensitive (a case insensitive SQL LIKE clause is used to query the case
* database).
*
* @param dataSource Root data source to limit search results to (Image,
* VirtualDirectory, etc.).
* @param fileName Pattern of the name of the file or directory to match
* (case insensitive, used in LIKE SQL statement).
* @param parentFile Object of root/parent directory to restrict search to.
* @param dataSource The data source.
* @param fileName The full or partial file name.
* @param parent The parent file or directory.
*
* @return a list of AbstractFile for localFiles/directories whose name
* matches fileName and that were inside a directory described by
* parentFsContent.
* @return The matching files and directories.
*
* @throws TskCoreException if there is a problem querying the case
* database.
*/
public synchronized List<AbstractFile> findFiles(Content dataSource, String fileName, AbstractFile parentFile) throws TskCoreException {
if (tskCase == null) {
throw new TskCoreException(NbBundle.getMessage(this.getClass(), "FileManager.findFiles3.exception.msg"));
public synchronized List<AbstractFile> findFiles(Content dataSource, String fileName, AbstractFile parent) throws TskCoreException {
if (null == caseDb) {
throw new TskCoreException("File manager has been closed");
}
return findFiles(dataSource, fileName, parentFile.getName());
return findFiles(dataSource, fileName, parent.getName());
}
/**
* @param dataSource data source Content (Image, parent-less
* VirtualDirectory) where to find localFiles
* @param filePath The full path to the file(s) of interest. This can
* optionally include the image and volume names.
* Finds all files and directories with a given file name and path in a
* given data source (image, local/logical files set, etc.). The name search
* is for full or partial matches and is case insensitive (a case
* insensitive SQL LIKE clause is used to query the case database). Any path
* components at the volume level and above are removed for the search.
*
* @return a list of AbstractFile that have the given file path.
* @param dataSource The data source.
* @param fileName The full or partial file name.
* @param filePath The file path (path components volume at the volume
* level or above will be removed).
*
* @return The matching files and directories.
*
* @throws TskCoreException if there is a problem querying the case
* database.
*/
public synchronized List<AbstractFile> openFiles(Content dataSource, String filePath) throws TskCoreException {
if (tskCase == null) {
throw new TskCoreException(NbBundle.getMessage(this.getClass(), "FileManager.openFiles.exception.msg"));
if (null == caseDb) {
throw new TskCoreException("File manager has been closed");
}
return tskCase.openFiles(dataSource, filePath);
return caseDb.openFiles(dataSource, filePath);
}
/**
* Creates a derived file, adds it to the database and returns it.
* Adds a derived file to the case.
*
* @param fileName file name the derived file
* @param localPath local path of the derived file, including the file
* name. The path is relative to the case folder.
* @param size size of the derived file in bytes
* @param ctime
* @param crtime
* @param atime
* @param mtime
* @param isFile whether a file or directory, true if a file
* @param parentFile the parent file object this the new file was
* derived from, either a fs file or parent derived
* file/dikr\\r
* @param rederiveDetails details needed to re-derive file (will be specific
* to the derivation method), currently unused
* @param toolName name of derivation method/tool, currently unused
* @param toolVersion version of derivation method/tool, currently
* unused
* @param otherDetails details of derivation method/tool, currently
* unused
* @param fileName The name of the file.
* @param localPath The local path of the file, relative to the case
* folder and including the file name.
* @param size The size of the file in bytes.
* @param ctime The change time of the file.
* @param crtime The create time of the file
* @param atime The accessed time of the file.
* @param mtime The modified time of the file.
* @param isFile True if a file, false if a directory.
* @param parentFile The parent file from which the file was derived.
* @param rederiveDetails The details needed to re-derive file (will be
* specific to the derivation method), currently
* unused.
* @param toolName The name of the derivation method or tool,
* currently unused.
* @param toolVersion The version of the derivation method or tool,
* currently unused.
* @param otherDetails Other details of the derivation method or tool,
* currently unused.
*
* @return newly created derived file object added to the database
*
* @throws TskCoreException exception thrown if the object creation failed
* due to a critical system error or of the file
* manager has already been closed
* @return A DerivedFile object representing the derived file.
*
* @throws TskCoreException if there is a problem adding the file to the
* case database.
*/
public synchronized DerivedFile addDerivedFile(String fileName, String localPath, long size,
public synchronized DerivedFile addDerivedFile(String fileName,
String localPath,
long size,
long ctime, long crtime, long atime, long mtime,
boolean isFile, AbstractFile parentFile,
boolean isFile,
AbstractFile parentFile,
String rederiveDetails, String toolName, String toolVersion, String otherDetails) throws TskCoreException {
if (tskCase == null) {
throw new TskCoreException(NbBundle.getMessage(this.getClass(), "FileManager.addDerivedFile.exception.msg"));
if (null == caseDb) {
throw new TskCoreException("File manager has been closed");
}
return tskCase.addDerivedFile(fileName, localPath, size,
return caseDb.addDerivedFile(fileName, localPath, size,
ctime, crtime, atime, mtime,
isFile, parentFile, rederiveDetails, toolName, toolVersion, otherDetails);
}
/**
* Adds a carved file to the VirtualDirectory '$CarvedFiles' in the volume
* or image given by systemId.
* Adds a carving result to the case database.
*
* @param carvedFileName the name of the carved file (containing appropriate
* extension)
* @param carvedFileSize size of the carved file to add
* @param systemId the ID of the parent volume or file system
* @param sectors a list of SectorGroups giving this sectors that
* make up this carved file.
* @param carvingResult The carving result (a set of carved files and their
* parent) to be added.
*
* @throws TskCoreException exception thrown when critical tsk error
* occurred and carved file could not be added
* @return A list of LayoutFile representations of the carved files.
*
* @throws TskCoreException If there is a problem completing a case database
* operation.
*/
public synchronized LayoutFile addCarvedFile(String carvedFileName, long carvedFileSize,
long systemId, List<TskFileRange> sectors) throws TskCoreException {
if (tskCase == null) {
throw new TskCoreException(NbBundle.getMessage(this.getClass(), "FileManager.addCarvedFile.exception.msg"));
public synchronized List<LayoutFile> addCarvedFiles(CarvingResult carvingResult) throws TskCoreException {
if (null == caseDb) {
throw new TskCoreException("File manager has been closed");
}
return tskCase.addCarvedFile(carvedFileName, carvedFileSize, systemId, sectors);
return caseDb.addCarvedFiles(carvingResult);
}
/**
* Adds a collection of carved localFiles to the VirtualDirectory
* '$CarvedFiles' in the volume or image given by systemId. Creates
* $CarvedFiles if it does not exist already.
*
* @param filesToAdd a list of CarvedFileContainer localFiles to add as
* carved localFiles
*
* @return List<LayoutFile> This is a list of the localFiles added to the
* database
*
* @throws org.sleuthkit.datamodel.TskCoreException
*/
public List<LayoutFile> addCarvedFiles(List<CarvedFileContainer> filesToAdd) throws TskCoreException {
if (tskCase == null) {
throw new TskCoreException(NbBundle.getMessage(this.getClass(), "FileManager.addCarvedFile.exception.msg"));
} else {
return tskCase.addCarvedFiles(filesToAdd);
}
}
/**
*
* Interface for receiving notifications on folders being added via a
* callback
* Interface for receiving a notification for each file or directory added
* to the case database by a FileManager add files operation.
*/
public interface FileAddProgressUpdater {
/**
* Called when new folders has been added
* Called after a file or directory is added to the case database.
*
* @param newFile the file/folder added to the Case
* @param An AbstractFile represeting the added file or directory.
*/
public void fileAdded(AbstractFile newFile);
}
/**
* Add a set of local/logical localFiles and dirs.
*
* @param localAbsPaths list of absolute paths to local localFiles and
* dirs
* @param addProgressUpdater notifier to receive progress notifications on
* folders added, or null if not used
*
* @return file set root VirtualDirectory contained containing all
* AbstractFile objects added
*
* @throws TskCoreException exception thrown if the object creation failed
* due to a critical system error or of the file
* manager has already been closed. There is no
* "revert" logic if one of the additions fails.
* The addition stops with the first error
* encountered.
*/
public synchronized VirtualDirectory addLocalFilesDirs(List<String> localAbsPaths, FileAddProgressUpdater addProgressUpdater) throws TskCoreException {
List<java.io.File> rootsToAdd;
try {
rootsToAdd = getFilesAndDirectories(localAbsPaths);
} catch (TskDataException ex) {
throw new TskCoreException(ex.getLocalizedMessage(), ex);
}
CaseDbTransaction trans = tskCase.beginTransaction();
// make a virtual top-level directory for this set of localFiles/dirs
final VirtualDirectory fileSetRootDir = addLocalFileSetRootDir(trans);
try {
// recursively add each item in the set
for (java.io.File localRootToAdd : rootsToAdd) {
AbstractFile localFileAdded = addLocalDirInt(trans, fileSetRootDir, localRootToAdd, addProgressUpdater);
if (localFileAdded == null) {
String msg = NbBundle
.getMessage(this.getClass(), "FileManager.addLocalFilesDirs.exception.cantAdd.msg",
localRootToAdd.getAbsolutePath());
logger.log(Level.SEVERE, msg);
throw new TskCoreException(msg);
} else {
//added.add(localFileAdded);
//send new content event
//for now reusing ingest events, in future this will be replaced by datamodel / observer sending out events
// @@@ Is this the right place for this? A directory tree refresh will be triggered, so this may be creating a race condition
// since the transaction is not yet committed.
IngestServices.getInstance().fireModuleContentEvent(new ModuleContentEvent(localFileAdded));
}
}
trans.commit();
} catch (TskCoreException ex) {
trans.rollback();
}
return fileSetRootDir;
void fileAdded(AbstractFile newFile);
}
/**
@ -419,20 +384,27 @@ public class FileManager implements Closeable {
* directory that does not exist or cannot be read.
*/
public synchronized LocalFilesDataSource addLocalFilesDataSource(String deviceId, String rootVirtualDirectoryName, String timeZone, List<String> localFilePaths, FileAddProgressUpdater progressUpdater) throws TskCoreException, TskDataException {
if (null == caseDb) {
throw new TskCoreException("File manager has been closed");
}
List<java.io.File> localFiles = getFilesAndDirectories(localFilePaths);
CaseDbTransaction trans = null;
try {
String rootDirectoryName = rootVirtualDirectoryName;
int newLocalFilesSetCount = curNumFileSets + 1;
if (rootVirtualDirectoryName.isEmpty()) {
rootDirectoryName = VirtualDirectoryNode.LOGICAL_FILE_SET_PREFIX + newLocalFilesSetCount;
if (rootDirectoryName.isEmpty()) {
rootDirectoryName = generateFilesDataSourceName(caseDb);
}
trans = tskCase.beginTransaction();
LocalFilesDataSource dataSource = tskCase.addLocalFilesDataSource(deviceId, rootDirectoryName, timeZone, trans);
/*
* Add the root virtual directory and its local/logical file
* children to the case database.
*/
trans = caseDb.beginTransaction();
LocalFilesDataSource dataSource = caseDb.addLocalFilesDataSource(deviceId, rootDirectoryName, timeZone, trans);
VirtualDirectory rootDirectory = dataSource.getRootDirectory();
List<AbstractFile> filesAdded = new ArrayList<>();
for (java.io.File localFile : localFiles) {
AbstractFile fileAdded = addLocalDirInt(trans, rootDirectory, localFile, progressUpdater);
AbstractFile fileAdded = addLocalFile(trans, rootDirectory, localFile, progressUpdater);
if (null != fileAdded) {
filesAdded.add(fileAdded);
} else {
@ -440,13 +412,16 @@ public class FileManager implements Closeable {
}
}
trans.commit();
if (rootVirtualDirectoryName.isEmpty()) {
curNumFileSets = newLocalFilesSetCount;
}
/*
* Publish content added events for the added files and directories.
*/
for (AbstractFile fileAdded : filesAdded) {
IngestServices.getInstance().fireModuleContentEvent(new ModuleContentEvent(fileAdded));
}
return dataSource;
} catch (TskCoreException ex) {
if (null != trans) {
trans.rollback();
@ -455,6 +430,34 @@ public class FileManager implements Closeable {
}
}
/**
* Generates a name for the root virtual directory for the data source.
*
* NOTE: Although this method is guarded by the file manager's monitor,
* there is currently a minimal chance of default name duplication for
* multi-user cases with multiple FileManagers running on different nodes.
*
* @return A default name for a local/logical files data source of the form:
* LogicalFileSet[N].
*
* @throws TskCoreException If there is a problem querying the case
* database.
*/
private static synchronized String generateFilesDataSourceName(SleuthkitCase caseDb) throws TskCoreException {
int localFileDataSourcesCounter = 0;
try {
List<VirtualDirectory> localFileDataSources = caseDb.getVirtualDirectoryRoots();
for (VirtualDirectory vd : localFileDataSources) {
if (vd.getName().startsWith(VirtualDirectoryNode.LOGICAL_FILE_SET_PREFIX)) {
++localFileDataSourcesCounter;
}
}
return VirtualDirectoryNode.LOGICAL_FILE_SET_PREFIX + (localFileDataSourcesCounter + 1);
} catch (TskCoreException ex) {
throw new TskCoreException("Error querying for existing local file data sources with defualt names", ex);
}
}
/**
* Converts a list of local/logical file and/or directory paths to a list of
* file objects.
@ -472,7 +475,7 @@ public class FileManager implements Closeable {
for (String path : localFilePaths) {
java.io.File localFile = new java.io.File(path);
if (!localFile.exists() || !localFile.canRead()) {
throw new TskDataException(NbBundle.getMessage(this.getClass(), "FileManager.addLocalFilesDirs.exception.notReadable.msg", localFile.getAbsolutePath()));
throw new TskDataException(String.format("File at %s does not exist or cannot be read", localFile.getAbsolutePath()));
}
localFiles.add(localFile);
}
@ -480,130 +483,141 @@ public class FileManager implements Closeable {
}
/**
* Adds a new virtual directory root object with FileSet X name and
* consecutive sequence number characteristic to every add operation
*
* @return the virtual dir root container created
*
* @throws TskCoreException
*/
private VirtualDirectory addLocalFileSetRootDir(CaseDbTransaction trans) throws TskCoreException {
VirtualDirectory created = null;
int newFileSetCount = curNumFileSets + 1;
final String fileSetName = VirtualDirectoryNode.LOGICAL_FILE_SET_PREFIX + newFileSetCount;
try {
created = tskCase.addVirtualDirectory(0, fileSetName, trans);
curNumFileSets = newFileSetCount;
} catch (TskCoreException ex) {
String msg = NbBundle
.getMessage(this.getClass(), "FileManager.addLocalFileSetRootDir.exception.errCreateDir.msg",
fileSetName);
logger.log(Level.SEVERE, msg, ex);
throw new TskCoreException(msg, ex);
}
return created;
}
/**
* Helper (internal) method to recursively add contents of a folder. Node
* passed in can be a file or directory. Children of directories are added.
* Adds a file or directory of logical/local files data source to the case
* database, recursively adding the contents of directories.
*
* @param trans A case database transaction.
* @param parentVd Dir that is the parent of localFile
* @param localFile File/Dir that we are adding
* @param parentDirectory The root virtual direcotry of the data source.
* @param localFile The local/logical file or directory.
* @param addProgressUpdater notifier to receive progress notifications on
* folders added, or null if not used
*
* @returns File object of file added or new virtualdirectory for the
* directory.
* @throws TskCoreException
* @param progressUpdater Called after each file/directory is added to
* the case database.
*
* @return An AbstractFile representation of the local/logical file.
*
* @throws TskCoreException If there is a problem completing a database
* operation.
*/
private AbstractFile addLocalDirInt(CaseDbTransaction trans, VirtualDirectory parentVd,
java.io.File localFile, FileAddProgressUpdater addProgressUpdater) throws TskCoreException {
if (tskCase == null) {
throw new TskCoreException(
NbBundle.getMessage(this.getClass(), "FileManager.addLocalDirInt.exception.closed.msg"));
}
//final String localName = localDir.getName();
if (!localFile.exists()) {
throw new TskCoreException(
NbBundle.getMessage(this.getClass(), "FileManager.addLocalDirInt.exception.doesntExist.msg",
localFile.getAbsolutePath()));
}
if (!localFile.canRead()) {
throw new TskCoreException(
NbBundle.getMessage(this.getClass(), "FileManager.addLocalDirInt.exception.notReadable.msg",
localFile.getAbsolutePath()));
}
private AbstractFile addLocalFile(CaseDbTransaction trans, VirtualDirectory parentDirectory, java.io.File localFile, FileAddProgressUpdater progressUpdater) throws TskCoreException {
if (localFile.isDirectory()) {
//create virtual folder (we don't have a notion of a 'local folder')
final VirtualDirectory childVd = tskCase.addVirtualDirectory(parentVd.getId(), localFile.getName(), trans);
if (childVd != null && addProgressUpdater != null) {
addProgressUpdater.fileAdded(childVd);
}
//add children recursively
final java.io.File[] childrenFiles = localFile.listFiles();
if (childrenFiles != null) {
for (java.io.File childFile : childrenFiles) {
addLocalDirInt(trans, childVd, childFile, addProgressUpdater);
/*
* Add the directory as a virtual directory.
*/
VirtualDirectory virtualDirectory = caseDb.addVirtualDirectory(parentDirectory.getId(), localFile.getName(), trans);
progressUpdater.fileAdded(virtualDirectory);
/*
* Add its children, if any.
*/
final java.io.File[] childFiles = localFile.listFiles();
if (childFiles != null && childFiles.length > 0) {
for (java.io.File childFile : childFiles) {
addLocalFile(trans, virtualDirectory, childFile, progressUpdater);
}
}
return childVd;
return virtualDirectory;
} else {
//add leaf file, base case
return this.addLocalFileInt(parentVd, localFile, trans);
return caseDb.addLocalFile(localFile.getName(), localFile.getAbsolutePath(), localFile.length(),
0, 0, 0, 0,
localFile.isFile(), parentDirectory, trans);
}
}
/**
* Adds a single local/logical file to the case. Adds it to the database.
* Does not refresh the views of data. Assumes that the local file exists
* and can be read. This checking is done by addLocalDirInt().
* Closes the file manager.
*
* @param parentFile parent file object container (such as virtual
* directory, another local file, or fscontent File),
* @param localFile File that we are adding
* @param trans A case database transaction.
*
* @return newly created local file object added to the database
*
* @throws TskCoreException exception thrown if the object creation failed
* due to a critical system error or of the file
* manager has already been closed
* @throws IOException If there is a problem closing the file manager.
*/
private synchronized LocalFile addLocalFileInt(AbstractFile parentFile, java.io.File localFile, CaseDbTransaction trans) throws TskCoreException {
if (tskCase == null) {
throw new TskCoreException(
NbBundle.getMessage(this.getClass(), "FileManager.addLocalDirInt2.exception.closed.msg"));
}
long size = localFile.length();
boolean isFile = localFile.isFile();
long ctime = 0;
long crtime = 0;
long atime = 0;
long mtime = 0;
String fileName = localFile.getName();
LocalFile lf = tskCase.addLocalFile(fileName, localFile.getAbsolutePath(), size,
ctime, crtime, atime, mtime,
isFile, parentFile, trans);
return lf;
}
@Override
public synchronized void close() throws IOException {
tskCase = null;
caseDb = null;
}
/**
* Adds a set of local/logical files and/or directories to the case database
* as data source.
*
* @param localFilePaths A list of local/logical file and/or directory
* localFilePaths.
* @param progressUpdater Called after each file/directory is added to the
* case database.
*
* @return The root virtual directory for the local/logical files data
* source.
*
* @throws TskCoreException If any of the local file paths is for a file or
* directory that does not exist or cannot be read,
* or there is a problem completing a database
* operation.
* @deprecated Use addLocalFilesDataSource instead.
*/
@Deprecated
public synchronized VirtualDirectory addLocalFilesDirs(List<String> localFilePaths, FileAddProgressUpdater progressUpdater) throws TskCoreException {
if (null == caseDb) {
throw new TskCoreException("File manager has been closed");
}
try {
return addLocalFilesDataSource("", "", "", localFilePaths, progressUpdater).getRootDirectory();
} catch (TskDataException ex) {
throw new TskCoreException(ex.getLocalizedMessage(), ex);
}
}
/**
* Adds a carved file to the '$CarvedFiles' virtual directory of a data
* source, volume or file system.
*
* @param fileName The name of the file.
* @param fileSize The size of the file.
* @param parentObjId The object id of the parent data source, volume or
* file system.
* @param layout A list of the offsets and sizes that gives the layout
* of the file within its parent.
*
* @return A LayoutFile object representing the carved file.
*
* @throws TskCoreException if there is a problem adding the file to the
* case database.
* @deprecated Use List<LayoutFile> addCarvedFiles(CarvingResult
* carvingResult instead.
*/
@Deprecated
public synchronized LayoutFile addCarvedFile(String fileName, long fileSize, long parentObjId, List<TskFileRange> layout) throws TskCoreException {
if (null == caseDb) {
throw new TskCoreException("File manager has been closed");
}
Content parent = caseDb.getContentById(parentObjId);
List<CarvingResult.CarvedFile> carvedFiles = new ArrayList<>();
carvedFiles.add(new CarvingResult.CarvedFile(fileName, fileSize, layout));
List<LayoutFile> layoutFiles = caseDb.addCarvedFiles(new CarvingResult(parent, carvedFiles));
return layoutFiles.get(0);
}
/**
* Adds a collection of carved files to the '$CarvedFiles' virtual directory
* of a data source, volume or file system.
*
* @param A collection of CarvedFileContainer objects, one per carved file,
* all of which must have the same parent object id.
*
* @return A collection of LayoutFile object representing the carved files.
*
* @throws TskCoreException if there is a problem adding the files to the
* case database.
* @deprecated Use List<LayoutFile> addCarvedFiles(CarvingResult
* carvingResult instead.
*/
@Deprecated
public synchronized List<LayoutFile> addCarvedFiles(List<org.sleuthkit.datamodel.CarvedFileContainer> filesToAdd) throws TskCoreException {
if (null == caseDb) {
throw new TskCoreException("File manager has been closed");
}
return caseDb.addCarvedFiles(filesToAdd);
}
}

View File

@ -1,19 +1,18 @@
/*
*
* Autopsy Forensic Browser
*
* Copyright 2012-2015 Basis Technology Corp.
*
*
* Copyright 2011-2016 Basis Technology Corp.
* Contact: carrier <at> sleuthkit <dot> org
* Copyright 2012 42six Solutions.
* Contact: aebadirad <at> 42six <dot> com
* Project Contact/Architect: 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.
@ -31,7 +30,8 @@ import org.sleuthkit.autopsy.keywordsearchservice.KeywordSearchService;
import org.sleuthkit.datamodel.SleuthkitCase;
/**
* A class to manage various services.
* A collection of case-level services (e.g., file manager, tags manager,
* keyword search, blackboard).
*/
public class Services implements Closeable {
@ -41,36 +41,67 @@ public class Services implements Closeable {
private final KeywordSearchService keywordSearchService;
private final Blackboard blackboard;
public Services(SleuthkitCase tskCase) {
fileManager = new FileManager(tskCase);
/**
* Constructs a collection of case-level services (e.g., file manager, tags
* manager, keyword search, blackboard).
*
* @param caseDb The case database for the current case.
*/
public Services(SleuthkitCase caseDb) {
fileManager = new FileManager(caseDb);
services.add(fileManager);
tagsManager = new TagsManager(tskCase);
tagsManager = new TagsManager(caseDb);
services.add(tagsManager);
keywordSearchService = Lookup.getDefault().lookup(KeywordSearchService.class);
services.add(keywordSearchService);
blackboard = new Blackboard();
blackboard = new Blackboard(caseDb);
services.add(blackboard);
}
/**
* Gets the file manager service for the current case.
*
* @return The file manager service for the current case.
*/
public FileManager getFileManager() {
return fileManager;
}
/**
* Gets the tags manager service for the current case.
*
* @return The tags manager service for the current case.
*/
public TagsManager getTagsManager() {
return tagsManager;
}
/**
* Gets the keyword search service for the current case.
*
* @return The keyword search service for the current case.
*/
public KeywordSearchService getKeywordSearchService() {
return keywordSearchService;
}
/**
* Gets the blackboard service for the current case.
*
* @return The blackboard service for the current case.
*/
public Blackboard getBlackboard() {
return blackboard;
}
/**
* Closes the services for the current case.
*
* @throws IOException if there is a problem closing the services.
*/
@Override
public void close() throws IOException {
for (Closeable service : services) {

View File

@ -1,7 +1,7 @@
/*
* Autopsy Forensic Browser
*
* Copyright 2011-16 Basis Technology Corp.
* Copyright 2011-2016 Basis Technology Corp.
* Contact: carrier <at> sleuthkit <dot> org
*
* Licensed under the Apache License, Version 2.0 (the "License");
@ -45,7 +45,7 @@ public class TagsManager implements Closeable {
private static final Logger logger = Logger.getLogger(TagsManager.class.getName());
private static final String TAGS_SETTINGS_NAME = "Tags"; //NON-NLS
private static final String TAG_NAMES_SETTING_KEY = "TagNames"; //NON-NLS
private final SleuthkitCase caseDb;
private SleuthkitCase caseDb;
private final HashMap<String, TagName> uniqueTagNames = new HashMap<>();
private boolean tagNamesLoaded = false;
@ -53,8 +53,8 @@ public class TagsManager implements Closeable {
* Constructs a per case Autopsy service that manages the creation,
* updating, and deletion of tags applied to content and blackboard
* artifacts by users.
*
* @param caseDb The case database for the current case.
*
* @param caseDb The case database.
*/
TagsManager(SleuthkitCase caseDb) {
this.caseDb = caseDb;
@ -70,6 +70,9 @@ public class TagsManager implements Closeable {
* database.
*/
public synchronized List<TagName> getAllTagNames() throws TskCoreException {
if (null == caseDb) {
throw new TskCoreException("Tags manager has been closed");
}
lazyLoadExistingTagNames();
return caseDb.getAllTagNames();
}
@ -84,6 +87,9 @@ public class TagsManager implements Closeable {
* database.
*/
public synchronized List<TagName> getTagNamesInUse() throws TskCoreException {
if (null == caseDb) {
throw new TskCoreException("Tags manager has been closed");
}
lazyLoadExistingTagNames();
return caseDb.getTagNamesInUse();
}
@ -114,6 +120,9 @@ public class TagsManager implements Closeable {
* to the case database.
*/
public TagName addTagName(String displayName) throws TagNameAlreadyExistsException, TskCoreException {
if (null == caseDb) {
throw new TskCoreException("Tags manager has been closed");
}
return addTagName(displayName, "", TagName.HTML_COLOR.NONE);
}
@ -132,6 +141,9 @@ public class TagsManager implements Closeable {
* to the case database.
*/
public TagName addTagName(String displayName, String description) throws TagNameAlreadyExistsException, TskCoreException {
if (null == caseDb) {
throw new TskCoreException("Tags manager has been closed");
}
return addTagName(displayName, description, TagName.HTML_COLOR.NONE);
}
@ -151,6 +163,9 @@ public class TagsManager implements Closeable {
* to the case database.
*/
public synchronized TagName addTagName(String displayName, String description, TagName.HTML_COLOR color) throws TagNameAlreadyExistsException, TskCoreException {
if (null == caseDb) {
throw new TskCoreException("Tags manager has been closed");
}
lazyLoadExistingTagNames();
if (uniqueTagNames.containsKey(displayName)) {
throw new TagNameAlreadyExistsException();
@ -182,6 +197,9 @@ public class TagsManager implements Closeable {
* database.
*/
public ContentTag addContentTag(Content content, TagName tagName) throws TskCoreException {
if (null == caseDb) {
throw new TskCoreException("Tags manager has been closed");
}
return addContentTag(content, tagName, "", -1, -1);
}
@ -198,6 +216,9 @@ public class TagsManager implements Closeable {
* database.
*/
public ContentTag addContentTag(Content content, TagName tagName, String comment) throws TskCoreException {
if (null == caseDb) {
throw new TskCoreException("Tags manager has been closed");
}
return addContentTag(content, tagName, comment, -1, -1);
}
@ -218,10 +239,17 @@ public class TagsManager implements Closeable {
* the case database.
*/
public ContentTag addContentTag(Content content, TagName tagName, String comment, long beginByteOffset, long endByteOffset) throws IllegalArgumentException, TskCoreException {
if (null == caseDb) {
throw new TskCoreException("Tags manager has been closed");
}
ContentTag tag;
synchronized (this) {
lazyLoadExistingTagNames();
if (null == comment) {
throw new IllegalArgumentException("Passed null comment argument");
}
if (beginByteOffset >= 0 && endByteOffset >= 1) {
if (beginByteOffset > content.getSize() - 1) {
throw new IllegalArgumentException(NbBundle.getMessage(this.getClass(),
@ -261,6 +289,9 @@ public class TagsManager implements Closeable {
* case database.
*/
public void deleteContentTag(ContentTag tag) throws TskCoreException {
if (null == caseDb) {
throw new TskCoreException("Tags manager has been closed");
}
synchronized (this) {
lazyLoadExistingTagNames();
caseDb.deleteContentTag(tag);
@ -282,6 +313,9 @@ public class TagsManager implements Closeable {
* case database.
*/
public synchronized List<ContentTag> getAllContentTags() throws TskCoreException {
if (null == caseDb) {
throw new TskCoreException("Tags manager has been closed");
}
lazyLoadExistingTagNames();
return caseDb.getAllContentTags();
}
@ -297,6 +331,9 @@ public class TagsManager implements Closeable {
* the case database.
*/
public synchronized long getContentTagsCountByTagName(TagName tagName) throws TskCoreException {
if (null == caseDb) {
throw new TskCoreException("Tags manager has been closed");
}
lazyLoadExistingTagNames();
return caseDb.getContentTagsCountByTagName(tagName);
}
@ -312,6 +349,9 @@ public class TagsManager implements Closeable {
* case database.
*/
public synchronized ContentTag getContentTagByTagID(long tagID) throws TskCoreException {
if (null == caseDb) {
throw new TskCoreException("Tags manager has been closed");
}
lazyLoadExistingTagNames();
return caseDb.getContentTagByID(tagID);
}
@ -328,6 +368,9 @@ public class TagsManager implements Closeable {
* case database.
*/
public synchronized List<ContentTag> getContentTagsByTagName(TagName tagName) throws TskCoreException {
if (null == caseDb) {
throw new TskCoreException("Tags manager has been closed");
}
lazyLoadExistingTagNames();
return caseDb.getContentTagsByTagName(tagName);
}
@ -344,6 +387,9 @@ public class TagsManager implements Closeable {
* case database.
*/
public synchronized List<ContentTag> getContentTagsByContent(Content content) throws TskCoreException {
if (null == caseDb) {
throw new TskCoreException("Tags manager has been closed");
}
lazyLoadExistingTagNames();
return caseDb.getContentTagsByContent(content);
}
@ -361,6 +407,9 @@ public class TagsManager implements Closeable {
* database.
*/
public BlackboardArtifactTag addBlackboardArtifactTag(BlackboardArtifact artifact, TagName tagName) throws TskCoreException {
if (null == caseDb) {
throw new TskCoreException("Tags manager has been closed");
}
return addBlackboardArtifactTag(artifact, tagName, "");
}
@ -378,9 +427,15 @@ public class TagsManager implements Closeable {
* database.
*/
public BlackboardArtifactTag addBlackboardArtifactTag(BlackboardArtifact artifact, TagName tagName, String comment) throws TskCoreException {
if (null == caseDb) {
throw new TskCoreException("Tags manager has been closed");
}
BlackboardArtifactTag tag;
synchronized (this) {
lazyLoadExistingTagNames();
if (null == comment) {
throw new IllegalArgumentException("Passed null comment argument");
}
tag = caseDb.addBlackboardArtifactTag(artifact, tagName, comment);
}
@ -401,6 +456,9 @@ public class TagsManager implements Closeable {
* case database.
*/
public void deleteBlackboardArtifactTag(BlackboardArtifactTag tag) throws TskCoreException {
if (null == caseDb) {
throw new TskCoreException("Tags manager has been closed");
}
synchronized (this) {
lazyLoadExistingTagNames();
caseDb.deleteBlackboardArtifactTag(tag);
@ -422,6 +480,9 @@ public class TagsManager implements Closeable {
* case database.
*/
public synchronized List<BlackboardArtifactTag> getAllBlackboardArtifactTags() throws TskCoreException {
if (null == caseDb) {
throw new TskCoreException("Tags manager has been closed");
}
lazyLoadExistingTagNames();
return caseDb.getAllBlackboardArtifactTags();
}
@ -438,6 +499,9 @@ public class TagsManager implements Closeable {
* the case database.
*/
public synchronized long getBlackboardArtifactTagsCountByTagName(TagName tagName) throws TskCoreException {
if (null == caseDb) {
throw new TskCoreException("Tags manager has been closed");
}
lazyLoadExistingTagNames();
return caseDb.getBlackboardArtifactTagsCountByTagName(tagName);
}
@ -453,6 +517,9 @@ public class TagsManager implements Closeable {
* case database.
*/
public synchronized BlackboardArtifactTag getBlackboardArtifactTagByTagID(long tagID) throws TskCoreException {
if (null == caseDb) {
throw new TskCoreException("Tags manager has been closed");
}
lazyLoadExistingTagNames();
return caseDb.getBlackboardArtifactTagByID(tagID);
}
@ -469,6 +536,9 @@ public class TagsManager implements Closeable {
* case database.
*/
public synchronized List<BlackboardArtifactTag> getBlackboardArtifactTagsByTagName(TagName tagName) throws TskCoreException {
if (null == caseDb) {
throw new TskCoreException("Tags manager has been closed");
}
lazyLoadExistingTagNames();
return caseDb.getBlackboardArtifactTagsByTagName(tagName);
}
@ -485,16 +555,25 @@ public class TagsManager implements Closeable {
* case database.
*/
public synchronized List<BlackboardArtifactTag> getBlackboardArtifactTagsByArtifact(BlackboardArtifact artifact) throws TskCoreException {
if (null == caseDb) {
throw new TskCoreException("Tags manager has been closed");
}
lazyLoadExistingTagNames();
return caseDb.getBlackboardArtifactTagsByArtifact(artifact);
}
/**
* Saves the avaialble tag names to secondary storage.
* Closes the tags manager, saving the avaialble tag names to secondary
* storage.
*
* @throws IOException If there is a problem closing the tags manager.
* @deprecated Tags manager clients should not close the tags manager.
*/
@Override
@Deprecated
public synchronized void close() throws IOException {
saveTagNamesToTagsSettings();
caseDb = null;
}
/**

View File

@ -5,12 +5,12 @@
<!-- ======================================================
General
====================================================== -->
<attr name="Toolbars\File\org-sleuthkit-autopsy-casemodule-CaseCloseAction.instance\iconBase" stringvalue="org/sleuthkit/autopsy/images/close-icon.gif"/>
<attr name="Menu\File\org-netbeans-modules-print-action-PageSetupAction.shadow_hidden\position" intvalue="300"/>
<attr name="Menu\File\org-netbeans-modules-print-action-PrintAction.shadow_hidden\position" intvalue="500"/>
<!--<attr name="Menu\File\Separator2.instance_hidden\position" intvalue="100"/>
<attr name="Menu\File\Separator3.instance_hidden\position" intvalue="200"/>
<attr name="Menu\File\Separator4.instance_hidden\position" intvalue="400"/>-->
<attr name="Toolbars\Case\org-sleuthkit-autopsy-casemodule-CaseCloseAction.instance\iconBase" stringvalue="org/sleuthkit/autopsy/images/close-icon.gif"/>
<attr name="Menu\Case\org-netbeans-modules-print-action-PageSetupAction.shadow_hidden\position" intvalue="300"/>
<attr name="Menu\Case\org-netbeans-modules-print-action-PrintAction.shadow_hidden\position" intvalue="500"/>
<!--<attr name="Menu\Case\Separator2.instance_hidden\position" intvalue="100"/>
<attr name="Menu\Case\Separator3.instance_hidden\position" intvalue="200"/>
<attr name="Menu\Case\Separator4.instance_hidden\position" intvalue="400"/>-->
<folder name="OptionsDialog">
<!--<folder name="General.instance_hidden"/>-->
@ -39,7 +39,7 @@
Actions
====================================================== -->
<folder name="Actions">
<folder name="File">
<folder name="Case">
<file name="org-sleuthkit-autopsy-casemodule-AddImageAction.instance"/>
<file name="org-sleuthkit-autopsy-casemodule-CaseCloseAction.instance"/>
<file name="org-sleuthkit-autopsy-casemodule-CaseNewAction.instance">
@ -145,24 +145,25 @@
<file name="GoTo_hidden"/>
<file name="Reports_hidden"/>
<file name="Edit_hidden"/>
<folder name="File">
<file name="File_hidden"/>
<folder name="Case">
<file name="org-sleuthkit-autopsy-casemodule-CaseNewAction.shadow">
<attr name="originalFile" stringvalue="Actions/File/org-sleuthkit-autopsy-casemodule-CaseNewAction.instance"/>
<attr name="originalFile" stringvalue="Actions/Case/org-sleuthkit-autopsy-casemodule-CaseNewAction.instance"/>
<attr name="position" intvalue="100"/>
</file>
<file name="org-sleuthkit-autopsy-casemodule-CaseOpenAction.shadow">
<attr name="originalFile" stringvalue="Actions/File/org-sleuthkit-autopsy-casemodule-CaseOpenAction.instance"/>
<attr name="originalFile" stringvalue="Actions/Case/org-sleuthkit-autopsy-casemodule-CaseOpenAction.instance"/>
<attr name="position" intvalue="101"/>
</file>
<folder name="OpenRecentCase">
<folder name="Open Recent Case">
<attr name="position" intvalue="102"/>
<attr name="SystemFileSystem.localizingBundle" stringvalue="org.sleuthkit.autopsy.casemodule.Bundle"/>
<file name="org-sleuthkit-autopsy-casemodule-RecentCasesAction.shadow">
<attr name="originalFile" stringvalue="Actions/File/org-sleuthkit-autopsy-casemodule-RecentCases.instance"/>
<attr name="originalFile" stringvalue="Actions/Case/org-sleuthkit-autopsy-casemodule-RecentCases.instance"/>
</file>
</folder>
<file name="org-sleuthkit-autopsy-casemodule-CaseCloseAct.shadow">
<attr name="originalFile" stringvalue="Actions/File/org-sleuthkit-autopsy-casemodule-CaseCloseAction.instance"/>
<attr name="originalFile" stringvalue="Actions/Case/org-sleuthkit-autopsy-casemodule-CaseCloseAction.instance"/>
<attr name="position" intvalue="103"/>
</file>
<file name="org-sleuthkit-autopsy-casemodule-AddImage-separatorBefore.instance">
@ -170,7 +171,7 @@
<attr name="position" intvalue="200"/>
</file>
<file name="org-sleuthkit-autopsy-casemodule-AddImageAction.shadow">
<attr name="originalFile" stringvalue="Actions/File/org-sleuthkit-autopsy-casemodule-AddImageAction.instance"/>
<attr name="originalFile" stringvalue="Actions/Case/org-sleuthkit-autopsy-casemodule-AddImageAction.instance"/>
<attr name="position" intvalue="201"/>
</file>
<file name="org-sleuthkit-autopsy-casemodule-AddImage-separatorAfter.instance">
@ -182,7 +183,7 @@
<attr name="position" intvalue="300"/>
</file>
<file name="org-sleuthkit-autopsy-casemodule-CasePropertiesAction.shadow">
<attr name="originalFile" stringvalue="Actions/File/org-sleuthkit-autopsy-casemodule-CasePropertiesAction.instance"/>
<attr name="originalFile" stringvalue="Actions/Case/org-sleuthkit-autopsy-casemodule-CasePropertiesAction.instance"/>
<attr name="position" intvalue="301"/>
</file>
<file name="org-netbeans-modules-print-action-PageSetupAction.shadow_hidden"/>
@ -361,7 +362,8 @@
<file name="Clipboard_hidden"/>
<file name="Memory_hidden"/>
<file name="UndoRedo_hidden"/>
<folder name="File">
<file name="File_hidden"/>
<folder name="Case">
<file name="org-sleuthkit-autopsy-casemodule-CaseCloseAction.instance">
<attr name="delegate" newvalue="org.sleuthkit.autopsy.casemodule.CaseCloseAction"/>
<attr name="displayName" bundlevalue="org.sleuthkit.autopsy.casemodule.Bundle#CTL_CaseCloseAct"/>
@ -385,11 +387,11 @@
<file name="org-sleuthkit-autopsy-report-ReportWizardAction.shadow">
<attr name="displayName" bundlevalue="org.sleuthkit.autopsy.report.Bundle#Toolbars/Reports/org-sleuthkit-autopsy-report-ReportWizardAction.shadow"/>
<attr name="originalFile" stringvalue="Actions/Tools/org-sleuthkit-autopsy-report-ReportWizardAction.instance"/>
<attr name="position" intvalue="102"/>
<attr name="position" intvalue="103"/>
</file>
</folder>
<folder name="Ingest">
<attr intvalue="103" name="position"/>
<attr intvalue="104" name="position"/>
<file name="org-sleuthkit-autopsy-ingest-IngestMessagesAction.shadow">
<attr name="originalFile" stringvalue="Actions/Tools/org-sleuthkit-autopsy-ingest-IngestMessagesAction.instance"/>
</file>
@ -404,10 +406,10 @@
====================================================== -->
<folder name="Shortcuts">
<file name="D-N.shadow">
<attr name="originalFile" stringvalue="Actions/File/org-sleuthkit-autopsy-casemodule-CaseNewAction.instance"/>
<attr name="originalFile" stringvalue="Actions/Case/org-sleuthkit-autopsy-casemodule-CaseNewAction.instance"/>
</file>
<file name="D-O.shadow">
<attr name="originalFile" stringvalue="Actions/File/org-sleuthkit-autopsy-casemodule-CaseOpenAction.instance"/>
<attr name="originalFile" stringvalue="Actions/Case/org-sleuthkit-autopsy-casemodule-CaseOpenAction.instance"/>
</file>
</folder>

View File

@ -3,7 +3,7 @@
<Form version="1.5" maxVersion="1.8" type="org.netbeans.modules.form.forminfo.JPanelFormInfo">
<Properties>
<Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[5, 5]"/>
<Dimension value="[0, 5]"/>
</Property>
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[5, 5]"/>
@ -56,6 +56,9 @@
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/corecomponents/Bundle.properties" key="DataResultPanel.directoryTablePath.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
<Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[5, 14]"/>
</Property>
</Properties>
</Component>
<Component class="javax.swing.JLabel" name="numberMatchLabel">
@ -73,6 +76,11 @@
</Properties>
</Component>
<Container class="javax.swing.JTabbedPane" name="dataResultTabbedPanel">
<Properties>
<Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[0, 5]"/>
</Property>
</Properties>
<Layout class="org.netbeans.modules.form.compat2.layouts.support.JTabbedPaneSupportLayout"/>
</Container>

View File

@ -1,7 +1,7 @@
/*
* Autopsy Forensic Browser
*
* Copyright 2013 Basis Technology Corp.
* Copyright 2011-2016 Basis Technology Corp.
* Contact: carrier <at> sleuthkit <dot> org
*
* Licensed under the Apache License, Version 2.0 (the "License");
@ -56,6 +56,8 @@ import org.sleuthkit.autopsy.coreutils.Logger;
public class DataResultPanel extends javax.swing.JPanel implements DataResult, ChangeListener {
private ExplorerManager explorerManager;
private ExplorerManagerNodeSelectionListener emNodeSelectionListener;
private Node rootNode;
private PropertyChangeSupport pcs;
@ -232,7 +234,8 @@ public class DataResultPanel extends javax.swing.JPanel implements DataResult, C
// can push the selections both to its child DataResultViewers and to a DataContent object.
// The default DataContent object is a DataContentTopComponent in the data content mode (area),
// and is the parent of a DataContentPanel that hosts a set of DataContentViewers.
explorerManager.addPropertyChangeListener(new ExplorerManagerNodeSelectionListener());
emNodeSelectionListener = new ExplorerManagerNodeSelectionListener();
explorerManager.addPropertyChangeListener(emNodeSelectionListener);
}
// Add all the DataContentViewer to the tabbed pannel.
@ -336,6 +339,11 @@ public class DataResultPanel extends javax.swing.JPanel implements DataResult, C
pcs.removePropertyChangeListener(pcl[i]);
}
if (null != explorerManager && null != emNodeSelectionListener) {
explorerManager.removePropertyChangeListener(emNodeSelectionListener);
explorerManager = null;
}
// clear all set nodes
for (UpdateWrapper drv : this.viewers) {
drv.setNode(null);
@ -536,26 +544,29 @@ public class DataResultPanel extends javax.swing.JPanel implements DataResult, C
matchLabel = new javax.swing.JLabel();
dataResultTabbedPanel = new javax.swing.JTabbedPane();
setMinimumSize(new java.awt.Dimension(5, 5));
setMinimumSize(new java.awt.Dimension(0, 5));
setPreferredSize(new java.awt.Dimension(5, 5));
org.openide.awt.Mnemonics.setLocalizedText(directoryTablePath, org.openide.util.NbBundle.getMessage(DataResultPanel.class, "DataResultPanel.directoryTablePath.text")); // NOI18N
directoryTablePath.setMinimumSize(new java.awt.Dimension(5, 14));
org.openide.awt.Mnemonics.setLocalizedText(numberMatchLabel, org.openide.util.NbBundle.getMessage(DataResultPanel.class, "DataResultPanel.numberMatchLabel.text")); // NOI18N
org.openide.awt.Mnemonics.setLocalizedText(matchLabel, org.openide.util.NbBundle.getMessage(DataResultPanel.class, "DataResultPanel.matchLabel.text")); // NOI18N
dataResultTabbedPanel.setMinimumSize(new java.awt.Dimension(0, 5));
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(directoryTablePath)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 518, Short.MAX_VALUE)
.addComponent(directoryTablePath, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addComponent(numberMatchLabel)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(matchLabel))
.addComponent(dataResultTabbedPanel)
.addComponent(dataResultTabbedPanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
);
layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
@ -564,9 +575,9 @@ public class DataResultPanel extends javax.swing.JPanel implements DataResult, C
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(numberMatchLabel)
.addComponent(matchLabel))
.addComponent(directoryTablePath))
.addComponent(directoryTablePath, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
.addGap(0, 0, 0)
.addComponent(dataResultTabbedPanel, javax.swing.GroupLayout.DEFAULT_SIZE, 340, Short.MAX_VALUE))
.addComponent(dataResultTabbedPanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
);
}// </editor-fold>//GEN-END:initComponents
// Variables declaration - do not modify//GEN-BEGIN:variables

View File

@ -1,4 +1,4 @@
/*
/*
* Autopsy Forensic Browser
*
* Copyright 2012-16 Basis Technology Corp.
@ -31,6 +31,7 @@ import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Paths;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
@ -89,7 +90,7 @@ public class ImageUtils {
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"});
private static final List<String> SUPPORTED_IMAGE_EXTENSIONS;
private static final List<String> SUPPORTED_IMAGE_EXTENSIONS = new ArrayList<>();
private static final SortedSet<String> SUPPORTED_IMAGE_MIME_TYPES;
private static final boolean openCVLoaded;
@ -124,7 +125,8 @@ public class ImageUtils {
}
openCVLoaded = openCVLoadedTemp;
SUPPORTED_IMAGE_EXTENSIONS = Arrays.asList(ImageIO.getReaderFileSuffixes());
SUPPORTED_IMAGE_EXTENSIONS.addAll(Arrays.asList(ImageIO.getReaderFileSuffixes()));
SUPPORTED_IMAGE_EXTENSIONS.add("tec"); // Add JFIF .tec files
SUPPORTED_IMAGE_MIME_TYPES = new TreeSet<>(Arrays.asList(ImageIO.getReaderMIMETypes()));
/*
* special cases and variants that we support, but don't get registered
@ -376,6 +378,45 @@ public class ImageUtils {
}
}
/**
* Find the offset for the first Start Of Image marker (0xFFD8) in JFIF,
* allowing for leading End Of Image markers.
*
* @param file the AbstractFile to parse
*
* @return Offset of first Start Of Image marker, or 0 if none found. This
* will let ImageIO try to open it from offset 0.
*/
private static long getJfifStartOfImageOffset(AbstractFile file) {
byte[] fileHeaderBuffer;
long length;
try {
length = file.getSize();
if (length % 2 != 0) {
length -= 1; // Make it an even number so we can parse two bytes at a time
}
if (length >= 1024) {
length = 1024;
}
fileHeaderBuffer = readHeader(file, (int) length); // read up to first 1024 bytes
} catch (TskCoreException ex) {
// Couldn't read header. Let ImageIO try it.
return 0;
}
if (fileHeaderBuffer != null) {
for (int index = 0; index < length; index += 2) {
// Look for Start Of Image marker and return the index when it's found
if ((fileHeaderBuffer[index] == (byte) 0xFF) && (fileHeaderBuffer[index + 1] == (byte) 0xD8)) {
return index;
}
}
}
// Didn't match JFIF. Let ImageIO try to open it from offset 0.
return 0;
}
/**
* Check if the given file is a png based on header.
*
@ -711,7 +752,7 @@ public class ImageUtils {
*/
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"; //NON-NLS
private static final String IMAGEIO_COULD_NOT_READ_UNSUPPORTED_OR_CORRUPT = "ImageIO could not read {0}. It may be unsupported or corrupt"; //NON-NLS
final AbstractFile file;
// private ImageReader reader;
@ -726,8 +767,17 @@ public class ImageUtils {
if (image.isError() == false) {
return image;
}
//fall through to default image reading code if there was an error
} else if (file.getNameExtension().equalsIgnoreCase("tec")) { //NON-NLS
ReadContentInputStream readContentInputStream = new ReadContentInputStream(file);
// Find first Start Of Image marker
readContentInputStream.seek(getJfifStartOfImageOffset(file));
//use JavaFX to directly read .tec files
javafx.scene.image.Image image = new javafx.scene.image.Image(new BufferedInputStream(readContentInputStream));
if (image.isError() == false) {
return image;
}
}
//fall through to default image reading code if there was an error
if (isCancelled()) {
return null;
}
@ -747,7 +797,7 @@ public class ImageUtils {
try {
bufferedImage = imageReader.read(0, param); //should always be same bufferedImage object
} catch (IOException iOException) {
LOGGER.log(Level.WARNING, IMAGEIO_COULD_NOT_READ_UNSUPPORTE_OR_CORRUPT + ": " + iOException.toString(), ImageUtils.getContentPathSafe(file)); //NON-NLS
LOGGER.log(Level.WARNING, IMAGEIO_COULD_NOT_READ_UNSUPPORTED_OR_CORRUPT + ": " + iOException.toString(), ImageUtils.getContentPathSafe(file)); //NON-NLS
} finally {
imageReader.removeIIOReadProgressListener(ReadImageTaskBase.this);
}
@ -755,7 +805,8 @@ public class ImageUtils {
return null;
}
return SwingFXUtils.toFXImage(bufferedImage, null);
});
}
);
}
@Override
@ -775,12 +826,10 @@ public class ImageUtils {
try {
javafx.scene.image.Image fxImage = get();
if (fxImage == null) {
LOGGER.log(Level.WARNING, IMAGEIO_COULD_NOT_READ_UNSUPPORTE_OR_CORRUPT, ImageUtils.getContentPathSafe(file));
} else {
if (fxImage.isError()) {
//if there was somekind of error, log it
LOGGER.log(Level.WARNING, IMAGEIO_COULD_NOT_READ_UNSUPPORTE_OR_CORRUPT + ": " + ObjectUtils.toString(fxImage.getException()), ImageUtils.getContentPathSafe(file));
}
LOGGER.log(Level.WARNING, IMAGEIO_COULD_NOT_READ_UNSUPPORTED_OR_CORRUPT, ImageUtils.getContentPathSafe(file));
} else if (fxImage.isError()) {
//if there was somekind of error, log it
LOGGER.log(Level.WARNING, IMAGEIO_COULD_NOT_READ_UNSUPPORTED_OR_CORRUPT + ": " + ObjectUtils.toString(fxImage.getException()), ImageUtils.getContentPathSafe(file));
}
} catch (InterruptedException | ExecutionException ex) {
failed();
@ -790,7 +839,7 @@ public class ImageUtils {
@Override
protected void failed() {
super.failed();
LOGGER.log(Level.WARNING, IMAGEIO_COULD_NOT_READ_UNSUPPORTE_OR_CORRUPT + ": " + ObjectUtils.toString(getException()), ImageUtils.getContentPathSafe(file));
LOGGER.log(Level.WARNING, IMAGEIO_COULD_NOT_READ_UNSUPPORTED_OR_CORRUPT + ": " + ObjectUtils.toString(getException()), ImageUtils.getContentPathSafe(file));
}
@Override

View File

@ -57,4 +57,26 @@ public class TextUtil {
return orientation;
}
/**
* This method determines if a passed-in Java char (16 bits) is a valid
* UTF-8 printable character, returning true if so, false if not.
*
* Note that this method can have ramifications for characters outside the
* Unicode Base Multilingual Plane (BMP), which require more than 16 bits.
* We are using Java characters (16 bits) to look at the data and this will
* not accurately identify any non-BMP character (larger than 16 bits)
* ending with 0xFFFF and 0xFFFE. In the interest of a fast solution, we
* have chosen to ignore the extended planes above Unicode BMP for the time
* being. The net result of this is some non-BMP characters may be
* interspersed with '^' characters in Autopsy.
*
* @param ch the character to test
*
* @return Returns true if the character is valid UTF-8, false if not.
*/
public static boolean isValidSolrUTF8(char ch) {
return ((ch <= 0xFDD0 || ch >= 0xFDEF) && (ch > 0x1F || ch == 0x9 || ch == 0xA || ch == 0xD) && (ch != 0xFFFF) && (ch != 0xFFFE));
}
}

View File

@ -268,7 +268,7 @@ public abstract class AbstractAbstractFileNode<T extends AbstractFile> extends A
map.put(AbstractFilePropertyType.USER_ID.toString(), content.getUid());
map.put(AbstractFilePropertyType.GROUP_ID.toString(), content.getGid());
map.put(AbstractFilePropertyType.META_ADDR.toString(), content.getMetaAddr());
map.put(AbstractFilePropertyType.ATTR_ADDR.toString(), Long.toString(content.getAttrType().getValue()) + "-" + Long.toString(content.getAttrId()));
map.put(AbstractFilePropertyType.ATTR_ADDR.toString(), Long.toString(content.getAttrType().getValue()) + "-" + content.getAttributeId());
map.put(AbstractFilePropertyType.TYPE_DIR.toString(), content.getDirType().getLabel());
map.put(AbstractFilePropertyType.TYPE_META.toString(), content.getMetaType().toString());
map.put(AbstractFilePropertyType.KNOWN.toString(), content.getKnown().getName());

View File

@ -20,13 +20,13 @@ package org.sleuthkit.autopsy.datamodel;
import java.util.List;
import java.util.logging.Level;
import org.sleuthkit.autopsy.coreutils.Logger;
import javax.swing.Action;
import org.openide.nodes.Children;
import org.openide.nodes.Sheet;
import org.openide.util.NbBundle;
import org.openide.util.lookup.Lookups;
import org.sleuthkit.autopsy.actions.DeleteBlackboardArtifactTagAction;
import org.sleuthkit.autopsy.coreutils.Logger;
import org.sleuthkit.datamodel.BlackboardArtifactTag;
import org.sleuthkit.datamodel.TskCoreException;
@ -93,7 +93,11 @@ public class BlackboardArtifactTagNode extends DisplayableItemNode {
@Override
public Action[] getActions(boolean context) {
List<Action> actions = DataModelActionsFactory.getActions(tag.getContent(), true);
actions.add(null); // Adds a menu item separator.
for (Action a : super.getActions(true)) {
actions.add(a);
}
actions.add(null); // Adds a menu item separator.
actions.add(DeleteBlackboardArtifactTagAction.getInstance());
return actions.toArray(new Action[0]);
}

View File

@ -147,7 +147,6 @@ HashsetHits.createSheet.name.name=Name
HashsetHits.createSheet.name.displayName=Name
HashsetHits.createSheet.name.desc=no description
ImageNode.getActions.viewInNewWin.text=View in New Window
ImageNode.getActions.openFileSearchByAttr.text=Open File Search by Attributes
ImageNode.createSheet.name.name=Name
ImageNode.createSheet.name.displayName=Name
ImageNode.createSheet.name.desc=no description

View File

@ -107,6 +107,9 @@ class ContentTagNode extends DisplayableItemNode {
@Override
public Action[] getActions(boolean context) {
List<Action> actions = DataModelActionsFactory.getActions(tag.getContent(), false);
for (Action a : super.getActions(true)) {
actions.add(a);
}
actions.add(null); // Adds a menu item separator.
actions.add(DeleteContentTagAction.getInstance());
return actions.toArray(new Action[0]);

View File

@ -21,10 +21,9 @@ package org.sleuthkit.autopsy.datamodel;
import java.util.ArrayList;
import java.util.List;
import javax.swing.Action;
import org.openide.util.NbBundle;
import org.sleuthkit.autopsy.coreutils.ContextMenuExtensionPoint;
import org.sleuthkit.autopsy.actions.AddContentTagAction;
import org.sleuthkit.autopsy.coreutils.ContextMenuExtensionPoint;
import org.sleuthkit.autopsy.directorytree.ExtractAction;
import org.sleuthkit.autopsy.directorytree.NewWindowViewAction;
import org.sleuthkit.autopsy.directorytree.ViewContextAction;
@ -72,6 +71,9 @@ public class DirectoryNode extends AbstractFsContentNode<AbstractFile> {
@Override
public Action[] getActions(boolean popup) {
List<Action> actions = new ArrayList<>();
for (Action a : super.getActions(true)) {
actions.add(a);
}
if (!getDirectoryBrowseMode()) {
actions.add(new ViewContextAction(
NbBundle.getMessage(this.getClass(), "DirectoryNode.getActions.viewFileInDir.text"), this));

View File

@ -79,18 +79,21 @@ public class FileNode extends AbstractFsContentNode<AbstractFile> {
@Override
public Action[] getActions(boolean popup) {
List<Action> actionsList = new ArrayList<>();
for (Action a : super.getActions(true)) {
actionsList.add(a);
}
if (!this.getDirectoryBrowseMode()) {
actionsList.add(new ViewContextAction(NbBundle.getMessage(this.getClass(), "FileNode.viewFileInDir.text"), this));
actionsList.add(new ViewContextAction(NbBundle.getMessage(FileNode.class, "FileNode.viewFileInDir.text"), this));
actionsList.add(null); // creates a menu separator
}
actionsList.add(new NewWindowViewAction(
NbBundle.getMessage(this.getClass(), "FileNode.getActions.viewInNewWin.text"), this));
NbBundle.getMessage(FileNode.class, "FileNode.getActions.viewInNewWin.text"), this));
actionsList.add(new ExternalViewerAction(
NbBundle.getMessage(this.getClass(), "FileNode.getActions.openInExtViewer.text"), this));
NbBundle.getMessage(FileNode.class, "FileNode.getActions.openInExtViewer.text"), this));
actionsList.add(null); // creates a menu separator
actionsList.add(ExtractAction.getInstance());
actionsList.add(new HashSearchAction(
NbBundle.getMessage(this.getClass(), "FileNode.getActions.searchFilesSameMD5.text"), this));
NbBundle.getMessage(FileNode.class, "FileNode.getActions.searchFilesSameMD5.text"), this));
actionsList.add(null); // creates a menu separator
actionsList.add(AddContentTagAction.getInstance());
actionsList.addAll(ContextMenuExtensionPoint.getActions());

View File

@ -27,7 +27,7 @@ import java.util.List;
*/
public class FileTypeExtensions {
private final static List<String> IMAGE_EXTENSIONS = Arrays.asList(".jpg", ".jpeg", ".png", ".psd", ".nef", ".tiff", ".bmp"); //NON-NLS
private final static List<String> IMAGE_EXTENSIONS = Arrays.asList(".jpg", ".jpeg", ".png", ".psd", ".nef", ".tiff", ".bmp", ".tec"); //NON-NLS
private final static List<String> VIDEO_EXTENSIONS = Arrays.asList(".aaf", ".3gp", ".asf", ".avi", ".m1v", ".m2v", //NON-NLS
".m4v", ".mp4", ".mov", ".mpeg", ".mpg", ".mpe", ".mp4", ".rm", ".wmv", ".mpv", ".flv", ".swf"); //NON-NLS
private final static List<String> AUDIO_EXTENSIONS = Arrays.asList(".aiff", ".aif", ".flac", ".wav", ".m4a", ".ape", //NON-NLS

View File

@ -18,15 +18,28 @@
*/
package org.sleuthkit.autopsy.datamodel;
import java.awt.event.ActionEvent;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.logging.Level;
import javax.swing.AbstractAction;
import javax.swing.Action;
import org.openide.nodes.Sheet;
import org.openide.util.NbBundle;
import org.openide.util.NbBundle.Messages;
import org.sleuthkit.autopsy.casemodule.Case;
import org.sleuthkit.autopsy.coreutils.Logger;
import org.sleuthkit.autopsy.directorytree.ExplorerNodeActionVisitor;
import org.sleuthkit.autopsy.directorytree.FileSearchAction;
import org.sleuthkit.autopsy.directorytree.NewWindowViewAction;
import org.sleuthkit.autopsy.ingest.RunIngestModulesDialog;
import org.sleuthkit.datamodel.Content;
import org.sleuthkit.datamodel.Image;
import org.sleuthkit.datamodel.SleuthkitCase.CaseDbQuery;
import org.sleuthkit.datamodel.TskCoreException;
/**
* This class is used to represent the "Node" for the image. The children of
@ -34,6 +47,8 @@ import org.sleuthkit.datamodel.Image;
*/
public class ImageNode extends AbstractContentNode<Image> {
private static final Logger logger = Logger.getLogger(ImageNode.class.getName());
/**
* Helper so that the display name and the name used in building the path
* are determined the same way.
@ -66,19 +81,53 @@ public class ImageNode extends AbstractContentNode<Image> {
* @return
*/
@Override
@Messages({"ImageNode.action.runIngestMods.text=Run Ingest Modules",
"ImageNode.getActions.openFileSearchByAttr.text=Open File Search by Attributes",})
public Action[] getActions(boolean context) {
List<Action> actionsList = new ArrayList<Action>();
for (Action a : super.getActions(true)) {
actionsList.add(a);
}
actionsList.addAll(ExplorerNodeActionVisitor.getActions(content));
actionsList.add(new FileSearchAction(
Bundle.ImageNode_getActions_openFileSearchByAttr_text()));
actionsList.add(new AbstractAction(
Bundle.ImageNode_action_runIngestMods_text()) {
@Override
public void actionPerformed(ActionEvent e) {
final RunIngestModulesDialog ingestDialog = new RunIngestModulesDialog(Collections.<Content>singletonList(content));
ingestDialog.display();
}
});
actionsList.add(new NewWindowViewAction(
NbBundle.getMessage(this.getClass(), "ImageNode.getActions.viewInNewWin.text"), this));
actionsList.add(new FileSearchAction(
NbBundle.getMessage(this.getClass(), "ImageNode.getActions.openFileSearchByAttr.text")));
actionsList.addAll(ExplorerNodeActionVisitor.getActions(content));
return actionsList.toArray(new Action[0]);
}
@Override
@Messages({"ImageNode.createSheet.size.name=Size (Bytes)",
"ImageNode.createSheet.size.displayName=Size (Bytes)",
"ImageNode.createSheet.size.desc=Size of the data source in bytes.",
"ImageNode.createSheet.type.name=Type",
"ImageNode.createSheet.type.displayName=Type",
"ImageNode.createSheet.type.desc=Type of the image.",
"ImageNode.createSheet.type.text=Image",
"ImageNode.createSheet.sectorSize.name=Sector Size (Bytes)",
"ImageNode.createSheet.sectorSize.displayName=Sector Size (Bytes)",
"ImageNode.createSheet.sectorSize.desc=Sector size of the image in bytes.",
"ImageNode.createSheet.md5.name=MD5 Hash",
"ImageNode.createSheet.md5.displayName=MD5 Hash",
"ImageNode.createSheet.md5.desc=MD5 Hash of the image",
"ImageNode.createSheet.timezone.name=Timezone",
"ImageNode.createSheet.timezone.displayName=Timezone",
"ImageNode.createSheet.timezone.desc=Timezone of the image",
"ImageNode.createSheet.deviceId.name=Device ID",
"ImageNode.createSheet.deviceId.displayName=Device ID",
"ImageNode.createSheet.deviceId.desc=Device ID of the image"})
protected Sheet createSheet() {
Sheet s = super.createSheet();
Sheet.Set ss = s.get(Sheet.PROPERTIES);
@ -92,6 +141,42 @@ public class ImageNode extends AbstractContentNode<Image> {
NbBundle.getMessage(this.getClass(), "ImageNode.createSheet.name.desc"),
getDisplayName()));
ss.put(new NodeProperty<>(Bundle.ImageNode_createSheet_type_name(),
Bundle.ImageNode_createSheet_type_displayName(),
Bundle.ImageNode_createSheet_type_desc(),
Bundle.ImageNode_createSheet_type_text()));
ss.put(new NodeProperty<>(Bundle.ImageNode_createSheet_size_name(),
Bundle.ImageNode_createSheet_size_displayName(),
Bundle.ImageNode_createSheet_size_desc(),
this.content.getSize()));
ss.put(new NodeProperty<>(Bundle.ImageNode_createSheet_sectorSize_name(),
Bundle.ImageNode_createSheet_sectorSize_displayName(),
Bundle.ImageNode_createSheet_sectorSize_desc(),
this.content.getSsize()));
ss.put(new NodeProperty<>(Bundle.ImageNode_createSheet_md5_name(),
Bundle.ImageNode_createSheet_md5_displayName(),
Bundle.ImageNode_createSheet_md5_desc(),
this.content.getMd5()));
ss.put(new NodeProperty<>(Bundle.ImageNode_createSheet_timezone_name(),
Bundle.ImageNode_createSheet_timezone_displayName(),
Bundle.ImageNode_createSheet_timezone_desc(),
this.content.getTimeZone()));
try (CaseDbQuery query = Case.getCurrentCase().getSleuthkitCase().executeQuery("SELECT device_id FROM data_source_info WHERE obj_id = " + this.content.getId());) {
ResultSet deviceIdSet = query.getResultSet();
if (deviceIdSet.next()) {
ss.put(new NodeProperty<>(Bundle.ImageNode_createSheet_deviceId_name(),
Bundle.ImageNode_createSheet_deviceId_displayName(),
Bundle.ImageNode_createSheet_deviceId_desc(),
deviceIdSet.getString("device_id")));
}
} catch (SQLException | TskCoreException ex) {
logger.log(Level.SEVERE, "Failed to get device id for the following image: " + this.content.getId(), ex);
}
return s;
}

View File

@ -25,11 +25,11 @@ import java.util.Map;
import javax.swing.Action;
import org.openide.nodes.Sheet;
import org.openide.util.NbBundle;
import org.sleuthkit.autopsy.actions.AddContentTagAction;
import org.sleuthkit.autopsy.coreutils.ContextMenuExtensionPoint;
import org.sleuthkit.autopsy.directorytree.ExternalViewerAction;
import org.sleuthkit.autopsy.directorytree.ExtractAction;
import org.sleuthkit.autopsy.directorytree.NewWindowViewAction;
import org.sleuthkit.autopsy.actions.AddContentTagAction;
import org.sleuthkit.datamodel.LayoutFile;
import org.sleuthkit.datamodel.TskData;
@ -116,6 +116,9 @@ public class LayoutFileNode extends AbstractAbstractFileNode<LayoutFile> {
@Override
public Action[] getActions(boolean context) {
List<Action> actionsList = new ArrayList<>();
for (Action a : super.getActions(true)) {
actionsList.add(a);
}
actionsList.add(new NewWindowViewAction(
NbBundle.getMessage(this.getClass(), "LayoutFileNode.getActions.viewInNewWin.text"), this));
actionsList.add(new ExternalViewerAction(

View File

@ -25,12 +25,12 @@ import java.util.Map;
import javax.swing.Action;
import org.openide.nodes.Sheet;
import org.openide.util.NbBundle;
import org.sleuthkit.autopsy.actions.AddContentTagAction;
import org.sleuthkit.autopsy.coreutils.ContextMenuExtensionPoint;
import org.sleuthkit.autopsy.directorytree.ExternalViewerAction;
import org.sleuthkit.autopsy.directorytree.ExtractAction;
import org.sleuthkit.autopsy.directorytree.HashSearchAction;
import org.sleuthkit.autopsy.directorytree.NewWindowViewAction;
import org.sleuthkit.autopsy.actions.AddContentTagAction;
import org.sleuthkit.autopsy.directorytree.ViewContextAction;
import org.sleuthkit.datamodel.AbstractFile;
@ -82,6 +82,9 @@ public class LocalFileNode extends AbstractAbstractFileNode<AbstractFile> {
@Override
public Action[] getActions(boolean context) {
List<Action> actionsList = new ArrayList<>();
for (Action a : super.getActions(true)) {
actionsList.add(a);
}
actionsList.add(new ViewContextAction(NbBundle.getMessage(this.getClass(), "LocalFileNode.viewFileInDir.text"), this.content));
actionsList.add(null); // creates a menu separator
actionsList.add(new NewWindowViewAction(

View File

@ -18,19 +18,32 @@
*/
package org.sleuthkit.autopsy.datamodel;
import java.awt.event.ActionEvent;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import javax.swing.AbstractAction;
import javax.swing.Action;
import org.openide.nodes.Sheet;
import org.openide.util.NbBundle;
import org.openide.util.NbBundle.Messages;
import org.sleuthkit.autopsy.casemodule.Case;
import org.sleuthkit.autopsy.coreutils.ContextMenuExtensionPoint;
import org.sleuthkit.autopsy.coreutils.Logger;
import org.sleuthkit.autopsy.directorytree.ExtractAction;
import org.sleuthkit.autopsy.directorytree.FileSearchAction;
import org.sleuthkit.autopsy.directorytree.NewWindowViewAction;
import org.sleuthkit.datamodel.VirtualDirectory;
import org.sleuthkit.autopsy.ingest.RunIngestModulesDialog;
import org.sleuthkit.datamodel.Content;
import org.sleuthkit.datamodel.SleuthkitCase;
import org.sleuthkit.datamodel.TskCoreException;
import org.sleuthkit.datamodel.TskData;
import org.sleuthkit.datamodel.VirtualDirectory;
/**
* Node for layout dir
@ -73,18 +86,46 @@ public class VirtualDirectoryNode extends AbstractAbstractFileNode<VirtualDirect
* @return
*/
@Override
@NbBundle.Messages({"VirtualDirectoryNode.action.runIngestMods.text=Run Ingest Modules"})
public Action[] getActions(boolean popup) {
List<Action> actions = new ArrayList<>();
for (Action a : super.getActions(true)) {
actions.add(a);
}
actions.add(new NewWindowViewAction(
NbBundle.getMessage(this.getClass(), "VirtualDirectoryNode.getActions.viewInNewWin.text"), this));
actions.add(null); // creates a menu separator
actions.add(ExtractAction.getInstance());
actions.add(null); // creates a menu separator
actions.add(new FileSearchAction(
Bundle.ImageNode_getActions_openFileSearchByAttr_text()));
actions.add(new AbstractAction(
Bundle.VirtualDirectoryNode_action_runIngestMods_text()) {
@Override
public void actionPerformed(ActionEvent e) {
final RunIngestModulesDialog ingestDialog = new RunIngestModulesDialog(Collections.<Content>singletonList(content));
ingestDialog.display();
}
});
actions.addAll(ContextMenuExtensionPoint.getActions());
return actions.toArray(new Action[0]);
}
@Override
@Messages({"VirtualDirectoryNode.createSheet.size.name=Size (Bytes)",
"VirtualDirectoryNode.createSheet.size.displayName=Size (Bytes)",
"VirtualDirectoryNode.createSheet.size.desc=Size of the data source in bytes.",
"VirtualDirectoryNode.createSheet.type.name=Type",
"VirtualDirectoryNode.createSheet.type.displayName=Type",
"VirtualDirectoryNode.createSheet.type.desc=Type of the image.",
"VirtualDirectoryNode.createSheet.type.text=Logical File Set",
"VirtualDirectoryNode.createSheet.timezone.name=Timezone",
"VirtualDirectoryNode.createSheet.timezone.displayName=Timezone",
"VirtualDirectoryNode.createSheet.timezone.desc=Timezone of the image",
"VirtualDirectoryNode.createSheet.deviceId.name=Device ID",
"VirtualDirectoryNode.createSheet.deviceId.displayName=Device ID",
"VirtualDirectoryNode.createSheet.deviceId.desc=Device ID of the image"})
protected Sheet createSheet() {
Sheet s = super.createSheet();
Sheet.Set ss = s.get(Sheet.PROPERTIES);
@ -93,18 +134,52 @@ public class VirtualDirectoryNode extends AbstractAbstractFileNode<VirtualDirect
s.put(ss);
}
Map<String, Object> map = new LinkedHashMap<>();
fillPropertyMap(map, content);
ss.put(new NodeProperty<>(NbBundle.getMessage(this.getClass(), "VirtualDirectoryNode.createSheet.name.name"),
NbBundle.getMessage(this.getClass(),
"VirtualDirectoryNode.createSheet.name.displayName"),
NbBundle.getMessage(this.getClass(), "VirtualDirectoryNode.createSheet.name.desc"),
getName()));
final String NO_DESCR = NbBundle.getMessage(this.getClass(), "VirtualDirectoryNode.createSheet.noDesc");
for (Map.Entry<String, Object> entry : map.entrySet()) {
ss.put(new NodeProperty<>(entry.getKey(), entry.getKey(), NO_DESCR, entry.getValue()));
if (!this.content.isDataSource()) {
Map<String, Object> map = new LinkedHashMap<>();
fillPropertyMap(map, content);
final String NO_DESCR = NbBundle.getMessage(this.getClass(), "VirtualDirectoryNode.createSheet.noDesc");
for (Map.Entry<String, Object> entry : map.entrySet()) {
ss.put(new NodeProperty<>(entry.getKey(), entry.getKey(), NO_DESCR, entry.getValue()));
}
} else {
ss.put(new NodeProperty<>(Bundle.VirtualDirectoryNode_createSheet_type_name(),
Bundle.VirtualDirectoryNode_createSheet_type_displayName(),
Bundle.VirtualDirectoryNode_createSheet_type_desc(),
Bundle.VirtualDirectoryNode_createSheet_type_text()));
ss.put(new NodeProperty<>(Bundle.VirtualDirectoryNode_createSheet_size_name(),
Bundle.VirtualDirectoryNode_createSheet_size_displayName(),
Bundle.VirtualDirectoryNode_createSheet_size_desc(),
this.content.getSize()));
try (SleuthkitCase.CaseDbQuery query = Case.getCurrentCase().getSleuthkitCase().executeQuery("SELECT time_zone FROM data_source_info WHERE obj_id = " + this.content.getId())) {
ResultSet timeZoneSet = query.getResultSet();
if (timeZoneSet.next()) {
ss.put(new NodeProperty<>(Bundle.VirtualDirectoryNode_createSheet_timezone_name(),
Bundle.VirtualDirectoryNode_createSheet_timezone_displayName(),
Bundle.VirtualDirectoryNode_createSheet_timezone_desc(),
timeZoneSet.getString("time_zone")));
}
} catch (SQLException | TskCoreException ex) {
logger.log(Level.SEVERE, "Failed to get time zone for the following image: " + this.content.getId(), ex);
}
try (SleuthkitCase.CaseDbQuery query = Case.getCurrentCase().getSleuthkitCase().executeQuery("SELECT device_id FROM data_source_info WHERE obj_id = " + this.content.getId());) {
ResultSet deviceIdSet = query.getResultSet();
if (deviceIdSet.next()) {
ss.put(new NodeProperty<>(Bundle.VirtualDirectoryNode_createSheet_deviceId_name(),
Bundle.VirtualDirectoryNode_createSheet_deviceId_displayName(),
Bundle.VirtualDirectoryNode_createSheet_deviceId_desc(),
deviceIdSet.getString("device_id")));
}
} catch (SQLException | TskCoreException ex) {
logger.log(Level.SEVERE, "Failed to get device id for the following image: " + this.content.getId(), ex);
}
}
return s;

View File

@ -131,6 +131,10 @@ public class VolumeNode extends AbstractContentNode<Volume> {
public Action[] getActions(boolean popup) {
List<Action> actionsList = new ArrayList<>();
for (Action a : super.getActions(true)) {
actionsList.add(a);
}
actionsList.add(new NewWindowViewAction(
NbBundle.getMessage(this.getClass(), "VolumeNode.getActions.viewInNewWin.text"), this));
actionsList.addAll(ExplorerNodeActionVisitor.getActions(content));

View File

@ -18,27 +18,14 @@
*/
package org.sleuthkit.autopsy.directorytree;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.logging.Level;
import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JTable;
import javax.swing.table.DefaultTableModel;
import org.openide.util.NbBundle;
import org.sleuthkit.autopsy.actions.AddContentTagAction;
import org.sleuthkit.autopsy.coreutils.ContextMenuExtensionPoint;
import org.sleuthkit.autopsy.coreutils.Logger;
import org.sleuthkit.datamodel.Content;
import org.sleuthkit.datamodel.ContentVisitor;
import org.sleuthkit.datamodel.DerivedFile;
@ -77,8 +64,6 @@ public class ExplorerNodeActionVisitor extends ContentVisitor.Default<List<? ext
@Override
public List<? extends Action> visit(final Image img) {
List<Action> lst = new ArrayList<>();
lst.add(new ImageDetails(
NbBundle.getMessage(this.getClass(), "ExplorerNodeActionVisitor.action.imgDetails.title"), img));
//TODO lst.add(new ExtractAction("Extract Image", img));
lst.add(new ExtractUnallocAction(
NbBundle.getMessage(this.getClass(), "ExplorerNodeActionVisitor.action.extUnallocToSingleFiles"), img));
@ -87,15 +72,12 @@ public class ExplorerNodeActionVisitor extends ContentVisitor.Default<List<? ext
@Override
public List<? extends Action> visit(final FileSystem fs) {
return Collections.singletonList(new FileSystemDetails(
NbBundle.getMessage(this.getClass(), "ExplorerNodeActionVisitor.action.fileSystemDetails.title"), fs));
return new ArrayList<>();
}
@Override
public List<? extends Action> visit(final Volume vol) {
List<AbstractAction> lst = new ArrayList<>();
lst.add(new VolumeDetails(
NbBundle.getMessage(this.getClass(), "ExplorerNodeActionVisitor.action.volumeDetails.title"), vol));
lst.add(new ExtractUnallocAction(
NbBundle.getMessage(this.getClass(), "ExplorerNodeActionVisitor.action.extUnallocToSingleFile"), vol));
return lst;
@ -152,242 +134,4 @@ public class ExplorerNodeActionVisitor extends ContentVisitor.Default<List<? ext
return Collections.<Action>emptyList();
}
//Below here are classes regarding node-specific actions
/**
* VolumeDetails class
*/
private class VolumeDetails extends AbstractAction {
private final String title;
private final Volume vol;
VolumeDetails(String title, Volume vol) {
super(title);
this.title = title;
this.vol = vol;
}
@Override
public void actionPerformed(ActionEvent e) {
final JFrame frame = new JFrame(title);
final JDialog popUpWindow = new JDialog(frame, title, true); // to make the popUp Window to be modal
Dimension screenDimension = Toolkit.getDefaultToolkit().getScreenSize();
// set the popUp window / JFrame
popUpWindow.setSize(800, 400);
int w = popUpWindow.getSize().width;
int h = popUpWindow.getSize().height;
// set the location of the popUp Window on the center of the screen
popUpWindow.setLocation((screenDimension.width - w) / 2, (screenDimension.height - h) / 2);
VolumeDetailsPanel volumeDetailPanel = new VolumeDetailsPanel();
Boolean counter = false;
volumeDetailPanel.setVolumeIDValue(Long.toString(vol.getAddr()));
volumeDetailPanel.setStartValue(Long.toString(vol.getStart()));
volumeDetailPanel.setLengthValue(Long.toString(vol.getLength()));
volumeDetailPanel.setDescValue(vol.getDescription());
volumeDetailPanel.setFlagsValue(vol.getFlagsAsString());
counter = true;
if (counter) {
// add the volume detail panel to the popUp window
popUpWindow.add(volumeDetailPanel);
} else {
// error handler if no volume matches
JLabel error = new JLabel(
NbBundle.getMessage(this.getClass(), "ExplorerNodeActionVisitor.volDetail.noVolMatchErr"));
error.setFont(error.getFont().deriveFont(Font.BOLD, 24));
popUpWindow.add(error);
}
// add the command to close the window to the button on the Volume Detail Panel
volumeDetailPanel.setOKButtonActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
popUpWindow.dispose();
}
});
popUpWindow.pack();
popUpWindow.setResizable(false);
popUpWindow.setVisible(true);
}
}
/**
* ImageDetails panel class
*/
private class ImageDetails extends AbstractAction {
final String title;
final Image img;
ImageDetails(String title, Image img) {
super(title);
this.title = title;
this.img = img;
}
@Override
public void actionPerformed(ActionEvent e) {
final JFrame frame = new JFrame(title);
final JDialog popUpWindow = new JDialog(frame, title, true); // to make the popUp Window to be modal
// if we select the Image Details menu
Dimension screenDimension = Toolkit.getDefaultToolkit().getScreenSize();
// set the popUp window / JFrame
popUpWindow.setSize(750, 400);
int w = popUpWindow.getSize().width;
int h = popUpWindow.getSize().height;
// set the location of the popUp Window on the center of the screen
popUpWindow.setLocation((screenDimension.width - w) / 2, (screenDimension.height - h) / 2);
ImageDetailsPanel imgDetailPanel = new ImageDetailsPanel();
Boolean counter = false;
imgDetailPanel.setImgNameValue(img.getName());
imgDetailPanel.setImgTypeValue(img.getType().getName());
imgDetailPanel.setImgSectorSizeValue(Long.toString(img.getSsize()));
imgDetailPanel.setImgTotalSizeValue(Long.toString(img.getSize()));
String hash = img.getMd5();
// don't show the hash if there isn't one
imgDetailPanel.setVisibleHashInfo(hash != null);
imgDetailPanel.setImgHashValue(hash);
counter = true;
if (counter) {
// add the volume detail panel to the popUp window
popUpWindow.add(imgDetailPanel);
} else {
// error handler if no volume matches
JLabel error = new JLabel(
NbBundle.getMessage(this.getClass(), "ExplorerNodeActionVisitor.imgDetail.noVolMatchesErr"));
error.setFont(error.getFont().deriveFont(Font.BOLD, 24));
popUpWindow.add(error);
}
// add the command to close the window to the button on the Volume Detail Panel
imgDetailPanel.setOKButtonActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
popUpWindow.dispose();
}
});
popUpWindow.pack();
popUpWindow.setResizable(false);
popUpWindow.setVisible(true);
}
}
/**
* FileSystemDetails class
*/
private class FileSystemDetails extends AbstractAction {
private final FileSystem fs;
private final String title;
FileSystemDetails(String title, FileSystem fs) {
super(title);
this.title = title;
this.fs = fs;
}
@Override
public void actionPerformed(ActionEvent e) {
Dimension screenDimension = Toolkit.getDefaultToolkit().getScreenSize();
final JFrame frame = new JFrame(title);
final JDialog popUpWindow = new JDialog(frame, title, true); // to make the popUp Window to be modal
// set the popUp window / JFrame
popUpWindow.setSize(1000, 500);
int w = popUpWindow.getSize().width;
int h = popUpWindow.getSize().height;
// set the location of the popUp Window on the center of the screen
popUpWindow.setLocation((screenDimension.width - w) / 2, (screenDimension.height - h) / 2);
String[] columnNames = new String[]{
"fs_id", //NON-NLS
"img_offset", //NON-NLS
"par_id", //NON-NLS
"fs_type", //NON-NLS
"block_size", //NON-NLS
"block_count", //NON-NLS
"root_inum", //NON-NLS
"first_inum", //NON-NLS
"last_inum" //NON-NLS
};
Object[][] rowValues = new Object[1][9];
Content parent = null;
try {
parent = fs.getParent();
} catch (Exception ex) {
throw new RuntimeException(
NbBundle.getMessage(this.getClass(), "ExplorerNodeActionVisitor.exception.probGetParent.text",
FileSystem.class.getName(), fs), ex);
}
long id = -1;
if (parent != null) {
id = parent.getId();
}
Arrays.fill(rowValues, 0, 1, new Object[]{
fs.getId(),
fs.getImageOffset(),
id,
fs.getFsType(),
fs.getBlock_size(),
fs.getBlock_count(),
fs.getRoot_inum(),
fs.getFirst_inum(),
fs.getLastInum()
});
JTable table = new JTable(new DefaultTableModel(rowValues, columnNames));
FileSystemDetailsPanel fsdPanel = new FileSystemDetailsPanel();
// add the command to close the window to the button on the Volume Detail Panel
fsdPanel.setOKButtonActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
popUpWindow.dispose();
}
});
try {
fsdPanel.setFileSystemTypeValue(table.getValueAt(0, 3).toString());
fsdPanel.setImageOffsetValue(table.getValueAt(0, 1).toString());
fsdPanel.setVolumeIDValue(table.getValueAt(0, 2).toString()); //TODO: fix this to parent id, not vol id
fsdPanel.setBlockSizeValue(table.getValueAt(0, 4).toString());
fsdPanel.setBlockCountValue(table.getValueAt(0, 5).toString());
fsdPanel.setRootInumValue(table.getValueAt(0, 6).toString());
fsdPanel.setFirstInumValue(table.getValueAt(0, 7).toString());
fsdPanel.setLastInumValue(table.getValueAt(0, 8).toString());
popUpWindow.add(fsdPanel);
} catch (Exception ex) {
Logger.getLogger(ExplorerNodeActionVisitor.class.getName()).log(Level.WARNING, "Error setting up File System Details panel.", ex); //NON-NLS
}
popUpWindow.pack();
popUpWindow.setResizable(false);
popUpWindow.setVisible(true);
}
}
}

View File

@ -27,6 +27,7 @@ import java.util.HashSet;
import java.util.List;
import java.util.logging.Level;
import org.openide.util.NbBundle;
import org.openide.util.NbBundle.Messages;
import org.sleuthkit.autopsy.casemodule.Case;
import org.sleuthkit.autopsy.casemodule.services.Blackboard;
import org.sleuthkit.autopsy.casemodule.services.FileManager;
@ -127,6 +128,7 @@ public final class ExternalResultsImporter {
}
}
@Messages({"ExternalResultsImporter.indexError.message=Failed to index imported artifact for keyword search."})
private void importArtifacts(ExternalResults results) {
SleuthkitCase caseDb = Case.getCurrentCase().getSleuthkitCase();
for (ExternalResults.Artifact artifactData : results.getArtifacts()) {
@ -200,9 +202,9 @@ public final class ExternalResultsImporter {
// index the artifact for keyword search
blackboard.indexArtifact(artifact);
} catch (Blackboard.BlackboardException ex) {
logger.log(Level.SEVERE, NbBundle.getMessage(Blackboard.class, "Blackboard.unableToIndexArtifact.error.msg", artifact.getDisplayName()), ex); //NON-NLS
logger.log(Level.SEVERE, "Unable to index blackboard artifact " + artifact.getArtifactID(), ex); //NON-NLS
MessageNotifyUtil.Notify.error(
NbBundle.getMessage(Blackboard.class, "Blackboard.unableToIndexArtifact.exception.msg"), artifact.getDisplayName());
Bundle.ExternalResultsImporter_indexError_message(), artifact.getDisplayName());
}
if (standardArtifactTypeIds.contains(artifactTypeId)) {

View File

@ -18,6 +18,7 @@
*/
package org.sleuthkit.autopsy.filesearch;
import java.beans.PropertyChangeListener;
import javax.swing.JComponent;
/**
@ -39,4 +40,9 @@ abstract class AbstractFileSearchFilter<T extends JComponent> implements FileSea
public T getComponent() {
return this.component;
}
@Override
public void addPropertyChangeListener(PropertyChangeListener listener) {
this.getComponent().addPropertyChangeListener(listener);
}
}

View File

@ -205,6 +205,11 @@ class DateSearchFilter extends AbstractFileSearchFilter<DateSearchPanel> {
getComponent().addActionListener(l);
}
@Override
public boolean isValid() {
return this.getComponent().isValidSearch();
}
/**
* Inner class to put the separator inside the combo box.
*/

View File

@ -236,6 +236,9 @@
<ResourceString bundle="org/sleuthkit/autopsy/filesearch/Bundle.properties" key="DateSearchPanel.modifiedCheckBox.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="modifiedCheckBoxActionPerformed"/>
</Events>
</Component>
<Component class="javax.swing.JCheckBox" name="changedCheckBox">
<Properties>
@ -244,6 +247,9 @@
<ResourceString bundle="org/sleuthkit/autopsy/filesearch/Bundle.properties" key="DateSearchPanel.changedCheckBox.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="changedCheckBoxActionPerformed"/>
</Events>
</Component>
<Component class="javax.swing.JCheckBox" name="accessedCheckBox">
<Properties>
@ -252,6 +258,9 @@
<ResourceString bundle="org/sleuthkit/autopsy/filesearch/Bundle.properties" key="DateSearchPanel.accessedCheckBox.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="accessedCheckBoxActionPerformed"/>
</Events>
</Component>
<Component class="javax.swing.JCheckBox" name="createdCheckBox">
<Properties>
@ -260,6 +269,9 @@
<ResourceString bundle="org/sleuthkit/autopsy/filesearch/Bundle.properties" key="DateSearchPanel.createdCheckBox.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="createdCheckBoxActionPerformed"/>
</Events>
</Component>
<Component class="org.jbundle.thin.base.screen.jcalendarbutton.JCalendarButton" name="dateFromButtonCalendar">
<Properties>

View File

@ -20,6 +20,8 @@ package org.sleuthkit.autopsy.filesearch;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.beans.PropertyChangeListener;
import java.beans.PropertyChangeSupport;
import java.text.DateFormat;
import java.text.ParseException;
import java.util.Date;
@ -37,6 +39,7 @@ class DateSearchPanel extends javax.swing.JPanel {
DateFormat dateFormat;
List<String> timeZones;
private final PropertyChangeSupport pcs = new PropertyChangeSupport(this);
DateSearchPanel(DateFormat dateFormat, List<String> timeZones) {
this.dateFormat = dateFormat;
@ -133,6 +136,16 @@ class DateSearchPanel extends javax.swing.JPanel {
this.changedCheckBox.setEnabled(enable);
this.createdCheckBox.setEnabled(enable);
}
@Override
public void addPropertyChangeListener(PropertyChangeListener pcl) {
pcs.addPropertyChangeListener(pcl);
}
@Override
public void removePropertyChangeListener(PropertyChangeListener pcl) {
pcs.removePropertyChangeListener(pcl);
}
/**
* This method is called from within the constructor to initialize the form.
@ -209,15 +222,35 @@ class DateSearchPanel extends javax.swing.JPanel {
modifiedCheckBox.setSelected(true);
modifiedCheckBox.setText(org.openide.util.NbBundle.getMessage(DateSearchPanel.class, "DateSearchPanel.modifiedCheckBox.text")); // NOI18N
modifiedCheckBox.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
modifiedCheckBoxActionPerformed(evt);
}
});
changedCheckBox.setSelected(true);
changedCheckBox.setText(org.openide.util.NbBundle.getMessage(DateSearchPanel.class, "DateSearchPanel.changedCheckBox.text")); // NOI18N
changedCheckBox.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
changedCheckBoxActionPerformed(evt);
}
});
accessedCheckBox.setSelected(true);
accessedCheckBox.setText(org.openide.util.NbBundle.getMessage(DateSearchPanel.class, "DateSearchPanel.accessedCheckBox.text")); // NOI18N
accessedCheckBox.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
accessedCheckBoxActionPerformed(evt);
}
});
createdCheckBox.setSelected(true);
createdCheckBox.setText(org.openide.util.NbBundle.getMessage(DateSearchPanel.class, "DateSearchPanel.createdCheckBox.text")); // NOI18N
createdCheckBox.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
createdCheckBoxActionPerformed(evt);
}
});
dateFromButtonCalendar.setText(org.openide.util.NbBundle.getMessage(DateSearchPanel.class, "DateSearchPanel.dateFromButtonCalendar.text")); // NOI18N
dateFromButtonCalendar.addPropertyChangeListener(new java.beans.PropertyChangeListener() {
@ -349,8 +382,25 @@ class DateSearchPanel extends javax.swing.JPanel {
private void dateCheckBoxActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_dateCheckBoxActionPerformed
this.setComponentsEnabled();
pcs.firePropertyChange(FileSearchPanel.EVENT.CHECKED.toString(), null, null);
}//GEN-LAST:event_dateCheckBoxActionPerformed
private void modifiedCheckBoxActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_modifiedCheckBoxActionPerformed
pcs.firePropertyChange(FileSearchPanel.EVENT.CHECKED.toString(), null, null);
}//GEN-LAST:event_modifiedCheckBoxActionPerformed
private void accessedCheckBoxActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_accessedCheckBoxActionPerformed
pcs.firePropertyChange(FileSearchPanel.EVENT.CHECKED.toString(), null, null);
}//GEN-LAST:event_accessedCheckBoxActionPerformed
private void createdCheckBoxActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_createdCheckBoxActionPerformed
pcs.firePropertyChange(FileSearchPanel.EVENT.CHECKED.toString(), null, null);
}//GEN-LAST:event_createdCheckBoxActionPerformed
private void changedCheckBoxActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_changedCheckBoxActionPerformed
pcs.firePropertyChange(FileSearchPanel.EVENT.CHECKED.toString(), null, null);
}//GEN-LAST:event_changedCheckBoxActionPerformed
/**
* Validate and set the datetime field on the screen given a datetime
* string.
@ -379,6 +429,13 @@ class DateSearchPanel extends javax.swing.JPanel {
dateToTextField.setText(dateStringResult);
dateToButtonCalendar.setTargetDate(date);
}
boolean isValidSearch() {
return this.accessedCheckBox.isSelected() ||
this.changedCheckBox.isSelected() ||
this.createdCheckBox.isSelected() ||
this.modifiedCheckBox.isSelected();
}
// Variables declaration - do not modify//GEN-BEGIN:variables
private javax.swing.JCheckBox accessedCheckBox;
private javax.swing.JCheckBox changedCheckBox;

View File

@ -19,6 +19,7 @@
package org.sleuthkit.autopsy.filesearch;
import java.awt.event.ActionListener;
import java.beans.PropertyChangeListener;
import javax.swing.JComponent;
/**
@ -40,6 +41,13 @@ interface FileSearchFilter {
*/
boolean isEnabled();
/**
* Checks if the panel has valid input for search.
*
* @return Whether the panel has valid input for search.
*/
boolean isValid();
/**
* Gets predicate expression to include in the SQL filter expression
*
@ -56,6 +64,13 @@ interface FileSearchFilter {
*/
void addActionListener(ActionListener l);
/**
* Adds the property change listener to the panel
*
* @param listener the listener to add.
*/
void addPropertyChangeListener(PropertyChangeListener listener);
/**
* Thrown if a filter's inputs are invalid
*/

View File

@ -17,38 +17,35 @@
* limitations under the License.
*/
/*
/*
* FileSearchPanel.java
*
* Created on Mar 5, 2012, 1:51:50 PM
*/
package org.sleuthkit.autopsy.filesearch;
import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Cursor;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.logging.Level;
import org.openide.util.NbBundle;
import org.sleuthkit.autopsy.coreutils.Logger;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.border.EmptyBorder;
import org.openide.DialogDisplayer;
import org.openide.NotifyDescriptor;
import org.openide.util.NbBundle;
import org.openide.windows.TopComponent;
import org.sleuthkit.autopsy.casemodule.Case;
import org.sleuthkit.autopsy.corecomponents.DataResultTopComponent;
import org.sleuthkit.autopsy.corecomponents.TableFilterNode;
import org.sleuthkit.autopsy.coreutils.Logger;
import org.sleuthkit.autopsy.coreutils.MessageNotifyUtil;
import org.sleuthkit.autopsy.filesearch.FileSearchFilter.FilterValidationException;
import org.sleuthkit.datamodel.AbstractFile;
@ -64,6 +61,10 @@ class FileSearchPanel extends javax.swing.JPanel {
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");
enum EVENT {
CHECKED
}
/**
* Creates new form FileSearchPanel
*/
@ -100,25 +101,39 @@ class FileSearchPanel extends javax.swing.JPanel {
filterPanel.add(fa);
}
for (FileSearchFilter filter : this.getFilters()) {
filter.addPropertyChangeListener(new PropertyChangeListener() {
@Override
public void propertyChange(PropertyChangeEvent evt) {
searchButton.setEnabled(isValidSearch());
}
});
}
addListenerToAll(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
search();
}
});
searchButton.setEnabled(isValidSearch());
}
/**
* @return true if any of the filters in the panel are enabled (checked)
*/
private boolean anyFiltersEnabled() {
private boolean isValidSearch() {
boolean enabled = false;
for (FileSearchFilter filter : this.getFilters()) {
if (filter.isEnabled()) {
return true;
enabled = true;
if (!filter.isValid()) {
return false;
}
}
}
return false;
return enabled;
}
/**
@ -129,7 +144,7 @@ class FileSearchPanel extends javax.swing.JPanel {
// change the cursor to "waiting cursor" for this operation
this.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
try {
if (this.anyFiltersEnabled()) {
if (this.isValidSearch()) {
String title = NbBundle.getMessage(this.getClass(), "FileSearchPanel.search.results.title", ++resultWindowCount);
String pathText = NbBundle.getMessage(this.getClass(), "FileSearchPanel.search.results.pathText");
@ -290,6 +305,7 @@ class FileSearchPanel extends javax.swing.JPanel {
.addContainerGap())
);
}// </editor-fold>//GEN-END:initComponents
// Variables declaration - do not modify//GEN-BEGIN:variables
private javax.swing.JPanel filterPanel;
private javax.swing.JButton searchButton;

View File

@ -19,7 +19,6 @@
package org.sleuthkit.autopsy.filesearch;
import java.awt.event.ActionListener;
import org.openide.util.NbBundle;
import org.sleuthkit.datamodel.TskData.FileKnown;
@ -42,6 +41,7 @@ class KnownStatusSearchFilter extends AbstractFileSearchFilter<KnownStatusSearch
@Override
public boolean isEnabled() {
return this.getComponent().getKnownCheckBox().isSelected();
}
@Override
@ -83,4 +83,9 @@ class KnownStatusSearchFilter extends AbstractFileSearchFilter<KnownStatusSearch
@Override
public void addActionListener(ActionListener l) {
}
@Override
public boolean isValid() {
return this.getComponent().isValidSearch();
}
}

View File

@ -64,6 +64,9 @@
<ResourceString bundle="org/sleuthkit/autopsy/filesearch/Bundle.properties" key="KnownStatusSearchPanel.unknownOptionCheckBox.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="unknownOptionCheckBoxActionPerformed"/>
</Events>
</Component>
<Component class="javax.swing.JCheckBox" name="knownOptionCheckBox">
<Properties>
@ -83,6 +86,9 @@
<ResourceString bundle="org/sleuthkit/autopsy/filesearch/Bundle.properties" key="KnownStatusSearchPanel.knownBadOptionCheckBox.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="knownBadOptionCheckBoxActionPerformed"/>
</Events>
</Component>
</SubComponents>
</Form>

View File

@ -17,13 +17,15 @@
* limitations under the License.
*/
/*
/*
* KnownStatusSearchPanel.java
*
* Created on Oct 19, 2011, 11:45:44 AM
*/
package org.sleuthkit.autopsy.filesearch;
import java.beans.PropertyChangeListener;
import java.beans.PropertyChangeSupport;
import javax.swing.JCheckBox;
/**
@ -32,6 +34,8 @@ import javax.swing.JCheckBox;
*/
class KnownStatusSearchPanel extends javax.swing.JPanel {
private final PropertyChangeSupport pcs = new PropertyChangeSupport(this);
/**
* Creates new form KnownStatusSearchPanel
*/
@ -55,7 +59,7 @@ class KnownStatusSearchPanel extends javax.swing.JPanel {
JCheckBox getUnknownOptionCheckBox() {
return unknownOptionCheckBox;
}
private void setComponentsEnabled() {
boolean enabled = this.knownCheckBox.isSelected();
this.unknownOptionCheckBox.setEnabled(enabled);
@ -63,6 +67,20 @@ class KnownStatusSearchPanel extends javax.swing.JPanel {
this.knownBadOptionCheckBox.setEnabled(enabled);
}
@Override
public void addPropertyChangeListener(PropertyChangeListener pcl) {
pcs.addPropertyChangeListener(pcl);
}
@Override
public void removePropertyChangeListener(PropertyChangeListener pcl) {
pcs.removePropertyChangeListener(pcl);
}
boolean isValidSearch() {
return this.unknownOptionCheckBox.isSelected() || this.knownBadOptionCheckBox.isSelected() || this.knownOptionCheckBox.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
@ -86,6 +104,11 @@ class KnownStatusSearchPanel extends javax.swing.JPanel {
unknownOptionCheckBox.setSelected(true);
unknownOptionCheckBox.setText(org.openide.util.NbBundle.getMessage(KnownStatusSearchPanel.class, "KnownStatusSearchPanel.unknownOptionCheckBox.text")); // NOI18N
unknownOptionCheckBox.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
unknownOptionCheckBoxActionPerformed(evt);
}
});
knownOptionCheckBox.setSelected(true);
knownOptionCheckBox.setText(org.openide.util.NbBundle.getMessage(KnownStatusSearchPanel.class, "KnownStatusSearchPanel.knownOptionCheckBox.text")); // NOI18N
@ -97,6 +120,11 @@ class KnownStatusSearchPanel extends javax.swing.JPanel {
knownBadOptionCheckBox.setSelected(true);
knownBadOptionCheckBox.setText(org.openide.util.NbBundle.getMessage(KnownStatusSearchPanel.class, "KnownStatusSearchPanel.knownBadOptionCheckBox.text")); // NOI18N
knownBadOptionCheckBox.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
knownBadOptionCheckBoxActionPerformed(evt);
}
});
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
this.setLayout(layout);
@ -127,13 +155,22 @@ class KnownStatusSearchPanel extends javax.swing.JPanel {
}// </editor-fold>//GEN-END:initComponents
private void knownOptionCheckBoxActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_knownOptionCheckBoxActionPerformed
// TODO add your handling code here:
pcs.firePropertyChange(FileSearchPanel.EVENT.CHECKED.toString(), null, null);
}//GEN-LAST:event_knownOptionCheckBoxActionPerformed
private void knownCheckBoxActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_knownCheckBoxActionPerformed
setComponentsEnabled();
pcs.firePropertyChange(FileSearchPanel.EVENT.CHECKED.toString(), null, null);
}//GEN-LAST:event_knownCheckBoxActionPerformed
private void unknownOptionCheckBoxActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_unknownOptionCheckBoxActionPerformed
pcs.firePropertyChange(FileSearchPanel.EVENT.CHECKED.toString(), null, null);
}//GEN-LAST:event_unknownOptionCheckBoxActionPerformed
private void knownBadOptionCheckBoxActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_knownBadOptionCheckBoxActionPerformed
pcs.firePropertyChange(FileSearchPanel.EVENT.CHECKED.toString(), null, null);
}//GEN-LAST:event_knownBadOptionCheckBoxActionPerformed
// Variables declaration - do not modify//GEN-BEGIN:variables
private javax.swing.JCheckBox knownBadOptionCheckBox;
private javax.swing.JCheckBox knownCheckBox;

View File

@ -10,28 +10,28 @@ import java.awt.event.ActionListener;
/**
* Filter by mime type used in filter areas of file search by attribute.
*/
class MimeTypeFilter extends AbstractFileSearchFilter<MimeTypePanel> {
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();
return this.getComponent().isSelected();
}
@Override
public String getPredicate() throws FilterValidationException {
String predicate = "";
for(String mimeType : this.getComponent().getMimeTypesSelected()) {
for (String mimeType : this.getComponent().getMimeTypesSelected()) {
predicate += "mime_type = '" + mimeType + "' OR ";
}
if(predicate.length() > 3) {
if (predicate.length() > 3) {
predicate = predicate.substring(0, predicate.length() - 3);
}
return predicate;
@ -40,5 +40,9 @@ class MimeTypeFilter extends AbstractFileSearchFilter<MimeTypePanel> {
@Override
public void addActionListener(ActionListener l) {
}
@Override
public boolean isValid() {
return !this.getComponent().getMimeTypesSelected().isEmpty();
}
}

View File

@ -31,7 +31,7 @@
<Group type="102" attributes="0">
<EmptySpace max="-2" attributes="0"/>
<Group type="103" groupAlignment="0" attributes="0">
<Component id="jScrollPane1" pref="298" max="32767" 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"/>

View File

@ -5,12 +5,16 @@
*/
package org.sleuthkit.autopsy.filesearch;
import java.beans.PropertyChangeListener;
import java.beans.PropertyChangeSupport;
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 javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import org.apache.tika.mime.MediaType;
import org.apache.tika.mime.MimeTypes;
import org.sleuthkit.autopsy.coreutils.Logger;
@ -25,6 +29,7 @@ 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;
private final PropertyChangeSupport pcs = new PropertyChangeSupport(this);
/**
* Creates new form MimeTypePanel
@ -32,6 +37,12 @@ public class MimeTypePanel extends javax.swing.JPanel {
public MimeTypePanel() {
initComponents();
setComponentsEnabled();
this.mimeTypeList.addListSelectionListener(new ListSelectionListener() {
@Override
public void valueChanged(ListSelectionEvent e) {
pcs.firePropertyChange(FileSearchPanel.EVENT.CHECKED.toString(), null, null);
}
});
}
private String[] getMimeTypeArray() {
@ -75,6 +86,16 @@ public class MimeTypePanel extends javax.swing.JPanel {
this.mimeTypeList.setEnabled(enabled);
this.jLabel1.setEnabled(enabled);
}
@Override
public void addPropertyChangeListener(PropertyChangeListener pcl) {
pcs.addPropertyChangeListener(pcl);
}
@Override
public void removePropertyChangeListener(PropertyChangeListener pcl) {
pcs.removePropertyChangeListener(pcl);
}
/**
* This method is called from within the constructor to initialize the form.
@ -141,6 +162,8 @@ public class MimeTypePanel extends javax.swing.JPanel {
private void mimeTypeCheckBoxActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_mimeTypeCheckBoxActionPerformed
setComponentsEnabled();
pcs.firePropertyChange(FileSearchPanel.EVENT.CHECKED.toString(), null, null);
this.mimeTypeList.setSelectedIndices(new int[0]);
}//GEN-LAST:event_mimeTypeCheckBoxActionPerformed

View File

@ -19,7 +19,6 @@
package org.sleuthkit.autopsy.filesearch;
import java.awt.event.ActionListener;
import org.openide.util.NbBundle;
import org.sleuthkit.autopsy.filesearch.FileSearchFilter.FilterValidationException;
@ -63,4 +62,9 @@ class NameSearchFilter extends AbstractFileSearchFilter<NameSearchPanel> {
public void addActionListener(ActionListener l) {
getComponent().addActionListener(l);
}
@Override
public boolean isValid() {
return !this.getComponent().getSearchTextField().getText().isEmpty();
}
}

View File

@ -17,7 +17,7 @@
* limitations under the License.
*/
/*
/*
* NameSearchPanel.java
*
* Created on Oct 19, 2011, 11:58:53 AM
@ -26,9 +26,13 @@ package org.sleuthkit.autopsy.filesearch;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.beans.PropertyChangeListener;
import java.beans.PropertyChangeSupport;
import javax.swing.JCheckBox;
import javax.swing.JMenuItem;
import javax.swing.JTextField;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
/**
*
@ -36,6 +40,8 @@ import javax.swing.JTextField;
*/
class NameSearchPanel extends javax.swing.JPanel {
private final PropertyChangeSupport pcs = new PropertyChangeSupport(this);
/**
* Creates new form NameSearchPanel
*/
@ -67,6 +73,22 @@ class NameSearchPanel extends javax.swing.JPanel {
copyMenuItem.addActionListener(actList);
pasteMenuItem.addActionListener(actList);
selectAllMenuItem.addActionListener(actList);
this.searchTextField.getDocument().addDocumentListener(new DocumentListener() {
@Override
public void insertUpdate(DocumentEvent e) {
pcs.firePropertyChange(FileSearchPanel.EVENT.CHECKED.toString(), null, null);
}
@Override
public void removeUpdate(DocumentEvent e) {
pcs.firePropertyChange(FileSearchPanel.EVENT.CHECKED.toString(), null, null);
}
@Override
public void changedUpdate(DocumentEvent e) {
pcs.firePropertyChange(FileSearchPanel.EVENT.CHECKED.toString(), null, null);
}
});
}
@ -77,12 +99,22 @@ class NameSearchPanel extends javax.swing.JPanel {
JTextField getSearchTextField() {
return searchTextField;
}
void setComponentsEnabled() {
boolean enabled = nameCheckBox.isSelected();
this.searchTextField.setEnabled(enabled);
this.noteNameLabel.setEnabled(enabled);
}
@Override
public void addPropertyChangeListener(PropertyChangeListener pcl) {
pcs.addPropertyChangeListener(pcl);
}
@Override
public void removePropertyChangeListener(PropertyChangeListener pcl) {
pcs.removePropertyChangeListener(pcl);
}
/**
* This method is called from within the constructor to initialize the form.
@ -168,6 +200,7 @@ class NameSearchPanel extends javax.swing.JPanel {
private void nameCheckBoxActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_nameCheckBoxActionPerformed
setComponentsEnabled();
pcs.firePropertyChange(FileSearchPanel.EVENT.CHECKED.toString(), null, null);
}//GEN-LAST:event_nameCheckBoxActionPerformed
// Variables declaration - do not modify//GEN-BEGIN:variables

View File

@ -20,7 +20,6 @@ package org.sleuthkit.autopsy.filesearch;
import java.awt.event.ActionListener;
import javax.swing.JComboBox;
import org.openide.util.NbBundle;
import org.sleuthkit.autopsy.filesearch.FileSearchFilter.FilterValidationException;
@ -73,4 +72,9 @@ class SizeSearchFilter extends AbstractFileSearchFilter<SizeSearchPanel> {
public void addActionListener(ActionListener l) {
getComponent().addActionListener(l);
}
@Override
public boolean isValid() {
return true;
}
}

View File

@ -20,6 +20,8 @@ package org.sleuthkit.autopsy.filesearch;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.beans.PropertyChangeListener;
import java.beans.PropertyChangeSupport;
import java.text.NumberFormat;
import javax.swing.JCheckBox;
import javax.swing.JComboBox;
@ -32,6 +34,8 @@ import javax.swing.JMenuItem;
*/
class SizeSearchPanel extends javax.swing.JPanel {
private final PropertyChangeSupport pcs = new PropertyChangeSupport(this);
/**
* Creates new form SizeSearchPanel
*/
@ -81,13 +85,23 @@ class SizeSearchPanel extends javax.swing.JPanel {
JComboBox<String> getSizeUnitComboBox() {
return sizeUnitComboBox;
}
void setComponentsEnabled() {
boolean enabled = this.sizeCheckBox.isSelected();
this.sizeCompareComboBox.setEnabled(enabled);
this.sizeUnitComboBox.setEnabled(enabled);
this.sizeTextField.setEnabled(enabled);
}
@Override
public void addPropertyChangeListener(PropertyChangeListener pcl) {
pcs.addPropertyChangeListener(pcl);
}
@Override
public void removePropertyChangeListener(PropertyChangeListener pcl) {
pcs.removePropertyChangeListener(pcl);
}
/**
* This method is called from within the constructor to initialize the form.
@ -168,6 +182,7 @@ class SizeSearchPanel extends javax.swing.JPanel {
private void sizeCheckBoxActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_sizeCheckBoxActionPerformed
setComponentsEnabled();
pcs.firePropertyChange(FileSearchPanel.EVENT.CHECKED.toString(), null, null);
}//GEN-LAST:event_sizeCheckBoxActionPerformed
// Variables declaration - do not modify//GEN-BEGIN:variables

View File

@ -32,9 +32,17 @@ import javax.swing.JOptionPane;
import org.netbeans.api.progress.ProgressHandle;
import org.openide.util.Cancellable;
import org.openide.util.NbBundle;
import org.sleuthkit.autopsy.casemodule.Case;
import org.sleuthkit.autopsy.coreutils.Logger;
import org.sleuthkit.autopsy.coreutils.NetworkUtils;
import org.sleuthkit.datamodel.AbstractFile;
import org.sleuthkit.datamodel.Content;
import org.sleuthkit.datamodel.IngestJobInfo;
import org.sleuthkit.datamodel.IngestJobInfo.IngestJobStatusType;
import org.sleuthkit.datamodel.IngestModuleInfo;
import org.sleuthkit.datamodel.IngestModuleInfo.IngestModuleType;
import org.sleuthkit.datamodel.SleuthkitCase;
import org.sleuthkit.datamodel.TskCoreException;
/**
* Encapsulates a data source and the ingest module pipelines used to process
@ -151,6 +159,8 @@ final class DataSourceIngestJob {
private ProgressHandle fileIngestProgress;
private String currentFileIngestModule = "";
private String currentFileIngestTask = "";
private List<IngestModuleInfo> ingestModules = new ArrayList<>();
private IngestJobInfo ingestJob;
/**
* A data source ingest job uses this field to report its creation time.
@ -243,6 +253,20 @@ final class DataSourceIngestJob {
*/
Thread.currentThread().interrupt();
}
SleuthkitCase skCase = Case.getCurrentCase().getSleuthkitCase();
try {
this.addIngestModules(firstStageDataSourceModuleTemplates, IngestModuleType.DATA_SOURCE_LEVEL, skCase);
this.addIngestModules(fileIngestModuleTemplates, IngestModuleType.FILE_LEVEL, skCase);
this.addIngestModules(secondStageDataSourceModuleTemplates, IngestModuleType.DATA_SOURCE_LEVEL, skCase);
} catch (TskCoreException ex) {
logger.log(Level.SEVERE, "Failed to add ingest modules to database.", ex);
}
}
private void addIngestModules(List<IngestModuleTemplate> templates, IngestModuleType type, SleuthkitCase skCase) throws TskCoreException {
for (IngestModuleTemplate module : templates) {
ingestModules.add(skCase.addIngestModule(module.getModuleName(), FactoryClassNameNormalizer.normalize(module.getModuleFactory().getClass().getCanonicalName()), type, module.getModuleFactory().getModuleVersionNumber()));
}
}
/**
@ -365,6 +389,11 @@ final class DataSourceIngestJob {
logger.log(Level.INFO, "Starting second stage analysis for {0} (jobId={1}), no first stage configured", new Object[]{dataSource.getName(), this.id}); //NON-NLS
this.startSecondStage();
}
try {
this.ingestJob = Case.getCurrentCase().getSleuthkitCase().addIngestJob(dataSource, NetworkUtils.getLocalHostName(), ingestModules, new Date(this.createTime), new Date(0), IngestJobStatusType.STARTED, "");
} catch (TskCoreException ex) {
logger.log(Level.SEVERE, "Failed to add ingest job to database.", ex);
}
}
return errors;
}
@ -641,8 +670,26 @@ final class DataSourceIngestJob {
}
}
}
if (this.cancelled) {
try {
ingestJob.setIngestJobStatus(IngestJobStatusType.CANCELLED);
} catch (TskCoreException ex) {
logger.log(Level.SEVERE, "Failed to set ingest status for ingest job in database.", ex);
}
} else {
try {
ingestJob.setIngestJobStatus(IngestJobStatusType.COMPLETED);
} catch (TskCoreException ex) {
logger.log(Level.SEVERE, "Failed to set ingest status for ingest job in database.", ex);
}
}
try {
this.ingestJob.setEndDateTime(new Date());
} catch (TskCoreException ex) {
logger.log(Level.SEVERE, "Failed to set end date for ingest job in database.", ex);
}
this.parentJob.dataSourceJobFinished(this);
}
/**

View File

@ -0,0 +1,42 @@
/*
* 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.ingest;
import org.sleuthkit.autopsy.coreutils.Logger;
/**
* Used to strip python ids on factory class names.
*/
class FactoryClassNameNormalizer {
private static final CharSequence pythonModuleSettingsPrefixCS = "org.python.proxies.".subSequence(0, "org.python.proxies.".length() - 1); //NON-NLS
private static final Logger logger = Logger.getLogger(FactoryClassNameNormalizer.class.getName());
static String normalize(String canonicalClassName) {
if (isPythonModuleSettingsFile(canonicalClassName)) {
// compiled python modules have variable instance number as a part of their file name.
// This block of code gets rid of that variable instance number and helps maitains constant module name over multiple runs.
String moduleClassName = canonicalClassName.replaceAll("[$][\\d]", ""); //NON-NLS NON-NLS
return moduleClassName;
}
return canonicalClassName;
}
/**
* Determines if the moduleSettingsFilePath is that of a serialized jython
* instance. Serialized Jython instances (settings saved on the disk)
* contain "org.python.proxies." in their fileName based on the current
* implementation.
*
* @param moduleSettingsFilePath path to the module settings file.
*
* @return True or false
*/
private static boolean isPythonModuleSettingsFile(String moduleSettingsFilePath) {
return moduleSettingsFilePath.contains(pythonModuleSettingsPrefixCS);
}
}

View File

@ -33,10 +33,10 @@ import java.util.logging.Level;
import org.openide.util.NbBundle;
import org.openide.util.io.NbObjectInputStream;
import org.openide.util.io.NbObjectOutputStream;
import org.python.util.PythonObjectInputStream;
import org.sleuthkit.autopsy.coreutils.Logger;
import org.sleuthkit.autopsy.coreutils.ModuleSettings;
import org.sleuthkit.autopsy.coreutils.PlatformUtil;
import org.sleuthkit.autopsy.coreutils.Logger;
import org.python.util.PythonObjectInputStream;
/**
* Encapsulates the ingest job settings for a particular execution context.
@ -467,17 +467,9 @@ public class IngestJobSettings {
* @param settings The ingest job settings for the ingest module
*/
private void saveModuleSettings(IngestModuleFactory factory, IngestModuleIngestJobSettings settings) {
try {
String moduleSettingsFilePath = getModuleSettingsFilePath(factory);
// compiled python modules have substring org.python.proxies. It can be used to identify them.
if (isPythonModuleSettingsFile(moduleSettingsFilePath)) {
// compiled python modules have variable instance number as a part of their file name.
// This block of code gets rid of that variable instance number and helps maitains constant module name over multiple runs.
moduleSettingsFilePath = moduleSettingsFilePath.replaceAll("[$][\\d]+.settings$", "\\$.settings"); //NON-NLS NON-NLS
}
try (NbObjectOutputStream out = new NbObjectOutputStream(new FileOutputStream(moduleSettingsFilePath))) {
out.writeObject(settings);
}
String moduleSettingsFilePath = Paths.get(this.moduleSettingsFolderPath, FactoryClassNameNormalizer.normalize(factory.getClass().getCanonicalName()) + MODULE_SETTINGS_FILE_EXT).toString();
try (NbObjectOutputStream out = new NbObjectOutputStream(new FileOutputStream(moduleSettingsFilePath))) {
out.writeObject(settings);
} catch (IOException ex) {
String warning = NbBundle.getMessage(IngestJobSettings.class, "IngestJobSettings.moduleSettingsSave.warning", factory.getModuleDisplayName(), this.executionContext); //NON-NLS
logger.log(Level.SEVERE, warning, ex);

View File

@ -1,7 +1,7 @@
/*
* Autopsy Forensic Browser
*
* Copyright 2014 Basis Technology Corp.
* Copyright 2011-2016 Basis Technology Corp.
* Contact: carrier <at> sleuthkit <dot> org
*
* Licensed under the Apache License, Version 2.0 (the "License");
@ -23,7 +23,9 @@ import org.sleuthkit.datamodel.BlackboardArtifact;
import org.sleuthkit.datamodel.TskCoreException;
/**
*
* An implementation of a keyword search service.
*
* TODO (AUT-2158: This interface should not extend Closeable.
*/
public interface KeywordSearchService extends Closeable {
@ -49,4 +51,4 @@ public interface KeywordSearchService extends Closeable {
*/
public void tryConnect(String host, int port) throws KeywordSearchServiceException;
}
}

View File

@ -26,7 +26,6 @@ import java.sql.SQLException;
import java.sql.Statement;
import java.util.List;
import java.util.logging.Level;
import org.openide.util.NbBundle;
import org.sleuthkit.autopsy.casemodule.Case;
import org.sleuthkit.autopsy.casemodule.services.Blackboard;
@ -72,6 +71,7 @@ class BrowserLocationAnalyzer {
}
}
@NbBundle.Messages({"BrowserLocationAnalyzer.indexError.message=Failed to index GPS trackpoint artifact for keyword search."})
private static void findGeoLocationsInDB(String DatabasePath, AbstractFile f) {
Connection connection = null;
ResultSet resultSet = null;
@ -110,9 +110,9 @@ class BrowserLocationAnalyzer {
// index the artifact for keyword search
blackboard.indexArtifact(bba);
} catch (Blackboard.BlackboardException ex) {
logger.log(Level.SEVERE, NbBundle.getMessage(Blackboard.class, "Blackboard.unableToIndexArtifact.error.msg", bba.getDisplayName()), ex); //NON-NLS
logger.log(Level.SEVERE, "Unable to index blackboard artifact " + bba.getArtifactTypeName(), ex); //NON-NLS
MessageNotifyUtil.Notify.error(
NbBundle.getMessage(Blackboard.class, "Blackboard.unableToIndexArtifact.exception.msg"), bba.getDisplayName());
Bundle.BrowserLocationAnalyzer_indexError_message(), bba.getDisplayName());
}
}
} catch (Exception e) {

View File

@ -25,8 +25,8 @@ import java.math.BigInteger;
import java.nio.ByteBuffer;
import java.util.List;
import java.util.logging.Level;
import org.openide.util.NbBundle;
import org.openide.util.NbBundle.Messages;
import org.sleuthkit.autopsy.casemodule.Case;
import org.sleuthkit.autopsy.casemodule.services.Blackboard;
import org.sleuthkit.autopsy.casemodule.services.FileManager;
@ -78,6 +78,7 @@ class CacheLocationAnalyzer {
}
}
@Messages({"CacheLocationAnalyzer.indexError.message=Failed to index GPS trackpoint artifact for keyword search."})
private static void findGeoLocationsInFile(File file, AbstractFile f) {
byte[] bytes; // will temporarily hold bytes to be converted into the correct data types
@ -140,14 +141,13 @@ class CacheLocationAnalyzer {
//Not storing these for now.
// bba.addAttribute(new BlackboardAttribute(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_VALUE.getTypeID(),moduleName, accuracy));
// bba.addAttribute(new BlackboardAttribute(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_COMMENT.getTypeID(),moduleName, confidence));
try {
// index the artifact for keyword search
blackboard.indexArtifact(bba);
} catch (Blackboard.BlackboardException ex) {
logger.log(Level.SEVERE, NbBundle.getMessage(Blackboard.class, "Blackboard.unableToIndexArtifact.error.msg", bba.getDisplayName()), ex); //NON-NLS
logger.log(Level.SEVERE, "Unable to index blackboard artifact " + bba.getArtifactID(), ex); //NON-NLS
MessageNotifyUtil.Notify.error(
NbBundle.getMessage(Blackboard.class, "Blackboard.unableToIndexArtifact.exception.msg"), bba.getDisplayName());
Bundle.CacheLocationAnalyzer_indexError_message(), bba.getDisplayName());
}
}

View File

@ -28,7 +28,7 @@ import java.sql.Statement;
import java.util.Arrays;
import java.util.List;
import java.util.logging.Level;
import org.openide.util.NbBundle;
import org.openide.util.NbBundle.Messages;
import org.sleuthkit.autopsy.casemodule.Case;
import org.sleuthkit.autopsy.casemodule.services.Blackboard;
import org.sleuthkit.autopsy.casemodule.services.FileManager;
@ -58,7 +58,7 @@ class CallLogAnalyzer {
private static final Iterable<String> tableNames = Arrays.asList("calls", "logs"); //NON-NLS
public static void findCallLogs(Content dataSource, FileManager fileManager) {
blackboard = Case.getCurrentCase().getServices().getBlackboard();
blackboard = Case.getCurrentCase().getServices().getBlackboard();
try {
List<AbstractFile> absFiles = fileManager.findFiles(dataSource, "logs.db"); //NON-NLS
absFiles.addAll(fileManager.findFiles(dataSource, "contacts.db")); //NON-NLS
@ -77,6 +77,7 @@ class CallLogAnalyzer {
}
}
@Messages({"CallLogAnalyzer.indexError.message=Failed to index call log artifact for keyword search."})
private static void findCallLogsInDB(String DatabasePath, AbstractFile f) {
if (DatabasePath == null || DatabasePath.isEmpty()) {
@ -113,16 +114,16 @@ class CallLogAnalyzer {
// index the artifact for keyword search
blackboard.indexArtifact(bba);
} catch (Blackboard.BlackboardException ex) {
logger.log(Level.SEVERE, NbBundle.getMessage(Blackboard.class, "Blackboard.unableToIndexArtifact.error.msg", bba.getDisplayName()), ex); //NON-NLS
logger.log(Level.SEVERE, "Unable to index blackboard artifact " + bba.getArtifactID(), ex); //NON-NLS
MessageNotifyUtil.Notify.error(
NbBundle.getMessage(Blackboard.class, "Blackboard.unableToIndexArtifact.exception.msg"), bba.getDisplayName());
Bundle.CallLogAnalyzer_indexError_message(), bba.getDisplayName());
}
} catch (TskCoreException ex) {
logger.log(Level.SEVERE, "Error posting call log record to the Blackboard", ex); //NON-NLS
}
}
} catch (SQLException e) {
logger.log(Level.WARNING, "Could not read table {0} in db {1}", new Object[]{tableName, DatabasePath}); //NON-NLS
logger.log(Level.WARNING, String.format("Could not read table %s in db %s", tableName, DatabasePath), e); //NON-NLS
}
}
} catch (SQLException e) {

View File

@ -27,7 +27,7 @@ import java.sql.SQLException;
import java.sql.Statement;
import java.util.List;
import java.util.logging.Level;
import org.openide.util.NbBundle;
import org.openide.util.NbBundle.Messages;
import org.sleuthkit.autopsy.casemodule.Case;
import org.sleuthkit.autopsy.casemodule.services.Blackboard;
import org.sleuthkit.autopsy.casemodule.services.FileManager;
@ -79,6 +79,7 @@ class ContactAnalyzer {
* path The fileId will be the Abstract file associated
* with the artifacts
*/
@Messages({"ContactAnalyzer.indexError.message=Failed to index contact artifact for keyword search."})
private static void findContactsInDB(String databasePath, AbstractFile f) {
Connection connection = null;
ResultSet resultSet = null;
@ -154,9 +155,9 @@ class ContactAnalyzer {
// index the artifact for keyword search
blackboard.indexArtifact(bba);
} catch (Blackboard.BlackboardException ex) {
logger.log(Level.SEVERE, NbBundle.getMessage(Blackboard.class, "Blackboard.unableToIndexArtifact.error.msg", bba.getDisplayName()), ex); //NON-NLS
logger.log(Level.SEVERE, "Unable to index blackboard artifact " + bba.getArtifactID(), ex); //NON-NLS
MessageNotifyUtil.Notify.error(
NbBundle.getMessage(Blackboard.class, "Blackboard.unableToIndexArtifact.exception.msg"), bba.getDisplayName());
Bundle.ContactAnalyzer_indexError_message(), bba.getDisplayName());
}
}

View File

@ -26,8 +26,8 @@ import java.sql.SQLException;
import java.sql.Statement;
import java.util.List;
import java.util.logging.Level;
import org.openide.util.NbBundle;
import org.openide.util.NbBundle.Messages;
import org.sleuthkit.autopsy.casemodule.Case;
import org.sleuthkit.autopsy.casemodule.services.Blackboard;
import org.sleuthkit.autopsy.casemodule.services.FileManager;
@ -71,6 +71,7 @@ class GoogleMapLocationAnalyzer {
}
}
@Messages({"GoogleMapLocationAnalyzer.indexError.message=Failed to index GPS route artifact for keyword search."})
private static void findGeoLocationsInDB(String DatabasePath, AbstractFile f) {
Connection connection = null;
ResultSet resultSet = null;
@ -136,9 +137,9 @@ class GoogleMapLocationAnalyzer {
// index the artifact for keyword search
blackboard.indexArtifact(bba);
} catch (Blackboard.BlackboardException ex) {
logger.log(Level.SEVERE, NbBundle.getMessage(Blackboard.class, "Blackboard.unableToIndexArtifact.error.msg", bba.getDisplayName()), ex); //NON-NLS
logger.log(Level.SEVERE, "Unable to index blackboard artifact " + bba.getArtifactID(), ex); //NON-NLS
MessageNotifyUtil.Notify.error(
NbBundle.getMessage(Blackboard.class, "Blackboard.unableToIndexArtifact.exception.msg"), bba.getDisplayName());
Bundle.GoogleMapLocationAnalyzer_indexError_message(), bba.getDisplayName());
}
}
} catch (Exception e) {

View File

@ -28,6 +28,7 @@ import java.util.List;
import java.util.logging.Level;
import org.apache.commons.codec.binary.Base64;
import org.openide.util.NbBundle;
import org.openide.util.NbBundle.Messages;
import org.sleuthkit.autopsy.casemodule.Case;
import org.sleuthkit.autopsy.casemodule.services.Blackboard;
import org.sleuthkit.autopsy.casemodule.services.FileManager;
@ -68,6 +69,7 @@ class TangoMessageAnalyzer {
}
}
@Messages({"TangoMessageAnalyzer.indexError.message=Failed to index Tango message artifact for keyword search."})
private static void findTangoMessagesInDB(String DatabasePath, AbstractFile f) {
Connection connection = null;
ResultSet resultSet = null;
@ -110,14 +112,14 @@ class TangoMessageAnalyzer {
bba.addAttribute(new BlackboardAttribute(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_MESSAGE_TYPE, moduleName,
NbBundle.getMessage(TangoMessageAnalyzer.class,
"TangoMessageAnalyzer.bbAttribute.tangoMessage")));
try {
// index the artifact for keyword search
blackboard.indexArtifact(bba);
} catch (Blackboard.BlackboardException ex) {
logger.log(Level.SEVERE, NbBundle.getMessage(Blackboard.class, "Blackboard.unableToIndexArtifact.error.msg", bba.getDisplayName()), ex); //NON-NLS
MessageNotifyUtil.Notify.error(
NbBundle.getMessage(Blackboard.class, "Blackboard.unableToIndexArtifact.exception.msg"), bba.getDisplayName());
Bundle.TangoMessageAnalyzer_indexError_message(), bba.getDisplayName());
logger.log(Level.SEVERE, "Unable to index blackboard artifact " + bba.getArtifactID(), ex); //NON-NLS
}
}
} catch (Exception e) {

View File

@ -26,8 +26,8 @@ import java.sql.SQLException;
import java.sql.Statement;
import java.util.List;
import java.util.logging.Level;
import org.openide.util.NbBundle;
import org.openide.util.NbBundle.Messages;
import org.sleuthkit.autopsy.casemodule.Case;
import org.sleuthkit.autopsy.casemodule.services.Blackboard;
import org.sleuthkit.autopsy.casemodule.services.FileManager;
@ -68,6 +68,7 @@ class TextMessageAnalyzer {
}
}
@Messages({"TextMessageAnalyzer.indexError.message=Failed to index text message artifact for keyword search."})
private static void findTextsInDB(String DatabasePath, AbstractFile f) {
Connection connection = null;
ResultSet resultSet = null;
@ -123,14 +124,14 @@ class TextMessageAnalyzer {
bba.addAttribute(new BlackboardAttribute(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_MESSAGE_TYPE, moduleName,
NbBundle.getMessage(TextMessageAnalyzer.class,
"TextMessageAnalyzer.bbAttribute.smsMessage")));
try {
// index the artifact for keyword search
blackboard.indexArtifact(bba);
} catch (Blackboard.BlackboardException ex) {
logger.log(Level.SEVERE, NbBundle.getMessage(Blackboard.class, "Blackboard.unableToIndexArtifact.error.msg", bba.getDisplayName()), ex); //NON-NLS
logger.log(Level.SEVERE, "Unable to index blackboard artifact " + bba.getArtifactID(), ex); //NON-NLS
MessageNotifyUtil.Notify.error(
NbBundle.getMessage(Blackboard.class, "Blackboard.unableToIndexArtifact.exception.msg"), bba.getDisplayName());
Bundle.TextMessageAnalyzer_indexError_message(), bba.getDisplayName());
}
}
} catch (Exception e) {

View File

@ -26,8 +26,8 @@ import java.sql.SQLException;
import java.sql.Statement;
import java.util.List;
import java.util.logging.Level;
import org.openide.util.NbBundle;
import org.openide.util.NbBundle.Messages;
import org.sleuthkit.autopsy.casemodule.Case;
import org.sleuthkit.autopsy.casemodule.services.Blackboard;
import org.sleuthkit.autopsy.casemodule.services.FileManager;
@ -71,6 +71,7 @@ class WWFMessageAnalyzer {
}
}
@Messages({"WWFMessageAnalyzer.indexError.message=Failed to index WWF message artifact for keyword search."})
private static void findWWFMessagesInDB(String DatabasePath, AbstractFile f) {
Connection connection = null;
ResultSet resultSet = null;
@ -110,14 +111,14 @@ class WWFMessageAnalyzer {
bba.addAttribute(new BlackboardAttribute(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_MESSAGE_TYPE, moduleName,
NbBundle.getMessage(WWFMessageAnalyzer.class,
"WWFMessageAnalyzer.bbAttribute.wordsWithFriendsMsg")));
try {
// index the artifact for keyword search
blackboard.indexArtifact(bba);
} catch (Blackboard.BlackboardException ex) {
logger.log(Level.SEVERE, NbBundle.getMessage(Blackboard.class, "Blackboard.unableToIndexArtifact.error.msg", bba.getDisplayName()), ex); //NON-NLS
logger.log(Level.SEVERE, "Unable to index blackboard artifact " + bba.getArtifactID(), ex); //NON-NLS
MessageNotifyUtil.Notify.error(
NbBundle.getMessage(Blackboard.class, "Blackboard.unableToIndexArtifact.exception.msg"), bba.getDisplayName());
Bundle.WWFMessageAnalyzer_indexError_message(), bba.getDisplayName());
}
}
} catch (Exception e) {

View File

@ -42,6 +42,7 @@ import net.sf.sevenzipjbinding.simple.ISimpleInArchive;
import net.sf.sevenzipjbinding.simple.ISimpleInArchiveItem;
import org.netbeans.api.progress.ProgressHandle;
import org.openide.util.NbBundle;
import org.openide.util.NbBundle.Messages;
import org.sleuthkit.autopsy.casemodule.Case;
import org.sleuthkit.autopsy.casemodule.services.Blackboard;
import org.sleuthkit.autopsy.casemodule.services.FileManager;
@ -50,7 +51,6 @@ import org.sleuthkit.autopsy.coreutils.Logger;
import org.sleuthkit.autopsy.coreutils.MessageNotifyUtil;
import org.sleuthkit.autopsy.ingest.IngestJobContext;
import org.sleuthkit.autopsy.ingest.IngestMessage;
import org.sleuthkit.autopsy.ingest.IngestModule.IngestModuleException;
import org.sleuthkit.autopsy.ingest.IngestMonitor;
import org.sleuthkit.autopsy.ingest.IngestServices;
import org.sleuthkit.autopsy.ingest.ModuleContentEvent;
@ -267,6 +267,7 @@ class SevenZipExtractor {
*
* @return list of unpacked derived files
*/
@Messages({"SevenZipExtractor.indexError.message=Failed to index encryption detected artifact for keyword search."})
void unpack(AbstractFile archiveFile) {
blackboard = Case.getCurrentCase().getServices().getBlackboard();
String archiveFilePath;
@ -586,9 +587,9 @@ class SevenZipExtractor {
// index the artifact for keyword search
blackboard.indexArtifact(artifact);
} catch (Blackboard.BlackboardException ex) {
logger.log(Level.SEVERE, NbBundle.getMessage(Blackboard.class, "Blackboard.unableToIndexArtifact.error.msg", artifact.getDisplayName()), ex); //NON-NLS
logger.log(Level.SEVERE, "Unable to index blackboard artifact " + artifact.getArtifactID(), ex); //NON-NLS
MessageNotifyUtil.Notify.error(
NbBundle.getMessage(Blackboard.class, "Blackboard.unableToIndexArtifact.exception.msg"), artifact.getDisplayName());
Bundle.SevenZipExtractor_indexError_message(), artifact.getDisplayName());
}
services.fireModuleDataEvent(new ModuleDataEvent(EmbeddedFileExtractorModuleFactory.getModuleName(), BlackboardArtifact.ARTIFACT_TYPE.TSK_ENCRYPTION_DETECTED));

View File

@ -38,15 +38,16 @@ import java.util.TimeZone;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.logging.Level;
import org.openide.util.NbBundle;
import org.openide.util.NbBundle.Messages;
import org.sleuthkit.autopsy.casemodule.Case;
import org.sleuthkit.autopsy.casemodule.services.Blackboard;
import org.sleuthkit.autopsy.coreutils.Logger;
import org.sleuthkit.autopsy.coreutils.MessageNotifyUtil;
import org.sleuthkit.autopsy.ingest.FileIngestModule;
import org.sleuthkit.autopsy.ingest.IngestJobContext;
import org.sleuthkit.autopsy.ingest.IngestModuleReferenceCounter;
import org.sleuthkit.autopsy.ingest.IngestServices;
import org.sleuthkit.autopsy.ingest.ModuleDataEvent;
import org.sleuthkit.autopsy.ingest.IngestModuleReferenceCounter;
import org.sleuthkit.autopsy.modules.filetypeid.FileTypeDetector;
import org.sleuthkit.datamodel.AbstractFile;
import org.sleuthkit.datamodel.BlackboardArtifact;
@ -133,6 +134,7 @@ public final class ExifParserFileIngestModule implements FileIngestModule {
return processFile(content);
}
@Messages({"ExifParserFileIngestModule.indexError.message=Failed to index EXIF Metadata artifact for keyword search."})
ProcessResult processFile(AbstractFile f) {
InputStream in = null;
BufferedInputStream bin = null;
@ -206,9 +208,9 @@ public final class ExifParserFileIngestModule implements FileIngestModule {
// index the artifact for keyword search
blackboard.indexArtifact(bba);
} catch (Blackboard.BlackboardException ex) {
logger.log(Level.SEVERE, NbBundle.getMessage(Blackboard.class, "Blackboard.unableToIndexArtifact.error.msg", bba.getDisplayName()), ex); //NON-NLS
logger.log(Level.SEVERE, "Unable to index blackboard artifact " + bba.getArtifactID(), ex); //NON-NLS
MessageNotifyUtil.Notify.error(
NbBundle.getMessage(Blackboard.class, "Blackboard.unableToIndexArtifact.exception.msg"), bba.getDisplayName());
Bundle.ExifParserFileIngestModule_indexError_message(), bba.getDisplayName());
}
filesToFire = true;
}

View File

@ -23,6 +23,7 @@ import java.util.HashMap;
import java.util.Set;
import java.util.logging.Level;
import org.openide.util.NbBundle;
import org.openide.util.NbBundle.Messages;
import org.sleuthkit.autopsy.casemodule.Case;
import org.sleuthkit.autopsy.casemodule.services.Blackboard;
import org.sleuthkit.autopsy.coreutils.Logger;
@ -105,6 +106,7 @@ public class FileExtMismatchIngestModule implements FileIngestModule {
}
@Override
@Messages({"FileExtMismatchIngestModule.indexError.message=Failed to index file extension mismatch artifact for keyword search."})
public ProcessResult process(AbstractFile abstractFile) {
blackboard = Case.getCurrentCase().getServices().getBlackboard();
if (this.settings.skipKnownFiles() && (abstractFile.getKnown() == FileKnown.KNOWN)) {
@ -139,9 +141,9 @@ public class FileExtMismatchIngestModule implements FileIngestModule {
// index the artifact for keyword search
blackboard.indexArtifact(bart);
} catch (Blackboard.BlackboardException ex) {
logger.log(Level.SEVERE, NbBundle.getMessage(Blackboard.class, "Blackboard.unableToIndexArtifact.error.msg", bart.getDisplayName()), ex); //NON-NLS
logger.log(Level.SEVERE, "Unable to index blackboard artifact " + bart.getArtifactID(), ex); //NON-NLS
MessageNotifyUtil.Notify.error(
NbBundle.getMessage(Blackboard.class, "Blackboard.unableToIndexArtifact.exception.msg"), bart.getDisplayName());
Bundle.FileExtMismatchIngestModule_indexError_message(), bart.getDisplayName());
}
services.fireModuleDataEvent(new ModuleDataEvent(FileExtMismatchDetectorModuleFactory.getModuleName(), ARTIFACT_TYPE.TSK_EXT_MISMATCH_DETECTED, Collections.singletonList(bart)));

View File

@ -104,6 +104,19 @@ final class CustomFileTypesManager {
return customTypes;
}
/**
* Gets the custom file types defined by Autopsy.
*
* @return A list of custom file types, possibly empty.
*/
synchronized List<FileType> getAutopsyDefinedFileTypes() {
/**
* It is safe to return references instead of copies in this snapshot
* because FileType objects are immutable.
*/
return new ArrayList<>(autopsyDefinedFileTypes);
}
/**
* Gets the user-defined custom file types.
*
@ -287,6 +300,15 @@ final class CustomFileTypesManager {
fileType = new FileType("application/x-iff", signatureList); //NON-NLS
autopsyDefinedFileTypes.add(fileType);
/*
* Add type for .tec files with leading End Of Image marker (JFIF JPEG)
*/
byteArray = DatatypeConverter.parseHexBinary("FFD9FFD8"); //NON-NLS
signatureList.clear();
signatureList.add(new Signature(byteArray, 0L));
fileType = new FileType("image/jpeg", signatureList); //NON-NLS
autopsyDefinedFileTypes.add(fileType);
} catch (IllegalArgumentException ex) {
/*
* parseHexBinary() throws this if the argument passed in is not hex

View File

@ -56,8 +56,8 @@ public class FileTypeDetector {
*/
public FileTypeDetector() throws FileTypeDetectorInitException {
try {
userDefinedFileTypes = CustomFileTypesManager.getInstance().getFileTypes();
autopsyDefinedFileTypes = CustomFileTypesManager.getInstance().getFileTypes();
userDefinedFileTypes = CustomFileTypesManager.getInstance().getUserDefinedFileTypes();
autopsyDefinedFileTypes = CustomFileTypesManager.getInstance().getAutopsyDefinedFileTypes();
} catch (CustomFileTypesManager.CustomFileTypesException ex) {
throw new FileTypeDetectorInitException("Error loading custom file types", ex); //NON-NLS
}
@ -168,7 +168,7 @@ public class FileTypeDetector {
/**
* 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.
* only if the add to case database flag is set.
*
* @param file The file to test.
* @param addToCaseDb Whether the MIME type should be added to the case

View File

@ -25,22 +25,24 @@
<DimensionLayout dim="0">
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" alignment="0" attributes="0">
<Component id="jPanel3" max="32767" attributes="0"/>
<Component id="jPanel3" pref="752" max="32767" attributes="0"/>
<EmptySpace min="-2" pref="0" max="-2" attributes="0"/>
</Group>
</Group>
</DimensionLayout>
<DimensionLayout dim="1">
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" alignment="0" attributes="0">
<Component id="jPanel3" max="32767" attributes="0"/>
<EmptySpace min="-2" pref="0" max="-2" attributes="0"/>
</Group>
<Component id="jPanel3" alignment="0" pref="345" max="32767" attributes="0"/>
</Group>
</DimensionLayout>
</Layout>
<SubComponents>
<Container class="javax.swing.JPanel" name="jPanel3">
<Properties>
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[781, 339]"/>
</Property>
</Properties>
<Layout>
<DimensionLayout dim="0">
@ -62,7 +64,7 @@
<EmptySpace max="-2" attributes="0"/>
<Component id="jLabel3" min="-2" max="-2" attributes="0"/>
<EmptySpace min="-2" max="-2" attributes="0"/>
<Component id="jScrollPane2" max="32767" attributes="0"/>
<Component id="jScrollPane2" pref="281" max="32767" attributes="0"/>
<EmptySpace min="-2" max="-2" attributes="0"/>
<Component id="ingestRunningWarningLabel" min="-2" pref="16" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
@ -101,7 +103,10 @@
<Container class="javax.swing.JScrollPane" name="jScrollPane2">
<Properties>
<Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[300, 100]"/>
<Dimension value="[300, 0]"/>
</Property>
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[550, 275]"/>
</Property>
</Properties>
@ -110,7 +115,7 @@
<Container class="javax.swing.JSplitPane" name="jSplitPane1">
<Properties>
<Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[558, 285]"/>
<Dimension value="[0, 0]"/>
</Property>
</Properties>
@ -119,7 +124,10 @@
<Container class="javax.swing.JPanel" name="jPanel1">
<Properties>
<Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[362, 283]"/>
<Dimension value="[362, 0]"/>
</Property>
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[362, 0]"/>
</Property>
</Properties>
<Constraints>
@ -154,14 +162,14 @@
<EmptySpace min="-2" pref="12" max="-2" attributes="0"/>
<Component id="jLabel2" min="-2" max="-2" attributes="0"/>
<EmptySpace min="-2" max="-2" attributes="0"/>
<Component id="typesScrollPane" pref="397" max="32767" attributes="0"/>
<EmptySpace min="-2" max="-2" attributes="0"/>
<Component id="typesScrollPane" pref="203" max="32767" attributes="0"/>
<EmptySpace min="-2" pref="10" max="-2" attributes="0"/>
<Group type="103" groupAlignment="3" attributes="0">
<Component id="newTypeButton" linkSize="2" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="editTypeButton" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="deleteTypeButton" linkSize="2" alignment="3" min="-2" max="-2" attributes="0"/>
</Group>
<EmptySpace min="-2" max="-2" attributes="0"/>
<EmptySpace min="-2" pref="7" max="-2" attributes="0"/>
</Group>
</Group>
</DimensionLayout>
@ -263,7 +271,7 @@
<Container class="javax.swing.JPanel" name="jPanel2">
<Properties>
<Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[79, 283]"/>
<Dimension value="[79, 0]"/>
</Property>
</Properties>
<Constraints>
@ -291,11 +299,11 @@
<DimensionLayout dim="1">
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" alignment="0" attributes="0">
<EmptySpace max="-2" attributes="0"/>
<Component id="jLabel1" min="-2" max="-2" attributes="0"/>
<EmptySpace min="-2" max="-2" attributes="0"/>
<Component id="jScrollPane1" pref="400" max="32767" attributes="0"/>
<EmptySpace min="-2" pref="40" max="-2" attributes="0"/>
<Component id="jLabel1" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="jScrollPane1" pref="235" max="32767" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
</Group>
</Group>
</DimensionLayout>
@ -320,6 +328,7 @@
<Property name="model" type="javax.swing.ListModel" editor="org.netbeans.modules.form.RADConnectionPropertyEditor">
<Connection code="new javax.swing.AbstractListModel&lt;Signature&gt;() {&#xa; Signature[] signatures = {};&#xa; public int getSize() { return signatures.length; }&#xa; public Signature getElementAt(int i) { return signatures[i]; }&#xa;}" type="code"/>
</Property>
<Property name="enabled" type="boolean" value="false"/>
<Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[32767, 32767]"/>
</Property>

View File

@ -36,8 +36,8 @@ import org.sleuthkit.autopsy.corecomponents.OptionsPanel;
import org.sleuthkit.autopsy.coreutils.Logger;
import org.sleuthkit.autopsy.ingest.IngestManager;
import org.sleuthkit.autopsy.ingest.IngestModuleGlobalSettingsPanel;
import org.sleuthkit.autopsy.modules.filetypeid.FileType.Signature;
import org.sleuthkit.autopsy.modules.filetypeid.CustomFileTypesManager.CustomFileTypesException;
import org.sleuthkit.autopsy.modules.filetypeid.FileType.Signature;
/**
* A panel to allow a user to make custom file type definitions. In addition to
@ -329,6 +329,8 @@ final class FileTypeIdGlobalSettingsPanel extends IngestModuleGlobalSettingsPane
setMaximumSize(null);
setPreferredSize(new java.awt.Dimension(752, 507));
jPanel3.setPreferredSize(new java.awt.Dimension(781, 339));
ingestRunningWarningLabel.setFont(ingestRunningWarningLabel.getFont().deriveFont(ingestRunningWarningLabel.getFont().getStyle() & ~java.awt.Font.BOLD, 11));
ingestRunningWarningLabel.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/modules/filetypeid/warning16.png"))); // NOI18N
org.openide.awt.Mnemonics.setLocalizedText(ingestRunningWarningLabel, org.openide.util.NbBundle.getMessage(FileTypeIdGlobalSettingsPanel.class, "FileTypeIdGlobalSettingsPanel.ingestRunningWarningLabel.text")); // NOI18N
@ -336,11 +338,13 @@ final class FileTypeIdGlobalSettingsPanel extends IngestModuleGlobalSettingsPane
jLabel3.setFont(jLabel3.getFont().deriveFont(jLabel3.getFont().getStyle() & ~java.awt.Font.BOLD, 11));
org.openide.awt.Mnemonics.setLocalizedText(jLabel3, org.openide.util.NbBundle.getMessage(FileTypeIdGlobalSettingsPanel.class, "FileTypeIdGlobalSettingsPanel.jLabel3.text")); // NOI18N
jScrollPane2.setMinimumSize(new java.awt.Dimension(300, 100));
jScrollPane2.setMinimumSize(new java.awt.Dimension(300, 0));
jScrollPane2.setPreferredSize(new java.awt.Dimension(550, 275));
jSplitPane1.setMinimumSize(new java.awt.Dimension(558, 285));
jSplitPane1.setMinimumSize(new java.awt.Dimension(0, 0));
jPanel1.setMinimumSize(new java.awt.Dimension(362, 283));
jPanel1.setMinimumSize(new java.awt.Dimension(362, 0));
jPanel1.setPreferredSize(new java.awt.Dimension(362, 0));
jLabel2.setFont(jLabel2.getFont().deriveFont(jLabel2.getFont().getStyle() & ~java.awt.Font.BOLD, 11));
org.openide.awt.Mnemonics.setLocalizedText(jLabel2, org.openide.util.NbBundle.getMessage(FileTypeIdGlobalSettingsPanel.class, "FileTypeIdGlobalSettingsPanel.jLabel2.text")); // NOI18N
@ -399,20 +403,20 @@ final class FileTypeIdGlobalSettingsPanel extends IngestModuleGlobalSettingsPane
.addGap(12, 12, 12)
.addComponent(jLabel2)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(typesScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, 397, Short.MAX_VALUE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(typesScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, 203, Short.MAX_VALUE)
.addGap(10, 10, 10)
.addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(newTypeButton)
.addComponent(editTypeButton)
.addComponent(deleteTypeButton))
.addContainerGap())
.addGap(7, 7, 7))
);
jPanel1Layout.linkSize(javax.swing.SwingConstants.VERTICAL, new java.awt.Component[] {deleteTypeButton, newTypeButton});
jSplitPane1.setLeftComponent(jPanel1);
jPanel2.setMinimumSize(new java.awt.Dimension(79, 283));
jPanel2.setMinimumSize(new java.awt.Dimension(79, 0));
org.openide.awt.Mnemonics.setLocalizedText(jLabel1, org.openide.util.NbBundle.getMessage(FileTypeIdGlobalSettingsPanel.class, "FileTypeIdGlobalSettingsPanel.jLabel1.text")); // NOI18N
@ -421,6 +425,7 @@ final class FileTypeIdGlobalSettingsPanel extends IngestModuleGlobalSettingsPane
public int getSize() { return signatures.length; }
public Signature getElementAt(int i) { return signatures[i]; }
});
signatureList.setEnabled(false);
signatureList.setMaximumSize(new java.awt.Dimension(32767, 32767));
signatureList.setPreferredSize(null);
jScrollPane1.setViewportView(signatureList);
@ -444,8 +449,8 @@ final class FileTypeIdGlobalSettingsPanel extends IngestModuleGlobalSettingsPane
.addContainerGap()
.addComponent(jLabel1)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 400, Short.MAX_VALUE)
.addGap(40, 40, 40))
.addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 235, Short.MAX_VALUE)
.addContainerGap())
);
jSplitPane1.setRightComponent(jPanel2);
@ -470,7 +475,7 @@ final class FileTypeIdGlobalSettingsPanel extends IngestModuleGlobalSettingsPane
.addContainerGap()
.addComponent(jLabel3)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(jScrollPane2, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addComponent(jScrollPane2, javax.swing.GroupLayout.DEFAULT_SIZE, 281, Short.MAX_VALUE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(ingestRunningWarningLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 16, javax.swing.GroupLayout.PREFERRED_SIZE)
.addContainerGap())
@ -481,14 +486,12 @@ final class FileTypeIdGlobalSettingsPanel extends IngestModuleGlobalSettingsPane
layout.setHorizontalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addComponent(jPanel3, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addComponent(jPanel3, javax.swing.GroupLayout.DEFAULT_SIZE, 752, Short.MAX_VALUE)
.addGap(0, 0, 0))
);
layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addComponent(jPanel3, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addGap(0, 0, 0))
.addComponent(jPanel3, javax.swing.GroupLayout.DEFAULT_SIZE, 345, Short.MAX_VALUE)
);
}// </editor-fold>//GEN-END:initComponents

View File

@ -22,6 +22,7 @@ import java.awt.Dimension;
import java.awt.Toolkit;
import java.io.File;
import java.io.IOException;
import java.nio.file.Paths;
import java.util.logging.Level;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
@ -30,6 +31,7 @@ import org.apache.commons.io.FilenameUtils;
import org.openide.util.NbBundle;
import org.sleuthkit.autopsy.coreutils.Logger;
import org.sleuthkit.autopsy.coreutils.ModuleSettings;
import org.sleuthkit.autopsy.coreutils.PlatformUtil;
import org.sleuthkit.autopsy.modules.hashdatabase.HashDbManager.HashDb;
import org.sleuthkit.autopsy.modules.hashdatabase.HashDbManager.HashDb.KnownFilesType;
import org.sleuthkit.autopsy.modules.hashdatabase.HashDbManager.HashDbManagerException;
@ -273,12 +275,17 @@ final class HashDbCreateDatabaseDialog extends javax.swing.JDialog {
private void saveAsButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_saveAsButtonActionPerformed
try {
String lastBaseDirectory = "";
String lastBaseDirectory = Paths.get(PlatformUtil.getUserConfigDirectory(), "HashDatabases").toString();
if (ModuleSettings.settingExists(ModuleSettings.MAIN_SETTINGS, LAST_FILE_PATH_KEY)) {
lastBaseDirectory = ModuleSettings.getConfigSetting(ModuleSettings.MAIN_SETTINGS, LAST_FILE_PATH_KEY);
}
StringBuilder path = new StringBuilder();
path.append(lastBaseDirectory);
File hashDbFolder = new File(path.toString());
// create the folder if it doesn't exist
if (!hashDbFolder.exists()){
hashDbFolder.mkdir();
}
if (!hashSetNameTextField.getText().isEmpty()) {
path.append(File.separator).append(hashSetNameTextField.getText());
} else {

View File

@ -22,6 +22,7 @@ import java.awt.Dimension;
import java.awt.Toolkit;
import java.io.File;
import java.io.IOException;
import java.nio.file.Paths;
import java.util.logging.Level;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
@ -31,6 +32,7 @@ import org.apache.commons.io.FilenameUtils;
import org.openide.util.NbBundle;
import org.sleuthkit.autopsy.coreutils.Logger;
import org.sleuthkit.autopsy.coreutils.ModuleSettings;
import org.sleuthkit.autopsy.coreutils.PlatformUtil;
import org.sleuthkit.autopsy.modules.hashdatabase.HashDbManager.HashDb;
import org.sleuthkit.autopsy.modules.hashdatabase.HashDbManager.HashDb.KnownFilesType;
import org.sleuthkit.autopsy.modules.hashdatabase.HashDbManager.HashDbManagerException;
@ -249,9 +251,16 @@ final class HashDbImportDatabaseDialog extends javax.swing.JDialog {
}// </editor-fold>//GEN-END:initComponents
private void openButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_openButtonActionPerformed
String lastBaseDirectory = Paths.get(PlatformUtil.getUserConfigDirectory(), "HashDatabases").toString();
if (ModuleSettings.settingExists(ModuleSettings.MAIN_SETTINGS, LAST_FILE_PATH_KEY)) {
fileChooser.setCurrentDirectory(new File(ModuleSettings.getConfigSetting(ModuleSettings.MAIN_SETTINGS, LAST_FILE_PATH_KEY)));
lastBaseDirectory = ModuleSettings.getConfigSetting(ModuleSettings.MAIN_SETTINGS, LAST_FILE_PATH_KEY);
}
File hashDbFolder = new File(lastBaseDirectory);
// create the folder if it doesn't exist
if (!hashDbFolder.exists()) {
hashDbFolder.mkdir();
}
fileChooser.setCurrentDirectory(hashDbFolder);
if (fileChooser.showOpenDialog(this) == JFileChooser.APPROVE_OPTION) {
File databaseFile = fileChooser.getSelectedFile();
try {

View File

@ -26,27 +26,28 @@ import java.util.List;
import java.util.concurrent.atomic.AtomicLong;
import java.util.logging.Level;
import org.openide.util.NbBundle;
import org.openide.util.NbBundle.Messages;
import org.sleuthkit.autopsy.casemodule.Case;
import org.sleuthkit.autopsy.casemodule.services.Blackboard;
import org.sleuthkit.autopsy.coreutils.Logger;
import org.sleuthkit.autopsy.coreutils.MessageNotifyUtil;
import org.sleuthkit.autopsy.ingest.FileIngestModule;
import org.sleuthkit.autopsy.ingest.IngestMessage;
import org.sleuthkit.autopsy.ingest.IngestModuleReferenceCounter;
import org.sleuthkit.autopsy.ingest.IngestServices;
import org.sleuthkit.autopsy.ingest.ModuleDataEvent;
import org.sleuthkit.autopsy.modules.hashdatabase.HashDbManager.HashDb;
import org.sleuthkit.datamodel.AbstractFile;
import org.sleuthkit.datamodel.BlackboardArtifact;
import org.sleuthkit.datamodel.BlackboardArtifact.ARTIFACT_TYPE;
import org.sleuthkit.datamodel.BlackboardAttribute;
import org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE;
import org.sleuthkit.datamodel.HashHitInfo;
import org.sleuthkit.datamodel.HashUtility;
import org.sleuthkit.datamodel.SleuthkitCase;
import org.sleuthkit.datamodel.TskCoreException;
import org.sleuthkit.datamodel.TskData;
import org.sleuthkit.datamodel.TskException;
import org.sleuthkit.autopsy.modules.hashdatabase.HashDbManager.HashDb;
import org.sleuthkit.autopsy.ingest.FileIngestModule;
import org.sleuthkit.autopsy.ingest.IngestModuleReferenceCounter;
import org.sleuthkit.datamodel.HashHitInfo;
@NbBundle.Messages({
"HashDbIngestModule.noKnownBadHashDbSetMsg=No known bad hash database set.",
@ -285,6 +286,7 @@ public class HashDbIngestModule implements FileIngestModule {
return ret;
}
@Messages({"HashDbIngestModule.indexError.message=Failed to index hashset hit artifact for keyword search."})
private void postHashSetHitToBlackboard(AbstractFile abstractFile, String md5Hash, String hashSetName, String comment, boolean showInboxMessage) {
try {
String MODULE_NAME = NbBundle.getMessage(HashDbIngestModule.class, "HashDbIngestModule.moduleName");
@ -303,9 +305,9 @@ public class HashDbIngestModule implements FileIngestModule {
// index the artifact for keyword search
blackboard.indexArtifact(badFile);
} catch (Blackboard.BlackboardException ex) {
logger.log(Level.SEVERE, NbBundle.getMessage(Blackboard.class, "Blackboard.unableToIndexArtifact.error.msg", badFile.getDisplayName()), ex); //NON-NLS
logger.log(Level.SEVERE, "Unable to index blackboard artifact " + badFile.getArtifactID(), ex); //NON-NLS
MessageNotifyUtil.Notify.error(
NbBundle.getMessage(Blackboard.class, "Blackboard.unableToIndexArtifact.exception.msg"), badFile.getDisplayName());
Bundle.HashDbIngestModule_indexError_message(), badFile.getDisplayName());
}
if (showInboxMessage) {

View File

@ -25,7 +25,7 @@ import java.sql.SQLException;
import java.sql.Statement;
import java.util.List;
import java.util.logging.Level;
import org.openide.util.NbBundle;
import org.openide.util.NbBundle.Messages;
import org.sleuthkit.autopsy.casemodule.Case;
import org.sleuthkit.autopsy.casemodule.services.Blackboard;
import org.sleuthkit.autopsy.coreutils.Logger;
@ -74,6 +74,7 @@ class CallLogAnalyzer {
}
}
@Messages({"CallLogAnalyzer.indexError.message=Failed to index call log artifact for keyword search."})
private void findCallLogsInDB(String DatabasePath, long fId) {
if (DatabasePath == null || DatabasePath.isEmpty()) {
return;
@ -128,9 +129,9 @@ class CallLogAnalyzer {
// index the artifact for keyword search
blackboard.indexArtifact(bba);
} catch (Blackboard.BlackboardException ex) {
logger.log(Level.SEVERE, NbBundle.getMessage(Blackboard.class, "Blackboard.unableToIndexArtifact.error.msg", bba.getDisplayName()), ex); //NON-NLS
logger.log(Level.SEVERE, "Unable to index blackboard artifact " + bba.getArtifactID(), ex); //NON-NLS
MessageNotifyUtil.Notify.error(
NbBundle.getMessage(Blackboard.class, "Blackboard.unableToIndexArtifact.exception.msg"), bba.getDisplayName());
Bundle.CallLogAnalyzer_indexError_message(), bba.getDisplayName());
}
}
} catch (Exception e) {

View File

@ -30,18 +30,18 @@ import java.sql.SQLException;
import java.sql.Statement;
import java.util.List;
import java.util.logging.Level;
import org.openide.util.NbBundle;
import org.openide.util.NbBundle.Messages;
import org.sleuthkit.autopsy.casemodule.Case;
import org.sleuthkit.autopsy.casemodule.services.Blackboard;
import org.sleuthkit.autopsy.coreutils.Logger;
import org.sleuthkit.autopsy.coreutils.MessageNotifyUtil;
import org.sleuthkit.autopsy.datamodel.ContentUtils;
import org.sleuthkit.datamodel.AbstractFile;
import org.sleuthkit.datamodel.BlackboardArtifact;
import org.sleuthkit.datamodel.BlackboardAttribute;
import org.sleuthkit.datamodel.ReadContentInputStream;
import org.sleuthkit.datamodel.SleuthkitCase;
import org.sleuthkit.datamodel.TskCoreException;
import org.sleuthkit.autopsy.datamodel.ContentUtils;
import org.sleuthkit.datamodel.ReadContentInputStream;
class ContactAnalyzer {
@ -91,6 +91,7 @@ class ContactAnalyzer {
* path The fileId will be the Abstract file associated
* with the artifacts
*/
@Messages({"ContactAnalyzer.indexError.message=Failed to index contact artifact for keyword search."})
private void findContactsInDB(String DatabasePath, long fId) {
if (DatabasePath == null || DatabasePath.isEmpty()) {
return;
@ -149,9 +150,9 @@ class ContactAnalyzer {
// index the artifact for keyword search
blackboard.indexArtifact(bba);
} catch (Blackboard.BlackboardException ex) {
logger.log(Level.SEVERE, NbBundle.getMessage(Blackboard.class, "Blackboard.unableToIndexArtifact.error.msg", bba.getDisplayName()), ex); //NON-NLS
logger.log(Level.SEVERE, "Unable to index blackboard artifact " + bba.getArtifactID(), ex); //NON-NLS
MessageNotifyUtil.Notify.error(
NbBundle.getMessage(Blackboard.class, "Blackboard.unableToIndexArtifact.exception.msg"), bba.getDisplayName());
Bundle.ContactAnalyzer_indexError_message(), bba.getDisplayName());
}
}

View File

@ -26,6 +26,7 @@ import java.sql.Statement;
import java.util.List;
import java.util.logging.Level;
import org.openide.util.NbBundle;
import org.openide.util.NbBundle.Messages;
import org.sleuthkit.autopsy.casemodule.Case;
import org.sleuthkit.autopsy.casemodule.services.Blackboard;
import org.sleuthkit.autopsy.coreutils.Logger;
@ -74,6 +75,7 @@ class TextMessageAnalyzer {
}
}
@Messages({"TextMessageAnalyzer.indexError.message=Failed to index text message artifact for keyword search."})
private void findTextsInDB(String DatabasePath, long fId) {
if (DatabasePath == null || DatabasePath.isEmpty()) {
return;
@ -127,14 +129,14 @@ class TextMessageAnalyzer {
bba.addAttribute(new BlackboardAttribute(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_SUBJECT, moduleName, subject));
bba.addAttribute(new BlackboardAttribute(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_TEXT, moduleName, body));
bba.addAttribute(new BlackboardAttribute(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_MESSAGE_TYPE, moduleName, NbBundle.getMessage(this.getClass(), "TextMessageAnalyzer.bbAttribute.smsMessage")));
try {
// index the artifact for keyword search
blackboard.indexArtifact(bba);
} catch (Blackboard.BlackboardException ex) {
logger.log(Level.SEVERE, NbBundle.getMessage(Blackboard.class, "Blackboard.unableToIndexArtifact.error.msg", bba.getDisplayName()), ex); //NON-NLS
logger.log(Level.SEVERE, "Unable to index blackboard artifact " + bba.getArtifactID(), ex); //NON-NLS
MessageNotifyUtil.Notify.error(
NbBundle.getMessage(Blackboard.class, "Blackboard.unableToIndexArtifact.exception.msg"), bba.getDisplayName());
Bundle.TextMessageAnalyzer_indexError_message(), bba.getDisplayName());
}
}

View File

@ -24,7 +24,6 @@ import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.logging.Level;
import org.openide.util.Exceptions;
import org.openide.util.NbBundle;
import org.openide.util.NbBundle.Messages;
import org.sleuthkit.autopsy.casemodule.Case;
@ -100,6 +99,7 @@ final class FilesIdentifierIngestModule implements FileIngestModule {
* @inheritDoc
*/
@Override
@Messages({"FilesIdentifierIngestModule.indexError.message=Failed to index interesting file hit artifact for keyword search."})
public ProcessResult process(AbstractFile file) {
blackboard = Case.getCurrentCase().getServices().getBlackboard();
@ -131,9 +131,8 @@ final class FilesIdentifierIngestModule implements FileIngestModule {
// index the artifact for keyword search
blackboard.indexArtifact(artifact);
} catch (Blackboard.BlackboardException ex) {
logger.log(Level.SEVERE, NbBundle.getMessage(Blackboard.class, "Blackboard.unableToIndexArtifact.error.msg", artifact.getDisplayName()), ex); //NON-NLS
MessageNotifyUtil.Notify.error(
NbBundle.getMessage(Blackboard.class, "Blackboard.unableToIndexArtifact.exception.msg"), artifact.getDisplayName());
logger.log(Level.SEVERE, "Unable to index blackboard artifact " + artifact.getArtifactID(), ex); //NON-NLS
MessageNotifyUtil.Notify.error(Bundle.FilesIdentifierIngestModule_indexError_message(), artifact.getDisplayName());
}
IngestServices.getInstance().fireModuleDataEvent(new ModuleDataEvent(moduleName, BlackboardArtifact.ARTIFACT_TYPE.TSK_INTERESTING_FILE_HIT, Collections.singletonList(artifact)));

View File

@ -1,7 +1,7 @@
/*
* Autopsy Forensic Browser
*
* Copyright 2014 Basis Technology Corp.
* Copyright 2011-2016 Basis Technology Corp.
* Contact: carrier <at> sleuthkit <dot> org
*
* Licensed under the Apache License, Version 2.0 (the "License");
@ -30,9 +30,9 @@ import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.HashMap;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicLong;
import java.util.logging.Level;
@ -40,29 +40,25 @@ import org.openide.modules.InstalledFileLocator;
import org.openide.util.NbBundle;
import org.sleuthkit.autopsy.casemodule.Case;
import org.sleuthkit.autopsy.coreutils.ExecUtil;
import org.sleuthkit.autopsy.coreutils.FileUtil;
import org.sleuthkit.autopsy.coreutils.Logger;
import org.sleuthkit.autopsy.coreutils.MessageNotifyUtil;
import org.sleuthkit.autopsy.coreutils.PlatformUtil;
import org.sleuthkit.autopsy.coreutils.UNCPathUtilities;
import org.sleuthkit.autopsy.datamodel.ContentUtils;
import org.sleuthkit.autopsy.ingest.FileIngestModule;
import org.sleuthkit.autopsy.ingest.FileIngestModuleProcessTerminator;
import org.sleuthkit.autopsy.ingest.IngestJobContext;
import org.sleuthkit.autopsy.ingest.IngestMessage;
import org.sleuthkit.autopsy.ingest.IngestModule;
import org.sleuthkit.autopsy.ingest.IngestModuleReferenceCounter;
import org.sleuthkit.datamodel.AbstractFile;
import org.sleuthkit.datamodel.Content;
import org.sleuthkit.datamodel.Image;
import org.sleuthkit.datamodel.LayoutFile;
import org.sleuthkit.datamodel.TskCoreException;
import org.sleuthkit.datamodel.TskData;
import org.sleuthkit.datamodel.Volume;
import org.sleuthkit.autopsy.coreutils.FileUtil;
import org.sleuthkit.autopsy.coreutils.UNCPathUtilities;
import org.sleuthkit.autopsy.coreutils.MessageNotifyUtil;
import org.sleuthkit.autopsy.coreutils.PlatformUtil;
import org.sleuthkit.autopsy.ingest.ProcTerminationCode;
import org.sleuthkit.autopsy.ingest.FileIngestModuleProcessTerminator;
import org.sleuthkit.autopsy.ingest.IngestMonitor;
import org.sleuthkit.autopsy.ingest.IngestServices;
import org.sleuthkit.autopsy.ingest.ModuleContentEvent;
import org.sleuthkit.autopsy.ingest.ProcTerminationCode;
import org.sleuthkit.datamodel.AbstractFile;
import org.sleuthkit.datamodel.LayoutFile;
import org.sleuthkit.datamodel.TskData;
/**
* A file ingest module that runs the Unallocated Carver executable with
@ -182,12 +178,6 @@ final class PhotoRecCarverFileIngestModule implements FileIngestModule {
Path tempFilePath = null;
try {
long id = getRootId(file);
// make sure we have a valid systemID
if (id == -1) {
return IngestModule.ProcessResult.ERROR;
}
// Verify initialization succeeded.
if (null == this.executableFile) {
logger.log(Level.SEVERE, "PhotoRec carver called after failed start up"); // NON-NLS
@ -205,6 +195,12 @@ final class PhotoRecCarverFileIngestModule implements FileIngestModule {
NbBundle.getMessage(this.getClass(), "PhotoRecIngestModule.NotEnoughDiskSpace"));
return IngestModule.ProcessResult.ERROR;
}
if (this.context.fileIngestIsCancelled() == true) {
// if it was cancelled by the user, result is OK
logger.log(Level.INFO, "PhotoRec cancelled by user"); // NON-NLS
MessageNotifyUtil.Notify.info(PhotoRecCarverIngestModuleFactory.getModuleName(), NbBundle.getMessage(PhotoRecCarverFileIngestModule.class, "PhotoRecIngestModule.cancelledByUser"));
return IngestModule.ProcessResult.OK;
}
// Write the file to disk.
long writestart = System.currentTimeMillis();
@ -212,6 +208,13 @@ final class PhotoRecCarverFileIngestModule implements FileIngestModule {
tempFilePath = Paths.get(paths.getTempDirPath().toString(), file.getName());
ContentUtils.writeToFile(file, tempFilePath.toFile());
if (this.context.fileIngestIsCancelled() == true) {
// if it was cancelled by the user, result is OK
logger.log(Level.INFO, "PhotoRec cancelled by user"); // NON-NLS
MessageNotifyUtil.Notify.info(PhotoRecCarverIngestModuleFactory.getModuleName(), NbBundle.getMessage(PhotoRecCarverFileIngestModule.class, "PhotoRecIngestModule.cancelledByUser"));
return IngestModule.ProcessResult.OK;
}
// Create a subdirectory for this file.
Path outputDirPath = Paths.get(paths.getOutputDirPath().toString(), file.getName());
Files.createDirectory(outputDirPath);
@ -262,6 +265,12 @@ final class PhotoRecCarverFileIngestModule implements FileIngestModule {
java.io.File newAuditFile = new java.io.File(Paths.get(outputDirPath.toString(), PHOTOREC_REPORT).toString()); //NON-NLS
oldAuditFile.renameTo(newAuditFile);
if (this.context.fileIngestIsCancelled() == true) {
// if it was cancelled by the user, result is OK
logger.log(Level.INFO, "PhotoRec cancelled by user"); // NON-NLS
MessageNotifyUtil.Notify.info(PhotoRecCarverIngestModuleFactory.getModuleName(), NbBundle.getMessage(PhotoRecCarverFileIngestModule.class, "PhotoRecIngestModule.cancelledByUser"));
return IngestModule.ProcessResult.OK;
}
Path pathToRemove = Paths.get(outputDirPath.toAbsolutePath().toString());
try (DirectoryStream<Path> stream = Files.newDirectoryStream(pathToRemove)) {
for (Path entry : stream) {
@ -276,10 +285,16 @@ final class PhotoRecCarverFileIngestModule implements FileIngestModule {
// Now that we've cleaned up the folders and data files, parse the xml output file to add carved items into the database
long calcstart = System.currentTimeMillis();
PhotoRecCarverOutputParser parser = new PhotoRecCarverOutputParser(outputDirPath);
List<LayoutFile> carvedItems = parser.parse(newAuditFile, id, file);
if (this.context.fileIngestIsCancelled() == true) {
// if it was cancelled by the user, result is OK
logger.log(Level.INFO, "PhotoRec cancelled by user"); // NON-NLS
MessageNotifyUtil.Notify.info(PhotoRecCarverIngestModuleFactory.getModuleName(), NbBundle.getMessage(PhotoRecCarverFileIngestModule.class, "PhotoRecIngestModule.cancelledByUser"));
return IngestModule.ProcessResult.OK;
}
List<LayoutFile> carvedItems = parser.parse(newAuditFile, file, context);
long calcdelta = (System.currentTimeMillis() - calcstart);
totals.totalParsetime.addAndGet(calcdelta);
if (carvedItems != null) { // if there were any results from carving, add the unallocated carving event to the reports list.
if (carvedItems != null && !carvedItems.isEmpty()) { // if there were any results from carving, add the unallocated carving event to the reports list.
totals.totalItemsRecovered.addAndGet(carvedItems.size());
context.addFilesToJob(new ArrayList<>(carvedItems));
services.fireModuleContentEvent(new ModuleContentEvent(carvedItems.get(0))); // fire an event to update the tree
@ -411,31 +426,6 @@ final class PhotoRecCarverFileIngestModule implements FileIngestModule {
return path;
}
/**
* Finds the root Volume or Image of the AbstractFile passed in.
*
* @param file The file we want to find the root parent for
*
* @return The ID of the root parent Volume or Image
*/
private static long getRootId(AbstractFile file) {
long id = -1;
Content parent = null;
try {
parent = file.getParent();
while (parent != null) {
if (parent instanceof Volume || parent instanceof Image) {
id = parent.getId();
break;
}
parent = parent.getParent();
}
} catch (TskCoreException ex) {
logger.log(Level.SEVERE, "PhotoRec carver exception while trying to get parent of AbstractFile.", ex); //NON-NLS
}
return id;
}
/**
* Finds and returns the path to the executable, if able.
*

View File

@ -1,7 +1,7 @@
/*
* Autopsy Forensic Browser
*
* Copyright 2014 Basis Technology Corp.
* Copyright 2011-2016 Basis Technology Corp.
* Contact: carrier <at> sleuthkit <dot> org
*
* Licensed under the Apache License, Version 2.0 (the "License");
@ -27,13 +27,16 @@ import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.logging.Level;
import org.openide.util.NbBundle;
import org.sleuthkit.autopsy.casemodule.Case;
import org.sleuthkit.autopsy.casemodule.services.FileManager;
import org.sleuthkit.autopsy.coreutils.Logger;
import org.sleuthkit.autopsy.coreutils.MessageNotifyUtil;
import org.sleuthkit.autopsy.coreutils.XMLUtil;
import org.sleuthkit.autopsy.ingest.IngestJobContext;
import org.sleuthkit.datamodel.AbstractFile;
import org.sleuthkit.datamodel.CarvingResult;
import org.sleuthkit.datamodel.LayoutFile;
import org.sleuthkit.datamodel.CarvedFileContainer;
import org.sleuthkit.datamodel.TskCoreException;
import org.sleuthkit.datamodel.TskFileRange;
import org.w3c.dom.Document;
@ -70,24 +73,24 @@ class PhotoRecCarverOutputParser {
* @throws FileNotFoundException
* @throws IOException
*/
List<LayoutFile> parse(File xmlInputFile, long id, AbstractFile af) throws FileNotFoundException, IOException {
List<LayoutFile> parse(File xmlInputFile, AbstractFile af, IngestJobContext context) throws FileNotFoundException, IOException {
try {
final Document doc = XMLUtil.loadDoc(PhotoRecCarverOutputParser.class, xmlInputFile.toString());
if (doc == null) {
return null;
return new ArrayList<>();
}
Element root = doc.getDocumentElement();
if (root == null) {
logger.log(Level.SEVERE, "Error loading config file: invalid file format (bad root)."); //NON-NLS
return null;
return new ArrayList<>();
}
NodeList fileObjects = root.getElementsByTagName("fileobject"); //NON-NLS
final int numberOfFiles = fileObjects.getLength();
if (numberOfFiles == 0) {
return null;
return new ArrayList<>();
}
String fileName;
Long fileSize;
@ -99,9 +102,14 @@ class PhotoRecCarverOutputParser {
FileManager fileManager = Case.getCurrentCase().getServices().getFileManager();
// create and initialize the list to put into the database
List<CarvedFileContainer> carvedFileContainer = new ArrayList<>();
List<CarvingResult.CarvedFile> carvedFiles = new ArrayList<>();
for (int fileIndex = 0; fileIndex < numberOfFiles; ++fileIndex) {
if (context.fileIngestIsCancelled() == true) {
// if it was cancelled by the user, result is OK
logger.log(Level.INFO, "PhotoRec cancelled by user"); // NON-NLS
MessageNotifyUtil.Notify.info(PhotoRecCarverIngestModuleFactory.getModuleName(), NbBundle.getMessage(PhotoRecCarverFileIngestModule.class, "PhotoRecIngestModule.cancelledByUser"));
break;
}
entry = (Element) fileObjects.item(fileIndex);
fileNames = entry.getElementsByTagName("filename"); //NON-NLS
fileSizes = entry.getElementsByTagName("filesize"); //NON-NLS
@ -133,7 +141,7 @@ class PhotoRecCarverOutputParser {
if (fileByteEnd > af.getSize()) {
long overshoot = fileByteEnd - af.getSize();
if (fileSize > overshoot) {
fileSize = fileSize - overshoot;
fileSize -= overshoot;
} else {
// This better never happen... Data for this file is corrupted. Skip it.
continue;
@ -144,10 +152,10 @@ class PhotoRecCarverOutputParser {
}
if (!tskRanges.isEmpty()) {
carvedFileContainer.add(new CarvedFileContainer(fileName, fileSize, id, tskRanges));
carvedFiles.add(new CarvingResult.CarvedFile(fileName, fileSize, tskRanges));
}
}
return fileManager.addCarvedFiles(carvedFileContainer);
return fileManager.addCarvedFiles(new CarvingResult(af, carvedFiles));
} catch (NumberFormatException | TskCoreException ex) {
logger.log(Level.SEVERE, "Error parsing PhotoRec output and inserting it into the database: {0}", ex); //NON-NLS
}

View File

@ -6,7 +6,7 @@ STIXReportModuleConfigPanel.jLabel2.text=Select a STIX file or directory of STIX
STIXReportModuleConfigPanel.jTextField1.text=
STIXReportModuleConfigPanel.jButton1.text=Choose file
STIXReportModuleConfigPanel.jCheckBox1.text=Include results for false indicators in output file
STIXReportModule.notifyMsg.unableToOpenReportFile=Unable to open STIX report file {0}
STIXReportModule.notifyMsg.unableToOpenReportFile=Unable to complete STIX report.
STIXReportModule.progress.completedWithErrors=Completed with errors
STIXReportModule.notifyMsg.unableToOpenFileDir=Unable to open STIX file/directory {0}
STIXReportModule.progress.couldNotOpenFileDir=Could not open file/directory {0}

View File

@ -1,14 +1,13 @@
OpenIDE-Module-Name=stix\u30E2\u30B8\u30E5\u30FC\u30EB
STIXReportModule.getDesc.text=\u30C7\u30FC\u30BF\u30BD\u30FC\u30B9\u306B\u5BFE\u3057\u3066\u5E7E\u3064\u304B\u306ESTIX\uFF08Structured Threat Information eXpression\uFF1B\u8105\u5A01\u60C5\u5831\u69CB\u9020\u5316\u8A18\u8FF0\u5F62\u5F0F\uFF09\u30D5\u30A1\u30A4\u30EB\u3092\u5B9F\u884C\u3057\u3001\u30EC\u30DD\u30FC\u30C8\u3092\u751F\u6210\u3057\u307E\u3059\u3002\u307E\u305F\u3001\u7591\u308F\u3057\u3044\u30D5\u30A1\u30A4\u30EB\u5185\u306B\u30A2\u30FC\u30C6\u30A3\u30D5\u30A1\u30AF\u30C8\u3092\u4F5C\u6210\u3002
OpenIDE-Module-Name=stix\u30e2\u30b8\u30e5\u30fc\u30eb
STIXReportModule.getDesc.text=\u30c7\u30fc\u30bf\u30bd\u30fc\u30b9\u306b\u5bfe\u3057\u3066\u5e7e\u3064\u304b\u306eSTIX\uff08Structured Threat Information eXpression\uff1b\u8105\u5a01\u60c5\u5831\u69cb\u9020\u5316\u8a18\u8ff0\u5f62\u5f0f\uff09\u30d5\u30a1\u30a4\u30eb\u3092\u5b9f\u884c\u3057\u3001\u30ec\u30dd\u30fc\u30c8\u3092\u751f\u6210\u3057\u307e\u3059\u3002\u307e\u305f\u3001\u7591\u308f\u3057\u3044\u30d5\u30a1\u30a4\u30eb\u5185\u306b\u30a2\u30fc\u30c6\u30a3\u30d5\u30a1\u30af\u30c8\u3092\u4f5c\u6210\u3002
STIXReportModule.getName.text=STIX
STIXReportModule.notifyMsg.tooManyArtifactsgt1000="{0}"\u7528\u306B\u751F\u6210\u3055\u308C\u305FSTIX\u95A2\u9023\u306E\u30A2\u30FC\u30C6\u30A3\u30D5\u30A1\u30AF\u30C8\u304C\u591A\u3059\u304E\u307E\u3059\u3002\u6700\u521D\u306E1000\u306E\u307F\u4FDD\u5B58\u3055\u308C\u307E\u3059\u3002
STIXReportModule.notifyMsg.unableToOpenFileDir=STIX\u30D5\u30A1\u30A4\u30EB\uFF0F\u30C7\u30A3\u30EC\u30AF\u30C8\u30EA{0}\u3092\u958B\u3051\u307E\u305B\u3093\u3067\u3057\u305F
STIXReportModule.notifyMsg.unableToOpenReportFile=STIX\u30EC\u30DD\u30FC\u30C8\u30D5\u30A1\u30A4\u30EB{0}\u3092\u958B\u3051\u307E\u305B\u3093\u3067\u3057\u305F
STIXReportModule.progress.completedWithErrors=\u30A8\u30E9\u30FC\u304C\u767A\u751F\u3057\u307E\u3057\u305F\u304C\u3001\u5B8C\u4E86\u3057\u307E\u3057\u305F
STIXReportModule.progress.couldNotOpenFileDir=\u30D5\u30A1\u30A4\u30EB\uFF0F\u30C7\u30A3\u30EC\u30AF\u30C8\u30EA{0}\u3092\u958B\u3051\u307E\u305B\u3093\u3067\u3057\u305F
STIXReportModule.progress.readSTIX=STIX\u30D5\u30A1\u30A4\u30EB\u3092\u30D1\u30FC\u30B9\u4E2D
STIXReportModuleConfigPanel.jButton1.text=\u30D5\u30A1\u30A4\u30EB\u3092\u9078\u629E
STIXReportModuleConfigPanel.jCheckBox1.text=\u30A2\u30A6\u30C8\u30D7\u30C3\u30C8\u30D5\u30A1\u30A4\u30EB\u306E\u8AA4\u3063\u305F\u30A4\u30F3\u30B8\u30B1\u30FC\u30BF\u30FC\u306E\u7D50\u679C\u3082\u542B\u3080
STIXReportModuleConfigPanel.jLabel2.text=STIX\u30D5\u30A1\u30A4\u30EB\u307E\u305F\u306FSTIX\u30D5\u30A1\u30A4\u30EB\u306E\u30C7\u30A3\u30EC\u30AF\u30C8\u30EA\u3092\u9078\u629E
STIXReportModule.notifyErr.noFildDirProvided=STIX\u30D5\u30A1\u30A4\u30EB\uFF0F\u30C7\u30A3\u30EC\u30AF\u30C8\u30EA\u304C\u63D0\u4F9B\u3055\u308C\u3066\u3044\u307E\u305B\u3093
STIXReportModule.progress.noFildDirProvided=STIX\u30D5\u30A1\u30A4\u30EB\uFF0F\u30C7\u30A3\u30EC\u30AF\u30C8\u30EA\u304C\u63D0\u4F9B\u3055\u308C\u3066\u3044\u307E\u305B\u3093
STIXReportModule.notifyMsg.tooManyArtifactsgt1000="{0}"\u7528\u306b\u751f\u6210\u3055\u308c\u305fSTIX\u95a2\u9023\u306e\u30a2\u30fc\u30c6\u30a3\u30d5\u30a1\u30af\u30c8\u304c\u591a\u3059\u304e\u307e\u3059\u3002\u6700\u521d\u306e1000\u306e\u307f\u4fdd\u5b58\u3055\u308c\u307e\u3059\u3002
STIXReportModule.notifyMsg.unableToOpenFileDir=STIX\u30d5\u30a1\u30a4\u30eb\uff0f\u30c7\u30a3\u30ec\u30af\u30c8\u30ea{0}\u3092\u958b\u3051\u307e\u305b\u3093\u3067\u3057\u305f
STIXReportModule.progress.completedWithErrors=\u30a8\u30e9\u30fc\u304c\u767a\u751f\u3057\u307e\u3057\u305f\u304c\u3001\u5b8c\u4e86\u3057\u307e\u3057\u305f
STIXReportModule.progress.couldNotOpenFileDir=\u30d5\u30a1\u30a4\u30eb\uff0f\u30c7\u30a3\u30ec\u30af\u30c8\u30ea{0}\u3092\u958b\u3051\u307e\u305b\u3093\u3067\u3057\u305f
STIXReportModule.progress.readSTIX=STIX\u30d5\u30a1\u30a4\u30eb\u3092\u30d1\u30fc\u30b9\u4e2d
STIXReportModuleConfigPanel.jButton1.text=\u30d5\u30a1\u30a4\u30eb\u3092\u9078\u629e
STIXReportModuleConfigPanel.jCheckBox1.text=\u30a2\u30a6\u30c8\u30d7\u30c3\u30c8\u30d5\u30a1\u30a4\u30eb\u306e\u8aa4\u3063\u305f\u30a4\u30f3\u30b8\u30b1\u30fc\u30bf\u30fc\u306e\u7d50\u679c\u3082\u542b\u3080
STIXReportModuleConfigPanel.jLabel2.text=STIX\u30d5\u30a1\u30a4\u30eb\u307e\u305f\u306fSTIX\u30d5\u30a1\u30a4\u30eb\u306e\u30c7\u30a3\u30ec\u30af\u30c8\u30ea\u3092\u9078\u629e
STIXReportModule.notifyErr.noFildDirProvided=STIX\u30d5\u30a1\u30a4\u30eb\uff0f\u30c7\u30a3\u30ec\u30af\u30c8\u30ea\u304c\u63d0\u4f9b\u3055\u308c\u3066\u3044\u307e\u305b\u3093
STIXReportModule.progress.noFildDirProvided=STIX\u30d5\u30a1\u30a4\u30eb\uff0f\u30c7\u30a3\u30ec\u30af\u30c8\u30ea\u304c\u63d0\u4f9b\u3055\u308c\u3066\u3044\u307e\u305b\u3093

View File

@ -18,48 +18,47 @@
*/
package org.sleuthkit.autopsy.modules.stix;
import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.List;
import java.util.logging.Level;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import javax.swing.JPanel;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Unmarshaller;
import javax.xml.namespace.QName;
import org.mitre.cybox.cybox_2.ObjectType;
import org.mitre.cybox.cybox_2.Observable;
import org.mitre.cybox.cybox_2.ObservableCompositionType;
import org.mitre.cybox.cybox_2.OperatorTypeEnum;
import org.mitre.cybox.objects.AccountObjectType;
import org.mitre.cybox.objects.Address;
import org.mitre.cybox.objects.DomainName;
import org.mitre.cybox.objects.EmailMessage;
import org.mitre.cybox.objects.FileObjectType;
import org.mitre.cybox.objects.SystemObjectType;
import org.mitre.cybox.objects.URIObjectType;
import org.mitre.cybox.objects.URLHistory;
import org.mitre.cybox.objects.WindowsNetworkShare;
import org.mitre.cybox.objects.WindowsRegistryKey;
import org.mitre.stix.common_1.IndicatorBaseType;
import org.mitre.stix.indicator_2.Indicator;
import org.mitre.stix.stix_1.STIXPackage;
import org.sleuthkit.autopsy.coreutils.Logger;
import org.sleuthkit.autopsy.report.GeneralReportModule;
import org.openide.util.NbBundle;
import org.sleuthkit.autopsy.report.ReportProgressPanel;
import org.sleuthkit.datamodel.TskCoreException;
import org.mitre.cybox.cybox_2.OperatorTypeEnum;
import org.mitre.cybox.objects.Address;
import org.mitre.cybox.objects.FileObjectType;
import org.mitre.cybox.objects.URIObjectType;
import org.mitre.cybox.objects.EmailMessage;
import org.mitre.cybox.objects.WindowsNetworkShare;
import org.mitre.cybox.objects.AccountObjectType;
import org.mitre.cybox.objects.SystemObjectType;
import org.mitre.cybox.objects.URLHistory;
import org.mitre.cybox.objects.DomainName;
import org.mitre.cybox.objects.WindowsRegistryKey;
import org.openide.util.NbBundle.Messages;
import org.sleuthkit.autopsy.casemodule.Case;
import org.sleuthkit.autopsy.coreutils.Logger;
import org.sleuthkit.autopsy.coreutils.MessageNotifyUtil;
import org.sleuthkit.autopsy.coreutils.ModuleSettings;
import org.sleuthkit.autopsy.report.GeneralReportModule;
import org.sleuthkit.autopsy.report.ReportProgressPanel;
import org.sleuthkit.autopsy.report.ReportProgressPanel.ReportStatus;
import org.sleuthkit.datamodel.TskCoreException;
/**
*
@ -79,8 +78,6 @@ public class STIXReportModule implements GeneralReportModule {
private final boolean skipShortCircuit = true;
private BufferedWriter output = null;
// Hidden constructor for the report
private STIXReportModule() {
}
@ -100,38 +97,23 @@ public class STIXReportModule implements GeneralReportModule {
* @param progressPanel panel to update the report's progress
*/
@Override
@Messages({"STIXReportModule.srcModuleName.text=STIX Report"})
public void generateReport(String baseReportDir, ReportProgressPanel progressPanel) {
// Start the progress bar and setup the report
progressPanel.setIndeterminate(false);
progressPanel.start();
progressPanel.updateStatusLabel(NbBundle.getMessage(this.getClass(), "STIXReportModule.progress.readSTIX"));
reportPath = baseReportDir + getRelativeFilePath();
File reportFile = new File(reportPath);
// Check if the user wants to display all output or just hits
reportAllResults = configPanel.getShowAllResults();
// Set up the output file
try {
File file = new File(reportPath);
output = new BufferedWriter(new FileWriter(file));
} catch (IOException ex) {
logger.log(Level.SEVERE, String.format("Unable to open STIX report file %s", reportPath), ex); //NON-NLS
MessageNotifyUtil.Notify.show("STIXReportModule", //NON-NLS
NbBundle.getMessage(this.getClass(),
"STIXReportModule.notifyMsg.unableToOpenReportFile",
reportPath),
MessageNotifyUtil.MessageType.ERROR);
progressPanel.complete(ReportStatus.ERROR);
progressPanel.updateStatusLabel(
NbBundle.getMessage(this.getClass(), "STIXReportModule.progress.completedWithErrors"));
return;
}
// Keep track of whether any errors occur during processing
boolean hadErrors = false;
// Process the file/directory name entry
String stixFileName = configPanel.getStixFile();
if (stixFileName == null) {
logger.log(Level.SEVERE, "STIXReportModuleConfigPanel.stixFile not initialized "); //NON-NLS
MessageNotifyUtil.Message.error(
@ -139,6 +121,7 @@ public class STIXReportModule implements GeneralReportModule {
progressPanel.complete(ReportStatus.ERROR);
progressPanel.updateStatusLabel(
NbBundle.getMessage(this.getClass(), "STIXReportModule.progress.noFildDirProvided"));
new File(baseReportDir).delete();
return;
}
if (stixFileName.isEmpty()) {
@ -148,6 +131,7 @@ public class STIXReportModule implements GeneralReportModule {
progressPanel.complete(ReportStatus.ERROR);
progressPanel.updateStatusLabel(
NbBundle.getMessage(this.getClass(), "STIXReportModule.progress.noFildDirProvided"));
new File(baseReportDir).delete();
return;
}
File stixFile = new File(stixFileName);
@ -160,58 +144,66 @@ public class STIXReportModule implements GeneralReportModule {
progressPanel.complete(ReportStatus.ERROR);
progressPanel.updateStatusLabel(
NbBundle.getMessage(this.getClass(), "STIXReportModule.progress.couldNotOpenFileDir", stixFileName));
new File(baseReportDir).delete();
return;
}
// Store the path
ModuleSettings.setConfigSetting("STIX", "defaultPath", stixFileName); //NON-NLS
try (BufferedWriter output = new BufferedWriter(new FileWriter(reportFile))) {
// Store the path
ModuleSettings.setConfigSetting("STIX", "defaultPath", stixFileName); //NON-NLS
// Create array of stix file(s)
File[] stixFiles;
if (stixFile.isFile()) {
stixFiles = new File[1];
stixFiles[0] = stixFile;
} else {
stixFiles = stixFile.listFiles();
}
// Set the length of the progress bar - we increment twice for each file
progressPanel.setMaximumProgress(stixFiles.length * 2 + 1);
// Process each STIX file
for (File file : stixFiles) {
try {
processFile(file.getAbsolutePath(), progressPanel);
} catch (TskCoreException ex) {
logger.log(Level.SEVERE, String.format("Unable to process STIX file %s", file), ex); //NON-NLS
MessageNotifyUtil.Notify.show("STIXReportModule", //NON-NLS
ex.getLocalizedMessage(),
MessageNotifyUtil.MessageType.ERROR);
hadErrors = true;
// Create array of stix file(s)
File[] stixFiles;
if (stixFile.isFile()) {
stixFiles = new File[1];
stixFiles[0] = stixFile;
} else {
stixFiles = stixFile.listFiles();
}
// Clear out the ID maps before loading the next file
idToObjectMap = new HashMap<String, ObjectType>();
idToResult = new HashMap<String, ObservableResult>();
}
// Set the length of the progress bar - we increment twice for each file
progressPanel.setMaximumProgress(stixFiles.length * 2 + 1);
// Close the output file
if (output != null) {
try {
output.close();
} catch (IOException ex) {
logger.log(Level.SEVERE, String.format("Error closing STIX report file %s", reportPath), ex); //NON-NLS
// Process each STIX file
for (File file : stixFiles) {
if (progressPanel.getStatus() == ReportStatus.CANCELED) {
return;
}
try {
processFile(file.getAbsolutePath(), progressPanel, output);
} catch (TskCoreException ex) {
logger.log(Level.SEVERE, String.format("Unable to process STIX file %s", file), ex); //NON-NLS
MessageNotifyUtil.Notify.show("STIXReportModule", //NON-NLS
ex.getLocalizedMessage(),
MessageNotifyUtil.MessageType.ERROR);
hadErrors = true;
}
// Clear out the ID maps before loading the next file
idToObjectMap = new HashMap<String, ObjectType>();
idToResult = new HashMap<String, ObservableResult>();
}
}
// Set the progress bar to done. If any errors occurred along the way, modify
// the "complete" message to indicate this.
if (hadErrors) {
// Set the progress bar to done. If any errors occurred along the way, modify
// the "complete" message to indicate this.
Case.getCurrentCase().addReport(reportPath, Bundle.STIXReportModule_srcModuleName_text(), "");
if (hadErrors) {
progressPanel.complete(ReportStatus.ERROR);
progressPanel.updateStatusLabel(
NbBundle.getMessage(this.getClass(), "STIXReportModule.progress.completedWithErrors"));
} else {
progressPanel.complete(ReportStatus.COMPLETE);
}
} catch (IOException ex) {
logger.log(Level.SEVERE, "Unable to complete STIX report.", ex); //NON-NLS
MessageNotifyUtil.Notify.show("STIXReportModule", //NON-NLS
NbBundle.getMessage(this.getClass(),
"STIXReportModule.notifyMsg.unableToOpenReportFile"),
MessageNotifyUtil.MessageType.ERROR);
progressPanel.complete(ReportStatus.ERROR);
progressPanel.updateStatusLabel(
NbBundle.getMessage(this.getClass(), "STIXReportModule.progress.completedWithErrors"));
} else {
progressPanel.complete(ReportStatus.COMPLETE);
} catch (TskCoreException ex) {
logger.log(Level.SEVERE, "Unable to add report to database.", ex);
}
}
@ -223,14 +215,14 @@ public class STIXReportModule implements GeneralReportModule {
*
* @throws TskCoreException
*/
private void processFile(String stixFile, ReportProgressPanel progressPanel) throws
private void processFile(String stixFile, ReportProgressPanel progressPanel, BufferedWriter output) throws
TskCoreException {
// Load the STIX file
STIXPackage stix;
stix = loadSTIXFile(stixFile);
printFileHeader(stixFile);
printFileHeader(stixFile, output);
// Save any observables listed up front
processObservables(stix);
@ -240,7 +232,7 @@ public class STIXReportModule implements GeneralReportModule {
registryFileData = EvalRegistryObj.copyRegistryFiles();
// Process the indicators
processIndicators(stix);
processIndicators(stix, output);
progressPanel.increment();
}
@ -292,7 +284,7 @@ public class STIXReportModule implements GeneralReportModule {
*
* @param stix STIXPackage
*/
private void processIndicators(STIXPackage stix) throws TskCoreException {
private void processIndicators(STIXPackage stix, BufferedWriter output) throws TskCoreException {
if (stix.getIndicators() != null) {
List<IndicatorBaseType> s = stix.getIndicators().getIndicators();
for (IndicatorBaseType t : s) {
@ -302,7 +294,7 @@ public class STIXReportModule implements GeneralReportModule {
if (ind.getObservable().getObject() != null) {
ObservableResult result = evaluateSingleObservable(ind.getObservable(), "");
if (result.isTrue() || reportAllResults) {
writeResultsToFile(ind, result.getDescription(), result.isTrue());
writeResultsToFile(ind, result.getDescription(), result.isTrue(), output);
}
if (result.isTrue()) {
saveResultsAsArtifacts(ind, result);
@ -311,7 +303,7 @@ public class STIXReportModule implements GeneralReportModule {
ObservableResult result = evaluateObservableComposition(ind.getObservable().getObservableComposition(), " ");
if (result.isTrue() || reportAllResults) {
writeResultsToFile(ind, result.getDescription(), result.isTrue());
writeResultsToFile(ind, result.getDescription(), result.isTrue(), output);
}
if (result.isTrue()) {
saveResultsAsArtifacts(ind, result);
@ -376,7 +368,7 @@ public class STIXReportModule implements GeneralReportModule {
* @param resultStr - Full results for this indicator
* @param found - true if the indicator was found in datasource(s)
*/
private void writeResultsToFile(Indicator ind, String resultStr, boolean found) {
private void writeResultsToFile(Indicator ind, String resultStr, boolean found, BufferedWriter output) {
if (output != null) {
try {
if (found) {
@ -412,7 +404,7 @@ public class STIXReportModule implements GeneralReportModule {
*
* @param a_fileName
*/
private void printFileHeader(String a_fileName) {
private void printFileHeader(String a_fileName, BufferedWriter output) {
if (output != null) {
try {
char[] chars = new char[a_fileName.length() + 8];

View File

@ -19,7 +19,7 @@
package org.sleuthkit.autopsy.modules.stix;
import java.util.logging.Level;
import org.openide.util.NbBundle;
import org.openide.util.NbBundle.Messages;
import org.sleuthkit.autopsy.casemodule.Case;
import org.sleuthkit.autopsy.casemodule.services.Blackboard;
import org.sleuthkit.autopsy.coreutils.Logger;
@ -58,6 +58,7 @@ class StixArtifactData {
objType = a_objType;
}
@Messages({"StixArtifactData.indexError.message=Failed to index STIX interesting file hit artifact for keyword search."})
public void createArtifact(String a_title) throws TskCoreException {
Blackboard blackboard = Case.getCurrentCase().getServices().getBlackboard();
@ -72,14 +73,13 @@ class StixArtifactData {
bba.addAttribute(new BlackboardAttribute(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_SET_NAME, "Stix", setName)); //NON-NLS
bba.addAttribute(new BlackboardAttribute(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_TITLE, "Stix", observableId)); //NON-NLS
bba.addAttribute(new BlackboardAttribute(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_CATEGORY, "Stix", objType)); //NON-NLS
try {
// index the artifact for keyword search
blackboard.indexArtifact(bba);
} catch (Blackboard.BlackboardException ex) {
logger.log(Level.SEVERE, NbBundle.getMessage(Blackboard.class, "Blackboard.unableToIndexArtifact.error.msg", bba.getDisplayName()), ex); //NON-NLS
MessageNotifyUtil.Notify.error(
NbBundle.getMessage(Blackboard.class, "Blackboard.unableToIndexArtifact.exception.msg"), bba.getDisplayName());
logger.log(Level.SEVERE, "Unable to index blackboard artifact " + bba.getArtifactID(), ex); //NON-NLS
MessageNotifyUtil.Notify.error(Bundle.StixArtifactData_indexError_message(), bba.getDisplayName());
}
}

View File

@ -179,7 +179,7 @@ ReportHTML.addThumbRows.dataType.msg=Tagged Results and Contents that contain im
ReportHTML.thumbLink.tags=Tags\:
ReportHTML.getName.text=Results - HTML
ReportHTML.getDesc.text=A report about results and tagged items in HTML format.
ReportHTML.writeIndex.title=Autopsy Report for case {0}
ReportHTML.writeIndex.title=for case {0}
ReportHTML.writeIndex.noFrames.msg=Your browser is not compatible with our frame setup.
ReportHTML.writeIndex.noFrames.seeNav=Please see <a href\="nav.html">the navigation page</a> for artifact links,
ReportHTML.writeIndex.seeSum=and <a href\="summary.html">the summary page</a> for a case summary.
@ -225,7 +225,8 @@ ReportHTML.writeSum.noCaseNum=<i>No case number</i>
ReportBodyFile.generateReport.srcModuleName.text=TSK Body File
ReportExcel.endReport.srcModuleName.text=Excel Report
ReportHTML.writeIndex.srcModuleName.text=HTML Report
ReportKML.genReport.srcModuleName.text=KML Report
ReportKML.genReport.srcModuleName.text=Geospatial Data
ReportKML.genReport.reportName=KML Report
ReportGenerator.artTableColHdr.extension.text=Extension
ReportGenerator.artTableColHdr.mimeType.text=MIME Type
ReportGenerator.artTableColHdr.processorArchitecture.text=Processor Architecture

View File

@ -188,7 +188,7 @@ ReportExcel.endReport.srcModuleName.text=Excel\u30ec\u30dd\u30fc\u30c8
ReportGenerator.artTableColHdr.extension.text=\u62e1\u5f35\u5b50
ReportGenerator.artTableColHdr.mimeType.text=MIME\u30bf\u30a4\u30d7
ReportHTML.writeIndex.srcModuleName.text=HTML\u30ec\u30dd\u30fc\u30c8
ReportKML.genReport.srcModuleName.text=KML\u30ec\u30dd\u30fc\u30c8
ReportKML.genReport.reportName=KML\u30ec\u30dd\u30fc\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.devMake=\u6a5f\u5668\u578b\u540d

File diff suppressed because it is too large Load Diff

View File

@ -838,10 +838,17 @@ class ReportHTML implements TableReportModule {
try {
indexOut = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(indexFilePath), "UTF-8")); //NON-NLS
StringBuilder index = new StringBuilder();
index.append("<head>\n<title>").append( //NON-NLS
final String reportTitle = reportBranding.getReportTitle();
String iconPath = reportBranding.getAgencyLogoPath();
if (iconPath == null){
// use default Autopsy icon if custom icon is not set
iconPath = "favicon.ico";
}
index.append("<head>\n<title>").append(reportTitle).append(" ").append(
NbBundle.getMessage(this.getClass(), "ReportHTML.writeIndex.title", currentCase.getName())).append(
"</title>\n"); //NON-NLS
index.append("<link rel=\"icon\" type=\"image/ico\" href=\"favicon.ico\" />\n"); //NON-NLS
index.append("<link rel=\"icon\" type=\"image/ico\" href=\"")
.append(iconPath).append("\" />\n"); //NON-NLS
index.append("<meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\">\n"); //NON-NLS
index.append("</head>\n"); //NON-NLS
index.append("<frameset cols=\"350px,*\">\n"); //NON-NLS

1016
Core/src/org/sleuthkit/autopsy/report/ReportKML.java Normal file → Executable file

File diff suppressed because it is too large Load Diff

View File

@ -24,9 +24,7 @@ import java.util.ArrayList;
import java.util.Collections;
import static java.util.Collections.swap;
import java.util.Comparator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import javax.swing.JList;
import javax.swing.JPanel;
@ -137,8 +135,8 @@ final class ReportVisualPanel1 extends JPanel implements ListSelectionListener {
// Make sure that the report module has a valid non-null name.
private boolean moduleIsValid(ReportModule module) {
return module.getName() != null && !module.getName().isEmpty()
&& module.getRelativeFilePath() != null;
return module.getName() != null && !module.getName().isEmpty()
&& module.getRelativeFilePath() != null;
}
private void popupWarning(ReportModule module) {
@ -163,13 +161,12 @@ final class ReportVisualPanel1 extends JPanel implements ListSelectionListener {
*
* @return
*/
Map<TableReportModule, Boolean> getTableModuleStates() {
Map<TableReportModule, Boolean> reportModuleStates = new LinkedHashMap<>();
TableReportModule getTableModule() {
ReportModule mod = getSelectedModule();
if (tableModules.contains(mod)) {
reportModuleStates.put((TableReportModule) mod, Boolean.TRUE);
return (TableReportModule) mod;
}
return reportModuleStates;
return null;
}
/**
@ -177,13 +174,12 @@ final class ReportVisualPanel1 extends JPanel implements ListSelectionListener {
*
* @return
*/
Map<GeneralReportModule, Boolean> getGeneralModuleStates() {
Map<GeneralReportModule, Boolean> reportModuleStates = new LinkedHashMap<>();
GeneralReportModule getGeneralModule() {
ReportModule mod = getSelectedModule();
if (generalModules.contains(mod)) {
reportModuleStates.put((GeneralReportModule) mod, Boolean.TRUE);
return (GeneralReportModule) mod;
}
return reportModuleStates;
return null;
}
/**
@ -191,13 +187,12 @@ final class ReportVisualPanel1 extends JPanel implements ListSelectionListener {
*
* @return
*/
Map<FileReportModule, Boolean> getFileModuleStates() {
Map<FileReportModule, Boolean> reportModuleStates = new LinkedHashMap<>();
FileReportModule getFileModule() {
ReportModule mod = getSelectedModule();
if (fileModules.contains(mod)) {
reportModuleStates.put((FileReportModule) mod, Boolean.TRUE);
return (FileReportModule) mod;
}
return reportModuleStates;
return null;
}
/**

View File

@ -1,4 +1,4 @@
/*
/*
*
* Autopsy Forensic Browser
*
@ -65,13 +65,17 @@ public final class ReportWizardAction extends CallableSystemAction implements Pr
wiz.setTitle(NbBundle.getMessage(ReportWizardAction.class, "ReportWizardAction.reportWiz.title"));
if (DialogDisplayer.getDefault().notify(wiz) == WizardDescriptor.FINISH_OPTION) {
@SuppressWarnings("unchecked")
ReportGenerator generator = new ReportGenerator((Map<TableReportModule, Boolean>) wiz.getProperty("tableModuleStates"), //NON-NLS
(Map<GeneralReportModule, Boolean>) wiz.getProperty("generalModuleStates"), //NON-NLS
(Map<FileReportModule, Boolean>) wiz.getProperty("fileModuleStates")); //NON-NLS
generator.generateTableReports((Map<BlackboardArtifact.Type, Boolean>) wiz.getProperty("artifactStates"), (Map<String, Boolean>) wiz.getProperty("tagStates")); //NON-NLS
generator.generateFileListReports((Map<FileReportDataTypes, Boolean>) wiz.getProperty("fileReportOptions")); //NON-NLS
generator.generateGeneralReports();
generator.displayProgressPanels();
ReportGenerator generator = new ReportGenerator(); //NON-NLS
TableReportModule tableReport = (TableReportModule) wiz.getProperty("tableModule");
GeneralReportModule generalReport = (GeneralReportModule) wiz.getProperty("generalModule");
FileReportModule fileReport = (FileReportModule) wiz.getProperty("fileModule");
if (tableReport != null) {
generator.generateTableReport(tableReport, (Map<BlackboardArtifact.Type, Boolean>) wiz.getProperty("artifactStates"), (Map<String, Boolean>) wiz.getProperty("tagStates")); //NON-NLS
} else if (generalReport != null) {
generator.generateGeneralReport(generalReport);
} else if (fileReport != null) {
generator.generateFileListReport(fileReport, (Map<FileReportDataTypes, Boolean>) wiz.getProperty("fileReportOptions")); //NON-NLS
}
}
}

View File

@ -21,7 +21,6 @@ package org.sleuthkit.autopsy.report;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Collection;
import java.util.Map;
import java.util.prefs.Preferences;
import javax.swing.JButton;
import javax.swing.event.ChangeListener;
@ -108,17 +107,17 @@ class ReportWizardPanel1 implements WizardDescriptor.FinishablePanel<WizardDescr
@Override
public void storeSettings(WizardDescriptor wiz) {
Map<TableReportModule, Boolean> tables = getComponent().getTableModuleStates();
Map<GeneralReportModule, Boolean> generals = getComponent().getGeneralModuleStates();
wiz.putProperty("tableModuleStates", tables); //NON-NLS
wiz.putProperty("generalModuleStates", generals); //NON-NLS
wiz.putProperty("fileModuleStates", getComponent().getFileModuleStates()); //NON-NLS
TableReportModule module = getComponent().getTableModule();
GeneralReportModule general = getComponent().getGeneralModule();
wiz.putProperty("tableModule", module); //NON-NLS
wiz.putProperty("generalModule", general); //NON-NLS
wiz.putProperty("fileModule", getComponent().getFileModule()); //NON-NLS
// Store preferences that WizardIterator will use to determine what
// panels need to be shown
Preferences prefs = NbPreferences.forModule(ReportWizardPanel1.class);
prefs.putBoolean("tableModule", any(tables.values())); //NON-NLS
prefs.putBoolean("generalModule", any(generals.values())); //NON-NLS
prefs.putBoolean("tableModule", module != null); //NON-NLS
prefs.putBoolean("generalModule", general != null); //NON-NLS
}
/**

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,299 @@
<?xml version="1.0" encoding="UTF-8"?>
<kml xmlns="http://www.opengis.net/kml/2.2" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:gx="http://www.google.com/kml/ext/2.2" xmlns:kml="http://www.opengis.net/kml/2.2">
<Document>
<StyleMap id="yellowFeature">
<Pair>
<key>normal</key>
<styleUrl>#n_YellowPushpin</styleUrl>
</Pair>
<Pair>
<key>highlight</key>
<styleUrl>#h_YellowPushpin</styleUrl>
</Pair>
</StyleMap>
<Style id="n_YellowPushpin">
<IconStyle>
<scale>1.0</scale>
<Icon>
<href>http://maps.google.com/mapfiles/kml/pushpin/ylw-pushpin.png</href>
</Icon>
<hotSpot x="20" y="2" xunits="pixels" yunits="pixels" />
</IconStyle>
<LabelStyle>
<scale>0</scale>
</LabelStyle>
<LineStyle>
<color>FF00FFFF</color>
<width>5.0</width>
</LineStyle>
<BalloonStyle>
<text>$[description]</text>
</BalloonStyle>
</Style>
<Style id="h_YellowPushpin">
<IconStyle>
<scale>1.3</scale>
<Icon>
<href>http://maps.google.com/mapfiles/kml/pushpin/ylw-pushpin.png</href>
</Icon>
<hotSpot x="20" y="2" xunits="pixels" yunits="pixels" />
</IconStyle>
<LabelStyle>
<scale>1</scale>
</LabelStyle>
<LineStyle>
<color>FF00FFFF</color>
<width>10.0</width>
</LineStyle>
<BalloonStyle>
<text>$[description]</text>
</BalloonStyle>
</Style>
<StyleMap id="blueFeature">
<Pair>
<key>normal</key>
<styleUrl>#n_bluePushpin</styleUrl>
</Pair>
<Pair>
<key>highlight</key>
<styleUrl>#h_bluePushpin</styleUrl>
</Pair>
</StyleMap>
<Style id="n_bluePushpin">
<IconStyle>
<scale>1.0</scale>
<Icon>
<href>http://maps.google.com/mapfiles/kml/pushpin/blue-pushpin.png</href>
</Icon>
<hotSpot x="20" y="2" xunits="pixels" yunits="pixels" />
</IconStyle>
<LabelStyle>
<scale>0</scale>
</LabelStyle>
<LineStyle>
<color>FFE63900</color>
<width>5.0</width>
</LineStyle>
<BalloonStyle>
<text>$[description]</text>
</BalloonStyle>
</Style>
<Style id="h_bluePushpin">
<IconStyle>
<scale>1.3</scale>
<Icon>
<href>http://maps.google.com/mapfiles/kml/pushpin/blue-pushpin.png</href>
</Icon>
<hotSpot x="20" y="2" xunits="pixels" yunits="pixels" />
</IconStyle>
<LabelStyle>
<scale>1</scale>
</LabelStyle>
<LineStyle>
<color>FFE63900</color>
<width>10.0</width>
</LineStyle>
<BalloonStyle>
<text>$[description]</text>
</BalloonStyle>
</Style>
<StyleMap id="redFeature">
<Pair>
<key>normal</key>
<styleUrl>#n_redPushpin</styleUrl>
</Pair>
<Pair>
<key>highlight</key>
<styleUrl>#h_redPushpin</styleUrl>
</Pair>
</StyleMap>
<Style id="n_redPushpin">
<IconStyle>
<scale>1.0</scale>
<Icon>
<href>http://maps.google.com/mapfiles/kml/pushpin/red-pushpin.png</href>
</Icon>
<hotSpot x="20" y="2" xunits="pixels" yunits="pixels" />
</IconStyle>
<LabelStyle>
<scale>0</scale>
</LabelStyle>
<LineStyle>
<color>FF0000FF</color>
<width>5.0</width>
</LineStyle>
<BalloonStyle>
<text>$[description]</text>
</BalloonStyle>
</Style>
<Style id="h_redPushpin">
<IconStyle>
<scale>1.3</scale>
<Icon>
<href>http://maps.google.com/mapfiles/kml/pushpin/red-pushpin.png</href>
</Icon>
<hotSpot x="20" y="2" xunits="pixels" yunits="pixels" />
</IconStyle>
<LabelStyle>
<scale>1</scale>
</LabelStyle>
<LineStyle>
<color>FF0000FF</color>
<width>10.0</width>
</LineStyle>
<BalloonStyle>
<text>$[description]</text>
</BalloonStyle>
</Style>
<StyleMap id="greenFeature">
<Pair>
<key>normal</key>
<styleUrl>#n_greenPushpin</styleUrl>
</Pair>
<Pair>
<key>highlight</key>
<styleUrl>#h_greenPushpin</styleUrl>
</Pair>
</StyleMap>
<Style id="n_greenPushpin">
<IconStyle>
<scale>1.0</scale>
<Icon>
<href>http://maps.google.com/mapfiles/kml/pushpin/grn-pushpin.png</href>
</Icon>
<hotSpot x="20" y="2" xunits="pixels" yunits="pixels" />
</IconStyle>
<LabelStyle>
<scale>1</scale>
</LabelStyle>
<LineStyle>
<color>FF00CC00</color>
<width>5.0</width>
</LineStyle>
<BalloonStyle>
<text>
A route was planned between these two points. The green line connecting the points is not the actual route, but it indicates which Start and End points are associated with each other.
$[description]
</text>
</BalloonStyle>
</Style>
<Style id="h_greenPushpin">
<IconStyle>
<scale>1.3</scale>
<Icon>
<href>http://maps.google.com/mapfiles/kml/pushpin/grn-pushpin.png</href>
</Icon>
<hotSpot x="20" y="2" xunits="pixels" yunits="pixels" />
</IconStyle>
<LabelStyle>
<scale>1</scale>
</LabelStyle>
<LineStyle>
<color>FF00CC00</color>
<width>10.0</width>
</LineStyle>
<BalloonStyle>
<text>
A route was planned between these two points. The green line connecting the points is not the actual route, but it indicates which Start and End points are associated with each other.
$[description]
</text>
</BalloonStyle>
</Style>
<StyleMap id="purpleFeature">
<Pair>
<key>normal</key>
<styleUrl>#n_purplePushpin</styleUrl>
</Pair>
<Pair>
<key>highlight</key>
<styleUrl>#h_purplePushpin</styleUrl>
</Pair>
</StyleMap>
<Style id="n_purplePushpin">
<IconStyle>
<scale>1.0</scale>
<Icon>
<href>http://maps.google.com/mapfiles/kml/pushpin/purple-pushpin.png</href>
</Icon>
<hotSpot x="20" y="2" xunits="pixels" yunits="pixels" />
</IconStyle>
<LabelStyle>
<scale>1</scale>
</LabelStyle>
<LineStyle>
<color>FFCC0066</color>
<width>5.0</width>
</LineStyle>
<BalloonStyle>
<text>$[description]</text>
</BalloonStyle>
</Style>
<Style id="h_purplePushpin">
<IconStyle>
<scale>1.3</scale>
<Icon>
<href>http://maps.google.com/mapfiles/kml/pushpin/purple-pushpin.png</href>
</Icon>
<hotSpot x="20" y="2" xunits="pixels" yunits="pixels" />
</IconStyle>
<LabelStyle>
<scale>1</scale>
</LabelStyle>
<LineStyle>
<color>FFCC0066</color>
<width>10.0</width>
</LineStyle>
<BalloonStyle>
<text>$[description]</text>
</BalloonStyle>
</Style>
<StyleMap id="whiteFeature">
<Pair>
<key>normal</key>
<styleUrl>#n_whitePushpin</styleUrl>
</Pair>
<Pair>
<key>highlight</key>
<styleUrl>#h_whitePushpin</styleUrl>
</Pair>
</StyleMap>
<Style id="n_whitePushpin">
<IconStyle>
<scale>1.0</scale>
<Icon>
<href>http://maps.google.com/mapfiles/kml/pushpin/wht-pushpin.png</href>
</Icon>
<hotSpot x="20" y="2" xunits="pixels" yunits="pixels" />
</IconStyle>
<LabelStyle>
<scale>0</scale>
</LabelStyle>
<BalloonStyle>
<text>$[description]</text>
</BalloonStyle>
<LineStyle>
<color>FFFFFFFF</color>
<width>5.0</width>
</LineStyle>
</Style>
<Style id="h_whitePushpin">
<IconStyle>
<scale>1.3</scale>
<Icon>
<href>http://maps.google.com/mapfiles/kml/pushpin/wht-pushpin.png</href>
</Icon>
<hotSpot x="20" y="2" xunits="pixels" yunits="pixels" />
</IconStyle>
<LabelStyle>
<scale>1</scale>
</LabelStyle>
<LineStyle>
<color>FFFFFFFF</color>
<width>10.0</width>
</LineStyle>
<BalloonStyle>
<text>$[description]</text>
</BalloonStyle>
</Style>
</Document>
</kml>

View File

@ -9,7 +9,7 @@ Timeline.zoomOutButton.text=Zoom Out
Timeline.goToButton.text=Go To\:
Timeline.yearBarChart.x.years=Years
Timeline.resultPanel.loading=Loading...
Timeline.node.root=Root
TimelineFrame.title=Timeline
TimelinePanel.jButton1.text=6m
TimelinePanel.jButton13.text=all
@ -24,4 +24,4 @@ TimelinePanel.jButton7.text=3d
TimelinePanel.jButton2.text=1m
TimelinePanel.jButton3.text=3m
TimelinePanel.jButton4.text=2w
ProgressWindow.progressHeader.text=\
ProgressWindow.progressHeader.text=\

View File

@ -1,48 +1,48 @@
CTL_MakeTimeline=\u300C\u30BF\u30A4\u30E0\u30E9\u30A4\u30F3\u300D
CTL_TimeLineTopComponent=\u30BF\u30A4\u30E0\u30E9\u30A4\u30F3\u30A6\u30A3\u30F3\u30C9\u30A6
CTL_TimeLineTopComponentAction=\u30BF\u30A4\u30E0\u30E9\u30A4\u30F3\u30C8\u30C3\u30D7\u30B3\u30F3\u30DD\u30FC\u30CD\u30F3\u30C8
HINT_TimeLineTopComponent=\u3053\u308C\u306F\u30BF\u30A4\u30E0\u30E9\u30A4\u30F3\u30A6\u30A3\u30F3\u30C9\u30A6\u3067\u3059
OpenTimelineAction.title=\u30BF\u30A4\u30E0\u30E9\u30A4\u30F3
Timeline.frameName.text={0} - Autopsy\u30BF\u30A4\u30E0\u30E9\u30A4\u30F3
Timeline.goToButton.text=\u4E0B\u8A18\u3078\u79FB\u52D5\uFF1A
Timeline.node.root=\u30EB\u30FC\u30C8
Timeline.pushDescrLOD.confdlg.msg={0}\u30A4\u30D9\u30F3\u30C8\u306E\u8A73\u7D30\u304C\u8868\u793A\u53EF\u80FD\u3067\u3059\u3002\u3053\u306E\u51E6\u7406\u306F\u9577\u6642\u9593\u304B\u304B\u308B\u3082\u3057\u304F\u306FAutopsy\u3092\u30AF\u30E9\u30C3\u30B7\u30E5\u3059\u308B\u53EF\u80FD\u6027\u304C\u3042\u308A\u307E\u3059\u3002\n\n\u5B9F\u884C\u3057\u307E\u3059\u304B\uFF1F
Timeline.resultPanel.loading=\u30ED\u30FC\u30C9\u4E2D\u30FB\u30FB\u30FB
Timeline.resultsPanel.title=\u30BF\u30A4\u30E0\u30E9\u30A4\u30F3\u7D50\u679C
Timeline.runJavaFxThread.progress.creating=\u30BF\u30A4\u30E0\u30E9\u30A4\u30F3\u4F5C\u6210\u4E2D\u30FB\u30FB\u30FB
Timeline.zoomOutButton.text=\u30BA\u30FC\u30E0\u30A2\u30A6\u30C8
TimelineFrame.title=\u30BF\u30A4\u30E0\u30E9\u30A4\u30F3
TimeLineTopComponent.eventsTab.name=\u30A4\u30D9\u30F3\u30C8
TimeLineTopComponent.filterTab.name=\u30D5\u30A3\u30EB\u30BF\u30FC
OpenTimeLineAction.msgdlg.text=\u30BF\u30A4\u30E0\u30E9\u30A4\u30F3\u3092\u4F5C\u6210\u3067\u304D\u307E\u305B\u3093\u3067\u3057\u305F\u3002\u30C7\u30FC\u30BF\u30BD\u30FC\u30B9\u304C\u3042\u308A\u307E\u305B\u3093\u3002
PrompDialogManager.buttonType.continueNoUpdate=\u66F4\u65B0\u305B\u305A\u6B21\u3078
PrompDialogManager.buttonType.showTimeline=\u30BF\u30A4\u30E0\u30E9\u30A4\u30F3\u3092\u8868\u793A
PrompDialogManager.buttonType.update=\u66F4\u65B0
PromptDialogManager.confirmDuringIngest.contentText=\u6B21\u3078\u9032\u307F\u307E\u3059\u304B\uFF1F
PromptDialogManager.confirmDuringIngest.headerText=\u30A4\u30F3\u30B8\u30A7\u30B9\u30C8\u304C\u5B8C\u4E86\u3059\u308B\u524D\u306B\u30BF\u30A4\u30E0\u30E9\u30A4\u30F3\u3092\u8868\u793A\u3057\u3088\u3046\u3068\u3057\u3066\u3044\u307E\u3059\u3002\n\u30BF\u30A4\u30E0\u30E9\u30A4\u30F3\u304C\u5B8C\u6210\u3057\u3066\u3044\u306A\u3044\u304B\u3082\u3057\u308C\u307E\u305B\u3093\u3002
PromptDialogManager.progressDialog.title=\u30BF\u30A4\u30E0\u30E9\u30A4\u30F3\u30C7\u30FC\u30BF\u3092\u5165\u529B\u4E2D
PromptDialogManager.rebuildPrompt.details=\u8A73\u7D30\uFF1A
PromptDialogManager.rebuildPrompt.headerText=\u30BF\u30A4\u30E0\u30E9\u30A4\u30F3\u30C7\u30FC\u30BF\u30D9\u30FC\u30B9\u304C\u4E0D\u5B8C\u5168\u307E\u305F\u306F\u6700\u65B0\u3067\u306F\u306A\u3044\u304B\u3082\u3057\u308C\u307E\u305B\u3093\u3002\n \u6B20\u843D\u3057\u3066\u3044\u308B\u307E\u305F\u306F\u4E0D\u6B63\u78BA\u306A\u30A4\u30D9\u30F3\u30C8\u304C\u4E00\u90E8\u3042\u308B\u304B\u3082\u3057\u308C\u307E\u305B\u3093\u3002\u4E00\u90E8\u306E\u6A5F\u80FD\u304C\u5229\u7528\u3067\u304D\u306A\u3044\u304B\u3082\u3057\u308C\u307E\u305B\u3093\u3002
Timeline.confirmation.dialogs.title=\u30BF\u30A4\u30E0\u30E9\u30A4\u30F3\u306E\u30C7\u30FC\u30BF\u30D9\u30FC\u30B9\u3092\u66F4\u65B0\u3057\u307E\u3059\u304B\uFF1F
Timeline.pushDescrLOD.confdlg.title=\u8AAC\u660E\u306E\u8A18\u8FF0\u30EC\u30D9\u30EB\u3092\u5909\u66F4\u3057\u307E\u3059\u304B\uFF1F
TimeLineController.errorTitle=\u30BF\u30A4\u30E0\u30E9\u30A4\u30F3\u30A8\u30E9\u30FC
TimeLineController.outOfDate.errorMessage=\u30BF\u30A4\u30E0\u30E9\u30A4\u30F3\u304C\u6700\u65B0\u304B\u78BA\u8A8D\u4E2D\u306B\u30A8\u30E9\u30FC\u304C\u767A\u751F\u3057\u307E\u3057\u305F\u3002\u66F4\u65B0\u304C\u5FC5\u8981\u3060\u3068\u60F3\u5B9A\u3057\u307E\u3059\u3002
TimeLineController.rebuildReasons.incompleteOldSchema=\u30BF\u30A4\u30E0\u30E9\u30A4\u30F3\u30A4\u30D9\u30F3\u30C8\u306E\u30C7\u30FC\u30BF\u30D9\u30FC\u30B9\u306B\u4E0D\u5B8C\u5168\u306A\u60C5\u5831\u304C\u4EE5\u524D\u5165\u529B\u3055\u308C\u3066\u3044\u307E\u3057\u305F\uFF1A\u30A4\u30D9\u30F3\u30C8\u30C7\u30FC\u30BF\u30D9\u30FC\u30B9\u3092\u66F4\u65B0\u3057\u306A\u3044\u3068\u3001\u4E00\u90E8\u306E\u6A5F\u80FD\u304C\u5229\u7528\u3067\u304D\u306A\u3044\u3001\u307E\u305F\u306F\u6A5F\u80FD\u3057\u306A\u3044\u304B\u3082\u3057\u308C\u306A\u3044\u3067\u3059\u3002
TimeLineController.rebuildReasons.ingestWasRunning=\u30A4\u30F3\u30B8\u30A7\u30B9\u30C8\u304C\u5B9F\u884C\u4E2D\u306B\u30BF\u30A4\u30E0\u30E9\u30A4\u30F3\u30A4\u30D9\u30F3\u30C8\u306E\u30C7\u30FC\u30BF\u30D9\u30FC\u30B9\u306B\u60C5\u5831\u304C\u5165\u529B\u3055\u308C\u3066\u3044\u307E\u3057\u305F\uFF1A\u30A4\u30D9\u30F3\u30C8\u304C\u6B20\u3051\u3066\u3044\u308B\u3001\u4E0D\u5B8C\u5168\u3001\u307E\u305F\u306F\u4E0D\u6B63\u78BA\u304B\u3082\u3057\u308C\u307E\u305B\u3093\u3002
TimeLineController.rebuildReasons.outOfDate=\u30A4\u30D9\u30F3\u30C8\u30C7\u30FC\u30BF\u304C\u6700\u65B0\u3067\u306F\u3042\u308A\u307E\u305B\u3093\uFF1A\u898B\u308C\u306A\u3044\u30A4\u30D9\u30F3\u30C8\u304C\u3042\u308A\u307E\u3059\u3002
TimeLineController.rebuildReasons.outOfDateError=\u30BF\u30A4\u30E0\u30E9\u30A4\u30F3\u30C7\u30FC\u30BF\u304C\u6700\u65B0\u304B\u78BA\u8A8D\u3067\u304D\u307E\u305B\u3093\u3067\u3057\u305F\u3002
TimeLinecontroller.updateNowQuestion=\u30A4\u30D9\u30F3\u30C8\u30C7\u30FC\u30BF\u30D9\u30FC\u30B9\u3092\u4ECA\u66F4\u65B0\u3057\u307E\u3059\u304B\uFF1F
CTL_MakeTimeline=\u300c\u30bf\u30a4\u30e0\u30e9\u30a4\u30f3\u300d
CTL_TimeLineTopComponent=\u30bf\u30a4\u30e0\u30e9\u30a4\u30f3\u30a6\u30a3\u30f3\u30c9\u30a6
CTL_TimeLineTopComponentAction=\u30bf\u30a4\u30e0\u30e9\u30a4\u30f3\u30c8\u30c3\u30d7\u30b3\u30f3\u30dd\u30fc\u30cd\u30f3\u30c8
HINT_TimeLineTopComponent=\u3053\u308c\u306f\u30bf\u30a4\u30e0\u30e9\u30a4\u30f3\u30a6\u30a3\u30f3\u30c9\u30a6\u3067\u3059
OpenTimelineAction.title=\u30bf\u30a4\u30e0\u30e9\u30a4\u30f3
Timeline.frameName.text={0} - Autopsy\u30bf\u30a4\u30e0\u30e9\u30a4\u30f3
Timeline.goToButton.text=\u4e0b\u8a18\u3078\u79fb\u52d5\uff1a
Timeline.pushDescrLOD.confdlg.msg={0}\u30a4\u30d9\u30f3\u30c8\u306e\u8a73\u7d30\u304c\u8868\u793a\u53ef\u80fd\u3067\u3059\u3002\u3053\u306e\u51e6\u7406\u306f\u9577\u6642\u9593\u304b\u304b\u308b\u3082\u3057\u304f\u306fAutopsy\u3092\u30af\u30e9\u30c3\u30b7\u30e5\u3059\u308b\u53ef\u80fd\u6027\u304c\u3042\u308a\u307e\u3059\u3002\n\n\u5b9f\u884c\u3057\u307e\u3059\u304b\uff1f
Timeline.resultPanel.loading=\u30ed\u30fc\u30c9\u4e2d\u30fb\u30fb\u30fb
Timeline.resultsPanel.title=\u30bf\u30a4\u30e0\u30e9\u30a4\u30f3\u7d50\u679c
Timeline.runJavaFxThread.progress.creating=\u30bf\u30a4\u30e0\u30e9\u30a4\u30f3\u4f5c\u6210\u4e2d\u30fb\u30fb\u30fb
Timeline.zoomOutButton.text=\u30ba\u30fc\u30e0\u30a2\u30a6\u30c8
TimelineFrame.title=\u30bf\u30a4\u30e0\u30e9\u30a4\u30f3
TimeLineTopComponent.eventsTab.name=\u30a4\u30d9\u30f3\u30c8
TimeLineTopComponent.filterTab.name=\u30d5\u30a3\u30eb\u30bf\u30fc
OpenTimeLineAction.msgdlg.text=\u30bf\u30a4\u30e0\u30e9\u30a4\u30f3\u3092\u4f5c\u6210\u3067\u304d\u307e\u305b\u3093\u3067\u3057\u305f\u3002\u30c7\u30fc\u30bf\u30bd\u30fc\u30b9\u304c\u3042\u308a\u307e\u305b\u3093\u3002
PrompDialogManager.buttonType.continueNoUpdate=\u66f4\u65b0\u305b\u305a\u6b21\u3078
PrompDialogManager.buttonType.showTimeline=\u30bf\u30a4\u30e0\u30e9\u30a4\u30f3\u3092\u8868\u793a
PrompDialogManager.buttonType.update=\u66f4\u65b0
PromptDialogManager.confirmDuringIngest.contentText=\u6b21\u3078\u9032\u307f\u307e\u3059\u304b\uff1f
PromptDialogManager.confirmDuringIngest.headerText=\u30a4\u30f3\u30b8\u30a7\u30b9\u30c8\u304c\u5b8c\u4e86\u3059\u308b\u524d\u306b\u30bf\u30a4\u30e0\u30e9\u30a4\u30f3\u3092\u8868\u793a\u3057\u3088\u3046\u3068\u3057\u3066\u3044\u307e\u3059\u3002\n\u30bf\u30a4\u30e0\u30e9\u30a4\u30f3\u304c\u5b8c\u6210\u3057\u3066\u3044\u306a\u3044\u304b\u3082\u3057\u308c\u307e\u305b\u3093\u3002
PromptDialogManager.progressDialog.title=\u30bf\u30a4\u30e0\u30e9\u30a4\u30f3\u30c7\u30fc\u30bf\u3092\u5165\u529b\u4e2d
PromptDialogManager.rebuildPrompt.details=\u8a73\u7d30\uff1a
PromptDialogManager.rebuildPrompt.headerText=\u30bf\u30a4\u30e0\u30e9\u30a4\u30f3\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u304c\u4e0d\u5b8c\u5168\u307e\u305f\u306f\u6700\u65b0\u3067\u306f\u306a\u3044\u304b\u3082\u3057\u308c\u307e\u305b\u3093\u3002\n \u6b20\u843d\u3057\u3066\u3044\u308b\u307e\u305f\u306f\u4e0d\u6b63\u78ba\u306a\u30a4\u30d9\u30f3\u30c8\u304c\u4e00\u90e8\u3042\u308b\u304b\u3082\u3057\u308c\u307e\u305b\u3093\u3002\u4e00\u90e8\u306e\u6a5f\u80fd\u304c\u5229\u7528\u3067\u304d\u306a\u3044\u304b\u3082\u3057\u308c\u307e\u305b\u3093\u3002
Timeline.confirmation.dialogs.title=\u30bf\u30a4\u30e0\u30e9\u30a4\u30f3\u306e\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u3092\u66f4\u65b0\u3057\u307e\u3059\u304b\uff1f
Timeline.pushDescrLOD.confdlg.title=\u8aac\u660e\u306e\u8a18\u8ff0\u30ec\u30d9\u30eb\u3092\u5909\u66f4\u3057\u307e\u3059\u304b\uff1f
TimeLineController.errorTitle=\u30bf\u30a4\u30e0\u30e9\u30a4\u30f3\u30a8\u30e9\u30fc
TimeLineController.outOfDate.errorMessage=\u30bf\u30a4\u30e0\u30e9\u30a4\u30f3\u304c\u6700\u65b0\u304b\u78ba\u8a8d\u4e2d\u306b\u30a8\u30e9\u30fc\u304c\u767a\u751f\u3057\u307e\u3057\u305f\u3002\u66f4\u65b0\u304c\u5fc5\u8981\u3060\u3068\u60f3\u5b9a\u3057\u307e\u3059\u3002
TimeLineController.rebuildReasons.incompleteOldSchema=\u30bf\u30a4\u30e0\u30e9\u30a4\u30f3\u30a4\u30d9\u30f3\u30c8\u306e\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u306b\u4e0d\u5b8c\u5168\u306a\u60c5\u5831\u304c\u4ee5\u524d\u5165\u529b\u3055\u308c\u3066\u3044\u307e\u3057\u305f\uff1a\u30a4\u30d9\u30f3\u30c8\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u3092\u66f4\u65b0\u3057\u306a\u3044\u3068\u3001\u4e00\u90e8\u306e\u6a5f\u80fd\u304c\u5229\u7528\u3067\u304d\u306a\u3044\u3001\u307e\u305f\u306f\u6a5f\u80fd\u3057\u306a\u3044\u304b\u3082\u3057\u308c\u306a\u3044\u3067\u3059\u3002
TimeLineController.rebuildReasons.ingestWasRunning=\u30a4\u30f3\u30b8\u30a7\u30b9\u30c8\u304c\u5b9f\u884c\u4e2d\u306b\u30bf\u30a4\u30e0\u30e9\u30a4\u30f3\u30a4\u30d9\u30f3\u30c8\u306e\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u306b\u60c5\u5831\u304c\u5165\u529b\u3055\u308c\u3066\u3044\u307e\u3057\u305f\uff1a\u30a4\u30d9\u30f3\u30c8\u304c\u6b20\u3051\u3066\u3044\u308b\u3001\u4e0d\u5b8c\u5168\u3001\u307e\u305f\u306f\u4e0d\u6b63\u78ba\u304b\u3082\u3057\u308c\u307e\u305b\u3093\u3002
TimeLineController.rebuildReasons.outOfDate=\u30a4\u30d9\u30f3\u30c8\u30c7\u30fc\u30bf\u304c\u6700\u65b0\u3067\u306f\u3042\u308a\u307e\u305b\u3093\uff1a\u898b\u308c\u306a\u3044\u30a4\u30d9\u30f3\u30c8\u304c\u3042\u308a\u307e\u3059\u3002
TimeLineController.rebuildReasons.outOfDateError=\u30bf\u30a4\u30e0\u30e9\u30a4\u30f3\u30c7\u30fc\u30bf\u304c\u6700\u65b0\u304b\u78ba\u8a8d\u3067\u304d\u307e\u305b\u3093\u3067\u3057\u305f\u3002
TimeLinecontroller.updateNowQuestion=\u30a4\u30d9\u30f3\u30c8\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u3092\u4eca\u66f4\u65b0\u3057\u307e\u3059\u304b\uff1f
TimelinePanel.jButton13.text=\u5168\u3066
Timeline.yearBarChart.x.years=\u5E74
TimelinePanel.jButton1.text=6\u30F6\u6708
Timeline.yearBarChart.x.years=\u5e74
TimelinePanel.jButton1.text=6\u30f6\u6708
TimelinePanel.jButton10.text=1\u6642\u9593
TimelinePanel.jButton9.text=12\u6642\u9593
TimelinePanel.jButton11.text=5\u5E74
TimelinePanel.jButton12.text=10\u5E74
TimelinePanel.jButton11.text=5\u5e74
TimelinePanel.jButton12.text=10\u5e74
TimelinePanel.jButton6.text=1\u9031\u9593
TimelinePanel.jButton5.text=1\u5E74
TimelinePanel.jButton8.text=1\u65E5
TimelinePanel.jButton7.text=3\u65E5
TimelinePanel.jButton2.text=1\u30F6\u6708
TimelinePanel.jButton3.text=3\u30F6\u6708
TimelinePanel.jButton4.text=2\u9031\u9593
TimelinePanel.jButton5.text=1\u5e74
TimelinePanel.jButton8.text=1\u65e5
TimelinePanel.jButton7.text=3\u65e5
TimelinePanel.jButton2.text=1\u30f6\u6708
TimelinePanel.jButton3.text=3\u30f6\u6708
TimelinePanel.jButton4.text=2\u9031\u9593
TimeLineResultView.startDateToEndDate.text={0}\u304b\u3089{1}

View File

@ -18,8 +18,13 @@
*/
package org.sleuthkit.autopsy.timeline;
import java.awt.Component;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.IOException;
import java.util.logging.Level;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import org.openide.awt.ActionID;
import org.openide.awt.ActionReference;
import org.openide.awt.ActionReferences;
@ -27,6 +32,7 @@ import org.openide.awt.ActionRegistration;
import org.openide.util.HelpCtx;
import org.openide.util.NbBundle;
import org.openide.util.actions.CallableSystemAction;
import org.openide.util.actions.Presenter;
import org.sleuthkit.autopsy.casemodule.Case;
import org.sleuthkit.autopsy.core.Installer;
import org.sleuthkit.autopsy.coreutils.Logger;
@ -36,8 +42,9 @@ import org.sleuthkit.autopsy.coreutils.ThreadConfined;
@ActionID(category = "Tools", id = "org.sleuthkit.autopsy.timeline.Timeline")
@ActionRegistration(displayName = "#CTL_MakeTimeline", lazy = false)
@ActionReferences(value = {
@ActionReference(path = "Menu/Tools", position = 100)})
public class OpenTimelineAction extends CallableSystemAction {
@ActionReference(path = "Menu/Tools", position = 100),
@ActionReference(path = "Toolbars/Case", position = 102)})
public class OpenTimelineAction extends CallableSystemAction implements Presenter.Toolbar {
private static final Logger LOGGER = Logger.getLogger(OpenTimelineAction.class.getName());
@ -45,10 +52,22 @@ public class OpenTimelineAction extends CallableSystemAction {
private static TimeLineController timeLineController = null;
private JButton toolbarButton = new JButton();
synchronized static void invalidateController() {
timeLineController = null;
}
public OpenTimelineAction() {
toolbarButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
performAction();
}
});
this.setEnabled(false);
}
@Override
public boolean isEnabled() {
/**
@ -102,4 +121,29 @@ public class OpenTimelineAction extends CallableSystemAction {
public boolean asynchronous() {
return false; // run on edt
}
/**
* Set this action to be enabled/disabled
*
* @param value whether to enable this action or not
*/
@Override
public void setEnabled(boolean value) {
super.setEnabled(value);
toolbarButton.setEnabled(value);
}
/**
* Returns the toolbar component of this action
*
* @return component the toolbar button
*/
@Override
public Component getToolbarPresenter() {
ImageIcon icon = new ImageIcon("Core/src/org/sleuthkit/autopsy/timeline/images/btn_icon_timeline_colorized_26.png"); //NON-NLS
toolbarButton.setIcon(icon);
toolbarButton.setText(this.getName());
return toolbarButton;
}
}

View File

@ -24,6 +24,7 @@ import java.io.IOException;
import java.time.ZoneId;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.TimeZone;
import java.util.concurrent.ExecutionException;
@ -188,7 +189,7 @@ public class TimeLineController {
}
@ThreadConfined(type = ThreadConfined.ThreadType.AWT)
private TimeLineTopComponent mainFrame;
private TimeLineTopComponent topComponent;
//are the listeners currently attached
@ThreadConfined(type = ThreadConfined.ThreadType.AWT)
@ -199,11 +200,7 @@ public class TimeLineController {
private final PropertyChangeListener ingestModuleListener = new AutopsyIngestModuleListener();
@GuardedBy("this")
private final ReadOnlyObjectWrapper<VisualizationMode> visualizationMode = new ReadOnlyObjectWrapper<>(VisualizationMode.COUNTS);
synchronized public ReadOnlyObjectProperty<VisualizationMode> visualizationModeProperty() {
return visualizationMode.getReadOnlyProperty();
}
private final ReadOnlyObjectWrapper<ViewMode> viewMode = new ReadOnlyObjectWrapper<>(ViewMode.COUNTS);
@GuardedBy("filteredEvents")
private final FilteredEventsModel filteredEvents;
@ -223,21 +220,38 @@ public class TimeLineController {
@GuardedBy("this")
private final ObservableList<Long> selectedEventIDs = FXCollections.<Long>synchronizedObservableList(FXCollections.<Long>observableArrayList());
@GuardedBy("this")
private final ReadOnlyObjectWrapper<Interval> selectedTimeRange = new ReadOnlyObjectWrapper<>();
private final ReadOnlyBooleanWrapper eventsDBStale = new ReadOnlyBooleanWrapper(true);
private final PromptDialogManager promptDialogManager = new PromptDialogManager(this);
/**
* @return A list of the selected event ids
* Get an ObservableList of selected event IDs
*
* @return A list of the selected event IDs
*/
synchronized public ObservableList<Long> getSelectedEventIDs() {
return selectedEventIDs;
}
@GuardedBy("this")
private final ReadOnlyObjectWrapper<Interval> selectedTimeRange = new ReadOnlyObjectWrapper<>();
/**
* Get a read only observable view of the selected time range.
*
* @return A read only view of the selected time range.
*/
synchronized public ReadOnlyObjectProperty<Interval> selectedTimeRangeProperty() {
return selectedTimeRange.getReadOnlyProperty();
}
/**
* @return a read only view of the selected interval.
* Get the selected time range.
*
* @return The selected time range.
*/
synchronized public ReadOnlyObjectProperty<Interval> getSelectedTimeRange() {
return selectedTimeRange.getReadOnlyProperty();
synchronized public Interval getSelectedTimeRange() {
return selectedTimeRange.get();
}
public ReadOnlyBooleanProperty eventsDBStaleProperty() {
@ -282,9 +296,30 @@ public class TimeLineController {
synchronized public ReadOnlyBooleanProperty canRetreatProperty() {
return historyManager.getCanRetreat();
}
private final ReadOnlyBooleanWrapper eventsDBStale = new ReadOnlyBooleanWrapper(true);
private final PromptDialogManager promptDialogManager = new PromptDialogManager(this);
synchronized public ReadOnlyObjectProperty<ViewMode> viewModeProperty() {
return viewMode.getReadOnlyProperty();
}
/**
* Set a new ViewMode as the active one.
*
* @param viewMode The new ViewMode to set.
*/
synchronized public void setViewMode(ViewMode viewMode) {
if (this.viewMode.get() != viewMode) {
this.viewMode.set(viewMode);
}
}
/**
* Get the currently active ViewMode.
*
* @return The currently active ViewMode.
*/
synchronized public ViewMode getViewMode() {
return viewMode.get();
}
public TimeLineController(Case autoCase) throws IOException {
this.autoCase = autoCase;
@ -310,6 +345,9 @@ public class TimeLineController {
filteredEvents.filterProperty().get(),
DescriptionLoD.SHORT);
historyManager.advance(InitialZoomState);
//clear the selected events when the view mode changes
viewMode.addListener(observable -> selectEventIDs(Collections.emptySet()));
}
/**
@ -449,9 +487,9 @@ public class TimeLineController {
IngestManager.getInstance().removeIngestModuleEventListener(ingestModuleListener);
IngestManager.getInstance().removeIngestJobEventListener(ingestJobListener);
Case.removePropertyChangeListener(caseListener);
if (mainFrame != null) {
mainFrame.close();
mainFrame = null;
if (topComponent != null) {
topComponent.close();
topComponent = null;
}
OpenTimelineAction.invalidateController();
}
@ -582,17 +620,6 @@ public class TimeLineController {
pushTimeRange(new Interval(start, end));
}
/**
* Set a new Visualization mode as the active one.
*
* @param visualizationMode The new VisaualizationMode to set.
*/
synchronized public void setVisualizationMode(VisualizationMode visualizationMode) {
if (this.visualizationMode.get() != visualizationMode) {
this.visualizationMode.set(visualizationMode);
}
}
public void selectEventIDs(Collection<Long> events) {
final LoggedTask<Interval> selectEventIDsTask = new LoggedTask<Interval>("Select Event IDs", true) { //NON-NLS
@Override
@ -624,16 +651,16 @@ public class TimeLineController {
*/
@ThreadConfined(type = ThreadConfined.ThreadType.AWT)
synchronized private void showWindow() {
if (mainFrame == null) {
mainFrame = new TimeLineTopComponent(this);
if (topComponent == null) {
topComponent = new TimeLineTopComponent(this);
}
mainFrame.open();
mainFrame.toFront();
topComponent.open();
topComponent.toFront();
/*
* Make this top component active so its ExplorerManager's lookup gets
* proxied in Utilities.actionsGlobalContext()
*/
mainFrame.requestActive();
topComponent.requestActive();
}
synchronized public void pushEventTypeZoom(EventTypeZoomLevel typeZoomeLevel) {

Some files were not shown because too many files have changed in this diff Show More