mirror of
https://github.com/overcuriousity/autopsy-flatpak.git
synced 2025-07-13 16:36:15 +00:00
Merge remote-tracking branch 'upstream/develop' into 2210-cleanup
# Conflicts: # Core/src/org/sleuthkit/autopsy/corecomponents/DataResultViewerTable.java
This commit is contained in:
commit
6f3f993073
@ -15,7 +15,7 @@
|
|||||||
|
|
||||||
<dependency conf="core->default" org="com.drewnoakes" name="metadata-extractor" rev="2.8.1"/>
|
<dependency conf="core->default" org="com.drewnoakes" name="metadata-extractor" rev="2.8.1"/>
|
||||||
|
|
||||||
<dependency conf="core->default" org="org.apache.tika" name="tika-core" rev="1.5"/>
|
<dependency conf="core->default" org="org.apache.tika" name="tika-core" rev="1.14"/>
|
||||||
<dependency conf="core->default" org="com.adobe.xmp" name="xmpcore" rev="5.1.2"/>
|
<dependency conf="core->default" org="com.adobe.xmp" name="xmpcore" rev="5.1.2"/>
|
||||||
<dependency conf="core->default" org="org.apache.zookeeper" name="zookeeper" rev="3.4.6"/>
|
<dependency conf="core->default" org="org.apache.zookeeper" name="zookeeper" rev="3.4.6"/>
|
||||||
|
|
||||||
|
@ -12,7 +12,7 @@ file.reference.sevenzipjbinding-AllPlatforms.jar=release/modules/ext/sevenzipjbi
|
|||||||
file.reference.sevenzipjbinding.jar=release/modules/ext/sevenzipjbinding.jar
|
file.reference.sevenzipjbinding.jar=release/modules/ext/sevenzipjbinding.jar
|
||||||
file.reference.sqlite-jdbc-3.8.11.jar=release/modules/ext/sqlite-jdbc-3.8.11.jar
|
file.reference.sqlite-jdbc-3.8.11.jar=release/modules/ext/sqlite-jdbc-3.8.11.jar
|
||||||
file.reference.StixLib.jar=release/modules/ext/StixLib.jar
|
file.reference.StixLib.jar=release/modules/ext/StixLib.jar
|
||||||
file.reference.tika-core-1.5.jar=release/modules/ext/tika-core-1.5.jar
|
file.reference.tika-core-1.14.jar=release/modules/ext/tika-core-1.14.jar
|
||||||
file.reference.Tsk_DataModel_PostgreSQL.jar=release/modules/ext/Tsk_DataModel_PostgreSQL.jar
|
file.reference.Tsk_DataModel_PostgreSQL.jar=release/modules/ext/Tsk_DataModel_PostgreSQL.jar
|
||||||
file.reference.xmpcore-5.1.2.jar=release/modules/ext/xmpcore-5.1.2.jar
|
file.reference.xmpcore-5.1.2.jar=release/modules/ext/xmpcore-5.1.2.jar
|
||||||
file.reference.curator-client-2.8.0.jar=release/modules/ext/curator-client-2.8.0.jar
|
file.reference.curator-client-2.8.0.jar=release/modules/ext/curator-client-2.8.0.jar
|
||||||
|
@ -243,6 +243,7 @@
|
|||||||
<package>net.sf.sevenzipjbinding.simple</package>
|
<package>net.sf.sevenzipjbinding.simple</package>
|
||||||
<package>net.sf.sevenzipjbinding.simple.impl</package>
|
<package>net.sf.sevenzipjbinding.simple.impl</package>
|
||||||
<package>org.sleuthkit.autopsy.actions</package>
|
<package>org.sleuthkit.autopsy.actions</package>
|
||||||
|
<package>org.sleuthkit.autopsy.appservices</package>
|
||||||
<package>org.sleuthkit.autopsy.casemodule</package>
|
<package>org.sleuthkit.autopsy.casemodule</package>
|
||||||
<package>org.sleuthkit.autopsy.casemodule.events</package>
|
<package>org.sleuthkit.autopsy.casemodule.events</package>
|
||||||
<package>org.sleuthkit.autopsy.casemodule.services</package>
|
<package>org.sleuthkit.autopsy.casemodule.services</package>
|
||||||
@ -254,17 +255,18 @@
|
|||||||
<package>org.sleuthkit.autopsy.corecomponents</package>
|
<package>org.sleuthkit.autopsy.corecomponents</package>
|
||||||
<package>org.sleuthkit.autopsy.coreutils</package>
|
<package>org.sleuthkit.autopsy.coreutils</package>
|
||||||
<package>org.sleuthkit.autopsy.datamodel</package>
|
<package>org.sleuthkit.autopsy.datamodel</package>
|
||||||
|
<package>org.sleuthkit.autopsy.datasourceprocessors</package>
|
||||||
<package>org.sleuthkit.autopsy.directorytree</package>
|
<package>org.sleuthkit.autopsy.directorytree</package>
|
||||||
<package>org.sleuthkit.autopsy.events</package>
|
<package>org.sleuthkit.autopsy.events</package>
|
||||||
<package>org.sleuthkit.autopsy.externalresults</package>
|
<package>org.sleuthkit.autopsy.externalresults</package>
|
||||||
<package>org.sleuthkit.autopsy.filesearch</package>
|
<package>org.sleuthkit.autopsy.filesearch</package>
|
||||||
<package>org.sleuthkit.autopsy.framework</package>
|
|
||||||
<package>org.sleuthkit.autopsy.ingest</package>
|
<package>org.sleuthkit.autopsy.ingest</package>
|
||||||
<package>org.sleuthkit.autopsy.keywordsearchservice</package>
|
<package>org.sleuthkit.autopsy.keywordsearchservice</package>
|
||||||
<package>org.sleuthkit.autopsy.menuactions</package>
|
<package>org.sleuthkit.autopsy.menuactions</package>
|
||||||
<package>org.sleuthkit.autopsy.modules.filetypeid</package>
|
<package>org.sleuthkit.autopsy.modules.filetypeid</package>
|
||||||
<package>org.sleuthkit.autopsy.modules.hashdatabase</package>
|
<package>org.sleuthkit.autopsy.modules.hashdatabase</package>
|
||||||
<package>org.sleuthkit.autopsy.modules.vmextractor</package>
|
<package>org.sleuthkit.autopsy.modules.vmextractor</package>
|
||||||
|
<package>org.sleuthkit.autopsy.progress</package>
|
||||||
<package>org.sleuthkit.autopsy.report</package>
|
<package>org.sleuthkit.autopsy.report</package>
|
||||||
<package>org.sleuthkit.datamodel</package>
|
<package>org.sleuthkit.datamodel</package>
|
||||||
</public-packages>
|
</public-packages>
|
||||||
@ -325,8 +327,8 @@
|
|||||||
<binary-origin>release/modules/ext/sevenzipjbinding-AllPlatforms.jar</binary-origin>
|
<binary-origin>release/modules/ext/sevenzipjbinding-AllPlatforms.jar</binary-origin>
|
||||||
</class-path-extension>
|
</class-path-extension>
|
||||||
<class-path-extension>
|
<class-path-extension>
|
||||||
<runtime-relative-path>ext/tika-core-1.5.jar</runtime-relative-path>
|
<runtime-relative-path>ext/tika-core-1.14.jar</runtime-relative-path>
|
||||||
<binary-origin>release/modules/ext/tika-core-1.5.jar</binary-origin>
|
<binary-origin>release/modules/ext/tika-core-1.14.jar</binary-origin>
|
||||||
</class-path-extension>
|
</class-path-extension>
|
||||||
<class-path-extension>
|
<class-path-extension>
|
||||||
<runtime-relative-path>ext/metadata-extractor-2.8.1.jar</runtime-relative-path>
|
<runtime-relative-path>ext/metadata-extractor-2.8.1.jar</runtime-relative-path>
|
||||||
|
@ -174,10 +174,6 @@ public class DeleteFileBlackboardArtifactTagAction extends AbstractAction implem
|
|||||||
for(BlackboardArtifactTag artifactTag : existingTagsList) {
|
for(BlackboardArtifactTag artifactTag : existingTagsList) {
|
||||||
if(tagDisplayName.equals(artifactTag.getName().getDisplayName())) {
|
if(tagDisplayName.equals(artifactTag.getName().getDisplayName())) {
|
||||||
JMenuItem tagNameItem = new JMenuItem(tagDisplayName);
|
JMenuItem tagNameItem = new JMenuItem(tagDisplayName);
|
||||||
// for the bookmark tag name only, added shortcut label
|
|
||||||
if (tagDisplayName.equals(NbBundle.getMessage(AddTagAction.class, "AddBookmarkTagAction.bookmark.text"))) {
|
|
||||||
tagNameItem.setAccelerator(AddBookmarkTagAction.BOOKMARK_SHORTCUT);
|
|
||||||
}
|
|
||||||
tagNameItem.addActionListener((ActionEvent e) -> {
|
tagNameItem.addActionListener((ActionEvent e) -> {
|
||||||
deleteTag(tagName, artifactTag, artifact.getArtifactID());
|
deleteTag(tagName, artifactTag, artifact.getArtifactID());
|
||||||
});
|
});
|
||||||
|
@ -159,8 +159,6 @@ public class DeleteFileContentTagAction extends AbstractAction implements Presen
|
|||||||
// a tag with the associated tag name.
|
// a tag with the associated tag name.
|
||||||
if (null != tagNamesMap && !tagNamesMap.isEmpty()) {
|
if (null != tagNamesMap && !tagNamesMap.isEmpty()) {
|
||||||
try {
|
try {
|
||||||
/*List<BlackboardArtifactTag> existingTagsList =
|
|
||||||
Case.getCurrentCase().getServices().getTagsManager().getBlackboardArtifactTagsByArtifact(artifact);*/
|
|
||||||
List<ContentTag> existingTagsList =
|
List<ContentTag> existingTagsList =
|
||||||
Case.getCurrentCase().getServices().getTagsManager()
|
Case.getCurrentCase().getServices().getTagsManager()
|
||||||
.getContentTagsByContent(file);
|
.getContentTagsByContent(file);
|
||||||
@ -172,10 +170,6 @@ public class DeleteFileContentTagAction extends AbstractAction implements Presen
|
|||||||
for(ContentTag contentTag : existingTagsList) {
|
for(ContentTag contentTag : existingTagsList) {
|
||||||
if(tagDisplayName.equals(contentTag.getName().getDisplayName())) {
|
if(tagDisplayName.equals(contentTag.getName().getDisplayName())) {
|
||||||
JMenuItem tagNameItem = new JMenuItem(tagDisplayName);
|
JMenuItem tagNameItem = new JMenuItem(tagDisplayName);
|
||||||
// for the bookmark tag name only, added shortcut label
|
|
||||||
if (tagDisplayName.equals(NbBundle.getMessage(AddTagAction.class, "AddBookmarkTagAction.bookmark.text"))) {
|
|
||||||
tagNameItem.setAccelerator(AddBookmarkTagAction.BOOKMARK_SHORTCUT);
|
|
||||||
}
|
|
||||||
tagNameItem.addActionListener((ActionEvent e) -> {
|
tagNameItem.addActionListener((ActionEvent e) -> {
|
||||||
deleteTag(tagName, contentTag, file.getId());
|
deleteTag(tagName, contentTag, file.getId());
|
||||||
});
|
});
|
||||||
|
@ -16,9 +16,10 @@
|
|||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
package org.sleuthkit.autopsy.framework;
|
package org.sleuthkit.autopsy.appservices;
|
||||||
|
|
||||||
import org.sleuthkit.autopsy.casemodule.Case;
|
import org.sleuthkit.autopsy.casemodule.Case;
|
||||||
|
import org.sleuthkit.autopsy.progress.ProgressIndicator;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An interface for services that report status and may manage case and
|
* An interface for services that report status and may manage case and
|
@ -96,10 +96,10 @@ Case.databaseConnectionInfo.error.msg=Error accessing database server connection
|
|||||||
Case.open.msgDlg.updated.msg=Updated case database schema.\nA backup copy of the database with the following path has been made\:\n {0}
|
Case.open.msgDlg.updated.msg=Updated case database schema.\nA backup copy of the database with the following path has been made\:\n {0}
|
||||||
Case.open.msgDlg.updated.title=Case Database Schema Update
|
Case.open.msgDlg.updated.title=Case Database Schema Update
|
||||||
Case.open.exception.multiUserCaseNotEnabled=Cannot open a multi-user case if multi-user cases are not enabled. See Tools, Options, Multi-user.
|
Case.open.exception.multiUserCaseNotEnabled=Cannot open a multi-user case if multi-user cases are not enabled. See Tools, Options, Multi-user.
|
||||||
Case.checkImgExist.confDlg.doesntExist.msg={0} has detected that one of the images associated with \n\
|
Case.checkImgExist.confDlg.doesntExist.msg=One of the images associated with \n\
|
||||||
this case are missing. Would you like to search for them now?\n\
|
this case are missing. Would you like to search for them now?\n\
|
||||||
Previously, the image was located at\:\n\
|
Previously, the image was located at\:\n\
|
||||||
{1}\n\
|
{0}\n\
|
||||||
Please note that you will still be able to browse directories and generate reports\n\
|
Please note that you will still be able to browse directories and generate reports\n\
|
||||||
if you choose No, but you will not be able to view file content or run the ingest process.
|
if you choose No, but you will not be able to view file content or run the ingest process.
|
||||||
Case.checkImgExist.confDlg.doesntExist.title=Missing Image
|
Case.checkImgExist.confDlg.doesntExist.title=Missing Image
|
||||||
@ -136,12 +136,6 @@ IntervalErrorReport.NewIssues=new issue(s)
|
|||||||
IntervalErrorReport.TotalIssues=total issue(s)
|
IntervalErrorReport.TotalIssues=total issue(s)
|
||||||
IntervalErrorReport.ErrorText=Database Connection Error
|
IntervalErrorReport.ErrorText=Database Connection Error
|
||||||
CasePropertiesAction.window.title=Case Properties
|
CasePropertiesAction.window.title=Case Properties
|
||||||
CasePropertiesForm.updateCaseName.msgDlg.empty.msg=The caseName cannot be empty.
|
|
||||||
CasePropertiesForm.updateCaseName.msgDlg.empty.title=Error
|
|
||||||
CasePropertiesForm.updateCaseName.msgDlg.invalidSymbols.msg=The Case Name cannot contain any of this following symbol\: \\ / \: * ? " < > |
|
|
||||||
CasePropertiesForm.updateCaseName.msgDlg.invalidSymbols.title=Error
|
|
||||||
CasePropertiesForm.updateCaseName.confMsg.msg=Are you sure you want to update the case name from "{0}" to "{1}"?
|
|
||||||
CasePropertiesForm.updateCaseName.confMsg.title=Change Case Name
|
|
||||||
CueBannerPanel.title.text=Open Recent Case
|
CueBannerPanel.title.text=Open Recent Case
|
||||||
GeneralFilter.rawImageDesc.text=Raw Images (*.img, *.dd, *.001, *.aa, *.raw, *.bin)
|
GeneralFilter.rawImageDesc.text=Raw Images (*.img, *.dd, *.001, *.aa, *.raw, *.bin)
|
||||||
GeneralFilter.encaseImageDesc.text=Encase Images (*.e01)
|
GeneralFilter.encaseImageDesc.text=Encase Images (*.e01)
|
||||||
|
@ -73,10 +73,6 @@ Case.getCurCase.exception.noneOpen=\u4f5c\u696d\u4e2d\u306e\u30b1\u30fc\u30b9\u3
|
|||||||
Case.open.msgDlg.updated.msg=\u30b1\u30fc\u30b9\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u306e\u30b9\u30ad\u30fc\u30de\u3092\u66f4\u65b0\u3057\u307e\u3057\u305f\u3002\n\u6b21\u306e\u30d1\u30b9\u3092\u6301\u3064\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u306e\u30d0\u30c3\u30af\u30a2\u30c3\u30d7\u30b3\u30d4\u30fc\u304c\u4f5c\u6210\u3055\u308c\u307e\u3057\u305f\uff1a\n\
|
Case.open.msgDlg.updated.msg=\u30b1\u30fc\u30b9\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u306e\u30b9\u30ad\u30fc\u30de\u3092\u66f4\u65b0\u3057\u307e\u3057\u305f\u3002\n\u6b21\u306e\u30d1\u30b9\u3092\u6301\u3064\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u306e\u30d0\u30c3\u30af\u30a2\u30c3\u30d7\u30b3\u30d4\u30fc\u304c\u4f5c\u6210\u3055\u308c\u307e\u3057\u305f\uff1a\n\
|
||||||
{0}
|
{0}
|
||||||
Case.open.msgDlg.updated.title=\u30b1\u30fc\u30b9\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u306e\u30b9\u30ad\u30fc\u30de\u3092\u66f4\u65b0
|
Case.open.msgDlg.updated.title=\u30b1\u30fc\u30b9\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u306e\u30b9\u30ad\u30fc\u30de\u3092\u66f4\u65b0
|
||||||
Case.checkImgExist.confDlg.doesntExist.msg={0} \u304c\u3053\u306e\u30b1\u30fc\u30b9\u306b\u95a2\u9023\u3059\u308b\u30a4\u30e1\u30fc\u30b8\u306e\u3046\u3061\uff11\u3064\u304c\u6b20\u843d\u3057\u3066\u3044\u308b\u306e\u3092\u691c\u51fa\u3057\u307e\u3057\u305f\u3002\u305d\u308c\u3092\u4eca\u304b\u3089\u691c\u7d22\u3057\u307e\u3059\u304b\uff1f\n\n\
|
|
||||||
\u4ee5\u524d\u3001\u30a4\u30e1\u30fc\u30b8\u306f\u6b21\u306b\u3042\u308a\u307e\u3057\u305f\uff1a\n\
|
|
||||||
{1}\n\
|
|
||||||
\u3044\u3044\u3048\u3092\u9078\u629e\u3057\u3066\u3082\u3001\u4eca\u5f8c\u3082\u30c7\u30a3\u30ec\u30af\u30c8\u30ea\u3092\u95b2\u89a7\u3057\u3001\u30ec\u30dd\u30fc\u30c8\u751f\u6210\u304c\u3067\u304d\u307e\u3059\u304c\u3001\n\u30d5\u30a1\u30a4\u30eb\u30b3\u30f3\u30c6\u30f3\u30c4\u306e\u8868\u793a\u307e\u305f\u306f\u30a4\u30f3\u30b8\u30a7\u30b9\u30c8\u30d7\u30ed\u30bb\u30b9\u306e\u5b9f\u884c\u304c\u3067\u304d\u306a\u304f\u306a\u308a\u307e\u3059\u3002
|
|
||||||
Case.checkImgExist.confDlg.doesntExist.title=\u6b20\u843d\u3057\u3066\u3044\u308b\u30a4\u30e1\u30fc\u30b8
|
Case.checkImgExist.confDlg.doesntExist.title=\u6b20\u843d\u3057\u3066\u3044\u308b\u30a4\u30e1\u30fc\u30b8
|
||||||
Case.addImg.exception.msg=\u30b1\u30fc\u30b9\u306b\u30a4\u30e1\u30fc\u30b8\u3092\u8ffd\u52a0\u4e2d\u306b\u30a8\u30e9\u30fc\u304c\u767a\u751f\u3057\u307e\u3057\u305f
|
Case.addImg.exception.msg=\u30b1\u30fc\u30b9\u306b\u30a4\u30e1\u30fc\u30b8\u3092\u8ffd\u52a0\u4e2d\u306b\u30a8\u30e9\u30fc\u304c\u767a\u751f\u3057\u307e\u3057\u305f
|
||||||
Case.updateCaseName.exception.msg=\u30b1\u30fc\u30b9\u540d\u3092\u30a2\u30c3\u30d7\u30c7\u30fc\u30c8\u4e2d\u306b\u30a8\u30e9\u30fc\u304c\u767a\u751f\u3057\u307e\u3057\u305f\u3002
|
Case.updateCaseName.exception.msg=\u30b1\u30fc\u30b9\u540d\u3092\u30a2\u30c3\u30d7\u30c7\u30fc\u30c8\u4e2d\u306b\u30a8\u30e9\u30fc\u304c\u767a\u751f\u3057\u307e\u3057\u305f\u3002
|
||||||
@ -99,10 +95,6 @@ CaseDeleteAction.msgDlg.caseDelete.msg=\u30b1\u30fc\u30b9\u304c\u524a\u9664\u305
|
|||||||
CaseOpenAction.autFilter.title={0} \u30b1\u30fc\u30b9\u30d5\u30a1\u30a4\u30eb ( {1})
|
CaseOpenAction.autFilter.title={0} \u30b1\u30fc\u30b9\u30d5\u30a1\u30a4\u30eb ( {1})
|
||||||
CaseOpenAction.msgDlg.cantOpenCase.title=\u30b1\u30fc\u30b9\u3092\u958b\u304f\u969b\u306b\u30a8\u30e9\u30fc\u304c\u767a\u751f\u3057\u307e\u3057\u305f
|
CaseOpenAction.msgDlg.cantOpenCase.title=\u30b1\u30fc\u30b9\u3092\u958b\u304f\u969b\u306b\u30a8\u30e9\u30fc\u304c\u767a\u751f\u3057\u307e\u3057\u305f
|
||||||
CasePropertiesAction.window.title=\u30b1\u30fc\u30b9\u30d7\u30ed\u30d1\u30c6\u30a3
|
CasePropertiesAction.window.title=\u30b1\u30fc\u30b9\u30d7\u30ed\u30d1\u30c6\u30a3
|
||||||
CasePropertiesForm.updateCaseName.msgDlg.empty.msg=\u30b1\u30fc\u30b9\u540d\u306f\u7a7a\u767d\u3067\u306f\u3044\u3051\u307e\u305b\u3093\u3002
|
|
||||||
CasePropertiesForm.updateCaseName.msgDlg.empty.title=\u30a8\u30e9\u30fc
|
|
||||||
CasePropertiesForm.updateCaseName.msgDlg.invalidSymbols.msg=\u30b1\u30fc\u30b9\u540d\u306b\u306f\u6b21\u306e\u8a18\u53f7\u3092\u542b\u3081\u307e\u305b\u3093\uff1a\\ / \: * ? " < > |
|
|
||||||
CasePropertiesForm.updateCaseName.msgDlg.invalidSymbols.title=\u30a8\u30e9\u30fc
|
|
||||||
CueBannerPanel.title.text=\u6700\u8fd1\u958b\u3044\u305f\u30b1\u30fc\u30b9\u3092\u958b\u304f
|
CueBannerPanel.title.text=\u6700\u8fd1\u958b\u3044\u305f\u30b1\u30fc\u30b9\u3092\u958b\u304f
|
||||||
GeneralFilter.rawImageDesc.text=\u30ed\u30fc\u30a4\u30e1\u30fc\u30b8(*.img, *.dd, *.001, *.aa, *.raw, *.bin)
|
GeneralFilter.rawImageDesc.text=\u30ed\u30fc\u30a4\u30e1\u30fc\u30b8(*.img, *.dd, *.001, *.aa, *.raw, *.bin)
|
||||||
GeneralFilter.encaseImageDesc.text=\u30a8\u30f3\u30b1\u30fc\u30b9\u30a4\u30e1\u30fc\u30b8(*.e01)
|
GeneralFilter.encaseImageDesc.text=\u30a8\u30f3\u30b1\u30fc\u30b9\u30a4\u30e1\u30fc\u30b8(*.e01)
|
||||||
|
File diff suppressed because it is too large
Load Diff
49
Core/src/org/sleuthkit/autopsy/casemodule/CaseActionCancelledException.java
Executable file
49
Core/src/org/sleuthkit/autopsy/casemodule/CaseActionCancelledException.java
Executable file
@ -0,0 +1,49 @@
|
|||||||
|
/*
|
||||||
|
* Autopsy Forensic Browser
|
||||||
|
*
|
||||||
|
* Copyright 2011-2017 Basis Technology Corp.
|
||||||
|
* Contact: carrier <at> sleuthkit <dot> org
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package org.sleuthkit.autopsy.casemodule;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Exception thrown when a case action (e.g., create, open, close, delete) is
|
||||||
|
* cancelled before it is completed.
|
||||||
|
*/
|
||||||
|
public final class CaseActionCancelledException extends CaseActionException {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructs an exception thrown when a case action (e.g., create, open,
|
||||||
|
* close, delete) is cancelled before it is completed.
|
||||||
|
*
|
||||||
|
* @param message An error message.
|
||||||
|
*/
|
||||||
|
CaseActionCancelledException(String message) {
|
||||||
|
super(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructs an exception thrown when a case action (e.g., create, open,
|
||||||
|
* close, delete) is cancelled before it is completed.
|
||||||
|
*
|
||||||
|
* @param message An error message.
|
||||||
|
* @param cause An excception that caused this exception to be thrown.
|
||||||
|
*/
|
||||||
|
CaseActionCancelledException(String message, Throwable cause) {
|
||||||
|
super(message, cause);
|
||||||
|
}
|
||||||
|
}
|
@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* Autopsy Forensic Browser
|
* Autopsy Forensic Browser
|
||||||
*
|
*
|
||||||
* Copyright 2012 Basis Technology Corp.
|
* Copyright 2011-2017 Basis Technology Corp.
|
||||||
* Contact: carrier <at> sleuthkit <dot> org
|
* Contact: carrier <at> sleuthkit <dot> org
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
@ -19,15 +19,30 @@
|
|||||||
package org.sleuthkit.autopsy.casemodule;
|
package org.sleuthkit.autopsy.casemodule;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Exception thrown when case action (such as open, close, create) resulted in
|
* Exception thrown when a case action (e.g., create, open, close, delete)
|
||||||
* an error
|
* experiences an error condition.
|
||||||
*/
|
*/
|
||||||
public class CaseActionException extends Exception {
|
public class CaseActionException extends Exception {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructs an exception thrown when a case action (e.g., create, open,
|
||||||
|
* close, delete) experiences an error condition.
|
||||||
|
*
|
||||||
|
* @param message An error message.
|
||||||
|
*/
|
||||||
public CaseActionException(String message) {
|
public CaseActionException(String message) {
|
||||||
super(message);
|
super(message);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructs an exception thrown when a case action (e.g., create, open,
|
||||||
|
* close, delete) experiences an error condition.
|
||||||
|
*
|
||||||
|
* @param message An error message.
|
||||||
|
* @param cause An excception that caused this exception to be thrown.
|
||||||
|
*/
|
||||||
public CaseActionException(String message, Throwable cause) {
|
public CaseActionException(String message, Throwable cause) {
|
||||||
super(message, cause);
|
super(message, cause);
|
||||||
}
|
}
|
||||||
|
@ -90,7 +90,7 @@ final class CaseDeleteAction extends CallableSystemAction {
|
|||||||
logger.log(Level.SEVERE, String.format("Failed to delete case %s at %s", caseName, caseDirectory), ex);
|
logger.log(Level.SEVERE, String.format("Failed to delete case %s at %s", caseName, caseDirectory), ex);
|
||||||
JOptionPane.showMessageDialog(
|
JOptionPane.showMessageDialog(
|
||||||
null,
|
null,
|
||||||
Bundle.Case_deleteCaseFailureMessageBox_message(ex.getMessage()),
|
Bundle.Case_deleteCaseFailureMessageBox_message(ex.getLocalizedMessage()),
|
||||||
Bundle.Case_deleteCaseFailureMessageBox_title(),
|
Bundle.Case_deleteCaseFailureMessageBox_title(),
|
||||||
JOptionPane.ERROR_MESSAGE);
|
JOptionPane.ERROR_MESSAGE);
|
||||||
}
|
}
|
||||||
@ -99,6 +99,7 @@ final class CaseDeleteAction extends CallableSystemAction {
|
|||||||
* of the Delete button that invokes this action.
|
* of the Delete button that invokes this action.
|
||||||
*/
|
*/
|
||||||
CasePropertiesAction.closeCasePropertiesWindow();
|
CasePropertiesAction.closeCasePropertiesWindow();
|
||||||
|
StartupWindowProvider.getInstance().open();
|
||||||
}
|
}
|
||||||
}.execute();
|
}.execute();
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* Autopsy Forensic Browser
|
* Autopsy Forensic Browser
|
||||||
*
|
*
|
||||||
* Copyright 2011-2016 Basis Technology Corp.
|
* Copyright 2011-2017 Basis Technology Corp.
|
||||||
* Contact: carrier <at> sleuthkit <dot> org
|
* Contact: carrier <at> sleuthkit <dot> org
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
@ -19,10 +19,6 @@
|
|||||||
package org.sleuthkit.autopsy.casemodule;
|
package org.sleuthkit.autopsy.casemodule;
|
||||||
|
|
||||||
import java.awt.event.ActionListener;
|
import java.awt.event.ActionListener;
|
||||||
import java.util.Map;
|
|
||||||
import java.util.logging.Level;
|
|
||||||
import java.util.logging.Logger;
|
|
||||||
import javax.swing.JOptionPane;
|
|
||||||
import javax.swing.event.ChangeEvent;
|
import javax.swing.event.ChangeEvent;
|
||||||
import org.openide.util.NbBundle.Messages;
|
import org.openide.util.NbBundle.Messages;
|
||||||
|
|
||||||
@ -32,44 +28,40 @@ import org.openide.util.NbBundle.Messages;
|
|||||||
*/
|
*/
|
||||||
class CaseInformationPanel extends javax.swing.JPanel {
|
class CaseInformationPanel extends javax.swing.JPanel {
|
||||||
|
|
||||||
private static final Logger logger = Logger.getLogger(CaseInformationPanel.class.getName());
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates new form CaseInformationPanel
|
* Constructs a panel for displaying the case information, including both
|
||||||
|
* case details and ingest job history.
|
||||||
*/
|
*/
|
||||||
CaseInformationPanel() {
|
CaseInformationPanel() {
|
||||||
initComponents();
|
initComponents();
|
||||||
customizeComponents();
|
customizeComponents();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Messages({"CaseInformationPanel.caseDetails.header=Case Details",
|
@Messages({
|
||||||
"CaseInformationPanel.ingestJobInfo.header=Ingest History",
|
"CaseInformationPanel.caseDetails.header=Case Details",
|
||||||
"CaseInformationPanel.loadMetadataFail.message=Failed to load case metadata.",
|
"CaseInformationPanel.ingestJobInfo.header=Ingest History"
|
||||||
"CaseInformationPanel.loadMetadataFail.title=Metadata load failure",})
|
})
|
||||||
private void customizeComponents() {
|
private void customizeComponents() {
|
||||||
try {
|
CasePropertiesPanel propertiesPanel = new CasePropertiesPanel(Case.getCurrentCase());
|
||||||
Case currentCase = Case.getCurrentCase();
|
propertiesPanel.setSize(propertiesPanel.getPreferredSize());
|
||||||
String crDate = currentCase.getCreatedDate();
|
this.tabbedPane.addTab(Bundle.CaseInformationPanel_caseDetails_header(), propertiesPanel);
|
||||||
String caseDir = currentCase.getCaseDirectory();
|
|
||||||
|
|
||||||
// put the image paths information into hashmap
|
|
||||||
Map<Long, String> imgPaths = Case.getImagePaths(currentCase.getSleuthkitCase());
|
|
||||||
CasePropertiesPanel cpf = new CasePropertiesPanel(currentCase, crDate, caseDir, imgPaths);
|
|
||||||
cpf.setSize(cpf.getPreferredSize());
|
|
||||||
this.tabbedPane.addTab(Bundle.CaseInformationPanel_caseDetails_header(), cpf);
|
|
||||||
this.tabbedPane.addTab(Bundle.CaseInformationPanel_ingestJobInfo_header(), new IngestJobInfoPanel());
|
this.tabbedPane.addTab(Bundle.CaseInformationPanel_ingestJobInfo_header(), new IngestJobInfoPanel());
|
||||||
this.tabbedPane.addChangeListener((ChangeEvent e) -> {
|
this.tabbedPane.addChangeListener((ChangeEvent e) -> {
|
||||||
tabbedPane.getSelectedComponent().setSize(tabbedPane.getSelectedComponent().getPreferredSize());
|
tabbedPane.getSelectedComponent().setSize(tabbedPane.getSelectedComponent().getPreferredSize());
|
||||||
});
|
});
|
||||||
} catch (CaseMetadata.CaseMetadataException ex) {
|
|
||||||
logger.log(Level.SEVERE, "Failed to load case metadata.", ex);
|
|
||||||
JOptionPane.showMessageDialog(null, Bundle.IngestJobInfoPanel_loadIngestJob_error_text(), Bundle.IngestJobInfoPanel_loadIngestJob_error_title(), JOptionPane.ERROR_MESSAGE);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds an action listener to the Close button of the panel.
|
||||||
|
*
|
||||||
|
* @param action
|
||||||
|
*/
|
||||||
void addCloseButtonAction(ActionListener action) {
|
void addCloseButtonAction(ActionListener action) {
|
||||||
this.closeButton.addActionListener(action);
|
this.closeButton.addActionListener(action);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This method is called from within the constructor to initialize the form.
|
* This method is called from within the constructor to initialize the form.
|
||||||
* WARNING: Do NOT modify this code. The content of this method is always
|
* WARNING: Do NOT modify this code. The content of this method is always
|
||||||
@ -127,7 +119,7 @@ class CaseInformationPanel extends javax.swing.JPanel {
|
|||||||
}// </editor-fold>//GEN-END:initComponents
|
}// </editor-fold>//GEN-END:initComponents
|
||||||
|
|
||||||
private void closeButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_closeButtonActionPerformed
|
private void closeButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_closeButtonActionPerformed
|
||||||
// TODO add your handling code here:
|
// Used by CasePropertiesAction
|
||||||
}//GEN-LAST:event_closeButtonActionPerformed
|
}//GEN-LAST:event_closeButtonActionPerformed
|
||||||
|
|
||||||
|
|
||||||
|
@ -54,7 +54,9 @@ public final class CaseMetadata {
|
|||||||
private static final String FILE_EXTENSION = ".aut";
|
private static final String FILE_EXTENSION = ".aut";
|
||||||
private static final DateFormat DATE_FORMAT = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss (z)");
|
private static final DateFormat DATE_FORMAT = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss (z)");
|
||||||
|
|
||||||
//fields from schema version 1
|
/*
|
||||||
|
* Fields from schema version 1
|
||||||
|
*/
|
||||||
private static final String SCHEMA_VERSION_ONE = "1.0";
|
private static final String SCHEMA_VERSION_ONE = "1.0";
|
||||||
private final static String ROOT_ELEMENT_NAME = "AutopsyCase"; //NON-NLS
|
private final static String ROOT_ELEMENT_NAME = "AutopsyCase"; //NON-NLS
|
||||||
private final static String SCHEMA_VERSION_ELEMENT_NAME = "SchemaVersion"; //NON-NLS
|
private final static String SCHEMA_VERSION_ELEMENT_NAME = "SchemaVersion"; //NON-NLS
|
||||||
@ -68,22 +70,28 @@ public final class CaseMetadata {
|
|||||||
private final static String CASE_DATABASE_NAME_ELEMENT_NAME = "DatabaseName"; //NON-NLS
|
private final static String CASE_DATABASE_NAME_ELEMENT_NAME = "DatabaseName"; //NON-NLS
|
||||||
private final static String TEXT_INDEX_NAME_ELEMENT = "TextIndexName"; //NON-NLS
|
private final static String TEXT_INDEX_NAME_ELEMENT = "TextIndexName"; //NON-NLS
|
||||||
|
|
||||||
//fields from schema version 2
|
/*
|
||||||
|
* Fields from schema version 2
|
||||||
|
*/
|
||||||
private static final String SCHEMA_VERSION_TWO = "2.0";
|
private static final String SCHEMA_VERSION_TWO = "2.0";
|
||||||
private final static String AUTOPSY_CREATED_BY_ELEMENT_NAME = "CreatedByAutopsyVersion"; //NON-NLS
|
private final static String AUTOPSY_CREATED_BY_ELEMENT_NAME = "CreatedByAutopsyVersion"; //NON-NLS
|
||||||
private final static String CASE_DATABASE_ABSOLUTE_PATH_ELEMENT_NAME = "Database"; //NON-NLS
|
private final static String CASE_DB_ABSOLUTE_PATH_ELEMENT_NAME = "Database"; //NON-NLS
|
||||||
private final static String TEXT_INDEX_ELEMENT = "TextIndex"; //NON-NLS
|
private final static String TEXT_INDEX_ELEMENT = "TextIndex"; //NON-NLS
|
||||||
|
|
||||||
//fields from schema version 3
|
/*
|
||||||
|
* Fields from schema version 3
|
||||||
|
*/
|
||||||
private static final String SCHEMA_VERSION_THREE = "3.0";
|
private static final String SCHEMA_VERSION_THREE = "3.0";
|
||||||
private final static String CASE_DISPLAY_NAME_ELEMENT_NAME = "DisplayName"; //NON-NLS
|
private final static String CASE_DISPLAY_NAME_ELEMENT_NAME = "DisplayName"; //NON-NLS
|
||||||
private final static String CASE_DATABASE_NAME_RELATIVE_ELEMENT_NAME = "CaseDatabase"; //NON-NLS
|
private final static String CASE_DB_NAME_RELATIVE_ELEMENT_NAME = "CaseDatabase"; //NON-NLS
|
||||||
|
|
||||||
//unread fields, these are regenerated on save
|
/*
|
||||||
|
* Unread fields, regenerated on save.
|
||||||
|
*/
|
||||||
private final static String MODIFIED_DATE_ELEMENT_NAME = "ModifiedDate"; //NON-NLS
|
private final static String MODIFIED_DATE_ELEMENT_NAME = "ModifiedDate"; //NON-NLS
|
||||||
private final static String AUTOPSY_SAVED_BY_ELEMENT_NAME = "SavedByAutopsyVersion"; //NON-NLS
|
private final static String AUTOPSY_SAVED_BY_ELEMENT_NAME = "SavedByAutopsyVersion"; //NON-NLS
|
||||||
|
|
||||||
private static final String CURRENT_SCHEMA_VERSION = SCHEMA_VERSION_THREE;
|
private final static String CURRENT_SCHEMA_VERSION = SCHEMA_VERSION_THREE;
|
||||||
|
|
||||||
private final Path metadataFilePath;
|
private final Path metadataFilePath;
|
||||||
private Case.CaseType caseType;
|
private Case.CaseType caseType;
|
||||||
@ -92,8 +100,8 @@ public final class CaseMetadata {
|
|||||||
private String caseNumber;
|
private String caseNumber;
|
||||||
private String examiner;
|
private String examiner;
|
||||||
private String caseDatabaseName;
|
private String caseDatabaseName;
|
||||||
private String caseDatabasePath;
|
private String caseDatabasePath; // Legacy
|
||||||
private String textIndexName;
|
private String textIndexName; // Legacy
|
||||||
private String createdDate;
|
private String createdDate;
|
||||||
private String createdByVersion;
|
private String createdByVersion;
|
||||||
|
|
||||||
@ -107,8 +115,9 @@ public final class CaseMetadata {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructs an object that provides access to the case metadata stored in
|
* Constructs a CaseMetadata object for a new case. The metadata is not
|
||||||
* a new case metadata file that is created using the supplied metadata.
|
* persisted to the case metadata file until writeFile or a setX method is
|
||||||
|
* called.
|
||||||
*
|
*
|
||||||
* @param caseDirectory The case directory.
|
* @param caseDirectory The case directory.
|
||||||
* @param caseType The type of case.
|
* @param caseType The type of case.
|
||||||
@ -117,29 +126,24 @@ public final class CaseMetadata {
|
|||||||
* user.
|
* user.
|
||||||
* @param caseNumber The case number.
|
* @param caseNumber The case number.
|
||||||
* @param examiner The name of the case examiner.
|
* @param examiner The name of the case examiner.
|
||||||
* @param caseDatabase For a single-user case, the full path to the case
|
|
||||||
* database file. For a multi-user case, the case
|
|
||||||
* database name.
|
|
||||||
*
|
|
||||||
* @throws CaseMetadataException If the new case metadata file cannot be
|
|
||||||
* created.
|
|
||||||
*/
|
*/
|
||||||
CaseMetadata(String caseDirectory, Case.CaseType caseType, String caseName, String caseDisplayName, String caseNumber, String examiner, String caseDatabase) throws CaseMetadataException {
|
CaseMetadata(String caseDirectory, Case.CaseType caseType, String caseName, String caseDisplayName, String caseNumber, String examiner) {
|
||||||
metadataFilePath = Paths.get(caseDirectory, caseDisplayName + FILE_EXTENSION);
|
metadataFilePath = Paths.get(caseDirectory, caseDisplayName + FILE_EXTENSION);
|
||||||
this.caseType = caseType;
|
this.caseType = caseType;
|
||||||
this.caseName = caseName;
|
this.caseName = caseName;
|
||||||
this.caseDisplayName = caseDisplayName;
|
this.caseDisplayName = caseDisplayName;
|
||||||
this.caseNumber = caseNumber;
|
this.caseNumber = caseNumber;
|
||||||
this.examiner = examiner;
|
this.examiner = examiner;
|
||||||
this.caseDatabaseName = caseDatabase;
|
caseDatabaseName = "";
|
||||||
|
caseDatabasePath = "";
|
||||||
|
textIndexName = "";
|
||||||
createdByVersion = Version.getVersion();
|
createdByVersion = Version.getVersion();
|
||||||
createdDate = CaseMetadata.DATE_FORMAT.format(new Date());
|
createdDate = CaseMetadata.DATE_FORMAT.format(new Date());
|
||||||
writeToFile();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructs an object that provides access to the case metadata stored in
|
* Constructs a CaseMetadata object for an existing case. The metadata is
|
||||||
* an existing case metadata file.
|
* read from an existing case metadata file.
|
||||||
*
|
*
|
||||||
* @param metadataFilePath The full path to the case metadata file.
|
* @param metadataFilePath The full path to the case metadata file.
|
||||||
*
|
*
|
||||||
@ -179,7 +183,7 @@ public final class CaseMetadata {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the immutable case name, set at case creation.
|
* Gets the unique and immutable case name.
|
||||||
*
|
*
|
||||||
* @return The case display name.
|
* @return The case display name.
|
||||||
*/
|
*/
|
||||||
@ -193,22 +197,23 @@ public final class CaseMetadata {
|
|||||||
* @return The case display name.
|
* @return The case display name.
|
||||||
*/
|
*/
|
||||||
public String getCaseDisplayName() {
|
public String getCaseDisplayName() {
|
||||||
return this.caseDisplayName;
|
return caseDisplayName;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the case display name. This does not change the name of the case
|
* Sets the case display name.
|
||||||
* directory, the case database, or the text index name.
|
|
||||||
*
|
*
|
||||||
* @param caseName A case display name.
|
* @param caseDisplayName A case display name.
|
||||||
|
*
|
||||||
|
* @throws CaseMetadataException If the operation fails.
|
||||||
*/
|
*/
|
||||||
void setCaseDisplayName(String caseName) throws CaseMetadataException {
|
void setCaseDisplayName(String caseDisplayName) throws CaseMetadataException {
|
||||||
String oldCaseName = caseName;
|
String oldCaseDisplayName = this.caseDisplayName;
|
||||||
this.caseDisplayName = caseName;
|
this.caseDisplayName = caseDisplayName;
|
||||||
try {
|
try {
|
||||||
writeToFile();
|
writeToFile();
|
||||||
} catch (CaseMetadataException ex) {
|
} catch (CaseMetadataException ex) {
|
||||||
this.caseDisplayName = oldCaseName;
|
this.caseDisplayName = oldCaseDisplayName;
|
||||||
throw ex;
|
throw ex;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -234,32 +239,35 @@ public final class CaseMetadata {
|
|||||||
/**
|
/**
|
||||||
* Gets the name of the case database.
|
* Gets the name of the case database.
|
||||||
*
|
*
|
||||||
* @return The case database name.
|
* @return The case database name, may be empty.
|
||||||
*/
|
*/
|
||||||
public String getCaseDatabaseName() {
|
public String getCaseDatabaseName() {
|
||||||
return caseDatabaseName;
|
return caseDatabaseName;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the text index name.
|
* Sets the name of the case database.
|
||||||
*
|
*
|
||||||
* @param caseTextIndexName The text index name.
|
* @param caseDatabaseName The case database name.
|
||||||
|
*
|
||||||
|
* @throws CaseMetadataException If the operation fails.
|
||||||
*/
|
*/
|
||||||
void setTextIndexName(String caseTextIndexName) throws CaseMetadataException {
|
void setCaseDatabaseName(String caseDatabaseName) throws CaseMetadataException {
|
||||||
String oldIndexName = caseTextIndexName;
|
String oldCaseDatabaseName = this.caseDatabaseName;
|
||||||
this.textIndexName = caseTextIndexName;
|
this.caseDatabaseName = caseDatabaseName;
|
||||||
try {
|
try {
|
||||||
writeToFile();
|
writeToFile();
|
||||||
} catch (CaseMetadataException ex) {
|
} catch (CaseMetadataException ex) {
|
||||||
this.textIndexName = oldIndexName;
|
this.caseDatabaseName = oldCaseDatabaseName;
|
||||||
throw ex;
|
throw ex;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the text index name.
|
* Gets the text index name. This is a legacy field and will be empty for
|
||||||
|
* cases created with Autopsy 4.4.0 and above.
|
||||||
*
|
*
|
||||||
* @return The name of the text index for the case.
|
* @return The name of the text index for the case, may be empty.
|
||||||
*/
|
*/
|
||||||
public String getTextIndexName() {
|
public String getTextIndexName() {
|
||||||
return textIndexName;
|
return textIndexName;
|
||||||
@ -268,7 +276,7 @@ public final class CaseMetadata {
|
|||||||
/**
|
/**
|
||||||
* Gets the date the case was created.
|
* Gets the date the case was created.
|
||||||
*
|
*
|
||||||
* @return The date this case was created as a string
|
* @return The date this case was created, as a string.
|
||||||
*/
|
*/
|
||||||
String getCreatedDate() {
|
String getCreatedDate() {
|
||||||
return createdDate;
|
return createdDate;
|
||||||
@ -278,7 +286,9 @@ public final class CaseMetadata {
|
|||||||
* Sets the date the case was created. Used for preserving the case creation
|
* Sets the date the case was created. Used for preserving the case creation
|
||||||
* date during single-user to multi-user case conversion.
|
* date during single-user to multi-user case conversion.
|
||||||
*
|
*
|
||||||
* @param createdDate The date the case was created as a string.
|
* @param createdDate The date the case was created, as a string.
|
||||||
|
*
|
||||||
|
* @throws CaseMetadataException If the operation fails.
|
||||||
*/
|
*/
|
||||||
void setCreatedDate(String createdDate) throws CaseMetadataException {
|
void setCreatedDate(String createdDate) throws CaseMetadataException {
|
||||||
String oldCreatedDate = createdDate;
|
String oldCreatedDate = createdDate;
|
||||||
@ -304,13 +314,15 @@ public final class CaseMetadata {
|
|||||||
* Sets the Autopsy version that created the case. Used for preserving this
|
* Sets the Autopsy version that created the case. Used for preserving this
|
||||||
* metadata during single-user to multi-user case conversion.
|
* metadata during single-user to multi-user case conversion.
|
||||||
*
|
*
|
||||||
* @param buildVersion An build version identifier.
|
* @param buildVersion A build version identifier.
|
||||||
|
*
|
||||||
|
* @throws CaseMetadataException If the operation fails.
|
||||||
*/
|
*/
|
||||||
void setCreatedByVersion(String buildVersion) throws CaseMetadataException {
|
void setCreatedByVersion(String buildVersion) throws CaseMetadataException {
|
||||||
String oldCreatedByVersion = this.createdByVersion;
|
String oldCreatedByVersion = this.createdByVersion;
|
||||||
this.createdByVersion = buildVersion;
|
this.createdByVersion = buildVersion;
|
||||||
try {
|
try {
|
||||||
this.writeToFile();
|
writeToFile();
|
||||||
} catch (CaseMetadataException ex) {
|
} catch (CaseMetadataException ex) {
|
||||||
this.createdByVersion = oldCreatedByVersion;
|
this.createdByVersion = oldCreatedByVersion;
|
||||||
throw ex;
|
throw ex;
|
||||||
@ -381,8 +393,8 @@ public final class CaseMetadata {
|
|||||||
createChildElement(doc, caseElement, CASE_NUMBER_ELEMENT_NAME, caseNumber);
|
createChildElement(doc, caseElement, CASE_NUMBER_ELEMENT_NAME, caseNumber);
|
||||||
createChildElement(doc, caseElement, EXAMINER_ELEMENT_NAME, examiner);
|
createChildElement(doc, caseElement, EXAMINER_ELEMENT_NAME, examiner);
|
||||||
createChildElement(doc, caseElement, CASE_TYPE_ELEMENT_NAME, caseType.toString());
|
createChildElement(doc, caseElement, CASE_TYPE_ELEMENT_NAME, caseType.toString());
|
||||||
createChildElement(doc, caseElement, CASE_DATABASE_ABSOLUTE_PATH_ELEMENT_NAME, caseDatabasePath);
|
createChildElement(doc, caseElement, CASE_DB_ABSOLUTE_PATH_ELEMENT_NAME, caseDatabasePath);
|
||||||
createChildElement(doc, caseElement, CASE_DATABASE_NAME_RELATIVE_ELEMENT_NAME, caseDatabaseName);
|
createChildElement(doc, caseElement, CASE_DB_NAME_RELATIVE_ELEMENT_NAME, caseDatabaseName);
|
||||||
createChildElement(doc, caseElement, TEXT_INDEX_ELEMENT, textIndexName);
|
createChildElement(doc, caseElement, TEXT_INDEX_ELEMENT, textIndexName);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -451,15 +463,19 @@ public final class CaseMetadata {
|
|||||||
if (null == this.caseType) {
|
if (null == this.caseType) {
|
||||||
throw new CaseMetadataException("Case metadata file corrupted");
|
throw new CaseMetadataException("Case metadata file corrupted");
|
||||||
}
|
}
|
||||||
if (schemaVersion.equals(SCHEMA_VERSION_ONE)) {
|
switch (schemaVersion) {
|
||||||
|
case SCHEMA_VERSION_ONE:
|
||||||
this.caseDatabaseName = getElementTextContent(caseElement, CASE_DATABASE_NAME_ELEMENT_NAME, true);
|
this.caseDatabaseName = getElementTextContent(caseElement, CASE_DATABASE_NAME_ELEMENT_NAME, true);
|
||||||
this.textIndexName = getElementTextContent(caseElement, TEXT_INDEX_NAME_ELEMENT, true);
|
this.textIndexName = getElementTextContent(caseElement, TEXT_INDEX_NAME_ELEMENT, true);
|
||||||
} else if (schemaVersion.equals(SCHEMA_VERSION_TWO)) {
|
break;
|
||||||
this.caseDatabaseName = getElementTextContent(caseElement, CASE_DATABASE_ABSOLUTE_PATH_ELEMENT_NAME, true);
|
case SCHEMA_VERSION_TWO:
|
||||||
|
this.caseDatabaseName = getElementTextContent(caseElement, CASE_DB_ABSOLUTE_PATH_ELEMENT_NAME, true);
|
||||||
this.textIndexName = getElementTextContent(caseElement, TEXT_INDEX_ELEMENT, false);
|
this.textIndexName = getElementTextContent(caseElement, TEXT_INDEX_ELEMENT, false);
|
||||||
} else {
|
break;
|
||||||
this.caseDatabaseName = getElementTextContent(caseElement, CASE_DATABASE_NAME_RELATIVE_ELEMENT_NAME, true);
|
default:
|
||||||
|
this.caseDatabaseName = getElementTextContent(caseElement, CASE_DB_NAME_RELATIVE_ELEMENT_NAME, true);
|
||||||
this.textIndexName = getElementTextContent(caseElement, TEXT_INDEX_ELEMENT, false);
|
this.textIndexName = getElementTextContent(caseElement, TEXT_INDEX_ELEMENT, false);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -489,7 +505,7 @@ public final class CaseMetadata {
|
|||||||
* @param elementName The element name.
|
* @param elementName The element name.
|
||||||
* @param contentIsRequired Whether or not the content is required.
|
* @param contentIsRequired Whether or not the content is required.
|
||||||
*
|
*
|
||||||
* @return The text content, may be empty if not required.
|
* @return The text content, may be empty If not required.
|
||||||
*
|
*
|
||||||
* @throws CaseMetadataException If the element is missing or content is
|
* @throws CaseMetadataException If the element is missing or content is
|
||||||
* required and it is empty.
|
* required and it is empty.
|
||||||
@ -530,7 +546,7 @@ public final class CaseMetadata {
|
|||||||
* @return The full path to the case database file for a single-user case.
|
* @return The full path to the case database file for a single-user case.
|
||||||
*
|
*
|
||||||
* @throws UnsupportedOperationException If called for a multi-user case.
|
* @throws UnsupportedOperationException If called for a multi-user case.
|
||||||
* @deprecated
|
* @deprecated Do not use.
|
||||||
*/
|
*/
|
||||||
@Deprecated
|
@Deprecated
|
||||||
public String getCaseDatabasePath() throws UnsupportedOperationException {
|
public String getCaseDatabasePath() throws UnsupportedOperationException {
|
||||||
|
@ -115,27 +115,20 @@ public final class CaseOpenAction extends CallableSystemAction implements Action
|
|||||||
protected void done() {
|
protected void done() {
|
||||||
try {
|
try {
|
||||||
get();
|
get();
|
||||||
} catch (InterruptedException ex) {
|
} catch (InterruptedException | ExecutionException ex) {
|
||||||
|
if (ex instanceof InterruptedException || (null != ex.getCause() && !(ex.getCause() instanceof CaseActionCancelledException))) {
|
||||||
logger.log(Level.SEVERE, String.format("Error opening case with metadata file path %s", path), ex); //NON-NLS
|
logger.log(Level.SEVERE, String.format("Error opening case with metadata file path %s", path), ex); //NON-NLS
|
||||||
WindowManager.getDefault().getMainWindow().setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
|
|
||||||
JOptionPane.showMessageDialog(
|
|
||||||
WindowManager.getDefault().getMainWindow(),
|
|
||||||
ex.getMessage(),
|
|
||||||
NbBundle.getMessage(this.getClass(), "CaseOpenAction.msgDlg.cantOpenCase.title"), //NON-NLS
|
|
||||||
JOptionPane.ERROR_MESSAGE);
|
|
||||||
StartupWindowProvider.getInstance().open();
|
|
||||||
} catch (ExecutionException ex) {
|
|
||||||
logger.log(Level.SEVERE, String.format("Error opening case with metadata file path %s", path), ex); //NON-NLS
|
|
||||||
WindowManager.getDefault().getMainWindow().setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
|
|
||||||
JOptionPane.showMessageDialog(
|
JOptionPane.showMessageDialog(
|
||||||
WindowManager.getDefault().getMainWindow(),
|
WindowManager.getDefault().getMainWindow(),
|
||||||
ex.getCause().getMessage(), //get the message of the wrapped exception
|
ex.getCause().getMessage(), //get the message of the wrapped exception
|
||||||
NbBundle.getMessage(this.getClass(), "CaseOpenAction.msgDlg.cantOpenCase.title"), //NON-NLS
|
NbBundle.getMessage(this.getClass(), "CaseOpenAction.msgDlg.cantOpenCase.title"), //NON-NLS
|
||||||
JOptionPane.ERROR_MESSAGE);
|
JOptionPane.ERROR_MESSAGE);
|
||||||
StartupWindowProvider.getInstance().open();
|
|
||||||
}
|
}
|
||||||
|
StartupWindowProvider.getInstance().open();
|
||||||
|
} finally {
|
||||||
WindowManager.getDefault().getMainWindow().setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
|
WindowManager.getDefault().getMainWindow().setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}.execute();
|
}.execute();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -22,7 +22,6 @@ import java.awt.Dimension;
|
|||||||
import java.awt.Toolkit;
|
import java.awt.Toolkit;
|
||||||
import java.awt.event.ActionEvent;
|
import java.awt.event.ActionEvent;
|
||||||
import java.beans.PropertyChangeEvent;
|
import java.beans.PropertyChangeEvent;
|
||||||
import java.beans.PropertyChangeListener;
|
|
||||||
import javax.swing.Action;
|
import javax.swing.Action;
|
||||||
import javax.swing.JDialog;
|
import javax.swing.JDialog;
|
||||||
import javax.swing.SwingUtilities;
|
import javax.swing.SwingUtilities;
|
||||||
@ -43,18 +42,14 @@ final class CasePropertiesAction extends CallableSystemAction {
|
|||||||
CasePropertiesAction() {
|
CasePropertiesAction() {
|
||||||
putValue(Action.NAME, NbBundle.getMessage(CasePropertiesAction.class, "CTL_CasePropertiesAction"));
|
putValue(Action.NAME, NbBundle.getMessage(CasePropertiesAction.class, "CTL_CasePropertiesAction"));
|
||||||
this.setEnabled(false);
|
this.setEnabled(false);
|
||||||
Case.addEventSubscriber(Case.Events.CURRENT_CASE.toString(), new PropertyChangeListener() {
|
Case.addEventSubscriber(Case.Events.CURRENT_CASE.toString(), (PropertyChangeEvent evt) -> {
|
||||||
@Override
|
|
||||||
public void propertyChange(PropertyChangeEvent evt) {
|
|
||||||
setEnabled(null != evt.getNewValue());
|
setEnabled(null != evt.getNewValue());
|
||||||
}
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void performAction() {
|
public void performAction() {
|
||||||
SwingUtilities.invokeLater(() -> {
|
SwingUtilities.invokeLater(() -> {
|
||||||
if (null == casePropertiesDialog) {
|
|
||||||
String title = NbBundle.getMessage(this.getClass(), "CasePropertiesAction.window.title");
|
String title = NbBundle.getMessage(this.getClass(), "CasePropertiesAction.window.title");
|
||||||
casePropertiesDialog = new JDialog(WindowManager.getDefault().getMainWindow(), title, false);
|
casePropertiesDialog = new JDialog(WindowManager.getDefault().getMainWindow(), title, false);
|
||||||
CaseInformationPanel caseInformationPanel = new CaseInformationPanel();
|
CaseInformationPanel caseInformationPanel = new CaseInformationPanel();
|
||||||
@ -70,7 +65,6 @@ final class CasePropertiesAction extends CallableSystemAction {
|
|||||||
double h = casePropertiesDialog.getSize().getHeight();
|
double h = casePropertiesDialog.getSize().getHeight();
|
||||||
casePropertiesDialog.setLocation((int) ((screenDimension.getWidth() - w) / 2), (int) ((screenDimension.getHeight() - h) / 2));
|
casePropertiesDialog.setLocation((int) ((screenDimension.getWidth() - w) / 2), (int) ((screenDimension.getHeight() - h) / 2));
|
||||||
casePropertiesDialog.setVisible(true);
|
casePropertiesDialog.setVisible(true);
|
||||||
}
|
|
||||||
casePropertiesDialog.setVisible(true);
|
casePropertiesDialog.setVisible(true);
|
||||||
casePropertiesDialog.toFront();
|
casePropertiesDialog.toFront();
|
||||||
});
|
});
|
||||||
@ -87,6 +81,9 @@ final class CasePropertiesAction extends CallableSystemAction {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void closeCasePropertiesWindow() {
|
static void closeCasePropertiesWindow() {
|
||||||
|
if (null != casePropertiesDialog) {
|
||||||
casePropertiesDialog.setVisible(false);
|
casePropertiesDialog.setVisible(false);
|
||||||
|
casePropertiesDialog = null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -16,63 +16,57 @@
|
|||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.sleuthkit.autopsy.casemodule;
|
package org.sleuthkit.autopsy.casemodule;
|
||||||
|
|
||||||
import java.nio.file.Paths;
|
import java.nio.file.Paths;
|
||||||
import java.util.Map;
|
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
import javax.swing.JOptionPane;
|
|
||||||
import javax.swing.JPanel;
|
|
||||||
import org.openide.DialogDescriptor;
|
|
||||||
import org.openide.DialogDisplayer;
|
|
||||||
import org.openide.NotifyDescriptor;
|
|
||||||
import org.openide.util.NbBundle;
|
import org.openide.util.NbBundle;
|
||||||
import org.openide.util.actions.CallableSystemAction;
|
import org.openide.util.actions.CallableSystemAction;
|
||||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||||
|
import org.sleuthkit.autopsy.coreutils.MessageNotifyUtil;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A panel that allows the user to view various properties of the current case
|
* A panel that allows the user to view various properties of a case and change
|
||||||
* and change the display name of the case.
|
* the display name of the case.
|
||||||
*/
|
*/
|
||||||
class CasePropertiesPanel extends javax.swing.JPanel {
|
class CasePropertiesPanel extends javax.swing.JPanel {
|
||||||
|
|
||||||
private static final long serialVersionUID = 1L;
|
private static final long serialVersionUID = 1L;
|
||||||
private Case current = null;
|
private static final Logger LOGGER = Logger.getLogger(CasePropertiesPanel.class.getName());
|
||||||
private static JPanel caller; // panel for error
|
private final Case theCase;
|
||||||
|
|
||||||
CasePropertiesPanel(Case currentCase, String crDate, String caseDir, Map<Long, String> imgPaths) throws CaseMetadata.CaseMetadataException {
|
/**
|
||||||
|
* Constructs a panel that allows the user to view various properties of the
|
||||||
|
* current case and change the display name of the case.
|
||||||
|
*
|
||||||
|
* @param aCase A case.
|
||||||
|
*/
|
||||||
|
CasePropertiesPanel(Case aCase) {
|
||||||
initComponents();
|
initComponents();
|
||||||
caseNameTextField.setText(currentCase.getDisplayName());
|
theCase = aCase;
|
||||||
String caseNumber = currentCase.getNumber();
|
caseNameTextField.setText(theCase.getDisplayName());
|
||||||
|
String caseNumber = theCase.getNumber();
|
||||||
if (!caseNumber.isEmpty()) {
|
if (!caseNumber.isEmpty()) {
|
||||||
caseNumberField.setText(caseNumber);
|
caseNumberField.setText(caseNumber);
|
||||||
} else {
|
} else {
|
||||||
caseNumberField.setText("N/A");
|
caseNumberField.setText("N/A");
|
||||||
}
|
}
|
||||||
String examiner = currentCase.getExaminer();
|
String examiner = theCase.getExaminer();
|
||||||
if (!examiner.isEmpty()) {
|
if (!examiner.isEmpty()) {
|
||||||
examinerField.setText(examiner);
|
examinerField.setText(examiner);
|
||||||
} else {
|
} else {
|
||||||
examinerField.setText("N/A");
|
examinerField.setText("N/A");
|
||||||
}
|
}
|
||||||
crDateField.setText(crDate);
|
crDateField.setText(theCase.getCreatedDate());
|
||||||
caseDirField.setText(caseDir);
|
caseDirField.setText(theCase.getCaseDirectory());
|
||||||
current = currentCase;
|
if (Case.CaseType.SINGLE_USER_CASE == theCase.getCaseType()) {
|
||||||
|
dbNameField.setText(Paths.get(theCase.getCaseDirectory(), theCase.getMetadata().getCaseDatabaseName()).toString());
|
||||||
CaseMetadata caseMetadata = currentCase.getCaseMetadata();
|
|
||||||
if (caseMetadata.getCaseType() == Case.CaseType.SINGLE_USER_CASE) {
|
|
||||||
dbNameField.setText(Paths.get(caseMetadata.getCaseDirectory(), caseMetadata.getCaseDatabaseName()).toString());
|
|
||||||
} else {
|
} else {
|
||||||
dbNameField.setText(caseMetadata.getCaseDatabaseName());
|
dbNameField.setText(theCase.getMetadata().getCaseDatabaseName());
|
||||||
}
|
}
|
||||||
Case.CaseType caseType = caseMetadata.getCaseType();
|
Case.CaseType caseType = theCase.getCaseType();
|
||||||
caseTypeField.setText(caseType.getLocalizedDisplayName());
|
caseTypeField.setText(caseType.getLocalizedDisplayName());
|
||||||
if (caseType == Case.CaseType.SINGLE_USER_CASE) {
|
deleteCaseButton.setEnabled(Case.CaseType.SINGLE_USER_CASE == caseType);
|
||||||
deleteCaseButton.setEnabled(true);
|
|
||||||
} else {
|
|
||||||
deleteCaseButton.setEnabled(false);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -259,59 +253,35 @@ class CasePropertiesPanel extends javax.swing.JPanel {
|
|||||||
}// </editor-fold>//GEN-END:initComponents
|
}// </editor-fold>//GEN-END:initComponents
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Updates the case name.
|
* Updates the case display name.
|
||||||
*
|
*
|
||||||
* @param evt The action event
|
* @param evt The action event
|
||||||
*/
|
*/
|
||||||
|
@NbBundle.Messages({
|
||||||
|
"CasePropertiesPanel.errorDialog.emptyCaseNameMessage=No case name entered.",
|
||||||
|
"CasePropertiesPanel.errorDialog.invalidCaseNameMessage=Case names cannot include the following symbols: \\, /, :, *, ?, \", <, >, |"
|
||||||
|
})
|
||||||
private void updateCaseNameButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_updateCaseNameButtonActionPerformed
|
private void updateCaseNameButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_updateCaseNameButtonActionPerformed
|
||||||
String oldCaseName = Case.getCurrentCase().getDisplayName();
|
String newCaseDisplayName = caseNameTextField.getText();
|
||||||
String newCaseName = caseNameTextField.getText();
|
if (newCaseDisplayName.equals(theCase.getDisplayName())) {
|
||||||
// check if the old and new case name is not equal
|
return;
|
||||||
if (!oldCaseName.equals(newCaseName)) {
|
}
|
||||||
|
|
||||||
// check if the case name is empty
|
if (newCaseDisplayName.trim().isEmpty()) {
|
||||||
if (newCaseName.trim().isEmpty()) {
|
MessageNotifyUtil.Message.error(Bundle.CasePropertiesPanel_errorDialog_emptyCaseNameMessage());
|
||||||
JOptionPane.showMessageDialog(caller,
|
return;
|
||||||
NbBundle.getMessage(this.getClass(),
|
}
|
||||||
"CasePropertiesForm.updateCaseName.msgDlg.empty.msg"),
|
|
||||||
NbBundle.getMessage(this.getClass(),
|
if (!Case.isValidName(newCaseDisplayName)) {
|
||||||
"CasePropertiesForm.updateCaseName.msgDlg.empty.title"),
|
MessageNotifyUtil.Message.error(Bundle.CasePropertiesPanel_errorDialog_invalidCaseNameMessage());
|
||||||
JOptionPane.ERROR_MESSAGE);
|
return;
|
||||||
} 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 {
|
try {
|
||||||
current.updateCaseName(oldCaseName, oldPath, newCaseName, oldPath);
|
theCase.updateDisplayName(newCaseDisplayName);
|
||||||
} catch (CaseActionException ex) {
|
} catch (CaseActionException ex) {
|
||||||
Logger.getLogger(CasePropertiesPanel.class.getName()).log(Level.WARNING, "Error: problem updating case name.", ex); //NON-NLS
|
MessageNotifyUtil.Message.error(ex.getLocalizedMessage());
|
||||||
}
|
LOGGER.log(Level.SEVERE, "Failed to update case display name", ex); //NON-NLS
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}//GEN-LAST:event_updateCaseNameButtonActionPerformed
|
}//GEN-LAST:event_updateCaseNameButtonActionPerformed
|
||||||
|
|
||||||
|
@ -33,7 +33,7 @@ import org.sleuthkit.autopsy.corecomponentinterfaces.DataSourceProcessorProgress
|
|||||||
import org.sleuthkit.autopsy.corecomponentinterfaces.DataSourceProcessorCallback;
|
import org.sleuthkit.autopsy.corecomponentinterfaces.DataSourceProcessorCallback;
|
||||||
import org.sleuthkit.autopsy.corecomponentinterfaces.DataSourceProcessor;
|
import org.sleuthkit.autopsy.corecomponentinterfaces.DataSourceProcessor;
|
||||||
import org.sleuthkit.autopsy.coreutils.DataSourceUtils;
|
import org.sleuthkit.autopsy.coreutils.DataSourceUtils;
|
||||||
import org.sleuthkit.autopsy.framework.AutoIngestDataSourceProcessor;
|
import org.sleuthkit.autopsy.datasourceprocessors.AutoIngestDataSourceProcessor;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A image file data source processor that implements the DataSourceProcessor
|
* A image file data source processor that implements the DataSourceProcessor
|
||||||
|
@ -31,7 +31,7 @@ import org.sleuthkit.autopsy.corecomponentinterfaces.DataSourceProcessorProgress
|
|||||||
import org.sleuthkit.autopsy.corecomponentinterfaces.DataSourceProcessor;
|
import org.sleuthkit.autopsy.corecomponentinterfaces.DataSourceProcessor;
|
||||||
import org.sleuthkit.autopsy.coreutils.DriveUtils;
|
import org.sleuthkit.autopsy.coreutils.DriveUtils;
|
||||||
import org.sleuthkit.autopsy.imagewriter.ImageWriterSettings;
|
import org.sleuthkit.autopsy.imagewriter.ImageWriterSettings;
|
||||||
import org.sleuthkit.autopsy.framework.AutoIngestDataSourceProcessor;
|
import org.sleuthkit.autopsy.datasourceprocessors.AutoIngestDataSourceProcessor;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A local drive data source processor that implements the DataSourceProcessor
|
* A local drive data source processor that implements the DataSourceProcessor
|
||||||
|
@ -29,7 +29,7 @@ import org.openide.util.lookup.ServiceProviders;
|
|||||||
import org.sleuthkit.autopsy.corecomponentinterfaces.DataSourceProcessorCallback;
|
import org.sleuthkit.autopsy.corecomponentinterfaces.DataSourceProcessorCallback;
|
||||||
import org.sleuthkit.autopsy.corecomponentinterfaces.DataSourceProcessorProgressMonitor;
|
import org.sleuthkit.autopsy.corecomponentinterfaces.DataSourceProcessorProgressMonitor;
|
||||||
import org.sleuthkit.autopsy.corecomponentinterfaces.DataSourceProcessor;
|
import org.sleuthkit.autopsy.corecomponentinterfaces.DataSourceProcessor;
|
||||||
import org.sleuthkit.autopsy.framework.AutoIngestDataSourceProcessor;
|
import org.sleuthkit.autopsy.datasourceprocessors.AutoIngestDataSourceProcessor;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A local/logical files and/or directories data source processor that
|
* A local/logical files and/or directories data source processor that
|
||||||
|
@ -94,15 +94,17 @@ final class NewCaseWizardAction extends CallableSystemAction {
|
|||||||
AddImageAction addImageAction = SystemAction.get(AddImageAction.class);
|
AddImageAction addImageAction = SystemAction.get(AddImageAction.class);
|
||||||
addImageAction.actionPerformed(null);
|
addImageAction.actionPerformed(null);
|
||||||
} catch (InterruptedException | ExecutionException ex) {
|
} catch (InterruptedException | ExecutionException ex) {
|
||||||
|
if (null != ex.getCause() && !(ex.getCause() instanceof CaseActionCancelledException)) {
|
||||||
logger.log(Level.SEVERE, String.format("Error creating case %s", wizardDescriptor.getProperty("caseName")), ex); //NON-NLS
|
logger.log(Level.SEVERE, String.format("Error creating case %s", wizardDescriptor.getProperty("caseName")), ex); //NON-NLS
|
||||||
JOptionPane.showMessageDialog(
|
JOptionPane.showMessageDialog(
|
||||||
WindowManager.getDefault().getMainWindow(),
|
WindowManager.getDefault().getMainWindow(),
|
||||||
(ex instanceof ExecutionException ? ex.getCause().getMessage() : ex.getMessage()),
|
(ex instanceof ExecutionException ? ex.getCause().getMessage() : ex.getMessage()),
|
||||||
NbBundle.getMessage(this.getClass(), "CaseCreateAction.msgDlg.cantCreateCase.msg"), //NON-NLS
|
NbBundle.getMessage(this.getClass(), "CaseCreateAction.msgDlg.cantCreateCase.msg"), //NON-NLS
|
||||||
JOptionPane.ERROR_MESSAGE);
|
JOptionPane.ERROR_MESSAGE);
|
||||||
|
}
|
||||||
|
doFailedCaseCleanup(wizardDescriptor);
|
||||||
StartupWindowProvider.getInstance().close();
|
StartupWindowProvider.getInstance().close();
|
||||||
StartupWindowProvider.getInstance().open();
|
StartupWindowProvider.getInstance().open();
|
||||||
doFailedCaseCleanup(wizardDescriptor);
|
|
||||||
} finally {
|
} finally {
|
||||||
WindowManager.getDefault().getMainWindow().setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
|
WindowManager.getDefault().getMainWindow().setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
|
||||||
}
|
}
|
||||||
|
@ -38,29 +38,21 @@ import org.sleuthkit.autopsy.coreutils.Logger;
|
|||||||
import org.sleuthkit.autopsy.coreutils.ModuleSettings;
|
import org.sleuthkit.autopsy.coreutils.ModuleSettings;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The "New Case" wizard panel with a component on it. This class represents
|
* The first panel of the New Case wizard.
|
||||||
* data of wizard step. It defers creation and initialization of UI component of
|
|
||||||
* wizard panel into getComponent() method.
|
|
||||||
*/
|
*/
|
||||||
class NewCaseWizardPanel1 implements WizardDescriptor.ValidatingPanel<WizardDescriptor> {
|
class NewCaseWizardPanel1 implements WizardDescriptor.ValidatingPanel<WizardDescriptor> {
|
||||||
|
|
||||||
/**
|
|
||||||
* The visual component that displays this panel. If you need to access the
|
|
||||||
* component from this class, just use getComponent().
|
|
||||||
*/
|
|
||||||
private NewCaseVisualPanel1 component;
|
|
||||||
private Boolean isFinish = false;
|
|
||||||
private static String createdDirectory;
|
|
||||||
private static final String PROP_BASECASE = "LBL_BaseCase_PATH"; //NON-NLS
|
|
||||||
private static final Logger logger = Logger.getLogger(NewCaseWizardPanel1.class.getName());
|
private static final Logger logger = Logger.getLogger(NewCaseWizardPanel1.class.getName());
|
||||||
|
private static final String PROP_BASECASE = "LBL_BaseCase_PATH"; //NON-NLS
|
||||||
|
private static String createdDirectory;
|
||||||
|
private final Set<ChangeListener> listeners = new HashSet<>(1);
|
||||||
|
private NewCaseVisualPanel1 component;
|
||||||
|
private boolean isFinish;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the visual component for the panel. In this template, the component
|
* Get the visual component for the panel.
|
||||||
* is kept separate. This can be more efficient: if the wizard is created
|
|
||||||
* but never displayed, or not all panels are displayed, it is better to
|
|
||||||
* create only those which really need to be visible.
|
|
||||||
*
|
*
|
||||||
* @return component the UI component of this wizard panel
|
* @return The UI component of this wizard panel
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public NewCaseVisualPanel1 getComponent() {
|
public NewCaseVisualPanel1 getComponent() {
|
||||||
@ -71,65 +63,57 @@ class NewCaseWizardPanel1 implements WizardDescriptor.ValidatingPanel<WizardDesc
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Help for this panel. When the panel is active, this is used as the help
|
* Gets the help object for this panel. When the panel is active, this is
|
||||||
* for the wizard dialog.
|
* used as the help for the wizard dialog.
|
||||||
*
|
*
|
||||||
* @return HelpCtx.DEFAULT_HELP the help for this panel
|
* @return The help for this panel.
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public HelpCtx getHelp() {
|
public HelpCtx getHelp() {
|
||||||
// Show no Help button for this panel:
|
/*
|
||||||
|
* Currently, no help is provided for this panel.
|
||||||
|
*/
|
||||||
return HelpCtx.DEFAULT_HELP;
|
return HelpCtx.DEFAULT_HELP;
|
||||||
// If you have context help:
|
|
||||||
// return new HelpCtx(SampleWizardPanel1.class);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tests whether the panel is finished. If the panel is valid, the "Finish"
|
* Tests whether the panel is finished. If the panel is valid, the "Finish"
|
||||||
* button will be enabled.
|
* button will be enabled.
|
||||||
*
|
*
|
||||||
* @return boolean true if all the fields are correctly filled, false
|
* @return boolean True if all the fields are correctly filled, false
|
||||||
* otherwise
|
* otherwise.
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public boolean isValid() {
|
public boolean isValid() {
|
||||||
// If it is always OK to press Next or Finish, then:
|
|
||||||
return isFinish;
|
return isFinish;
|
||||||
// If it depends on some condition (form filled out...), then:
|
|
||||||
// return someCondition();
|
|
||||||
// and when this condition changes (last form field filled in...) then:
|
|
||||||
// fireChangeEvent();
|
|
||||||
// and uncomment the complicated stuff below.
|
|
||||||
}
|
}
|
||||||
private final Set<ChangeListener> listeners = new HashSet<>(1); // or can use ChangeSupport in NB 6.0
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Adds a listener to changes of the panel's validity.
|
* Adds a change listener to this panel.
|
||||||
*
|
*
|
||||||
* @param l the change listener to add
|
* @param listener The change listener to add.
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public final void addChangeListener(ChangeListener l) {
|
public final void addChangeListener(ChangeListener listener) {
|
||||||
synchronized (listeners) {
|
synchronized (listeners) {
|
||||||
listeners.add(l);
|
listeners.add(listener);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Removes a listener to changes of the panel's validity.
|
* Removes a change listener from this panel.
|
||||||
*
|
*
|
||||||
* @param l the change listener to move
|
* @param listener The change listener to remove.
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public final void removeChangeListener(ChangeListener l) {
|
public final void removeChangeListener(ChangeListener listener) {
|
||||||
synchronized (listeners) {
|
synchronized (listeners) {
|
||||||
listeners.remove(l);
|
listeners.remove(listener);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This method is auto-generated. It seems that this method is used to
|
* Notifies any registerd change listeners of a change in the panel.
|
||||||
* listen to any change in this wizard panel.
|
|
||||||
*/
|
*/
|
||||||
protected final void fireChangeEvent() {
|
protected final void fireChangeEvent() {
|
||||||
Iterator<ChangeListener> it;
|
Iterator<ChangeListener> it;
|
||||||
@ -153,12 +137,8 @@ class NewCaseWizardPanel1 implements WizardDescriptor.ValidatingPanel<WizardDesc
|
|||||||
fireChangeEvent();
|
fireChangeEvent();
|
||||||
}
|
}
|
||||||
|
|
||||||
// You can use a settings object to keep track of state. Normally the
|
|
||||||
// settings object will be the WizardDescriptor, so you can use
|
|
||||||
// WizardDescriptor.getProperty & putProperty to store information entered
|
|
||||||
// by the user.
|
|
||||||
/**
|
/**
|
||||||
* Provides the wizard panel with the current data--either the default data
|
* Provides the wizard panel with the current data - either the default data
|
||||||
* or already-modified settings, if the user used the previous and/or next
|
* or already-modified settings, if the user used the previous and/or next
|
||||||
* buttons. This method can be called multiple times on one instance of
|
* buttons. This method can be called multiple times on one instance of
|
||||||
* WizardDescriptor.Panel.
|
* WizardDescriptor.Panel.
|
||||||
@ -322,4 +302,5 @@ class NewCaseWizardPanel1 implements WizardDescriptor.ValidatingPanel<WizardDesc
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* Autopsy Forensic Browser
|
* Autopsy Forensic Browser
|
||||||
*
|
*
|
||||||
* Copyright 2011-2015 Basis Technology Corp.
|
* Copyright 2011-2017 Basis Technology Corp.
|
||||||
* Contact: carrier <at> sleuthkit <dot> org
|
* Contact: carrier <at> sleuthkit <dot> org
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
@ -28,35 +28,19 @@ import org.openide.WizardValidationException;
|
|||||||
import org.openide.util.HelpCtx;
|
import org.openide.util.HelpCtx;
|
||||||
import org.openide.windows.WindowManager;
|
import org.openide.windows.WindowManager;
|
||||||
import java.awt.Cursor;
|
import java.awt.Cursor;
|
||||||
import org.sleuthkit.autopsy.casemodule.Case.CaseType;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The "New Case" wizard panel with a component on it. This class represents
|
* The second panel of the New Case wizard.
|
||||||
* data of wizard step. It defers creation and initialization of UI component of
|
|
||||||
* wizard panel into getComponent() method.
|
|
||||||
*
|
|
||||||
* @author jantonius
|
|
||||||
*/
|
*/
|
||||||
class NewCaseWizardPanel2 implements WizardDescriptor.ValidatingPanel<WizardDescriptor> {
|
class NewCaseWizardPanel2 implements WizardDescriptor.ValidatingPanel<WizardDescriptor> {
|
||||||
|
|
||||||
/**
|
|
||||||
* The visual component that displays this panel. If you need to access the
|
|
||||||
* component from this class, just use getComponent().
|
|
||||||
*/
|
|
||||||
private NewCaseVisualPanel2 component;
|
private NewCaseVisualPanel2 component;
|
||||||
private Boolean isFinish = true;
|
private final Set<ChangeListener> listeners = new HashSet<>(1);
|
||||||
private String caseName;
|
|
||||||
private String caseDir;
|
|
||||||
private String createdDirectory;
|
|
||||||
private CaseType caseType;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the visual component for the panel. In this template, the component
|
* Get the visual component for the panel.
|
||||||
* is kept separate. This can be more efficient: if the wizard is created
|
|
||||||
* but never displayed, or not all panels are displayed, it is better to
|
|
||||||
* create only those which really need to be visible.
|
|
||||||
*
|
*
|
||||||
* @return component the UI component of this wizard panel
|
* @return component The UI component of this wizard panel.
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public NewCaseVisualPanel2 getComponent() {
|
public NewCaseVisualPanel2 getComponent() {
|
||||||
@ -67,17 +51,17 @@ class NewCaseWizardPanel2 implements WizardDescriptor.ValidatingPanel<WizardDesc
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Help for this panel. When the panel is active, this is used as the help
|
* Gets the help object for this panel. When the panel is active, this is
|
||||||
* for the wizard dialog.
|
* used as the help for the wizard dialog.
|
||||||
*
|
*
|
||||||
* @return HelpCtx.DEFAULT_HELP the help for this panel
|
* @return The help for this panel.
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public HelpCtx getHelp() {
|
public HelpCtx getHelp() {
|
||||||
// Show no Help button for this panel:
|
/*
|
||||||
|
* Currently, no help is provided for this panel.
|
||||||
|
*/
|
||||||
return HelpCtx.DEFAULT_HELP;
|
return HelpCtx.DEFAULT_HELP;
|
||||||
// If you have context help:
|
|
||||||
// return new HelpCtx(SampleWizardPanel1.class);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -89,43 +73,35 @@ class NewCaseWizardPanel2 implements WizardDescriptor.ValidatingPanel<WizardDesc
|
|||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public boolean isValid() {
|
public boolean isValid() {
|
||||||
// If it is always OK to press Next or Finish, then:
|
return true;
|
||||||
return isFinish;
|
|
||||||
// If it depends on some condition (form filled out...), then:
|
|
||||||
// return someCondition();
|
|
||||||
// and when this condition changes (last form field filled in...) then:
|
|
||||||
// fireChangeEvent();
|
|
||||||
// and uncomment the complicated stuff below.
|
|
||||||
}
|
}
|
||||||
private final Set<ChangeListener> listeners = new HashSet<ChangeListener>(1); // or can use ChangeSupport in NB 6.0
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Adds a listener to changes of the panel's validity.
|
* Adds a change listener to this panel.
|
||||||
*
|
*
|
||||||
* @param l the change listener to add
|
* @param listener The change listener to add.
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public final void addChangeListener(ChangeListener l) {
|
public final void addChangeListener(ChangeListener listener) {
|
||||||
synchronized (listeners) {
|
synchronized (listeners) {
|
||||||
listeners.add(l);
|
listeners.add(listener);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Removes a listener to changes of the panel's validity.
|
* Removes a change listener from this panel.
|
||||||
*
|
*
|
||||||
* @param l the change listener to move
|
* @param listener The change listener to remove.
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public final void removeChangeListener(ChangeListener l) {
|
public final void removeChangeListener(ChangeListener listener) {
|
||||||
synchronized (listeners) {
|
synchronized (listeners) {
|
||||||
listeners.remove(l);
|
listeners.remove(listener);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This method is auto-generated. It seems that this method is used to
|
* Notifies any registerd change listeners of a change in the panel.
|
||||||
* listen to any change in this wizard panel.
|
|
||||||
*/
|
*/
|
||||||
protected final void fireChangeEvent() {
|
protected final void fireChangeEvent() {
|
||||||
Iterator<ChangeListener> it;
|
Iterator<ChangeListener> it;
|
||||||
@ -138,10 +114,6 @@ class NewCaseWizardPanel2 implements WizardDescriptor.ValidatingPanel<WizardDesc
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// You can use a settings object to keep track of state. Normally the
|
|
||||||
// settings object will be the WizardDescriptor, so you can use
|
|
||||||
// WizardDescriptor.getProperty & putProperty to store information entered
|
|
||||||
// by the user.
|
|
||||||
/**
|
/**
|
||||||
* Provides the wizard panel with the current data--either the default data
|
* Provides the wizard panel with the current data--either the default data
|
||||||
* or already-modified settings, if the user used the previous and/or next
|
* or already-modified settings, if the user used the previous and/or next
|
||||||
@ -152,10 +124,6 @@ class NewCaseWizardPanel2 implements WizardDescriptor.ValidatingPanel<WizardDesc
|
|||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void readSettings(WizardDescriptor settings) {
|
public void readSettings(WizardDescriptor settings) {
|
||||||
caseName = (String) settings.getProperty("caseName"); //NON-NLS
|
|
||||||
caseDir = (String) settings.getProperty("caseParentDir"); //NON-NLS
|
|
||||||
createdDirectory = (String) settings.getProperty("createdDirectory"); //NON-NLS
|
|
||||||
caseType = CaseType.values()[(int) settings.getProperty("caseType")]; //NON-NLS
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -100,9 +100,9 @@ class OpenRecentCasePanel extends javax.swing.JPanel {
|
|||||||
if (casePaths.length < 1) {
|
if (casePaths.length < 1) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
final String casePath = casePaths[imagesTable.getSelectedRow()];
|
final String caseMetadataFilePath = casePaths[imagesTable.getSelectedRow()];
|
||||||
final String caseName = caseNames[imagesTable.getSelectedRow()];
|
final String caseName = caseNames[imagesTable.getSelectedRow()];
|
||||||
if (!casePath.isEmpty()) {
|
if (!caseMetadataFilePath.isEmpty()) {
|
||||||
try {
|
try {
|
||||||
StartupWindowProvider.getInstance().close();
|
StartupWindowProvider.getInstance().close();
|
||||||
CueBannerPanel.closeOpenRecentCasesWindow();
|
CueBannerPanel.closeOpenRecentCasesWindow();
|
||||||
@ -113,25 +113,27 @@ class OpenRecentCasePanel extends javax.swing.JPanel {
|
|||||||
/*
|
/*
|
||||||
* Open the case.
|
* Open the case.
|
||||||
*/
|
*/
|
||||||
if (caseName.isEmpty() || casePath.isEmpty() || (!new File(casePath).exists())) {
|
if (caseName.isEmpty() || caseMetadataFilePath.isEmpty() || (!new File(caseMetadataFilePath).exists())) {
|
||||||
JOptionPane.showMessageDialog(WindowManager.getDefault().getMainWindow(),
|
JOptionPane.showMessageDialog(WindowManager.getDefault().getMainWindow(),
|
||||||
NbBundle.getMessage(this.getClass(), "RecentItems.openRecentCase.msgDlg.text", caseName),
|
NbBundle.getMessage(this.getClass(), "RecentItems.openRecentCase.msgDlg.text", caseName),
|
||||||
NbBundle.getMessage(this.getClass(), "CaseOpenAction.msgDlg.cantOpenCase.title"),
|
NbBundle.getMessage(this.getClass(), "CaseOpenAction.msgDlg.cantOpenCase.title"),
|
||||||
JOptionPane.ERROR_MESSAGE);
|
JOptionPane.ERROR_MESSAGE);
|
||||||
RecentCases.getInstance().removeRecentCase(caseName, casePath); // remove the recent case if it doesn't exist anymore
|
RecentCases.getInstance().removeRecentCase(caseName, caseMetadataFilePath); // remove the recent case if it doesn't exist anymore
|
||||||
StartupWindowProvider.getInstance().open();
|
StartupWindowProvider.getInstance().open();
|
||||||
} else {
|
} else {
|
||||||
new Thread(() -> {
|
new Thread(() -> {
|
||||||
try {
|
try {
|
||||||
Case.openAsCurrentCase(casePath);
|
Case.openAsCurrentCase(caseMetadataFilePath);
|
||||||
} catch (CaseActionException ex) {
|
} catch (CaseActionException ex) {
|
||||||
logger.log(Level.SEVERE, String.format("Error opening case with metadata file path %s", casePath), ex); //NON-NLS
|
|
||||||
SwingUtilities.invokeLater(() -> {
|
SwingUtilities.invokeLater(() -> {
|
||||||
|
if (!(ex instanceof CaseActionCancelledException)) {
|
||||||
|
logger.log(Level.SEVERE, String.format("Error opening case with metadata file path %s", caseMetadataFilePath), ex); //NON-NLS
|
||||||
JOptionPane.showMessageDialog(
|
JOptionPane.showMessageDialog(
|
||||||
WindowManager.getDefault().getMainWindow(),
|
WindowManager.getDefault().getMainWindow(),
|
||||||
ex.getMessage(), // Should be user-friendly
|
ex.getMessage(),
|
||||||
NbBundle.getMessage(this.getClass(), "CaseOpenAction.msgDlg.cantOpenCase.title"), //NON-NLS
|
NbBundle.getMessage(OpenRecentCasePanel.this.getClass(), "CaseOpenAction.msgDlg.cantOpenCase.title"), //NON-NLS
|
||||||
JOptionPane.ERROR_MESSAGE);
|
JOptionPane.ERROR_MESSAGE);
|
||||||
|
}
|
||||||
StartupWindowProvider.getInstance().open();
|
StartupWindowProvider.getInstance().open();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -407,9 +407,11 @@ final class RecentCases extends CallableSystemAction implements Presenter.Menu {
|
|||||||
String[] casePaths = new String[LENGTH];
|
String[] casePaths = new String[LENGTH];
|
||||||
String currentCasePath = null;
|
String currentCasePath = null;
|
||||||
try {
|
try {
|
||||||
currentCasePath = Case.getCurrentCase().getCaseMetadata().getFilePath().toString();
|
currentCasePath = Case.getCurrentCase().getMetadata().getFilePath().toString();
|
||||||
} catch (IllegalStateException ex) {
|
} catch (IllegalStateException ex) {
|
||||||
// in case there is no current case.
|
/*
|
||||||
|
* There may be no current case.
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
Iterator<RecentCase> mostRecentFirst = recentCases.descendingIterator();
|
Iterator<RecentCase> mostRecentFirst = recentCases.descendingIterator();
|
||||||
|
@ -64,14 +64,17 @@ class RecentItems implements ActionListener {
|
|||||||
new Thread(() -> {
|
new Thread(() -> {
|
||||||
try {
|
try {
|
||||||
Case.openAsCurrentCase(caseMetaDataFilePath);
|
Case.openAsCurrentCase(caseMetaDataFilePath);
|
||||||
|
StartupWindowProvider.getInstance().close();
|
||||||
} catch (CaseActionException ex) {
|
} catch (CaseActionException ex) {
|
||||||
logger.log(Level.SEVERE, String.format("Error opening case with metadata file path %s", caseMetaDataFilePath), ex); //NON-NLS
|
|
||||||
SwingUtilities.invokeLater(() -> {
|
SwingUtilities.invokeLater(() -> {
|
||||||
|
if (!(ex instanceof CaseActionCancelledException)) {
|
||||||
|
logger.log(Level.SEVERE, String.format("Error opening case with metadata file path %s", caseMetaDataFilePath), ex); //NON-NLS
|
||||||
JOptionPane.showMessageDialog(
|
JOptionPane.showMessageDialog(
|
||||||
WindowManager.getDefault().getMainWindow(),
|
WindowManager.getDefault().getMainWindow(),
|
||||||
ex.getMessage(),
|
ex.getMessage(),
|
||||||
NbBundle.getMessage(RecentItems.this.getClass(), "CaseOpenAction.msgDlg.cantOpenCase.title"), //NON-NLS
|
NbBundle.getMessage(RecentItems.this.getClass(), "CaseOpenAction.msgDlg.cantOpenCase.title"), //NON-NLS
|
||||||
JOptionPane.ERROR_MESSAGE);
|
JOptionPane.ERROR_MESSAGE);
|
||||||
|
}
|
||||||
StartupWindowProvider.getInstance().open();
|
StartupWindowProvider.getInstance().open();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -204,8 +204,8 @@ public class SingleUserCaseConverter {
|
|||||||
icd.getNewCaseName(),
|
icd.getNewCaseName(),
|
||||||
icd.getNewCaseName(),
|
icd.getNewCaseName(),
|
||||||
oldCaseMetadata.getCaseNumber(),
|
oldCaseMetadata.getCaseNumber(),
|
||||||
oldCaseMetadata.getExaminer(),
|
oldCaseMetadata.getExaminer());
|
||||||
dbName);
|
newCaseMetadata.setCaseDatabaseName(dbName);
|
||||||
// Set created date. This calls writefile, no need to call it again
|
// Set created date. This calls writefile, no need to call it again
|
||||||
newCaseMetadata.setCreatedDate(oldCaseMetadata.getCreatedDate());
|
newCaseMetadata.setCreatedDate(oldCaseMetadata.getCreatedDate());
|
||||||
newCaseMetadata.setCreatedByVersion(oldCaseMetadata.getCreatedByVersion());
|
newCaseMetadata.setCreatedByVersion(oldCaseMetadata.getCreatedByVersion());
|
||||||
|
@ -26,9 +26,12 @@ import java.awt.Graphics;
|
|||||||
import java.awt.dnd.DnDConstants;
|
import java.awt.dnd.DnDConstants;
|
||||||
import java.awt.event.MouseAdapter;
|
import java.awt.event.MouseAdapter;
|
||||||
import java.awt.event.MouseEvent;
|
import java.awt.event.MouseEvent;
|
||||||
|
import java.beans.FeatureDescriptor;
|
||||||
|
import java.beans.PropertyChangeEvent;
|
||||||
import java.lang.reflect.InvocationTargetException;
|
import java.lang.reflect.InvocationTargetException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
import java.util.Comparator;
|
||||||
import java.util.LinkedHashSet;
|
import java.util.LinkedHashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
@ -36,6 +39,8 @@ import java.util.Set;
|
|||||||
import java.util.TreeMap;
|
import java.util.TreeMap;
|
||||||
import java.util.prefs.Preferences;
|
import java.util.prefs.Preferences;
|
||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
|
import java.util.TreeSet;
|
||||||
|
import java.util.prefs.Preferences;
|
||||||
import javax.swing.JTable;
|
import javax.swing.JTable;
|
||||||
import javax.swing.ListSelectionModel;
|
import javax.swing.ListSelectionModel;
|
||||||
import javax.swing.SwingUtilities;
|
import javax.swing.SwingUtilities;
|
||||||
@ -44,6 +49,8 @@ import javax.swing.event.ListSelectionEvent;
|
|||||||
import javax.swing.event.TableColumnModelEvent;
|
import javax.swing.event.TableColumnModelEvent;
|
||||||
import javax.swing.event.TableColumnModelListener;
|
import javax.swing.event.TableColumnModelListener;
|
||||||
import javax.swing.table.TableCellRenderer;
|
import javax.swing.table.TableCellRenderer;
|
||||||
|
|
||||||
|
import javax.swing.table.TableColumnModel;
|
||||||
import org.netbeans.swing.etable.ETableColumn;
|
import org.netbeans.swing.etable.ETableColumn;
|
||||||
import org.netbeans.swing.outline.DefaultOutlineCellRenderer;
|
import org.netbeans.swing.outline.DefaultOutlineCellRenderer;
|
||||||
import org.netbeans.swing.outline.DefaultOutlineModel;
|
import org.netbeans.swing.outline.DefaultOutlineModel;
|
||||||
@ -96,6 +103,7 @@ public class DataResultViewerTable extends AbstractDataResultViewer {
|
|||||||
// the column started and where it ended up.
|
// the column started and where it ended up.
|
||||||
private int startColumnIndex = -1;
|
private int startColumnIndex = -1;
|
||||||
private int endColumnIndex = -1;
|
private int endColumnIndex = -1;
|
||||||
|
private OutlineView ov;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Convience reference to internal Outline.
|
* Convience reference to internal Outline.
|
||||||
@ -125,8 +133,8 @@ public class DataResultViewerTable extends AbstractDataResultViewer {
|
|||||||
initComponents();
|
initComponents();
|
||||||
|
|
||||||
outlineView.setAllowedDragActions(DnDConstants.ACTION_NONE);
|
outlineView.setAllowedDragActions(DnDConstants.ACTION_NONE);
|
||||||
outline = outlineView.getOutline();
|
|
||||||
|
|
||||||
|
outline = outlineView.getOutline();
|
||||||
outline.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
|
outline.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
|
||||||
outline.setRootVisible(false); // don't show the root node
|
outline.setRootVisible(false); // don't show the root node
|
||||||
outline.setDragEnabled(false);
|
outline.setDragEnabled(false);
|
||||||
@ -334,7 +342,6 @@ public class DataResultViewerTable extends AbstractDataResultViewer {
|
|||||||
@Override
|
@Override
|
||||||
@ThreadConfined(type = ThreadConfined.ThreadType.AWT)
|
@ThreadConfined(type = ThreadConfined.ThreadType.AWT)
|
||||||
public void setNode(Node selectedNode) {
|
public void setNode(Node selectedNode) {
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The quick filter must be reset because when determining column width,
|
* The quick filter must be reset because when determining column width,
|
||||||
* ETable.getRowCount is called, and the documentation states that quick
|
* ETable.getRowCount is called, and the documentation states that quick
|
||||||
@ -406,14 +413,15 @@ public class DataResultViewerTable extends AbstractDataResultViewer {
|
|||||||
// Get the columns setup with respect to names and sortability
|
// Get the columns setup with respect to names and sortability
|
||||||
String[] propStrings = new String[props.size() * 2];
|
String[] propStrings = new String[props.size() * 2];
|
||||||
for (int i = 0; i < props.size(); i++) {
|
for (int i = 0; i < props.size(); i++) {
|
||||||
props.get(i).setValue("ComparableColumnTTV", Boolean.TRUE); //NON-NLS
|
final Property<?> prop = props.get(i);
|
||||||
|
prop.setValue("ComparableColumnTTV", Boolean.TRUE); //NON-NLS
|
||||||
//First property column is sorted initially
|
//First property column is sorted initially
|
||||||
if (i == 0) {
|
if (i == 0) {
|
||||||
props.get(i).setValue("TreeColumnTTV", Boolean.TRUE); // Identifies special property representing first (tree) column. NON-NLS
|
prop.setValue("TreeColumnTTV", Boolean.TRUE); // Identifies special property representing first (tree) column. NON-NLS
|
||||||
props.get(i).setValue("SortingColumnTTV", Boolean.TRUE); // TreeTableView should be initially sorted by this property column. NON-NLS
|
prop.setValue("SortingColumnTTV", Boolean.TRUE); // TreeTableView should be initially sorted by this property column. NON-NLS
|
||||||
}
|
}
|
||||||
propStrings[2 * i] = props.get(i).getName();
|
propStrings[2 * i] = prop.getName();
|
||||||
propStrings[2 * i + 1] = props.get(i).getDisplayName();
|
propStrings[2 * i + 1] = prop.getDisplayName();
|
||||||
}
|
}
|
||||||
|
|
||||||
outlineView.setPropertyColumns(propStrings);
|
outlineView.setPropertyColumns(propStrings);
|
||||||
@ -474,22 +482,41 @@ public class DataResultViewerTable extends AbstractDataResultViewer {
|
|||||||
final Preferences preferences = NbPreferences.forModule(DataResultViewerTable.class);
|
final Preferences preferences = NbPreferences.forModule(DataResultViewerTable.class);
|
||||||
// Store the current order of the columns into settings
|
// Store the current order of the columns into settings
|
||||||
for (Map.Entry<Integer, Property<?>> entry : propertiesMap.entrySet()) {
|
for (Map.Entry<Integer, Property<?>> entry : propertiesMap.entrySet()) {
|
||||||
preferences.put(getColumnPositionKey(tfn, entry.getValue().getName()), String.valueOf(entry.getKey()));
|
|
||||||
|
preferences.put(getColumnPositionKey(tfn.getColumnOrderKey(), entry.getValue().getName()), String.valueOf(entry.getKey()));
|
||||||
|
}
|
||||||
|
final TableColumnModel columnModel = ov.getOutline().getColumnModel();
|
||||||
|
|
||||||
|
//store the sorting information
|
||||||
|
int numCols = columnModel.getColumnCount();
|
||||||
|
for (int i = 0; i < numCols; i++) {
|
||||||
|
ETableColumn etc = (ETableColumn) columnModel.getColumn(i);
|
||||||
|
String columnName = ov.getOutline().getColumnName(i);
|
||||||
|
if (etc.isSorted()) {
|
||||||
|
preferences.put(getColumnSortOrderKey(tfn.getColumnOrderKey(), columnName), String.valueOf(etc.isAscending()));
|
||||||
|
preferences.put(getColumnSortRankKey(tfn.getColumnOrderKey(), columnName), String.valueOf(etc.getSortRank()));
|
||||||
|
} else {
|
||||||
|
preferences.remove(getColumnSortOrderKey(tfn.getColumnOrderKey(), columnName));
|
||||||
|
preferences.remove(getColumnSortRankKey(tfn.getColumnOrderKey(), columnName));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int numCols = outline.getColumnModel().getColumnCount();
|
static private final class ColumnSortInfo {
|
||||||
for (int i = 0; i < numCols; i++) {
|
|
||||||
ETableColumn etc = (ETableColumn) outline.getColumnModel().getColumn(i);
|
private final int modelIndex;
|
||||||
if (etc.isSorted()) {
|
private final int rank;
|
||||||
preferences.put(getColumnSortOrderKey(tfn, etc.getIdentifier().toString()), String.valueOf(etc.isAscending()));
|
private final boolean order;
|
||||||
preferences.put(getColumnSortRankKey(tfn, etc.getIdentifier().toString()), String.valueOf(etc.getSortRank()));
|
|
||||||
preferences.put(getColumnSortOrderKey(tfn, etc.getIdentifier().toString()), String.valueOf(etc.isAscending()));
|
private ColumnSortInfo(int modelIndex, int rank, boolean order) {
|
||||||
preferences.put(getColumnSortRankKey(tfn, etc.getIdentifier().toString()), String.valueOf(etc.getSortRank()));
|
this.modelIndex = modelIndex;
|
||||||
} else {
|
this.rank = rank;
|
||||||
preferences.remove(getColumnSortOrderKey(tfn, etc.getIdentifier().toString()));
|
this.order = order;
|
||||||
preferences.remove(getColumnSortRankKey(tfn, etc.getIdentifier().toString()));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private int getRank() {
|
||||||
|
return rank;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -502,24 +529,30 @@ public class DataResultViewerTable extends AbstractDataResultViewer {
|
|||||||
final Preferences preferences = NbPreferences.forModule(DataResultViewerTable.class);
|
final Preferences preferences = NbPreferences.forModule(DataResultViewerTable.class);
|
||||||
TableFilterNode tfn = (TableFilterNode) currentRoot;
|
TableFilterNode tfn = (TableFilterNode) currentRoot;
|
||||||
|
|
||||||
Map<Integer, Boolean> orderMap = new TreeMap<>();
|
if (currentRoot instanceof TableFilterNode) {
|
||||||
Map<Integer, Integer> indexMap = new TreeMap<>();
|
final String columnOrderKey = ((TableFilterNode) currentRoot).getColumnOrderKey();
|
||||||
|
|
||||||
propertiesMap.entrySet().forEach((entry) -> {
|
final Preferences preferences = NbPreferences.forModule(DataResultViewerTable.class);
|
||||||
Boolean sortOrder = Boolean.valueOf(preferences.get(getColumnSortOrderKey(tfn, entry.getValue().getName()), "true"));
|
|
||||||
Integer sortRank = Integer.valueOf(preferences.get(getColumnSortRankKey(tfn, entry.getValue().getName()), "0"));
|
|
||||||
//if the sort rank is undefined, it will be defaulted to 0 , unsorted.
|
|
||||||
|
|
||||||
orderMap.put(sortRank, sortOrder);
|
//organize property sorting information, sorted by rank
|
||||||
indexMap.put(sortRank, outline.getColumn(entry.getValue().getName()).getModelIndex());
|
TreeSet<ColumnSortInfo> treeSet = new TreeSet<>(Comparator.comparing(ColumnSortInfo::getRank));
|
||||||
|
propertiesMap.entrySet().stream()
|
||||||
|
.forEach(entry -> {
|
||||||
|
final String propName = entry.getValue().getName();
|
||||||
|
//if the sort rank is undefined, it will be defaulted to 0 => unsorted.
|
||||||
|
Integer sortRank = Integer.valueOf(preferences.get(getColumnSortRankKey(columnOrderKey, propName), "0"));
|
||||||
|
//default to true => ascending
|
||||||
|
Boolean sortOrder = Boolean.valueOf(preferences.get(getColumnSortOrderKey(columnOrderKey, propName), "true"));
|
||||||
|
|
||||||
|
treeSet.add(new ColumnSortInfo(entry.getKey(), sortRank, sortOrder));
|
||||||
});
|
});
|
||||||
|
|
||||||
orderMap.entrySet().forEach((entry) -> {
|
//apply sort information in rank order.
|
||||||
outline.setColumnSorted(indexMap.get(entry.getKey()), orderMap.get(entry.getKey()), entry.getKey());
|
treeSet.forEach(sortInfo -> ov.getOutline().setColumnSorted(sortInfo.modelIndex, sortInfo.order, sortInfo.rank));
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Loads the stored column order from the preference file.
|
* Loads the stored column order from the preference file.
|
||||||
@ -547,8 +580,9 @@ public class DataResultViewerTable extends AbstractDataResultViewer {
|
|||||||
boolean noPreviousSettings = true;
|
boolean noPreviousSettings = true;
|
||||||
|
|
||||||
final Preferences preferences = NbPreferences.forModule(DataResultViewerTable.class);
|
final Preferences preferences = NbPreferences.forModule(DataResultViewerTable.class);
|
||||||
|
|
||||||
for (Property<?> prop : props) {
|
for (Property<?> prop : props) {
|
||||||
Integer value = Integer.valueOf(preferences.get(getColumnPositionKey(tfn, prop.getName()), "-1"));
|
Integer value = Integer.valueOf(preferences.get(getColumnPositionKey(tfn.getColumnOrderKey(), prop.getName()), "-1"));
|
||||||
if (value >= 0 && value < offset && !propertiesMap.containsKey(value)) {
|
if (value >= 0 && value < offset && !propertiesMap.containsKey(value)) {
|
||||||
propertiesMap.put(value, prop);
|
propertiesMap.put(value, prop);
|
||||||
noPreviousSettings = false;
|
noPreviousSettings = false;
|
||||||
@ -574,29 +608,29 @@ public class DataResultViewerTable extends AbstractDataResultViewer {
|
|||||||
* Gets a key for the current node and a property of its child nodes to
|
* Gets a key for the current node and a property of its child nodes to
|
||||||
* store the column position into a preference file.
|
* store the column position into a preference file.
|
||||||
*
|
*
|
||||||
* @param propName Property of the column
|
* @param prop Property of the column
|
||||||
* @param node The current node to use as a base for the property key.
|
* @param type The type of the current node
|
||||||
*
|
*
|
||||||
* @return A generated key for the preference file
|
* @return A generated key for the preference file
|
||||||
*/
|
*/
|
||||||
private String getColumnPositionKey(TableFilterNode node, String propName) {
|
private String getColumnPositionKey(String type, String propName) {
|
||||||
return getColumnKeyBase(node, propName) + ".column"; //NON-NLS
|
return getColumnKeyBase(type, propName) + ".column";
|
||||||
}
|
}
|
||||||
|
|
||||||
private String getColumnSortOrderKey(TableFilterNode node, String propName) {
|
private String getColumnSortOrderKey(String type, String propName) {
|
||||||
return getColumnKeyBase(node, propName) + ".sortOrder";//NON-NLS
|
return getColumnKeyBase(type, propName) + ".sortOrder";
|
||||||
}
|
}
|
||||||
|
|
||||||
private String getColumnSortRankKey(TableFilterNode node, String propName) {
|
private String getColumnSortRankKey(String type, String propName) {
|
||||||
return getColumnKeyBase(node, propName) + ".sortRank";//NON-NLS
|
return getColumnKeyBase(type, propName) + ".sortRank";
|
||||||
}
|
}
|
||||||
|
|
||||||
private static String getColumnKeyBase(TableFilterNode node, String propName) {
|
private static String getColumnKeyBase(String type, String propName) {
|
||||||
return stripNonAlphanumeric(node.getColumnOrderKey()) + "." + stripNonAlphanumeric(propName);
|
return stripNonAlphanumeric(type) + "." + stripNonAlphanumeric(propName);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static String stripNonAlphanumeric(String str) {
|
private static String stripNonAlphanumeric(String str) {
|
||||||
return str.replaceAll("[^a-zA-Z0-9_]", "");//NON-NLS
|
return str.replaceAll("[^a-zA-Z0-9_]", "");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* Autopsy Forensic Browser
|
* Autopsy Forensic Browser
|
||||||
*
|
*
|
||||||
* Copyright 2011 - 2016 Basis Technology Corp.
|
* Copyright 2011 - 2017 Basis Technology Corp.
|
||||||
* Contact: carrier <at> sleuthkit <dot> org
|
* Contact: carrier <at> sleuthkit <dot> org
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
@ -156,6 +156,8 @@ public interface DisplayableItemNodeVisitor<T> {
|
|||||||
|
|
||||||
T visit(EmptyNode.MessageNode emptyNode);
|
T visit(EmptyNode.MessageNode emptyNode);
|
||||||
|
|
||||||
|
T visit(InterestingHits.InterestingItemTypeNode aThis);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Visitor with an implementable default behavior for all types. Override
|
* Visitor with an implementable default behavior for all types. Override
|
||||||
* specific visit types to not use the default behavior.
|
* specific visit types to not use the default behavior.
|
||||||
@ -238,6 +240,11 @@ public interface DisplayableItemNodeVisitor<T> {
|
|||||||
return defaultVisit(ftByMimeTypeEmptyNode);
|
return defaultVisit(ftByMimeTypeEmptyNode);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public T visit(InterestingHits.InterestingItemTypeNode interestingItemTypeNode) {
|
||||||
|
return defaultVisit(interestingItemTypeNode);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public T visit(DeletedContentNode dcn) {
|
public T visit(DeletedContentNode dcn) {
|
||||||
return defaultVisit(dcn);
|
return defaultVisit(dcn);
|
||||||
|
@ -453,7 +453,7 @@ public final class FileTypesByMimeType extends Observable implements AutopsyVisi
|
|||||||
* @return query.toString - portion of SQL query which will follow a
|
* @return query.toString - portion of SQL query which will follow a
|
||||||
* WHERE clause.
|
* WHERE clause.
|
||||||
*/
|
*/
|
||||||
private String createQuery(String mime_type) {
|
private String createQuery(String mimeType) {
|
||||||
StringBuilder query = new StringBuilder();
|
StringBuilder query = new StringBuilder();
|
||||||
query.append("(dir_type = ").append(TskData.TSK_FS_NAME_TYPE_ENUM.REG.getValue()).append(")"); //NON-NLS
|
query.append("(dir_type = ").append(TskData.TSK_FS_NAME_TYPE_ENUM.REG.getValue()).append(")"); //NON-NLS
|
||||||
query.append(" AND (type IN (").append(TskData.TSK_DB_FILES_TYPE_ENUM.FS.ordinal()).append(","); //NON-NLS
|
query.append(" AND (type IN (").append(TskData.TSK_DB_FILES_TYPE_ENUM.FS.ordinal()).append(","); //NON-NLS
|
||||||
@ -466,7 +466,7 @@ public final class FileTypesByMimeType extends Observable implements AutopsyVisi
|
|||||||
if (UserPreferences.hideKnownFilesInViewsTree()) {
|
if (UserPreferences.hideKnownFilesInViewsTree()) {
|
||||||
query.append(" AND (known IS NULL OR known != ").append(TskData.FileKnown.KNOWN.getFileKnownValue()).append(")"); //NON-NLS
|
query.append(" AND (known IS NULL OR known != ").append(TskData.FileKnown.KNOWN.getFileKnownValue()).append(")"); //NON-NLS
|
||||||
}
|
}
|
||||||
query.append(" AND mime_type = '").append(mime_type).append("'"); //NON-NLS
|
query.append(" AND mime_type = '").append(mimeType).append("'"); //NON-NLS
|
||||||
return query.toString();
|
return query.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -379,9 +379,10 @@ public class HashsetHits implements AutopsyVisitableItem {
|
|||||||
|
|
||||||
hashsetResults.getArtifactIds(hashsetName).forEach((id) -> {
|
hashsetResults.getArtifactIds(hashsetName).forEach((id) -> {
|
||||||
try {
|
try {
|
||||||
|
if (!artifactHits.containsKey(id)) {
|
||||||
BlackboardArtifact art = skCase.getBlackboardArtifact(id);
|
BlackboardArtifact art = skCase.getBlackboardArtifact(id);
|
||||||
|
|
||||||
artifactHits.put(id, art);
|
artifactHits.put(id, art);
|
||||||
|
}
|
||||||
list.add(id);
|
list.add(id);
|
||||||
} catch (TskException ex) {
|
} catch (TskException ex) {
|
||||||
logger.log(Level.SEVERE, "TSK Exception occurred", ex); //NON-NLS
|
logger.log(Level.SEVERE, "TSK Exception occurred", ex); //NON-NLS
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* Autopsy Forensic Browser
|
* Autopsy Forensic Browser
|
||||||
*
|
*
|
||||||
* Copyright 2011-2015 Basis Technology Corp.
|
* Copyright 2011-2017 Basis Technology Corp.
|
||||||
* Contact: carrier <at> sleuthkit <dot> org
|
* Contact: carrier <at> sleuthkit <dot> org
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
@ -66,7 +66,7 @@ public class InterestingHits implements AutopsyVisitableItem {
|
|||||||
private class InterestingResults extends Observable {
|
private class InterestingResults extends Observable {
|
||||||
|
|
||||||
// NOTE: the map can be accessed by multiple worker threads and needs to be synchronized
|
// NOTE: the map can be accessed by multiple worker threads and needs to be synchronized
|
||||||
private final Map<String, Set<Long>> interestingItemsMap = new LinkedHashMap<>();
|
private final Map<String, Map<String, Set<Long>>> interestingItemsMap = new LinkedHashMap<>();
|
||||||
|
|
||||||
public List<String> getSetNames() {
|
public List<String> getSetNames() {
|
||||||
List<String> setNames;
|
List<String> setNames;
|
||||||
@ -77,9 +77,9 @@ public class InterestingHits implements AutopsyVisitableItem {
|
|||||||
return setNames;
|
return setNames;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Set<Long> getArtifactIds(String setName) {
|
public Set<Long> getArtifactIds(String setName, String typeName) {
|
||||||
synchronized (interestingItemsMap) {
|
synchronized (interestingItemsMap) {
|
||||||
return interestingItemsMap.get(setName);
|
return interestingItemsMap.get(setName).get(typeName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -118,9 +118,11 @@ public class InterestingHits implements AutopsyVisitableItem {
|
|||||||
String value = resultSet.getString("value_text"); //NON-NLS
|
String value = resultSet.getString("value_text"); //NON-NLS
|
||||||
long artifactId = resultSet.getLong("artifact_id"); //NON-NLS
|
long artifactId = resultSet.getLong("artifact_id"); //NON-NLS
|
||||||
if (!interestingItemsMap.containsKey(value)) {
|
if (!interestingItemsMap.containsKey(value)) {
|
||||||
interestingItemsMap.put(value, new HashSet<>());
|
interestingItemsMap.put(value, new LinkedHashMap<>());
|
||||||
|
interestingItemsMap.get(value).put(BlackboardArtifact.ARTIFACT_TYPE.TSK_INTERESTING_FILE_HIT.getDisplayName(), new HashSet<>());
|
||||||
|
interestingItemsMap.get(value).put(BlackboardArtifact.ARTIFACT_TYPE.TSK_INTERESTING_ARTIFACT_HIT.getDisplayName(), new HashSet<>());
|
||||||
}
|
}
|
||||||
interestingItemsMap.get(value).add(artifactId);
|
interestingItemsMap.get(value).get(artType.getDisplayName()).add(artifactId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (TskCoreException | SQLException ex) {
|
} catch (TskCoreException | SQLException ex) {
|
||||||
@ -280,7 +282,7 @@ public class InterestingHits implements AutopsyVisitableItem {
|
|||||||
private final String setName;
|
private final String setName;
|
||||||
|
|
||||||
public SetNameNode(String setName) {//, Set<Long> children) {
|
public SetNameNode(String setName) {//, Set<Long> children) {
|
||||||
super(Children.create(new HitFactory(setName), true), Lookups.singleton(setName));
|
super(Children.create(new HitTypeFactory(setName), true), Lookups.singleton(setName));
|
||||||
this.setName = setName;
|
this.setName = setName;
|
||||||
super.setName(setName);
|
super.setName(setName);
|
||||||
updateDisplayName();
|
updateDisplayName();
|
||||||
@ -289,12 +291,14 @@ public class InterestingHits implements AutopsyVisitableItem {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void updateDisplayName() {
|
private void updateDisplayName() {
|
||||||
super.setDisplayName(setName + " (" + interestingResults.getArtifactIds(setName).size() + ")");
|
int sizeOfSet = interestingResults.getArtifactIds(setName, BlackboardArtifact.ARTIFACT_TYPE.TSK_INTERESTING_ARTIFACT_HIT.getDisplayName()).size()
|
||||||
|
+ interestingResults.getArtifactIds(setName, BlackboardArtifact.ARTIFACT_TYPE.TSK_INTERESTING_FILE_HIT.getDisplayName()).size();
|
||||||
|
super.setDisplayName(setName + " (" + sizeOfSet + ")");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isLeafTypeNode() {
|
public boolean isLeafTypeNode() {
|
||||||
return true;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -334,14 +338,104 @@ public class InterestingHits implements AutopsyVisitableItem {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private class HitTypeFactory extends ChildFactory<String> implements Observer {
|
||||||
|
|
||||||
|
private final String setName;
|
||||||
|
private final Map<Long, BlackboardArtifact> artifactHits = new HashMap<>();
|
||||||
|
|
||||||
|
private HitTypeFactory(String setName) {
|
||||||
|
super();
|
||||||
|
this.setName = setName;
|
||||||
|
interestingResults.addObserver(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected boolean createKeys(List<String> list) {
|
||||||
|
list.add(BlackboardArtifact.ARTIFACT_TYPE.TSK_INTERESTING_FILE_HIT.getDisplayName());
|
||||||
|
list.add(BlackboardArtifact.ARTIFACT_TYPE.TSK_INTERESTING_ARTIFACT_HIT.getDisplayName());
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Node createNodeForKey(String key) {
|
||||||
|
return new InterestingItemTypeNode(setName, key);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void update(Observable o, Object arg) {
|
||||||
|
refresh(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class InterestingItemTypeNode extends DisplayableItemNode implements Observer {
|
||||||
|
|
||||||
|
private final String typeName;
|
||||||
|
private final String setName;
|
||||||
|
|
||||||
|
private InterestingItemTypeNode(String setName, String typeName) {
|
||||||
|
super(Children.create(new HitFactory(setName, typeName), true), Lookups.singleton(setName));
|
||||||
|
this.typeName = typeName;
|
||||||
|
this.setName = setName;
|
||||||
|
super.setName(typeName);
|
||||||
|
updateDisplayName();
|
||||||
|
this.setIconBaseWithExtension("org/sleuthkit/autopsy/images/interesting_item.png"); //NON-NLS
|
||||||
|
interestingResults.addObserver(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void updateDisplayName() {
|
||||||
|
super.setDisplayName(typeName + " (" + interestingResults.getArtifactIds(setName, typeName).size() + ")");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isLeafTypeNode() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Sheet createSheet() {
|
||||||
|
Sheet s = super.createSheet();
|
||||||
|
Sheet.Set ss = s.get(Sheet.PROPERTIES);
|
||||||
|
if (ss == null) {
|
||||||
|
ss = Sheet.createPropertiesSet();
|
||||||
|
s.put(ss);
|
||||||
|
}
|
||||||
|
ss.put(new NodeProperty<>(NbBundle.getMessage(this.getClass(), "InterestingHits.createSheet.name.name"),
|
||||||
|
NbBundle.getMessage(this.getClass(), "InterestingHits.createSheet.name.name"),
|
||||||
|
NbBundle.getMessage(this.getClass(), "InterestingHits.createSheet.name.desc"),
|
||||||
|
getName()));
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public <T> T accept(DisplayableItemNodeVisitor<T> v) {
|
||||||
|
return v.visit(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void update(Observable o, Object arg) {
|
||||||
|
updateDisplayName();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getItemType() {
|
||||||
|
/**
|
||||||
|
* For custom settings for each rule set, return
|
||||||
|
* getClass().getName() + setName instead.
|
||||||
|
*/
|
||||||
|
return getClass().getName();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private class HitFactory extends ChildFactory<Long> implements Observer {
|
private class HitFactory extends ChildFactory<Long> implements Observer {
|
||||||
|
|
||||||
private final String setName;
|
private final String setName;
|
||||||
private Map<Long, BlackboardArtifact> artifactHits = new HashMap<>();
|
private final String typeName;
|
||||||
|
private final Map<Long, BlackboardArtifact> artifactHits = new HashMap<>();
|
||||||
|
|
||||||
private HitFactory(String setName) {
|
private HitFactory(String setName, String typeName) {
|
||||||
super();
|
super();
|
||||||
this.setName = setName;
|
this.setName = setName;
|
||||||
|
this.typeName = typeName;
|
||||||
interestingResults.addObserver(this);
|
interestingResults.addObserver(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -352,11 +446,12 @@ public class InterestingHits implements AutopsyVisitableItem {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
interestingResults.getArtifactIds(setName).forEach((id) -> {
|
interestingResults.getArtifactIds(setName, typeName).forEach((id) -> {
|
||||||
try {
|
try {
|
||||||
|
if (!artifactHits.containsKey(id)) {
|
||||||
BlackboardArtifact art = skCase.getBlackboardArtifact(id);
|
BlackboardArtifact art = skCase.getBlackboardArtifact(id);
|
||||||
|
|
||||||
artifactHits.put(id, art);
|
artifactHits.put(id, art);
|
||||||
|
}
|
||||||
list.add(id);
|
list.add(id);
|
||||||
} catch (TskCoreException ex) {
|
} catch (TskCoreException ex) {
|
||||||
logger.log(Level.SEVERE, "TSK Exception occurred", ex); //NON-NLS
|
logger.log(Level.SEVERE, "TSK Exception occurred", ex); //NON-NLS
|
||||||
|
@ -707,14 +707,17 @@ public class KeywordHits implements AutopsyVisitableItem {
|
|||||||
if ((instances.size() == 1) && (instances.get(0).equals(DEFAULT_INSTANCE_NAME))) {
|
if ((instances.size() == 1) && (instances.get(0).equals(DEFAULT_INSTANCE_NAME))) {
|
||||||
for (Long id : keywordResults.getArtifactIds(setName, keyword, DEFAULT_INSTANCE_NAME) ) {
|
for (Long id : keywordResults.getArtifactIds(setName, keyword, DEFAULT_INSTANCE_NAME) ) {
|
||||||
RegExpInstanceKey key = new RegExpInstanceKey(id);
|
RegExpInstanceKey key = new RegExpInstanceKey(id);
|
||||||
|
if (!nodesMap.containsKey(key)) {
|
||||||
nodesMap.put(key, createNode(key));
|
nodesMap.put(key, createNode(key));
|
||||||
|
}
|
||||||
list.add(key);
|
list.add(key);
|
||||||
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
for (String instance : instances) {
|
for (String instance : instances) {
|
||||||
RegExpInstanceKey key = new RegExpInstanceKey(instance);
|
RegExpInstanceKey key = new RegExpInstanceKey(instance);
|
||||||
|
if (!nodesMap.containsKey(key)) {
|
||||||
nodesMap.put(key, createNode(key));
|
nodesMap.put(key, createNode(key));
|
||||||
|
}
|
||||||
list.add(key);
|
list.add(key);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -897,9 +900,10 @@ public class KeywordHits implements AutopsyVisitableItem {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected boolean createKeys(List<Long> list) {
|
protected boolean createKeys(List<Long> list) {
|
||||||
list.addAll(keywordResults.getArtifactIds(setName, keyword, instance));
|
|
||||||
for (Long id : keywordResults.getArtifactIds(setName, keyword, instance) ) {
|
for (Long id : keywordResults.getArtifactIds(setName, keyword, instance) ) {
|
||||||
|
if (!nodesMap.containsKey(id)) {
|
||||||
nodesMap.put(id, createBlackboardArtifactNode(id));
|
nodesMap.put(id, createBlackboardArtifactNode(id));
|
||||||
|
}
|
||||||
list.add(id);
|
list.add(id);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
@ -16,7 +16,7 @@
|
|||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
package org.sleuthkit.autopsy.framework;
|
package org.sleuthkit.autopsy.datasourceprocessors;
|
||||||
|
|
||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
import org.sleuthkit.autopsy.corecomponentinterfaces.DataSourceProcessor;
|
import org.sleuthkit.autopsy.corecomponentinterfaces.DataSourceProcessor;
|
@ -28,26 +28,27 @@ import org.sleuthkit.autopsy.corecomponentinterfaces.DataSourceProcessor;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* A Raw data source processor that implements the DataSourceProcessor service
|
* A Raw data source processor that implements the DataSourceProcessor service
|
||||||
* provider interface to allow integration with the add data source wizard.
|
* provider interface to allow integration with the add data source wizard. It
|
||||||
* It also provides a run method overload to allow it to be used independently
|
* also provides a run method overload to allow it to be used independently of
|
||||||
* of the wizard.
|
* the wizard.
|
||||||
*/
|
*/
|
||||||
@ServiceProvider(service = DataSourceProcessor.class)
|
@ServiceProvider(service = DataSourceProcessor.class)
|
||||||
public class RawDSProcessor implements DataSourceProcessor {
|
public class RawDSProcessor implements DataSourceProcessor {
|
||||||
|
|
||||||
private final RawDSInputPanel configPanel;
|
private final RawDSInputPanel configPanel;
|
||||||
private AddRawImageTask addImageTask;
|
private AddRawImageTask addImageTask;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Constructs a Raw data source processor that implements the
|
* Constructs a Raw data source processor that implements the
|
||||||
* DataSourceProcessor service provider interface to allow integration
|
* DataSourceProcessor service provider interface to allow integration with
|
||||||
* with the add data source wizard. It also provides a run method
|
* the add data source wizard. It also provides a run method overload to
|
||||||
* overload to allow it to be used independently of the wizard.
|
* allow it to be used independently of the wizard.
|
||||||
*/
|
*/
|
||||||
public RawDSProcessor() {
|
public RawDSProcessor() {
|
||||||
configPanel = RawDSInputPanel.createInstance(RawDSProcessor.class.getName());
|
configPanel = RawDSInputPanel.createInstance(RawDSProcessor.class.getName());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets a string that describes the type of data sources this processor is
|
* Gets a string that describes the type of data sources this processor is
|
||||||
* able to add to the case database. The string is suitable for display in a
|
* able to add to the case database. The string is suitable for display in a
|
||||||
* type selection UI component (e.g., a combo box).
|
* type selection UI component (e.g., a combo box).
|
||||||
@ -119,28 +120,32 @@ public class RawDSProcessor implements DataSourceProcessor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Adds a data source to the case database using a background task in a
|
* Adds a "raw" data source to the case database using a background task in
|
||||||
* separate thread and the given settings instead of those provided by the
|
* a separate thread and the given settings instead of those provided by the
|
||||||
* selection and configuration panel. Returns as soon as the background task
|
* selection and configuration panel. Returns as soon as the background task
|
||||||
* is started and uses the callback object to signal task completion and
|
* is started and uses the callback object to signal task completion and
|
||||||
* return results.
|
* return results.
|
||||||
*
|
*
|
||||||
* @param deviceId An ASCII-printable identifier for the
|
* @param deviceId An ASCII-printable identifier for the device
|
||||||
* device associated with the data source
|
* associated with the data source that is
|
||||||
* that is intended to be unique across
|
* intended to be unique across multiple cases
|
||||||
* multiple cases (e.g., a UUID).
|
* (e.g., a UUID).
|
||||||
* @param rawDSInputFilePath Path to a Raw data source file.
|
* @param imageFilePath Path to the image file.
|
||||||
* @param isHandsetFile Indicates whether the XML file is for a
|
* @param timeZone The time zone to use when processing dates
|
||||||
* handset or a SIM.
|
* and times for the image, obtained from
|
||||||
|
* java.util.TimeZone.getID.
|
||||||
|
* @param chunkSize The maximum size of each chunk of the raw
|
||||||
|
* data source as it is divided up into virtual
|
||||||
|
* unallocated space files.
|
||||||
* @param progressMonitor Progress monitor for reporting progress
|
* @param progressMonitor Progress monitor for reporting progress
|
||||||
* during processing.
|
* during processing.
|
||||||
|
* @param callback Callback to call when processing is done.
|
||||||
*/
|
*/
|
||||||
private void run(String deviceId, String imageFilePath, String timeZone, long chunkSize, DataSourceProcessorProgressMonitor progressMonitor, DataSourceProcessorCallback callback) {
|
private void run(String deviceId, String imageFilePath, String timeZone, long chunkSize, DataSourceProcessorProgressMonitor progressMonitor, DataSourceProcessorCallback callback) {
|
||||||
addImageTask = new AddRawImageTask(deviceId, imageFilePath, timeZone, chunkSize, progressMonitor, callback);
|
addImageTask = new AddRawImageTask(deviceId, imageFilePath, timeZone, chunkSize, progressMonitor, callback);
|
||||||
new Thread(addImageTask).start();
|
new Thread(addImageTask).start();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void cancel() {
|
public void cancel() {
|
||||||
}
|
}
|
||||||
|
@ -71,8 +71,9 @@ import org.sleuthkit.datamodel.TskException;
|
|||||||
import org.sleuthkit.datamodel.VirtualDirectory;
|
import org.sleuthkit.datamodel.VirtualDirectory;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This class wraps nodes as they are passed to the DataResult viewers. It
|
* A node used to wrap another node before passing it to the result viewers. The
|
||||||
* defines the actions that the node should have.
|
* wrapper node defines the actions associated with the wrapped node and may
|
||||||
|
* filter out some of its children.
|
||||||
*/
|
*/
|
||||||
public class DataResultFilterNode extends FilterNode {
|
public class DataResultFilterNode extends FilterNode {
|
||||||
|
|
||||||
@ -111,20 +112,31 @@ public class DataResultFilterNode extends FilterNode {
|
|||||||
private final ExplorerManager sourceEm;
|
private final ExplorerManager sourceEm;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* Constructs a node used to wrap another node before passing it to the
|
||||||
|
* result viewers. The wrapper node defines the actions associated with the
|
||||||
|
* wrapped node and may filter out some of its children.
|
||||||
*
|
*
|
||||||
* @param node Root node to be passed to DataResult viewers
|
* @param node The node to wrap.
|
||||||
* @param em ExplorerManager for component that is creating the node
|
* @param em The ExplorerManager for the component that is creating the
|
||||||
|
* node.
|
||||||
*/
|
*/
|
||||||
public DataResultFilterNode(Node node, ExplorerManager em) {
|
public DataResultFilterNode(Node node, ExplorerManager em) {
|
||||||
super(node, new DataResultFilterChildren(node, em));
|
super(node, new DataResultFilterChildren(node, em));
|
||||||
this.sourceEm = em;
|
this.sourceEm = em;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* Constructs a node used to wrap another node before passing it to the
|
||||||
|
* result viewers. The wrapper node defines the actions associated with the
|
||||||
|
* wrapped node and may filter out some of its children.
|
||||||
*
|
*
|
||||||
* @param node Root node to be passed to DataResult viewers
|
* @param node The node to wrap.
|
||||||
* @param em ExplorerManager for component that is creating the node
|
* @param em The ExplorerManager for the component that is creating
|
||||||
|
* the node.
|
||||||
|
* @param filterKnown Whether or not to filter out children that represent
|
||||||
|
* known files.
|
||||||
|
* @param filterSlack Whether or not to filter out children that represent
|
||||||
|
* virtual slack space files.
|
||||||
*/
|
*/
|
||||||
private DataResultFilterNode(Node node, ExplorerManager em, boolean filterKnown, boolean filterSlack) {
|
private DataResultFilterNode(Node node, ExplorerManager em, boolean filterKnown, boolean filterSlack) {
|
||||||
super(node, new DataResultFilterChildren(node, em, filterKnown, filterSlack));
|
super(node, new DataResultFilterChildren(node, em, filterKnown, filterSlack));
|
||||||
@ -326,9 +338,9 @@ public class DataResultFilterNode extends FilterNode {
|
|||||||
actionsList.add(AddContentTagAction.getInstance());
|
actionsList.add(AddContentTagAction.getInstance());
|
||||||
actionsList.add(AddBlackboardArtifactTagAction.getInstance());
|
actionsList.add(AddBlackboardArtifactTagAction.getInstance());
|
||||||
|
|
||||||
final Collection<AbstractFile> selectedFilesList =
|
final Collection<AbstractFile> selectedFilesList
|
||||||
new HashSet<>(Utilities.actionsGlobalContext().lookupAll(AbstractFile.class));
|
= new HashSet<>(Utilities.actionsGlobalContext().lookupAll(AbstractFile.class));
|
||||||
if(selectedFilesList.size() == 1) {
|
if (selectedFilesList.size() == 1) {
|
||||||
actionsList.add(DeleteFileContentTagAction.getInstance());
|
actionsList.add(DeleteFileContentTagAction.getInstance());
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -338,13 +350,13 @@ public class DataResultFilterNode extends FilterNode {
|
|||||||
actionsList.add(AddBlackboardArtifactTagAction.getInstance());
|
actionsList.add(AddBlackboardArtifactTagAction.getInstance());
|
||||||
}
|
}
|
||||||
|
|
||||||
final Collection<BlackboardArtifact> selectedArtifactsList =
|
final Collection<BlackboardArtifact> selectedArtifactsList
|
||||||
new HashSet<>(Utilities.actionsGlobalContext().lookupAll(BlackboardArtifact.class));
|
= new HashSet<>(Utilities.actionsGlobalContext().lookupAll(BlackboardArtifact.class));
|
||||||
if(selectedArtifactsList.size() == 1) {
|
if (selectedArtifactsList.size() == 1) {
|
||||||
actionsList.add(DeleteFileBlackboardArtifactTagAction.getInstance());
|
actionsList.add(DeleteFileBlackboardArtifactTagAction.getInstance());
|
||||||
}
|
}
|
||||||
|
|
||||||
if(n != null) {
|
if (n != null) {
|
||||||
actionsList.addAll(ContextMenuExtensionPoint.getActions());
|
actionsList.addAll(ContextMenuExtensionPoint.getActions());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -362,7 +374,6 @@ public class DataResultFilterNode extends FilterNode {
|
|||||||
return defaultVisit(fileTypes);
|
return defaultVisit(fileTypes);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected List<Action> defaultVisit(DisplayableItemNode ditem) {
|
protected List<Action> defaultVisit(DisplayableItemNode ditem) {
|
||||||
//preserve the default node's actions
|
//preserve the default node's actions
|
||||||
@ -460,8 +471,6 @@ public class DataResultFilterNode extends FilterNode {
|
|||||||
return openChild(fileTypes);
|
return openChild(fileTypes);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tell the originating ExplorerManager to display the given
|
* Tell the originating ExplorerManager to display the given
|
||||||
* dataModelNode.
|
* dataModelNode.
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* Autopsy Forensic Browser
|
* Autopsy Forensic Browser
|
||||||
*
|
*
|
||||||
* Copyright 2011 Basis Technology Corp.
|
* Copyright 2011-2017 Basis Technology Corp.
|
||||||
* Contact: carrier <at> sleuthkit <dot> org
|
* Contact: carrier <at> sleuthkit <dot> org
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
@ -56,15 +56,15 @@ import org.sleuthkit.datamodel.VolumeSystem;
|
|||||||
* the DataResultViewer. 3. Waits for all the Children to be contentNode in the
|
* the DataResultViewer. 3. Waits for all the Children to be contentNode in the
|
||||||
* DataResultViewer and selects the Node that represents the Content.
|
* DataResultViewer and selects the Node that represents the Content.
|
||||||
*/
|
*/
|
||||||
public class ViewContextAction extends AbstractAction {
|
public final class ViewContextAction extends AbstractAction {
|
||||||
|
|
||||||
private Content content;
|
private static final long serialVersionUID = 1L;
|
||||||
private static final Logger logger = Logger.getLogger(ViewContextAction.class.getName());
|
private static final Logger logger = Logger.getLogger(ViewContextAction.class.getName());
|
||||||
|
private Content content;
|
||||||
|
|
||||||
public ViewContextAction(String title, BlackboardArtifactNode node) {
|
public ViewContextAction(String title, BlackboardArtifactNode node) {
|
||||||
super(title);
|
super(title);
|
||||||
this.content = node.getLookup().lookup(Content.class);
|
this.content = node.getLookup().lookup(Content.class);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public ViewContextAction(String title, AbstractFsContentNode<? extends AbstractFile> node) {
|
public ViewContextAction(String title, AbstractFsContentNode<? extends AbstractFile> node) {
|
||||||
@ -79,9 +79,7 @@ public class ViewContextAction extends AbstractAction {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void actionPerformed(ActionEvent e) {
|
public void actionPerformed(ActionEvent e) {
|
||||||
EventQueue.invokeLater(new Runnable() {
|
EventQueue.invokeLater(() -> {
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
// create a list of Content objects starting with content's
|
// create a list of Content objects starting with content's
|
||||||
// Image and ends with content
|
// Image and ends with content
|
||||||
ReverseHierarchyVisitor vtor = new ReverseHierarchyVisitor();
|
ReverseHierarchyVisitor vtor = new ReverseHierarchyVisitor();
|
||||||
@ -125,17 +123,24 @@ public class ViewContextAction extends AbstractAction {
|
|||||||
logger.log(Level.WARNING, "Couldn't set selected node", ex); //NON-NLS
|
logger.log(Level.WARNING, "Couldn't set selected node", ex); //NON-NLS
|
||||||
}
|
}
|
||||||
|
|
||||||
EventQueue.invokeLater(new Runnable() {
|
EventQueue.invokeLater(() -> {
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
DataResultTopComponent dataResultTC = dirTree.getDirectoryListing();
|
DataResultTopComponent dataResultTC = dirTree.getDirectoryListing();
|
||||||
Node currentRootNodeOfDataResultTC = dataResultTC.getRootNode();
|
Node currentRootNodeOfDataResultTC = dataResultTC.getRootNode();
|
||||||
Node contentNode = content.accept(new RootContentChildren.CreateSleuthkitNodeVisitor());
|
Node contentNode = content.accept(new RootContentChildren.CreateSleuthkitNodeVisitor());
|
||||||
new SelectionWorker(dataResultTC, contentNode.getName(), currentRootNodeOfDataResultTC).execute();
|
new SelectionWorker(dataResultTC, contentNode.getName(), currentRootNodeOfDataResultTC).execute();
|
||||||
}
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
|
||||||
|
@Override
|
||||||
|
public Object clone() throws CloneNotSupportedException {
|
||||||
|
ViewContextAction clone = (ViewContextAction)super.clone();
|
||||||
|
clone.setContent(this.content);
|
||||||
|
return clone;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setContent(Content content) {
|
||||||
|
this.content = content;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -215,14 +220,14 @@ public class ViewContextAction extends AbstractAction {
|
|||||||
*/
|
*/
|
||||||
private class ReverseHierarchyVisitor extends ContentVisitor.Default<List<Content>> {
|
private class ReverseHierarchyVisitor extends ContentVisitor.Default<List<Content>> {
|
||||||
|
|
||||||
List<Content> ret = new ArrayList<Content>();
|
List<Content> ret = new ArrayList<>();
|
||||||
|
|
||||||
private List<Content> visitParentButDontAddMe(Content content) {
|
private List<Content> visitParentButDontAddMe(Content content) {
|
||||||
Content parent = null;
|
Content parent = null;
|
||||||
try {
|
try {
|
||||||
parent = content.getParent();
|
parent = content.getParent();
|
||||||
} catch (TskCoreException ex) {
|
} catch (TskCoreException ex) {
|
||||||
logger.log(Level.WARNING, "Couldn't get parent of Content object: " + content); //NON-NLS
|
logger.log(Level.WARNING, "Could not get parent of Content object: {0}", content); //NON-NLS
|
||||||
}
|
}
|
||||||
return parent == null ? ret : parent.accept(this);
|
return parent == null ? ret : parent.accept(this);
|
||||||
}
|
}
|
||||||
@ -234,7 +239,7 @@ public class ViewContextAction extends AbstractAction {
|
|||||||
try {
|
try {
|
||||||
parent = content.getParent();
|
parent = content.getParent();
|
||||||
} catch (TskCoreException ex) {
|
} catch (TskCoreException ex) {
|
||||||
logger.log(Level.WARNING, "Couldn't get parent of Content object: " + content); //NON-NLS
|
logger.log(Level.WARNING, "Could not get parent of Content object: {0}", content); //NON-NLS
|
||||||
}
|
}
|
||||||
return parent == null ? ret : parent.accept(this);
|
return parent == null ? ret : parent.accept(this);
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* Autopsy Forensic Browser
|
* Autopsy Forensic Browser
|
||||||
*
|
*
|
||||||
* Copyright 2011-2016 Basis Technology Corp.
|
* Copyright 2011-2017 Basis Technology Corp.
|
||||||
* Contact: carrier <at> sleuthkit <dot> org
|
* Contact: carrier <at> sleuthkit <dot> org
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
@ -25,19 +25,15 @@ import org.openide.DialogDisplayer;
|
|||||||
import org.openide.NotifyDescriptor;
|
import org.openide.NotifyDescriptor;
|
||||||
import org.openide.util.NbBundle;
|
import org.openide.util.NbBundle;
|
||||||
import org.openide.util.lookup.ServiceProvider;
|
import org.openide.util.lookup.ServiceProvider;
|
||||||
import org.openide.util.lookup.ServiceProviders;
|
import org.sleuthkit.autopsy.appservices.AutopsyService;
|
||||||
import org.sleuthkit.autopsy.casemodule.Case;
|
|
||||||
import org.sleuthkit.autopsy.framework.AutopsyService;
|
|
||||||
|
|
||||||
@ServiceProviders(value = {@ServiceProvider(service = AutopsyService.class)})
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates and handles closing of ImageWriter objects.
|
* Creates and handles closing of ImageWriter objects. Currently, ImageWriter is
|
||||||
* Currently, ImageWriter is only enabled for local disks, and local disks can
|
* only enabled for local disks, and local disks can not be processed in multi
|
||||||
* not be processed in multi user mode. If ImageWriter is ever enabled for multi user
|
* user mode. If ImageWriter is ever enabled for multi user cases this code will
|
||||||
* cases this code will need to be revised.
|
* need to be revised.
|
||||||
*/
|
*/
|
||||||
|
@ServiceProvider(service = AutopsyService.class)
|
||||||
public class ImageWriterService implements AutopsyService {
|
public class ImageWriterService implements AutopsyService {
|
||||||
|
|
||||||
private static final List<ImageWriter> imageWriters = new ArrayList<>(); // Contains all Image Writer objects
|
private static final List<ImageWriter> imageWriters = new ArrayList<>(); // Contains all Image Writer objects
|
||||||
@ -45,14 +41,16 @@ public class ImageWriterService implements AutopsyService {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Create an image writer object for the given data source ID.
|
* Create an image writer object for the given data source ID.
|
||||||
* @param imageId ID for the image
|
*
|
||||||
|
* @param imageId ID for the image.
|
||||||
|
* @param settings Image writer settings to be used when writing the image.
|
||||||
*/
|
*/
|
||||||
public static void createImageWriter(Long imageId, ImageWriterSettings settings){
|
public static void createImageWriter(Long imageId, ImageWriterSettings settings) {
|
||||||
|
|
||||||
// ImageWriter objects are created during the addImageTask. They can not arrive while
|
// ImageWriter objects are created during the addImageTask. They can not arrive while
|
||||||
// we're closing case resources so we don't need to worry about one showing up while
|
// we're closing case resources so we don't need to worry about one showing up while
|
||||||
// doing our close/cleanup.
|
// doing our close/cleanup.
|
||||||
synchronized(imageWritersLock){
|
synchronized (imageWritersLock) {
|
||||||
ImageWriter writer = new ImageWriter(imageId, settings);
|
ImageWriter writer = new ImageWriter(imageId, settings);
|
||||||
writer.subscribeToEvents();
|
writer.subscribeToEvents();
|
||||||
imageWriters.add(writer);
|
imageWriters.add(writer);
|
||||||
@ -66,28 +64,32 @@ public class ImageWriterService implements AutopsyService {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void closeCaseResources(CaseContext context) throws AutopsyServiceException {
|
public void closeCaseResources(CaseContext context) throws AutopsyServiceException {
|
||||||
|
synchronized (imageWritersLock) {
|
||||||
|
if (imageWriters.isEmpty()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
context.getProgressIndicator().progress(NbBundle.getMessage(this.getClass(), "ImageWriterService.waitingForVHDs"));
|
context.getProgressIndicator().progress(NbBundle.getMessage(this.getClass(), "ImageWriterService.waitingForVHDs"));
|
||||||
|
|
||||||
synchronized(imageWritersLock){
|
|
||||||
// If any of our ImageWriter objects haven't started the finish task, set the cancel flag
|
// If any of our ImageWriter objects haven't started the finish task, set the cancel flag
|
||||||
// to make sure they don't start now. The reason they haven't started is that
|
// to make sure they don't start now. The reason they haven't started is that
|
||||||
// ingest was not complete, and the user already confirmed that they want to exit
|
// ingest was not complete, and the user already confirmed that they want to exit
|
||||||
// even though ingest is not complete so we will take that to mean that they
|
// even though ingest is not complete so we will take that to mean that they
|
||||||
// also don't want to wait for Image Writer.
|
// also don't want to wait for Image Writer.
|
||||||
for(ImageWriter writer: imageWriters){
|
for (ImageWriter writer : imageWriters) {
|
||||||
writer.cancelIfNotStarted();
|
writer.cancelIfNotStarted();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Test whether any finishImage tasks are in progress
|
// Test whether any finishImage tasks are in progress
|
||||||
boolean jobsAreInProgress = false;
|
boolean jobsAreInProgress = false;
|
||||||
for(ImageWriter writer: imageWriters){
|
for (ImageWriter writer : imageWriters) {
|
||||||
if(writer.jobIsInProgress()){
|
if (writer.jobIsInProgress()) {
|
||||||
jobsAreInProgress = true;
|
jobsAreInProgress = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(jobsAreInProgress){
|
if (jobsAreInProgress) {
|
||||||
// If jobs are in progress, ask the user if they want to wait for them to complete
|
// If jobs are in progress, ask the user if they want to wait for them to complete
|
||||||
NotifyDescriptor descriptor = new NotifyDescriptor.Confirmation(
|
NotifyDescriptor descriptor = new NotifyDescriptor.Confirmation(
|
||||||
NbBundle.getMessage(this.getClass(), "ImageWriterService.shouldWait"),
|
NbBundle.getMessage(this.getClass(), "ImageWriterService.shouldWait"),
|
||||||
@ -97,23 +99,23 @@ public class ImageWriterService implements AutopsyService {
|
|||||||
descriptor.setValue(NotifyDescriptor.NO_OPTION);
|
descriptor.setValue(NotifyDescriptor.NO_OPTION);
|
||||||
Object response = DialogDisplayer.getDefault().notify(descriptor);
|
Object response = DialogDisplayer.getDefault().notify(descriptor);
|
||||||
|
|
||||||
if(response == DialogDescriptor.NO_OPTION){
|
if (response == DialogDescriptor.NO_OPTION) {
|
||||||
// Cancel all the jobs
|
// Cancel all the jobs
|
||||||
for(ImageWriter writer: imageWriters){
|
for (ImageWriter writer : imageWriters) {
|
||||||
writer.cancelJob();
|
writer.cancelJob();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Wait for all finishImage jobs to complete. If the jobs got cancelled
|
// Wait for all finishImage jobs to complete. If the jobs got cancelled
|
||||||
// this will be very fast.
|
// this will be very fast.
|
||||||
for(ImageWriter writer: imageWriters){
|
for (ImageWriter writer : imageWriters) {
|
||||||
writer.waitForJobToFinish();
|
writer.waitForJobToFinish();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Stop listening for events
|
// Stop listening for events
|
||||||
for(ImageWriter writer: imageWriters){
|
for (ImageWriter writer : imageWriters) {
|
||||||
writer.unsubscribeFromEvents();
|
writer.unsubscribeFromEvents();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -393,6 +393,9 @@ public class IngestJobSettings {
|
|||||||
/**
|
/**
|
||||||
* Gets the module names for a given key within these ingest job settings.
|
* Gets the module names for a given key within these ingest job settings.
|
||||||
*
|
*
|
||||||
|
* @param context The identifier for the context for which to get the
|
||||||
|
* module names, e.g., the Add Data Source wizard or
|
||||||
|
* Run Ingest Modules context.
|
||||||
* @param key The key string.
|
* @param key The key string.
|
||||||
* @param defaultSetting The default list of module names.
|
* @param defaultSetting The default list of module names.
|
||||||
*
|
*
|
||||||
|
@ -138,9 +138,6 @@ public class IngestOptionsPanel extends IngestModuleGlobalSettingsPanel implemen
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @inheritDoc
|
|
||||||
*/
|
|
||||||
@Override
|
@Override
|
||||||
public void addPropertyChangeListener(PropertyChangeListener l) {
|
public void addPropertyChangeListener(PropertyChangeListener l) {
|
||||||
filterPanel.addPropertyChangeListener(l);
|
filterPanel.addPropertyChangeListener(l);
|
||||||
@ -148,9 +145,6 @@ public class IngestOptionsPanel extends IngestModuleGlobalSettingsPanel implemen
|
|||||||
profilePanel.addPropertyChangeListener(l);
|
profilePanel.addPropertyChangeListener(l);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @inheritDoc
|
|
||||||
*/
|
|
||||||
@Override
|
@Override
|
||||||
public void removePropertyChangeListener(PropertyChangeListener l) {
|
public void removePropertyChangeListener(PropertyChangeListener l) {
|
||||||
filterPanel.removePropertyChangeListener(l);
|
filterPanel.removePropertyChangeListener(l);
|
||||||
@ -158,9 +152,6 @@ public class IngestOptionsPanel extends IngestModuleGlobalSettingsPanel implemen
|
|||||||
profilePanel.removePropertyChangeListener(l);
|
profilePanel.removePropertyChangeListener(l);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @inheritDoc
|
|
||||||
*/
|
|
||||||
@Override
|
@Override
|
||||||
public void saveSettings() {
|
public void saveSettings() {
|
||||||
saveTabByIndex(tabbedPane.getSelectedIndex());
|
saveTabByIndex(tabbedPane.getSelectedIndex());
|
||||||
@ -189,17 +180,11 @@ public class IngestOptionsPanel extends IngestModuleGlobalSettingsPanel implemen
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @inheritDoc
|
|
||||||
*/
|
|
||||||
@Override
|
@Override
|
||||||
public void store() {
|
public void store() {
|
||||||
saveSettings();
|
saveSettings();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @inheritDoc
|
|
||||||
*/
|
|
||||||
@Override
|
@Override
|
||||||
public void load() {
|
public void load() {
|
||||||
filterPanel.load();
|
filterPanel.load();
|
||||||
|
@ -40,9 +40,6 @@ public class IngestOptionsPanelController extends OptionsPanelController {
|
|||||||
private final PropertyChangeSupport pcs = new PropertyChangeSupport(this);
|
private final PropertyChangeSupport pcs = new PropertyChangeSupport(this);
|
||||||
private boolean changed;
|
private boolean changed;
|
||||||
|
|
||||||
/**
|
|
||||||
* @inheritDoc
|
|
||||||
*/
|
|
||||||
@Override
|
@Override
|
||||||
public void update() {
|
public void update() {
|
||||||
getPanel().load();
|
getPanel().load();
|
||||||
@ -69,9 +66,6 @@ public class IngestOptionsPanelController extends OptionsPanelController {
|
|||||||
return panel;
|
return panel;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @inheritDoc
|
|
||||||
*/
|
|
||||||
@Override
|
@Override
|
||||||
public void applyChanges() {
|
public void applyChanges() {
|
||||||
if (changed) {
|
if (changed) {
|
||||||
@ -85,57 +79,36 @@ public class IngestOptionsPanelController extends OptionsPanelController {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @inheritDoc
|
|
||||||
*/
|
|
||||||
@Override
|
@Override
|
||||||
public void cancel() {
|
public void cancel() {
|
||||||
getPanel().cancel();
|
getPanel().cancel();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @inheritDoc
|
|
||||||
*/
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isValid() {
|
public boolean isValid() {
|
||||||
return getPanel().valid();
|
return getPanel().valid();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @inheritDoc
|
|
||||||
*/
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isChanged() {
|
public boolean isChanged() {
|
||||||
return changed;
|
return changed;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @inheritDoc
|
|
||||||
*/
|
|
||||||
@Override
|
@Override
|
||||||
public JComponent getComponent(Lookup lkp) {
|
public JComponent getComponent(Lookup lkp) {
|
||||||
return getPanel();
|
return getPanel();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @inheritDoc
|
|
||||||
*/
|
|
||||||
@Override
|
@Override
|
||||||
public HelpCtx getHelpCtx() {
|
public HelpCtx getHelpCtx() {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @inheritDoc
|
|
||||||
*/
|
|
||||||
@Override
|
@Override
|
||||||
public void addPropertyChangeListener(PropertyChangeListener pl) {
|
public void addPropertyChangeListener(PropertyChangeListener pl) {
|
||||||
pcs.addPropertyChangeListener(pl);
|
pcs.addPropertyChangeListener(pl);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @inheritDoc
|
|
||||||
*/
|
|
||||||
@Override
|
@Override
|
||||||
public void removePropertyChangeListener(PropertyChangeListener pl) {
|
public void removePropertyChangeListener(PropertyChangeListener pl) {
|
||||||
pcs.removePropertyChangeListener(pl);
|
pcs.removePropertyChangeListener(pl);
|
||||||
|
@ -43,7 +43,6 @@ public abstract class ShortcutWizardDescriptorPanel implements WizardDescriptor.
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Whether or not the panel immediately following this one should be skipped
|
* Whether or not the panel immediately following this one should be skipped
|
||||||
* .
|
|
||||||
*
|
*
|
||||||
* @return true or false
|
* @return true or false
|
||||||
*/
|
*/
|
||||||
|
@ -21,19 +21,24 @@ package org.sleuthkit.autopsy.modules.embeddedfileextractor;
|
|||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FileOutputStream;
|
import java.io.FileOutputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.lang.IllegalArgumentException;
|
||||||
|
import java.lang.IndexOutOfBoundsException;
|
||||||
|
import java.lang.NullPointerException;
|
||||||
import java.nio.file.Paths;
|
import java.nio.file.Paths;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
import org.apache.poi.OldFileFormatException;
|
|
||||||
import org.apache.poi.POIXMLException;
|
import org.apache.poi.POIXMLException;
|
||||||
import org.apache.poi.hslf.model.Picture;
|
import org.apache.poi.hwpf.usermodel.Picture;
|
||||||
import org.apache.poi.hslf.usermodel.PictureData;
|
import org.apache.poi.hslf.usermodel.HSLFPictureData;
|
||||||
import org.apache.poi.hslf.usermodel.SlideShow;
|
import org.apache.poi.hslf.usermodel.HSLFSlideShow;
|
||||||
|
import org.apache.poi.hssf.record.RecordInputStream.LeftoverDataException;
|
||||||
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
|
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
|
||||||
import org.apache.poi.hwpf.HWPFDocument;
|
import org.apache.poi.hwpf.HWPFDocument;
|
||||||
import org.apache.poi.hwpf.model.PicturesTable;
|
import org.apache.poi.hwpf.model.PicturesTable;
|
||||||
|
import org.apache.poi.sl.usermodel.PictureData.PictureType;
|
||||||
import org.apache.poi.ss.usermodel.Workbook;
|
import org.apache.poi.ss.usermodel.Workbook;
|
||||||
|
import org.apache.poi.util.RecordFormatException;
|
||||||
import org.apache.poi.xslf.usermodel.XMLSlideShow;
|
import org.apache.poi.xslf.usermodel.XMLSlideShow;
|
||||||
import org.apache.poi.xslf.usermodel.XSLFPictureData;
|
import org.apache.poi.xslf.usermodel.XSLFPictureData;
|
||||||
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
|
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
|
||||||
@ -209,20 +214,31 @@ class ImageExtractor {
|
|||||||
* extracted.
|
* extracted.
|
||||||
*/
|
*/
|
||||||
private List<ExtractedImage> extractImagesFromDoc(AbstractFile af) {
|
private List<ExtractedImage> extractImagesFromDoc(AbstractFile af) {
|
||||||
List<org.apache.poi.hwpf.usermodel.Picture> listOfAllPictures;
|
List<Picture> listOfAllPictures;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
HWPFDocument doc = new HWPFDocument(new ReadContentInputStream(af));
|
HWPFDocument doc = new HWPFDocument(new ReadContentInputStream(af));
|
||||||
PicturesTable pictureTable = doc.getPicturesTable();
|
PicturesTable pictureTable = doc.getPicturesTable();
|
||||||
listOfAllPictures = pictureTable.getAllPictures();
|
listOfAllPictures = pictureTable.getAllPictures();
|
||||||
} catch (OldFileFormatException | IOException ex) {
|
} catch (IOException | IllegalArgumentException |
|
||||||
// OldFileFormatException:
|
IndexOutOfBoundsException | NullPointerException ex) {
|
||||||
// Thrown when the document version is unsupported (Word 95 and
|
|
||||||
// older)
|
|
||||||
|
|
||||||
// IOException:
|
// IOException:
|
||||||
// Thrown when the document has issues being read.
|
// Thrown when the document has issues being read.
|
||||||
|
|
||||||
|
// IllegalArgumentException:
|
||||||
|
// This will catch OldFileFormatException, which is thrown when the
|
||||||
|
// document's format is Word 95 or older. Alternatively, this is
|
||||||
|
// thrown when attempting to load an RTF file as a DOC file.
|
||||||
|
// However, our code verifies the file format before ever running it
|
||||||
|
// through the ImageExtractor. This exception gets thrown in the
|
||||||
|
// "IN10-0137.E01" image regardless. The reason is unknown.
|
||||||
|
|
||||||
|
// IndexOutOfBoundsException:
|
||||||
|
// NullPointerException:
|
||||||
|
// These get thrown in certain images. The reason is unknown. It is
|
||||||
|
// likely due to problems with the file formats that POI is poorly
|
||||||
|
// handling.
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
} catch (Throwable ex) {
|
} catch (Throwable ex) {
|
||||||
// instantiating POI containers throw RuntimeExceptions
|
// instantiating POI containers throw RuntimeExceptions
|
||||||
@ -241,7 +257,7 @@ class ImageExtractor {
|
|||||||
}
|
}
|
||||||
List<ExtractedImage> listOfExtractedImages = new ArrayList<>();
|
List<ExtractedImage> listOfExtractedImages = new ArrayList<>();
|
||||||
byte[] data = null;
|
byte[] data = null;
|
||||||
for (org.apache.poi.hwpf.usermodel.Picture picture : listOfAllPictures) {
|
for (Picture picture : listOfAllPictures) {
|
||||||
String fileName = picture.suggestFullFileName();
|
String fileName = picture.suggestFullFileName();
|
||||||
try {
|
try {
|
||||||
data = picture.getContent();
|
data = picture.getContent();
|
||||||
@ -319,17 +335,25 @@ class ImageExtractor {
|
|||||||
* extracted.
|
* extracted.
|
||||||
*/
|
*/
|
||||||
private List<ExtractedImage> extractImagesFromPpt(AbstractFile af) {
|
private List<ExtractedImage> extractImagesFromPpt(AbstractFile af) {
|
||||||
PictureData[] listOfAllPictures = null;
|
List<HSLFPictureData> listOfAllPictures = null;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
SlideShow ppt = new SlideShow(new ReadContentInputStream(af));
|
HSLFSlideShow ppt = new HSLFSlideShow(new ReadContentInputStream(af));
|
||||||
listOfAllPictures = ppt.getPictureData();
|
listOfAllPictures = ppt.getPictureData();
|
||||||
} catch (OldFileFormatException | IOException ex) {
|
} catch (IOException | IllegalArgumentException |
|
||||||
// OldFileFormatException:
|
IndexOutOfBoundsException ex) {
|
||||||
// Thrown when the document version is unsupported
|
// IllegalArgumentException:
|
||||||
|
// This will catch OldFileFormatException, which is thrown when the
|
||||||
|
// document version is unsupported. The IllegalArgumentException may
|
||||||
|
// also get thrown for unknown reasons.
|
||||||
|
|
||||||
// IOException:
|
// IOException:
|
||||||
// Thrown when the document has issues being read
|
// Thrown when the document has issues being read.
|
||||||
|
|
||||||
|
// IndexOutOfBoundsException:
|
||||||
|
// This gets thrown in certain images. The reason is unknown. It is
|
||||||
|
// likely due to problems with the file formats that POI is poorly
|
||||||
|
// handling.
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
} catch (Throwable ex) {
|
} catch (Throwable ex) {
|
||||||
@ -341,7 +365,7 @@ class ImageExtractor {
|
|||||||
// if no images are extracted from the PPT, return null, else initialize
|
// if no images are extracted from the PPT, return null, else initialize
|
||||||
// the output folder for image extraction.
|
// the output folder for image extraction.
|
||||||
String outputFolderPath;
|
String outputFolderPath;
|
||||||
if (listOfAllPictures.length == 0) {
|
if (listOfAllPictures.isEmpty()) {
|
||||||
return null;
|
return null;
|
||||||
} else {
|
} else {
|
||||||
outputFolderPath = getOutputFolderPath(this.parentFileName);
|
outputFolderPath = getOutputFolderPath(this.parentFileName);
|
||||||
@ -355,26 +379,26 @@ class ImageExtractor {
|
|||||||
int i = 0;
|
int i = 0;
|
||||||
List<ExtractedImage> listOfExtractedImages = new ArrayList<>();
|
List<ExtractedImage> listOfExtractedImages = new ArrayList<>();
|
||||||
byte[] data = null;
|
byte[] data = null;
|
||||||
for (PictureData pictureData : listOfAllPictures) {
|
for (HSLFPictureData pictureData : listOfAllPictures) {
|
||||||
|
|
||||||
// Get image extension, generate image name, write image to the module
|
// Get image extension, generate image name, write image to the module
|
||||||
// output folder, add it to the listOfExtractedImageAbstractFiles
|
// output folder, add it to the listOfExtractedImageAbstractFiles
|
||||||
int type = pictureData.getType();
|
PictureType type = pictureData.getType();
|
||||||
String ext;
|
String ext;
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case Picture.JPEG:
|
case JPEG:
|
||||||
ext = ".jpg"; //NON-NLS
|
ext = ".jpg"; //NON-NLS
|
||||||
break;
|
break;
|
||||||
case Picture.PNG:
|
case PNG:
|
||||||
ext = ".png"; //NON-NLS
|
ext = ".png"; //NON-NLS
|
||||||
break;
|
break;
|
||||||
case Picture.WMF:
|
case WMF:
|
||||||
ext = ".wmf"; //NON-NLS
|
ext = ".wmf"; //NON-NLS
|
||||||
break;
|
break;
|
||||||
case Picture.EMF:
|
case EMF:
|
||||||
ext = ".emf"; //NON-NLS
|
ext = ".emf"; //NON-NLS
|
||||||
break;
|
break;
|
||||||
case Picture.PICT:
|
case PICT:
|
||||||
ext = ".pict"; //NON-NLS
|
ext = ".pict"; //NON-NLS
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@ -406,7 +430,7 @@ class ImageExtractor {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
XMLSlideShow pptx = new XMLSlideShow(new ReadContentInputStream(af));
|
XMLSlideShow pptx = new XMLSlideShow(new ReadContentInputStream(af));
|
||||||
listOfAllPictures = pptx.getAllPictures();
|
listOfAllPictures = pptx.getPictureData();
|
||||||
} catch (POIXMLException | IOException ex) {
|
} catch (POIXMLException | IOException ex) {
|
||||||
// POIXMLException:
|
// POIXMLException:
|
||||||
// Thrown when document fails to load.
|
// Thrown when document fails to load.
|
||||||
@ -468,12 +492,30 @@ class ImageExtractor {
|
|||||||
try {
|
try {
|
||||||
Workbook xls = new HSSFWorkbook(new ReadContentInputStream(af));
|
Workbook xls = new HSSFWorkbook(new ReadContentInputStream(af));
|
||||||
listOfAllPictures = xls.getAllPictures();
|
listOfAllPictures = xls.getAllPictures();
|
||||||
} catch (OldFileFormatException | IOException ex) {
|
} catch (IOException | LeftoverDataException |
|
||||||
// OldFileFormatException:
|
RecordFormatException | IllegalArgumentException |
|
||||||
// Thrown when the document version is unsupported
|
IndexOutOfBoundsException ex) {
|
||||||
|
// IllegalArgumentException:
|
||||||
|
// This will catch OldFileFormatException, which is thrown when the
|
||||||
|
// document version is unsupported. The IllegalArgumentException may
|
||||||
|
// also get thrown for unknown reasons.
|
||||||
|
|
||||||
// IOException:
|
// IOException:
|
||||||
// Thrown when the document has issues being read
|
// Thrown when the document has issues being read.
|
||||||
|
|
||||||
|
// LeftoverDataException:
|
||||||
|
// This is thrown for poorly formatted files that have more data
|
||||||
|
// than expected.
|
||||||
|
|
||||||
|
// RecordFormatException:
|
||||||
|
// This is thrown for poorly formatted files that have less data
|
||||||
|
// that expected.
|
||||||
|
|
||||||
|
// IllegalArgumentException:
|
||||||
|
// IndexOutOfBoundsException:
|
||||||
|
// These get thrown in certain images. The reason is unknown. It is
|
||||||
|
// likely due to problems with the file formats that POI is poorly
|
||||||
|
// handling.
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
} catch (Throwable ex) {
|
} catch (Throwable ex) {
|
||||||
|
@ -169,9 +169,6 @@ public final class FilesSetDefsPanel extends IngestModuleGlobalSettingsPanel imp
|
|||||||
this.equalitySignComboBox.setSelectedIndex(2);
|
this.equalitySignComboBox.setSelectedIndex(2);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @inheritDoc
|
|
||||||
*/
|
|
||||||
@Override
|
@Override
|
||||||
public void saveSettings() {
|
public void saveSettings() {
|
||||||
try {
|
try {
|
||||||
@ -203,17 +200,11 @@ public final class FilesSetDefsPanel extends IngestModuleGlobalSettingsPanel imp
|
|||||||
ingestWarningLabel.setVisible(!isEnabled);
|
ingestWarningLabel.setVisible(!isEnabled);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @inheritDoc
|
|
||||||
*/
|
|
||||||
@Override
|
@Override
|
||||||
public void store() {
|
public void store() {
|
||||||
this.saveSettings();
|
this.saveSettings();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @inheritDoc
|
|
||||||
*/
|
|
||||||
@Override
|
@Override
|
||||||
public void load() {
|
public void load() {
|
||||||
this.resetComponents();
|
this.resetComponents();
|
||||||
|
@ -16,7 +16,7 @@
|
|||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
package org.sleuthkit.autopsy.framework;
|
package org.sleuthkit.autopsy.progress;
|
||||||
|
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||||
@ -59,7 +59,7 @@ public final class LoggingProgressIndicator implements ProgressIndicator {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void progress(int workUnitsCompleted) {
|
public void progress(int workUnitsCompleted) {
|
||||||
LOGGER.log(Level.INFO, "{1} of {2} total work units completed", new Object[]{workUnitsCompleted, this.totalWorkUnits});
|
LOGGER.log(Level.INFO, "{0} of {1} total work units completed", new Object[]{workUnitsCompleted, this.totalWorkUnits});
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -68,8 +68,8 @@ public final class LoggingProgressIndicator implements ProgressIndicator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void finish(String message) {
|
public void finish() {
|
||||||
LOGGER.log(Level.INFO, "{0} finished", message);
|
LOGGER.log(Level.INFO, "Finished");
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
@ -16,11 +16,13 @@
|
|||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
package org.sleuthkit.autopsy.framework;
|
package org.sleuthkit.autopsy.progress;
|
||||||
|
|
||||||
import java.awt.Dialog;
|
import java.awt.Dialog;
|
||||||
import java.awt.Frame;
|
import java.awt.Frame;
|
||||||
import java.awt.event.ActionListener;
|
import java.awt.event.ActionListener;
|
||||||
|
import javax.annotation.concurrent.GuardedBy;
|
||||||
|
import javax.annotation.concurrent.ThreadSafe;
|
||||||
import javax.swing.JDialog;
|
import javax.swing.JDialog;
|
||||||
import javax.swing.SwingUtilities;
|
import javax.swing.SwingUtilities;
|
||||||
import org.openide.DialogDescriptor;
|
import org.openide.DialogDescriptor;
|
||||||
@ -30,14 +32,21 @@ import org.openide.util.HelpCtx;
|
|||||||
/**
|
/**
|
||||||
* A progress indicator that displays progress using a modal dialog with a
|
* A progress indicator that displays progress using a modal dialog with a
|
||||||
* message label, a progress bar, and optionally, a configurable set of buttons
|
* message label, a progress bar, and optionally, a configurable set of buttons
|
||||||
* with a button listener.
|
* with a button listener. Setting a cancelling flag which locks in a cancelling
|
||||||
|
* message and an indeterminate progress bar is supported.
|
||||||
*/
|
*/
|
||||||
|
@ThreadSafe
|
||||||
public final class ModalDialogProgressIndicator implements ProgressIndicator {
|
public final class ModalDialogProgressIndicator implements ProgressIndicator {
|
||||||
|
|
||||||
private final Frame parent;
|
private final Frame parent;
|
||||||
|
private final String title;
|
||||||
private final ProgressPanel progressPanel;
|
private final ProgressPanel progressPanel;
|
||||||
private final Dialog dialog;
|
private final Object[] buttonLabels;
|
||||||
|
private final Object focusedButtonLabel;
|
||||||
private final ActionListener buttonListener;
|
private final ActionListener buttonListener;
|
||||||
|
private Dialog dialog;
|
||||||
|
@GuardedBy("this")
|
||||||
|
private boolean cancelling;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a progress indicator that displays progress using a modal dialog
|
* Creates a progress indicator that displays progress using a modal dialog
|
||||||
@ -53,17 +62,11 @@ public final class ModalDialogProgressIndicator implements ProgressIndicator {
|
|||||||
*/
|
*/
|
||||||
public ModalDialogProgressIndicator(Frame parent, String title, Object[] buttonLabels, Object focusedButtonLabel, ActionListener buttonListener) {
|
public ModalDialogProgressIndicator(Frame parent, String title, Object[] buttonLabels, Object focusedButtonLabel, ActionListener buttonListener) {
|
||||||
this.parent = parent;
|
this.parent = parent;
|
||||||
|
this.title = title;
|
||||||
progressPanel = new ProgressPanel();
|
progressPanel = new ProgressPanel();
|
||||||
DialogDescriptor dialogDescriptor = new DialogDescriptor(
|
progressPanel.setIndeterminate(true);
|
||||||
progressPanel,
|
this.buttonLabels = buttonLabels;
|
||||||
title,
|
this.focusedButtonLabel = focusedButtonLabel;
|
||||||
true,
|
|
||||||
buttonLabels,
|
|
||||||
focusedButtonLabel,
|
|
||||||
DialogDescriptor.BOTTOM_ALIGN,
|
|
||||||
HelpCtx.DEFAULT_HELP,
|
|
||||||
buttonListener);
|
|
||||||
dialog = DialogDisplayer.getDefault().createDialog(dialogDescriptor);
|
|
||||||
this.buttonListener = buttonListener;
|
this.buttonListener = buttonListener;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -76,32 +79,12 @@ public final class ModalDialogProgressIndicator implements ProgressIndicator {
|
|||||||
*/
|
*/
|
||||||
public ModalDialogProgressIndicator(Frame parent, String title) {
|
public ModalDialogProgressIndicator(Frame parent, String title) {
|
||||||
this.parent = parent;
|
this.parent = parent;
|
||||||
|
this.title = title;
|
||||||
progressPanel = new ProgressPanel();
|
progressPanel = new ProgressPanel();
|
||||||
dialog = new JDialog(parent, title, true);
|
progressPanel.setIndeterminate(true);
|
||||||
dialog.add(progressPanel);
|
this.buttonLabels = null;
|
||||||
dialog.pack();
|
this.focusedButtonLabel = null;
|
||||||
buttonListener = null;
|
this.buttonListener = null;
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Calls setVisible on the underlying modal dialog.
|
|
||||||
*
|
|
||||||
* @param isVisible True or false.
|
|
||||||
*/
|
|
||||||
public void setVisible(boolean isVisible) {
|
|
||||||
if (isVisible) {
|
|
||||||
dialog.setLocationRelativeTo(parent);
|
|
||||||
}
|
|
||||||
this.dialog.setVisible(isVisible);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the button listener for the dialog, if there is one.
|
|
||||||
*
|
|
||||||
* @return The button listener or null.
|
|
||||||
*/
|
|
||||||
public ActionListener getButtonListener() {
|
|
||||||
return buttonListener;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -112,14 +95,13 @@ public final class ModalDialogProgressIndicator implements ProgressIndicator {
|
|||||||
* @param totalWorkUnits The total number of work units.
|
* @param totalWorkUnits The total number of work units.
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void start(String message, int totalWorkUnits) {
|
public synchronized void start(String message, int totalWorkUnits) {
|
||||||
SwingUtilities.invokeLater(new Runnable() {
|
cancelling = false;
|
||||||
@Override
|
SwingUtilities.invokeLater(() -> {
|
||||||
public void run() {
|
progressPanel.setIndeterminate(false);
|
||||||
progressPanel.setInderminate(false);
|
|
||||||
progressPanel.setMessage(message);
|
progressPanel.setMessage(message);
|
||||||
progressPanel.setMaximum(totalWorkUnits);
|
progressPanel.setMaximum(totalWorkUnits);
|
||||||
}
|
displayDialog();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -130,13 +112,27 @@ public final class ModalDialogProgressIndicator implements ProgressIndicator {
|
|||||||
* @param message The initial progress message.
|
* @param message The initial progress message.
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void start(String message) {
|
public synchronized void start(String message) {
|
||||||
SwingUtilities.invokeLater(new Runnable() {
|
cancelling = false;
|
||||||
@Override
|
SwingUtilities.invokeLater(() -> {
|
||||||
public void run() {
|
progressPanel.setIndeterminate(true);
|
||||||
progressPanel.setInderminate(true);
|
|
||||||
progressPanel.setMessage(message);
|
progressPanel.setMessage(message);
|
||||||
|
displayDialog();
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets a cancelling message and makes the progress bar indeterminate. Once
|
||||||
|
* cancel has been called, the progress indicator no longer accepts updates
|
||||||
|
* unless start is called again.
|
||||||
|
*
|
||||||
|
* @param cancellingMessage
|
||||||
|
*/
|
||||||
|
public synchronized void setCancelling(String cancellingMessage) {
|
||||||
|
cancelling = true;
|
||||||
|
SwingUtilities.invokeLater(() -> {
|
||||||
|
progressPanel.setIndeterminate(false);
|
||||||
|
progressPanel.setMessage(cancellingMessage);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -147,15 +143,14 @@ public final class ModalDialogProgressIndicator implements ProgressIndicator {
|
|||||||
* @param message The initial progress message.
|
* @param message The initial progress message.
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void switchToIndeterminate(String message) {
|
public synchronized void switchToIndeterminate(String message) {
|
||||||
SwingUtilities.invokeLater(new Runnable() {
|
if (!cancelling) {
|
||||||
@Override
|
SwingUtilities.invokeLater(() -> {
|
||||||
public void run() {
|
progressPanel.setIndeterminate(true);
|
||||||
progressPanel.setInderminate(true);
|
|
||||||
progressPanel.setMessage(message);
|
progressPanel.setMessage(message);
|
||||||
}
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Switches the progress indicator to determinate mode (the total number of
|
* Switches the progress indicator to determinate mode (the total number of
|
||||||
@ -166,17 +161,16 @@ public final class ModalDialogProgressIndicator implements ProgressIndicator {
|
|||||||
* @param totalWorkUnits The total number of work units to be completed.
|
* @param totalWorkUnits The total number of work units to be completed.
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void switchToDeterminate(String message, int workUnitsCompleted, int totalWorkUnits) {
|
public synchronized void switchToDeterminate(String message, int workUnitsCompleted, int totalWorkUnits) {
|
||||||
SwingUtilities.invokeLater(new Runnable() {
|
if (!cancelling) {
|
||||||
@Override
|
SwingUtilities.invokeLater(() -> {
|
||||||
public void run() {
|
progressPanel.setIndeterminate(false);
|
||||||
progressPanel.setInderminate(false);
|
|
||||||
progressPanel.setMessage(message);
|
progressPanel.setMessage(message);
|
||||||
progressPanel.setMaximum(totalWorkUnits);
|
progressPanel.setMaximum(totalWorkUnits);
|
||||||
progressPanel.setCurrent(workUnitsCompleted);
|
progressPanel.setCurrent(workUnitsCompleted);
|
||||||
}
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Updates the progress indicator with a progress message.
|
* Updates the progress indicator with a progress message.
|
||||||
@ -184,14 +178,13 @@ public final class ModalDialogProgressIndicator implements ProgressIndicator {
|
|||||||
* @param message The progress message.
|
* @param message The progress message.
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void progress(String message) {
|
public synchronized void progress(String message) {
|
||||||
SwingUtilities.invokeLater(new Runnable() {
|
if (!cancelling) {
|
||||||
@Override
|
SwingUtilities.invokeLater(() -> {
|
||||||
public void run() {
|
|
||||||
progressPanel.setMessage(message);
|
progressPanel.setMessage(message);
|
||||||
}
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Updates the progress indicator with the number of work units completed so
|
* Updates the progress indicator with the number of work units completed so
|
||||||
@ -201,14 +194,13 @@ public final class ModalDialogProgressIndicator implements ProgressIndicator {
|
|||||||
* @param workUnitsCompleted Number of work units completed so far.
|
* @param workUnitsCompleted Number of work units completed so far.
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void progress(int workUnitsCompleted) {
|
public synchronized void progress(int workUnitsCompleted) {
|
||||||
SwingUtilities.invokeLater(new Runnable() {
|
if (!cancelling) {
|
||||||
@Override
|
SwingUtilities.invokeLater(() -> {
|
||||||
public void run() {
|
|
||||||
progressPanel.setCurrent(workUnitsCompleted);
|
progressPanel.setCurrent(workUnitsCompleted);
|
||||||
}
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Updates the progress indicator with a progress message and the number of
|
* Updates the progress indicator with a progress message and the number of
|
||||||
@ -219,29 +211,52 @@ public final class ModalDialogProgressIndicator implements ProgressIndicator {
|
|||||||
* @param workUnitsCompleted Number of work units completed so far.
|
* @param workUnitsCompleted Number of work units completed so far.
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void progress(String message, int workUnitsCompleted) {
|
public synchronized void progress(String message, int workUnitsCompleted) {
|
||||||
SwingUtilities.invokeLater(new Runnable() {
|
if (!cancelling) {
|
||||||
@Override
|
SwingUtilities.invokeLater(() -> {
|
||||||
public void run() {
|
|
||||||
progressPanel.setMessage(message);
|
progressPanel.setMessage(message);
|
||||||
progressPanel.setCurrent(workUnitsCompleted);
|
progressPanel.setCurrent(workUnitsCompleted);
|
||||||
}
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Finishes the progress indicator when the task is completed.
|
* Finishes the progress indicator when the task is completed.
|
||||||
*
|
|
||||||
* @param message The finished message.
|
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void finish(String message) {
|
public synchronized void finish() {
|
||||||
SwingUtilities.invokeLater(new Runnable() {
|
SwingUtilities.invokeLater(() -> {
|
||||||
@Override
|
this.dialog.setVisible(false);
|
||||||
public void run() {
|
|
||||||
progressPanel.setMessage(message);
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates and dislpays the dialog for the progress indicator.
|
||||||
|
*/
|
||||||
|
private void displayDialog() {
|
||||||
|
if (null != buttonLabels && null != focusedButtonLabel && null != buttonListener) {
|
||||||
|
/*
|
||||||
|
* Dialog with buttons.
|
||||||
|
*/
|
||||||
|
DialogDescriptor dialogDescriptor = new DialogDescriptor(
|
||||||
|
progressPanel,
|
||||||
|
title,
|
||||||
|
true,
|
||||||
|
buttonLabels,
|
||||||
|
focusedButtonLabel,
|
||||||
|
DialogDescriptor.BOTTOM_ALIGN,
|
||||||
|
HelpCtx.DEFAULT_HELP,
|
||||||
|
buttonListener);
|
||||||
|
dialog = DialogDisplayer.getDefault().createDialog(dialogDescriptor);
|
||||||
|
} else {
|
||||||
|
/*
|
||||||
|
* Dialog without buttons.
|
||||||
|
*/
|
||||||
|
dialog = new JDialog(parent, title, true);
|
||||||
|
dialog.add(progressPanel);
|
||||||
|
dialog.pack();
|
||||||
|
}
|
||||||
|
dialog.setLocationRelativeTo(parent);
|
||||||
|
this.dialog.setVisible(true);
|
||||||
|
}
|
||||||
}
|
}
|
@ -16,7 +16,7 @@
|
|||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
package org.sleuthkit.autopsy.framework;
|
package org.sleuthkit.autopsy.progress;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An interface for progress indicators. A progress indicator can run in
|
* An interface for progress indicators. A progress indicator can run in
|
||||||
@ -46,6 +46,7 @@ public interface ProgressIndicator {
|
|||||||
/**
|
/**
|
||||||
* Switches the progress indicator to indeterminate mode (the total number
|
* Switches the progress indicator to indeterminate mode (the total number
|
||||||
* of work units to be completed is unknown).
|
* of work units to be completed is unknown).
|
||||||
|
*
|
||||||
* @param message The initial progress message.
|
* @param message The initial progress message.
|
||||||
*/
|
*/
|
||||||
public void switchToIndeterminate(String message);
|
public void switchToIndeterminate(String message);
|
||||||
@ -88,9 +89,7 @@ public interface ProgressIndicator {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Finishes the progress indicator when the task is completed.
|
* Finishes the progress indicator when the task is completed.
|
||||||
*
|
|
||||||
* @param message The finished message.
|
|
||||||
*/
|
*/
|
||||||
void finish(String message);
|
void finish();
|
||||||
|
|
||||||
}
|
}
|
@ -42,7 +42,7 @@
|
|||||||
<Component class="javax.swing.JLabel" name="progressMessage">
|
<Component class="javax.swing.JLabel" name="progressMessage">
|
||||||
<Properties>
|
<Properties>
|
||||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||||
<ResourceString bundle="org/sleuthkit/autopsy/framework/Bundle.properties" key="ProgressPanel.progressMessage.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
<ResourceString bundle="org/sleuthkit/autopsy/progress/Bundle.properties" key="ProgressPanel.progressMessage.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||||
</Property>
|
</Property>
|
||||||
</Properties>
|
</Properties>
|
||||||
</Component>
|
</Component>
|
@ -16,7 +16,7 @@
|
|||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
package org.sleuthkit.autopsy.framework;
|
package org.sleuthkit.autopsy.progress;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A progress panel consisting of a message label and a progress bar.
|
* A progress panel consisting of a message label and a progress bar.
|
||||||
@ -35,7 +35,7 @@ class ProgressPanel extends javax.swing.JPanel {
|
|||||||
this.progressMessage.setText(message);
|
this.progressMessage.setText(message);
|
||||||
}
|
}
|
||||||
|
|
||||||
void setInderminate(boolean indeterminate) {
|
void setIndeterminate(boolean indeterminate) {
|
||||||
this.progressBar.setIndeterminate(indeterminate);
|
this.progressBar.setIndeterminate(indeterminate);
|
||||||
}
|
}
|
||||||
|
|
@ -16,9 +16,9 @@
|
|||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
package org.sleuthkit.autopsy.framework;
|
package org.sleuthkit.autopsy.progress;
|
||||||
|
|
||||||
import org.sleuthkit.autopsy.framework.ProgressIndicator;
|
import org.sleuthkit.autopsy.progress.ProgressIndicator;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A "silent" or "null" progress indicator.
|
* A "silent" or "null" progress indicator.
|
||||||
@ -54,7 +54,7 @@ public class SilentProgressIndicator implements ProgressIndicator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void finish(String message) {
|
public void finish() {
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* Autopsy Forensic Browser
|
* Autopsy Forensic Browser
|
||||||
*
|
*
|
||||||
* Copyright 2013-2014 Basis Technology Corp.
|
* Copyright 2013-2017 Basis Technology Corp.
|
||||||
* Contact: carrier <at> sleuthkit <dot> org
|
* Contact: carrier <at> sleuthkit <dot> org
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
@ -80,15 +80,15 @@ class ReportExcel implements TableReportModule {
|
|||||||
Font titleFont = wb.createFont();
|
Font titleFont = wb.createFont();
|
||||||
titleFont.setFontHeightInPoints((short) 12);
|
titleFont.setFontHeightInPoints((short) 12);
|
||||||
titleStyle.setFont(titleFont);
|
titleStyle.setFont(titleFont);
|
||||||
titleStyle.setAlignment(CellStyle.ALIGN_LEFT);
|
titleStyle.setAlignment(HorizontalAlignment.LEFT);
|
||||||
titleStyle.setWrapText(true);
|
titleStyle.setWrapText(true);
|
||||||
|
|
||||||
setStyle = wb.createCellStyle();
|
setStyle = wb.createCellStyle();
|
||||||
Font setFont = wb.createFont();
|
Font setFont = wb.createFont();
|
||||||
setFont.setFontHeightInPoints((short) 14);
|
setFont.setFontHeightInPoints((short) 14);
|
||||||
setFont.setBoldweight((short) 10);
|
setFont.setBold(true);
|
||||||
setStyle.setFont(setFont);
|
setStyle.setFont(setFont);
|
||||||
setStyle.setAlignment(CellStyle.ALIGN_LEFT);
|
setStyle.setAlignment(HorizontalAlignment.LEFT);
|
||||||
setStyle.setWrapText(true);
|
setStyle.setWrapText(true);
|
||||||
|
|
||||||
elementStyle = wb.createCellStyle();
|
elementStyle = wb.createCellStyle();
|
||||||
@ -96,7 +96,7 @@ class ReportExcel implements TableReportModule {
|
|||||||
Font elementFont = wb.createFont();
|
Font elementFont = wb.createFont();
|
||||||
elementFont.setFontHeightInPoints((short) 14);
|
elementFont.setFontHeightInPoints((short) 14);
|
||||||
elementStyle.setFont(elementFont);
|
elementStyle.setFont(elementFont);
|
||||||
elementStyle.setAlignment(CellStyle.ALIGN_LEFT);
|
elementStyle.setAlignment(HorizontalAlignment.LEFT);
|
||||||
elementStyle.setWrapText(true);
|
elementStyle.setWrapText(true);
|
||||||
|
|
||||||
writeSummaryWorksheet();
|
writeSummaryWorksheet();
|
||||||
|
@ -0,0 +1,126 @@
|
|||||||
|
/*
|
||||||
|
* Autopsy Forensic Browser
|
||||||
|
*
|
||||||
|
* Copyright 2011-2017 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.test;
|
||||||
|
|
||||||
|
import java.util.logging.Level;
|
||||||
|
|
||||||
|
import org.openide.util.Exceptions;
|
||||||
|
import org.sleuthkit.autopsy.casemodule.Case;
|
||||||
|
import org.sleuthkit.autopsy.casemodule.services.Blackboard;
|
||||||
|
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||||
|
import org.sleuthkit.autopsy.ingest.FileIngestModuleAdapter;
|
||||||
|
import org.sleuthkit.autopsy.ingest.IngestJobContext;
|
||||||
|
import org.sleuthkit.datamodel.AbstractFile;
|
||||||
|
import org.sleuthkit.datamodel.BlackboardArtifact;
|
||||||
|
import org.sleuthkit.datamodel.BlackboardAttribute;
|
||||||
|
import org.sleuthkit.datamodel.TskCoreException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A file ingest module that creates some interestng artifacts
|
||||||
|
* with attributes based on files for test purposes.
|
||||||
|
*/
|
||||||
|
|
||||||
|
final class InterestingArtifactCreatorIngestModule extends FileIngestModuleAdapter {
|
||||||
|
|
||||||
|
private static final Logger logger = Logger.getLogger(InterestingArtifactCreatorIngestModule.class.getName());
|
||||||
|
private static final String MODULE_NAME = InterestingArtifactCreatorIngestModuleFactory.getModuleName();
|
||||||
|
private static final String[] ARTIFACT_TYPE_NAMES = {"TSK_WEB_BOOKMARK", "TSK_KEYWORD_HIT", "TSK_CALLLOG"};
|
||||||
|
private static final String[] ARTIFACT_DISPLAY_NAMES = {"Web Bookmarks", "Keyword Hits", "Call Logs"};
|
||||||
|
private static final String INT_ARTIFACT_TYPE_NAME = BlackboardArtifact.ARTIFACT_TYPE.TSK_INTERESTING_ARTIFACT_HIT.getLabel();
|
||||||
|
private static final String INT_ARTIFACT_DISPLAY_NAME = BlackboardArtifact.ARTIFACT_TYPE.TSK_INTERESTING_ARTIFACT_HIT.getDisplayName();
|
||||||
|
private BlackboardArtifact.Type artifactType;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void startUp(IngestJobContext context) throws IngestModuleException {
|
||||||
|
Blackboard blackboard = Case.getCurrentCase().getServices().getBlackboard();
|
||||||
|
try {
|
||||||
|
artifactType = blackboard.getOrAddArtifactType(INT_ARTIFACT_TYPE_NAME, INT_ARTIFACT_DISPLAY_NAME);
|
||||||
|
} catch (Blackboard.BlackboardException ex) {
|
||||||
|
throw new IngestModuleException(Bundle.ErrorCreatingCustomBlackBoardType(), ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ProcessResult process(AbstractFile file) {
|
||||||
|
/*
|
||||||
|
* Skip directories and virtual files.
|
||||||
|
*/
|
||||||
|
if (file.isDir() || file.isVirtual()) {
|
||||||
|
return ProcessResult.OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
/*
|
||||||
|
* Add a custom artifact with one custom attribute of each value
|
||||||
|
* type.
|
||||||
|
*/
|
||||||
|
int randomArtIndex = (int) (Math.random() * 3);
|
||||||
|
Blackboard blackboard = Case.getCurrentCase().getServices().getBlackboard();
|
||||||
|
BlackboardArtifact.Type artifactTypeBase = blackboard.getOrAddArtifactType(ARTIFACT_TYPE_NAMES[randomArtIndex], ARTIFACT_DISPLAY_NAMES[randomArtIndex]);
|
||||||
|
BlackboardArtifact artifactBase = file.newArtifact(artifactTypeBase.getTypeID());
|
||||||
|
String commentTxt;
|
||||||
|
BlackboardAttribute baseAttr;
|
||||||
|
switch (artifactBase.getArtifactTypeID()) {
|
||||||
|
case 2:
|
||||||
|
commentTxt = "www.placeholderWebsiteDOTCOM";
|
||||||
|
baseAttr = new BlackboardAttribute(
|
||||||
|
BlackboardAttribute.ATTRIBUTE_TYPE.TSK_URL, "Fake Web BookMark", "www.thisWebsiteIsStillFake.com");
|
||||||
|
artifactBase.addAttribute(baseAttr);
|
||||||
|
break;
|
||||||
|
case 9:
|
||||||
|
commentTxt = "fakeKeyword";
|
||||||
|
baseAttr = new BlackboardAttribute(
|
||||||
|
BlackboardAttribute.ATTRIBUTE_TYPE.TSK_KEYWORD_PREVIEW, "Fake Keyword Search", "Fake Keyword Preview Text");
|
||||||
|
BlackboardAttribute set = new BlackboardAttribute(
|
||||||
|
BlackboardAttribute.ATTRIBUTE_TYPE.TSK_SET_NAME, "Fake Keyword Search", "Fake");
|
||||||
|
BlackboardAttribute keyword = new BlackboardAttribute(
|
||||||
|
BlackboardAttribute.ATTRIBUTE_TYPE.TSK_KEYWORD, "Fake Keyword Search", "FakeKeyword");
|
||||||
|
artifactBase.addAttribute(baseAttr);
|
||||||
|
artifactBase.addAttribute(set);
|
||||||
|
artifactBase.addAttribute(keyword);
|
||||||
|
break;
|
||||||
|
case 25:
|
||||||
|
commentTxt = "fake phone number from";
|
||||||
|
baseAttr = new BlackboardAttribute(
|
||||||
|
BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PHONE_NUMBER_FROM, "Fake Call Log Whatever", "555-555-5555");
|
||||||
|
artifactBase.addAttribute(baseAttr);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
commentTxt = "DEPENDENT ON ARTIFACT TYPE";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
BlackboardArtifact artifact = file.newArtifact(artifactType.getTypeID());
|
||||||
|
BlackboardAttribute att = new BlackboardAttribute(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_SET_NAME, MODULE_NAME, "ArtifactsAndTxt");
|
||||||
|
|
||||||
|
BlackboardAttribute att2 = new BlackboardAttribute(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_COMMENT, MODULE_NAME, commentTxt);
|
||||||
|
BlackboardAttribute att3 = new BlackboardAttribute(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_CATEGORY, MODULE_NAME, "");
|
||||||
|
artifact.addAttribute(att);
|
||||||
|
artifact.addAttribute(att2);
|
||||||
|
artifact.addAttribute(att3);
|
||||||
|
artifact.addAttribute(new BlackboardAttribute(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_ASSOCIATED_ARTIFACT, MODULE_NAME, artifactBase.getArtifactID()));
|
||||||
|
} catch (TskCoreException ex) {
|
||||||
|
logger.log(Level.SEVERE, String.format("Failed to process file (obj_id = %d)", file.getId()), ex);
|
||||||
|
return ProcessResult.ERROR;
|
||||||
|
} catch (Blackboard.BlackboardException ex) {
|
||||||
|
Exceptions.printStackTrace(ex);
|
||||||
|
}
|
||||||
|
return ProcessResult.OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,64 @@
|
|||||||
|
/*
|
||||||
|
* Autopsy Forensic Browser
|
||||||
|
*
|
||||||
|
* Copyright 2011-2017 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.test;
|
||||||
|
|
||||||
|
import org.openide.util.lookup.ServiceProvider;
|
||||||
|
import org.sleuthkit.autopsy.coreutils.Version;
|
||||||
|
import org.sleuthkit.autopsy.ingest.FileIngestModule;
|
||||||
|
import org.sleuthkit.autopsy.ingest.IngestModuleFactory;
|
||||||
|
import org.sleuthkit.autopsy.ingest.IngestModuleFactoryAdapter;
|
||||||
|
import org.sleuthkit.autopsy.ingest.IngestModuleIngestJobSettings;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A factory for file ingest modules that creates some interestng artifacts with
|
||||||
|
* attributes based on files for test purposes. Uncomment the service provider
|
||||||
|
* annotation to activate this test fixture.
|
||||||
|
*/
|
||||||
|
//@ServiceProvider(service = IngestModuleFactory.class)
|
||||||
|
public final class InterestingArtifactCreatorIngestModuleFactory extends IngestModuleFactoryAdapter {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getModuleDisplayName() {
|
||||||
|
return getModuleName();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getModuleDescription() {
|
||||||
|
return "Creates some interestng artifacts with attributes based on files for test purposes.";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getModuleVersionNumber() {
|
||||||
|
return Version.getVersion();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isFileIngestModuleFactory() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public FileIngestModule createFileIngestModule(IngestModuleIngestJobSettings settings) {
|
||||||
|
return new InterestingArtifactCreatorIngestModule();
|
||||||
|
}
|
||||||
|
|
||||||
|
static String getModuleName() {
|
||||||
|
return "Test Interesting Artifact Creator";
|
||||||
|
}
|
||||||
|
}
|
@ -21,8 +21,8 @@ package org.sleuthkit.autopsy.test;
|
|||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
import org.openide.util.lookup.ServiceProvider;
|
import org.openide.util.lookup.ServiceProvider;
|
||||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||||
import org.sleuthkit.autopsy.framework.AutopsyService;
|
import org.sleuthkit.autopsy.appservices.AutopsyService;
|
||||||
import org.sleuthkit.autopsy.framework.ProgressIndicator;
|
import org.sleuthkit.autopsy.progress.ProgressIndicator;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An implementation of the Autopsy service interface used for test purposes.
|
* An implementation of the Autopsy service interface used for test purposes.
|
||||||
@ -53,7 +53,7 @@ public class TestAutopsyService implements AutopsyService {
|
|||||||
progressIndicator.progress(80);
|
progressIndicator.progress(80);
|
||||||
Thread.sleep(1000L);
|
Thread.sleep(1000L);
|
||||||
progressIndicator.progress(100);
|
progressIndicator.progress(100);
|
||||||
progressIndicator.finish("First task completed by Test Autopsy Service.");
|
progressIndicator.finish();
|
||||||
progressIndicator.start("Test Autopsy Service doing second task...");
|
progressIndicator.start("Test Autopsy Service doing second task...");
|
||||||
for (int i = 0; i < 10000; ++i) {
|
for (int i = 0; i < 10000; ++i) {
|
||||||
logger.log(Level.INFO, "Test Autopsy Service simulating work on second task");
|
logger.log(Level.INFO, "Test Autopsy Service simulating work on second task");
|
||||||
@ -62,7 +62,7 @@ public class TestAutopsyService implements AutopsyService {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
progressIndicator.finish("Second task completed by Test Autopsy Service.");
|
progressIndicator.finish();
|
||||||
} catch (InterruptedException ex) {
|
} catch (InterruptedException ex) {
|
||||||
logger.log(Level.INFO, "Test Autopsy Service interrupted (cancelled) while doing first task, cancel requested = {0}", context.cancelRequested());
|
logger.log(Level.INFO, "Test Autopsy Service interrupted (cancelled) while doing first task, cancel requested = {0}", context.cancelRequested());
|
||||||
}
|
}
|
||||||
|
@ -100,11 +100,15 @@ public class EventRootNode extends DisplayableItemNode {
|
|||||||
*/
|
*/
|
||||||
if (eventIDs.size() < MAX_EVENTS_TO_DISPLAY) {
|
if (eventIDs.size() < MAX_EVENTS_TO_DISPLAY) {
|
||||||
for (Long eventId: eventIDs){
|
for (Long eventId: eventIDs){
|
||||||
|
if (!nodesMap.containsKey(eventId)) {
|
||||||
nodesMap.put(eventId, createNode(eventId));
|
nodesMap.put(eventId, createNode(eventId));
|
||||||
|
}
|
||||||
toPopulate.add(eventId);
|
toPopulate.add(eventId);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
if (!nodesMap.containsKey(-1L)) {
|
||||||
nodesMap.put(-1L, createNode(-1L));
|
nodesMap.put(-1L, createNode(-1L));
|
||||||
|
}
|
||||||
toPopulate.add(-1L);
|
toPopulate.add(-1L);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
@ -28,8 +28,8 @@
|
|||||||
<dependency conf="autopsy_core->*" org="log4j" name="log4j" rev="1.2.17"/>
|
<dependency conf="autopsy_core->*" org="log4j" name="log4j" rev="1.2.17"/>
|
||||||
|
|
||||||
<!-- <dependency conf="autopsy_core->*" org="org.jdom" name="jdom" rev="1.1.3"/> -->
|
<!-- <dependency conf="autopsy_core->*" org="org.jdom" name="jdom" rev="1.1.3"/> -->
|
||||||
<dependency conf="autopsy_core->*" org="org.apache.poi" name="poi-excelant" rev="3.8"/>
|
<dependency conf="autopsy_core->*" org="org.apache.poi" name="poi-excelant" rev="3.15"/>
|
||||||
<dependency conf="autopsy_core->*" org="org.apache.poi" name="poi-scratchpad" rev="3.8"/>
|
<dependency conf="autopsy_core->*" org="org.apache.poi" name="poi-scratchpad" rev="3.15"/>
|
||||||
|
|
||||||
<!-- process and system monitoring, note: matching native libs pulled from thirdparty -->
|
<!-- process and system monitoring, note: matching native libs pulled from thirdparty -->
|
||||||
<dependency conf="autopsy_core->*" org="org.fusesource" name="sigar" rev="1.6.4" />
|
<dependency conf="autopsy_core->*" org="org.fusesource" name="sigar" rev="1.6.4" />
|
||||||
|
@ -6,7 +6,8 @@ file.reference.avalon-framework-4.1.5.jar=release/modules/ext/avalon-framework-4
|
|||||||
file.reference.common-image-3.2.jar=release/modules/ext/common-image-3.2.jar
|
file.reference.common-image-3.2.jar=release/modules/ext/common-image-3.2.jar
|
||||||
file.reference.common-io-3.2.jar=release/modules/ext/common-io-3.2.jar
|
file.reference.common-io-3.2.jar=release/modules/ext/common-io-3.2.jar
|
||||||
file.reference.common-lang-3.2.jar=release/modules/ext/common-lang-3.2.jar
|
file.reference.common-lang-3.2.jar=release/modules/ext/common-lang-3.2.jar
|
||||||
file.reference.commons-codec-1.5.jar=release/modules/ext/commons-codec-1.5.jar
|
file.reference.commons-codec-1.10.jar=release/modules/ext/commons-codec-1.10.jar
|
||||||
|
file.reference.commons-collections4-4.1.jar=release/modules/ext/commons-collections4-4.1.jar
|
||||||
file.reference.commons-csv-1.4.jar=release/modules/ext/commons-csv-1.4.jar
|
file.reference.commons-csv-1.4.jar=release/modules/ext/commons-csv-1.4.jar
|
||||||
file.reference.commons-io-2.4.jar=release/modules/ext/commons-io-2.4.jar
|
file.reference.commons-io-2.4.jar=release/modules/ext/commons-io-2.4.jar
|
||||||
file.reference.commons-lang-2.6.jar=release/modules/ext/commons-lang-2.6.jar
|
file.reference.commons-lang-2.6.jar=release/modules/ext/commons-lang-2.6.jar
|
||||||
@ -56,11 +57,11 @@ file.reference.logkit-1.0.1.jar=release/modules/ext/logkit-1.0.1.jar
|
|||||||
file.reference.mail-1.4.3.jar=release/modules/ext/mail-1.4.3.jar
|
file.reference.mail-1.4.3.jar=release/modules/ext/mail-1.4.3.jar
|
||||||
file.reference.openjfx-dialogs-1.0.2.jar=release/modules/ext/openjfx-dialogs-1.0.3.jar
|
file.reference.openjfx-dialogs-1.0.2.jar=release/modules/ext/openjfx-dialogs-1.0.3.jar
|
||||||
file.reference.platform-3.4.0.jar=release/modules/ext/platform-3.4.0.jar
|
file.reference.platform-3.4.0.jar=release/modules/ext/platform-3.4.0.jar
|
||||||
file.reference.poi-3.8.jar=release/modules/ext/poi-3.8.jar
|
file.reference.poi-3.15.jar=release/modules/ext/poi-3.15.jar
|
||||||
file.reference.poi-excelant-3.8.jar=release/modules/ext/poi-excelant-3.8.jar
|
file.reference.poi-excelant-3.15.jar=release/modules/ext/poi-excelant-3.15.jar
|
||||||
file.reference.poi-ooxml-3.8.jar=release/modules/ext/poi-ooxml-3.8.jar
|
file.reference.poi-ooxml-3.15.jar=release/modules/ext/poi-ooxml-3.15.jar
|
||||||
file.reference.poi-ooxml-schemas-3.8.jar=release/modules/ext/poi-ooxml-schemas-3.8.jar
|
file.reference.poi-ooxml-schemas-3.15.jar=release/modules/ext/poi-ooxml-schemas-3.15.jar
|
||||||
file.reference.poi-scratchpad-3.8.jar=release/modules/ext/poi-scratchpad-3.8.jar
|
file.reference.poi-scratchpad-3.15.jar=release/modules/ext/poi-scratchpad-3.15.jar
|
||||||
file.reference.reflections-0.9.8.jar=release/modules/ext/reflections-0.9.8.jar
|
file.reference.reflections-0.9.8.jar=release/modules/ext/reflections-0.9.8.jar
|
||||||
file.reference.servlet-api-2.5.jar=release/modules/ext/servlet-api-2.5.jar
|
file.reference.servlet-api-2.5.jar=release/modules/ext/servlet-api-2.5.jar
|
||||||
file.reference.sigar-1.6.4-sources.jar=release/modules/ext/sigar-1.6.4-sources.jar
|
file.reference.sigar-1.6.4-sources.jar=release/modules/ext/sigar-1.6.4-sources.jar
|
||||||
@ -69,7 +70,7 @@ file.reference.slf4j-api-1.6.1.jar=release/modules/ext/slf4j-api-1.6.1.jar
|
|||||||
file.reference.slf4j-simple-1.6.1.jar=release/modules/ext/slf4j-simple-1.6.1.jar
|
file.reference.slf4j-simple-1.6.1.jar=release/modules/ext/slf4j-simple-1.6.1.jar
|
||||||
file.reference.stax-api-1.0.1.jar=release/modules/ext/stax-api-1.0.1.jar
|
file.reference.stax-api-1.0.1.jar=release/modules/ext/stax-api-1.0.1.jar
|
||||||
file.reference.xml-apis-1.0.b2.jar=release/modules/ext/xml-apis-1.0.b2.jar
|
file.reference.xml-apis-1.0.b2.jar=release/modules/ext/xml-apis-1.0.b2.jar
|
||||||
file.reference.xmlbeans-2.3.0.jar=release/modules/ext/xmlbeans-2.3.0.jar
|
file.reference.xmlbeans-2.6.0.jar=release/modules/ext/xmlbeans-2.6.0.jar
|
||||||
javac.source=1.8
|
javac.source=1.8
|
||||||
javac.compilerargs=-Xlint -Xlint:-serial
|
javac.compilerargs=-Xlint -Xlint:-serial
|
||||||
javadoc.reference.commons-csv-1.4.jar=release/modules/ext/commons-csv-1.4-javadoc.jar
|
javadoc.reference.commons-csv-1.4.jar=release/modules/ext/commons-csv-1.4-javadoc.jar
|
||||||
|
@ -700,16 +700,16 @@
|
|||||||
<binary-origin>release/modules/ext/sigar-1.6.4.jar</binary-origin>
|
<binary-origin>release/modules/ext/sigar-1.6.4.jar</binary-origin>
|
||||||
</class-path-extension>
|
</class-path-extension>
|
||||||
<class-path-extension>
|
<class-path-extension>
|
||||||
<runtime-relative-path>ext/xmlbeans-2.3.0.jar</runtime-relative-path>
|
<runtime-relative-path>ext/xmlbeans-2.6.0.jar</runtime-relative-path>
|
||||||
<binary-origin>release/modules/ext/xmlbeans-2.3.0.jar</binary-origin>
|
<binary-origin>release/modules/ext/xmlbeans-2.6.0.jar</binary-origin>
|
||||||
</class-path-extension>
|
</class-path-extension>
|
||||||
<class-path-extension>
|
<class-path-extension>
|
||||||
<runtime-relative-path>ext/jna-3.4.0.jar</runtime-relative-path>
|
<runtime-relative-path>ext/jna-3.4.0.jar</runtime-relative-path>
|
||||||
<binary-origin>release/modules/ext/jna-3.4.0.jar</binary-origin>
|
<binary-origin>release/modules/ext/jna-3.4.0.jar</binary-origin>
|
||||||
</class-path-extension>
|
</class-path-extension>
|
||||||
<class-path-extension>
|
<class-path-extension>
|
||||||
<runtime-relative-path>ext/poi-ooxml-schemas-3.8.jar</runtime-relative-path>
|
<runtime-relative-path>ext/poi-ooxml-schemas-3.15.jar</runtime-relative-path>
|
||||||
<binary-origin>release/modules/ext/poi-ooxml-schemas-3.8.jar</binary-origin>
|
<binary-origin>release/modules/ext/poi-ooxml-schemas-3.15.jar</binary-origin>
|
||||||
</class-path-extension>
|
</class-path-extension>
|
||||||
<class-path-extension>
|
<class-path-extension>
|
||||||
<runtime-relative-path>ext/gson-1.4.jar</runtime-relative-path>
|
<runtime-relative-path>ext/gson-1.4.jar</runtime-relative-path>
|
||||||
@ -768,8 +768,8 @@
|
|||||||
<binary-origin>release/modules/ext/jcalendarbutton-1.4.6.jar</binary-origin>
|
<binary-origin>release/modules/ext/jcalendarbutton-1.4.6.jar</binary-origin>
|
||||||
</class-path-extension>
|
</class-path-extension>
|
||||||
<class-path-extension>
|
<class-path-extension>
|
||||||
<runtime-relative-path>ext/poi-ooxml-3.8.jar</runtime-relative-path>
|
<runtime-relative-path>ext/poi-ooxml-3.15.jar</runtime-relative-path>
|
||||||
<binary-origin>release/modules/ext/poi-ooxml-3.8.jar</binary-origin>
|
<binary-origin>release/modules/ext/poi-ooxml-3.15.jar</binary-origin>
|
||||||
</class-path-extension>
|
</class-path-extension>
|
||||||
<class-path-extension>
|
<class-path-extension>
|
||||||
<runtime-relative-path>ext/imageio-psd-3.2.jar</runtime-relative-path>
|
<runtime-relative-path>ext/imageio-psd-3.2.jar</runtime-relative-path>
|
||||||
@ -779,13 +779,17 @@
|
|||||||
<runtime-relative-path>ext/stax-api-1.0.1.jar</runtime-relative-path>
|
<runtime-relative-path>ext/stax-api-1.0.1.jar</runtime-relative-path>
|
||||||
<binary-origin>release/modules/ext/stax-api-1.0.1.jar</binary-origin>
|
<binary-origin>release/modules/ext/stax-api-1.0.1.jar</binary-origin>
|
||||||
</class-path-extension>
|
</class-path-extension>
|
||||||
|
<class-path-extension>
|
||||||
|
<runtime-relative-path>ext/commons-collections4-4.1.jar</runtime-relative-path>
|
||||||
|
<binary-origin>release/modules/ext/commons-collections4-4.1.jar</binary-origin>
|
||||||
|
</class-path-extension>
|
||||||
<class-path-extension>
|
<class-path-extension>
|
||||||
<runtime-relative-path>ext/servlet-api-2.5.jar</runtime-relative-path>
|
<runtime-relative-path>ext/servlet-api-2.5.jar</runtime-relative-path>
|
||||||
<binary-origin>release/modules/ext/servlet-api-2.5.jar</binary-origin>
|
<binary-origin>release/modules/ext/servlet-api-2.5.jar</binary-origin>
|
||||||
</class-path-extension>
|
</class-path-extension>
|
||||||
<class-path-extension>
|
<class-path-extension>
|
||||||
<runtime-relative-path>ext/poi-excelant-3.8.jar</runtime-relative-path>
|
<runtime-relative-path>ext/poi-excelant-3.15.jar</runtime-relative-path>
|
||||||
<binary-origin>release/modules/ext/poi-excelant-3.8.jar</binary-origin>
|
<binary-origin>release/modules/ext/poi-excelant-3.15.jar</binary-origin>
|
||||||
</class-path-extension>
|
</class-path-extension>
|
||||||
<class-path-extension>
|
<class-path-extension>
|
||||||
<runtime-relative-path>ext/imageio-pcx-3.2.jar</runtime-relative-path>
|
<runtime-relative-path>ext/imageio-pcx-3.2.jar</runtime-relative-path>
|
||||||
@ -824,8 +828,8 @@
|
|||||||
<binary-origin>release/modules/ext/geronimo-jms_1.1_spec-1.0.jar</binary-origin>
|
<binary-origin>release/modules/ext/geronimo-jms_1.1_spec-1.0.jar</binary-origin>
|
||||||
</class-path-extension>
|
</class-path-extension>
|
||||||
<class-path-extension>
|
<class-path-extension>
|
||||||
<runtime-relative-path>ext/poi-scratchpad-3.8.jar</runtime-relative-path>
|
<runtime-relative-path>ext/poi-scratchpad-3.15.jar</runtime-relative-path>
|
||||||
<binary-origin>release/modules/ext/poi-scratchpad-3.8.jar</binary-origin>
|
<binary-origin>release/modules/ext/poi-scratchpad-3.15.jar</binary-origin>
|
||||||
</class-path-extension>
|
</class-path-extension>
|
||||||
<class-path-extension>
|
<class-path-extension>
|
||||||
<runtime-relative-path>ext/joda-time-2.4-sources.jar</runtime-relative-path>
|
<runtime-relative-path>ext/joda-time-2.4-sources.jar</runtime-relative-path>
|
||||||
@ -876,8 +880,8 @@
|
|||||||
<binary-origin>release/modules/ext/ant-1.8.2.jar</binary-origin>
|
<binary-origin>release/modules/ext/ant-1.8.2.jar</binary-origin>
|
||||||
</class-path-extension>
|
</class-path-extension>
|
||||||
<class-path-extension>
|
<class-path-extension>
|
||||||
<runtime-relative-path>ext/commons-codec-1.5.jar</runtime-relative-path>
|
<runtime-relative-path>ext/commons-codec-1.10.jar</runtime-relative-path>
|
||||||
<binary-origin>release/modules/ext/commons-codec-1.5.jar</binary-origin>
|
<binary-origin>release/modules/ext/commons-codec-1.10.jar</binary-origin>
|
||||||
</class-path-extension>
|
</class-path-extension>
|
||||||
<class-path-extension>
|
<class-path-extension>
|
||||||
<runtime-relative-path>ext/javassist-3.12.1.GA.jar</runtime-relative-path>
|
<runtime-relative-path>ext/javassist-3.12.1.GA.jar</runtime-relative-path>
|
||||||
@ -896,8 +900,8 @@
|
|||||||
<binary-origin>release/modules/ext/commons-io-2.4.jar</binary-origin>
|
<binary-origin>release/modules/ext/commons-io-2.4.jar</binary-origin>
|
||||||
</class-path-extension>
|
</class-path-extension>
|
||||||
<class-path-extension>
|
<class-path-extension>
|
||||||
<runtime-relative-path>ext/poi-3.8.jar</runtime-relative-path>
|
<runtime-relative-path>ext/poi-3.15.jar</runtime-relative-path>
|
||||||
<binary-origin>release/modules/ext/poi-3.8.jar</binary-origin>
|
<binary-origin>release/modules/ext/poi-3.15.jar</binary-origin>
|
||||||
</class-path-extension>
|
</class-path-extension>
|
||||||
<class-path-extension>
|
<class-path-extension>
|
||||||
<runtime-relative-path>ext/controlsfx-8.40.11.jar</runtime-relative-path>
|
<runtime-relative-path>ext/controlsfx-8.40.11.jar</runtime-relative-path>
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
</configurations>
|
</configurations>
|
||||||
<dependencies>
|
<dependencies>
|
||||||
<dependency conf="experimental->default" org="com.github.lgooddatepicker" name="LGoodDatePicker" rev="4.3.1"/>
|
<dependency conf="experimental->default" org="com.github.lgooddatepicker" name="LGoodDatePicker" rev="4.3.1"/>
|
||||||
<dependency conf="experimental->default" org="org.apache.tika" name="tika-core" rev="1.5"/>
|
<dependency conf="experimental->default" org="org.apache.tika" name="tika-core" rev="1.14"/>
|
||||||
<dependency conf="experimental->default" org="org.postgresql" name="postgresql" rev="9.4-1201-jdbc41"/>
|
<dependency conf="experimental->default" org="org.postgresql" name="postgresql" rev="9.4-1201-jdbc41"/>
|
||||||
<dependency conf="experimental->default" org="com.mchange" name="c3p0" rev="0.9.5"/>
|
<dependency conf="experimental->default" org="com.mchange" name="c3p0" rev="0.9.5"/>
|
||||||
<dependency conf="experimental->default" org="com.fasterxml.jackson.core" name="jackson-core" rev="2.7.0"/>
|
<dependency conf="experimental->default" org="com.fasterxml.jackson.core" name="jackson-core" rev="2.7.0"/>
|
||||||
|
@ -3,7 +3,7 @@ file.reference.jackson-core-2.7.0.jar=release/modules/ext/jackson-core-2.7.0.jar
|
|||||||
file.reference.LGoodDatePicker-4.3.1.jar=release/modules/ext/LGoodDatePicker-4.3.1.jar
|
file.reference.LGoodDatePicker-4.3.1.jar=release/modules/ext/LGoodDatePicker-4.3.1.jar
|
||||||
file.reference.mchange-commons-java-0.2.9.jar=release/modules/ext/mchange-commons-java-0.2.9.jar
|
file.reference.mchange-commons-java-0.2.9.jar=release/modules/ext/mchange-commons-java-0.2.9.jar
|
||||||
file.reference.postgresql-9.4-1201-jdbc41.jar=release/modules/ext/postgresql-9.4-1201-jdbc41.jar
|
file.reference.postgresql-9.4-1201-jdbc41.jar=release/modules/ext/postgresql-9.4-1201-jdbc41.jar
|
||||||
file.reference.tika-core-1.5.jar=release/modules/ext/tika-core-1.5.jar
|
file.reference.tika-core-1.14.jar=release/modules/ext/tika-core-1.14.jar
|
||||||
javac.source=1.8
|
javac.source=1.8
|
||||||
javac.compilerargs=-Xlint -Xlint:-serial
|
javac.compilerargs=-Xlint -Xlint:-serial
|
||||||
javadoc.reference.LGoodDatePicker-4.3.1.jar=release/modules/ext/LGoodDatePicker-4.3.1-javadoc.jar
|
javadoc.reference.LGoodDatePicker-4.3.1.jar=release/modules/ext/LGoodDatePicker-4.3.1-javadoc.jar
|
||||||
|
@ -132,8 +132,8 @@
|
|||||||
<binary-origin>release/modules/ext/LGoodDatePicker-4.3.1.jar</binary-origin>
|
<binary-origin>release/modules/ext/LGoodDatePicker-4.3.1.jar</binary-origin>
|
||||||
</class-path-extension>
|
</class-path-extension>
|
||||||
<class-path-extension>
|
<class-path-extension>
|
||||||
<runtime-relative-path>ext/tika-core-1.5.jar</runtime-relative-path>
|
<runtime-relative-path>ext/tika-core-1.14.jar</runtime-relative-path>
|
||||||
<binary-origin>release/modules/ext/tika-core-1.5.jar</binary-origin>
|
<binary-origin>release/modules/ext/tika-core-1.14.jar</binary-origin>
|
||||||
</class-path-extension>
|
</class-path-extension>
|
||||||
<class-path-extension>
|
<class-path-extension>
|
||||||
<runtime-relative-path>ext/jackson-core-2.7.0.jar</runtime-relative-path>
|
<runtime-relative-path>ext/jackson-core-2.7.0.jar</runtime-relative-path>
|
||||||
|
@ -39,10 +39,11 @@ import javax.swing.SwingWorker;
|
|||||||
import javax.swing.event.ListSelectionEvent;
|
import javax.swing.event.ListSelectionEvent;
|
||||||
import javax.swing.table.DefaultTableModel;
|
import javax.swing.table.DefaultTableModel;
|
||||||
import javax.swing.table.TableColumn;
|
import javax.swing.table.TableColumn;
|
||||||
import org.openide.windows.WindowManager;
|
import org.sleuthkit.autopsy.casemodule.CaseActionCancelledException;
|
||||||
import org.sleuthkit.autopsy.casemodule.CaseMetadata;
|
import org.sleuthkit.autopsy.casemodule.CaseMetadata;
|
||||||
import org.sleuthkit.autopsy.casemodule.StartupWindowProvider;
|
import org.sleuthkit.autopsy.casemodule.StartupWindowProvider;
|
||||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||||
|
import org.sleuthkit.autopsy.coreutils.MessageNotifyUtil;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A panel that allows a user to open cases created by auto ingest.
|
* A panel that allows a user to open cases created by auto ingest.
|
||||||
@ -295,18 +296,12 @@ public final class AutoIngestCasePanel extends JPanel {
|
|||||||
protected void done() {
|
protected void done() {
|
||||||
try {
|
try {
|
||||||
get();
|
get();
|
||||||
} catch (InterruptedException ex) {
|
} catch (InterruptedException | ExecutionException ex) {
|
||||||
logger.log(Level.SEVERE, String.format("Error while opening case with case metadata file path %s", caseMetadataFilePath), ex);
|
if (null != ex.getCause() && !(ex.getCause() instanceof CaseActionCancelledException)) {
|
||||||
JOptionPane.showMessageDialog(WindowManager.getDefault().getMainWindow(),
|
logger.log(Level.SEVERE, String.format("Error opening case with metadata file path %s", caseMetadataFilePath), ex); //NON-NLS
|
||||||
ex.getMessage(),
|
MessageNotifyUtil.Message.error(ex.getCause().getLocalizedMessage());
|
||||||
org.openide.util.NbBundle.getMessage(AutoIngestCasePanel.class, "ReviewModeCasePanel.cannotOpenCase"),
|
}
|
||||||
JOptionPane.ERROR_MESSAGE);
|
StartupWindowProvider.getInstance().open();
|
||||||
} catch (ExecutionException ex) {
|
|
||||||
logger.log(Level.SEVERE, String.format("Error while opening case with case metadata file path %s", caseMetadataFilePath), ex);
|
|
||||||
JOptionPane.showMessageDialog(WindowManager.getDefault().getMainWindow(),
|
|
||||||
ex.getCause().getMessage(),
|
|
||||||
org.openide.util.NbBundle.getMessage(AutoIngestCasePanel.class, "ReviewModeCasePanel.cannotOpenCase"),
|
|
||||||
JOptionPane.ERROR_MESSAGE);
|
|
||||||
} finally {
|
} finally {
|
||||||
setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
|
setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
|
||||||
}
|
}
|
||||||
|
@ -92,8 +92,8 @@ import static org.sleuthkit.autopsy.experimental.autoingest.ManifestNodeData.Pro
|
|||||||
import org.sleuthkit.autopsy.experimental.configuration.AutoIngestUserPreferences;
|
import org.sleuthkit.autopsy.experimental.configuration.AutoIngestUserPreferences;
|
||||||
import org.sleuthkit.autopsy.experimental.configuration.SharedConfiguration;
|
import org.sleuthkit.autopsy.experimental.configuration.SharedConfiguration;
|
||||||
import org.sleuthkit.autopsy.experimental.configuration.SharedConfiguration.SharedConfigurationException;
|
import org.sleuthkit.autopsy.experimental.configuration.SharedConfiguration.SharedConfigurationException;
|
||||||
import org.sleuthkit.autopsy.framework.AutoIngestDataSourceProcessor;
|
import org.sleuthkit.autopsy.datasourceprocessors.AutoIngestDataSourceProcessor;
|
||||||
import org.sleuthkit.autopsy.framework.AutoIngestDataSourceProcessor.AutoIngestDataSourceProcessorException;
|
import org.sleuthkit.autopsy.datasourceprocessors.AutoIngestDataSourceProcessor.AutoIngestDataSourceProcessorException;
|
||||||
import org.sleuthkit.autopsy.ingest.IngestJob;
|
import org.sleuthkit.autopsy.ingest.IngestJob;
|
||||||
import org.sleuthkit.autopsy.ingest.IngestJob.CancellationReason;
|
import org.sleuthkit.autopsy.ingest.IngestJob.CancellationReason;
|
||||||
import org.sleuthkit.autopsy.ingest.IngestJobSettings;
|
import org.sleuthkit.autopsy.ingest.IngestJobSettings;
|
||||||
|
@ -39,10 +39,10 @@ import org.xml.sax.SAXException;
|
|||||||
public final class AutopsyManifestFileParser implements ManifestFileParser {
|
public final class AutopsyManifestFileParser implements ManifestFileParser {
|
||||||
|
|
||||||
private static final String MANIFEST_FILE_NAME_SIGNATURE = "_Manifest.xml";
|
private static final String MANIFEST_FILE_NAME_SIGNATURE = "_Manifest.xml";
|
||||||
private static final String ROOT_ELEM_TAG_NAME = "Manifest";
|
private static final String ROOT_ELEM_TAG_NAME = "AutopsyManifest";
|
||||||
private static final String CASE_NAME_XPATH = "/Manifest/Collection/Name/text()";
|
private static final String CASE_NAME_XPATH = "/AutopsyManifest/CaseName/text()";
|
||||||
private static final String DEVICE_ID_XPATH = "/Manifest/Collection/Image/ID/text()";
|
private static final String DEVICE_ID_XPATH = "/AutopsyManifest/DeviceId/text()";
|
||||||
private static final String DATA_SOURCE_NAME_XPATH = "/Manifest/Collection/Image/Name/text()";
|
private static final String DATA_SOURCE_NAME_XPATH = "/AutopsyManifest/DataSource/text()";
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean fileIsManifest(Path filePath) {
|
public boolean fileIsManifest(Path filePath) {
|
||||||
@ -62,10 +62,6 @@ public final class AutopsyManifestFileParser implements ManifestFileParser {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Manifest parse(Path filePath) throws ManifestFileParserException {
|
public Manifest parse(Path filePath) throws ManifestFileParserException {
|
||||||
if (!fileIsManifest(filePath)) {
|
|
||||||
throw new ManifestFileParserException(String.format("%s not recognized as a manifest", filePath));
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
Document doc = this.createManifestDOM(filePath);
|
Document doc = this.createManifestDOM(filePath);
|
||||||
XPath xpath = XPathFactory.newInstance().newXPath();
|
XPath xpath = XPathFactory.newInstance().newXPath();
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* Autopsy Forensic Browser
|
* Autopsy Forensic Browser
|
||||||
*
|
*
|
||||||
* Copyright 2015 Basis Technology Corp.
|
* Copyright 2015-2017 Basis Technology Corp.
|
||||||
* Contact: carrier <at> sleuthkit <dot> org
|
* Contact: carrier <at> sleuthkit <dot> org
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
@ -20,9 +20,28 @@ package org.sleuthkit.autopsy.experimental.autoingest;
|
|||||||
|
|
||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Responsible for parsing the manifest files that
|
||||||
|
* describe cases, devices, and data sources.
|
||||||
|
* These are used by autoingest to create cases and add
|
||||||
|
* data sources to the correct case.
|
||||||
|
*/
|
||||||
public interface ManifestFileParser {
|
public interface ManifestFileParser {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if a file is this type of manifest file
|
||||||
|
* @param filePath Path to potential manifest file
|
||||||
|
* @return True if the file is a manifest that this parser supports
|
||||||
|
*/
|
||||||
boolean fileIsManifest(Path filePath);
|
boolean fileIsManifest(Path filePath);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parses the given file. Will only be called if
|
||||||
|
* fileIsManifest() previously returned true.
|
||||||
|
* @param filePath Path to manifest file
|
||||||
|
* @return Parsed results
|
||||||
|
* @throws org.sleuthkit.autopsy.experimental.autoingest.ManifestFileParser.ManifestFileParserException
|
||||||
|
*/
|
||||||
Manifest parse(Path filePath) throws ManifestFileParserException;
|
Manifest parse(Path filePath) throws ManifestFileParserException;
|
||||||
|
|
||||||
public final static class ManifestFileParserException extends Exception {
|
public final static class ManifestFileParserException extends Exception {
|
||||||
|
@ -35,6 +35,7 @@ import org.openide.util.actions.Presenter;
|
|||||||
import org.openide.windows.WindowManager;
|
import org.openide.windows.WindowManager;
|
||||||
import org.sleuthkit.autopsy.casemodule.Case;
|
import org.sleuthkit.autopsy.casemodule.Case;
|
||||||
import org.sleuthkit.autopsy.core.Installer;
|
import org.sleuthkit.autopsy.core.Installer;
|
||||||
|
import org.sleuthkit.autopsy.core.RuntimeProperties;
|
||||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||||
import org.sleuthkit.autopsy.imagegallery.ImageGalleryController;
|
import org.sleuthkit.autopsy.imagegallery.ImageGalleryController;
|
||||||
import org.sleuthkit.autopsy.imagegallery.ImageGalleryModule;
|
import org.sleuthkit.autopsy.imagegallery.ImageGalleryModule;
|
||||||
@ -64,7 +65,7 @@ public final class OpenAction extends CallableSystemAction implements Presenter.
|
|||||||
toolbarButton.addActionListener(actionEvent -> performAction());
|
toolbarButton.addActionListener(actionEvent -> performAction());
|
||||||
pcl = (PropertyChangeEvent evt) -> {
|
pcl = (PropertyChangeEvent evt) -> {
|
||||||
if (evt.getPropertyName().equals(Case.Events.CURRENT_CASE.toString())) {
|
if (evt.getPropertyName().equals(Case.Events.CURRENT_CASE.toString())) {
|
||||||
setEnabled(evt.getNewValue() != null);
|
setEnabled(RuntimeProperties.runningWithGUI() && evt.getNewValue() != null);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
Case.addPropertyChangeListener(pcl);
|
Case.addPropertyChangeListener(pcl);
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* Autopsy Forensic Browser
|
* Autopsy Forensic Browser
|
||||||
*
|
*
|
||||||
* Copyright 2013-16 Basis Technology Corp.
|
* Copyright 2011-17 Basis Technology Corp.
|
||||||
* Contact: carrier <at> sleuthkit <dot> org
|
* Contact: carrier <at> sleuthkit <dot> org
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
@ -54,7 +54,7 @@ public class GroupSortBy implements Comparator<DrawableGroup> {
|
|||||||
/**
|
/**
|
||||||
* sort the groups by some priority metric to be determined and implemented
|
* sort the groups by some priority metric to be determined and implemented
|
||||||
*/
|
*/
|
||||||
public final static GroupSortBy PRIORITY = new GroupSortBy(Bundle.GroupSortBy_priority(), "hashset_hits.png", Comparator.comparing(DrawableGroup::getHashHitDensity).thenComparing(Comparator.comparing(DrawableGroup::getUncategorizedCount)));
|
public final static GroupSortBy PRIORITY = new GroupSortBy(Bundle.GroupSortBy_priority(), "hashset_hits.png", Comparator.comparing(DrawableGroup::getHashHitDensity).thenComparing(Comparator.comparing(DrawableGroup::getUncategorizedCount)).reversed());
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int compare(DrawableGroup o1, DrawableGroup o2) {
|
public int compare(DrawableGroup o1, DrawableGroup o2) {
|
||||||
|
@ -5,10 +5,6 @@
|
|||||||
<!-- module dependencies -->
|
<!-- module dependencies -->
|
||||||
<conf name="autopsy"/>
|
<conf name="autopsy"/>
|
||||||
|
|
||||||
<!-- Solr index upgrade tool dependencies -->
|
|
||||||
<conf name="solr4to5"/>
|
|
||||||
<conf name="solr5to6"/>
|
|
||||||
|
|
||||||
<!-- Solr server dependencies -->
|
<!-- Solr server dependencies -->
|
||||||
<conf name="solr-libs"/>
|
<conf name="solr-libs"/>
|
||||||
<conf name="solr-war"/>
|
<conf name="solr-war"/>
|
||||||
@ -22,19 +18,6 @@
|
|||||||
<dependency conf="solr-libs->default" org="org.apache.solr" name="solr-cell" rev="4.9.1"/>
|
<dependency conf="solr-libs->default" org="org.apache.solr" name="solr-cell" rev="4.9.1"/>
|
||||||
<dependency conf="solr-war->default" org="org.apache.solr" name="solr" rev="4.9.1" transitive="false" /> <!-- the war file -->
|
<dependency conf="solr-war->default" org="org.apache.solr" name="solr" rev="4.9.1" transitive="false" /> <!-- the war file -->
|
||||||
|
|
||||||
<!-- Solr index upgrade -->
|
|
||||||
<dependency conf="solr4to5->default" org="org.apache.lucene" name="lucene-analyzers-common" rev="5.5.1"/>
|
|
||||||
<dependency conf="solr4to5->default" org="org.apache.lucene" name="lucene-backward-codecs" rev="5.5.1"/>
|
|
||||||
<dependency conf="solr4to5->default" org="org.apache.lucene" name="lucene-codecs" rev="5.5.1"/>
|
|
||||||
<dependency conf="solr4to5->default" org="org.apache.lucene" name="lucene-core" rev="5.5.1"/>
|
|
||||||
|
|
||||||
<dependency conf="solr5to6->default" org="org.apache.lucene" name="lucene-analyzers-common" rev="6.2.1"/>
|
|
||||||
<dependency conf="solr5to6->default" org="org.apache.lucene" name="lucene-backward-codecs" rev="6.2.1"/>
|
|
||||||
<dependency conf="solr5to6->default" org="org.apache.lucene" name="lucene-codecs" rev="6.2.1"/>
|
|
||||||
<dependency conf="solr5to6->default" org="org.apache.lucene" name="lucene-core" rev="6.2.1"/>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<!-- Autopsy -->
|
<!-- Autopsy -->
|
||||||
<dependency conf="autopsy->*" org="org.apache.solr" name="solr-solrj" rev="4.9.1"/>
|
<dependency conf="autopsy->*" org="org.apache.solr" name="solr-solrj" rev="4.9.1"/>
|
||||||
<dependency conf="autopsy->*" org="commons-lang" name="commons-lang" rev="2.4"/>
|
<dependency conf="autopsy->*" org="commons-lang" name="commons-lang" rev="2.4"/>
|
||||||
|
@ -124,9 +124,6 @@ file.reference.slf4j-api-1.7.12.jar=release/modules/ext/slf4j-api-1.7.12.jar
|
|||||||
file.reference.solr-solrj-4.9.1-javadoc.jar=release/modules/ext/solr-solrj-4.9.1-javadoc.jar
|
file.reference.solr-solrj-4.9.1-javadoc.jar=release/modules/ext/solr-solrj-4.9.1-javadoc.jar
|
||||||
file.reference.solr-solrj-4.9.1-sources.jar=release/modules/ext/solr-solrj-4.9.1-sources.jar
|
file.reference.solr-solrj-4.9.1-sources.jar=release/modules/ext/solr-solrj-4.9.1-sources.jar
|
||||||
file.reference.solr-solrj-4.9.1.jar=release/modules/ext/solr-solrj-4.9.1.jar
|
file.reference.solr-solrj-4.9.1.jar=release/modules/ext/solr-solrj-4.9.1.jar
|
||||||
file.reference.solr-solrj-6.2.1-javadoc.jar=release/modules/ext/solr-solrj-6.2.1-javadoc.jar
|
|
||||||
file.reference.solr-solrj-6.2.1-sources.jar=release/modules/ext/solr-solrj-6.2.1-sources.jar
|
|
||||||
file.reference.solr-solrj-6.2.1.jar=release/modules/ext/solr-solrj-6.2.1.jar
|
|
||||||
file.reference.spring-aop-3.1.2.RELEASE.jar=release/modules/ext/spring-aop-3.1.2.RELEASE.jar
|
file.reference.spring-aop-3.1.2.RELEASE.jar=release/modules/ext/spring-aop-3.1.2.RELEASE.jar
|
||||||
file.reference.spring-asm-3.1.2.RELEASE.jar=release/modules/ext/spring-asm-3.1.2.RELEASE.jar
|
file.reference.spring-asm-3.1.2.RELEASE.jar=release/modules/ext/spring-asm-3.1.2.RELEASE.jar
|
||||||
file.reference.spring-beans-3.1.2.RELEASE.jar=release/modules/ext/spring-beans-3.1.2.RELEASE.jar
|
file.reference.spring-beans-3.1.2.RELEASE.jar=release/modules/ext/spring-beans-3.1.2.RELEASE.jar
|
||||||
|
@ -213,7 +213,7 @@ Server.queryNumFileChunks.exception.msg=Error getting number of file chunks,
|
|||||||
Server.query.exception.msg=Error running query\: {0}
|
Server.query.exception.msg=Error running query\: {0}
|
||||||
Server.query2.exception.msg=Error running query\: {0}
|
Server.query2.exception.msg=Error running query\: {0}
|
||||||
Server.queryTerms.exception.msg=Error running terms query\: {0}
|
Server.queryTerms.exception.msg=Error running terms query\: {0}
|
||||||
Server.connect.exception.msg=Failed to connect to Solr server\:
|
Server.connect.exception.msg=Failed to connect to Solr server\: {0}
|
||||||
Server.openCore.exception.msg=Keyword search service not yet running
|
Server.openCore.exception.msg=Keyword search service not yet running
|
||||||
Server.openCore.exception.cantOpen.msg=Could not create or open index
|
Server.openCore.exception.cantOpen.msg=Could not create or open index
|
||||||
Server.openCore.exception.noIndexDir.msg=Index directory could not be created or is missing
|
Server.openCore.exception.noIndexDir.msg=Index directory could not be created or is missing
|
||||||
@ -315,8 +315,6 @@ GlobalListsManagementPanel.copyListButton.text=Copy List
|
|||||||
GlobalListsManagementPanel.renameListButton.text=Edit List Name
|
GlobalListsManagementPanel.renameListButton.text=Edit List Name
|
||||||
GlobalEditListPanel.editWordButton.text=Edit Keyword
|
GlobalEditListPanel.editWordButton.text=Edit Keyword
|
||||||
SolrSearchService.ServiceName=Solr Keyword Search Service
|
SolrSearchService.ServiceName=Solr Keyword Search Service
|
||||||
SolrSearchService.IndexUpgradeDialog.title=Text Index Upgrade Required In Order To Open Case
|
|
||||||
SolrSearchService.IndexUpgradeDialog.msg=<html>The text index upgrade can take some time. <br />When completed, you will be able to see existing keyword search results and perform literal keyword searches,<br />but you will not be able to add new text to the index or perform regex searches. You may instead open the case<br /> with your previous version of this application. Do you wish to proceed with the index upgrade?</html>
|
|
||||||
SolrSearchService.IndexReadOnlyDialog.title=Text Index Is Read-Only
|
SolrSearchService.IndexReadOnlyDialog.title=Text Index Is Read-Only
|
||||||
SolrSearchService.IndexReadOnlyDialog.msg=<html>The text index for this case is read-only. <br />You will be able to see existing keyword search results and perform literal keyword searches,<br />but you will not be able to add new text to the index or perform regex searches. You may instead open the case<br /> with your previous version of this application.</html>
|
SolrSearchService.IndexReadOnlyDialog.msg=<html>The text index for this case is read-only. <br />You will be able to see existing keyword search results and perform exact match and substring match keyword searches,<br />but you will not be able to add new text to the index or perform regex searches. You may instead open the case<br /> with your previous version of this application.</html>
|
||||||
|
|
||||||
|
@ -270,7 +270,7 @@ HighlightedMatchesSource.getMarkup.queryFailedMsg=<html><pre><span style\\\\\='b
|
|||||||
KeywordSearch.openCore.notification.msg=\u30ad\u30fc\u30ef\u30fc\u30c9\u691c\u7d22\u30a4\u30f3\u30c7\u30c3\u30af\u30b9\u3092\u958b\u3051\u307e\u305b\u3093\u3067\u3057\u305f
|
KeywordSearch.openCore.notification.msg=\u30ad\u30fc\u30ef\u30fc\u30c9\u691c\u7d22\u30a4\u30f3\u30c7\u30c3\u30af\u30b9\u3092\u958b\u3051\u307e\u305b\u3093\u3067\u3057\u305f
|
||||||
KeywordSearch.closeCore.notification.msg=\u30ad\u30fc\u30ef\u30fc\u30c9\u691c\u7d22\u30a4\u30f3\u30c7\u30c3\u30af\u30b9\u3092\u9589\u3058\u308b\u969b\u306b\u30a8\u30e9\u30fc\u304c\u767a\u751f\u3057\u307e\u3057\u305f
|
KeywordSearch.closeCore.notification.msg=\u30ad\u30fc\u30ef\u30fc\u30c9\u691c\u7d22\u30a4\u30f3\u30c7\u30c3\u30af\u30b9\u3092\u9589\u3058\u308b\u969b\u306b\u30a8\u30e9\u30fc\u304c\u767a\u751f\u3057\u307e\u3057\u305f
|
||||||
KeywordSearchListsManagementPanel.fileExtensionFilterLb2=\u30ad\u30fc\u30ef\u30fc\u30c9\u30ea\u30b9\u30c8\u30d5\u30a1\u30a4\u30eb\u3092\u30a8\u30f3\u30b1\u30fc\u30b9\u3059\u308b(txt)
|
KeywordSearchListsManagementPanel.fileExtensionFilterLb2=\u30ad\u30fc\u30ef\u30fc\u30c9\u30ea\u30b9\u30c8\u30d5\u30a1\u30a4\u30eb\u3092\u30a8\u30f3\u30b1\u30fc\u30b9\u3059\u308b(txt)
|
||||||
Server.connect.exception.msg=Solr\u30b5\u30fc\u30d0\u30fc\u3078\u306e\u63a5\u7d9a\u306b\u5931\u6557\u3057\u307e\u3057\u305f\uff1a
|
Server.connect.exception.msg=Solr\u30b5\u30fc\u30d0\u30fc\u3078\u306e\u63a5\u7d9a\u306b\u5931\u6557\u3057\u307e\u3057\u305f\uff1a{0}
|
||||||
Server.openCore.exception.noIndexDir.msg=\u30a4\u30f3\u30c7\u30c3\u30af\u30b9\u30c7\u30a3\u30ec\u30af\u30c8\u30ea\u3092\u4f5c\u6210\u3067\u304d\u307e\u305b\u3093\u3067\u3057\u305f\u3002\u307e\u305f\u306f\u898b\u3064\u304b\u308a\u307e\u305b\u3093\u3067\u3057\u305f\u3002
|
Server.openCore.exception.noIndexDir.msg=\u30a4\u30f3\u30c7\u30c3\u30af\u30b9\u30c7\u30a3\u30ec\u30af\u30c8\u30ea\u3092\u4f5c\u6210\u3067\u304d\u307e\u305b\u3093\u3067\u3057\u305f\u3002\u307e\u305f\u306f\u898b\u3064\u304b\u308a\u307e\u305b\u3093\u3067\u3057\u305f\u3002
|
||||||
KeywordSearchIngestModule.startUp.noOpenCore.msg=\u30a4\u30f3\u30c7\u30c3\u30af\u30b9\u304c\u958b\u3051\u307e\u305b\u3093\u3067\u3057\u305f\u3002\u307e\u305f\u306f\u5b58\u5728\u3057\u307e\u305b\u3093\u3002
|
KeywordSearchIngestModule.startUp.noOpenCore.msg=\u30a4\u30f3\u30c7\u30c3\u30af\u30b9\u304c\u958b\u3051\u307e\u305b\u3093\u3067\u3057\u305f\u3002\u307e\u305f\u306f\u5b58\u5728\u3057\u307e\u305b\u3093\u3002
|
||||||
SolrConnectionCheck.HostnameOrPort=hostname\u3084\u30dd\u30fc\u30c8\u756a\u53f7\u304c\u7121\u52b9\u3067\u3059\u3002
|
SolrConnectionCheck.HostnameOrPort=hostname\u3084\u30dd\u30fc\u30c8\u756a\u53f7\u304c\u7121\u52b9\u3067\u3059\u3002
|
||||||
|
@ -19,6 +19,9 @@
|
|||||||
package org.sleuthkit.autopsy.keywordsearch;
|
package org.sleuthkit.autopsy.keywordsearch;
|
||||||
|
|
||||||
import com.google.common.collect.Iterators;
|
import com.google.common.collect.Iterators;
|
||||||
|
import com.google.common.collect.Range;
|
||||||
|
import com.google.common.collect.RangeSet;
|
||||||
|
import com.google.common.collect.TreeRangeSet;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
@ -32,6 +35,7 @@ import java.util.stream.Collectors;
|
|||||||
import javax.annotation.concurrent.GuardedBy;
|
import javax.annotation.concurrent.GuardedBy;
|
||||||
import org.apache.commons.lang.StringEscapeUtils;
|
import org.apache.commons.lang.StringEscapeUtils;
|
||||||
import org.apache.commons.lang.StringUtils;
|
import org.apache.commons.lang.StringUtils;
|
||||||
|
import org.apache.commons.lang3.math.NumberUtils;
|
||||||
import org.apache.solr.client.solrj.SolrQuery;
|
import org.apache.solr.client.solrj.SolrQuery;
|
||||||
import org.apache.solr.client.solrj.SolrRequest.METHOD;
|
import org.apache.solr.client.solrj.SolrRequest.METHOD;
|
||||||
import org.apache.solr.client.solrj.response.QueryResponse;
|
import org.apache.solr.client.solrj.response.QueryResponse;
|
||||||
@ -337,7 +341,6 @@ class HighlightedText implements IndexedText {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getText() {
|
public String getText() {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
loadPageInfo(); //inits once
|
loadPageInfo(); //inits once
|
||||||
SolrQuery q = new SolrQuery();
|
SolrQuery q = new SolrQuery();
|
||||||
@ -349,15 +352,22 @@ class HighlightedText implements IndexedText {
|
|||||||
contentIdStr += "0".equals(chunkID) ? "" : "_" + chunkID;
|
contentIdStr += "0".equals(chunkID) ? "" : "_" + chunkID;
|
||||||
}
|
}
|
||||||
final String filterQuery = Server.Schema.ID.toString() + ":" + KeywordSearchUtil.escapeLuceneQuery(contentIdStr);
|
final String filterQuery = Server.Schema.ID.toString() + ":" + KeywordSearchUtil.escapeLuceneQuery(contentIdStr);
|
||||||
|
|
||||||
|
double indexSchemaVersion = NumberUtils.toDouble(solrServer.getIndexInfo().getSchemaVersion());
|
||||||
|
//choose field to highlight based on isLiteral and Solr index schema version.
|
||||||
|
String highlightField = (isLiteral || (indexSchemaVersion < 2.0))
|
||||||
|
? LuceneQuery.HIGHLIGHT_FIELD
|
||||||
|
: Server.Schema.CONTENT_STR.toString();
|
||||||
if (isLiteral) {
|
if (isLiteral) {
|
||||||
|
//if the query is literal try to get solr to do the highlighting
|
||||||
final String highlightQuery = keywords.stream()
|
final String highlightQuery = keywords.stream()
|
||||||
.map(HighlightedText::constructEscapedSolrQuery)
|
.map(HighlightedText::constructEscapedSolrQuery)
|
||||||
.collect(Collectors.joining(" "));
|
.collect(Collectors.joining(" "));
|
||||||
|
|
||||||
q.setQuery(highlightQuery);
|
q.setQuery(highlightQuery);
|
||||||
q.addField(Server.Schema.TEXT.toString());
|
q.addField(highlightField);
|
||||||
q.addFilterQuery(filterQuery);
|
q.addFilterQuery(filterQuery);
|
||||||
q.addHighlightField(LuceneQuery.HIGHLIGHT_FIELD);
|
q.addHighlightField(highlightField);
|
||||||
q.setHighlightFragsize(0); // don't fragment the highlight, works with original highlighter, or needs "single" list builder with FVH
|
q.setHighlightFragsize(0); // don't fragment the highlight, works with original highlighter, or needs "single" list builder with FVH
|
||||||
|
|
||||||
//tune the highlighter
|
//tune the highlighter
|
||||||
@ -369,8 +379,12 @@ class HighlightedText implements IndexedText {
|
|||||||
//docs says makes sense for the original Highlighter only, but not really
|
//docs says makes sense for the original Highlighter only, but not really
|
||||||
q.setParam("hl.maxAnalyzedChars", Server.HL_ANALYZE_CHARS_UNLIMITED); //NON-NLS
|
q.setParam("hl.maxAnalyzedChars", Server.HL_ANALYZE_CHARS_UNLIMITED); //NON-NLS
|
||||||
} else {
|
} else {
|
||||||
|
/*
|
||||||
|
* if the query is not literal just pull back the text. We will
|
||||||
|
* do the highlighting in autopsy.
|
||||||
|
*/
|
||||||
q.setQuery(filterQuery);
|
q.setQuery(filterQuery);
|
||||||
q.addField(Server.Schema.CONTENT_STR.toString());
|
q.addField(highlightField);
|
||||||
}
|
}
|
||||||
|
|
||||||
QueryResponse response = solrServer.query(q, METHOD.POST);
|
QueryResponse response = solrServer.query(q, METHOD.POST);
|
||||||
@ -383,9 +397,7 @@ class HighlightedText implements IndexedText {
|
|||||||
}
|
}
|
||||||
String highlightedContent;
|
String highlightedContent;
|
||||||
Map<String, Map<String, List<String>>> responseHighlight = response.getHighlighting();
|
Map<String, Map<String, List<String>>> responseHighlight = response.getHighlighting();
|
||||||
String highlightField = isLiteral
|
|
||||||
? LuceneQuery.HIGHLIGHT_FIELD
|
|
||||||
: Server.Schema.CONTENT_STR.toString();
|
|
||||||
if (responseHighlight == null) {
|
if (responseHighlight == null) {
|
||||||
highlightedContent = attemptManualHighlighting(response.getResults(), highlightField, keywords);
|
highlightedContent = attemptManualHighlighting(response.getResults(), highlightField, keywords);
|
||||||
} else {
|
} else {
|
||||||
@ -433,6 +445,7 @@ class HighlightedText implements IndexedText {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
return this.numberOfHitsPerPage.get(this.currentPage);
|
return this.numberOfHitsPerPage.get(this.currentPage);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -445,7 +458,7 @@ class HighlightedText implements IndexedText {
|
|||||||
* to a Solr query. We expect there to only ever be
|
* to a Solr query. We expect there to only ever be
|
||||||
* a single document.
|
* a single document.
|
||||||
*
|
*
|
||||||
* @return Either a string with the keyword highlighted or a string
|
* @return Either a string with the keyword highlighted via HTML span tags or a string
|
||||||
* indicating that we did not find a hit in the document.
|
* indicating that we did not find a hit in the document.
|
||||||
*/
|
*/
|
||||||
static String attemptManualHighlighting(SolrDocumentList solrDocumentList, String highlightField, Collection<String> keywords) {
|
static String attemptManualHighlighting(SolrDocumentList solrDocumentList, String highlightField, Collection<String> keywords) {
|
||||||
@ -465,38 +478,41 @@ class HighlightedText implements IndexedText {
|
|||||||
// not see highlighted text in the content viewer.
|
// not see highlighted text in the content viewer.
|
||||||
text = StringEscapeUtils.escapeHtml(text);
|
text = StringEscapeUtils.escapeHtml(text);
|
||||||
|
|
||||||
StringBuilder highlightedText = new StringBuilder("");
|
TreeRangeSet<Integer> highlights = TreeRangeSet.create();
|
||||||
|
|
||||||
//do a highlighting pass for each keyword
|
//for each keyword find the locations of hits and record them in the RangeSet
|
||||||
for (String keyword : keywords) {
|
for (String keyword : keywords) {
|
||||||
//we also need to escape the keyword so that it matches the escpared text
|
//we also need to escape the keyword so that it matches the escaped text
|
||||||
final String escapedKeyword = StringEscapeUtils.escapeHtml(keyword);
|
final String escapedKeyword = StringEscapeUtils.escapeHtml(keyword);
|
||||||
int textOffset = 0;
|
int searchOffset = 0;
|
||||||
int hitOffset = StringUtils.indexOfIgnoreCase(text, escapedKeyword, textOffset);
|
int hitOffset = StringUtils.indexOfIgnoreCase(text, escapedKeyword, searchOffset);
|
||||||
while (hitOffset != -1) {
|
while (hitOffset != -1) {
|
||||||
// Append the portion of text up to (but not including) the hit.
|
// Advance the search offset past the keyword.
|
||||||
highlightedText.append(text.substring(textOffset, hitOffset));
|
searchOffset = hitOffset + escapedKeyword.length();
|
||||||
// Add in the highlighting around the keyword.
|
|
||||||
highlightedText.append(HIGHLIGHT_PRE);
|
|
||||||
highlightedText.append(keyword);
|
|
||||||
highlightedText.append(HIGHLIGHT_POST);
|
|
||||||
|
|
||||||
// Advance the text offset past the keyword.
|
//record the location of the hit, possibly merging it with other hits
|
||||||
textOffset = hitOffset + escapedKeyword.length();
|
highlights.add(Range.closedOpen(hitOffset, searchOffset));
|
||||||
|
|
||||||
hitOffset = StringUtils.indexOfIgnoreCase(text, escapedKeyword, textOffset);
|
//look for next hit
|
||||||
|
hitOffset = StringUtils.indexOfIgnoreCase(text, escapedKeyword, searchOffset);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// Append the remainder of text field
|
|
||||||
highlightedText.append(text.substring(textOffset, text.length()));
|
|
||||||
|
|
||||||
if (highlightedText.length() == 0) {
|
StringBuilder highlightedText = new StringBuilder(text);
|
||||||
return NbBundle.getMessage(HighlightedText.class, "HighlightedMatchesSource.getMarkup.noMatchMsg");
|
int totalHighLightLengthInserted = 0;
|
||||||
|
//for each range to be highlighted...
|
||||||
|
for (Range<Integer> highlightRange : highlights.asRanges()) {
|
||||||
|
int hStart = highlightRange.lowerEndpoint();
|
||||||
|
int hEnd = highlightRange.upperEndpoint();
|
||||||
|
|
||||||
|
//insert the pre and post tag, adjusting indices for previously added tags
|
||||||
|
highlightedText.insert(hStart + totalHighLightLengthInserted, HIGHLIGHT_PRE);
|
||||||
|
totalHighLightLengthInserted += HIGHLIGHT_PRE.length();
|
||||||
|
highlightedText.insert(hEnd + totalHighLightLengthInserted, HIGHLIGHT_POST);
|
||||||
|
totalHighLightLengthInserted += HIGHLIGHT_POST.length();
|
||||||
}
|
}
|
||||||
//reset for next pass
|
|
||||||
text = highlightedText.toString();
|
return highlightedText.toString();
|
||||||
highlightedText = new StringBuilder("");
|
|
||||||
}
|
|
||||||
return text;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* Autopsy Forensic Browser
|
* Autopsy Forensic Browser
|
||||||
*
|
*
|
||||||
* Copyright 2011-2016 Basis Technology Corp.
|
* Copyright 2011-2017 Basis Technology Corp.
|
||||||
* Contact: carrier <at> sleuthkit <dot> org
|
* Contact: carrier <at> sleuthkit <dot> org
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
@ -25,6 +25,8 @@ import java.util.Arrays;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
import net.htmlparser.jericho.Attributes;
|
import net.htmlparser.jericho.Attributes;
|
||||||
|
import net.htmlparser.jericho.Config;
|
||||||
|
import net.htmlparser.jericho.LoggerProvider;
|
||||||
import net.htmlparser.jericho.Renderer;
|
import net.htmlparser.jericho.Renderer;
|
||||||
import net.htmlparser.jericho.Source;
|
import net.htmlparser.jericho.Source;
|
||||||
import net.htmlparser.jericho.StartTag;
|
import net.htmlparser.jericho.StartTag;
|
||||||
@ -50,6 +52,11 @@ class HtmlTextExtractor extends FileTextExtractor {
|
|||||||
"text/javascript" //NON-NLS
|
"text/javascript" //NON-NLS
|
||||||
);
|
);
|
||||||
|
|
||||||
|
static {
|
||||||
|
// Disable Jericho HTML Parser log messages.
|
||||||
|
Config.LoggerProvider = LoggerProvider.DISABLED;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
boolean isContentTypeSpecific() {
|
boolean isContentTypeSpecific() {
|
||||||
return true;
|
return true;
|
||||||
|
@ -27,7 +27,7 @@ import java.util.List;
|
|||||||
import org.apache.commons.lang.math.NumberUtils;
|
import org.apache.commons.lang.math.NumberUtils;
|
||||||
import org.sleuthkit.autopsy.casemodule.Case;
|
import org.sleuthkit.autopsy.casemodule.Case;
|
||||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||||
import org.sleuthkit.autopsy.framework.AutopsyService;
|
import org.sleuthkit.autopsy.appservices.AutopsyService;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This class handles the task of finding and identifying KWS index folders.
|
* This class handles the task of finding and identifying KWS index folders.
|
||||||
|
@ -315,16 +315,16 @@ class Ingester {
|
|||||||
*
|
*
|
||||||
* @return The field map of fields that are common to all file classes.
|
* @return The field map of fields that are common to all file classes.
|
||||||
*/
|
*/
|
||||||
private Map<String, String> getCommonFields(AbstractFile af) {
|
private Map<String, String> getCommonFields(AbstractFile file) {
|
||||||
Map<String, String> params = new HashMap<>();
|
Map<String, String> params = new HashMap<>();
|
||||||
params.put(Server.Schema.ID.toString(), Long.toString(af.getId()));
|
params.put(Server.Schema.ID.toString(), Long.toString(file.getId()));
|
||||||
try {
|
try {
|
||||||
params.put(Server.Schema.IMAGE_ID.toString(), Long.toString(af.getDataSource().getId()));
|
params.put(Server.Schema.IMAGE_ID.toString(), Long.toString(file.getDataSource().getId()));
|
||||||
} catch (TskCoreException ex) {
|
} catch (TskCoreException ex) {
|
||||||
logger.log(Level.SEVERE, "Could not get data source id to properly index the file " + af.getId(), ex); //NON-NLS
|
logger.log(Level.SEVERE, "Could not get data source id to properly index the file " + file.getId(), ex); //NON-NLS
|
||||||
params.put(Server.Schema.IMAGE_ID.toString(), Long.toString(-1));
|
params.put(Server.Schema.IMAGE_ID.toString(), Long.toString(-1));
|
||||||
}
|
}
|
||||||
params.put(Server.Schema.FILE_NAME.toString(), af.getName());
|
params.put(Server.Schema.FILE_NAME.toString(), file.getName());
|
||||||
return params;
|
return params;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* Autopsy Forensic Browser
|
* Autopsy Forensic Browser
|
||||||
*
|
*
|
||||||
* Copyright 2011-2016 Basis Technology Corp.
|
* Copyright 2011-2017 Basis Technology Corp.
|
||||||
* Contact: carrier <at> sleuthkit <dot> org
|
* Contact: carrier <at> sleuthkit <dot> org
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
@ -446,7 +446,7 @@ public final class KeywordSearchIngestModule implements FileIngestModule {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (extractor == null) {
|
if (extractor == null) {
|
||||||
logger.log(Level.INFO, "No text extractor found for file id:{0}, name: {1}, detected format: {2}", new Object[]{aFile.getId(), aFile.getName(), detectedFormat}); //NON-NLS
|
// No text extractor found.
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -561,7 +561,7 @@ public final class KeywordSearchIngestModule implements FileIngestModule {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!extractTextAndIndex(aFile, fileType)) {
|
if (!extractTextAndIndex(aFile, fileType)) {
|
||||||
logger.log(Level.WARNING, "Text extractor not found for file. Extracting strings only. File: ''{0}'' (id:{1}).", new Object[]{aFile.getName(), aFile.getId()}); //NON-NLS
|
// Text extractor not found for file. Extract string only.
|
||||||
putIngestStatus(jobId, aFile.getId(), IngestStatus.SKIPPED_ERROR_TEXTEXTRACT);
|
putIngestStatus(jobId, aFile.getId(), IngestStatus.SKIPPED_ERROR_TEXTEXTRACT);
|
||||||
} else {
|
} else {
|
||||||
putIngestStatus(jobId, aFile.getId(), IngestStatus.TEXT_INGESTED);
|
putIngestStatus(jobId, aFile.getId(), IngestStatus.TEXT_INGESTED);
|
||||||
|
@ -713,7 +713,6 @@ public class Server {
|
|||||||
/**
|
/**
|
||||||
* ** end single-case specific methods ***
|
* ** end single-case specific methods ***
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Deletes the keyword search core for a case.
|
* Deletes the keyword search core for a case.
|
||||||
*
|
*
|
||||||
@ -721,41 +720,36 @@ public class Server {
|
|||||||
*/
|
*/
|
||||||
@NbBundle.Messages({
|
@NbBundle.Messages({
|
||||||
"# {0} - core name", "Server.deleteCore.exception.msg=Failed to delete Solr core {0}",})
|
"# {0} - core name", "Server.deleteCore.exception.msg=Failed to delete Solr core {0}",})
|
||||||
void deleteCore(String coreName) throws KeywordSearchServiceException {
|
void deleteCore(String coreName, Case.CaseType caseType) throws KeywordSearchServiceException {
|
||||||
/*
|
|
||||||
* Send a core unload request to the Solr server, with the parameters
|
|
||||||
* that request deleting the index and the instance directory
|
|
||||||
* (deleteInstanceDir removes everything related to the core, the index
|
|
||||||
* directory, the configuration files, etc.) set to true.
|
|
||||||
* NOTE: this method doesn't delete the actual Solr index directory. That is
|
|
||||||
* done as part of deleting case output directory.
|
|
||||||
*/
|
|
||||||
|
|
||||||
// check whether the core we are deleting is the currently open core
|
|
||||||
currentCoreLock.readLock().lock();
|
|
||||||
try {
|
try {
|
||||||
if (null != currentCore) {
|
HttpSolrServer solrServer;
|
||||||
if (currentCore.getName().equals(coreName)) {
|
if (caseType == CaseType.SINGLE_USER_CASE) {
|
||||||
// close current core first
|
Integer localSolrServerPort = Integer.decode(ModuleSettings.getConfigSetting(PROPERTIES_FILE, PROPERTIES_CURRENT_SERVER_PORT));
|
||||||
closeCore();
|
solrServer = new HttpSolrServer("http://localhost:" + localSolrServerPort + "/solr"); //NON-NLS
|
||||||
|
} else {
|
||||||
|
String host = UserPreferences.getIndexingServerHost();
|
||||||
|
String port = UserPreferences.getIndexingServerPort();
|
||||||
|
solrServer = new HttpSolrServer("http://" + host + ":" + port + "/solr"); //NON-NLS
|
||||||
}
|
}
|
||||||
}
|
|
||||||
} catch (KeywordSearchModuleException ex) {
|
|
||||||
throw new KeywordSearchServiceException(NbBundle.getMessage(Server.class, "Server.close.exception.msg"), ex);
|
|
||||||
} finally {
|
|
||||||
currentCoreLock.readLock().unlock();
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
HttpSolrServer solrServer = new HttpSolrServer("http://" + UserPreferences.getIndexingServerHost() + ":" + UserPreferences.getIndexingServerPort() + "/solr"); //NON-NLS
|
|
||||||
connectToSolrServer(solrServer);
|
connectToSolrServer(solrServer);
|
||||||
|
CoreAdminResponse response = CoreAdminRequest.getStatus(coreName, solrServer);
|
||||||
|
if (null != response.getCoreStatus(coreName).get("instanceDir")) { //NON-NLS
|
||||||
|
/*
|
||||||
|
* Send a core unload request to the Solr server, with the
|
||||||
|
* parameter set that request deleting the index and the
|
||||||
|
* instance directory (deleteInstanceDir = true). Note that this
|
||||||
|
* removes everything related to the core on the server (the
|
||||||
|
* index directory, the configuration files, etc.), but does not
|
||||||
|
* delete the actual Solr text index because it is currently
|
||||||
|
* stored in the case directory.
|
||||||
|
*/
|
||||||
org.apache.solr.client.solrj.request.CoreAdminRequest.unloadCore(coreName, true, true, solrServer);
|
org.apache.solr.client.solrj.request.CoreAdminRequest.unloadCore(coreName, true, true, solrServer);
|
||||||
} catch (SolrServerException | IOException ex) {
|
}
|
||||||
|
} catch (SolrServerException | HttpSolrServer.RemoteSolrException | IOException ex) {
|
||||||
throw new KeywordSearchServiceException(Bundle.Server_deleteCore_exception_msg(coreName), ex);
|
throw new KeywordSearchServiceException(Bundle.Server_deleteCore_exception_msg(coreName), ex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates/opens a Solr core (index) for a case.
|
* Creates/opens a Solr core (index) for a case.
|
||||||
*
|
*
|
||||||
@ -780,7 +774,7 @@ public class Server {
|
|||||||
connectToSolrServer(currentSolrServer);
|
connectToSolrServer(currentSolrServer);
|
||||||
|
|
||||||
} catch (SolrServerException | IOException ex) {
|
} catch (SolrServerException | IOException ex) {
|
||||||
throw new KeywordSearchModuleException(NbBundle.getMessage(Server.class, "Server.connect.exception.msg"), ex);
|
throw new KeywordSearchModuleException(NbBundle.getMessage(Server.class, "Server.connect.exception.msg", ex.getLocalizedMessage()), ex);
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@ -891,8 +885,8 @@ public class Server {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Execute query that gets only number of all Solr file chunks (not
|
* Execute query that gets only number of all Solr file chunks (not logical
|
||||||
* logical files) indexed without actually returning the content.
|
* files) indexed without actually returning the content.
|
||||||
*
|
*
|
||||||
* @return int representing number of indexed chunks
|
* @return int representing number of indexed chunks
|
||||||
*
|
*
|
||||||
@ -916,8 +910,8 @@ public class Server {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Execute query that gets only number of all Solr documents indexed
|
* Execute query that gets only number of all Solr documents indexed (files
|
||||||
* (files and chunks) without actually returning the documents
|
* and chunks) without actually returning the documents
|
||||||
*
|
*
|
||||||
* @return int representing number of indexed files (files and chunks)
|
* @return int representing number of indexed files (files and chunks)
|
||||||
*
|
*
|
||||||
@ -970,11 +964,10 @@ public class Server {
|
|||||||
/**
|
/**
|
||||||
* Execute query that gets number of indexed file chunks for a file
|
* Execute query that gets number of indexed file chunks for a file
|
||||||
*
|
*
|
||||||
* @param fileID file id of the original file broken into chunks and
|
* @param fileID file id of the original file broken into chunks and indexed
|
||||||
* indexed
|
|
||||||
*
|
*
|
||||||
* @return int representing number of indexed file chunks, 0 if there is
|
* @return int representing number of indexed file chunks, 0 if there is no
|
||||||
* no chunks
|
* chunks
|
||||||
*
|
*
|
||||||
* @throws KeywordSearchModuleException
|
* @throws KeywordSearchModuleException
|
||||||
* @throws NoOpenCoreException
|
* @throws NoOpenCoreException
|
||||||
@ -1206,8 +1199,7 @@ public class Server {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Determines whether or not the index files folder for a Solr core
|
* Determines whether or not the index files folder for a Solr core exists.
|
||||||
* exists.
|
|
||||||
*
|
*
|
||||||
* @param coreName the name of the core.
|
* @param coreName the name of the core.
|
||||||
*
|
*
|
||||||
@ -1385,8 +1377,8 @@ public class Server {
|
|||||||
* Execute query that gets only number of all Solr files (not chunks)
|
* Execute query that gets only number of all Solr files (not chunks)
|
||||||
* indexed without actually returning the files
|
* indexed without actually returning the files
|
||||||
*
|
*
|
||||||
* @return int representing number of indexed files (entire files,
|
* @return int representing number of indexed files (entire files, not
|
||||||
* not chunks)
|
* chunks)
|
||||||
*
|
*
|
||||||
* @throws SolrServerException
|
* @throws SolrServerException
|
||||||
*/
|
*/
|
||||||
@ -1447,11 +1439,11 @@ public class Server {
|
|||||||
/**
|
/**
|
||||||
* Execute query that gets number of indexed file chunks for a file
|
* Execute query that gets number of indexed file chunks for a file
|
||||||
*
|
*
|
||||||
* @param contentID file id of the original file broken into chunks
|
* @param contentID file id of the original file broken into chunks and
|
||||||
* and indexed
|
* indexed
|
||||||
*
|
*
|
||||||
* @return int representing number of indexed file chunks, 0 if there
|
* @return int representing number of indexed file chunks, 0 if there is
|
||||||
* is no chunks
|
* no chunks
|
||||||
*
|
*
|
||||||
* @throws SolrServerException
|
* @throws SolrServerException
|
||||||
*/
|
*/
|
||||||
|
@ -18,6 +18,7 @@
|
|||||||
*/
|
*/
|
||||||
package org.sleuthkit.autopsy.keywordsearch;
|
package org.sleuthkit.autopsy.keywordsearch;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.lang.reflect.InvocationTargetException;
|
import java.lang.reflect.InvocationTargetException;
|
||||||
import java.net.InetAddress;
|
import java.net.InetAddress;
|
||||||
@ -37,9 +38,10 @@ import org.openide.util.lookup.ServiceProviders;
|
|||||||
import org.sleuthkit.autopsy.casemodule.Case;
|
import org.sleuthkit.autopsy.casemodule.Case;
|
||||||
import org.sleuthkit.autopsy.casemodule.CaseMetadata;
|
import org.sleuthkit.autopsy.casemodule.CaseMetadata;
|
||||||
import org.sleuthkit.autopsy.core.RuntimeProperties;
|
import org.sleuthkit.autopsy.core.RuntimeProperties;
|
||||||
|
import org.sleuthkit.autopsy.coreutils.FileUtil;
|
||||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||||
import org.sleuthkit.autopsy.framework.AutopsyService;
|
import org.sleuthkit.autopsy.appservices.AutopsyService;
|
||||||
import org.sleuthkit.autopsy.framework.ProgressIndicator;
|
import org.sleuthkit.autopsy.progress.ProgressIndicator;
|
||||||
import org.sleuthkit.autopsy.keywordsearchservice.KeywordSearchService;
|
import org.sleuthkit.autopsy.keywordsearchservice.KeywordSearchService;
|
||||||
import org.sleuthkit.autopsy.keywordsearchservice.KeywordSearchServiceException;
|
import org.sleuthkit.autopsy.keywordsearchservice.KeywordSearchServiceException;
|
||||||
import org.sleuthkit.datamodel.BlackboardArtifact;
|
import org.sleuthkit.datamodel.BlackboardArtifact;
|
||||||
@ -50,7 +52,8 @@ import org.sleuthkit.datamodel.TskCoreException;
|
|||||||
* text indexing and search.
|
* text indexing and search.
|
||||||
*/
|
*/
|
||||||
@ServiceProviders(value = {
|
@ServiceProviders(value = {
|
||||||
@ServiceProvider(service = KeywordSearchService.class),
|
@ServiceProvider(service = KeywordSearchService.class)
|
||||||
|
,
|
||||||
@ServiceProvider(service = AutopsyService.class)}
|
@ServiceProvider(service = AutopsyService.class)}
|
||||||
)
|
)
|
||||||
public class SolrSearchService implements KeywordSearchService, AutopsyService {
|
public class SolrSearchService implements KeywordSearchService, AutopsyService {
|
||||||
@ -138,16 +141,17 @@ public class SolrSearchService implements KeywordSearchService, AutopsyService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@NbBundle.Messages({"# {0} - case directory",
|
|
||||||
"SolrSearchService.exceptionMessage.noIndexMetadata=Unable to create IndexMetaData from caseDirectory: {0}",
|
|
||||||
"# {0} - case directory",
|
|
||||||
"SolrSearchService.exceptionMessage.noCurrentSolrCore=IndexMetadata did not contain a current Solr core so could not delete the case"
|
|
||||||
})
|
|
||||||
/**
|
/**
|
||||||
* Deletes Solr core for a case.
|
* Deletes Solr core for a case.
|
||||||
*
|
*
|
||||||
* @param metadata The CaseMetadata which will have its core deleted.
|
* @param metadata The CaseMetadata which will have its core deleted.
|
||||||
*/
|
*/
|
||||||
|
@NbBundle.Messages({"# {0} - case directory",
|
||||||
|
"SolrSearchService.exceptionMessage.noIndexMetadata=Unable to create IndexMetaData from caseDirectory: {0}",
|
||||||
|
"# {0} - case directory",
|
||||||
|
"SolrSearchService.exceptionMessage.noCurrentSolrCore=IndexMetadata did not contain a current Solr core so could not delete the case",
|
||||||
|
"SolrSearchService.exceptionMessage.failedToDeleteIndexFiles=Failed to delete text index files at {0}"
|
||||||
|
})
|
||||||
@Override
|
@Override
|
||||||
public void deleteTextIndex(CaseMetadata metadata) throws KeywordSearchServiceException {
|
public void deleteTextIndex(CaseMetadata metadata) throws KeywordSearchServiceException {
|
||||||
String caseDirectory = metadata.getCaseDirectory();
|
String caseDirectory = metadata.getCaseDirectory();
|
||||||
@ -163,13 +167,23 @@ public class SolrSearchService implements KeywordSearchService, AutopsyService {
|
|||||||
String currentSolr = IndexFinder.getCurrentSolrVersion();
|
String currentSolr = IndexFinder.getCurrentSolrVersion();
|
||||||
for (Index index : indexMetadata.getIndexes()) {
|
for (Index index : indexMetadata.getIndexes()) {
|
||||||
if (index.getSolrVersion().equals(currentSolr) && index.getSchemaVersion().equals(currentSchema)) {
|
if (index.getSolrVersion().equals(currentSolr) && index.getSchemaVersion().equals(currentSchema)) {
|
||||||
KeywordSearch.getServer().deleteCore(index.getIndexName());
|
/*
|
||||||
|
* Unload/delete the core on the server and then delete the text
|
||||||
|
* index files.
|
||||||
|
*/
|
||||||
|
KeywordSearch.getServer().deleteCore(index.getIndexName(), metadata.getCaseType());
|
||||||
|
if (!FileUtil.deleteDir(new File(index.getIndexPath()).getParentFile())) {
|
||||||
|
throw new KeywordSearchServiceException(Bundle.SolrSearchService_exceptionMessage_failedToDeleteIndexFiles(index.getIndexPath()));
|
||||||
|
}
|
||||||
|
}
|
||||||
return; //only one core exists for each combination of solr and schema version
|
return; //only one core exists for each combination of solr and schema version
|
||||||
}
|
}
|
||||||
}
|
|
||||||
//this code this code will only execute if an index for the current core was not found
|
//this code this code will only execute if an index for the current core was not found
|
||||||
logger.log(Level.WARNING, NbBundle.getMessage(SolrSearchService.class, "SolrSearchService.exceptionMessage.noCurrentSolrCore"));
|
logger.log(Level.WARNING, NbBundle.getMessage(SolrSearchService.class,
|
||||||
throw new KeywordSearchServiceException(NbBundle.getMessage(SolrSearchService.class, "SolrSearchService.exceptionMessage.noCurrentSolrCore"));
|
"SolrSearchService.exceptionMessage.noCurrentSolrCore"));
|
||||||
|
throw new KeywordSearchServiceException(NbBundle.getMessage(SolrSearchService.class,
|
||||||
|
"SolrSearchService.exceptionMessage.noCurrentSolrCore"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -200,6 +214,10 @@ public class SolrSearchService implements KeywordSearchService, AutopsyService {
|
|||||||
"SolrSearch.openCore.msg=Opening text index",
|
"SolrSearch.openCore.msg=Opening text index",
|
||||||
"SolrSearch.complete.msg=Text index successfully opened"})
|
"SolrSearch.complete.msg=Text index successfully opened"})
|
||||||
public void openCaseResources(CaseContext context) throws AutopsyServiceException {
|
public void openCaseResources(CaseContext context) throws AutopsyServiceException {
|
||||||
|
if (context.cancelRequested()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
ProgressIndicator progress = context.getProgressIndicator();
|
ProgressIndicator progress = context.getProgressIndicator();
|
||||||
int totalNumProgressUnits = 7;
|
int totalNumProgressUnits = 7;
|
||||||
int progressUnitsCompleted = 0;
|
int progressUnitsCompleted = 0;
|
||||||
|
@ -174,13 +174,10 @@ class StringsTextExtractor extends FileTextExtractor {
|
|||||||
private final byte[] oneCharBuf = new byte[1];
|
private final byte[] oneCharBuf = new byte[1];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Construct new string stream from FsContent Do not attempt to fill
|
* Construct new string stream from FsContent. Do not attempt to fill
|
||||||
* entire read buffer if that would break a string
|
* entire read buffer if that would break a string
|
||||||
*
|
*
|
||||||
* @param content to extract strings from
|
* @param content Content object from which to extract strings.
|
||||||
* @param outputCharset target charset to encode into bytes and index
|
|
||||||
* as, e.g. UTF-8
|
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
private EnglishOnlyStream(AbstractFile content) {
|
private EnglishOnlyStream(AbstractFile content) {
|
||||||
this.content = content;
|
this.content = content;
|
||||||
@ -378,8 +375,10 @@ class StringsTextExtractor extends FileTextExtractor {
|
|||||||
private final AbstractFile content;
|
private final AbstractFile content;
|
||||||
private final byte[] oneCharBuf = new byte[1];
|
private final byte[] oneCharBuf = new byte[1];
|
||||||
private final StringExtract stringExtractor;
|
private final StringExtract stringExtractor;
|
||||||
/** true if there is nothing to do because neither extractUTF8 nor
|
/**
|
||||||
* extractUTF16 was true in constructor */
|
* true if there is nothing to do because neither extractUTF8 nor
|
||||||
|
* extractUTF16 was true in constructor
|
||||||
|
*/
|
||||||
private final boolean nothingToDo;
|
private final boolean nothingToDo;
|
||||||
private final byte[] fileReadBuff = new byte[FILE_BUF_SIZE];
|
private final byte[] fileReadBuff = new byte[FILE_BUF_SIZE];
|
||||||
private long fileReadOffset = 0L;
|
private long fileReadOffset = 0L;
|
||||||
|
@ -57,7 +57,6 @@ class TikaTextExtractor extends FileTextExtractor {
|
|||||||
@Override
|
@Override
|
||||||
public void logWarning(final String msg, Exception ex) {
|
public void logWarning(final String msg, Exception ex) {
|
||||||
KeywordSearch.getTikaLogger().log(Level.WARNING, msg, ex);
|
KeywordSearch.getTikaLogger().log(Level.WARNING, msg, ex);
|
||||||
logger.log(Level.WARNING, msg, ex); //NON-NLS }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
23
NEWS.txt
23
NEWS.txt
@ -1,3 +1,26 @@
|
|||||||
|
---------------- VERSION 4.4.0 --------------
|
||||||
|
Improvements:
|
||||||
|
- Keyword search supports regular expressions that include spaces.
|
||||||
|
- Improvements to keyword search highlighting and standard regular expressions.
|
||||||
|
- User can edit keyword lists.
|
||||||
|
- Simultaneous acquisition of a sparse VHD from a USB device during analysis.
|
||||||
|
- Support for ingest profiles that combine file ingest filters with ingest
|
||||||
|
module settings.
|
||||||
|
- Artifact attributes can be marked to indicate discovery by multiple tools.
|
||||||
|
- Import/export of interesting files set membership rules.
|
||||||
|
- High DPI display support added.
|
||||||
|
- Support for application service plug-in modules (Java only).
|
||||||
|
- Progress dialogs for case create/open/close/delete operations that support
|
||||||
|
cancellation of create/open operations and cancellation of the opening of case
|
||||||
|
resources by individual application services.
|
||||||
|
- Coordination service now used for all multi-user cases, not just auto
|
||||||
|
ingest cases; e.g., any open multi-user case cannot be deleted by another user.
|
||||||
|
- Updated Recent Activity ingest module to use RegRipper 2.8 plugins.
|
||||||
|
- Updated version of Tika used for extracting text.
|
||||||
|
- Updated version of POI used for extracting embedded MS Office documents.
|
||||||
|
- Ability to customize HTML report logo.
|
||||||
|
- Assorted small enhancements and bug fixes.
|
||||||
|
|
||||||
---------------- VERSION 4.3.0 --------------
|
---------------- VERSION 4.3.0 --------------
|
||||||
Improvements:
|
Improvements:
|
||||||
- Support for slack space on files (as separate virtual files) to enable keyword searching and other analysis.
|
- Support for slack space on files (as separate virtual files) to enable keyword searching and other analysis.
|
||||||
|
@ -17,9 +17,11 @@
|
|||||||
</target>
|
</target>
|
||||||
|
|
||||||
<!-- use manifestclasspath (http://ant.apache.org/manual/Tasks/manifestclasspath.html) to put all the jar files that we need for junit/regression test
|
<!-- use manifestclasspath (http://ant.apache.org/manual/Tasks/manifestclasspath.html) to put all the jar files that we need for junit/regression test
|
||||||
to a single jar file: allJarsInUse.jar. Then we put this new jar to classpath for testing program to avoid command line Java classpath too long problem. -->
|
to a single jar file: allJarsInUse.jar. Then we put this new jar to classpath for testing program to avoid command line Java classpath too long problem.
|
||||||
|
Note: Started from ant 1.10, maxParentLevels are enforced. If you get error from manifestclasspath complaines 'No suitable relative path from ...' then it's time to
|
||||||
|
increase your maxParentLevels -->
|
||||||
<target name="manifest-classpath">
|
<target name="manifest-classpath">
|
||||||
<manifestclasspath property="tem.classpath" jarfile="allJarsInUse.jar">
|
<manifestclasspath property="tem.classpath" jarfile="allJarsInUse.jar" maxParentLevels="5">
|
||||||
<classpath refid="test.${regression}.run.cp"/>
|
<classpath refid="test.${regression}.run.cp"/>
|
||||||
</manifestclasspath>
|
</manifestclasspath>
|
||||||
<jar destfile="allJarsInUse.jar" basedir="build/classes">
|
<jar destfile="allJarsInUse.jar" basedir="build/classes">
|
||||||
|
@ -59,11 +59,9 @@ public class AutopsyTestCases {
|
|||||||
private long start;
|
private long start;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This method is used to escape file/directory path. Example:
|
* Escapes the slashes in a file or directory path.
|
||||||
* \\NetworkLocation\foo\bar get escaped to \\\\NetworkLocation\foo\bar so
|
|
||||||
* that it can be used as intended.
|
|
||||||
*
|
*
|
||||||
* @param path
|
* @param path The path to be escaped.
|
||||||
*
|
*
|
||||||
* @return escaped path the the file/directory location.
|
* @return escaped path the the file/directory location.
|
||||||
*/
|
*/
|
||||||
@ -78,7 +76,7 @@ public class AutopsyTestCases {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public AutopsyTestCases () {
|
public AutopsyTestCases() {
|
||||||
start = 0;
|
start = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -107,7 +105,10 @@ public class AutopsyTestCases {
|
|||||||
|
|
||||||
public void testStartAddImageFileDataSource() {
|
public void testStartAddImageFileDataSource() {
|
||||||
logger.info("Starting Add Image process");
|
logger.info("Starting Add Image process");
|
||||||
WizardOperator wo = new WizardOperator("Add Data");
|
WizardOperator wo = new WizardOperator("Add Data Source");
|
||||||
|
while(!wo.btNext().isEnabled()){
|
||||||
|
new Timeout("pausing", 1000).sleep(); // give it a second till the Add Data Source dialog enabled
|
||||||
|
}
|
||||||
//select the toggle button for Disk Image or VM File it will be the first button created and proceed to next panel
|
//select the toggle button for Disk Image or VM File it will be the first button created and proceed to next panel
|
||||||
JToggleButtonOperator jtbo = new JToggleButtonOperator(wo, 0);
|
JToggleButtonOperator jtbo = new JToggleButtonOperator(wo, 0);
|
||||||
jtbo.clickMouse();
|
jtbo.clickMouse();
|
||||||
@ -123,7 +124,10 @@ public class AutopsyTestCases {
|
|||||||
|
|
||||||
public void testStartAddLogicalFilesDataSource() {
|
public void testStartAddLogicalFilesDataSource() {
|
||||||
logger.info("Starting Add Logical Files process");
|
logger.info("Starting Add Logical Files process");
|
||||||
WizardOperator wo = new WizardOperator("Add Data");
|
WizardOperator wo = new WizardOperator("Add Data Source");
|
||||||
|
while(!wo.btNext().isEnabled()){
|
||||||
|
new Timeout("pausing", 1000).sleep(); // give it a second till the Add Data Source dialog enabled
|
||||||
|
}
|
||||||
//select the toggle button for Logical Files it will be the third button created and proceed to next panel
|
//select the toggle button for Logical Files it will be the third button created and proceed to next panel
|
||||||
JToggleButtonOperator jtbo = new JToggleButtonOperator(wo, 2);
|
JToggleButtonOperator jtbo = new JToggleButtonOperator(wo, 2);
|
||||||
jtbo.clickMouse();
|
jtbo.clickMouse();
|
||||||
@ -139,7 +143,7 @@ public class AutopsyTestCases {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void testAddSourceWizard1() {
|
public void testAddSourceWizard1() {
|
||||||
WizardOperator wo = new WizardOperator("Add Data");
|
WizardOperator wo = new WizardOperator("Add Data Source");
|
||||||
while (!wo.btFinish().isEnabled()) {
|
while (!wo.btFinish().isEnabled()) {
|
||||||
new Timeout("pausing", 1000).sleep(); // give it a second (or five) to process
|
new Timeout("pausing", 1000).sleep(); // give it a second (or five) to process
|
||||||
}
|
}
|
||||||
@ -155,7 +159,10 @@ public class AutopsyTestCases {
|
|||||||
new Timeout("pausing", 10000).sleep();
|
new Timeout("pausing", 10000).sleep();
|
||||||
|
|
||||||
logger.info("Looking for hash lookup module in ingest job settings panel");
|
logger.info("Looking for hash lookup module in ingest job settings panel");
|
||||||
WizardOperator wo = new WizardOperator("Add Data");
|
WizardOperator wo = new WizardOperator("Add Data Source");
|
||||||
|
while(!wo.btNext().isEnabled()){
|
||||||
|
new Timeout("pausing", 1000).sleep(); // give it a second till the Add Data Source dialog enabled
|
||||||
|
}
|
||||||
JTableOperator jto = new JTableOperator(wo, 0);
|
JTableOperator jto = new JTableOperator(wo, 0);
|
||||||
int row = jto.findCellRow("Hash Lookup", 2, 0);
|
int row = jto.findCellRow("Hash Lookup", 2, 0);
|
||||||
jto.clickOnCell(row, 1);
|
jto.clickOnCell(row, 1);
|
||||||
@ -201,7 +208,10 @@ public class AutopsyTestCases {
|
|||||||
|
|
||||||
public void testConfigureIngest2() {
|
public void testConfigureIngest2() {
|
||||||
logger.info("Looking for keyword search module in ingest job settings panel");
|
logger.info("Looking for keyword search module in ingest job settings panel");
|
||||||
WizardOperator wo = new WizardOperator("Add Data");
|
WizardOperator wo = new WizardOperator("Add Data Source");
|
||||||
|
while(!wo.btNext().isEnabled()){
|
||||||
|
new Timeout("pausing", 1000).sleep(); // give it a second till the Add Data Source dialog enabled
|
||||||
|
}
|
||||||
JTableOperator jto = new JTableOperator(wo, 0);
|
JTableOperator jto = new JTableOperator(wo, 0);
|
||||||
int row = jto.findCellRow("Keyword Search", 2, 0);
|
int row = jto.findCellRow("Keyword Search", 2, 0);
|
||||||
jto.clickOnCell(row, 1);
|
jto.clickOnCell(row, 1);
|
||||||
@ -234,7 +244,7 @@ public class AutopsyTestCases {
|
|||||||
}
|
}
|
||||||
JButtonOperator jbo2 = new JButtonOperator(jdo, "OK", 0);
|
JButtonOperator jbo2 = new JButtonOperator(jdo, "OK", 0);
|
||||||
jbo2.pushNoBlock();
|
jbo2.pushNoBlock();
|
||||||
WizardOperator wo = new WizardOperator("Add Data");
|
WizardOperator wo = new WizardOperator("Add Data Source");
|
||||||
new Timeout("pausing", 10000).sleep(); // let things catch up
|
new Timeout("pausing", 10000).sleep(); // let things catch up
|
||||||
wo.btNext().clickMouse();
|
wo.btNext().clickMouse();
|
||||||
}
|
}
|
||||||
|
@ -76,6 +76,8 @@
|
|||||||
<unzip src="${nbdist.dir}/${app.name}.zip" dest="${zip-tmp}"/>
|
<unzip src="${nbdist.dir}/${app.name}.zip" dest="${zip-tmp}"/>
|
||||||
|
|
||||||
<!-- step (3) do your copying stuff here, check the ant doc for copy, move, etc file -->
|
<!-- step (3) do your copying stuff here, check the ant doc for copy, move, etc file -->
|
||||||
|
<copy file="${nbplatform.active.dir}/platform/modules/ext/junit-4.10.jar"
|
||||||
|
tofile="${zip-tmp}/${app.name}/platform/modules/ext/junit-4.10.jar"/>
|
||||||
<copy file="${basedir}/README.txt" tofile="${zip-tmp}/${app.name}/README.txt"/>
|
<copy file="${basedir}/README.txt" tofile="${zip-tmp}/${app.name}/README.txt"/>
|
||||||
<copy file="${basedir}/LICENSE-2.0.txt" tofile="${zip-tmp}/${app.name}/LICENSE-2.0.txt"/>
|
<copy file="${basedir}/LICENSE-2.0.txt" tofile="${zip-tmp}/${app.name}/LICENSE-2.0.txt"/>
|
||||||
<copy file="${basedir}/NEWS.txt" tofile="${zip-tmp}/${app.name}/NEWS.txt"/>
|
<copy file="${basedir}/NEWS.txt" tofile="${zip-tmp}/${app.name}/NEWS.txt"/>
|
||||||
|
18
developers/README.txt
Executable file
18
developers/README.txt
Executable file
@ -0,0 +1,18 @@
|
|||||||
|
Common NetBeans IDE settings for the Autopsy project are stored here.
|
||||||
|
All contributors are kindly asked to use these settings.
|
||||||
|
|
||||||
|
1. To make Java code formatting (pretty-printing) settings, select Tools,
|
||||||
|
Options, Editor tab, Formatting tab. Push the Import... button to pop up the
|
||||||
|
Select Options to Import dialog. Push the Browse... button to pop up a file
|
||||||
|
chooser. Select ~\autopsy\developers\netbeans_ide_formatting_settings.zip.
|
||||||
|
NetBeans IDE will require a restart for the settings to take effect. Formatting
|
||||||
|
can be done by selecting Source, Format (Alt + Shift + F).
|
||||||
|
2. To make Java code hygiene hints (lint) settings, copy the entire contents of
|
||||||
|
~\autopsy\developers\netbeans_ide_java_hint_settings to the hint/default
|
||||||
|
subdirectory of your user settings directory for the IDE. For Windows, this is
|
||||||
|
~\AppData\Roaming\NetBeans\8.2\config\Preferences\org\netbeans\modules\java\hints
|
||||||
|
\default. Restart the IDE.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
Binary file not shown.
@ -0,0 +1 @@
|
|||||||
|
enabled=true
|
1
developers/netbeans_ide_java_hint_settings/Braces_FOR_LOOP.properties
Executable file
1
developers/netbeans_ide_java_hint_settings/Braces_FOR_LOOP.properties
Executable file
@ -0,0 +1 @@
|
|||||||
|
enabled=true
|
1
developers/netbeans_ide_java_hint_settings/Braces_IF.properties
Executable file
1
developers/netbeans_ide_java_hint_settings/Braces_IF.properties
Executable file
@ -0,0 +1 @@
|
|||||||
|
enabled=true
|
1
developers/netbeans_ide_java_hint_settings/Braces_WHILE_LOOP.properties
Executable file
1
developers/netbeans_ide_java_hint_settings/Braces_WHILE_LOOP.properties
Executable file
@ -0,0 +1 @@
|
|||||||
|
enabled=true
|
1
developers/netbeans_ide_java_hint_settings/EmptyStatements_IF.properties
Executable file
1
developers/netbeans_ide_java_hint_settings/EmptyStatements_IF.properties
Executable file
@ -0,0 +1 @@
|
|||||||
|
enabled=true
|
1
developers/netbeans_ide_java_hint_settings/Imports_STAR.properties
Executable file
1
developers/netbeans_ide_java_hint_settings/Imports_STAR.properties
Executable file
@ -0,0 +1 @@
|
|||||||
|
enabled=true
|
1
developers/netbeans_ide_java_hint_settings/Javac_DEPRECATED.properties
Executable file
1
developers/netbeans_ide_java_hint_settings/Javac_DEPRECATED.properties
Executable file
@ -0,0 +1 @@
|
|||||||
|
enabled=true
|
@ -0,0 +1 @@
|
|||||||
|
enabled=true
|
@ -0,0 +1 @@
|
|||||||
|
enabled=true
|
1
developers/netbeans_ide_java_hint_settings/Javac_FALLTHROUGH.properties
Executable file
1
developers/netbeans_ide_java_hint_settings/Javac_FALLTHROUGH.properties
Executable file
@ -0,0 +1 @@
|
|||||||
|
enabled=true
|
1
developers/netbeans_ide_java_hint_settings/Javac_FINALLY.properties
Executable file
1
developers/netbeans_ide_java_hint_settings/Javac_FINALLY.properties
Executable file
@ -0,0 +1 @@
|
|||||||
|
enabled=true
|
1
developers/netbeans_ide_java_hint_settings/Javac_OVERRIDES.properties
Executable file
1
developers/netbeans_ide_java_hint_settings/Javac_OVERRIDES.properties
Executable file
@ -0,0 +1 @@
|
|||||||
|
enabled=true
|
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