mirror of
https://github.com/overcuriousity/autopsy-flatpak.git
synced 2025-07-15 09:17:42 +00:00
Merged upstream/develop.
This commit is contained in:
commit
4294885a63
@ -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/>
|
||||
|
@ -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) {
|
||||
|
@ -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) {
|
||||
|
51
Core/src/org/sleuthkit/autopsy/actions/ExitAction.java
Executable file
51
Core/src/org/sleuthkit/autopsy/actions/ExitAction.java
Executable 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();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -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 {
|
||||
|
||||
|
@ -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=
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
63
Core/src/org/sleuthkit/autopsy/casemodule/CaseInformationPanel.form
Executable file
63
Core/src/org/sleuthkit/autopsy/casemodule/CaseInformationPanel.form
Executable 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>
|
90
Core/src/org/sleuthkit/autopsy/casemodule/CaseInformationPanel.java
Executable file
90
Core/src/org/sleuthkit/autopsy/casemodule/CaseInformationPanel.java
Executable 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
|
||||
}
|
@ -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();
|
||||
|
@ -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, "{key}")"/>
|
||||
</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, "{key}")"/>
|
||||
</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, "{key}")"/>
|
||||
</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, "{key}")"/>
|
||||
</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, "{key}")"/>
|
||||
</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, "{key}")"/>
|
||||
</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, "{key}")"/>
|
||||
</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, "{key}")"/>
|
||||
</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, "{key}")"/>
|
||||
</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, "{key}")"/>
|
||||
</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, "{key}")"/>
|
||||
</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, "{key}")"/>
|
||||
</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, "{key}")"/>
|
||||
</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, "{key}")"/>
|
||||
</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, "{key}")"/>
|
||||
</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, "{key}")"/>
|
||||
</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, "{key}")"/>
|
||||
</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, "{key}")"/>
|
||||
</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, "{key}")"/>
|
||||
</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, "{key}")"/>
|
||||
</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, "{key}")"/>
|
||||
</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, "{key}")"/>
|
||||
</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, "{key}")"/>
|
||||
</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, "{key}")"/>
|
||||
</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, "{key}")"/>
|
||||
</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, "{key}")"/>
|
||||
</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, "{key}")"/>
|
||||
</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, "{key}")"/>
|
||||
</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, "{key}")"/>
|
||||
</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, "{key}")"/>
|
||||
</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, "{key}")"/>
|
||||
</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, "{key}")"/>
|
||||
</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, "{key}")"/>
|
||||
</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, "{key}")"/>
|
||||
</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, "{key}")"/>
|
||||
</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, "{key}")"/>
|
||||
</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, "{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
</Component>
|
||||
</SubComponents>
|
||||
</Form>
|
||||
|
@ -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
|
||||
|
||||
|
@ -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.
|
||||
*/
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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) {
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -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>
|
||||
|
||||
|
@ -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, "{key}")"/>
|
||||
</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>
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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));
|
||||
}
|
||||
}
|
||||
|
@ -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());
|
||||
|
@ -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]);
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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]);
|
||||
|
@ -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));
|
||||
|
@ -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());
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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(
|
||||
|
@ -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(
|
||||
|
@ -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;
|
||||
|
@ -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));
|
||||
|
@ -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);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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)) {
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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.
|
||||
*/
|
||||
|
@ -236,6 +236,9 @@
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/filesearch/Bundle.properties" key="DateSearchPanel.modifiedCheckBox.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<Events>
|
||||
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="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, "{key}")"/>
|
||||
</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, "{key}")"/>
|
||||
</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, "{key}")"/>
|
||||
</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>
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
*/
|
||||
|
@ -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;
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
@ -64,6 +64,9 @@
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/filesearch/Bundle.properties" key="KnownStatusSearchPanel.unknownOptionCheckBox.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<Events>
|
||||
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="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, "{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<Events>
|
||||
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="knownBadOptionCheckBoxActionPerformed"/>
|
||||
</Events>
|
||||
</Component>
|
||||
</SubComponents>
|
||||
</Form>
|
||||
|
@ -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;
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
@ -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"/>
|
||||
|
@ -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
|
||||
|
||||
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
42
Core/src/org/sleuthkit/autopsy/ingest/FactoryClassNameNormalizer.java
Executable file
42
Core/src/org/sleuthkit/autopsy/ingest/FactoryClassNameNormalizer.java
Executable 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);
|
||||
}
|
||||
|
||||
}
|
@ -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);
|
||||
|
@ -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;
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -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) {
|
||||
|
@ -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());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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) {
|
||||
|
@ -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());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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) {
|
||||
|
@ -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) {
|
||||
|
@ -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) {
|
||||
|
@ -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) {
|
||||
|
@ -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));
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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)));
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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<Signature>() {
 Signature[] signatures = {};
 public int getSize() { return signatures.length; }
 public Signature getElementAt(int i) { return signatures[i]; }
}" 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>
|
||||
|
@ -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
|
||||
|
||||
|
@ -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 {
|
||||
|
@ -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 {
|
||||
|
@ -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) {
|
||||
|
@ -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) {
|
||||
|
@ -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());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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)));
|
||||
|
@ -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.
|
||||
*
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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}
|
||||
|
@ -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
|
@ -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];
|
||||
|
@ -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());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
@ -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
1016
Core/src/org/sleuthkit/autopsy/report/ReportKML.java
Normal file → Executable file
File diff suppressed because it is too large
Load Diff
@ -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;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
}
|
||||
|
||||
/**
|
||||
|
1686
Core/src/org/sleuthkit/autopsy/report/TableReportGenerator.java
Executable file
1686
Core/src/org/sleuthkit/autopsy/report/TableReportGenerator.java
Executable file
File diff suppressed because it is too large
Load Diff
299
Core/src/org/sleuthkit/autopsy/report/stylesheets/style.kml
Executable file
299
Core/src/org/sleuthkit/autopsy/report/stylesheets/style.kml
Executable 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>
|
@ -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=\
|
||||
|
@ -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}
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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
Loading…
x
Reference in New Issue
Block a user