mirror of
https://github.com/overcuriousity/autopsy-flatpak.git
synced 2025-07-17 10:17:41 +00:00
Merge remote-tracking branch 'upstream/develop' into Add-date-time-to-logical-files
This commit is contained in:
commit
db552aa5ae
6
.gitattributes
vendored
6
.gitattributes
vendored
@ -18,4 +18,8 @@ Doxyfile text
|
||||
/KeywordSearch/solr/bin/autopsy-solr eol=lf
|
||||
/KeywordSearch/solr/bin/init.d/solr eol=lf
|
||||
/KeywordSearch/solr/bin/post eol=lf
|
||||
/KeywordSearch/solr/bin/solr eol=lf
|
||||
/KeywordSearch/solr/bin/solr eol=lf
|
||||
|
||||
# ensure properties files and xml files in the platform don't get changed during the build
|
||||
/netbeans-plat/15/**/*.properties eol=lf
|
||||
/netbeans-plat/15/**/*.xml eol=lf
|
224
.gitignore
vendored
224
.gitignore
vendored
@ -1,111 +1,113 @@
|
||||
/dist/
|
||||
/build/
|
||||
/*/build/
|
||||
*/nbproject/private/*
|
||||
/nbproject/private/*
|
||||
/apidiff_output/
|
||||
|
||||
/Core/release/
|
||||
/Core/src/org/sleuthkit/autopsy/coreutils/Version.properties
|
||||
/Core/src/org/sleuthkit/autopsy/casemodule/docs/QuickStart.html
|
||||
/Core/src/org/sleuthkit/autopsy/casemodule/docs/screenshot.png
|
||||
/Core/src/org/sleuthkit/autopsy/datamodel/ranges.csv
|
||||
/Core/build/
|
||||
/Core/dist/
|
||||
/Core/nbproject/*
|
||||
/Core/test/qa-functional/data/*
|
||||
!/Core/nbproject/project.xml
|
||||
!/Core/nbproject/project.properties
|
||||
|
||||
/CoreLibs/release/
|
||||
/CoreLibs/build/
|
||||
/CoreLibs/dist/
|
||||
/CoreLibs/nbproject/*
|
||||
!/CoreLibs/nbproject/project.xml
|
||||
!/CoreLibs/nbproject/project.properties
|
||||
|
||||
/CoreTestLibs/release/
|
||||
/CoreTestLibs/build/
|
||||
/CoreTestLibs/dist/
|
||||
|
||||
/Core/test/qa-functional/data/*
|
||||
!/Core/test/qa-functional/data/PasswordDetection_img1_v1.img
|
||||
|
||||
/KeywordSearch/release/
|
||||
/KeywordSearch/build/
|
||||
/KeywordSearch/dist/
|
||||
/KeywordSearch/nbproject/*
|
||||
!/KeywordSearch/nbproject/project.xml
|
||||
!/KeywordSearch/nbproject/project.properties
|
||||
|
||||
*/genfiles.properties
|
||||
genfiles.properties
|
||||
|
||||
/branding/core/core.jar/org/netbeans/core/startup/Bundle.properties
|
||||
/branding/modules/org-netbeans-core-windows.jar/org/netbeans/core/windows/view/ui/Bundle.properties
|
||||
/branding/build/
|
||||
/branding/dist/
|
||||
/branding/nbproject/*
|
||||
!/branding/nbproject/project.xml
|
||||
!/branding/nbproject/project.properties
|
||||
|
||||
/test/input/*
|
||||
!/test/input/notablehashes.txt-md5.idx
|
||||
!/test/input/notablekeywords.xml
|
||||
!/test/input/NSRL.txt-md5.idx
|
||||
/test/output/*
|
||||
!/test/output/gold
|
||||
/test/script/output_dir_link.txt
|
||||
/test/output/gold/tmp
|
||||
/test/script/ScriptLog.txt
|
||||
/test/script/__pycache__/
|
||||
/test/script/*.pyc
|
||||
/test/script/DBDump-Diff.txt
|
||||
/test/script/DBDump.txt
|
||||
/test/script/SortedData-Diff.txt
|
||||
/test/script/SortedData.txt
|
||||
/test/script/myconfig.xml
|
||||
/test/script/*/*.xml
|
||||
/test/build/
|
||||
/test/dist/
|
||||
/test/nbproject/*
|
||||
|
||||
!/Testing/nbproject/project.xml
|
||||
!/Testing/nbproject/project.properties
|
||||
*~
|
||||
/netbeans-plat
|
||||
/docs/doxygen-user/user-docs
|
||||
/docs/doxygen-dev/build-docs
|
||||
/jdiff-javadocs/*
|
||||
/jdiff-logs/*
|
||||
/gen_version.txt
|
||||
hs_err_pid*.log
|
||||
|
||||
.DS_Store
|
||||
.*.swp
|
||||
/Experimental/release/
|
||||
/ImageGallery/release/
|
||||
/thunderbirdparser/release/
|
||||
/RecentActivity/release/
|
||||
/CentralRepository/release/
|
||||
/Tika/release
|
||||
|
||||
.idea/
|
||||
*.iml
|
||||
|
||||
*.img
|
||||
*.vhd
|
||||
*.E01
|
||||
|
||||
/thirdparty/yara/yarabridge/yarabridge/x64/
|
||||
/thirdparty/yara/yarabridge/yarabridge.VC.db
|
||||
/thirdparty/yara/yarabridge/yarabridge.VC.VC.opendb
|
||||
/thirdparty/yara/yarabridge/x64/
|
||||
/thirdparty/yara/YaraWrapperTest/nbproject/private/
|
||||
/thirdparty/yara/YaraWrapperTest/build/
|
||||
/thirdparty/yara/YaraJNIWrapper/dist/
|
||||
/thirdparty/yara/YaraJNIWrapper/build/
|
||||
/thirdparty/yara/YaraJNIWrapper/nbproject/private/
|
||||
/thirdparty/yara/yarabridge/.vs/
|
||||
|
||||
*/path_list.txt
|
||||
/dist/
|
||||
/build/
|
||||
/*/build/
|
||||
*/nbproject/private/*
|
||||
/nbproject/private/*
|
||||
/apidiff_output/
|
||||
|
||||
/Core/release/
|
||||
/Core/src/org/sleuthkit/autopsy/coreutils/Version.properties
|
||||
/Core/src/org/sleuthkit/autopsy/casemodule/docs/QuickStart.html
|
||||
/Core/src/org/sleuthkit/autopsy/casemodule/docs/screenshot.png
|
||||
/Core/src/org/sleuthkit/autopsy/datamodel/ranges.csv
|
||||
/Core/build/
|
||||
/Core/dist/
|
||||
/Core/nbproject/*
|
||||
/Core/test/qa-functional/data/*
|
||||
!/Core/nbproject/project.xml
|
||||
!/Core/nbproject/project.properties
|
||||
|
||||
/CoreLibs/release/
|
||||
/CoreLibs/build/
|
||||
/CoreLibs/dist/
|
||||
/CoreLibs/nbproject/*
|
||||
!/CoreLibs/nbproject/project.xml
|
||||
!/CoreLibs/nbproject/project.properties
|
||||
|
||||
/CoreTestLibs/release/
|
||||
/CoreTestLibs/build/
|
||||
/CoreTestLibs/dist/
|
||||
|
||||
/Core/test/qa-functional/data/*
|
||||
!/Core/test/qa-functional/data/PasswordDetection_img1_v1.img
|
||||
|
||||
/KeywordSearch/release/
|
||||
/KeywordSearch/build/
|
||||
/KeywordSearch/dist/
|
||||
/KeywordSearch/nbproject/*
|
||||
!/KeywordSearch/nbproject/project.xml
|
||||
!/KeywordSearch/nbproject/project.properties
|
||||
|
||||
*/genfiles.properties
|
||||
genfiles.properties
|
||||
|
||||
/branding/core/core.jar/org/netbeans/core/startup/Bundle.properties
|
||||
/branding/modules/org-netbeans-core-windows.jar/org/netbeans/core/windows/view/ui/Bundle.properties
|
||||
/branding/build/
|
||||
/branding/dist/
|
||||
/branding/nbproject/*
|
||||
!/branding/nbproject/project.xml
|
||||
!/branding/nbproject/project.properties
|
||||
|
||||
/test/input/*
|
||||
!/test/input/notablehashes.txt-md5.idx
|
||||
!/test/input/notablekeywords.xml
|
||||
!/test/input/NSRL.txt-md5.idx
|
||||
/test/output/*
|
||||
!/test/output/gold
|
||||
/test/script/output_dir_link.txt
|
||||
/test/output/gold/tmp
|
||||
/test/script/ScriptLog.txt
|
||||
/test/script/__pycache__/
|
||||
/test/script/*.pyc
|
||||
/test/script/DBDump-Diff.txt
|
||||
/test/script/DBDump.txt
|
||||
/test/script/SortedData-Diff.txt
|
||||
/test/script/SortedData.txt
|
||||
/test/script/myconfig.xml
|
||||
/test/script/*/*.xml
|
||||
/test/build/
|
||||
/test/dist/
|
||||
/test/nbproject/*
|
||||
|
||||
!/Testing/nbproject/project.xml
|
||||
!/Testing/nbproject/project.properties
|
||||
*~
|
||||
/netbeans-plat/*
|
||||
# include netbeans platform 15 because it doesn't seem to download consistently or is being updated
|
||||
!/netbeans-plat/15
|
||||
/docs/doxygen-user/user-docs
|
||||
/docs/doxygen-dev/build-docs
|
||||
/jdiff-javadocs/*
|
||||
/jdiff-logs/*
|
||||
/gen_version.txt
|
||||
hs_err_pid*.log
|
||||
|
||||
.DS_Store
|
||||
.*.swp
|
||||
/Experimental/release/
|
||||
/ImageGallery/release/
|
||||
/thunderbirdparser/release/
|
||||
/RecentActivity/release/
|
||||
/CentralRepository/release/
|
||||
/Tika/release
|
||||
|
||||
.idea/
|
||||
*.iml
|
||||
|
||||
*.img
|
||||
*.vhd
|
||||
*.E01
|
||||
|
||||
/thirdparty/yara/yarabridge/yarabridge/x64/
|
||||
/thirdparty/yara/yarabridge/yarabridge.VC.db
|
||||
/thirdparty/yara/yarabridge/yarabridge.VC.VC.opendb
|
||||
/thirdparty/yara/yarabridge/x64/
|
||||
/thirdparty/yara/YaraWrapperTest/nbproject/private/
|
||||
/thirdparty/yara/YaraWrapperTest/build/
|
||||
/thirdparty/yara/YaraJNIWrapper/dist/
|
||||
/thirdparty/yara/YaraJNIWrapper/build/
|
||||
/thirdparty/yara/YaraJNIWrapper/nbproject/private/
|
||||
/thirdparty/yara/yarabridge/.vs/
|
||||
|
||||
*/path_list.txt
|
||||
|
77
.travis.yml
77
.travis.yml
@ -1,5 +1,4 @@
|
||||
language: java
|
||||
sudo: required
|
||||
|
||||
jobs:
|
||||
include:
|
||||
@ -9,63 +8,61 @@ jobs:
|
||||
osx_image: xcode12.2
|
||||
|
||||
env:
|
||||
global:
|
||||
- TSK_HOME=$TRAVIS_BUILD_DIR/sleuthkit/sleuthkit
|
||||
global:
|
||||
- TSK_HOME=$TRAVIS_BUILD_DIR/sleuthkit/sleuthkit
|
||||
|
||||
addons:
|
||||
apt:
|
||||
update: true
|
||||
packages:
|
||||
- testdisk
|
||||
- libafflib-dev
|
||||
- libewf-dev
|
||||
- libpq-dev
|
||||
- autopoint
|
||||
- libsqlite3-dev
|
||||
- ant
|
||||
- ant-optional
|
||||
- libcppunit-dev
|
||||
- wget
|
||||
- openjdk-8-jdk
|
||||
- openjfx=8u161-b12-1ubuntu2
|
||||
- libopenjfx-java=8u161-b12-1ubuntu2
|
||||
- libopenjfx-jni=8u161-b12-1ubuntu2
|
||||
- testdisk
|
||||
- libafflib-dev
|
||||
- libewf-dev
|
||||
- libpq-dev
|
||||
- autopoint
|
||||
- libsqlite3-dev
|
||||
- ant
|
||||
- ant-optional
|
||||
- libcppunit-dev
|
||||
- wget
|
||||
homebrew:
|
||||
update: true
|
||||
packages:
|
||||
- ant
|
||||
- wget
|
||||
- libpq
|
||||
- libewf
|
||||
- gettext
|
||||
- cppunit
|
||||
- afflib
|
||||
- testdisk
|
||||
- ant
|
||||
- wget
|
||||
- libpq
|
||||
- libewf
|
||||
- gettext
|
||||
- cppunit
|
||||
- afflib
|
||||
- testdisk
|
||||
|
||||
python:
|
||||
- "2.7"
|
||||
- 2.7
|
||||
|
||||
before_install:
|
||||
- git clone https://github.com/sleuthkit/sleuthkit.git sleuthkit/sleuthkit
|
||||
- python setupSleuthkitBranch.py
|
||||
- git clone https://github.com/sleuthkit/sleuthkit.git sleuthkit/sleuthkit
|
||||
- python setupSleuthkitBranch.py
|
||||
|
||||
install:
|
||||
- pushd sleuthkit/sleuthkit && ./travis_install_libs.sh && popd
|
||||
- pushd sleuthkit/sleuthkit && ./travis_install_libs.sh && popd
|
||||
|
||||
before_script:
|
||||
- if [ $TRAVIS_OS_NAME = linux ]; then
|
||||
sudo update-alternatives --set java /usr/lib/jvm/java-8-openjdk-amd64/jre/bin/java;
|
||||
sudo update-alternatives --set javac /usr/lib/jvm/java-8-openjdk-amd64/bin/javac;
|
||||
export PATH=/usr/bin:$PATH;
|
||||
unset JAVA_HOME;
|
||||
wget -q -O - https://download.bell-sw.com/pki/GPG-KEY-bellsoft | sudo apt-key add -;
|
||||
echo "deb [arch=amd64] https://apt.bell-sw.com/ stable main" | sudo tee /etc/apt/sources.list.d/bellsoft.list;
|
||||
sudo apt-get update;
|
||||
sudo apt-get install bellsoft-java17-full;
|
||||
export PATH=/usr/bin:$PATH;
|
||||
export JAVA_HOME=/usr/lib/jvm/bellsoft-java17-full-amd64;
|
||||
fi
|
||||
- if [ $TRAVIS_OS_NAME = osx ]; then
|
||||
brew uninstall java --force;
|
||||
brew cask uninstall java --force;
|
||||
brew tap homebrew/cask-versions;
|
||||
brew cask install corretto8;
|
||||
export JAVA_HOME=/Library/Java/JavaVirtualMachines/amazon-corretto-8.jdk/Contents/Home;
|
||||
- if [ $TRAVIS_OS_NAME = osx ]; then
|
||||
brew uninstall java --force --ignore-dependencies;
|
||||
brew cask uninstall java --force;
|
||||
brew tap bell-sw/liberica;
|
||||
brew install --cask liberica-jdk17-full;
|
||||
export JAVA_HOME=/Library/Java/JavaVirtualMachines/liberica-jdk-17-full.jdk/Contents/Home;
|
||||
fi
|
||||
- java -version
|
||||
|
||||
script: ./travis_build.sh
|
||||
script: ./travis_build.sh
|
@ -310,41 +310,19 @@
|
||||
(i.e. https://stackoverflow.com/questions/219585/including-all-the-jars-in-a-directory-within-the-java-classpath).
|
||||
This solution involves taking the initial ‘module.run.classpath’ property and simplifying it to the directories containing jars
|
||||
(i.e. instead of “/dir/lib1.jar:/dir/lib2.jar:/dir/lib3.jar” it becomes “/dir/*” ).
|
||||
More information on ‘module.run.classpath’ can be found in “netbeans-plat\11.3\harness\README” and it appears that
|
||||
“netbeans-plat\11.3\harness\build.xml:build-init target is in charge of setting the ‘module.run.classpath’ variable.
|
||||
More information on ‘module.run.classpath’ can be found in “netbeans-plat\15\harness\README” and it appears that
|
||||
“netbeans-plat\15\harness\build.xml:build-init target is in charge of setting the ‘module.run.classpath’ variable.
|
||||
More information in Jira: 6970.
|
||||
-->
|
||||
<target name="unit-test-path-simplification" depends="projectized-common.test-init">
|
||||
<property name="unit-test-path-simplification.dir.path" value="${thirdparty.dir}/ClasspathSimplification/target"/>
|
||||
<property name="unit-test-path-simplification.jar.path" value="${unit-test-path-simplification.dir.path}/ClasspathSimplification-1.0-jar-with-dependencies.jar"/>
|
||||
<taskdef name="classpathsimplify" classname="org.sleuthkit.autopsy.classpathsimplification.ClasspathSimplification" classpath="${unit-test-path-simplification.jar.path}"/>
|
||||
|
||||
|
||||
<sequential>
|
||||
<script language="javascript">
|
||||
<![CDATA[
|
||||
var moduleRunClasspath = project.getProperty("module.run.classpath");
|
||||
|
||||
var directories = [];
|
||||
// searches for jar file parent directories with path separators of \ or /
|
||||
var individualPathRegex = /^\s*(.+?[\\\/])[^\\\/]+?\.jar\s*$/i;
|
||||
// split on ':' but not 'C:\'
|
||||
var classPathRegex = /((C:\\)?.+?)(:|$)/gi;
|
||||
var match;
|
||||
while((match = classPathRegex.exec(moduleRunClasspath)) !== null) {
|
||||
var thisPath = match[1];
|
||||
var pathMatch = thisPath.match(individualPathRegex);
|
||||
// find unique matches
|
||||
if (pathMatch && directories.indexOf(pathMatch[1]) < 0) {
|
||||
directories.push(pathMatch[1]);
|
||||
}
|
||||
}
|
||||
|
||||
// suffix with *
|
||||
for (var i = 0; i < directories.length; i++) {
|
||||
directories[i] = directories[i] + "*";
|
||||
}
|
||||
|
||||
// set project property
|
||||
project.setNewProperty("test.unit.abbreviatedModuleRunClassPath", directories.join(":"));
|
||||
]]>
|
||||
</script>
|
||||
|
||||
<classpathsimplify classpath="${module.run.classpath}" outputprop="test.unit.abbreviatedModuleRunClassPath" />
|
||||
|
||||
<!--grab properties from common.xml:test-init so that "test.unit.run.cp" can be properly formed-->
|
||||
<property name="build.test.unit.dir" location="${build.dir}/test/unit"/>
|
||||
<property name="build.test.unit.classes.dir" location="${build.test.unit.dir}/classes"/>
|
||||
|
@ -40,6 +40,10 @@
|
||||
|
||||
<!-- for handling diffs -->
|
||||
<dependency conf="core->default" org="io.github.java-diff-utils" name="java-diff-utils" rev="4.11"/>
|
||||
|
||||
<!-- JAXB -->
|
||||
<dependency conf="core->default" org="javax.xml.bind" name="jaxb-api" rev="2.3.1"/>
|
||||
<dependency conf="core->default" org="org.glassfish.jaxb" name="jaxb-runtime" rev="2.3.3"/>
|
||||
|
||||
<dependency conf="core->default" org="org.icepdf.os" name="icepdf-viewer" rev="6.2.2">
|
||||
<!-- get the new latest batik items below, override bouncy castle -->
|
||||
|
@ -1,16 +1,16 @@
|
||||
cluster.path=\
|
||||
${nbplatform.active.dir}/platform
|
||||
disabled.modules=\
|
||||
org.netbeans.api.visual,\
|
||||
org.netbeans.core.execution,\
|
||||
org.netbeans.core.multiview,\
|
||||
org.netbeans.libs.jsr223,\
|
||||
org.netbeans.modules.autoupdate.services,\
|
||||
org.netbeans.modules.autoupdate.ui,\
|
||||
org.netbeans.modules.core.kit,\
|
||||
org.netbeans.modules.favorites,\
|
||||
org.openide.compat,\
|
||||
org.openide.execution,\
|
||||
org.openide.options,\
|
||||
org.openide.util.enumerations
|
||||
nbplatform.active=default
|
||||
# cluster.path=\
|
||||
# ${nbplatform.active.dir}/platform
|
||||
# disabled.modules=\
|
||||
# org.netbeans.api.visual,\
|
||||
# org.netbeans.core.execution,\
|
||||
# org.netbeans.core.multiview,\
|
||||
# org.netbeans.libs.jsr223,\
|
||||
# org.netbeans.modules.autoupdate.services,\
|
||||
# org.netbeans.modules.autoupdate.ui,\
|
||||
# org.netbeans.modules.core.kit,\
|
||||
# org.netbeans.modules.favorites,\
|
||||
# org.openide.compat,\
|
||||
# org.openide.execution,\
|
||||
# org.openide.options,\
|
||||
# org.openide.util.enumerations
|
||||
# nbplatform.active=default
|
||||
|
@ -1,7 +1,13 @@
|
||||
file.reference.activemq-all-5.16.4.jar=release/modules/ext/activemq-all-5.16.4.jar
|
||||
file.reference.audience-annotations-0.12.0.jar=release/modules/ext/audience-annotations-0.12.0.jar
|
||||
file.reference.batik-awt-util-1.14.jar=release/modules/ext/batik-awt-util-1.14.jar
|
||||
file.reference.batik-constants-1.14.jar=release/modules/ext/batik-constants-1.14.jar
|
||||
file.reference.batik-css-1.14.jar=release/modules/ext/batik-css-1.14.jar
|
||||
file.reference.batik-dom-1.14.jar=release/modules/ext/batik-dom-1.14.jar
|
||||
file.reference.batik-ext-1.14.jar=release/modules/ext/batik-ext-1.14.jar
|
||||
file.reference.batik-i18n-1.14.jar=release/modules/ext/batik-i18n-1.14.jar
|
||||
file.reference.batik-parser-1.14.jar=release/modules/ext/batik-parser-1.14.jar
|
||||
file.reference.batik-shared-resources-1.14.jar=release/modules/ext/batik-shared-resources-1.14.jar
|
||||
file.reference.batik-svg-dom-1.14.jar=release/modules/ext/batik-svg-dom-1.14.jar
|
||||
file.reference.batik-svggen-1.14.jar=release/modules/ext/batik-svggen-1.14.jar
|
||||
file.reference.batik-util-1.14.jar=release/modules/ext/batik-util-1.14.jar
|
||||
@ -9,6 +15,7 @@ file.reference.batik-xml-1.14.jar=release/modules/ext/batik-xml-1.14.jar
|
||||
file.reference.bcpkix-jdk15on-1.70.jar=release/modules/ext/bcpkix-jdk15on-1.70.jar
|
||||
file.reference.bcprov-ext-jdk15on-1.70.jar=release/modules/ext/bcprov-ext-jdk15on-1.70.jar
|
||||
file.reference.bcprov-jdk15on-1.70.jar=release/modules/ext/bcprov-jdk15on-1.70.jar
|
||||
file.reference.bcutil-jdk15on-1.70.jar=release/modules/ext/bcutil-jdk15on-1.70.jar
|
||||
file.reference.c3p0-0.9.5.5.jar=release/modules/ext/c3p0-0.9.5.5.jar
|
||||
file.reference.checker-qual-3.12.0.jar=release/modules/ext/checker-qual-3.12.0.jar
|
||||
file.reference.commons-dbcp2-2.9.0.jar=release/modules/ext/commons-dbcp2-2.9.0.jar
|
||||
@ -26,13 +33,19 @@ file.reference.failureaccess-1.0.1.jar=release/modules/ext/failureaccess-1.0.1.j
|
||||
file.reference.guava-31.1-jre.jar=release/modules/ext/guava-31.1-jre.jar
|
||||
file.reference.icepdf-core-6.2.2.jar=release/modules/ext/icepdf-core-6.2.2.jar
|
||||
file.reference.icepdf-viewer-6.2.2.jar=release/modules/ext/icepdf-viewer-6.2.2.jar
|
||||
file.reference.istack-commons-runtime-3.0.11.jar=release/modules/ext/istack-commons-runtime-3.0.11.jar
|
||||
file.reference.j2objc-annotations-1.3.jar=release/modules/ext/j2objc-annotations-1.3.jar
|
||||
file.reference.jackcess-4.0.1.jar=release/modules/ext/jackcess-4.0.1.jar
|
||||
file.reference.jackcess-encrypt-4.0.1.jar=release/modules/ext/jackcess-encrypt-4.0.1.jar
|
||||
file.reference.jai_core-1.1.3.jar=release/modules/ext/jai_core-1.1.3.jar
|
||||
file.reference.jai_imageio-1.1.jar=release/modules/ext/jai_imageio-1.1.jar
|
||||
file.reference.jakarta.activation-1.2.2.jar=release/modules/ext/jakarta.activation-1.2.2.jar
|
||||
file.reference.jakarta.xml.bind-api-2.3.3.jar=release/modules/ext/jakarta.xml.bind-api-2.3.3.jar
|
||||
file.reference.java-diff-utils-4.11.jar=release/modules/ext/java-diff-utils-4.11.jar
|
||||
file.reference.javax.activation-api-1.2.0.jar=release/modules/ext/javax.activation-api-1.2.0.jar
|
||||
file.reference.javax.ws.rs-api-2.1.1.jar=release/modules/ext/javax.ws.rs-api-2.1.1.jar
|
||||
file.reference.jaxb-api-2.3.1.jar=release/modules/ext/jaxb-api-2.3.1.jar
|
||||
file.reference.jaxb-runtime-2.3.3.jar=release/modules/ext/jaxb-runtime-2.3.3.jar
|
||||
file.reference.jdom-2.0.5.jar=release/modules/ext/jdom-2.0.5.jar
|
||||
file.reference.jfreechart-1.5.3.jar=release/modules/ext/jfreechart-1.5.3.jar
|
||||
file.reference.jgraphx-4.2.2.jar=release/modules/ext/jgraphx-4.2.2.jar
|
||||
@ -62,19 +75,25 @@ file.reference.okhttp-2.7.5.jar=release/modules/ext/okhttp-2.7.5.jar
|
||||
file.reference.okio-1.6.0.jar=release/modules/ext/okio-1.6.0.jar
|
||||
file.reference.postgresql-42.3.5.jar=release/modules/ext/postgresql-42.3.5.jar
|
||||
file.reference.Rejistry-1.1-SNAPSHOT.jar=release/modules/ext/Rejistry-1.1-SNAPSHOT.jar
|
||||
file.reference.serializer-2.7.2.jar=release/modules/ext/serializer-2.7.2.jar
|
||||
file.reference.sevenzipjbinding-AllPlatforms.jar=release/modules/ext/sevenzipjbinding-AllPlatforms.jar
|
||||
file.reference.sevenzipjbinding.jar=release/modules/ext/sevenzipjbinding.jar
|
||||
file.reference.sleuthkit-4.11.1.jar=release/modules/ext/sleuthkit-4.11.1.jar
|
||||
file.reference.sleuthkit-caseuco-4.11.1.jar=release/modules/ext/sleuthkit-caseuco-4.11.1.jar
|
||||
file.reference.sleuthkit-4.12.0.jar=release/modules/ext/sleuthkit-4.12.0.jar
|
||||
file.reference.sleuthkit-caseuco-4.12.0.jar=release/modules/ext/sleuthkit-caseuco-4.12.0.jar
|
||||
file.reference.snakeyaml-1.30.jar=release/modules/ext/snakeyaml-1.30.jar
|
||||
file.reference.SparseBitSet-1.1.jar=release/modules/ext/SparseBitSet-1.1.jar
|
||||
file.reference.spotbugs-annotations-4.6.0.jar=release/modules/ext/spotbugs-annotations-4.6.0.jar
|
||||
file.reference.sqlite-jdbc-3.36.0.3.jar=release/modules/ext/sqlite-jdbc-3.36.0.3.jar
|
||||
file.reference.txw2-2.3.3.jar=release/modules/ext/txw2-2.3.3.jar
|
||||
file.reference.xalan-2.7.2.jar=release/modules/ext/xalan-2.7.2.jar
|
||||
file.reference.xml-apis-1.4.01.jar=release/modules/ext/xml-apis-1.4.01.jar
|
||||
file.reference.xml-apis-ext-1.3.04.jar=release/modules/ext/xml-apis-ext-1.3.04.jar
|
||||
file.reference.xmlgraphics-commons-2.6.jar=release/modules/ext/xmlgraphics-commons-2.6.jar
|
||||
file.reference.xmpcore-6.1.11.jar=release/modules/ext/xmpcore-6.1.11.jar
|
||||
file.reference.YaraJNIWrapper.jar=release/modules/ext/YaraJNIWrapper.jar
|
||||
file.reference.zookeeper-3.8.0.jar=release/modules/ext/zookeeper-3.8.0.jar
|
||||
file.reference.zookeeper-jute-3.8.0.jar=release/modules/ext/zookeeper-jute-3.8.0.jar
|
||||
javac.source=1.8
|
||||
javac.source=17
|
||||
javac.compilerargs=-Xlint -Xlint:-serial
|
||||
license.file=../LICENSE-2.0.txt
|
||||
nbm.homepage=http://www.sleuthkit.org/
|
||||
|
@ -12,7 +12,7 @@
|
||||
<compile-dependency/>
|
||||
<run-dependency>
|
||||
<release-version>1</release-version>
|
||||
<specification-version>1.28.1</specification-version>
|
||||
<specification-version>1.65</specification-version>
|
||||
</run-dependency>
|
||||
</dependency>
|
||||
<dependency>
|
||||
@ -20,7 +20,7 @@
|
||||
<build-prerequisite/>
|
||||
<compile-dependency/>
|
||||
<run-dependency>
|
||||
<specification-version>1.46.1</specification-version>
|
||||
<specification-version>1.64</specification-version>
|
||||
</run-dependency>
|
||||
</dependency>
|
||||
<dependency>
|
||||
@ -28,7 +28,7 @@
|
||||
<build-prerequisite/>
|
||||
<compile-dependency/>
|
||||
<run-dependency>
|
||||
<specification-version>1.46.1</specification-version>
|
||||
<specification-version>1.65</specification-version>
|
||||
</run-dependency>
|
||||
</dependency>
|
||||
<dependency>
|
||||
@ -36,7 +36,7 @@
|
||||
<build-prerequisite/>
|
||||
<compile-dependency/>
|
||||
<run-dependency>
|
||||
<specification-version>1.6.1</specification-version>
|
||||
<specification-version>1.25</specification-version>
|
||||
</run-dependency>
|
||||
</dependency>
|
||||
<dependency>
|
||||
@ -48,13 +48,31 @@
|
||||
<implementation-version/>
|
||||
</run-dependency>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<code-name-base>org.netbeans.core.multitabs</code-name-base>
|
||||
<build-prerequisite/>
|
||||
<compile-dependency/>
|
||||
<run-dependency>
|
||||
<release-version>1</release-version>
|
||||
<implementation-version/>
|
||||
</run-dependency>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<code-name-base>org.netbeans.core.windows</code-name-base>
|
||||
<build-prerequisite/>
|
||||
<compile-dependency/>
|
||||
<run-dependency>
|
||||
<release-version>2</release-version>
|
||||
<implementation-version/>
|
||||
</run-dependency>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<code-name-base>org.netbeans.modules.options.api</code-name-base>
|
||||
<build-prerequisite/>
|
||||
<compile-dependency/>
|
||||
<run-dependency>
|
||||
<release-version>1</release-version>
|
||||
<specification-version>1.26.1</specification-version>
|
||||
<specification-version>1.62</specification-version>
|
||||
</run-dependency>
|
||||
</dependency>
|
||||
<dependency>
|
||||
@ -63,7 +81,7 @@
|
||||
<compile-dependency/>
|
||||
<run-dependency>
|
||||
<release-version>2</release-version>
|
||||
<specification-version>2.25.1</specification-version>
|
||||
<specification-version>2.53</specification-version>
|
||||
</run-dependency>
|
||||
</dependency>
|
||||
<dependency>
|
||||
@ -72,7 +90,7 @@
|
||||
<compile-dependency/>
|
||||
<run-dependency>
|
||||
<release-version>1</release-version>
|
||||
<specification-version>1.35.1</specification-version>
|
||||
<specification-version>1.66</specification-version>
|
||||
</run-dependency>
|
||||
</dependency>
|
||||
<dependency>
|
||||
@ -80,7 +98,7 @@
|
||||
<build-prerequisite/>
|
||||
<compile-dependency/>
|
||||
<run-dependency>
|
||||
<specification-version>1.14.1</specification-version>
|
||||
<specification-version>1.44</specification-version>
|
||||
</run-dependency>
|
||||
</dependency>
|
||||
<dependency>
|
||||
@ -88,7 +106,7 @@
|
||||
<build-prerequisite/>
|
||||
<compile-dependency/>
|
||||
<run-dependency>
|
||||
<specification-version>1.20.1</specification-version>
|
||||
<specification-version>1.51</specification-version>
|
||||
</run-dependency>
|
||||
</dependency>
|
||||
<dependency>
|
||||
@ -96,7 +114,7 @@
|
||||
<build-prerequisite/>
|
||||
<compile-dependency/>
|
||||
<run-dependency>
|
||||
<specification-version>1.25.1</specification-version>
|
||||
<specification-version>1.59</specification-version>
|
||||
</run-dependency>
|
||||
</dependency>
|
||||
<dependency>
|
||||
@ -104,7 +122,7 @@
|
||||
<build-prerequisite/>
|
||||
<compile-dependency/>
|
||||
<run-dependency>
|
||||
<specification-version>1.36.1</specification-version>
|
||||
<specification-version>1.74</specification-version>
|
||||
</run-dependency>
|
||||
</dependency>
|
||||
<dependency>
|
||||
@ -112,7 +130,7 @@
|
||||
<build-prerequisite/>
|
||||
<compile-dependency/>
|
||||
<run-dependency>
|
||||
<specification-version>6.26.1</specification-version>
|
||||
<specification-version>6.56</specification-version>
|
||||
</run-dependency>
|
||||
</dependency>
|
||||
<dependency>
|
||||
@ -120,7 +138,7 @@
|
||||
<build-prerequisite/>
|
||||
<compile-dependency/>
|
||||
<run-dependency>
|
||||
<specification-version>7.46.1</specification-version>
|
||||
<specification-version>7.85</specification-version>
|
||||
</run-dependency>
|
||||
</dependency>
|
||||
<dependency>
|
||||
@ -128,7 +146,7 @@
|
||||
<build-prerequisite/>
|
||||
<compile-dependency/>
|
||||
<run-dependency>
|
||||
<specification-version>7.25.1</specification-version>
|
||||
<specification-version>7.63</specification-version>
|
||||
</run-dependency>
|
||||
</dependency>
|
||||
<dependency>
|
||||
@ -136,7 +154,7 @@
|
||||
<build-prerequisite/>
|
||||
<compile-dependency/>
|
||||
<run-dependency>
|
||||
<specification-version>6.45.1</specification-version>
|
||||
<specification-version>6.79</specification-version>
|
||||
</run-dependency>
|
||||
</dependency>
|
||||
<dependency>
|
||||
@ -144,23 +162,23 @@
|
||||
<build-prerequisite/>
|
||||
<compile-dependency/>
|
||||
<run-dependency>
|
||||
<specification-version>7.62.1</specification-version>
|
||||
<specification-version>9.29</specification-version>
|
||||
</run-dependency>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<!-- <dependency>
|
||||
<code-name-base>org.openide.filesystems.compat8</code-name-base>
|
||||
<build-prerequisite/>
|
||||
<compile-dependency/>
|
||||
<run-dependency>
|
||||
<specification-version>9.7.1</specification-version>
|
||||
<specification-version>9.26</specification-version>
|
||||
</run-dependency>
|
||||
</dependency>
|
||||
</dependency> -->
|
||||
<dependency>
|
||||
<code-name-base>org.openide.filesystems.nb</code-name-base>
|
||||
<build-prerequisite/>
|
||||
<compile-dependency/>
|
||||
<run-dependency>
|
||||
<specification-version>9.7.1</specification-version>
|
||||
<specification-version>9.27</specification-version>
|
||||
</run-dependency>
|
||||
</dependency>
|
||||
<dependency>
|
||||
@ -168,7 +186,7 @@
|
||||
<build-prerequisite/>
|
||||
<compile-dependency/>
|
||||
<run-dependency>
|
||||
<specification-version>7.63.2</specification-version>
|
||||
<specification-version>7.87</specification-version>
|
||||
</run-dependency>
|
||||
</dependency>
|
||||
<dependency>
|
||||
@ -176,7 +194,7 @@
|
||||
<build-prerequisite/>
|
||||
<compile-dependency/>
|
||||
<run-dependency>
|
||||
<specification-version>7.32.1</specification-version>
|
||||
<specification-version>7.65</specification-version>
|
||||
</run-dependency>
|
||||
</dependency>
|
||||
<dependency>
|
||||
@ -184,7 +202,7 @@
|
||||
<build-prerequisite/>
|
||||
<compile-dependency/>
|
||||
<run-dependency>
|
||||
<specification-version>7.28.1</specification-version>
|
||||
<specification-version>7.62</specification-version>
|
||||
</run-dependency>
|
||||
</dependency>
|
||||
<dependency>
|
||||
@ -192,7 +210,7 @@
|
||||
<build-prerequisite/>
|
||||
<compile-dependency/>
|
||||
<run-dependency>
|
||||
<specification-version>6.49.1</specification-version>
|
||||
<specification-version>6.85</specification-version>
|
||||
</run-dependency>
|
||||
</dependency>
|
||||
<dependency>
|
||||
@ -200,7 +218,7 @@
|
||||
<build-prerequisite/>
|
||||
<compile-dependency/>
|
||||
<run-dependency>
|
||||
<specification-version>8.25.1</specification-version>
|
||||
<specification-version>9.25</specification-version>
|
||||
</run-dependency>
|
||||
</dependency>
|
||||
<dependency>
|
||||
@ -208,7 +226,7 @@
|
||||
<build-prerequisite/>
|
||||
<compile-dependency/>
|
||||
<run-dependency>
|
||||
<specification-version>8.15.1</specification-version>
|
||||
<specification-version>8.51</specification-version>
|
||||
</run-dependency>
|
||||
</dependency>
|
||||
<dependency>
|
||||
@ -216,7 +234,7 @@
|
||||
<build-prerequisite/>
|
||||
<compile-dependency/>
|
||||
<run-dependency>
|
||||
<specification-version>9.4.1</specification-version>
|
||||
<specification-version>9.25</specification-version>
|
||||
</run-dependency>
|
||||
</dependency>
|
||||
<dependency>
|
||||
@ -224,7 +242,7 @@
|
||||
<build-prerequisite/>
|
||||
<compile-dependency/>
|
||||
<run-dependency>
|
||||
<specification-version>6.55.1</specification-version>
|
||||
<specification-version>6.94</specification-version>
|
||||
</run-dependency>
|
||||
</dependency>
|
||||
<dependency>
|
||||
@ -362,10 +380,34 @@
|
||||
<runtime-relative-path>ext/batik-awt-util-1.14.jar</runtime-relative-path>
|
||||
<binary-origin>release/modules/ext/batik-awt-util-1.14.jar</binary-origin>
|
||||
</class-path-extension>
|
||||
<class-path-extension>
|
||||
<runtime-relative-path>ext/batik-constants-1.14.jar</runtime-relative-path>
|
||||
<binary-origin>release/modules/ext/batik-constants-1.14.jar</binary-origin>
|
||||
</class-path-extension>
|
||||
<class-path-extension>
|
||||
<runtime-relative-path>ext/batik-css-1.14.jar</runtime-relative-path>
|
||||
<binary-origin>release/modules/ext/batik-css-1.14.jar</binary-origin>
|
||||
</class-path-extension>
|
||||
<class-path-extension>
|
||||
<runtime-relative-path>ext/batik-dom-1.14.jar</runtime-relative-path>
|
||||
<binary-origin>release/modules/ext/batik-dom-1.14.jar</binary-origin>
|
||||
</class-path-extension>
|
||||
<class-path-extension>
|
||||
<runtime-relative-path>ext/batik-ext-1.14.jar</runtime-relative-path>
|
||||
<binary-origin>release/modules/ext/batik-ext-1.14.jar</binary-origin>
|
||||
</class-path-extension>
|
||||
<class-path-extension>
|
||||
<runtime-relative-path>ext/batik-i18n-1.14.jar</runtime-relative-path>
|
||||
<binary-origin>release/modules/ext/batik-i18n-1.14.jar</binary-origin>
|
||||
</class-path-extension>
|
||||
<class-path-extension>
|
||||
<runtime-relative-path>ext/batik-parser-1.14.jar</runtime-relative-path>
|
||||
<binary-origin>release/modules/ext/batik-parser-1.14.jar</binary-origin>
|
||||
</class-path-extension>
|
||||
<class-path-extension>
|
||||
<runtime-relative-path>ext/batik-shared-resources-1.14.jar</runtime-relative-path>
|
||||
<binary-origin>release/modules/ext/batik-shared-resources-1.14.jar</binary-origin>
|
||||
</class-path-extension>
|
||||
<class-path-extension>
|
||||
<runtime-relative-path>ext/batik-svg-dom-1.14.jar</runtime-relative-path>
|
||||
<binary-origin>release/modules/ext/batik-svg-dom-1.14.jar</binary-origin>
|
||||
@ -394,6 +436,10 @@
|
||||
<runtime-relative-path>ext/bcprov-jdk15on-1.70.jar</runtime-relative-path>
|
||||
<binary-origin>release/modules/ext/bcprov-jdk15on-1.70.jar</binary-origin>
|
||||
</class-path-extension>
|
||||
<class-path-extension>
|
||||
<runtime-relative-path>ext/bcutil-jdk15on-1.70.jar</runtime-relative-path>
|
||||
<binary-origin>release/modules/ext/bcutil-jdk15on-1.70.jar</binary-origin>
|
||||
</class-path-extension>
|
||||
<class-path-extension>
|
||||
<runtime-relative-path>ext/c3p0-0.9.5.5.jar</runtime-relative-path>
|
||||
<binary-origin>release/modules/ext/c3p0-0.9.5.5.jar</binary-origin>
|
||||
@ -462,6 +508,10 @@
|
||||
<runtime-relative-path>ext/icepdf-viewer-6.2.2.jar</runtime-relative-path>
|
||||
<binary-origin>release/modules/ext/icepdf-viewer-6.2.2.jar</binary-origin>
|
||||
</class-path-extension>
|
||||
<class-path-extension>
|
||||
<runtime-relative-path>ext/istack-commons-runtime-3.0.11.jar</runtime-relative-path>
|
||||
<binary-origin>release/modules/ext/istack-commons-runtime-3.0.11.jar</binary-origin>
|
||||
</class-path-extension>
|
||||
<class-path-extension>
|
||||
<runtime-relative-path>ext/j2objc-annotations-1.3.jar</runtime-relative-path>
|
||||
<binary-origin>release/modules/ext/j2objc-annotations-1.3.jar</binary-origin>
|
||||
@ -482,14 +532,34 @@
|
||||
<runtime-relative-path>ext/jai_imageio-1.1.jar</runtime-relative-path>
|
||||
<binary-origin>release/modules/ext/jai_imageio-1.1.jar</binary-origin>
|
||||
</class-path-extension>
|
||||
<class-path-extension>
|
||||
<runtime-relative-path>ext/jakarta.activation-1.2.2.jar</runtime-relative-path>
|
||||
<binary-origin>release/modules/ext/jakarta.activation-1.2.2.jar</binary-origin>
|
||||
</class-path-extension>
|
||||
<class-path-extension>
|
||||
<runtime-relative-path>ext/jakarta.xml.bind-api-2.3.3.jar</runtime-relative-path>
|
||||
<binary-origin>release/modules/ext/jakarta.xml.bind-api-2.3.3.jar</binary-origin>
|
||||
</class-path-extension>
|
||||
<class-path-extension>
|
||||
<runtime-relative-path>ext/java-diff-utils-4.11.jar</runtime-relative-path>
|
||||
<binary-origin>release/modules/ext/java-diff-utils-4.11.jar</binary-origin>
|
||||
</class-path-extension>
|
||||
<class-path-extension>
|
||||
<runtime-relative-path>ext/javax.activation-api-1.2.0.jar</runtime-relative-path>
|
||||
<binary-origin>release/modules/ext/javax.activation-api-1.2.0.jar</binary-origin>
|
||||
</class-path-extension>
|
||||
<class-path-extension>
|
||||
<runtime-relative-path>ext/javax.ws.rs-api-2.1.1.jar</runtime-relative-path>
|
||||
<binary-origin>release/modules/ext/javax.ws.rs-api-2.1.1.jar</binary-origin>
|
||||
</class-path-extension>
|
||||
<class-path-extension>
|
||||
<runtime-relative-path>ext/jaxb-api-2.3.1.jar</runtime-relative-path>
|
||||
<binary-origin>release/modules/ext/jaxb-api-2.3.1.jar</binary-origin>
|
||||
</class-path-extension>
|
||||
<class-path-extension>
|
||||
<runtime-relative-path>ext/jaxb-runtime-2.3.3.jar</runtime-relative-path>
|
||||
<binary-origin>release/modules/ext/jaxb-runtime-2.3.3.jar</binary-origin>
|
||||
</class-path-extension>
|
||||
<class-path-extension>
|
||||
<runtime-relative-path>ext/jdom-2.0.5.jar</runtime-relative-path>
|
||||
<binary-origin>release/modules/ext/jdom-2.0.5.jar</binary-origin>
|
||||
@ -506,6 +576,10 @@
|
||||
<runtime-relative-path>ext/jsoup-1.14.3.jar</runtime-relative-path>
|
||||
<binary-origin>release/modules/ext/jsoup-1.14.3.jar</binary-origin>
|
||||
</class-path-extension>
|
||||
<class-path-extension>
|
||||
<runtime-relative-path>ext/jsr305-3.0.2.jar</runtime-relative-path>
|
||||
<binary-origin>release/modules/ext/jsr305-3.0.2.jar</binary-origin>
|
||||
</class-path-extension>
|
||||
<class-path-extension>
|
||||
<runtime-relative-path>ext/jutf7-1.0.0.jar</runtime-relative-path>
|
||||
<binary-origin>release/modules/ext/jutf7-1.0.0.jar</binary-origin>
|
||||
@ -602,6 +676,10 @@
|
||||
<runtime-relative-path>ext/Rejistry-1.1-SNAPSHOT.jar</runtime-relative-path>
|
||||
<binary-origin>release/modules/ext/Rejistry-1.1-SNAPSHOT.jar</binary-origin>
|
||||
</class-path-extension>
|
||||
<class-path-extension>
|
||||
<runtime-relative-path>ext/serializer-2.7.2.jar</runtime-relative-path>
|
||||
<binary-origin>release/modules/ext/serializer-2.7.2.jar</binary-origin>
|
||||
</class-path-extension>
|
||||
<class-path-extension>
|
||||
<runtime-relative-path>ext/sevenzipjbinding-AllPlatforms.jar</runtime-relative-path>
|
||||
<binary-origin>release/modules/ext/sevenzipjbinding-AllPlatforms.jar</binary-origin>
|
||||
@ -611,12 +689,12 @@
|
||||
<binary-origin>release/modules/ext/sevenzipjbinding.jar</binary-origin>
|
||||
</class-path-extension>
|
||||
<class-path-extension>
|
||||
<runtime-relative-path>ext/sleuthkit-4.11.1.jar</runtime-relative-path>
|
||||
<binary-origin>release/modules/ext/sleuthkit-4.11.1.jar</binary-origin>
|
||||
<runtime-relative-path>ext/sleuthkit-4.12.0.jar</runtime-relative-path>
|
||||
<binary-origin>release/modules/ext/sleuthkit-4.12.0.jar</binary-origin>
|
||||
</class-path-extension>
|
||||
<class-path-extension>
|
||||
<runtime-relative-path>ext/sleuthkit-caseuco-4.11.1.jar</runtime-relative-path>
|
||||
<binary-origin>release/modules/ext/sleuthkit-caseuco-4.11.1.jar</binary-origin>
|
||||
<runtime-relative-path>ext/sleuthkit-caseuco-4.12.0.jar</runtime-relative-path>
|
||||
<binary-origin>release/modules/ext/sleuthkit-caseuco-4.12.0.jar</binary-origin>
|
||||
</class-path-extension>
|
||||
<class-path-extension>
|
||||
<runtime-relative-path>ext/snakeyaml-1.30.jar</runtime-relative-path>
|
||||
@ -634,6 +712,26 @@
|
||||
<runtime-relative-path>ext/sqlite-jdbc-3.36.0.3.jar</runtime-relative-path>
|
||||
<binary-origin>release/modules/ext/sqlite-jdbc-3.36.0.3.jar</binary-origin>
|
||||
</class-path-extension>
|
||||
<class-path-extension>
|
||||
<runtime-relative-path>ext/txw2-2.3.3.jar</runtime-relative-path>
|
||||
<binary-origin>release/modules/ext/txw2-2.3.3.jar</binary-origin>
|
||||
</class-path-extension>
|
||||
<class-path-extension>
|
||||
<runtime-relative-path>ext/xalan-2.7.2.jar</runtime-relative-path>
|
||||
<binary-origin>release/modules/ext/xalan-2.7.2.jar</binary-origin>
|
||||
</class-path-extension>
|
||||
<class-path-extension>
|
||||
<runtime-relative-path>ext/xml-apis-1.4.01.jar</runtime-relative-path>
|
||||
<binary-origin>release/modules/ext/xml-apis-1.4.01.jar</binary-origin>
|
||||
</class-path-extension>
|
||||
<class-path-extension>
|
||||
<runtime-relative-path>ext/xml-apis-ext-1.3.04.jar</runtime-relative-path>
|
||||
<binary-origin>release/modules/ext/xml-apis-ext-1.3.04.jar</binary-origin>
|
||||
</class-path-extension>
|
||||
<class-path-extension>
|
||||
<runtime-relative-path>ext/xmlgraphics-commons-2.6.jar</runtime-relative-path>
|
||||
<binary-origin>release/modules/ext/xmlgraphics-commons-2.6.jar</binary-origin>
|
||||
</class-path-extension>
|
||||
<class-path-extension>
|
||||
<runtime-relative-path>ext/xmpcore-6.1.11.jar</runtime-relative-path>
|
||||
<binary-origin>release/modules/ext/xmpcore-6.1.11.jar</binary-origin>
|
||||
|
@ -247,15 +247,10 @@ AddImageWizardIngestConfigPanel.dsProcDone.errs.text=*Errors encountered in addi
|
||||
AddImageWizardIngestConfigVisual.getName.text=Configure Ingest
|
||||
AddImageWizardIterator.stepXofN=Step {0} of {1}
|
||||
AddLocalFilesTask.localFileAdd.progress.text=Adding: {0}/{1}
|
||||
Case.getCurCase.exception.noneOpen=Cannot get the current case; there is no case open\!
|
||||
Case.getCurCase.exception.noneOpen=Cannot get the current case; there is no case open!
|
||||
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.checkImgExist.confDlg.doesntExist.msg=One of the images associated with \n\
|
||||
this case are missing. Would you like to search for them now?\n\
|
||||
Previously, the image was located at:\n\
|
||||
{0}\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.
|
||||
Case.checkImgExist.confDlg.doesntExist.msg=One of the images associated with \nthis case are missing. Would you like to search for them now?\nPreviously, the image was located at:\n{0}\nPlease note that you will still be able to browse directories and generate reports\nif 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.addImg.exception.msg=Error adding image to the case
|
||||
Case.updateCaseName.exception.msg=Error while trying to update the case name.
|
||||
@ -274,12 +269,9 @@ Case.GetCaseTypeGivenPath.Failure=Unable to get case type
|
||||
Case.metaDataFileCorrupt.exception.msg=The case metadata file (.aut) is corrupted.
|
||||
Case.deleteReports.deleteFromDiskException.log.msg=Unable to delete the report from the disk.
|
||||
Case.deleteReports.deleteFromDiskException.msg=Unable to delete the report {0} from the disk.\nYou may manually delete it from {1}
|
||||
CaseDeleteAction.closeConfMsg.text=Are you sure want to close and delete this case? \n\
|
||||
Case Name: {0}\n\
|
||||
Case Directory: {1}
|
||||
CaseDeleteAction.closeConfMsg.text=Are you sure want to close and delete this case? \nCase Name: {0}\nCase Directory: {1}
|
||||
CaseDeleteAction.closeConfMsg.title=Warning: Closing the Current Case
|
||||
CaseDeleteAction.msgDlg.fileInUse.msg=The delete action cannot be fully completed because the folder or file in it is open by another program.\n\n\
|
||||
Close the folder and file and try again or you can delete the case manually.
|
||||
CaseDeleteAction.msgDlg.fileInUse.msg=The delete action cannot be fully completed because the folder or file in it is open by another program.\n\nClose the folder and file and try again or you can delete the case manually.
|
||||
CaseDeleteAction.msgDlg.fileInUse.title=Error: Folder In Use
|
||||
CaseDeleteAction.msgDlg.caseDelete.msg=Case {0} has been deleted.
|
||||
CaseOpenAction.autFilter.title={0} Case File ( {1})
|
||||
@ -311,8 +303,7 @@ NewCaseWizardAction.databaseProblem1.text=Cannot open database. Cancelling case
|
||||
NewCaseWizardAction.databaseProblem2.text=Error
|
||||
NewCaseWizardPanel1.validate.errMsg.invalidSymbols=The Case Name cannot contain any of the following symbols: \\ / : * ? " < > |
|
||||
NewCaseWizardPanel1.validate.errMsg.dirExists=Case directory ''{0}'' already exists.
|
||||
NewCaseWizardPanel1.validate.confMsg.createDir.msg=The base directory "{0}" does not exist. \n\n\
|
||||
Do you want to create that directory?
|
||||
NewCaseWizardPanel1.validate.confMsg.createDir.msg=The base directory "{0}" does not exist. \n\nDo you want to create that directory?
|
||||
NewCaseWizardPanel1.validate.confMsg.createDir.title=Create directory
|
||||
NewCaseWizardPanel1.validate.errMsg.cantCreateParDir.msg=Error: Could not create case parent directory {0}
|
||||
NewCaseWizardPanel1.validate.errMsg.prevCreateBaseDir.msg=Prevented from creating base directory {0}
|
||||
@ -369,8 +360,8 @@ UnpackageWorker.doInBackground.previouslySeenCase=Case has been previously opene
|
||||
UpdateRecentCases.menuItem.clearRecentCases.text=Clear Recent Cases
|
||||
UpdateRecentCases.menuItem.empty=-Empty-
|
||||
AddImageWizardIngestConfigPanel.CANCEL_BUTTON.text=Cancel
|
||||
NewCaseVisualPanel1.CaseFolderOnCDriveError.text=Warning: Path to multi-user case folder is on \"C:\" drive
|
||||
NewCaseVisualPanel1.CaseFolderOnInternalDriveWindowsError.text=Warning: Path to case folder is on \"C:\" drive. Case folder is created on the target system
|
||||
NewCaseVisualPanel1.CaseFolderOnCDriveError.text=Warning: Path to multi-user case folder is on "C:" drive
|
||||
NewCaseVisualPanel1.CaseFolderOnInternalDriveWindowsError.text=Warning: Path to case folder is on "C:" drive. Case folder is created on the target system
|
||||
NewCaseVisualPanel1.CaseFolderOnInternalDriveLinuxError.text=Warning: Path to case folder is on the target system. Create case folder in mounted drive.
|
||||
NewCaseVisualPanel1.uncPath.error=Error: UNC paths are not allowed for Single-User cases
|
||||
CollaborationMonitor.addingDataSourceStatus.msg={0} adding data source
|
||||
@ -378,7 +369,7 @@ CollaborationMonitor.analyzingDataSourceStatus.msg={0} analyzing {1}
|
||||
MissingImageDialog.lbWarning.text=
|
||||
MissingImageDialog.lbWarning.toolTipText=
|
||||
NewCaseVisualPanel1.caseParentDirWarningLabel.text=
|
||||
NewCaseVisualPanel1.multiUserCaseRadioButton.text=Multi-User
|
||||
NewCaseVisualPanel1.multiUserCaseRadioButton.text=Multi-User\t\t
|
||||
NewCaseVisualPanel1.singleUserCaseRadioButton.text=Single-User
|
||||
NewCaseVisualPanel1.caseTypeLabel.text=Case Type:
|
||||
SingleUserCaseConverter.BadDatabaseFileName=Database file does not exist!
|
||||
|
@ -45,7 +45,6 @@
|
||||
<Group type="102" alignment="1" attributes="0">
|
||||
<EmptySpace min="0" pref="0" max="-2" attributes="0"/>
|
||||
<Component id="detailsPanel" max="32767" attributes="0"/>
|
||||
<EmptySpace min="0" pref="0" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
@ -87,7 +86,6 @@
|
||||
<Border info="org.netbeans.modules.form.compat2.border.TitledBorderInfo">
|
||||
<TitledBorder title="<CaseDetailsPanel.casePanel.border.title>">
|
||||
<ResourceString PropertyName="titleX" bundle="org/sleuthkit/autopsy/casemodule/Bundle.properties" key="CaseDetailsPanel.casePanel.border.title" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
<Font PropertyName="font" name="Tahoma" size="12" style="0"/>
|
||||
</TitledBorder>
|
||||
</Border>
|
||||
</Property>
|
||||
@ -328,7 +326,6 @@
|
||||
<Border info="org.netbeans.modules.form.compat2.border.TitledBorderInfo">
|
||||
<TitledBorder title="<CaseDetailsPanel.examinerPanel.border.title>">
|
||||
<ResourceString PropertyName="titleX" bundle="org/sleuthkit/autopsy/casemodule/Bundle.properties" key="CaseDetailsPanel.examinerPanel.border.title" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
<Font PropertyName="font" name="Tahoma" size="12" style="0"/>
|
||||
</TitledBorder>
|
||||
</Border>
|
||||
</Property>
|
||||
@ -506,7 +503,6 @@
|
||||
<Border info="org.netbeans.modules.form.compat2.border.TitledBorderInfo">
|
||||
<TitledBorder title="<CaseDetailsPanel.pnOrganization.border.title>">
|
||||
<ResourceString PropertyName="titleX" bundle="org/sleuthkit/autopsy/casemodule/Bundle.properties" key="CaseDetailsPanel.pnOrganization.border.title" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
<Font PropertyName="font" name="Tahoma" size="12" style="0"/>
|
||||
</TitledBorder>
|
||||
</Border>
|
||||
</Property>
|
||||
|
@ -182,7 +182,7 @@ final class CaseDetailsPanel extends javax.swing.JPanel {
|
||||
jTextArea1.setRows(5);
|
||||
jScrollPane1.setViewportView(jTextArea1);
|
||||
|
||||
casePanel.setBorder(javax.swing.BorderFactory.createTitledBorder(null, org.openide.util.NbBundle.getMessage(CaseDetailsPanel.class, "CaseDetailsPanel.casePanel.border.title"), javax.swing.border.TitledBorder.DEFAULT_JUSTIFICATION, javax.swing.border.TitledBorder.DEFAULT_POSITION, new java.awt.Font("Tahoma", 0, 12))); // NOI18N
|
||||
casePanel.setBorder(javax.swing.BorderFactory.createTitledBorder(org.openide.util.NbBundle.getMessage(CaseDetailsPanel.class, "CaseDetailsPanel.casePanel.border.title"))); // NOI18N
|
||||
|
||||
caseNameLabel.setText(org.openide.util.NbBundle.getMessage(CaseDetailsPanel.class, "CaseDetailsPanel.caseNameLabel.text")); // NOI18N
|
||||
caseNameLabel.setMaximumSize(new java.awt.Dimension(82, 14));
|
||||
@ -295,7 +295,7 @@ final class CaseDetailsPanel extends javax.swing.JPanel {
|
||||
.addGap(6, 6, 6))
|
||||
);
|
||||
|
||||
examinerPanel.setBorder(javax.swing.BorderFactory.createTitledBorder(null, org.openide.util.NbBundle.getMessage(CaseDetailsPanel.class, "CaseDetailsPanel.examinerPanel.border.title"), javax.swing.border.TitledBorder.DEFAULT_JUSTIFICATION, javax.swing.border.TitledBorder.DEFAULT_POSITION, new java.awt.Font("Tahoma", 0, 12))); // NOI18N
|
||||
examinerPanel.setBorder(javax.swing.BorderFactory.createTitledBorder(org.openide.util.NbBundle.getMessage(CaseDetailsPanel.class, "CaseDetailsPanel.examinerPanel.border.title"))); // NOI18N
|
||||
|
||||
lbNotesLabel.setText(org.openide.util.NbBundle.getMessage(CaseDetailsPanel.class, "CaseDetailsPanel.lbNotesLabel.text")); // NOI18N
|
||||
lbNotesLabel.setMaximumSize(new java.awt.Dimension(82, 14));
|
||||
@ -381,7 +381,7 @@ final class CaseDetailsPanel extends javax.swing.JPanel {
|
||||
.addGap(6, 6, 6))
|
||||
);
|
||||
|
||||
pnOrganization.setBorder(javax.swing.BorderFactory.createTitledBorder(null, org.openide.util.NbBundle.getMessage(CaseDetailsPanel.class, "CaseDetailsPanel.pnOrganization.border.title"), javax.swing.border.TitledBorder.DEFAULT_JUSTIFICATION, javax.swing.border.TitledBorder.DEFAULT_POSITION, new java.awt.Font("Tahoma", 0, 12))); // NOI18N
|
||||
pnOrganization.setBorder(javax.swing.BorderFactory.createTitledBorder(org.openide.util.NbBundle.getMessage(CaseDetailsPanel.class, "CaseDetailsPanel.pnOrganization.border.title"))); // NOI18N
|
||||
|
||||
lbOrganizationNameLabel.setText(org.openide.util.NbBundle.getMessage(CaseDetailsPanel.class, "CaseDetailsPanel.lbOrganizationNameLabel.text")); // NOI18N
|
||||
lbOrganizationNameLabel.setMaximumSize(new java.awt.Dimension(82, 14));
|
||||
@ -484,8 +484,7 @@ final class CaseDetailsPanel extends javax.swing.JPanel {
|
||||
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
|
||||
.addGap(0, 0, 0)
|
||||
.addComponent(detailsPanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
||||
.addGap(0, 0, 0))
|
||||
.addComponent(detailsPanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
|
||||
);
|
||||
}// </editor-fold>//GEN-END:initComponents
|
||||
|
||||
|
@ -5,10 +5,7 @@ CentralRepoCommentDialog.title.addEditCentralRepoComment=Add/Edit Central Reposi
|
||||
OpenIDE-Module-Name=Central Repository
|
||||
OpenIDE-Module-Display-Category=Ingest Module
|
||||
OpenIDE-Module-Short-Description=Central Repository Ingest Module
|
||||
OpenIDE-Module-Long-Description=\
|
||||
Central Repository ingest module and central database. \n\n\
|
||||
The Central Repository ingest module stores attributes of artifacts matching selected correlation types into a central database.\n\
|
||||
Stored attributes are used in future cases to correlate and analyzes files and artifacts during ingest.
|
||||
OpenIDE-Module-Long-Description=Central Repository ingest module and central database. \n\nThe Central Repository ingest module stores attributes of artifacts matching selected correlation types into a central database.\nStored attributes are used in future cases to correlate and analyzes files and artifacts during ingest.
|
||||
CentralRepoCommentDialog.commentLabel.text=Comment:
|
||||
CentralRepoCommentDialog.okButton.text=&OK
|
||||
CentralRepoCommentDialog.cancelButton.text=C&ancel
|
||||
|
@ -163,7 +163,9 @@ final public class VisualizationPanel extends JPanel {
|
||||
this.relationshipBrowser = relationshipBrowser;
|
||||
initComponents();
|
||||
//initialize invisible JFXPanel that is used to show JFXNotifications over this window.
|
||||
notificationsJFXPanel.setScene(new Scene(new Pane()));
|
||||
Platform.runLater(() -> {
|
||||
notificationsJFXPanel.setScene(new Scene(new Pane()));
|
||||
});
|
||||
|
||||
graph = new CommunicationsGraph(pinnedAccountModel, lockedVertexModel);
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -20,6 +20,7 @@ package org.sleuthkit.autopsy.contentviewers;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.ByteOrder;
|
||||
import javafx.application.Platform;
|
||||
import javafx.embed.swing.JFXPanel;
|
||||
import javafx.scene.Scene;
|
||||
import javafx.scene.image.Image;
|
||||
@ -87,7 +88,12 @@ final class JavaFxAppSink extends AppSink {
|
||||
fxImageView = new ImageView(); // Will hold the current video frame.
|
||||
BorderPane borderpane = new BorderPane(fxImageView); // Center and size ImageView.
|
||||
Scene scene = new Scene(borderpane); // Root of the JavaFX tree.
|
||||
target.setScene(scene);
|
||||
// Although the documentation for JFXPanel.setScene() claims that it
|
||||
// can be called on either the EDT or the JavaFX thread, with JavaFX 11
|
||||
// it doesn't work unless you call it on the JavaFX application thread.
|
||||
Platform.runLater(() -> {
|
||||
target.setScene(scene);
|
||||
});
|
||||
|
||||
// Bind size of image to that of scene, while keeping proportions
|
||||
fxImageView.fitWidthProperty().bind(scene.widthProperty());
|
||||
|
@ -19,7 +19,7 @@
|
||||
|
||||
.label {
|
||||
-fx-wrap-text:true;
|
||||
-fx-text-fill: red;
|
||||
-fx-text-fill: #ff0000;
|
||||
-fx-font-size: 2em;
|
||||
}
|
||||
|
||||
@ -28,6 +28,6 @@
|
||||
}
|
||||
|
||||
.masker-pane .masker-text {
|
||||
-fx-text-fill: white;
|
||||
-fx-text-fill: #ffffff;
|
||||
-fx-font-size: 1.5em;
|
||||
}
|
||||
|
@ -18,7 +18,9 @@
|
||||
*/
|
||||
package org.sleuthkit.autopsy.contentviewers.imagetagging;
|
||||
|
||||
import com.sun.javafx.event.EventDispatchChainImpl;
|
||||
|
||||
// TODO: See JIRA-6693
|
||||
//import com.sun.javafx.event.EventDispatchChainImpl;
|
||||
import java.beans.PropertyChangeEvent;
|
||||
import java.beans.PropertyChangeListener;
|
||||
import java.beans.PropertyChangeSupport;
|
||||
@ -46,7 +48,7 @@ import org.sleuthkit.autopsy.casemodule.services.contentviewertags.ContentViewer
|
||||
public final class ImageTag extends Group {
|
||||
|
||||
// Used to tell the 8 edit handles to hide if this tag is no longer selected
|
||||
private final EventDispatchChainImpl ALL_CHILDREN;
|
||||
// private final EventDispatchChainImpl ALL_CHILDREN;
|
||||
|
||||
private final PhysicalTag physicalTag;
|
||||
|
||||
@ -57,13 +59,13 @@ public final class ImageTag extends Group {
|
||||
private final ContentViewerTag<ImageTagRegion> appTag;
|
||||
|
||||
public ImageTag(ContentViewerTag<ImageTagRegion> contentViewerTag, ImageView image) {
|
||||
ALL_CHILDREN = new EventDispatchChainImpl();
|
||||
// ALL_CHILDREN = new EventDispatchChainImpl();
|
||||
this.appTag = contentViewerTag;
|
||||
|
||||
this.getChildren().addListener((ListChangeListener<Node>) change -> {
|
||||
change.next();
|
||||
change.getAddedSubList().forEach((node) -> ALL_CHILDREN.append(node.getEventDispatcher()));
|
||||
});
|
||||
// this.getChildren().addListener((ListChangeListener<Node>) change -> {
|
||||
// change.next();
|
||||
// change.getAddedSubList().forEach((node) -> ALL_CHILDREN.append(node.getEventDispatcher()));
|
||||
// });
|
||||
|
||||
ImageTagRegion details = contentViewerTag.getDetails();
|
||||
physicalTag = new PhysicalTag(details);
|
||||
@ -120,8 +122,8 @@ public final class ImageTag extends Group {
|
||||
Tooltip.install(this, new Tooltip(contentViewerTag.getContentTag()
|
||||
.getName().getDisplayName()));
|
||||
|
||||
this.addEventHandler(ImageTagControls.NOT_FOCUSED, event -> ALL_CHILDREN.dispatchEvent(event));
|
||||
this.addEventHandler(ImageTagControls.FOCUSED, event -> ALL_CHILDREN.dispatchEvent(event));
|
||||
// this.addEventHandler(ImageTagControls.NOT_FOCUSED, event -> ALL_CHILDREN.dispatchEvent(event));
|
||||
// this.addEventHandler(ImageTagControls.FOCUSED, event -> ALL_CHILDREN.dispatchEvent(event));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -18,11 +18,11 @@
|
||||
*/
|
||||
package org.sleuthkit.autopsy.contentviewers.imagetagging;
|
||||
|
||||
import com.sun.javafx.event.EventDispatchChainImpl;
|
||||
import java.beans.PropertyChangeEvent;
|
||||
import java.beans.PropertyChangeListener;
|
||||
import java.beans.PropertyChangeSupport;
|
||||
import javafx.event.Event;
|
||||
import javafx.event.EventDispatchChain;
|
||||
import javafx.geometry.Point2D;
|
||||
import javafx.scene.Group;
|
||||
import javafx.scene.Node;
|
||||
@ -41,7 +41,8 @@ import javafx.scene.input.MouseEvent;
|
||||
*/
|
||||
public final class ImageTagsGroup extends Group {
|
||||
|
||||
private final EventDispatchChainImpl NO_OP_CHAIN = new EventDispatchChainImpl();
|
||||
// TODO: See JIRA-6693
|
||||
// private final EventDispatchChain NO_OP_CHAIN = new EventDispatchChainImpl();
|
||||
private final PropertyChangeSupport pcs = new PropertyChangeSupport(this);
|
||||
|
||||
private volatile ImageTag currentFocus;
|
||||
@ -50,10 +51,10 @@ public final class ImageTagsGroup extends Group {
|
||||
|
||||
//Reset focus of current selection if the back drop has focus.
|
||||
backDrop.setOnMousePressed((mouseEvent) -> {
|
||||
if (currentFocus != null) {
|
||||
currentFocus.getEventDispatcher().dispatchEvent(
|
||||
new Event(ImageTagControls.NOT_FOCUSED), NO_OP_CHAIN);
|
||||
}
|
||||
// if (currentFocus != null) {
|
||||
// currentFocus.getEventDispatcher().dispatchEvent(
|
||||
// new Event(ImageTagControls.NOT_FOCUSED), NO_OP_CHAIN);
|
||||
// }
|
||||
|
||||
this.pcs.firePropertyChange(new PropertyChangeEvent(this,
|
||||
ImageTagControls.NOT_FOCUSED.getName(), currentFocus, null));
|
||||
@ -130,7 +131,7 @@ public final class ImageTagsGroup extends Group {
|
||||
* @param n
|
||||
*/
|
||||
private void resetFocus(ImageTag n) {
|
||||
n.getEventDispatcher().dispatchEvent(new Event(ImageTagControls.NOT_FOCUSED), NO_OP_CHAIN);
|
||||
// n.getEventDispatcher().dispatchEvent(new Event(ImageTagControls.NOT_FOCUSED), NO_OP_CHAIN);
|
||||
this.pcs.firePropertyChange(new PropertyChangeEvent(this, ImageTagControls.NOT_FOCUSED.getName(), n, null));
|
||||
}
|
||||
|
||||
@ -146,7 +147,7 @@ public final class ImageTagsGroup extends Group {
|
||||
resetFocus(currentFocus);
|
||||
}
|
||||
|
||||
n.getEventDispatcher().dispatchEvent(new Event(ImageTagControls.FOCUSED), NO_OP_CHAIN);
|
||||
// n.getEventDispatcher().dispatchEvent(new Event(ImageTagControls.FOCUSED), NO_OP_CHAIN);
|
||||
this.pcs.firePropertyChange(new PropertyChangeEvent(this, ImageTagControls.FOCUSED.getName(), currentFocus, n));
|
||||
|
||||
currentFocus = n;
|
||||
|
@ -11,7 +11,7 @@ OpenIDE-Module-Short-Description=Autopsy Core Module
|
||||
org_sleuthkit_autopsy_core_update_center=http://sleuthkit.org/autopsy/updates.xml
|
||||
Services/AutoupdateType/org_sleuthkit_autopsy_core_update_center.settings=Autopsy Update Center
|
||||
Installer.errorInitJavafx.msg=Error initializing JavaFX.
|
||||
Installer.errorInitJavafx.details=\ Some features will not be available. Check that you have JavaFX installed (OpenJFX 8).
|
||||
Installer.errorInitJavafx.details=\ Some features will not be available. Check that you have JavaFX installed (OpenJFX 11).
|
||||
ServicesMonitor.failedService.notify.title=Service Is Down
|
||||
ServicesMonitor.failedService.notify.msg=Connection to {0} is down
|
||||
ServicesMonitor.restoredService.notify.title=Service Is Up
|
||||
|
@ -15,7 +15,7 @@ OpenIDE-Module-Short-Description=Autopsy Core Module
|
||||
org_sleuthkit_autopsy_core_update_center=http://sleuthkit.org/autopsy/updates.xml
|
||||
Services/AutoupdateType/org_sleuthkit_autopsy_core_update_center.settings=Autopsy Update Center
|
||||
Installer.errorInitJavafx.msg=Error initializing JavaFX.
|
||||
Installer.errorInitJavafx.details=\ Some features will not be available. Check that you have JavaFX installed (OpenJFX 8).
|
||||
Installer.errorInitJavafx.details=\ Some features will not be available. Check that you have JavaFX installed (OpenJFX 11).
|
||||
ServicesMonitor.failedService.notify.title=Service Is Down
|
||||
ServicesMonitor.failedService.notify.msg=Connection to {0} is down
|
||||
ServicesMonitor.restoredService.notify.title=Service Is Up
|
||||
|
@ -263,8 +263,15 @@ public class Installer extends ModuleInstall {
|
||||
//initialize java fx if exists
|
||||
System.setProperty("javafx.macosx.embedded", "true");
|
||||
try {
|
||||
|
||||
// Due to a lingering issue https://bugs.openjdk.org/browse/JDK-8223377 where glass.dll from java 8 gets loaded instead of the java 17 one.
|
||||
String javaLibraryPath = "java.library.path";
|
||||
String jvmBinPathStr = Paths.get(System.getProperty("java.home"), "bin").toAbsolutePath().toString();
|
||||
String path = System.getProperty(javaLibraryPath);
|
||||
System.setProperty(javaLibraryPath, StringUtils.isBlank(path) ? jvmBinPathStr : jvmBinPathStr + File.pathSeparator + path);
|
||||
|
||||
// Creating a JFXPanel initializes JavaFX
|
||||
JFXPanel panel = new JFXPanel();
|
||||
new JFXPanel();
|
||||
Platform.setImplicitExit(false);
|
||||
javaFxInit = true;
|
||||
} catch (UnsatisfiedLinkError | NoClassDefFoundError | Exception e) {
|
||||
|
@ -24,6 +24,7 @@ import org.openide.DialogDescriptor;
|
||||
import org.openide.DialogDisplayer;
|
||||
import org.openide.awt.ActionID;
|
||||
import org.openide.awt.ActionReference;
|
||||
import org.openide.awt.ActionRegistration;
|
||||
import org.openide.util.NbBundle;
|
||||
import org.openide.util.NbBundle.Messages;
|
||||
|
||||
@ -32,6 +33,7 @@ import org.openide.util.NbBundle.Messages;
|
||||
* menu.
|
||||
*/
|
||||
@ActionID(id = "org.sleuthkit.autopsy.corecomponents.AboutWindowAction", category = "Help")
|
||||
@ActionRegistration(displayName = "#CTL_CustomAboutAction", iconInMenu = true, lazy = false)
|
||||
@ActionReference(path = "Menu/Help", position = 3000, separatorBefore = 2999)
|
||||
public class AboutWindowAction extends AboutAction {
|
||||
|
||||
|
@ -26,12 +26,12 @@
|
||||
<Layout>
|
||||
<DimensionLayout dim="0">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Component id="jScrollPane1" alignment="0" pref="860" max="32767" attributes="0"/>
|
||||
<Component id="jScrollPane1" alignment="0" pref="955" max="32767" attributes="0"/>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
<DimensionLayout dim="1">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Component id="jScrollPane1" alignment="0" pref="620" max="32767" attributes="0"/>
|
||||
<Component id="jScrollPane1" alignment="0" pref="699" max="32767" attributes="0"/>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
</Layout>
|
||||
@ -244,7 +244,7 @@
|
||||
<Group type="102" alignment="0" attributes="0">
|
||||
<EmptySpace min="-2" pref="23" max="-2" attributes="0"/>
|
||||
<Component id="memFieldValidationLabel" min="-2" pref="478" max="-2" attributes="0"/>
|
||||
<EmptySpace pref="12" max="32767" attributes="0"/>
|
||||
<EmptySpace pref="117" max="32767" attributes="0"/>
|
||||
</Group>
|
||||
<Group type="102" alignment="0" attributes="0">
|
||||
<EmptySpace min="-2" pref="18" max="-2" attributes="0"/>
|
||||
@ -521,7 +521,7 @@
|
||||
</Group>
|
||||
</Group>
|
||||
</Group>
|
||||
<EmptySpace pref="164" max="32767" attributes="0"/>
|
||||
<EmptySpace pref="269" max="32767" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
@ -635,11 +635,14 @@
|
||||
</TitledBorder>
|
||||
</Border>
|
||||
</Property>
|
||||
<Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||
<Dimension value="[300, 175]"/>
|
||||
</Property>
|
||||
<Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||
<Dimension value="[33, 100]"/>
|
||||
<Dimension value="[300, 175]"/>
|
||||
</Property>
|
||||
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||
<Dimension value="[100, 150]"/>
|
||||
<Dimension value="[300, 175]"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<Constraints>
|
||||
@ -678,7 +681,15 @@
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/corecomponents/Bundle.properties" key="AutopsyOptionsPanel.sizingTextPane.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
<Property name="autoscrolls" type="boolean" value="false"/>
|
||||
<Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||
<Dimension value="[453, 220]"/>
|
||||
</Property>
|
||||
<Property name="opaque" type="boolean" value="false"/>
|
||||
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||
<Dimension value="[453, 220]"/>
|
||||
</Property>
|
||||
<Property name="selectionStart" type="int" value="0"/>
|
||||
</Properties>
|
||||
<AuxValues>
|
||||
<AuxValue name="JavaCodeGenerator_VariableLocal" type="java.lang.Boolean" value="true"/>
|
||||
|
@ -1016,7 +1016,7 @@ final class AutopsyOptionsPanel extends javax.swing.JPanel {
|
||||
.addGroup(runtimePanelLayout.createSequentialGroup()
|
||||
.addGap(23, 23, 23)
|
||||
.addComponent(memFieldValidationLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 478, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||
.addContainerGap(12, Short.MAX_VALUE))
|
||||
.addContainerGap(117, Short.MAX_VALUE))
|
||||
.addGroup(runtimePanelLayout.createSequentialGroup()
|
||||
.addGap(18, 18, 18)
|
||||
.addComponent(solrJVMHeapWarning, javax.swing.GroupLayout.PREFERRED_SIZE, 331, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||
@ -1149,7 +1149,7 @@ final class AutopsyOptionsPanel extends javax.swing.JPanel {
|
||||
.addComponent(tempCustomField, javax.swing.GroupLayout.PREFERRED_SIZE, 459, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(tempDirectoryBrowseButton)))))
|
||||
.addContainerGap(164, Short.MAX_VALUE))
|
||||
.addContainerGap(269, Short.MAX_VALUE))
|
||||
);
|
||||
tempDirectoryPanelLayout.setVerticalGroup(
|
||||
tempDirectoryPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
@ -1179,8 +1179,9 @@ final class AutopsyOptionsPanel extends javax.swing.JPanel {
|
||||
tempDirectoryPanel.getAccessibleContext().setAccessibleName(org.openide.util.NbBundle.getMessage(AutopsyOptionsPanel.class, "AutopsyOptionsPanel.tempDirectoryPanel.AccessibleContext.accessibleName")); // NOI18N
|
||||
|
||||
rdpPanel.setBorder(javax.swing.BorderFactory.createTitledBorder(org.openide.util.NbBundle.getMessage(AutopsyOptionsPanel.class, "AutopsyOptionsPanel.rdpPanel.border.title"))); // NOI18N
|
||||
rdpPanel.setMinimumSize(new java.awt.Dimension(33, 100));
|
||||
rdpPanel.setPreferredSize(new java.awt.Dimension(100, 150));
|
||||
rdpPanel.setMaximumSize(new java.awt.Dimension(300, 175));
|
||||
rdpPanel.setMinimumSize(new java.awt.Dimension(300, 175));
|
||||
rdpPanel.setPreferredSize(new java.awt.Dimension(300, 175));
|
||||
rdpPanel.setLayout(new java.awt.GridBagLayout());
|
||||
|
||||
sizingScrollPane.setBorder(null);
|
||||
@ -1188,7 +1189,11 @@ final class AutopsyOptionsPanel extends javax.swing.JPanel {
|
||||
sizingTextPane.setEditable(false);
|
||||
sizingTextPane.setBorder(null);
|
||||
sizingTextPane.setText(org.openide.util.NbBundle.getMessage(AutopsyOptionsPanel.class, "AutopsyOptionsPanel.sizingTextPane.text")); // NOI18N
|
||||
sizingTextPane.setAutoscrolls(false);
|
||||
sizingTextPane.setMinimumSize(new java.awt.Dimension(453, 220));
|
||||
sizingTextPane.setOpaque(false);
|
||||
sizingTextPane.setPreferredSize(new java.awt.Dimension(453, 220));
|
||||
sizingTextPane.setSelectionStart(0);
|
||||
sizingScrollPane.setViewportView(sizingTextPane);
|
||||
|
||||
gridBagConstraints = new java.awt.GridBagConstraints();
|
||||
@ -1220,11 +1225,11 @@ final class AutopsyOptionsPanel extends javax.swing.JPanel {
|
||||
this.setLayout(layout);
|
||||
layout.setHorizontalGroup(
|
||||
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 860, Short.MAX_VALUE)
|
||||
.addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 955, Short.MAX_VALUE)
|
||||
);
|
||||
layout.setVerticalGroup(
|
||||
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 620, Short.MAX_VALUE)
|
||||
.addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 699, Short.MAX_VALUE)
|
||||
);
|
||||
}// </editor-fold>//GEN-END:initComponents
|
||||
|
||||
|
@ -1,3 +1,4 @@
|
||||
CTL_CustomAboutAction=About
|
||||
CTL_DataContentAction=DataContent
|
||||
CTL_DataContentTopComponent=Data Content
|
||||
OptionsCategory_Name_General=Application
|
||||
|
@ -23,16 +23,19 @@ import java.awt.Insets;
|
||||
import java.beans.PropertyChangeEvent;
|
||||
import java.beans.PropertyChangeListener;
|
||||
import java.util.Collection;
|
||||
import java.util.Enumeration;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
import java.util.TreeMap;
|
||||
import java.util.logging.Level;
|
||||
import java.util.stream.Stream;
|
||||
import javax.swing.BorderFactory;
|
||||
import javax.swing.ImageIcon;
|
||||
import javax.swing.SwingUtilities;
|
||||
import javax.swing.UIManager;
|
||||
import javax.swing.UIManager.LookAndFeelInfo;
|
||||
import javax.swing.UnsupportedLookAndFeelException;
|
||||
import javax.swing.plaf.FontUIResource;
|
||||
import org.netbeans.spi.sendopts.OptionProcessor;
|
||||
import org.netbeans.swing.tabcontrol.plaf.DefaultTabbedContainerUI;
|
||||
import org.openide.modules.ModuleInstall;
|
||||
@ -128,7 +131,7 @@ public class Installer extends ModuleInstall {
|
||||
UIManager.put("OptionPane.warningIcon", warningIcon);
|
||||
UIManager.put("OptionPane.questionIcon", questionIcon);
|
||||
UIManager.put("OptionPane.informationIcon", informationIcon);
|
||||
|
||||
|
||||
if (System.getProperty("os.name").toLowerCase().contains("mac")) { //NON-NLS
|
||||
setUnixLookAndFeel();
|
||||
setModuleSettings("false");
|
||||
|
@ -6,8 +6,11 @@
|
||||
</Component>
|
||||
</NonVisualComponents>
|
||||
<Properties>
|
||||
<Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||
<Dimension value="[727, 520]"/>
|
||||
</Property>
|
||||
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||
<Dimension value="[727, 495]"/>
|
||||
<Dimension value="[727, 520]"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<AuxValues>
|
||||
@ -30,7 +33,7 @@
|
||||
</DimensionLayout>
|
||||
<DimensionLayout dim="1">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Component id="viewPreferencesScrollPane" alignment="0" max="32767" attributes="0"/>
|
||||
<Component id="viewPreferencesScrollPane" alignment="0" pref="520" max="32767" attributes="0"/>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
</Layout>
|
||||
@ -40,8 +43,11 @@
|
||||
<Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor">
|
||||
<Border info="null"/>
|
||||
</Property>
|
||||
<Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||
<Dimension value="[727, 500]"/>
|
||||
</Property>
|
||||
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||
<Dimension value="[727, 493]"/>
|
||||
<Dimension value="[727, 500]"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
|
||||
|
@ -187,10 +187,12 @@ public class ViewPreferencesPanel extends JPanel implements OptionsPanel {
|
||||
currentSessionSettingsPanel = new javax.swing.JPanel();
|
||||
hideRejectedResultsCheckbox = new javax.swing.JCheckBox();
|
||||
|
||||
setPreferredSize(new java.awt.Dimension(727, 495));
|
||||
setMinimumSize(new java.awt.Dimension(727, 520));
|
||||
setPreferredSize(new java.awt.Dimension(727, 520));
|
||||
|
||||
viewPreferencesScrollPane.setBorder(null);
|
||||
viewPreferencesScrollPane.setPreferredSize(new java.awt.Dimension(727, 493));
|
||||
viewPreferencesScrollPane.setMinimumSize(new java.awt.Dimension(727, 500));
|
||||
viewPreferencesScrollPane.setPreferredSize(new java.awt.Dimension(727, 500));
|
||||
|
||||
viewPreferencesPanel.setPreferredSize(new java.awt.Dimension(727, 492));
|
||||
|
||||
@ -502,7 +504,7 @@ public class ViewPreferencesPanel extends JPanel implements OptionsPanel {
|
||||
);
|
||||
layout.setVerticalGroup(
|
||||
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addComponent(viewPreferencesScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
||||
.addComponent(viewPreferencesScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, 520, Short.MAX_VALUE)
|
||||
);
|
||||
}// </editor-fold>//GEN-END:initComponents
|
||||
|
||||
|
@ -18,7 +18,6 @@
|
||||
*/
|
||||
package org.sleuthkit.autopsy.coreutils;
|
||||
|
||||
import com.sun.javafx.PlatformUtil;
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
@ -28,6 +27,7 @@ import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.logging.Level;
|
||||
import org.apache.commons.lang3.SystemUtils;
|
||||
import org.sleuthkit.autopsy.core.UserPreferences;
|
||||
|
||||
/**
|
||||
@ -371,7 +371,7 @@ public final class ExecUtil {
|
||||
return;
|
||||
}
|
||||
|
||||
if (PlatformUtil.isWindows()) {
|
||||
if (SystemUtils.IS_OS_WINDOWS) {
|
||||
try {
|
||||
Win32Process parentProcess = new Win32Process(process);
|
||||
List<Win32Process> children = parentProcess.getChildren();
|
||||
|
@ -20,25 +20,31 @@ package org.sleuthkit.autopsy.coreutils;
|
||||
|
||||
import java.io.BufferedInputStream;
|
||||
import java.io.BufferedOutputStream;
|
||||
import java.io.BufferedReader;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.OutputStream;
|
||||
import java.lang.management.ManagementFactory;
|
||||
import java.lang.management.MemoryMXBean;
|
||||
import java.lang.management.MemoryUsage;
|
||||
import java.nio.charset.Charset;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.regex.Pattern;
|
||||
import java.util.stream.Stream;
|
||||
import javax.swing.filechooser.FileSystemView;
|
||||
import org.apache.commons.io.FilenameUtils;
|
||||
import org.hyperic.sigar.Sigar;
|
||||
import org.hyperic.sigar.ptql.ProcessFinder;
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.openide.modules.InstalledFileLocator;
|
||||
import org.openide.modules.Places;
|
||||
import org.openide.util.NbBundle;
|
||||
@ -60,7 +66,6 @@ public class PlatformUtil {
|
||||
public static final String OS_VERSION_UNKNOWN = NbBundle.getMessage(PlatformUtil.class, "PlatformUtil.verUnknown");
|
||||
public static final String OS_ARCH_UNKNOWN = NbBundle.getMessage(PlatformUtil.class, "PlatformUtil.archUnknown");
|
||||
private static volatile long pid = -1;
|
||||
private static volatile Sigar sigar = null;
|
||||
private static volatile MemoryMXBean memoryManager = null;
|
||||
|
||||
/**
|
||||
@ -238,7 +243,7 @@ public class PlatformUtil {
|
||||
public static String getModuleConfigDirectory() {
|
||||
return Paths.get(getUserConfigDirectory(), "ModuleConfig").toString();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get log directory path
|
||||
*
|
||||
@ -504,25 +509,8 @@ public class PlatformUtil {
|
||||
* @return PID of this process or -1 if it couldn't be determined
|
||||
*/
|
||||
public static synchronized long getPID() {
|
||||
|
||||
if (pid != -1) {
|
||||
return pid;
|
||||
}
|
||||
|
||||
try {
|
||||
if (sigar == null) {
|
||||
sigar = org.sleuthkit.autopsy.corelibs.SigarLoader.getSigar();
|
||||
}
|
||||
if (sigar != null) {
|
||||
pid = sigar.getPid();
|
||||
} else {
|
||||
System.out.println(NbBundle.getMessage(PlatformUtil.class, "PlatformUtil.getPID.sigarNotInit.msg"));
|
||||
}
|
||||
} catch (Exception e) {
|
||||
System.out.println(NbBundle.getMessage(PlatformUtil.class, "PlatformUtil.getPID.gen.msg", e.toString()));
|
||||
}
|
||||
return pid;
|
||||
|
||||
// taken from https://stackoverflow.com/a/7303433/2375948
|
||||
return ProcessHandle.current().pid();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -536,56 +524,123 @@ public class PlatformUtil {
|
||||
* @return PID of a java process or -1 if it couldn't be determined
|
||||
*/
|
||||
public static synchronized long getJavaPID(String sigarSubQuery) {
|
||||
long jpid = -1;
|
||||
final String sigarQuery = "State.Name.sw=java," + sigarSubQuery; //NON-NLS
|
||||
try {
|
||||
if (sigar == null) {
|
||||
sigar = org.sleuthkit.autopsy.corelibs.SigarLoader.getSigar();
|
||||
}
|
||||
if (sigar != null) {
|
||||
ProcessFinder finder = new ProcessFinder(sigar);
|
||||
jpid = finder.findSingleProcess(sigarQuery);
|
||||
} else {
|
||||
System.out.println(NbBundle.getMessage(PlatformUtil.class, "PlatformUtil.getJavaPID.sigarNotInit.msg"));
|
||||
}
|
||||
} catch (Exception e) {
|
||||
System.out.println(
|
||||
NbBundle.getMessage(PlatformUtil.class, "PlatformUtil.getJavaPID.gen.msg", sigarQuery, e.toString()));
|
||||
long[] pids = getJavaPIDs(sigarSubQuery);
|
||||
return pids == null || pids.length < 1
|
||||
? -1
|
||||
: pids[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs a simple conversion of a sql like statement to regex replacing
|
||||
* '%' and '_' in a like statement with regex equivalents.
|
||||
*
|
||||
* @param originalLikeStatement The original like statement.
|
||||
* @return The equivalent regex string.
|
||||
*/
|
||||
private static String convertSqlLikeToRegex(String originalLikeStatement) {
|
||||
if (originalLikeStatement == null) {
|
||||
return "";
|
||||
}
|
||||
return jpid;
|
||||
|
||||
Map<Character, String> likeEscapeSequences = new HashMap<>() {
|
||||
{
|
||||
put('%', ".*");
|
||||
put('_', ".");
|
||||
}
|
||||
};
|
||||
|
||||
String regexQuoted = Pattern.quote(originalLikeStatement);
|
||||
char[] charArr = regexQuoted.toCharArray();
|
||||
StringBuilder sb = new StringBuilder();
|
||||
|
||||
for (int i = 0; i < charArr.length; i++) {
|
||||
char curChar = charArr[i];
|
||||
String regexReplacement = likeEscapeSequences.get(curChar);
|
||||
if (regexReplacement == null) {
|
||||
sb.append(curChar);
|
||||
} else {
|
||||
Character nextChar = charArr.length > i + 1 ? charArr[i + 1] : null;
|
||||
if (nextChar != null && curChar == nextChar) {
|
||||
sb.append(curChar);
|
||||
i++;
|
||||
} else {
|
||||
sb.append(regexReplacement);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Query and get PIDs of another java processes matching a query
|
||||
*
|
||||
* @param sigarSubQuery a sigar subquery to identify a java processes among
|
||||
* other java processes, for example, by class name,
|
||||
* use: Args.*.eq=org.jboss.Main more examples here:
|
||||
* http://support.hyperic.com/display/SIGAR/PTQL
|
||||
* @param argsSubQuery A like query for command line arguments
|
||||
*
|
||||
* @return array of PIDs of a java processes matching the query or null if
|
||||
* it couldn't be determined
|
||||
*/
|
||||
public static synchronized long[] getJavaPIDs(String sigarSubQuery) {
|
||||
long[] jpids = null;
|
||||
final String sigarQuery = "State.Name.sw=java," + sigarSubQuery; //NON-NLS
|
||||
public static synchronized long[] getJavaPIDs(String argsSubQuery) {
|
||||
try {
|
||||
if (sigar == null) {
|
||||
sigar = org.sleuthkit.autopsy.corelibs.SigarLoader.getSigar();
|
||||
}
|
||||
if (sigar != null) {
|
||||
ProcessFinder finder = new ProcessFinder(sigar);
|
||||
jpids = finder.find(sigarQuery);
|
||||
} else {
|
||||
System.out.println(NbBundle.getMessage(PlatformUtil.class, "PlatformUtil.getJavaPIDs.sigarNotInit"));
|
||||
}
|
||||
} catch (Exception e) {
|
||||
System.out.println(
|
||||
NbBundle.getMessage(PlatformUtil.class, "PlatformUtil.getJavaPIDs.gen.msg", sigarQuery, e.toString()));
|
||||
}
|
||||
return jpids;
|
||||
if (isWindowsOS()) {
|
||||
|
||||
ProcessBuilder pb = new ProcessBuilder("wmic process where \"name='java.exe' AND commandline LIKE '%" + argsSubQuery + "%'\" get ProcessID");
|
||||
String output = IOUtils.toString(pb.start().getInputStream(), StandardCharsets.UTF_8);
|
||||
String[] lines = output.split("\\r?\\n");
|
||||
|
||||
return Stream.of(lines).skip(1).map(ln -> {
|
||||
if (ln == null || ln.trim().isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
try {
|
||||
return Long.parseLong(ln.trim());
|
||||
} catch (NumberFormatException ex) {
|
||||
return null;
|
||||
}
|
||||
})
|
||||
.filter(num -> num != null)
|
||||
.mapToLong(l -> l)
|
||||
.toArray();
|
||||
|
||||
} else {
|
||||
String sigarRegexQuery = convertSqlLikeToRegex(argsSubQuery);
|
||||
ProcessBuilder pb = new ProcessBuilder("sh", "-c", "ps -ef | grep -E 'java.*" + sigarRegexQuery + ".*'");
|
||||
String output = IOUtils.toString(pb.start().getInputStream(), StandardCharsets.UTF_8);
|
||||
List<String> lines = Arrays.asList(output.split("\\r?\\n"));
|
||||
|
||||
if (lines.size() > 0) {
|
||||
// ignore last one as it will be the same as this command
|
||||
lines.remove(lines.size() - 1);
|
||||
}
|
||||
|
||||
return lines.stream().skip(1).map(ln -> {
|
||||
if (ln == null || ln.trim().isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
ln = ln.trim();
|
||||
|
||||
String[] pieces = ln.split("\\s*");
|
||||
if (pieces.length < 2) {
|
||||
return null;
|
||||
}
|
||||
|
||||
try {
|
||||
return Long.parseLong(pieces[1]);
|
||||
} catch (NumberFormatException ex) {
|
||||
return null;
|
||||
}
|
||||
})
|
||||
.filter(num -> num != null)
|
||||
.mapToLong(l -> l)
|
||||
.toArray();
|
||||
}
|
||||
} catch (IOException ex) {
|
||||
System.out.println("An exception occurred while fetching java pids with query: " + argsSubQuery + " with IO Exception: " + ex.getMessage());
|
||||
ex.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -594,20 +649,16 @@ public class PlatformUtil {
|
||||
* @param pid pid of the process to kill
|
||||
*/
|
||||
public static synchronized void killProcess(long pid) {
|
||||
try {
|
||||
if (sigar == null) {
|
||||
sigar = org.sleuthkit.autopsy.corelibs.SigarLoader.getSigar();
|
||||
}
|
||||
if (sigar != null) {
|
||||
sigar.kill(pid, 9);
|
||||
} else {
|
||||
System.out.println(NbBundle.getMessage(PlatformUtil.class, "PlatformUtil.killProcess.sigarNotInit.msg"));
|
||||
}
|
||||
} catch (Exception e) {
|
||||
System.out.println(
|
||||
NbBundle.getMessage(PlatformUtil.class, "PlatformUtil.killProcess.gen.msg", pid, e.toString()));
|
||||
}
|
||||
String cmd = isWindowsOS()
|
||||
? "taskkill /F /PID " + pid
|
||||
: "kill " + pid;
|
||||
|
||||
try {
|
||||
Runtime.getRuntime().exec(cmd);
|
||||
} catch (IOException ex) {
|
||||
System.out.println("An exception occurred while killing process pid: " + pid);
|
||||
ex.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -616,23 +667,8 @@ public class PlatformUtil {
|
||||
* @return virt memory used in bytes or -1 if couldn't be queried
|
||||
*/
|
||||
public static synchronized long getProcessVirtualMemoryUsed() {
|
||||
long virtMem = -1;
|
||||
|
||||
try {
|
||||
if (sigar == null) {
|
||||
sigar = org.sleuthkit.autopsy.corelibs.SigarLoader.getSigar();
|
||||
}
|
||||
|
||||
if (sigar == null || getPID() == -1) {
|
||||
System.out.println(NbBundle.getMessage(PlatformUtil.class, "PlatformUtil.getProcVmUsed.sigarNotInit.msg"));
|
||||
return -1;
|
||||
}
|
||||
virtMem = sigar.getProcMem(getPID()).getSize();
|
||||
} catch (Exception e) {
|
||||
System.out.println(NbBundle.getMessage(PlatformUtil.class, "PlatformUtil.getProcVmUsed.gen.msg", e.toString()));
|
||||
}
|
||||
|
||||
return virtMem;
|
||||
// taken from https://stackoverflow.com/a/17376879/2375948
|
||||
return Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -55,6 +55,11 @@ import org.xml.sax.SAXException;
|
||||
*/
|
||||
public class XMLUtil {
|
||||
|
||||
static {
|
||||
// this is to ensure using xalan for the transformer factory: https://stackoverflow.com/a/64364531/2375948
|
||||
System.setProperty("javax.xml.transform.TransformerFactory","com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl");
|
||||
}
|
||||
|
||||
private static DocumentBuilder getDocumentBuilder() throws ParserConfigurationException {
|
||||
// See JIRA-6958 for details about class loading and jaxb.
|
||||
ClassLoader original = Thread.currentThread().getContextClassLoader();
|
||||
|
@ -515,7 +515,7 @@ public class Artifacts {
|
||||
} catch (TskCoreException ex) {
|
||||
logger.log(Level.WARNING, "Error getting child count", ex); //NON-NLS
|
||||
}
|
||||
super.setDisplayName(this.baseName + " \u200E(\u200E" + this.childCount + ")\u200E");
|
||||
super.setDisplayName(this.baseName + " (" + this.childCount + ")");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -329,7 +329,7 @@ public class Tags implements AutopsyVisitableItem {
|
||||
} catch (TskCoreException | NoCurrentCaseException ex) {
|
||||
Logger.getLogger(TagNameNode.class.getName()).log(Level.SEVERE, "Failed to get tags count for " + tagName.getDisplayName() + " tag name", ex); //NON-NLS
|
||||
}
|
||||
setDisplayName(TagUtils.getDecoratedTagDisplayName(tagName) + " \u200E(\u200E" + tagsCount + ")\u200E");
|
||||
setDisplayName(TagUtils.getDecoratedTagDisplayName(tagName) + " (" + tagsCount + ")");
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -84,12 +84,7 @@ class DirectoryTreeFilterNode extends FilterNode {
|
||||
try {
|
||||
int numVisibleChildren = getVisibleChildCount(file);
|
||||
|
||||
/*
|
||||
* Left-to-right marks here are necessary to keep the count
|
||||
* and parens together for mixed right-to-left and
|
||||
* left-to-right names.
|
||||
*/
|
||||
name = name + " \u200E(\u200E" + numVisibleChildren + ")\u200E"; //NON-NLS
|
||||
name = name + " (" + numVisibleChildren + ")"; //NON-NLS
|
||||
|
||||
} catch (TskCoreException ex) {
|
||||
logger.log(Level.SEVERE, "Error getting children count to display for file: " + file, ex); //NON-NLS
|
||||
@ -98,7 +93,7 @@ class DirectoryTreeFilterNode extends FilterNode {
|
||||
BlackboardArtifact artifact = ((BlackboardArtifactNode) orig).getArtifact();
|
||||
try {
|
||||
int numAttachments = artifact.getChildrenCount();
|
||||
name = name + " \u200E(\u200E" + numAttachments + ")\u200E"; //NON-NLS
|
||||
name = name + " (" + numAttachments + ")"; //NON-NLS
|
||||
} catch (TskCoreException ex) {
|
||||
logger.log(Level.SEVERE, "Error getting chidlren count for atifact: " + artifact, ex); //NON-NLS
|
||||
}
|
||||
|
228
Core/src/org/sleuthkit/autopsy/guicomponentutils/AutoCompletion.java
Executable file
228
Core/src/org/sleuthkit/autopsy/guicomponentutils/AutoCompletion.java
Executable file
@ -0,0 +1,228 @@
|
||||
package org.sleuthkit.autopsy.guicomponentutils;
|
||||
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.awt.event.FocusAdapter;
|
||||
import java.awt.event.FocusEvent;
|
||||
import java.awt.event.FocusListener;
|
||||
import java.awt.event.KeyAdapter;
|
||||
import java.awt.event.KeyEvent;
|
||||
import java.awt.event.KeyListener;
|
||||
import java.beans.PropertyChangeEvent;
|
||||
import java.beans.PropertyChangeListener;
|
||||
import javax.swing.ComboBoxEditor;
|
||||
import javax.swing.ComboBoxModel;
|
||||
import javax.swing.JComboBox;
|
||||
import javax.swing.text.AttributeSet;
|
||||
import javax.swing.text.BadLocationException;
|
||||
import javax.swing.text.JTextComponent;
|
||||
import javax.swing.text.PlainDocument;
|
||||
|
||||
|
||||
/*
|
||||
* This code is taken from http://www.orbital-computer.de/JComboBox/source/AutoCompletion.java
|
||||
* Author: Thomas Bierhance
|
||||
* This work is hereby released into the Public Domain. To view a copy of the
|
||||
* public domain dedication, visit
|
||||
* http://creativecommons.org/licenses/publicdomain/
|
||||
*/
|
||||
public class AutoCompletion extends PlainDocument {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private JComboBox<?> comboBox;
|
||||
private ComboBoxModel<?> model;
|
||||
private JTextComponent editor;
|
||||
// flag to indicate if setSelectedItem has been called
|
||||
// subsequent calls to remove/insertString should be ignored
|
||||
private boolean selecting = false;
|
||||
private boolean hidePopupOnFocusLoss;
|
||||
private boolean hitBackspace = false;
|
||||
private boolean hitBackspaceOnSelection;
|
||||
|
||||
private KeyListener editorKeyListener;
|
||||
private FocusListener editorFocusListener;
|
||||
|
||||
public AutoCompletion(final JComboBox<?> comboBox) {
|
||||
this.comboBox = comboBox;
|
||||
model = comboBox.getModel();
|
||||
comboBox.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
if (!selecting) {
|
||||
highlightCompletedText(0);
|
||||
}
|
||||
}
|
||||
});
|
||||
comboBox.addPropertyChangeListener(new PropertyChangeListener() {
|
||||
@Override
|
||||
public void propertyChange(PropertyChangeEvent e) {
|
||||
if (e.getPropertyName().equals("editor")) {
|
||||
configureEditor((ComboBoxEditor) e.getNewValue());
|
||||
}
|
||||
if (e.getPropertyName().equals("model")) {
|
||||
model = (ComboBoxModel) e.getNewValue();
|
||||
}
|
||||
}
|
||||
});
|
||||
editorKeyListener = new KeyAdapter() {
|
||||
@Override
|
||||
public void keyPressed(KeyEvent e) {
|
||||
if (comboBox.isDisplayable()) {
|
||||
comboBox.setPopupVisible(true);
|
||||
}
|
||||
hitBackspace = false;
|
||||
switch (e.getKeyCode()) {
|
||||
// determine if the pressed key is backspace (needed by the remove method)
|
||||
case KeyEvent.VK_BACK_SPACE:
|
||||
hitBackspace = true;
|
||||
hitBackspaceOnSelection = editor.getSelectionStart() != editor.getSelectionEnd();
|
||||
break;
|
||||
// ignore delete key
|
||||
case KeyEvent.VK_DELETE:
|
||||
e.consume();
|
||||
comboBox.getToolkit().beep();
|
||||
break;
|
||||
}
|
||||
}
|
||||
};
|
||||
// Bug 5100422 on Java 1.5: Editable JComboBox won't hide popup when tabbing out
|
||||
hidePopupOnFocusLoss = System.getProperty("java.version").startsWith("1.5");
|
||||
// Highlight whole text when gaining focus
|
||||
editorFocusListener = new FocusAdapter() {
|
||||
@Override
|
||||
public void focusGained(FocusEvent e) {
|
||||
highlightCompletedText(0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void focusLost(FocusEvent e) {
|
||||
// Workaround for Bug 5100422 - Hide Popup on focus loss
|
||||
if (hidePopupOnFocusLoss) {
|
||||
comboBox.setPopupVisible(false);
|
||||
}
|
||||
}
|
||||
};
|
||||
configureEditor(comboBox.getEditor());
|
||||
// Handle initially selected object
|
||||
Object selected = comboBox.getSelectedItem();
|
||||
if (selected != null) {
|
||||
setText(selected.toString());
|
||||
}
|
||||
highlightCompletedText(0);
|
||||
}
|
||||
|
||||
public static void enable(JComboBox<?> comboBox) {
|
||||
// has to be editable
|
||||
comboBox.setEditable(true);
|
||||
// change the editor's document
|
||||
new AutoCompletion(comboBox);
|
||||
}
|
||||
|
||||
void configureEditor(ComboBoxEditor newEditor) {
|
||||
if (editor != null) {
|
||||
editor.removeKeyListener(editorKeyListener);
|
||||
editor.removeFocusListener(editorFocusListener);
|
||||
}
|
||||
|
||||
if (newEditor != null) {
|
||||
editor = (JTextComponent) newEditor.getEditorComponent();
|
||||
editor.addKeyListener(editorKeyListener);
|
||||
editor.addFocusListener(editorFocusListener);
|
||||
editor.setDocument(this);
|
||||
}
|
||||
}
|
||||
|
||||
public void remove(int offs, int len) throws BadLocationException {
|
||||
// return immediately when selecting an item
|
||||
if (selecting) {
|
||||
return;
|
||||
}
|
||||
if (hitBackspace) {
|
||||
// user hit backspace => move the selection backwards
|
||||
// old item keeps being selected
|
||||
if (offs > 0) {
|
||||
if (hitBackspaceOnSelection) {
|
||||
offs--;
|
||||
}
|
||||
} else {
|
||||
// User hit backspace with the cursor positioned on the start => beep
|
||||
comboBox.getToolkit().beep(); // when available use: UIManager.getLookAndFeel().provideErrorFeedback(comboBox);
|
||||
}
|
||||
highlightCompletedText(offs);
|
||||
} else {
|
||||
super.remove(offs, len);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void insertString(int offs, String str, AttributeSet a) throws BadLocationException {
|
||||
// return immediately when selecting an item
|
||||
if (selecting) {
|
||||
return;
|
||||
}
|
||||
// insert the string into the document
|
||||
super.insertString(offs, str, a);
|
||||
// lookup and select a matching item
|
||||
Object item = lookupItem(getText(0, getLength()));
|
||||
if (item != null) {
|
||||
setSelectedItem(item);
|
||||
} else {
|
||||
// keep old item selected if there is no match
|
||||
item = comboBox.getSelectedItem();
|
||||
// imitate no insert (later on offs will be incremented by str.length(): selection won't move forward)
|
||||
offs = offs - str.length();
|
||||
// provide feedback to the user that his input has been received but can not be accepted
|
||||
comboBox.getToolkit().beep(); // when available use: UIManager.getLookAndFeel().provideErrorFeedback(comboBox);
|
||||
}
|
||||
setText(item.toString());
|
||||
// select the completed part
|
||||
highlightCompletedText(offs + str.length());
|
||||
}
|
||||
|
||||
private void setText(String text) {
|
||||
try {
|
||||
// remove all text and insert the completed string
|
||||
super.remove(0, getLength());
|
||||
super.insertString(0, text, null);
|
||||
} catch (BadLocationException e) {
|
||||
throw new RuntimeException(e.toString());
|
||||
}
|
||||
}
|
||||
|
||||
private void highlightCompletedText(int start) {
|
||||
editor.setCaretPosition(getLength());
|
||||
editor.moveCaretPosition(start);
|
||||
}
|
||||
|
||||
private void setSelectedItem(Object item) {
|
||||
selecting = true;
|
||||
model.setSelectedItem(item);
|
||||
selecting = false;
|
||||
}
|
||||
|
||||
private Object lookupItem(String pattern) {
|
||||
Object selectedItem = model.getSelectedItem();
|
||||
// only search for a different item if the currently selected does not match
|
||||
if (selectedItem != null && startsWithIgnoreCase(selectedItem.toString(), pattern)) {
|
||||
return selectedItem;
|
||||
} else {
|
||||
// iterate over all items
|
||||
for (int i = 0, n = model.getSize(); i < n; i++) {
|
||||
Object currentItem = model.getElementAt(i);
|
||||
// current item starts with the pattern?
|
||||
if (currentItem != null && startsWithIgnoreCase(currentItem.toString(), pattern)) {
|
||||
return currentItem;
|
||||
}
|
||||
}
|
||||
}
|
||||
// no item starts with the pattern => return null
|
||||
return null;
|
||||
}
|
||||
|
||||
// checks if str1 starts with str2 - ignores case
|
||||
private boolean startsWithIgnoreCase(String str1, String str2) {
|
||||
return str1.toUpperCase().startsWith(str2.toUpperCase());
|
||||
}
|
||||
|
||||
}
|
@ -25,6 +25,7 @@ import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.text.MessageFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
@ -402,7 +403,7 @@ public final class IngestJobSettings {
|
||||
}
|
||||
for (String moduleName : disabledModuleNames) {
|
||||
if (!loadedModuleNames.contains(moduleName)) {
|
||||
missingModuleNames.add(moduleName);
|
||||
logger.log(Level.WARNING, MessageFormat.format("A module marked as disabled in the ingest job settings, ''{0}'', could not be found.", moduleName));
|
||||
}
|
||||
}
|
||||
for (String moduleName : missingModuleNames) {
|
||||
|
@ -23,8 +23,8 @@ import java.security.NoSuchAlgorithmException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.logging.Level;
|
||||
import javax.xml.bind.DatatypeConverter;
|
||||
import java.util.Arrays;
|
||||
import org.apache.commons.codec.binary.Hex;
|
||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||
import org.sleuthkit.autopsy.ingest.DataSourceIngestModule;
|
||||
import org.sleuthkit.autopsy.ingest.DataSourceIngestModuleProgress;
|
||||
@ -250,8 +250,8 @@ public class DataSourceIntegrityIngestModule implements DataSourceIngestModule {
|
||||
}
|
||||
|
||||
// Produce the final hashes
|
||||
for (HashData hashData : hashDataList) {
|
||||
hashData.calculatedHash = DatatypeConverter.printHexBinary(hashData.digest.digest()).toLowerCase();
|
||||
for(HashData hashData: hashDataList) {
|
||||
hashData.calculatedHash = Hex.encodeHexString(hashData.digest.digest()).toLowerCase();
|
||||
logger.log(Level.INFO, "Hash calculated from {0}: {1}", new Object[]{imgName, hashData.calculatedHash}); //NON-NLS
|
||||
}
|
||||
|
||||
|
@ -22,7 +22,8 @@ import java.io.UnsupportedEncodingException;
|
||||
import java.nio.charset.Charset;
|
||||
import javax.swing.DefaultComboBoxModel;
|
||||
import javax.swing.JOptionPane;
|
||||
import javax.xml.bind.DatatypeConverter;
|
||||
import org.apache.commons.codec.DecoderException;
|
||||
import org.apache.commons.codec.binary.Hex;
|
||||
import org.openide.util.NbBundle;
|
||||
import org.openide.util.NbBundle.Messages;
|
||||
import org.sleuthkit.autopsy.modules.filetypeid.FileType.Signature;
|
||||
@ -101,7 +102,7 @@ class AddFileTypeSignaturePanel extends javax.swing.JPanel {
|
||||
this.offsetTextField.setText(toEdit.getOffset() + "");
|
||||
if (Signature.Type.RAW == toEdit.getType()) {
|
||||
this.signatureTypeComboBox.setSelectedIndex(0);
|
||||
this.signatureTextField.setText(DatatypeConverter.printHexBinary(toEdit.getSignatureBytes()));
|
||||
this.signatureTextField.setText(Hex.encodeHexString(toEdit.getSignatureBytes()));
|
||||
} else {
|
||||
this.signatureTypeComboBox.setSelectedIndex(1);
|
||||
try {
|
||||
@ -146,8 +147,8 @@ class AddFileTypeSignaturePanel extends javax.swing.JPanel {
|
||||
if (FileType.Signature.Type.RAW == sigType) {
|
||||
try {
|
||||
sigString = sigString.replaceAll("\\s", ""); //NON-NLS
|
||||
signatureBytes = DatatypeConverter.parseHexBinary(sigString);
|
||||
} catch (IllegalArgumentException ex) {
|
||||
signatureBytes = Hex.decodeHex(sigString);
|
||||
} catch (DecoderException ex) {
|
||||
JOptionPane.showMessageDialog(this,
|
||||
NbBundle.getMessage(FileTypeIdGlobalSettingsPanel.class, "FileTypeIdGlobalSettingsPanel.JOptionPane.invalidRawSignatureBytes.message"),
|
||||
NbBundle.getMessage(FileTypeIdGlobalSettingsPanel.class, "FileTypeIdGlobalSettingsPanel.JOptionPane.invalidSignatureBytes.title"),
|
||||
|
@ -28,6 +28,8 @@ import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import javax.xml.bind.DatatypeConverter;
|
||||
import javax.xml.parsers.ParserConfigurationException;
|
||||
import org.apache.commons.codec.DecoderException;
|
||||
import org.apache.commons.codec.binary.Hex;
|
||||
import org.openide.util.io.NbObjectInputStream;
|
||||
import org.openide.util.io.NbObjectOutputStream;
|
||||
import org.sleuthkit.autopsy.coreutils.PlatformUtil;
|
||||
@ -166,7 +168,7 @@ final class CustomFileTypesManager {
|
||||
/*
|
||||
* Add type for gzip.
|
||||
*/
|
||||
byteArray = DatatypeConverter.parseHexBinary("1F8B"); //NON-NLS
|
||||
byteArray = Hex.decodeHex("1F8B"); //NON-NLS
|
||||
signatureList.clear();
|
||||
signatureList.add(new Signature(byteArray, 0L));
|
||||
fileType = new FileType("application/x-gzip", signatureList); //NON-NLS
|
||||
@ -175,7 +177,7 @@ final class CustomFileTypesManager {
|
||||
/*
|
||||
* Add type for wk1.
|
||||
*/
|
||||
byteArray = DatatypeConverter.parseHexBinary("0000020006040600080000000000"); //NON-NLS
|
||||
byteArray = Hex.decodeHex("0000020006040600080000000000"); //NON-NLS
|
||||
signatureList.clear();
|
||||
signatureList.add(new Signature(byteArray, 0L));
|
||||
fileType = new FileType("application/x-123", signatureList); //NON-NLS
|
||||
@ -184,7 +186,7 @@ final class CustomFileTypesManager {
|
||||
/*
|
||||
* Add type for Radiance images.
|
||||
*/
|
||||
byteArray = DatatypeConverter.parseHexBinary("233F52414449414E43450A");//NON-NLS
|
||||
byteArray = Hex.decodeHex("233F52414449414E43450A");//NON-NLS
|
||||
signatureList.clear();
|
||||
signatureList.add(new Signature(byteArray, 0L));
|
||||
fileType = new FileType("image/vnd.radiance", signatureList); //NON-NLS
|
||||
@ -193,7 +195,7 @@ final class CustomFileTypesManager {
|
||||
/*
|
||||
* Add type for dcx images.
|
||||
*/
|
||||
byteArray = DatatypeConverter.parseHexBinary("B168DE3A"); //NON-NLS
|
||||
byteArray = Hex.decodeHex("B168DE3A"); //NON-NLS
|
||||
signatureList.clear();
|
||||
signatureList.add(new Signature(byteArray, 0L));
|
||||
fileType = new FileType("image/x-dcx", signatureList); //NON-NLS
|
||||
@ -210,7 +212,7 @@ final class CustomFileTypesManager {
|
||||
/*
|
||||
* Add type for pict images.
|
||||
*/
|
||||
byteArray = DatatypeConverter.parseHexBinary("001102FF"); //NON-NLS
|
||||
byteArray = Hex.decodeHex("001102FF"); //NON-NLS
|
||||
signatureList.clear();
|
||||
signatureList.add(new Signature(byteArray, 522L));
|
||||
fileType = new FileType("image/x-pict", signatureList); //NON-NLS
|
||||
@ -251,7 +253,7 @@ final class CustomFileTypesManager {
|
||||
/*
|
||||
* Add type for tga.
|
||||
*/
|
||||
byteArray = DatatypeConverter.parseHexBinary("54525545564953494F4E2D5846494C452E00"); //NON-NLS
|
||||
byteArray = Hex.decodeHex("54525545564953494F4E2D5846494C452E00"); //NON-NLS
|
||||
signatureList.clear();
|
||||
signatureList.add(new Signature(byteArray, 17, false));
|
||||
fileType = new FileType("image/x-tga", signatureList); //NON-NLS
|
||||
@ -311,7 +313,7 @@ final class CustomFileTypesManager {
|
||||
* Add type for .tec files with leading End Of Image marker (JFIF
|
||||
* JPEG)
|
||||
*/
|
||||
byteArray = DatatypeConverter.parseHexBinary("FFD9FFD8"); //NON-NLS
|
||||
byteArray = Hex.decodeHex("FFD9FFD8"); //NON-NLS
|
||||
signatureList.clear();
|
||||
signatureList.add(new Signature(byteArray, 0L));
|
||||
fileType = new FileType("image/jpeg", signatureList); //NON-NLS
|
||||
@ -321,7 +323,7 @@ final class CustomFileTypesManager {
|
||||
* Add type for Windows NT registry files with leading End Of Image marker (JFIF
|
||||
* JPEG)
|
||||
*/
|
||||
byteArray = DatatypeConverter.parseHexBinary("72656766"); //NON-NLS
|
||||
byteArray = Hex.decodeHex("72656766"); //NON-NLS
|
||||
signatureList.clear();
|
||||
signatureList.add(new Signature(byteArray, 0L));
|
||||
fileType = new FileType("application/x.windows-registry", signatureList); //NON-NLS
|
||||
@ -345,9 +347,10 @@ final class CustomFileTypesManager {
|
||||
fileType = new FileType("application/x-vhd", signatureList); //NON-NLS
|
||||
autopsyDefinedFileTypes.add(fileType);
|
||||
|
||||
} catch (IllegalArgumentException ex) {
|
||||
} catch (DecoderException ex) {
|
||||
/*
|
||||
* parseHexBinary() throws this if the argument passed in is not hex
|
||||
* decodeHex() throws this if an odd number of characters or illegal
|
||||
* characters are supplied
|
||||
*/
|
||||
throw new CustomFileTypesException("Error creating Autopsy defined custom file types", ex); //NON-NLS
|
||||
}
|
||||
@ -442,7 +445,7 @@ final class CustomFileTypesManager {
|
||||
}
|
||||
}
|
||||
return fileTypes;
|
||||
} catch (IOException | ParserConfigurationException | SAXException ex) {
|
||||
} catch (IOException | ParserConfigurationException | SAXException | DecoderException ex) {
|
||||
throw new CustomFileTypesException(String.format("Failed to read ssettings from %s", filePath), ex); //NON-NLS
|
||||
}
|
||||
}
|
||||
@ -459,7 +462,7 @@ final class CustomFileTypesManager {
|
||||
* @throws NumberFormatException if there is a problem parsing the file
|
||||
* type.
|
||||
*/
|
||||
private static FileType parseFileType(Element fileTypeElem) throws IllegalArgumentException, NumberFormatException {
|
||||
private static FileType parseFileType(Element fileTypeElem) throws DecoderException, NumberFormatException {
|
||||
String mimeType = parseMimeType(fileTypeElem);
|
||||
Signature signature = parseSignature(fileTypeElem);
|
||||
// File type definitions in the XML file were written prior to the
|
||||
@ -487,7 +490,7 @@ final class CustomFileTypesManager {
|
||||
*
|
||||
* @return The signature.
|
||||
*/
|
||||
private static Signature parseSignature(Element fileTypeElem) throws IllegalArgumentException, NumberFormatException {
|
||||
private static Signature parseSignature(Element fileTypeElem) throws DecoderException, NumberFormatException {
|
||||
NodeList signatureElems = fileTypeElem.getElementsByTagName(SIGNATURE_TAG_NAME);
|
||||
Element signatureElem = (Element) signatureElems.item(0);
|
||||
|
||||
@ -495,18 +498,18 @@ final class CustomFileTypesManager {
|
||||
Signature.Type signatureType = Signature.Type.valueOf(sigTypeAttribute);
|
||||
|
||||
String sigBytesString = getChildElementTextContent(signatureElem, BYTES_TAG_NAME);
|
||||
byte[] signatureBytes = DatatypeConverter.parseHexBinary(sigBytesString);
|
||||
byte[] signatureBytes = Hex.decodeHex(sigBytesString);
|
||||
|
||||
Element offsetElem = (Element) signatureElem.getElementsByTagName(OFFSET_TAG_NAME).item(0);
|
||||
String offsetString = offsetElem.getTextContent();
|
||||
long offset = DatatypeConverter.parseLong(offsetString);
|
||||
long offset = Long.parseLong(offsetString);
|
||||
|
||||
boolean isRelativeToStart;
|
||||
String relativeString = offsetElem.getAttribute(RELATIVE_ATTRIBUTE);
|
||||
if (null == relativeString || relativeString.equals("")) {
|
||||
isRelativeToStart = true;
|
||||
} else {
|
||||
isRelativeToStart = DatatypeConverter.parseBoolean(relativeString);
|
||||
isRelativeToStart = Boolean.parseBoolean(relativeString);
|
||||
}
|
||||
|
||||
return new Signature(signatureBytes, offset, signatureType, isRelativeToStart);
|
||||
|
@ -28,7 +28,7 @@ import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.logging.Level;
|
||||
import javax.swing.JOptionPane;
|
||||
import javax.xml.bind.DatatypeConverter;
|
||||
import org.apache.commons.codec.binary.Hex;
|
||||
import org.openide.windows.WindowManager;
|
||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||
import org.sleuthkit.datamodel.AbstractFile;
|
||||
@ -389,7 +389,7 @@ class FileType implements Serializable {
|
||||
public String toString() {
|
||||
String signatureBytesString;
|
||||
if (Signature.Type.RAW == this.getType()) {
|
||||
signatureBytesString = DatatypeConverter.printHexBinary(this.getSignatureBytes());
|
||||
signatureBytesString = Hex.encodeHexString(this.getSignatureBytes());
|
||||
signatureBytesString = "0x" + signatureBytesString;
|
||||
} else {
|
||||
try {
|
||||
|
@ -61,10 +61,7 @@ ImportCentralRepoDbProgressDialog.errorParsingFile.message=Error parsing hash se
|
||||
ImportCentralRepoDbProgressDialog.linesProcessed.message=\ hashes processed
|
||||
ImportCentralRepoDbProgressDialog.title.text=Central Repository Import Progress
|
||||
OpenIDE-Module-Display-Category=Ingest Module
|
||||
OpenIDE-Module-Long-Description=\
|
||||
Hash Set ingest module. \n\n\
|
||||
The ingest module analyzes files in the disk image and marks them as "known" (based on NSRL hashset lookup for "known" files) and "bad / interesting" (based on one or more hash sets supplied by the user).\n\n\
|
||||
The module also contains additional non-ingest tools that are integrated in the GUI, such as file lookup by hash and hash set configuration.
|
||||
OpenIDE-Module-Long-Description=Hash Set ingest module. \n\nThe ingest module analyzes files in the disk image and marks them as "known" (based on NSRL hashset lookup for "known" files) and "bad / interesting" (based on one or more hash sets supplied by the user).\n\nThe module also contains additional non-ingest tools that are integrated in the GUI, such as file lookup by hash and hash set configuration.
|
||||
OpenIDE-Module-Name=HashDatabases
|
||||
OptionsCategory_Name_HashDatabase=Hash Sets
|
||||
OptionsCategory_Keywords_HashDatabase=Hash Sets
|
||||
@ -191,10 +188,7 @@ HashDbSearchThread.name.searching=Searching
|
||||
HashDbSearchThread.noMoreFilesWithMD5Msg=No other files with the same MD5 hash were found.
|
||||
ModalNoButtons.indexingDbsTitle=Indexing hash sets
|
||||
ModalNoButtons.indexingDbTitle=Indexing hash set
|
||||
ModalNoButtons.exitHashDbIndexingMsg=You are about to exit out of indexing your hash sets. \n\
|
||||
The generated index will be left unusable. If you choose to continue,\n\
|
||||
please delete the corresponding -md5.idx file in the hash folder.\n\
|
||||
Exit indexing?
|
||||
ModalNoButtons.exitHashDbIndexingMsg=You are about to exit out of indexing your hash sets. \nThe generated index will be left unusable. If you choose to continue,\nplease delete the corresponding -md5.idx file in the hash folder.\nExit indexing?
|
||||
ModalNoButtons.dlgTitle.unfinishedIndexing=Unfinished Indexing
|
||||
ModalNoButtons.indexThis.currentlyIndexing1Db=Currently indexing 1 hash set
|
||||
ModalNoButtons.indexThese.currentlyIndexing1OfNDbs=Currently indexing 1 of {0}
|
||||
|
@ -123,8 +123,8 @@ FilesSetRulePanel.nameTextField.text=
|
||||
FilesSetRulePanel.ruleNameLabel.text=Rule Name (Optional):
|
||||
FilesSetRulePanel.messages.emptyNameCondition=You must specify a name pattern for this rule.
|
||||
FilesSetRulePanel.messages.invalidNameRegex=The name regular expression is not valid:\n\n{0}
|
||||
FilesSetRulePanel.messages.invalidCharInName=The name cannot contain \\, /, :, *, ?, \", <, or > unless it is a regular expression.
|
||||
FilesSetRulePanel.messages.invalidCharInPath=The path cannot contain \\, :, *, ?, \", <, or > unless it is a regular expression.
|
||||
FilesSetRulePanel.messages.invalidCharInName=The name cannot contain \\, /, :, *, ?, ", <, or > unless it is a regular expression.
|
||||
FilesSetRulePanel.messages.invalidCharInPath=The path cannot contain \\, :, *, ?, ", <, or > unless it is a regular expression.
|
||||
FilesSetRulePanel.messages.invalidPathRegex=The path regular expression is not valid:\n\n{0}
|
||||
FilesSetDefsPanel.doFileSetsDialog.duplicateRuleSet.text=Rule set with name {0} already exists.
|
||||
FilesSetRulePanel.pathSeparatorInfoLabel.text=Folder must be in parent path. Use '/' to give consecutive names
|
||||
|
@ -18,6 +18,7 @@
|
||||
*/
|
||||
package org.sleuthkit.autopsy.modules.interestingitems;
|
||||
|
||||
import org.sleuthkit.autopsy.guicomponentutils.AutoCompletion;
|
||||
import java.awt.Color;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.util.Arrays;
|
||||
@ -76,6 +77,7 @@ final class FilesSetRulePanel extends javax.swing.JPanel {
|
||||
*/
|
||||
FilesSetRulePanel(JButton okButton, JButton cancelButton, PANEL_TYPE panelType) {
|
||||
initComponents();
|
||||
AutoCompletion.enable(mimeTypeComboBox);
|
||||
if (panelType == FilesSetDefsPanel.PANEL_TYPE.FILE_INGEST_FILTERS) { //Hide the mimetype settings when this is displaying a FileSet rule instead of a interesting item rule
|
||||
mimeTypeComboBox.setVisible(false);
|
||||
mimeCheck.setVisible(false);
|
||||
@ -102,6 +104,7 @@ final class FilesSetRulePanel extends javax.swing.JPanel {
|
||||
*/
|
||||
FilesSetRulePanel(FilesSet.Rule rule, JButton okButton, JButton cancelButton, PANEL_TYPE panelType) {
|
||||
initComponents();
|
||||
AutoCompletion.enable(mimeTypeComboBox);
|
||||
if (panelType == FilesSetDefsPanel.PANEL_TYPE.FILE_INGEST_FILTERS) { //Hide the mimetype settings when this is displaying a FileSet rule instead of a interesting item rule
|
||||
mimeTypeComboBox.setVisible(false);
|
||||
mimeCheck.setVisible(false);
|
||||
|
@ -24,7 +24,7 @@ PhotoRecIngestModule.complete.totalParsetime=Total Parsing Time:
|
||||
PhotoRecIngestModule.complete.photoRecResults=PhotoRec Results
|
||||
PhotoRecIngestModule.NotEnoughDiskSpace.detail.msg=PhotoRec error processing {0} with {1} Not enough space on primary disk to save unallocated space.
|
||||
PhotoRecIngestModule.cancelledByUser=PhotoRec cancelled by user.
|
||||
PhotoRecIngestModule.error.exitValue=PhotoRec carver returned error exit value \= {0} when scanning {1}
|
||||
PhotoRecIngestModule.error.exitValue=PhotoRec carver returned error exit value = {0} when scanning {1}
|
||||
PhotoRecIngestModule.error.msg=Error processing {0} with PhotoRec carver.
|
||||
PhotoRecIngestModule.complete.numberOfErrors=Number of Errors while Carving:
|
||||
PhotoRecCarverIngestJobSettingsPanel.detectionSettingsLabel.text=PhotoRec Settings
|
||||
|
@ -24,14 +24,14 @@
|
||||
<Group type="102" alignment="0" attributes="0">
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Component id="statusMessageLabel" max="32767" attributes="0"/>
|
||||
<Component id="statusMessageLabel" pref="474" max="32767" attributes="0"/>
|
||||
<Component id="reportProgressBar" alignment="0" max="32767" attributes="0"/>
|
||||
<Group type="102" alignment="0" attributes="0">
|
||||
<Component id="reportLabel" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="separationLabel" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="pathLabel" pref="548" max="32767" attributes="0"/>
|
||||
<Component id="pathLabel" max="32767" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
@ -86,11 +86,32 @@
|
||||
</Property>
|
||||
</Properties>
|
||||
</Component>
|
||||
<Component class="javax.swing.JLabel" name="statusMessageLabel">
|
||||
<Component class="javax.swing.JTextArea" name="statusMessageLabel">
|
||||
<Properties>
|
||||
<Property name="editable" type="boolean" value="false"/>
|
||||
<Property name="background" type="java.awt.Color" editor="org.netbeans.modules.form.RADConnectionPropertyEditor">
|
||||
<Connection code="null" type="code"/>
|
||||
</Property>
|
||||
<Property name="lineWrap" type="boolean" value="true"/>
|
||||
<Property name="rows" type="int" value="5"/>
|
||||
<Property name="tabSize" type="int" value="4"/>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/report/Bundle.properties" key="ReportProgressPanel.statusMessageLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
<Property name="wrapStyleWord" type="boolean" value="true"/>
|
||||
<Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor">
|
||||
<Border info="null"/>
|
||||
</Property>
|
||||
<Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||
<Dimension value="[2147483647, 80]"/>
|
||||
</Property>
|
||||
<Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||
<Dimension value="[101, 80]"/>
|
||||
</Property>
|
||||
<Property name="opaque" type="boolean" value="false"/>
|
||||
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||
<Dimension value="[2147483647, 80]"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
</Component>
|
||||
</SubComponents>
|
||||
|
@ -41,6 +41,8 @@ public class ReportProgressPanel extends javax.swing.JPanel {
|
||||
private static final Color GREEN = new Color(50, 205, 50);
|
||||
private static final Color RED = new Color(178, 34, 34);
|
||||
private volatile ReportStatus status;
|
||||
private static final int MAX_STATUS_LENGTH = 500;
|
||||
private static final String ELIPSIS = "...";
|
||||
|
||||
/**
|
||||
* Used by a report generation module to communicate report generation
|
||||
@ -75,6 +77,15 @@ public class ReportProgressPanel extends javax.swing.JPanel {
|
||||
return displayName;
|
||||
}
|
||||
}
|
||||
|
||||
private void setStatusText(String message) {
|
||||
if (message == null) {
|
||||
message = "";
|
||||
} else if (message.length() > MAX_STATUS_LENGTH) {
|
||||
message = message.substring(0, MAX_STATUS_LENGTH) + ELIPSIS;
|
||||
}
|
||||
this.statusMessageLabel.setText(message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a panel used by report generation module to show progress.
|
||||
@ -83,7 +94,7 @@ public class ReportProgressPanel extends javax.swing.JPanel {
|
||||
initComponents();
|
||||
reportProgressBar.setIndeterminate(true);
|
||||
reportProgressBar.setMaximum(100);
|
||||
statusMessageLabel.setText(Bundle.ReportProgressPanel_progress_queuing());
|
||||
setStatusText(Bundle.ReportProgressPanel_progress_queuing());
|
||||
status = ReportStatus.QUEUING;
|
||||
reportLabel.setText("");
|
||||
pathLabel.setText(""); //NON-NLS
|
||||
@ -174,7 +185,7 @@ public class ReportProgressPanel extends javax.swing.JPanel {
|
||||
*/
|
||||
public void start() {
|
||||
EventQueue.invokeLater(() -> {
|
||||
statusMessageLabel.setText(NbBundle.getMessage(this.getClass(), "ReportProgressPanel.start.progress.text"));
|
||||
setStatusText(NbBundle.getMessage(this.getClass(), "ReportProgressPanel.start.progress.text"));
|
||||
status = ReportStatus.RUNNING;
|
||||
});
|
||||
}
|
||||
@ -242,7 +253,7 @@ public class ReportProgressPanel extends javax.swing.JPanel {
|
||||
public void updateStatusLabel(String statusMessage) {
|
||||
EventQueue.invokeLater(() -> {
|
||||
if (status != ReportStatus.CANCELED) {
|
||||
statusMessageLabel.setText(statusMessage);
|
||||
setStatusText(statusMessage);
|
||||
}
|
||||
});
|
||||
}
|
||||
@ -284,7 +295,7 @@ public class ReportProgressPanel extends javax.swing.JPanel {
|
||||
ReportStatus oldValue = status;
|
||||
status = ReportStatus.COMPLETE;
|
||||
statusMessageLabel.setForeground(Color.BLACK);
|
||||
statusMessageLabel.setText(statusMessage);
|
||||
setStatusText(statusMessage);
|
||||
reportProgressBar.setValue(reportProgressBar.getMaximum());
|
||||
reportProgressBar.setStringPainted(true);
|
||||
reportProgressBar.setForeground(GREEN);
|
||||
@ -296,7 +307,7 @@ public class ReportProgressPanel extends javax.swing.JPanel {
|
||||
ReportStatus oldValue = status;
|
||||
status = ReportStatus.ERROR;
|
||||
statusMessageLabel.setForeground(RED);
|
||||
statusMessageLabel.setText(statusMessage);
|
||||
setStatusText(statusMessage);
|
||||
reportProgressBar.setValue(reportProgressBar.getMaximum());
|
||||
reportProgressBar.setStringPainted(true);
|
||||
reportProgressBar.setForeground(RED);
|
||||
@ -334,7 +345,7 @@ public class ReportProgressPanel extends javax.swing.JPanel {
|
||||
reportProgressBar.setString(ReportStatus.CANCELED.getDisplayName());
|
||||
firePropertyChange(ReportStatus.CANCELED.toString(), oldValue, status);
|
||||
statusMessageLabel.setForeground(RED);
|
||||
statusMessageLabel.setText(NbBundle.getMessage(this.getClass(), "ReportProgressPanel.cancel.procLbl.text"));
|
||||
setStatusText(NbBundle.getMessage(this.getClass(), "ReportProgressPanel.cancel.procLbl.text"));
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -368,7 +379,7 @@ public class ReportProgressPanel extends javax.swing.JPanel {
|
||||
reportLabel = new javax.swing.JLabel();
|
||||
pathLabel = new javax.swing.JLabel();
|
||||
separationLabel = new javax.swing.JLabel();
|
||||
statusMessageLabel = new javax.swing.JLabel();
|
||||
statusMessageLabel = new javax.swing.JTextArea();
|
||||
|
||||
setMinimumSize(new java.awt.Dimension(486, 68));
|
||||
|
||||
@ -380,7 +391,18 @@ public class ReportProgressPanel extends javax.swing.JPanel {
|
||||
|
||||
org.openide.awt.Mnemonics.setLocalizedText(separationLabel, org.openide.util.NbBundle.getMessage(ReportProgressPanel.class, "ReportProgressPanel.separationLabel.text")); // NOI18N
|
||||
|
||||
org.openide.awt.Mnemonics.setLocalizedText(statusMessageLabel, org.openide.util.NbBundle.getMessage(ReportProgressPanel.class, "ReportProgressPanel.statusMessageLabel.text")); // NOI18N
|
||||
statusMessageLabel.setEditable(false);
|
||||
statusMessageLabel.setBackground(null);
|
||||
statusMessageLabel.setLineWrap(true);
|
||||
statusMessageLabel.setRows(5);
|
||||
statusMessageLabel.setTabSize(4);
|
||||
statusMessageLabel.setText(org.openide.util.NbBundle.getMessage(ReportProgressPanel.class, "ReportProgressPanel.statusMessageLabel.text")); // NOI18N
|
||||
statusMessageLabel.setWrapStyleWord(true);
|
||||
statusMessageLabel.setBorder(null);
|
||||
statusMessageLabel.setMaximumSize(new java.awt.Dimension(2147483647, 80));
|
||||
statusMessageLabel.setMinimumSize(new java.awt.Dimension(101, 80));
|
||||
statusMessageLabel.setOpaque(false);
|
||||
statusMessageLabel.setPreferredSize(new java.awt.Dimension(2147483647, 80));
|
||||
|
||||
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
|
||||
this.setLayout(layout);
|
||||
@ -389,14 +411,14 @@ public class ReportProgressPanel extends javax.swing.JPanel {
|
||||
.addGroup(layout.createSequentialGroup()
|
||||
.addContainerGap()
|
||||
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addComponent(statusMessageLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
||||
.addComponent(statusMessageLabel, javax.swing.GroupLayout.DEFAULT_SIZE, 474, Short.MAX_VALUE)
|
||||
.addComponent(reportProgressBar, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
||||
.addGroup(layout.createSequentialGroup()
|
||||
.addComponent(reportLabel)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(separationLabel)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(pathLabel, javax.swing.GroupLayout.DEFAULT_SIZE, 548, Short.MAX_VALUE)))
|
||||
.addComponent(pathLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)))
|
||||
.addContainerGap())
|
||||
);
|
||||
layout.setVerticalGroup(
|
||||
@ -410,7 +432,7 @@ public class ReportProgressPanel extends javax.swing.JPanel {
|
||||
.addComponent(pathLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
||||
.addComponent(separationLabel))
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(statusMessageLabel)
|
||||
.addComponent(statusMessageLabel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||
.addGap(13, 13, 13))
|
||||
);
|
||||
}// </editor-fold>//GEN-END:initComponents
|
||||
@ -421,7 +443,7 @@ public class ReportProgressPanel extends javax.swing.JPanel {
|
||||
private javax.swing.JLabel reportLabel;
|
||||
private javax.swing.JProgressBar reportProgressBar;
|
||||
private javax.swing.JLabel separationLabel;
|
||||
private javax.swing.JLabel statusMessageLabel;
|
||||
private javax.swing.JTextArea statusMessageLabel;
|
||||
// End of variables declaration//GEN-END:variables
|
||||
|
||||
/**
|
||||
|
@ -9,6 +9,21 @@ PortableCaseTagsListPanel.error.noOpenCase=There is no case open
|
||||
ReportGenerator.artTableColHdr.comment=Comment
|
||||
ReportGenerator.errList.failedGetBBArtifactTags=Failed to get result tags.
|
||||
ReportGenerator.errList.noOpenCase=No open case available.
|
||||
# {0} - report module name
|
||||
ReportGenerator.error.exception=Exception while running report module {0}
|
||||
# {0} - report module name
|
||||
ReportGenerator.error.invalidSettings=Invalid settings for report module {0}
|
||||
# {0} - report module name
|
||||
ReportGenerator.error.moduleNotFound=Report module {0} not found
|
||||
# {0} - report module name
|
||||
ReportGenerator.error.noFileReportSettings=No file report settings for report module {0}
|
||||
ReportGenerator.error.noReportModules=No report modules found
|
||||
# {0} - report module name
|
||||
ReportGenerator.error.noTableReportSettings=No table report settings for report module {0}
|
||||
# {0} - report configuration name
|
||||
ReportGenerator.error.unableToLoadConfig=Unable to load reporting configuration {0}.
|
||||
# {0} - report module name
|
||||
ReportGenerator.error.unsupportedType=Report module {0} has unsupported report module type
|
||||
ReportGenerator.tagTable.header.userName=User Name
|
||||
ReportProgressIndicator.cancelledMessage=Report generation cancelled
|
||||
ReportProgressIndicator.completedMessage=Report generation completed
|
||||
|
@ -5,8 +5,8 @@ ReportHTML.getName.text=HTML Report
|
||||
ReportHTML.getDesc.text=A report about results and tagged items in HTML format.
|
||||
ReportHTML.writeIndex.title=for case {0}
|
||||
ReportHTML.writeIndex.noFrames.msg=Your browser is not compatible with our frame setup.
|
||||
ReportHTML.writeIndex.noFrames.seeNav=Please see <a href\="content\nav.html">the navigation page</a> for artifact links,
|
||||
ReportHTML.writeIndex.seeSum=and <a href\="content\summary.html">the summary page</a> for a case summary.
|
||||
ReportHTML.writeIndex.noFrames.seeNav=Please see <a href="content\nav.html">the navigation page</a> for artifact links,
|
||||
ReportHTML.writeIndex.seeSum=and <a href="contentsummary.html">the summary page</a> for a case summary.
|
||||
ReportHTML.writeNav.title=Report Navigation
|
||||
ReportHTML.writeNav.h1=Report Navigation
|
||||
ReportHTML.writeNav.summary=Case Summary
|
||||
@ -16,7 +16,7 @@ ReportHTML.writeSum.caseNumber=Case Number:
|
||||
ReportHTML.writeSum.caseNumImages=Number of data sources in case:
|
||||
ReportHTML.writeSum.examiner=Examiner:
|
||||
ReportHTML.writeSum.title=Case Summary
|
||||
ReportHTML.writeSum.warningMsg=<span>Warning, this report was run before ingest services completed\!</span>
|
||||
ReportHTML.writeSum.warningMsg=<span>Warning, this report was run before ingest services completed!</span>
|
||||
#
|
||||
# autopsy/test/scripts/regression.py._html_report_diff() uses reportGenOn.text, caseName, caseNum,
|
||||
# examiner as a regex signature to skip report.html and summary.html
|
||||
|
@ -1378,7 +1378,7 @@ public class PortableCaseReportModule implements ReportModule {
|
||||
}
|
||||
|
||||
try {
|
||||
OsAccountRealm newRealm = newRealmManager.newWindowsRealm(oldRealm.getRealmAddr().orElse(null), realmName, newHost, oldRealm.getScope());
|
||||
OsAccountRealm newRealm = newRealmManager.newWindowsRealm(oldOsAccount.getAddr().orElse(null), realmName, newHost, oldRealm.getScope());
|
||||
oldRealmIdToNewRealm.put(oldOsAccount.getRealmId(), newRealm);
|
||||
} catch (NotUserSIDException ex) {
|
||||
throw new TskCoreException("Failed to copy OsAccountRealm with ID=" + oldOsAccount.getRealmId(), ex);
|
||||
|
@ -1,18 +1,18 @@
|
||||
body {margin: 0px; padding: 0px; background: #FFFFFF; font: 13px/20px Arial, Helvetica, sans-serif; color: #535353;}
|
||||
#snapshot{max-width:800; max-height:600}
|
||||
#content {padding: 30px;}
|
||||
#header {width:100%; padding: 10px; line-height: 25px; background: #07A; color: #FFF; font-size: 20px;}
|
||||
h1 {font-size: 20px; font-weight: normal; color: #07A; padding: 0 0 7px 0; margin-top: 25px; border-bottom: 1px solid #D6D6D6;}
|
||||
h2 {font-size: 20px; font-weight: bolder; color: #07A;}
|
||||
h3 {font-size: 16px; color: #07A;}
|
||||
h4 {background: #07A; color: #FFF; font-size: 16px; margin: 0 0 0 25px; padding: 0; padding-left: 15px;}
|
||||
#header {width:100%; padding: 10px; line-height: 25px; background: #0077AA; color: #FFFFFF; font-size: 20px;}
|
||||
h1 {font-size: 20px; font-weight: normal; color: #0077AA; padding: 0 0 7px 0; margin-top: 25px; border-bottom: 1px solid #D6D6D6;}
|
||||
h2 {font-size: 20px; font-weight: bolder; color: #0077AA;}
|
||||
h3 {font-size: 16px; color: #0077AA;}
|
||||
h4 {background: #0077AA; color: #FFFFFF; font-size: 16px; margin: 0 0 0 25px; padding: 0; padding-left: 15px;}
|
||||
ul.nav {list-style-type: none; line-height: 35px; padding: 0px; margin-left: 15px;}
|
||||
ul li a {font-size: 14px; color: #444; text-decoration: none; padding-left: 25px;}
|
||||
ul li a {font-size: 14px; color: #444444; text-decoration: none; padding-left: 25px;}
|
||||
ul li a:hover {text-decoration: underline;}
|
||||
p {margin: 0 0 20px 0;}
|
||||
table {white-space:nowrap; min-width: 800px; padding: 2; margin: 0; border-collapse: collapse; border-bottom: 2px solid #e5e5e5;}
|
||||
.keyword_list table {margin: 0 0 25px 25px; border-bottom: 2px solid #dedede;}
|
||||
table th {white-space:nowrap; display: table-cell; text-align: center; padding: 2px 4px; background: #e5e5e5; color: #777; font-size: 11px; text-shadow: #e9f9fd 0 1px 0; border-top: 1px solid #dedede; border-bottom: 2px solid #e5e5e5;}
|
||||
table th {white-space:nowrap; display: table-cell; text-align: center; padding: 2px 4px; background: #e5e5e5; color: #777777; font-size: 11px; text-shadow: #e9f9fd 0 1px 0; border-top: 1px solid #dedede; border-bottom: 2px solid #e5e5e5;}
|
||||
table .left_align_cell{display: table-cell; padding: 2px 4px; font: 13px/20px Arial, Helvetica, sans-serif; min-width: 125px; overflow: auto; text-align: left; }
|
||||
table .right_align_cell{display: table-cell; padding: 2px 4px; font: 13px/20px Arial, Helvetica, sans-serif; min-width: 125px; overflow: auto; text-align: right; }
|
||||
table td {white-space:nowrap; display: table-cell; padding: 2px 3px; font: 13px/20px Arial, Helvetica, sans-serif; min-width: 125px; overflow: auto; text-align:left; }
|
||||
|
@ -1,8 +1,8 @@
|
||||
body { padding: 0px; margin: 0px; font: 13px/20px Arial, Helvetica, sans-serif; color: #535353; }
|
||||
body { padding: 0px; margin: 0px; font: 13px Arial, Helvetica, sans-serif; color: #535353; }
|
||||
#wrapper { width: 90%; margin: 0px auto; margin-top: 35px; }
|
||||
h1 { color: #07A; font-size: 36px; line-height: 42px; font-weight: normal; margin: 0px; border-bottom: 1px solid #81B9DB; }
|
||||
h1 span { color: #F00; display: block; font-size: 16px; font-weight: bold; line-height: 22px;}
|
||||
h2 { padding: 0 0 3px 0; margin: 0px; color: #07A; font-weight: normal; border-bottom: 1px dotted #81B9DB; }
|
||||
h1 { color: #0077AA; font-size: 36px; line-height: 42px; font-weight: normal; margin: 0px; border-bottom: 1px solid #81B9DB; }
|
||||
h1 span { color: #FF0000; display: block; font-size: 16px; font-weight: bold; line-height: 22px;}
|
||||
h2 { padding: 0 0 3px 0; margin: 0px; color: #0077AA; font-weight: normal; border-bottom: 1px dotted #81B9DB; }
|
||||
table td { padding-right: 25px; }
|
||||
p.subheadding { padding: 0px; margin: 0px; font-size: 11px; color: #B5B5B5; }
|
||||
.title { width: 660px; margin-bottom: 50px; }
|
||||
@ -10,5 +10,5 @@ p.subheadding { padding: 0px; margin: 0px; font-size: 11px; color: #B5B5B5; }
|
||||
.left img { max-width: 250px; max-height: 250px; min-width: 200px; min-height: 200px; }
|
||||
.right { float: right; width: 385px; margin-top: 25px; font-size: 14px; }
|
||||
.clear { clear: both; }
|
||||
.info p { padding: 3px 10px; background: #e5e5e5; color: #777; font-size: 12px; font-weight: bold; text-shadow: #e9f9fd 0 1px 0; border-top: 1px solid #dedede; border-bottom: 2px solid #dedede; }
|
||||
.info p { padding: 3px 10px; background: #e5e5e5; color: #777777; font-size: 12px; font-weight: bold; text-shadow: #e9f9fd 0 1px 0; border-top: 1px solid #dedede; border-bottom: 2px solid #dedede; }
|
||||
.info table { margin: 0 25px 20px 25px; }
|
||||
|
@ -20,7 +20,8 @@ package org.sleuthkit.autopsy.test;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import javax.xml.bind.DatatypeConverter;
|
||||
import org.apache.commons.codec.DecoderException;
|
||||
import org.apache.commons.codec.binary.Hex;
|
||||
import org.joda.time.DateTime;
|
||||
import org.sleuthkit.autopsy.casemodule.Case;
|
||||
import org.sleuthkit.datamodel.Blackboard;
|
||||
@ -95,13 +96,13 @@ final class CustomArtifactType {
|
||||
* @throws Blackboard.BlackboardException If there is an error posting the
|
||||
* artifact to the blackboard.
|
||||
*/
|
||||
static BlackboardArtifact createAndPostInstance(Content source, long ingestJobId) throws TskCoreException, Blackboard.BlackboardException {
|
||||
static BlackboardArtifact createAndPostInstance(Content source, long ingestJobId) throws TskCoreException, Blackboard.BlackboardException, DecoderException {
|
||||
List<BlackboardAttribute> attributes = new ArrayList<>();
|
||||
attributes.add(new BlackboardAttribute(intAttrType, MODULE_NAME, 0));
|
||||
attributes.add(new BlackboardAttribute(doubleAttrType, MODULE_NAME, 0.0));
|
||||
attributes.add(new BlackboardAttribute(longAttributeType, MODULE_NAME, 0L));
|
||||
attributes.add(new BlackboardAttribute(dateTimeAttrType, MODULE_NAME, DateTime.now().getMillis()/1000));
|
||||
attributes.add(new BlackboardAttribute(bytesAttrType, MODULE_NAME, DatatypeConverter.parseHexBinary("ABCD")));
|
||||
attributes.add(new BlackboardAttribute(dateTimeAttrType, MODULE_NAME, 60L));
|
||||
attributes.add(new BlackboardAttribute(bytesAttrType, MODULE_NAME, Hex.decodeHex("ABCD")));
|
||||
attributes.add(new BlackboardAttribute(stringAttrType, MODULE_NAME, "Zero"));
|
||||
attributes.add(new BlackboardAttribute(jsonAttrType, MODULE_NAME, "{\"fruit\": \"Apple\",\"size\": \"Large\",\"color\": \"Red\"}"));
|
||||
|
||||
|
@ -19,6 +19,7 @@
|
||||
package org.sleuthkit.autopsy.test;
|
||||
|
||||
import java.util.logging.Level;
|
||||
import org.apache.commons.codec.DecoderException;
|
||||
import org.openide.util.NbBundle;
|
||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||
import org.sleuthkit.autopsy.ingest.DataSourceIngestModuleAdapter;
|
||||
@ -73,7 +74,7 @@ public class CustomArtifactsCreatorDataSourceIngestModule extends DataSourceInge
|
||||
public ProcessResult process(Content dataSource, DataSourceIngestModuleProgress progressBar) {
|
||||
try {
|
||||
CustomArtifactType.createAndPostInstance(dataSource, context.getJobId());
|
||||
} catch (TskCoreException | Blackboard.BlackboardException ex) {
|
||||
} catch (TskCoreException | Blackboard.BlackboardException | DecoderException ex) {
|
||||
logger.log(Level.SEVERE, String.format("Failed to process data source (obj_id = %d)", dataSource.getId()), ex);
|
||||
return ProcessResult.ERROR;
|
||||
}
|
||||
|
@ -19,6 +19,7 @@
|
||||
package org.sleuthkit.autopsy.test;
|
||||
|
||||
import java.util.logging.Level;
|
||||
import org.apache.commons.codec.DecoderException;
|
||||
import org.openide.util.NbBundle;
|
||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||
import org.sleuthkit.autopsy.ingest.FileIngestModuleAdapter;
|
||||
@ -74,7 +75,7 @@ final class CustomArtifactsCreatorFileIngestModule extends FileIngestModuleAdapt
|
||||
}
|
||||
try {
|
||||
CustomArtifactType.createAndPostInstance(file, context.getJobId());
|
||||
} catch (TskCoreException | Blackboard.BlackboardException ex) {
|
||||
} catch (TskCoreException | Blackboard.BlackboardException | DecoderException ex) {
|
||||
logger.log(Level.SEVERE, String.format("Failed to process file (obj_id = %d)", file.getId()), ex);
|
||||
return ProcessResult.ERROR;
|
||||
}
|
||||
|
@ -25,10 +25,11 @@ import javafx.scene.control.TableCell;
|
||||
import javafx.scene.control.TableColumn;
|
||||
import javafx.scene.control.TreeTableCell;
|
||||
import javafx.scene.control.TreeTableColumn;
|
||||
import javafx.scene.control.TreeTableView;
|
||||
|
||||
/**
|
||||
* An abstract base class for Cell factories. This class provides the basic
|
||||
* infrustructure for implementations to be able to create similar cells for
|
||||
* infrastructure for implementations to be able to create similar cells for
|
||||
* ListView, TableViews or TreeTableViews via the appropriate method call.
|
||||
* Implementations need only implement the abstract configureCell method in the
|
||||
* same spirit as IndexedCell.updateItem
|
||||
@ -64,6 +65,12 @@ public abstract class AbstractFXCellFactory<X, Y> {
|
||||
@Override
|
||||
protected void updateItem(Y item, boolean empty) {
|
||||
super.updateItem(item, empty);
|
||||
// Due to a JavaFX issue in Java 10+,
|
||||
// https://bugs.java.com/bugdatabase/view_bug.do?bug_id=8231644
|
||||
// the arrows to expand the tree were removed (FilterTable.css)
|
||||
// and the following code was added to indent the subnodes.
|
||||
TreeTableView<X> treeTableView = this.treeTableViewProperty().get();
|
||||
this.setTranslateX(treeTableView.getTreeItemLevel(treeTableView.getTreeItem(getIndex())) << 4);
|
||||
configureCell(this, item, empty, (() -> this.getTreeTableRow().getItem()));
|
||||
}
|
||||
}
|
||||
|
@ -662,6 +662,7 @@ final public class ViewFrame extends BorderPane {
|
||||
: defaultTimeNavigationNodes);
|
||||
|
||||
//do further setup of new view.
|
||||
ActionUtils.unconfigureButton(refreshButton);
|
||||
ActionUtils.configureButton(new Refresh(), refreshButton);//configure new refresh action for new view
|
||||
hostedView.refresh();
|
||||
notificationPane.setContent(hostedView);
|
||||
|
@ -1,6 +1,6 @@
|
||||
.guide-line{
|
||||
-fx-opacity: .5;
|
||||
-fx-stroke: red;
|
||||
-fx-stroke: #FF0000;
|
||||
-fx-stroke-dash-array: 5 5;
|
||||
-fx-stroke-width: 3;
|
||||
-fx-cursor: h-resize;
|
||||
|
@ -24,6 +24,7 @@ import javafx.beans.InvalidationListener;
|
||||
import javafx.beans.binding.Bindings;
|
||||
import javafx.collections.FXCollections;
|
||||
import javafx.collections.ObservableMap;
|
||||
import javafx.event.EventHandler;
|
||||
import javafx.fxml.FXML;
|
||||
import javafx.scene.control.Button;
|
||||
import javafx.scene.control.Cell;
|
||||
@ -35,6 +36,7 @@ import javafx.scene.control.TreeTableColumn;
|
||||
import javafx.scene.control.TreeTableView;
|
||||
import javafx.scene.image.Image;
|
||||
import javafx.scene.image.ImageView;
|
||||
import javafx.scene.input.KeyEvent;
|
||||
import javafx.scene.layout.BorderPane;
|
||||
import org.controlsfx.control.action.Action;
|
||||
import org.controlsfx.control.action.ActionUtils;
|
||||
@ -117,6 +119,8 @@ final public class FilterSetPanel extends BorderPane {
|
||||
//type is the only filter expanded initialy
|
||||
expansionMap.put(filteredEvents.getEventFilterState().getFilter(), true);
|
||||
expansionMap.put(filteredEvents.getEventFilterState().getEventTypeFilterState().getFilter(), true);
|
||||
expansionMap.put(filteredEvents.getEventFilterState().getDataSourcesFilterState().getFilter(), true);
|
||||
expansionMap.put(filteredEvents.getEventFilterState().getFileTypesFilterState().getFilter(), true);
|
||||
|
||||
InvalidationListener applyFiltersListener = observable -> applyFilters();
|
||||
|
||||
@ -128,7 +132,7 @@ final public class FilterSetPanel extends BorderPane {
|
||||
refreshFilterUI();
|
||||
|
||||
hiddenDescriptionsListView.setItems(controller.getQuickHideFilters());
|
||||
hiddenDescriptionsListView.setCellFactory(listView -> getNewDiscriptionFilterListCell());
|
||||
hiddenDescriptionsListView.setCellFactory(listView -> getNewDescriptionFilterListCell());
|
||||
|
||||
//show and hide the "hidden descriptions" panel depending on the current view mode
|
||||
controller.viewModeProperty().addListener(observable -> {
|
||||
@ -154,6 +158,14 @@ final public class FilterSetPanel extends BorderPane {
|
||||
throw new UnsupportedOperationException("Unknown ViewMode: " + controller.getViewMode());
|
||||
}
|
||||
});
|
||||
|
||||
//Block the default treetable keyboard events.
|
||||
filterTreeTable.addEventFilter(KeyEvent.ANY, new EventHandler<KeyEvent>() {
|
||||
@Override
|
||||
public void handle(KeyEvent event) {
|
||||
event.consume();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public FilterSetPanel(TimeLineController controller) {
|
||||
@ -173,7 +185,7 @@ final public class FilterSetPanel extends BorderPane {
|
||||
});
|
||||
}
|
||||
|
||||
private ListCell<DescriptionFilterState> getNewDiscriptionFilterListCell() {
|
||||
private ListCell<DescriptionFilterState> getNewDescriptionFilterListCell() {
|
||||
final ListCell<DescriptionFilterState> cell = new FilterCheckBoxCellFactory< DescriptionFilterState>().forList();
|
||||
cell.itemProperty().addListener(itemProperty -> {
|
||||
if (cell.getItem() == null) {
|
||||
|
@ -1,3 +1,16 @@
|
||||
|
||||
|
||||
.column-header-background { visibility: hidden; -fx-padding: -1em; }
|
||||
.tree-disclosure-node {
|
||||
-fx-padding: 0px;
|
||||
-fx-background-color: transparent;
|
||||
}
|
||||
|
||||
.tree-disclosure-node .arrow {
|
||||
-fx-background-color: -fx-mark-color;
|
||||
-fx-padding: 0.0em;
|
||||
}
|
||||
|
||||
.tree-table-row-cell {
|
||||
-fx-table-cell-border-color: transparent;
|
||||
}
|
||||
|
@ -44,8 +44,8 @@ class FilterTreeItem extends TreeItem<FilterState<?>> {
|
||||
super(filterState);
|
||||
|
||||
//keep expanion map upto date if user expands/collapses filter
|
||||
expandedProperty().addListener(expandedProperty -> expansionMap.put(filterState.getFilter(), isExpanded()));
|
||||
setExpanded(expansionMap.getOrDefault(filterState.getFilter(), false));
|
||||
expandedProperty().addListener(expandedProperty -> expansionMap.put(filterState.getFilter(), true));
|
||||
setExpanded(true);
|
||||
|
||||
//if the filter is a compound filter, add its subfilters to the tree
|
||||
if (filterState instanceof CompoundFilterState<?, ?>) {
|
||||
|
@ -14,7 +14,7 @@ import javafx.collections.ObservableList;
|
||||
import javafx.collections.transformation.TransformationList;
|
||||
|
||||
/**
|
||||
*
|
||||
* Maps an observable list of type E to an observable list of type F.
|
||||
*/
|
||||
public class MappedList<E, F> extends TransformationList<E, F> {
|
||||
private final Function<F, E> mapper;
|
||||
@ -112,4 +112,9 @@ public class MappedList<E, F> extends TransformationList<E, F> {
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getViewIndex(int index) {
|
||||
return index;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,13 +1,7 @@
|
||||
<project name="NativeCoreLibs">
|
||||
|
||||
<target name="build-native-libs" description="build native library dependencies">
|
||||
<!-- sigar: note, matching jar is pulled with ivy -->
|
||||
<mkdir dir="${lib.dir}"/>
|
||||
<unzip src="${thirdparty.dir}/sigar/1.6.4/sigar-native.zip" dest="${lib.dir}" >
|
||||
<!-- get all, rely on jna to locate <patternset>
|
||||
<include name="**/*.dylib"/>
|
||||
</patternset> -->
|
||||
</unzip>
|
||||
</target>
|
||||
|
||||
</project>
|
||||
|
@ -1,13 +1,7 @@
|
||||
<project name="NativeCoreLibs">
|
||||
|
||||
<target name="build-native-libs" description="build native library dependencies">
|
||||
<!-- sigar: note, matching jar is pulled with ivy -->
|
||||
<mkdir dir="${lib.dir}"/>
|
||||
<unzip src="${thirdparty.dir}/sigar/1.6.4/sigar-native.zip" dest="${lib.dir}" >
|
||||
<!-- get all, rely on jna to locate <patternset>
|
||||
<include name="**/*.so"/>
|
||||
</patternset> -->
|
||||
</unzip>
|
||||
</target>
|
||||
|
||||
</project>
|
||||
|
@ -1,13 +1,7 @@
|
||||
<project name="NativeCoreLibs">
|
||||
|
||||
<target name="build-native-libs" description="build native library dependencies">
|
||||
<!-- sigar: note, matching jar is pulled with ivy -->
|
||||
<mkdir dir="${lib.dir}"/>
|
||||
<unzip src="${thirdparty.dir}/sigar/1.6.4/sigar-native.zip" dest="${lib.dir}" >
|
||||
<!-- get all, rely on jna to locate <patternset>
|
||||
<include name="**/*.dll"/>
|
||||
</patternset> -->
|
||||
</unzip>
|
||||
</target>
|
||||
|
||||
</project>
|
||||
|
@ -14,7 +14,7 @@
|
||||
|
||||
<!-- for viewers -->
|
||||
<dependency conf="autopsy_core->default" org="org.freedesktop.gstreamer" name="gst1-java-core" rev="1.4.0"/>
|
||||
<dependency conf="autopsy_core->default" org="net.java.dev.jna" name="jna-platform" rev="5.12.0"/>
|
||||
<dependency conf="autopsy_core->default" org="net.java.dev.jna" name="jna-platform" rev="5.13.0"/>
|
||||
|
||||
<!-- for file search -->
|
||||
<dependency conf="autopsy_core->default" org="com.github.lgooddatepicker" name="LGoodDatePicker" rev="11.2.1"/>
|
||||
@ -41,24 +41,25 @@
|
||||
<dependency conf="autopsy_core->default" org="net.htmlparser.jericho" name="jericho-html" rev="3.4"/>
|
||||
|
||||
<dependency conf="autopsy_core->default" org="com.fasterxml.jackson.dataformat" name="jackson-dataformat-csv" rev="2.13.2"/>
|
||||
|
||||
<!-- process and system monitoring, note: matching native libs pulled from thirdparty -->
|
||||
<dependency conf="autopsy_core->default" org="org.fusesource" name="sigar" rev="1.6.4" />
|
||||
|
||||
<!-- better image resizing -->
|
||||
<dependency conf="autopsy_core->default" org="org.imgscalr" name="imgscalr-lib" rev="4.2" />
|
||||
|
||||
<!-- timeline and image analyzer -->
|
||||
<!-- ControlsFX after version 9.0.0 has a bug that causes the Image Gallery GridView
|
||||
to constantly reload images (JIRA-6724). Do not upgrade ControlsFX unless you can
|
||||
confirm that the following issue is fixed.
|
||||
|
||||
https://github.com/controlsfx/controlsfx/issues/1241
|
||||
-->
|
||||
<dependency conf="autopsy_core->*" org="org.controlsfx" name="controlsfx" rev="11.1.2" />
|
||||
|
||||
<dependency conf="autopsy_core->default" org="joda-time" name="joda-time" rev="2.10.14" />
|
||||
|
||||
|
||||
<!-- timeline -->
|
||||
<!-- NOTE: the version of these dependencies appears to be tied to javafx / java version -->
|
||||
<dependency conf="autopsy_core->default" org="org.controlsfx" name="controlsfx" rev="8.40.11" />
|
||||
<dependency conf="autopsy_core->default" org="org.jfxtras" name="jfxtras-fxml" rev="8.0-r4" />
|
||||
<dependency conf="autopsy_core->default" org="org.jfxtras" name="jfxtras-controls" rev="8.0-r4" />
|
||||
<dependency conf="autopsy_core->default" org="org.jfxtras" name="jfxtras-common" rev="8.0-r4" />
|
||||
|
||||
|
||||
<dependency conf="autopsy_core->default" org="org.jfxtras" name="jfxtras-fxml" rev="17-r1" />
|
||||
<dependency conf="autopsy_core->default" org="org.jfxtras" name="jfxtras-controls" rev="17-r1" />
|
||||
<dependency conf="autopsy_core->default" org="org.jfxtras" name="jfxtras-common" rev="17-r1" />
|
||||
<!-- templateing engine used by timeline to generate its snapshot report -->
|
||||
<dependency conf="autopsy_core->default" org="com.github.spullara.mustache.java" name="compiler" rev="0.9.10" />
|
||||
|
||||
|
@ -26,7 +26,7 @@ file.reference.commons-text-1.9.jar=release/modules/ext/commons-text-1.9.jar
|
||||
file.reference.commons-validator-1.7.jar=release/modules/ext/commons-validator-1.7.jar
|
||||
file.reference.compiler-0.9.10.jar=release/modules/ext/compiler-0.9.10.jar
|
||||
file.reference.conscrypt-openjdk-uber-2.5.1.jar=release/modules/ext/conscrypt-openjdk-uber-2.5.1.jar
|
||||
file.reference.controlsfx-8.40.11.jar=release/modules/ext/controlsfx-8.40.11.jar
|
||||
file.reference.controlsfx-11.1.2.jar=release/modules/ext/controlsfx-11.1.2.jar
|
||||
file.reference.dd-plist-1.23.jar=release/modules/ext/dd-plist-1.23.jar
|
||||
file.reference.error_prone_annotations-2.11.0.jar=release/modules/ext/error_prone_annotations-2.11.0.jar
|
||||
file.reference.failureaccess-1.0.1.jar=release/modules/ext/failureaccess-1.0.1.jar
|
||||
@ -85,18 +85,17 @@ file.reference.jackson-databind-2.13.2.jar=release/modules/ext/jackson-databind-
|
||||
file.reference.jackson-dataformat-csv-2.13.2.jar=release/modules/ext/jackson-dataformat-csv-2.13.2.jar
|
||||
file.reference.javax.annotation-api-1.3.2.jar=release/modules/ext/javax.annotation-api-1.3.2.jar
|
||||
file.reference.jericho-html-3.4.jar=release/modules/ext/jericho-html-3.4.jar
|
||||
file.reference.jfxtras-common-8.0-r4.jar=release/modules/ext/jfxtras-common-8.0-r4.jar
|
||||
file.reference.jfxtras-controls-8.0-r4.jar=release/modules/ext/jfxtras-controls-8.0-r4.jar
|
||||
file.reference.jfxtras-fxml-8.0-r4.jar=release/modules/ext/jfxtras-fxml-8.0-r4.jar
|
||||
file.reference.jna-5.12.1.jar=release/modules/ext/jna-5.12.1.jar
|
||||
file.reference.jna-platform-5.12.0.jar=release/modules/ext/jna-platform-5.12.0.jar
|
||||
file.reference.jfxtras-common-17-r1.jar=release/modules/ext/jfxtras-common-17-r1.jar
|
||||
file.reference.jfxtras-controls-17-r1.jar=release/modules/ext/jfxtras-controls-17-r1.jar
|
||||
file.reference.jfxtras-fxml-17-r1.jar=release/modules/ext/jfxtras-fxml-17-r1.jar
|
||||
file.reference.jna-5.13.0.jar=release/modules/ext/jna-5.13.0.jar
|
||||
file.reference.jna-platform-5.13.0.jar=release/modules/ext/jna-platform-5.13.0.jar
|
||||
file.reference.joda-time-2.10.14.jar=release/modules/ext/joda-time-2.10.14.jar
|
||||
file.reference.jsr305-3.0.2.jar=release/modules/ext/jsr305-3.0.2.jar
|
||||
file.reference.LGoodDatePicker-11.2.1.jar=release/modules/ext/LGoodDatePicker-11.2.1.jar
|
||||
file.reference.listenablefuture-9999.0-empty-to-avoid-conflict-with-guava.jar=release/modules/ext/listenablefuture-9999.0-empty-to-avoid-conflict-with-guava.jar
|
||||
file.reference.log4j-api-2.17.2.jar=release/modules/ext/log4j-api-2.17.2.jar
|
||||
file.reference.log4j-core-2.17.2.jar=release/modules/ext/log4j-core-2.17.2.jar
|
||||
file.reference.ooxml-schemas-1.4.jar=release/modules/ext/ooxml-schemas-1.4.jar
|
||||
file.reference.opencensus-api-0.31.0.jar=release/modules/ext/opencensus-api-0.31.0.jar
|
||||
file.reference.opencensus-contrib-http-util-0.31.0.jar=release/modules/ext/opencensus-contrib-http-util-0.31.0.jar
|
||||
file.reference.opencensus-proto-0.2.0.jar=release/modules/ext/opencensus-proto-0.2.0.jar
|
||||
@ -110,12 +109,10 @@ file.reference.protobuf-java-3.19.4.jar=release/modules/ext/protobuf-java-3.19.4
|
||||
file.reference.protobuf-java-util-3.19.4.jar=release/modules/ext/protobuf-java-util-3.19.4.jar
|
||||
file.reference.re2j-1.5.jar=release/modules/ext/re2j-1.5.jar
|
||||
file.reference.reload4j-1.2.19.jar=release/modules/ext/reload4j-1.2.19.jar
|
||||
file.reference.sigar-1.6.4.jar=release/modules/ext/sigar-1.6.4.jar
|
||||
file.reference.slf4j-api-1.7.36.jar=release/modules/ext/slf4j-api-1.7.36.jar
|
||||
file.reference.slf4j-reload4j-1.7.36.jar=release/modules/ext/slf4j-reload4j-1.7.36.jar
|
||||
file.reference.threetenbp-1.5.2.jar=release/modules/ext/threetenbp-1.5.2.jar
|
||||
file.reference.webp-imageio-sejda-0.1.0.jar=release/modules/ext/webp-imageio-sejda-0.1.0.jar
|
||||
javac.source=1.8
|
||||
javac.source=17
|
||||
javac.compilerargs=-Xlint -Xlint:-serial
|
||||
nbm.needs.restart=true
|
||||
|
||||
|
@ -11,7 +11,7 @@
|
||||
<build-prerequisite/>
|
||||
<compile-dependency/>
|
||||
<run-dependency>
|
||||
<specification-version>8.25.1</specification-version>
|
||||
<specification-version>9.25</specification-version>
|
||||
</run-dependency>
|
||||
</dependency>
|
||||
<dependency>
|
||||
@ -19,7 +19,7 @@
|
||||
<build-prerequisite/>
|
||||
<compile-dependency/>
|
||||
<run-dependency>
|
||||
<specification-version>9.4.1</specification-version>
|
||||
<specification-version>9.25</specification-version>
|
||||
</run-dependency>
|
||||
</dependency>
|
||||
</module-dependencies>
|
||||
@ -246,6 +246,19 @@
|
||||
<package>javax.annotation</package>
|
||||
<package>javax.annotation.concurrent</package>
|
||||
<package>javax.annotation.meta</package>
|
||||
<package>javax.jms</package>
|
||||
<package>javax.mail</package>
|
||||
<package>javax.mail.event</package>
|
||||
<package>javax.mail.internet</package>
|
||||
<package>javax.mail.search</package>
|
||||
<package>javax.mail.util</package>
|
||||
<package>javax.servlet</package>
|
||||
<package>javax.servlet.http</package>
|
||||
<package>javax.xml.parsers</package>
|
||||
<package>javax.xml.transform</package>
|
||||
<package>javax.xml.transform.dom</package>
|
||||
<package>javax.xml.transform.sax</package>
|
||||
<package>javax.xml.transform.stream</package>
|
||||
<package>jfxtras.animation</package>
|
||||
<package>jfxtras.css</package>
|
||||
<package>jfxtras.css.converters</package>
|
||||
@ -313,6 +326,16 @@
|
||||
<package>org.apache.commons.lang3.tuple</package>
|
||||
<package>org.apache.commons.logging</package>
|
||||
<package>org.apache.commons.logging.impl</package>
|
||||
<package>org.apache.log</package>
|
||||
<package>org.apache.log.filter</package>
|
||||
<package>org.apache.log.format</package>
|
||||
<package>org.apache.log.output</package>
|
||||
<package>org.apache.log.output.db</package>
|
||||
<package>org.apache.log.output.io</package>
|
||||
<package>org.apache.log.output.io.rotate</package>
|
||||
<package>org.apache.log.output.jms</package>
|
||||
<package>org.apache.log.output.net</package>
|
||||
<package>org.apache.log.util</package>
|
||||
<package>org.apache.commons.text</package>
|
||||
<package>org.apache.commons.validator.routines</package>
|
||||
<package>org.apache.commons.validator.routines.checkdigit</package>
|
||||
@ -401,7 +424,6 @@
|
||||
<package>org.controlsfx.control.action</package>
|
||||
<package>org.controlsfx.control.cell</package>
|
||||
<package>org.controlsfx.control.decoration</package>
|
||||
<package>org.controlsfx.control.spreadsheet</package>
|
||||
<package>org.controlsfx.control.table</package>
|
||||
<package>org.controlsfx.control.table.model</package>
|
||||
<package>org.controlsfx.control.textfield</package>
|
||||
@ -423,17 +445,6 @@
|
||||
<package>org.freedesktop.gstreamer.message</package>
|
||||
<package>org.freedesktop.gstreamer.query</package>
|
||||
<package>org.freedesktop.gstreamer.webrtc</package>
|
||||
<package>org.hyperic.jni</package>
|
||||
<package>org.hyperic.sigar</package>
|
||||
<package>org.hyperic.sigar.cmd</package>
|
||||
<package>org.hyperic.sigar.jmx</package>
|
||||
<package>org.hyperic.sigar.pager</package>
|
||||
<package>org.hyperic.sigar.ptql</package>
|
||||
<package>org.hyperic.sigar.shell</package>
|
||||
<package>org.hyperic.sigar.test</package>
|
||||
<package>org.hyperic.sigar.util</package>
|
||||
<package>org.hyperic.sigar.vmware</package>
|
||||
<package>org.hyperic.sigar.win32</package>
|
||||
<package>org.imgscalr</package>
|
||||
<package>org.joda.time</package>
|
||||
<package>org.joda.time.base</package>
|
||||
@ -460,7 +471,7 @@
|
||||
<package>org.slf4j.helpers</package>
|
||||
<package>org.slf4j.spi</package>
|
||||
</public-packages>
|
||||
<class-path-extension>
|
||||
<class-path-extension>
|
||||
<runtime-relative-path>ext/animal-sniffer-annotations-1.21.jar</runtime-relative-path>
|
||||
<binary-origin>release/modules/ext/animal-sniffer-annotations-1.21.jar</binary-origin>
|
||||
</class-path-extension>
|
||||
@ -573,8 +584,8 @@
|
||||
<binary-origin>release/modules/ext/conscrypt-openjdk-uber-2.5.1.jar</binary-origin>
|
||||
</class-path-extension>
|
||||
<class-path-extension>
|
||||
<runtime-relative-path>ext/controlsfx-8.40.11.jar</runtime-relative-path>
|
||||
<binary-origin>release/modules/ext/controlsfx-8.40.11.jar</binary-origin>
|
||||
<runtime-relative-path>ext/controlsfx-11.1.2.jar</runtime-relative-path>
|
||||
<binary-origin>release/modules/ext/controlsfx-11.1.2.jar</binary-origin>
|
||||
</class-path-extension>
|
||||
<class-path-extension>
|
||||
<runtime-relative-path>ext/dd-plist-1.23.jar</runtime-relative-path>
|
||||
@ -809,24 +820,24 @@
|
||||
<binary-origin>release/modules/ext/jericho-html-3.4.jar</binary-origin>
|
||||
</class-path-extension>
|
||||
<class-path-extension>
|
||||
<runtime-relative-path>ext/jfxtras-common-8.0-r4.jar</runtime-relative-path>
|
||||
<binary-origin>release/modules/ext/jfxtras-common-8.0-r4.jar</binary-origin>
|
||||
<runtime-relative-path>ext/jfxtras-common-17-r1.jar</runtime-relative-path>
|
||||
<binary-origin>release/modules/ext/jfxtras-common-17-r1.jar</binary-origin>
|
||||
</class-path-extension>
|
||||
<class-path-extension>
|
||||
<runtime-relative-path>ext/jfxtras-controls-8.0-r4.jar</runtime-relative-path>
|
||||
<binary-origin>release/modules/ext/jfxtras-controls-8.0-r4.jar</binary-origin>
|
||||
<runtime-relative-path>ext/jfxtras-controls-17-r1.jar</runtime-relative-path>
|
||||
<binary-origin>release/modules/ext/jfxtras-controls-17-r1.jar</binary-origin>
|
||||
</class-path-extension>
|
||||
<class-path-extension>
|
||||
<runtime-relative-path>ext/jfxtras-fxml-8.0-r4.jar</runtime-relative-path>
|
||||
<binary-origin>release/modules/ext/jfxtras-fxml-8.0-r4.jar</binary-origin>
|
||||
<runtime-relative-path>ext/jfxtras-fxml-17-r1.jar</runtime-relative-path>
|
||||
<binary-origin>release/modules/ext/jfxtras-fxml-17-r1.jar</binary-origin>
|
||||
</class-path-extension>
|
||||
<class-path-extension>
|
||||
<runtime-relative-path>ext/jna-5.12.1.jar</runtime-relative-path>
|
||||
<binary-origin>release/modules/ext/jna-5.12.1.jar</binary-origin>
|
||||
<runtime-relative-path>ext/jna-5.13.0.jar</runtime-relative-path>
|
||||
<binary-origin>release/modules/ext/jna-5.13.0.jar</binary-origin>
|
||||
</class-path-extension>
|
||||
<class-path-extension>
|
||||
<runtime-relative-path>ext/jna-platform-5.12.0.jar</runtime-relative-path>
|
||||
<binary-origin>release/modules/ext/jna-platform-5.12.0.jar</binary-origin>
|
||||
<runtime-relative-path>ext/jna-platform-5.13.0.jar</runtime-relative-path>
|
||||
<binary-origin>release/modules/ext/jna-platform-5.13.0.jar</binary-origin>
|
||||
</class-path-extension>
|
||||
<class-path-extension>
|
||||
<runtime-relative-path>ext/joda-time-2.10.14.jar</runtime-relative-path>
|
||||
@ -852,10 +863,6 @@
|
||||
<runtime-relative-path>ext/log4j-core-2.17.2.jar</runtime-relative-path>
|
||||
<binary-origin>release/modules/ext/log4j-core-2.17.2.jar</binary-origin>
|
||||
</class-path-extension>
|
||||
<class-path-extension>
|
||||
<runtime-relative-path>ext/ooxml-schemas-1.4.jar</runtime-relative-path>
|
||||
<binary-origin>release/modules/ext/ooxml-schemas-1.4.jar</binary-origin>
|
||||
</class-path-extension>
|
||||
<class-path-extension>
|
||||
<runtime-relative-path>ext/opencensus-api-0.31.0.jar</runtime-relative-path>
|
||||
<binary-origin>release/modules/ext/opencensus-api-0.31.0.jar</binary-origin>
|
||||
@ -908,10 +915,6 @@
|
||||
<runtime-relative-path>ext/reload4j-1.2.19.jar</runtime-relative-path>
|
||||
<binary-origin>release/modules/ext/reload4j-1.2.19.jar</binary-origin>
|
||||
</class-path-extension>
|
||||
<class-path-extension>
|
||||
<runtime-relative-path>ext/sigar-1.6.4.jar</runtime-relative-path>
|
||||
<binary-origin>release/modules/ext/sigar-1.6.4.jar</binary-origin>
|
||||
</class-path-extension>
|
||||
<class-path-extension>
|
||||
<runtime-relative-path>ext/slf4j-api-1.7.36.jar</runtime-relative-path>
|
||||
<binary-origin>release/modules/ext/slf4j-api-1.7.36.jar</binary-origin>
|
||||
|
@ -4,4 +4,3 @@ OpenIDE-Module-Long-Description=\
|
||||
The libraries can also be imported by other modules.
|
||||
OpenIDE-Module-Name=Autopsy-CoreLibs
|
||||
OpenIDE-Module-Short-Description=Autopsy Core module external libraries
|
||||
SigarLoader.linkErr.msg=Could not load sigar library for your environment (non-critical), OS-level metrics will be unavailable.
|
||||
|
@ -1,67 +0,0 @@
|
||||
/*
|
||||
* Autopsy Forensic Browser
|
||||
*
|
||||
* Copyright 2013 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.corelibs;
|
||||
|
||||
import com.sun.javafx.PlatformUtil;
|
||||
import org.hyperic.sigar.Sigar;
|
||||
import org.openide.util.NbBundle;
|
||||
|
||||
/**
|
||||
* Wrapper over Sigar instrumentation class to facilitate dll loading. Our setup
|
||||
* bypasses Sigar library loader which does not work well for netbeans
|
||||
* environment We are responsible for loading the library ourselves.
|
||||
*/
|
||||
public class SigarLoader {
|
||||
|
||||
private static volatile Sigar sigar;
|
||||
|
||||
static {
|
||||
//bypass the process of validation/loading of the library by sigar jar
|
||||
System.setProperty("org.hyperic.sigar.path", "-");
|
||||
//System.setProperty(org.hyperic.sigar.SigarLoader.PROP_SIGAR_JAR_NAME, "sigar-1.6.4.jar");
|
||||
}
|
||||
|
||||
public static Sigar getSigar() {
|
||||
if (sigar == null) {
|
||||
synchronized (SigarLoader.class) {
|
||||
if (sigar == null) {
|
||||
try {
|
||||
//rely on netbeans / jna to locate the lib variation for architecture/OS
|
||||
if (PlatformUtil.isWindows()) {
|
||||
System.loadLibrary("libsigar"); //NON-NLS
|
||||
} else {
|
||||
System.loadLibrary("sigar"); //NON-NLS
|
||||
}
|
||||
sigar = new Sigar();
|
||||
sigar.enableLogging(false); //forces a test
|
||||
|
||||
} catch (UnsatisfiedLinkError ex) {
|
||||
String msg = NbBundle.getMessage(SigarLoader.class, "SigarLoader.linkErr.msg");
|
||||
System.out.println(msg + ex.toString());
|
||||
} catch (Exception ex) {
|
||||
String msg = NbBundle.getMessage(SigarLoader.class, "SigarLoader.linkErr.msg");
|
||||
System.out.println(msg + ex.toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return sigar;
|
||||
}
|
||||
}
|
@ -4,10 +4,10 @@
|
||||
<conf name="coretestlibs"/>
|
||||
</configurations>
|
||||
<dependencies >
|
||||
<dependency conf="coretestlibs->default" org="org.mockito" name="mockito-core" rev="3.5.7"/>
|
||||
<dependency conf="coretestlibs->default" org="net.bytebuddy" name="byte-buddy" rev="1.10.13"/>
|
||||
<dependency conf="coretestlibs->default" org="net.bytebuddy" name="byte-buddy-agent" rev="1.10.13"/>
|
||||
<dependency conf="coretestlibs->default" org="org.objenesis" name="objenesis" rev="3.1"/>
|
||||
<dependency conf="coretestlibs->default" org="org.mockito" name="mockito-core" rev="4.8.1"/>
|
||||
<dependency conf="coretestlibs->default" org="net.bytebuddy" name="byte-buddy" rev="1.12.18"/>
|
||||
<dependency conf="coretestlibs->default" org="net.bytebuddy" name="byte-buddy-agent" rev="1.12.18"/>
|
||||
<dependency conf="coretestlibs->default" org="org.objenesis" name="objenesis" rev="3.3"/>
|
||||
<dependency conf="coretestlibs->default" org="junit" name="junit" rev="4.13.2"/>
|
||||
</dependencies>
|
||||
</ivy-module>
|
@ -2,7 +2,7 @@ file.reference.byte-buddy-1.10.13.jar=release/modules/ext/byte-buddy-1.10.13.jar
|
||||
file.reference.byte-buddy-agent-1.10.13.jar=release/modules/ext/byte-buddy-agent-1.10.13.jar
|
||||
file.reference.hamcrest-core-1.3.jar=release/modules/ext/hamcrest-core-1.3.jar
|
||||
file.reference.junit-4.13.2.jar=release/modules/ext/junit-4.13.2.jar
|
||||
file.reference.mockito-core-3.5.7.jar=release/modules/ext/mockito-core-3.5.7.jar
|
||||
file.reference.mockito-core-4.8.1.jar=release/modules/ext/mockito-core-4.8.1.jar
|
||||
file.reference.objenesis-3.1.jar=release/modules/ext/objenesis-3.1.jar
|
||||
javac.source=1.8
|
||||
javac.source=11
|
||||
javac.compilerargs=-Xlint -Xlint:-serial
|
||||
|
@ -44,12 +44,12 @@
|
||||
<package>org.junit.validator</package>
|
||||
</public-packages>
|
||||
<class-path-extension>
|
||||
<runtime-relative-path>ext/byte-buddy-1.10.13.jar</runtime-relative-path>
|
||||
<binary-origin>release/modules/ext/byte-buddy-1.10.13.jar</binary-origin>
|
||||
<runtime-relative-path>ext/byte-buddy-1.12.18.jar</runtime-relative-path>
|
||||
<binary-origin>release/modules/ext/byte-buddy-1.12.18.jar</binary-origin>
|
||||
</class-path-extension>
|
||||
<class-path-extension>
|
||||
<runtime-relative-path>ext/byte-buddy-agent-1.10.13.jar</runtime-relative-path>
|
||||
<binary-origin>release/modules/ext/byte-buddy-agent-1.10.13.jar</binary-origin>
|
||||
<runtime-relative-path>ext/byte-buddy-agent-1.12.18.jar</runtime-relative-path>
|
||||
<binary-origin>release/modules/ext/byte-buddy-agent-1.12.18.jar</binary-origin>
|
||||
</class-path-extension>
|
||||
<class-path-extension>
|
||||
<runtime-relative-path>ext/hamcrest-core-1.3.jar</runtime-relative-path>
|
||||
@ -60,12 +60,12 @@
|
||||
<binary-origin>release/modules/ext/junit-4.13.2.jar</binary-origin>
|
||||
</class-path-extension>
|
||||
<class-path-extension>
|
||||
<runtime-relative-path>ext/mockito-core-3.5.7.jar</runtime-relative-path>
|
||||
<binary-origin>release/modules/ext/mockito-core-3.5.7.jar</binary-origin>
|
||||
<runtime-relative-path>ext/mockito-core-4.8.1.jar</runtime-relative-path>
|
||||
<binary-origin>release/modules/ext/mockito-core-4.8.1.jar</binary-origin>
|
||||
</class-path-extension>
|
||||
<class-path-extension>
|
||||
<runtime-relative-path>ext/objenesis-3.1.jar</runtime-relative-path>
|
||||
<binary-origin>release/modules/ext/objenesis-3.1.jar</binary-origin>
|
||||
<runtime-relative-path>ext/objenesis-3.3.jar</runtime-relative-path>
|
||||
<binary-origin>release/modules/ext/objenesis-3.3.jar</binary-origin>
|
||||
</class-path-extension>
|
||||
</data>
|
||||
</configuration>
|
||||
|
@ -1,4 +1,4 @@
|
||||
file.reference.jtidy-r938.jar=release/modules/ext/jtidy-r938.jar
|
||||
javac.source=1.8
|
||||
javac.source=17
|
||||
javac.compilerargs=-Xlint -Xlint:-serial
|
||||
spec.version.base=1.0
|
||||
|
@ -12,7 +12,7 @@
|
||||
<compile-dependency/>
|
||||
<run-dependency>
|
||||
<release-version>1</release-version>
|
||||
<specification-version>1.47.1</specification-version>
|
||||
<specification-version>1.65</specification-version>
|
||||
</run-dependency>
|
||||
</dependency>
|
||||
<dependency>
|
||||
@ -21,7 +21,7 @@
|
||||
<compile-dependency/>
|
||||
<run-dependency>
|
||||
<release-version>1</release-version>
|
||||
<specification-version>1.44.1</specification-version>
|
||||
<specification-version>1.62</specification-version>
|
||||
</run-dependency>
|
||||
</dependency>
|
||||
<dependency>
|
||||
@ -30,7 +30,7 @@
|
||||
<compile-dependency/>
|
||||
<run-dependency>
|
||||
<release-version>1</release-version>
|
||||
<specification-version>1.49.1</specification-version>
|
||||
<specification-version>1.66</specification-version>
|
||||
</run-dependency>
|
||||
</dependency>
|
||||
<dependency>
|
||||
@ -38,7 +38,7 @@
|
||||
<build-prerequisite/>
|
||||
<compile-dependency/>
|
||||
<run-dependency>
|
||||
<specification-version>1.34.1</specification-version>
|
||||
<specification-version>1.51</specification-version>
|
||||
</run-dependency>
|
||||
</dependency>
|
||||
<dependency>
|
||||
@ -46,7 +46,7 @@
|
||||
<build-prerequisite/>
|
||||
<compile-dependency/>
|
||||
<run-dependency>
|
||||
<specification-version>7.65.1</specification-version>
|
||||
<specification-version>7.85</specification-version>
|
||||
</run-dependency>
|
||||
</dependency>
|
||||
<dependency>
|
||||
@ -54,7 +54,7 @@
|
||||
<build-prerequisite/>
|
||||
<compile-dependency/>
|
||||
<run-dependency>
|
||||
<specification-version>7.41.1</specification-version>
|
||||
<specification-version>7.63</specification-version>
|
||||
</run-dependency>
|
||||
</dependency>
|
||||
<dependency>
|
||||
@ -62,7 +62,7 @@
|
||||
<build-prerequisite/>
|
||||
<compile-dependency/>
|
||||
<run-dependency>
|
||||
<specification-version>6.62.1</specification-version>
|
||||
<specification-version>6.79</specification-version>
|
||||
</run-dependency>
|
||||
</dependency>
|
||||
<dependency>
|
||||
@ -70,7 +70,7 @@
|
||||
<build-prerequisite/>
|
||||
<compile-dependency/>
|
||||
<run-dependency>
|
||||
<specification-version>9.8.1</specification-version>
|
||||
<specification-version>9.29</specification-version>
|
||||
</run-dependency>
|
||||
</dependency>
|
||||
<dependency>
|
||||
@ -78,7 +78,7 @@
|
||||
<build-prerequisite/>
|
||||
<compile-dependency/>
|
||||
<run-dependency>
|
||||
<specification-version>7.63.2</specification-version>
|
||||
<specification-version>7.87</specification-version>
|
||||
</run-dependency>
|
||||
</dependency>
|
||||
<dependency>
|
||||
@ -86,7 +86,7 @@
|
||||
<build-prerequisite/>
|
||||
<compile-dependency/>
|
||||
<run-dependency>
|
||||
<specification-version>7.47.1</specification-version>
|
||||
<specification-version>7.65</specification-version>
|
||||
</run-dependency>
|
||||
</dependency>
|
||||
<dependency>
|
||||
@ -94,7 +94,7 @@
|
||||
<build-prerequisite/>
|
||||
<compile-dependency/>
|
||||
<run-dependency>
|
||||
<specification-version>7.45.1</specification-version>
|
||||
<specification-version>7.62</specification-version>
|
||||
</run-dependency>
|
||||
</dependency>
|
||||
<dependency>
|
||||
@ -102,7 +102,7 @@
|
||||
<build-prerequisite/>
|
||||
<compile-dependency/>
|
||||
<run-dependency>
|
||||
<specification-version>9.5.1</specification-version>
|
||||
<specification-version>9.25</specification-version>
|
||||
</run-dependency>
|
||||
</dependency>
|
||||
<dependency>
|
||||
@ -110,7 +110,7 @@
|
||||
<build-prerequisite/>
|
||||
<compile-dependency/>
|
||||
<run-dependency>
|
||||
<specification-version>8.32.1</specification-version>
|
||||
<specification-version>8.51</specification-version>
|
||||
</run-dependency>
|
||||
</dependency>
|
||||
<dependency>
|
||||
@ -118,7 +118,7 @@
|
||||
<build-prerequisite/>
|
||||
<compile-dependency/>
|
||||
<run-dependency>
|
||||
<specification-version>9.4.1</specification-version>
|
||||
<specification-version>9.25</specification-version>
|
||||
</run-dependency>
|
||||
</dependency>
|
||||
<dependency>
|
||||
@ -126,7 +126,7 @@
|
||||
<build-prerequisite/>
|
||||
<compile-dependency/>
|
||||
<run-dependency>
|
||||
<specification-version>6.74.1</specification-version>
|
||||
<specification-version>6.94</specification-version>
|
||||
</run-dependency>
|
||||
</dependency>
|
||||
<dependency>
|
||||
|
@ -80,6 +80,7 @@ import java.time.Instant;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.ZoneId;
|
||||
import javax.swing.DefaultListModel;
|
||||
import javax.swing.tree.TreeNode;
|
||||
import org.apache.commons.codec.DecoderException;
|
||||
import org.apache.commons.codec.binary.Hex;
|
||||
import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException;
|
||||
@ -1322,10 +1323,10 @@ public final class FileExporterSettingsPanel extends JPanel {
|
||||
*/
|
||||
private TreePath findTreePathByRuleAndArtifactClauseName(String ruleName, String clauseName) {
|
||||
@SuppressWarnings("unchecked")
|
||||
Enumeration<DefaultMutableTreeNode> enumeration = rootNode.preorderEnumeration();
|
||||
Enumeration<TreeNode> enumeration = rootNode.preorderEnumeration();
|
||||
boolean insideRule = false;
|
||||
while (enumeration.hasMoreElements()) {
|
||||
DefaultMutableTreeNode node = enumeration.nextElement();
|
||||
DefaultMutableTreeNode node = (DefaultMutableTreeNode) enumeration.nextElement();
|
||||
Item item = (Item) node.getUserObject();
|
||||
if (item.getItemType() == ItemType.RULE) {
|
||||
insideRule = node.toString().equalsIgnoreCase(ruleName);
|
||||
@ -1349,9 +1350,9 @@ public final class FileExporterSettingsPanel extends JPanel {
|
||||
*/
|
||||
private TreePath findTreePathByRuleName(String ruleName) {
|
||||
@SuppressWarnings("unchecked")
|
||||
Enumeration<DefaultMutableTreeNode> enumeration = rootNode.depthFirstEnumeration();
|
||||
Enumeration<TreeNode> enumeration = rootNode.depthFirstEnumeration();
|
||||
while (enumeration.hasMoreElements()) {
|
||||
DefaultMutableTreeNode node = enumeration.nextElement();
|
||||
DefaultMutableTreeNode node = (DefaultMutableTreeNode) enumeration.nextElement();
|
||||
if (node.toString().equalsIgnoreCase(ruleName)) {
|
||||
return new TreePath(node.getPath());
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
file.reference.sqlite-jdbc-3.36.0.3.jar=release/modules/ext/sqlite-jdbc-3.36.0.3.jar
|
||||
javac.source=1.8
|
||||
javac.source=17
|
||||
javac.compilerargs=-Xlint -Xlint:-serial
|
||||
license.file=LICENSE-2.0.txt
|
||||
nbm.homepage=http://www.sleuthkit.org/
|
||||
|
@ -12,7 +12,7 @@
|
||||
<compile-dependency/>
|
||||
<run-dependency>
|
||||
<release-version>1</release-version>
|
||||
<specification-version>1.32.1</specification-version>
|
||||
<specification-version>1.65</specification-version>
|
||||
</run-dependency>
|
||||
</dependency>
|
||||
<dependency>
|
||||
@ -20,7 +20,7 @@
|
||||
<build-prerequisite/>
|
||||
<compile-dependency/>
|
||||
<run-dependency>
|
||||
<specification-version>1.46.1</specification-version>
|
||||
<specification-version>1.64</specification-version>
|
||||
</run-dependency>
|
||||
</dependency>
|
||||
<dependency>
|
||||
@ -28,7 +28,7 @@
|
||||
<build-prerequisite/>
|
||||
<compile-dependency/>
|
||||
<run-dependency>
|
||||
<specification-version>1.46.1</specification-version>
|
||||
<specification-version>1.65</specification-version>
|
||||
</run-dependency>
|
||||
</dependency>
|
||||
<dependency>
|
||||
@ -37,7 +37,7 @@
|
||||
<compile-dependency/>
|
||||
<run-dependency>
|
||||
<release-version>1</release-version>
|
||||
<specification-version>1.31.2</specification-version>
|
||||
<specification-version>1.62</specification-version>
|
||||
</run-dependency>
|
||||
</dependency>
|
||||
<dependency>
|
||||
@ -46,7 +46,7 @@
|
||||
<compile-dependency/>
|
||||
<run-dependency>
|
||||
<release-version>1</release-version>
|
||||
<specification-version>1.38.2</specification-version>
|
||||
<specification-version>1.66</specification-version>
|
||||
</run-dependency>
|
||||
</dependency>
|
||||
<dependency>
|
||||
@ -54,7 +54,7 @@
|
||||
<build-prerequisite/>
|
||||
<compile-dependency/>
|
||||
<run-dependency>
|
||||
<specification-version>7.55.1</specification-version>
|
||||
<specification-version>7.85</specification-version>
|
||||
</run-dependency>
|
||||
</dependency>
|
||||
<dependency>
|
||||
@ -62,7 +62,7 @@
|
||||
<build-prerequisite/>
|
||||
<compile-dependency/>
|
||||
<run-dependency>
|
||||
<specification-version>7.28.1</specification-version>
|
||||
<specification-version>7.63</specification-version>
|
||||
</run-dependency>
|
||||
</dependency>
|
||||
<dependency>
|
||||
@ -70,7 +70,7 @@
|
||||
<build-prerequisite/>
|
||||
<compile-dependency/>
|
||||
<run-dependency>
|
||||
<specification-version>6.50.3</specification-version>
|
||||
<specification-version>6.79</specification-version>
|
||||
</run-dependency>
|
||||
</dependency>
|
||||
<dependency>
|
||||
@ -78,7 +78,7 @@
|
||||
<build-prerequisite/>
|
||||
<compile-dependency/>
|
||||
<run-dependency>
|
||||
<specification-version>7.35.1</specification-version>
|
||||
<specification-version>7.65</specification-version>
|
||||
</run-dependency>
|
||||
</dependency>
|
||||
<dependency>
|
||||
@ -86,7 +86,7 @@
|
||||
<build-prerequisite/>
|
||||
<compile-dependency/>
|
||||
<run-dependency>
|
||||
<specification-version>7.33.2</specification-version>
|
||||
<specification-version>7.62</specification-version>
|
||||
</run-dependency>
|
||||
</dependency>
|
||||
<dependency>
|
||||
@ -94,7 +94,7 @@
|
||||
<build-prerequisite/>
|
||||
<compile-dependency/>
|
||||
<run-dependency>
|
||||
<specification-version>8.29.3</specification-version>
|
||||
<specification-version>9.25</specification-version>
|
||||
</run-dependency>
|
||||
</dependency>
|
||||
<dependency>
|
||||
@ -102,7 +102,7 @@
|
||||
<build-prerequisite/>
|
||||
<compile-dependency/>
|
||||
<run-dependency>
|
||||
<specification-version>8.19.1</specification-version>
|
||||
<specification-version>8.51</specification-version>
|
||||
</run-dependency>
|
||||
</dependency>
|
||||
<dependency>
|
||||
@ -110,7 +110,7 @@
|
||||
<build-prerequisite/>
|
||||
<compile-dependency/>
|
||||
<run-dependency>
|
||||
<specification-version>9.4.1</specification-version>
|
||||
<specification-version>9.25</specification-version>
|
||||
</run-dependency>
|
||||
</dependency>
|
||||
<dependency>
|
||||
@ -118,7 +118,7 @@
|
||||
<build-prerequisite/>
|
||||
<compile-dependency/>
|
||||
<run-dependency>
|
||||
<specification-version>6.60.1</specification-version>
|
||||
<specification-version>6.94</specification-version>
|
||||
</run-dependency>
|
||||
</dependency>
|
||||
<dependency>
|
||||
|
@ -240,7 +240,7 @@ public class GroupPane extends BorderPane {
|
||||
*/
|
||||
@ThreadConfined(type = ThreadType.JFX)
|
||||
private final Map<Long, DrawableCell> cellMap = new HashMap<>();
|
||||
|
||||
|
||||
private final InvalidationListener filesSyncListener = (observable) -> {
|
||||
final String header = getHeaderString();
|
||||
final List<Long> fileIds = getGroup().getFileIDs();
|
||||
@ -658,40 +658,46 @@ public class GroupPane extends BorderPane {
|
||||
}
|
||||
}
|
||||
|
||||
private class DrawableCell extends GridCell<Long> {
|
||||
private class DrawableCell extends GridCell<Long> implements AutoCloseable {
|
||||
|
||||
private final DrawableTile tile = new DrawableTile(GroupPane.this, controller);
|
||||
|
||||
|
||||
/**
|
||||
* This stores the last non-null file id. So that only new file ids for
|
||||
* this item are tracked. This prevents an infinite render loop. See
|
||||
* https://github.com/controlsfx/controlsfx/issues/1241 for more
|
||||
* information
|
||||
*/
|
||||
private Long oldItem = null;
|
||||
|
||||
DrawableCell() {
|
||||
itemProperty().addListener((ObservableValue<? extends Long> observable, Long oldValue, Long newValue) -> {
|
||||
if (oldValue != null) {
|
||||
cellMap.remove(oldValue, DrawableCell.this);
|
||||
tile.setFile(null);
|
||||
}
|
||||
if (newValue != null) {
|
||||
if (cellMap.containsKey(newValue)) {
|
||||
if (tile != null) {
|
||||
// Clear out the old value to prevent out-of-date listeners
|
||||
// from activating.
|
||||
cellMap.get(newValue).tile.setFile(null);
|
||||
}
|
||||
}
|
||||
cellMap.put(newValue, DrawableCell.this);
|
||||
}
|
||||
});
|
||||
|
||||
setGraphic(tile);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void updateItem(Long item, boolean empty) {
|
||||
super.updateItem(item, empty);
|
||||
tile.setFile(item);
|
||||
|
||||
if (item != null && oldItem != item) {
|
||||
tile.setFile(item);
|
||||
}
|
||||
|
||||
if (item != null) {
|
||||
cellMap.put(item, this);
|
||||
oldItem = item;
|
||||
} else if (oldItem != null) {
|
||||
cellMap.remove(oldItem);
|
||||
}
|
||||
}
|
||||
|
||||
void resetItem() {
|
||||
tile.setFile(null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() throws Exception {
|
||||
resetItem();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -18,7 +18,8 @@
|
||||
<dependency conf="solr-war->default" org="org.apache.solr" name="solr" rev="4.10.4" transitive="false" /> <!-- the war file for embedded Solr 4 -->
|
||||
|
||||
<dependency conf="solr-libs->default" name="solr-cell" rev="8.11.2" org="org.apache.solr"/>
|
||||
|
||||
<!-- https://mvnrepository.com/artifact/org.apache.lucene/lucene-core -->
|
||||
<dependency conf="autopsy->default" org="org.apache.lucene" name="lucene-core" rev="8.11.2"/>
|
||||
<!-- Autopsy -->
|
||||
<dependency conf="autopsy->default" org="org.apache.solr" name="solr-solrj" rev="8.11.2"/>
|
||||
<dependency conf="autopsy->default" org="com.optimaize.languagedetector" name="language-detector" rev="0.6"/>
|
||||
|
@ -6,6 +6,7 @@ file.reference.commons-math3-3.6.1.jar=release/modules/ext/commons-math3-3.6.1.j
|
||||
file.reference.error_prone_annotations-2.11.0.jar=release/modules/ext/error_prone_annotations-2.11.0.jar
|
||||
file.reference.failureaccess-1.0.1.jar=release/modules/ext/failureaccess-1.0.1.jar
|
||||
file.reference.guava-31.1-jre.jar=release/modules/ext/guava-31.1-jre.jar
|
||||
file.reference.hamcrest-core-1.3.jar=release/modules/ext/hamcrest-core-1.3.jar
|
||||
file.reference.http2-client-9.4.44.v20210927.jar=release/modules/ext/http2-client-9.4.44.v20210927.jar
|
||||
file.reference.http2-common-9.4.44.v20210927.jar=release/modules/ext/http2-common-9.4.44.v20210927.jar
|
||||
file.reference.http2-hpack-9.4.44.v20210927.jar=release/modules/ext/http2-hpack-9.4.44.v20210927.jar
|
||||
@ -24,6 +25,8 @@ file.reference.jetty-http-9.4.44.v20210927.jar=release/modules/ext/jetty-http-9.
|
||||
file.reference.jetty-io-9.4.44.v20210927.jar=release/modules/ext/jetty-io-9.4.44.v20210927.jar
|
||||
file.reference.jetty-util-9.4.44.v20210927.jar=release/modules/ext/jetty-util-9.4.44.v20210927.jar
|
||||
file.reference.jsonic-1.2.11.jar=release/modules/ext/jsonic-1.2.11.jar
|
||||
file.reference.jsr305-3.0.2.jar=release/modules/ext/jsr305-3.0.2.jar
|
||||
file.reference.junit-4.13.2.jar=release/modules/ext/junit-4.13.2.jar
|
||||
file.reference.language-detector-0.6.jar=release/modules/ext/language-detector-0.6.jar
|
||||
file.reference.listenablefuture-9999.0-empty-to-avoid-conflict-with-guava.jar=release/modules/ext/listenablefuture-9999.0-empty-to-avoid-conflict-with-guava.jar
|
||||
file.reference.logback-classic-1.2.10.jar=release/modules/ext/logback-classic-1.2.10.jar
|
||||
@ -38,13 +41,15 @@ file.reference.netty-tcnative-classes-2.0.48.Final.jar=release/modules/ext/netty
|
||||
file.reference.netty-transport-4.1.68.Final.jar=release/modules/ext/netty-transport-4.1.68.Final.jar
|
||||
file.reference.netty-transport-native-epoll-4.1.68.Final.jar=release/modules/ext/netty-transport-native-epoll-4.1.68.Final.jar
|
||||
file.reference.netty-transport-native-unix-common-4.1.68.Final.jar=release/modules/ext/netty-transport-native-unix-common-4.1.68.Final.jar
|
||||
file.reference.slf4j-api-1.7.36.jar=release/modules/ext/slf4j-api-1.7.36.jar
|
||||
file.reference.snappy-java-1.1.7.6.jar=release/modules/ext/snappy-java-1.1.7.6.jar
|
||||
file.reference.solr-solrj-8.11.2.jar=release/modules/ext/solr-solrj-8.11.2.jar
|
||||
file.reference.stax2-api-4.2.1.jar=release/modules/ext/stax2-api-4.2.1.jar
|
||||
file.reference.woodstox-core-6.2.4.jar=release/modules/ext/woodstox-core-6.2.4.jar
|
||||
file.reference.zookeeper-3.8.0.jar=release/modules/ext/zookeeper-3.8.0.jar
|
||||
file.reference.zookeeper-jute-3.8.0.jar=release/modules/ext/zookeeper-jute-3.8.0.jar
|
||||
javac.source=1.8
|
||||
file.reference.lucene-core-8.11.2.jar=release/modules/ext/lucene-core-8.11.2.jar
|
||||
javac.source=17
|
||||
javac.compilerargs=-Xlint -Xlint:-serial
|
||||
license.file=../LICENSE-2.0.txt
|
||||
nbm.homepage=http://www.sleuthkit.org/autopsy/
|
||||
|
@ -12,7 +12,7 @@
|
||||
<compile-dependency/>
|
||||
<run-dependency>
|
||||
<release-version>1</release-version>
|
||||
<specification-version>1.24.1</specification-version>
|
||||
<specification-version>1.65</specification-version>
|
||||
</run-dependency>
|
||||
</dependency>
|
||||
<dependency>
|
||||
@ -20,7 +20,7 @@
|
||||
<build-prerequisite/>
|
||||
<compile-dependency/>
|
||||
<run-dependency>
|
||||
<specification-version>1.46.1</specification-version>
|
||||
<specification-version>1.64</specification-version>
|
||||
</run-dependency>
|
||||
</dependency>
|
||||
<dependency>
|
||||
@ -28,7 +28,7 @@
|
||||
<build-prerequisite/>
|
||||
<compile-dependency/>
|
||||
<run-dependency>
|
||||
<specification-version>1.46.1</specification-version>
|
||||
<specification-version>1.65</specification-version>
|
||||
</run-dependency>
|
||||
</dependency>
|
||||
<dependency>
|
||||
@ -37,7 +37,7 @@
|
||||
<compile-dependency/>
|
||||
<run-dependency>
|
||||
<release-version>1</release-version>
|
||||
<specification-version>1.26.1</specification-version>
|
||||
<specification-version>1.62</specification-version>
|
||||
</run-dependency>
|
||||
</dependency>
|
||||
<dependency>
|
||||
@ -46,7 +46,7 @@
|
||||
<compile-dependency/>
|
||||
<run-dependency>
|
||||
<release-version>1</release-version>
|
||||
<specification-version>1.31.1</specification-version>
|
||||
<specification-version>1.66</specification-version>
|
||||
</run-dependency>
|
||||
</dependency>
|
||||
<dependency>
|
||||
@ -54,7 +54,7 @@
|
||||
<build-prerequisite/>
|
||||
<compile-dependency/>
|
||||
<run-dependency>
|
||||
<specification-version>7.31.1</specification-version>
|
||||
<specification-version>7.85</specification-version>
|
||||
</run-dependency>
|
||||
</dependency>
|
||||
<dependency>
|
||||
@ -62,7 +62,7 @@
|
||||
<build-prerequisite/>
|
||||
<compile-dependency/>
|
||||
<run-dependency>
|
||||
<specification-version>6.50.3</specification-version>
|
||||
<specification-version>6.79</specification-version>
|
||||
</run-dependency>
|
||||
</dependency>
|
||||
<dependency>
|
||||
@ -70,7 +70,7 @@
|
||||
<build-prerequisite/>
|
||||
<compile-dependency/>
|
||||
<run-dependency>
|
||||
<specification-version>7.23.1</specification-version>
|
||||
<specification-version>7.65</specification-version>
|
||||
</run-dependency>
|
||||
</dependency>
|
||||
<dependency>
|
||||
@ -78,7 +78,7 @@
|
||||
<build-prerequisite/>
|
||||
<compile-dependency/>
|
||||
<run-dependency>
|
||||
<specification-version>7.21.1</specification-version>
|
||||
<specification-version>7.62</specification-version>
|
||||
</run-dependency>
|
||||
</dependency>
|
||||
<dependency>
|
||||
@ -86,7 +86,7 @@
|
||||
<build-prerequisite/>
|
||||
<compile-dependency/>
|
||||
<run-dependency>
|
||||
<specification-version>8.15.1</specification-version>
|
||||
<specification-version>9.25</specification-version>
|
||||
</run-dependency>
|
||||
</dependency>
|
||||
<dependency>
|
||||
@ -94,7 +94,7 @@
|
||||
<build-prerequisite/>
|
||||
<compile-dependency/>
|
||||
<run-dependency>
|
||||
<specification-version>8.8.1</specification-version>
|
||||
<specification-version>8.51</specification-version>
|
||||
</run-dependency>
|
||||
</dependency>
|
||||
<dependency>
|
||||
@ -102,7 +102,7 @@
|
||||
<build-prerequisite/>
|
||||
<compile-dependency/>
|
||||
<run-dependency>
|
||||
<specification-version>9.4.1</specification-version>
|
||||
<specification-version>9.25</specification-version>
|
||||
</run-dependency>
|
||||
</dependency>
|
||||
<dependency>
|
||||
@ -110,7 +110,7 @@
|
||||
<build-prerequisite/>
|
||||
<compile-dependency/>
|
||||
<run-dependency>
|
||||
<specification-version>6.40.1</specification-version>
|
||||
<specification-version>6.94</specification-version>
|
||||
</run-dependency>
|
||||
</dependency>
|
||||
<dependency>
|
||||
@ -266,6 +266,10 @@
|
||||
<runtime-relative-path>ext/guava-31.1-jre.jar</runtime-relative-path>
|
||||
<binary-origin>release/modules/ext/guava-31.1-jre.jar</binary-origin>
|
||||
</class-path-extension>
|
||||
<class-path-extension>
|
||||
<runtime-relative-path>ext/hamcrest-core-1.3.jar</runtime-relative-path>
|
||||
<binary-origin>release/modules/ext/hamcrest-core-1.3.jar</binary-origin>
|
||||
</class-path-extension>
|
||||
<class-path-extension>
|
||||
<runtime-relative-path>ext/http2-client-9.4.44.v20210927.jar</runtime-relative-path>
|
||||
<binary-origin>release/modules/ext/http2-client-9.4.44.v20210927.jar</binary-origin>
|
||||
@ -338,6 +342,14 @@
|
||||
<runtime-relative-path>ext/jsonic-1.2.11.jar</runtime-relative-path>
|
||||
<binary-origin>release/modules/ext/jsonic-1.2.11.jar</binary-origin>
|
||||
</class-path-extension>
|
||||
<class-path-extension>
|
||||
<runtime-relative-path>ext/jsr305-3.0.2.jar</runtime-relative-path>
|
||||
<binary-origin>release/modules/ext/jsr305-3.0.2.jar</binary-origin>
|
||||
</class-path-extension>
|
||||
<class-path-extension>
|
||||
<runtime-relative-path>ext/junit-4.13.2.jar</runtime-relative-path>
|
||||
<binary-origin>release/modules/ext/junit-4.13.2.jar</binary-origin>
|
||||
</class-path-extension>
|
||||
<class-path-extension>
|
||||
<runtime-relative-path>ext/language-detector-0.6.jar</runtime-relative-path>
|
||||
<binary-origin>release/modules/ext/language-detector-0.6.jar</binary-origin>
|
||||
@ -394,6 +406,10 @@
|
||||
<runtime-relative-path>ext/netty-transport-native-unix-common-4.1.68.Final.jar</runtime-relative-path>
|
||||
<binary-origin>release/modules/ext/netty-transport-native-unix-common-4.1.68.Final.jar</binary-origin>
|
||||
</class-path-extension>
|
||||
<class-path-extension>
|
||||
<runtime-relative-path>ext/slf4j-api-1.7.36.jar</runtime-relative-path>
|
||||
<binary-origin>release/modules/ext/slf4j-api-1.7.36.jar</binary-origin>
|
||||
</class-path-extension>
|
||||
<class-path-extension>
|
||||
<runtime-relative-path>ext/snappy-java-1.1.7.6.jar</runtime-relative-path>
|
||||
<binary-origin>release/modules/ext/snappy-java-1.1.7.6.jar</binary-origin>
|
||||
@ -418,6 +434,10 @@
|
||||
<runtime-relative-path>ext/zookeeper-jute-3.8.0.jar</runtime-relative-path>
|
||||
<binary-origin>release/modules/ext/zookeeper-jute-3.8.0.jar</binary-origin>
|
||||
</class-path-extension>
|
||||
<class-path-extension>
|
||||
<runtime-relative-path>ext/lucene-core-8.11.2.jar</runtime-relative-path>
|
||||
<binary-origin>release/modules/ext/lucene-core-8.11.2.jar</binary-origin>
|
||||
</class-path-extension>
|
||||
</data>
|
||||
</configuration>
|
||||
</project>
|
||||
|
@ -301,7 +301,7 @@
|
||||
<autoCommit>
|
||||
<maxTime>300000</maxTime>
|
||||
<!-- maxDocs>15000</maxDocs -->
|
||||
<openSearcher>true</openSearcher>
|
||||
<openSearcher>false</openSearcher>
|
||||
</autoCommit>
|
||||
|
||||
<!-- softAutoCommit is like autoCommit except it causes a
|
||||
|
@ -112,9 +112,9 @@ abstract class AdHocSearchPanel extends javax.swing.JPanel {
|
||||
}
|
||||
if (filesIndexed == 0) {
|
||||
if (isIngestRunning) {
|
||||
// ELTODO this message should be dependent on whether Solr indexing is enabled or not
|
||||
KeywordSearchUtil.displayDialog(keywordSearchErrorDialogHeader, NbBundle.getMessage(this.getClass(),
|
||||
"AbstractKeywordSearchPerformer.search.noFilesInIdxMsg",
|
||||
KeywordSearchSettings.getUpdateFrequency().getTime()), KeywordSearchUtil.DIALOG_MESSAGE_TYPE.ERROR);
|
||||
"AbstractKeywordSearchPerformer.search.noFilesInIdxMsg"), KeywordSearchUtil.DIALOG_MESSAGE_TYPE.ERROR);
|
||||
} else {
|
||||
KeywordSearchUtil.displayDialog(keywordSearchErrorDialogHeader, NbBundle.getMessage(this.getClass(),
|
||||
"AbstractKeywordSearchPerformer.search.noFilesIdxdMsg"), KeywordSearchUtil.DIALOG_MESSAGE_TYPE.ERROR);
|
||||
|
@ -39,8 +39,8 @@ AbstractKeywordSearchPerformer.search.invalidSyntaxHeader=Invalid query statemen
|
||||
AbstractKeywordSearchPerformer.search.searchIngestInProgressTitle=Keyword Search Ingest in Progress
|
||||
AbstractKeywordSearchPerformer.search.ingestInProgressBody=<html>Keyword Search Ingest is currently running.<br />Not all files have been indexed and this search might yield incomplete results.<br />Do you want to proceed with this search anyway?</html>
|
||||
AbstractKeywordSearchPerformer.search.emptyKeywordErrorBody=Keyword list is empty, please add at least one keyword to the list
|
||||
AbstractKeywordSearchPerformer.search.noFilesInIdxMsg=<html>No files are in index yet. <br />Try again later. Index is updated every {0} minutes.</html>
|
||||
AbstractKeywordSearchPerformer.search.noFilesIdxdMsg=<html>No files were indexed.<br />Re-ingest the image with the Keyword Search Module enabled. </html>
|
||||
AbstractKeywordSearchPerformer.search.noFilesInIdxMsg=<html>No files are in index yet. <br />If Solr keyword search indexing was enabled, wait for ingest to complete</html>
|
||||
AbstractKeywordSearchPerformer.search.noFilesIdxdMsg=<html>No files were indexed.<br />Re-ingest the image with the Keyword Search Module and Solr indexing enabled. </html>
|
||||
ExtractedContentViewer.toolTip=Displays extracted text from files and keyword-search results. Requires Keyword Search ingest to be run on a file to activate this viewer.
|
||||
ExtractedContentViewer.getTitle=Indexed Text
|
||||
HighlightedMatchesSource.toString=Search Results
|
||||
@ -122,7 +122,7 @@ KeywordSearchListsManagementPanel.fileExtensionFilterLbl=Autopsy Keyword List Fi
|
||||
KeywordSearchListsManagementPanel.fileExtensionFilterLb2=Encase Keyword List File (txt)
|
||||
KeywordSearch.listImportFeatureTitle=Keyword List Import
|
||||
KeywordSearchIngestModule.moduleName=Keyword Search
|
||||
KeywordSearchIngestModule.moduleDescription=Performs file indexing and periodic search using keywords and regular expressions in lists.
|
||||
KeywordSearchIngestModule.moduleDescription=Performs file indexing and search using selected keyword lists.
|
||||
DropdownSearchPanel.keywordTextField.text=
|
||||
KeywordSearchPanel.searchDropButton.text=Keyword Search
|
||||
DropdownSearchPanel.exactRadioButton.text=Exact Match
|
||||
@ -211,11 +211,6 @@ KeywordSearchGlobalLanguageSettingsPanel.enableUTF8Checkbox.text=Enable UTF8 tex
|
||||
KeywordSearchGlobalLanguageSettingsPanel.ingestSettingsLabel.text=Ingest settings for string extraction from unknown file types (changes effective on next ingest):
|
||||
KeywordSearchGlobalLanguageSettingsPanel.enableUTF16Checkbox.text=Enable UTF16LE and UTF16BE string extraction
|
||||
KeywordSearchGlobalLanguageSettingsPanel.languagesLabel.text=Enabled scripts (languages):
|
||||
KeywordSearchGlobalSearchSettingsPanel.timeRadioButton1.toolTipText=20 mins. (fastest ingest time)
|
||||
KeywordSearchGlobalSearchSettingsPanel.timeRadioButton1.text=20 minutes (slowest feedback, fastest ingest)
|
||||
KeywordSearchGlobalSearchSettingsPanel.timeRadioButton2.toolTipText=10 minutes (faster overall ingest time than default)
|
||||
KeywordSearchGlobalSearchSettingsPanel.timeRadioButton2.text=10 minutes (slower feedback, faster ingest)
|
||||
KeywordSearchGlobalSearchSettingsPanel.frequencyLabel.text=Results update frequency during ingest:
|
||||
KeywordSearchGlobalSearchSettingsPanel.skipNSRLCheckBox.toolTipText=Requires Hash Set service to had run previously, or be selected for next ingest.
|
||||
KeywordSearchGlobalSearchSettingsPanel.skipNSRLCheckBox.text=Do not add files in NSRL (known files) to keyword index during ingest
|
||||
KeywordSearchGlobalSearchSettingsPanel.informationLabel.text=Information
|
||||
@ -224,11 +219,7 @@ KeywordSearchGlobalSearchSettingsPanel.filesIndexedValue.text=0
|
||||
KeywordSearchGlobalSearchSettingsPanel.filesIndexedLabel.text=Files in keyword index:
|
||||
KeywordSearchGlobalSearchSettingsPanel.showSnippetsCB.text=Show Keyword Preview in Keyword Search Results (will result in longer search times)
|
||||
KeywordSearchGlobalSearchSettingsPanel.chunksValLabel.text=0
|
||||
KeywordSearchGlobalSearchSettingsPanel.timeRadioButton4.toolTipText=1 minute (overall ingest time will be longest)
|
||||
KeywordSearchGlobalSearchSettingsPanel.timeRadioButton4.text_1=1 minute (faster feedback, longest ingest)
|
||||
KeywordSearchGlobalSearchSettingsPanel.chunksLabel.text=Chunks in keyword index:
|
||||
KeywordSearchGlobalSearchSettingsPanel.timeRadioButton3.toolTipText=5 minutes (overall ingest time will be longer)
|
||||
KeywordSearchGlobalSearchSettingsPanel.timeRadioButton3.text=5 minutes (default)
|
||||
KeywordSearchIngestModule.regExpHitLbl=Reg Ex hit:
|
||||
KeywordSearchIngestModule.kwHitLbl=Keyword hit:
|
||||
KeywordSearchIngestModule.kwHitThLbl=Keyword
|
||||
@ -254,8 +245,6 @@ KeywordSearchListsManagementPanel.newKeywordListDescription2=Keyword list <{0}>
|
||||
KeywordSearchModuleFactory.getIngestJobSettingsPanel.exception.msg=Expected settings argument to be instanceof KeywordSearchJobSettings
|
||||
KeywordSearchModuleFactory.createFileIngestModule.exception.msg=Expected settings argument to be instanceof KeywordSearchJobSettings
|
||||
SearchRunner.Searcher.done.err.msg=Error performing keyword search
|
||||
KeywordSearchGlobalSearchSettingsPanel.timeRadioButton5.toolTipText=Fastest overall, but no results until the end
|
||||
KeywordSearchGlobalSearchSettingsPanel.timeRadioButton5.text=No periodic searches
|
||||
SolrConnectionCheck.HostnameOrPort=Invalid hostname and/or port number.
|
||||
SolrConnectionCheck.Hostname=Invalid hostname.
|
||||
SolrConnectionCheck.MissingHostname=Missing hostname.
|
||||
@ -322,3 +311,4 @@ ExtractedContentPanel.pagesLabel.text=Page:
|
||||
KeywordSearchJobSettingsPanel.ocrCheckBox.text=Enable Optical Character Recognition (OCR)
|
||||
KeywordSearchJobSettingsPanel.limitedOcrCheckbox.text=<html>Only process PDFs, MS Office docs and images which are over 100KB in size or extracted from another file (Beta)</html>
|
||||
KeywordSearchJobSettingsPanel.ocrOnlyCheckbox.text=Only index text extracted using OCR
|
||||
KeywordSearchJobSettingsPanel.solrCheckbox.text=Add text to Solr Index
|
||||
|
@ -15,16 +15,13 @@ ExtractAllTermsReport.error.noOpenCase=No currently open case.
|
||||
ExtractAllTermsReport.export.error=Error During Unique Word Extraction
|
||||
ExtractAllTermsReport.exportComplete=Unique Word Extraction Complete
|
||||
ExtractAllTermsReport.getName.text=Extract Unique Words
|
||||
# {0} - Number of extracted terms
|
||||
ExtractAllTermsReport.numberExtractedTerms=Extracted {0} terms...
|
||||
ExtractAllTermsReport.search.ingestInProgressBody=<html>Keyword Search Ingest is currently running.<br />Not all files have been indexed and unique word extraction might yield incomplete results.<br />Do you want to proceed with unique word extraction anyway?</html>
|
||||
# {0} - Keyword search commit frequency
|
||||
ExtractAllTermsReport.search.noFilesInIdxMsg=No files are in index yet. Try again later. Index is updated every {0} minutes.
|
||||
ExtractAllTermsReport.search.noFilesInIdxMsg2=No files are in index yet. Try again later
|
||||
ExtractAllTermsReport.search.noFilesInIdxMsg=No files are in index yet. If Solr keyword search indexing and Solr indexing were enabled, wait for ingest to complete.
|
||||
ExtractAllTermsReport.search.noFilesInIdxMsg2=No files are in index yet. Re-ingest the image with the Keyword Search Module and Solr indexing enabled.
|
||||
ExtractAllTermsReport.search.searchIngestInProgressTitle=Keyword Search Ingest in Progress
|
||||
ExtractAllTermsReport.startExport=Starting Unique Word Extraction
|
||||
ExtractedContentPanel.setMarkup.panelTxt=<span style='font-style:italic'>Loading text... Please wait</span>
|
||||
# {0} - Content name
|
||||
ExtractedContentPanel.SetMarkup.progress.loading=Loading text for {0}
|
||||
GlobalEditListPanel.editKeyword.title=Edit Keyword
|
||||
GlobalEditListPanel.warning.text=Boundary characters ^ and $ do not match word boundaries. Consider\nreplacing with an explicit list of boundary characters, such as [ \\.,]
|
||||
@ -91,8 +88,8 @@ AbstractKeywordSearchPerformer.search.invalidSyntaxHeader=Invalid query statemen
|
||||
AbstractKeywordSearchPerformer.search.searchIngestInProgressTitle=Keyword Search Ingest in Progress
|
||||
AbstractKeywordSearchPerformer.search.ingestInProgressBody=<html>Keyword Search Ingest is currently running.<br />Not all files have been indexed and this search might yield incomplete results.<br />Do you want to proceed with this search anyway?</html>
|
||||
AbstractKeywordSearchPerformer.search.emptyKeywordErrorBody=Keyword list is empty, please add at least one keyword to the list
|
||||
AbstractKeywordSearchPerformer.search.noFilesInIdxMsg=<html>No files are in index yet. <br />Try again later. Index is updated every {0} minutes.</html>
|
||||
AbstractKeywordSearchPerformer.search.noFilesIdxdMsg=<html>No files were indexed.<br />Re-ingest the image with the Keyword Search Module enabled. </html>
|
||||
AbstractKeywordSearchPerformer.search.noFilesInIdxMsg=<html>No files are in index yet. <br />If Solr keyword search indexing was enabled, wait for ingest to complete</html>
|
||||
AbstractKeywordSearchPerformer.search.noFilesIdxdMsg=<html>No files were indexed.<br />Re-ingest the image with the Keyword Search Module and Solr indexing enabled. </html>
|
||||
ExtractedContentViewer.toolTip=Displays extracted text from files and keyword-search results. Requires Keyword Search ingest to be run on a file to activate this viewer.
|
||||
ExtractedContentViewer.getTitle=Indexed Text
|
||||
HighlightedMatchesSource.toString=Search Results
|
||||
@ -176,7 +173,7 @@ KeywordSearchListsManagementPanel.fileExtensionFilterLbl=Autopsy Keyword List Fi
|
||||
KeywordSearchListsManagementPanel.fileExtensionFilterLb2=Encase Keyword List File (txt)
|
||||
KeywordSearch.listImportFeatureTitle=Keyword List Import
|
||||
KeywordSearchIngestModule.moduleName=Keyword Search
|
||||
KeywordSearchIngestModule.moduleDescription=Performs file indexing and periodic search using keywords and regular expressions in lists.
|
||||
KeywordSearchIngestModule.moduleDescription=Performs file indexing and search using selected keyword lists.
|
||||
DropdownSearchPanel.keywordTextField.text=
|
||||
KeywordSearchPanel.searchDropButton.text=Keyword Search
|
||||
DropdownSearchPanel.exactRadioButton.text=Exact Match
|
||||
@ -227,8 +224,6 @@ KeywordSearchSettings.properties_options.text={0}_Options
|
||||
KeywordSearchSettings.propertiesNSRL.text={0}_NSRL
|
||||
KeywordSearchSettings.propertiesScripts.text={0}_Scripts
|
||||
NoOpenCoreException.err.noOpenSorlCore.msg=No currently open Solr core.
|
||||
SearchRunner.query.exception.msg=Error performing query:
|
||||
# {0} - colelction name
|
||||
Server.deleteCore.exception.msg=Failed to delete Solr colelction {0}
|
||||
Server.exceptionMessage.unableToBackupCollection=Unable to backup Solr collection
|
||||
Server.exceptionMessage.unableToCreateCollection=Unable to create Solr collection
|
||||
@ -272,11 +267,6 @@ KeywordSearchGlobalLanguageSettingsPanel.enableUTF8Checkbox.text=Enable UTF8 tex
|
||||
KeywordSearchGlobalLanguageSettingsPanel.ingestSettingsLabel.text=Ingest settings for string extraction from unknown file types (changes effective on next ingest):
|
||||
KeywordSearchGlobalLanguageSettingsPanel.enableUTF16Checkbox.text=Enable UTF16LE and UTF16BE string extraction
|
||||
KeywordSearchGlobalLanguageSettingsPanel.languagesLabel.text=Enabled scripts (languages):
|
||||
KeywordSearchGlobalSearchSettingsPanel.timeRadioButton1.toolTipText=20 mins. (fastest ingest time)
|
||||
KeywordSearchGlobalSearchSettingsPanel.timeRadioButton1.text=20 minutes (slowest feedback, fastest ingest)
|
||||
KeywordSearchGlobalSearchSettingsPanel.timeRadioButton2.toolTipText=10 minutes (faster overall ingest time than default)
|
||||
KeywordSearchGlobalSearchSettingsPanel.timeRadioButton2.text=10 minutes (slower feedback, faster ingest)
|
||||
KeywordSearchGlobalSearchSettingsPanel.frequencyLabel.text=Results update frequency during ingest:
|
||||
KeywordSearchGlobalSearchSettingsPanel.skipNSRLCheckBox.toolTipText=Requires Hash Set service to had run previously, or be selected for next ingest.
|
||||
KeywordSearchGlobalSearchSettingsPanel.skipNSRLCheckBox.text=Do not add files in NSRL (known files) to keyword index during ingest
|
||||
KeywordSearchGlobalSearchSettingsPanel.informationLabel.text=Information
|
||||
@ -285,11 +275,7 @@ KeywordSearchGlobalSearchSettingsPanel.filesIndexedValue.text=0
|
||||
KeywordSearchGlobalSearchSettingsPanel.filesIndexedLabel.text=Files in keyword index:
|
||||
KeywordSearchGlobalSearchSettingsPanel.showSnippetsCB.text=Show Keyword Preview in Keyword Search Results (will result in longer search times)
|
||||
KeywordSearchGlobalSearchSettingsPanel.chunksValLabel.text=0
|
||||
KeywordSearchGlobalSearchSettingsPanel.timeRadioButton4.toolTipText=1 minute (overall ingest time will be longest)
|
||||
KeywordSearchGlobalSearchSettingsPanel.timeRadioButton4.text_1=1 minute (faster feedback, longest ingest)
|
||||
KeywordSearchGlobalSearchSettingsPanel.chunksLabel.text=Chunks in keyword index:
|
||||
KeywordSearchGlobalSearchSettingsPanel.timeRadioButton3.toolTipText=5 minutes (overall ingest time will be longer)
|
||||
KeywordSearchGlobalSearchSettingsPanel.timeRadioButton3.text=5 minutes (default)
|
||||
KeywordSearchIngestModule.regExpHitLbl=Reg Ex hit:
|
||||
KeywordSearchIngestModule.kwHitLbl=Keyword hit:
|
||||
KeywordSearchIngestModule.kwHitThLbl=Keyword
|
||||
@ -315,8 +301,6 @@ KeywordSearchListsManagementPanel.newKeywordListDescription2=Keyword list <{0}>
|
||||
KeywordSearchModuleFactory.getIngestJobSettingsPanel.exception.msg=Expected settings argument to be instanceof KeywordSearchJobSettings
|
||||
KeywordSearchModuleFactory.createFileIngestModule.exception.msg=Expected settings argument to be instanceof KeywordSearchJobSettings
|
||||
SearchRunner.Searcher.done.err.msg=Error performing keyword search
|
||||
KeywordSearchGlobalSearchSettingsPanel.timeRadioButton5.toolTipText=Fastest overall, but no results until the end
|
||||
KeywordSearchGlobalSearchSettingsPanel.timeRadioButton5.text=No periodic searches
|
||||
Server.status.failed.msg=Local Solr server did not respond to status request. This may be because the server failed to start or is taking too long to initialize.
|
||||
SolrConnectionCheck.HostnameOrPort=Invalid hostname and/or port number.
|
||||
SolrConnectionCheck.Hostname=Invalid hostname.
|
||||
@ -371,7 +355,6 @@ SolrSearchService.exceptionMessage.noCurrentSolrCore=IndexMetadata did not conta
|
||||
SolrSearchService.exceptionMessage.noIndexMetadata=Unable to create IndexMetaData from case directory: {0}
|
||||
# {0} - collection name
|
||||
SolrSearchService.exceptionMessage.unableToDeleteCollection=Unable to delete collection {0}
|
||||
SolrSearchService.indexingError=Unable to index blackboard artifact.
|
||||
SolrSearchService.ServiceName=Solr Keyword Search Service
|
||||
SolrSearchService.DeleteDataSource.msg=Error Deleting Solr data for data source id {0}
|
||||
DropdownSingleTermSearchPanel.dataSourceCheckBox.text=Restrict search to the selected data sources:
|
||||
@ -405,6 +388,7 @@ ExtractedContentPanel.pagesLabel.text=Page:
|
||||
KeywordSearchJobSettingsPanel.ocrCheckBox.text=Enable Optical Character Recognition (OCR)
|
||||
KeywordSearchJobSettingsPanel.limitedOcrCheckbox.text=<html>Only process PDFs, MS Office docs and images which are over 100KB in size or extracted from another file (Beta)</html>
|
||||
KeywordSearchJobSettingsPanel.ocrOnlyCheckbox.text=Only index text extracted using OCR
|
||||
KeywordSearchJobSettingsPanel.solrCheckbox.text=Add text to Solr Index
|
||||
TextZoomPanel.zoomInButton.text=
|
||||
TextZoomPanel.zoomOutButton.text=
|
||||
TextZoomPanel.zoomResetButton.text=Reset
|
||||
|
@ -7,8 +7,6 @@ AbstractKeywordSearchPerformer.search.dialogErrorHeader=\u30ad\u30fc\u30ef\u30fc
|
||||
AbstractKeywordSearchPerformer.search.emptyKeywordErrorBody=\u30ad\u30fc\u30ef\u30fc\u30c9\u30ea\u30b9\u30c8\u304c\u7a7a(\u672a\u5165\u529b)\u3067\u3059\u3002\u5c11\u306a\u304f\u3068\u30821\u3064\u306e\u30ad\u30fc\u30ef\u30fc\u30c9\u3092\u30ea\u30b9\u30c8\u306b\u8ffd\u52a0\u3057\u3066\u304f\u3060\u3055\u3044\u3002
|
||||
AbstractKeywordSearchPerformer.search.ingestInProgressBody=<html>\u30ad\u30fc\u30ef\u30fc\u30c9\u691c\u7d22\u30a4\u30f3\u30b8\u30a7\u30b9\u30c8\u304c\u73fe\u5728\u5b9f\u884c\u4e2d\u3067\u3059\u3002<br />\u3059\u3079\u3066\u306e\u30d5\u30a1\u30a4\u30eb\u304c\u30a4\u30f3\u30c7\u30c3\u30af\u30b9\u3055\u308c\u306a\u304b\u3063\u305f\u305f\u3081\u3001\u3053\u306e\u691c\u7d22\u306f\u4e0d\u5b8c\u5168\u306a\u7d50\u679c\u3092\u751f\u6210\u3059\u308b\u53ef\u80fd\u6027\u304c\u3042\u308a\u307e\u3059\u3002<br />\u305d\u308c\u3067\u3082\u3053\u306e\u691c\u7d22\u3092\u7d9a\u884c\u3057\u307e\u3059\u304b?</html>
|
||||
AbstractKeywordSearchPerformer.search.invalidSyntaxHeader=\u7121\u52b9\u306a\u30af\u30a8\u30ea\u30fb\u30b9\u30c6\u30fc\u30c8\u30e1\u30f3\u30c8\u3002 \u5185\u5bb9\u304c\u6b63\u898f\u8868\u73fe\u306e\u5834\u5408\u3001Lucene\u6b63\u898f\u8868\u73fe\u30d1\u30bf\u30fc\u30f3\u306e\u307f\u304c\u30b5\u30dd\u30fc\u30c8\u3055\u308c\u307e\u3059\u3002 POSIX\u6587\u5b57\u30af\u30e9\u30b9\uff08\\ n\u3084\\ w\u306a\u3069\uff09\u306f\u7121\u52b9\u3067\u3059\u3002
|
||||
AbstractKeywordSearchPerformer.search.noFilesIdxdMsg=<html>\u30d5\u30a1\u30a4\u30eb\u304c\u30a4\u30f3\u30c7\u30c3\u30af\u30b9\u3055\u308c\u3066\u3044\u307e\u305b\u3093\u3002<br />\u30ad\u30fc\u30ef\u30fc\u30c9\u691c\u7d22\u30e2\u30b8\u30e5\u30fc\u30eb\u3092\u6709\u52b9\u306b\u3057\u305f\u72b6\u614b\u3067\u30a4\u30e1\u30fc\u30b8\u3092\u518d\u30a4\u30f3\u30b8\u30a7\u30b9\u30c8\u3057\u3066\u304f\u3060\u3055\u3044\u3002</html>
|
||||
AbstractKeywordSearchPerformer.search.noFilesInIdxMsg=<html>\u307e\u3060\u30d5\u30a1\u30a4\u30eb\u304c\u7d22\u5f15\u306b\u542b\u307e\u308c\u3066\u3044\u307e\u305b\u3093\u3002<br />\u5f8c\u3067\u3082\u3046\u4e00\u5ea6\u304a\u8a66\u3057\u304f\u3060\u3055\u3044\u3002 \u7d22\u5f15\u306f {0} \u5206\u3054\u3068\u306b\u66f4\u65b0\u3055\u308c\u307e\u3059\u3002</html>
|
||||
AbstractKeywordSearchPerformer.search.searchIngestInProgressTitle=\u30ad\u30fc\u30ef\u30fc\u30c9\u691c\u7d22\u30a4\u30f3\u30b8\u30a7\u30b9\u30c8\u304c\u9032\u884c\u4e2d\u3067\u3059
|
||||
AccountsText.creditCardNumber=\u30af\u30ec\u30b8\u30c3\u30c8\u30ab\u30fc\u30c9\u756a\u53f7
|
||||
AccountsText.creditCardNumbers=\u30af\u30ec\u30b8\u30c3\u30c8\u30ab\u30fc\u30c9\u756a\u53f7
|
||||
@ -55,8 +53,6 @@ ExtractAllTermsReport.exportComplete=\u30e6\u30cb\u30fc\u30af\u306a\u5358\u8a9e\
|
||||
ExtractAllTermsReport.getName.text=\u30e6\u30cb\u30fc\u30af\u306a\u5358\u8a9e\u3092\u62bd\u51fa\u3059\u308b
|
||||
ExtractAllTermsReport.numberExtractedTerms=\u62bd\u51fa\u3055\u308c\u305f{0}\u7528\u8a9e...
|
||||
ExtractAllTermsReport.search.ingestInProgressBody=<html> \u30ad\u30fc\u30ef\u30fc\u30c9\u691c\u7d22\u8aad\u8fbc\u306f\u73fe\u5728\u5b9f\u884c\u4e2d\u3067\u3059\u3002<br/>\u3059\u3079\u3066\u306e\u30d5\u30a1\u30a4\u30eb\u304c\u30a4\u30f3\u30c7\u30c3\u30af\u30b9\u306b\u767b\u9332\u3055\u308c\u3066\u3044\u308b\u308f\u3051\u3067\u306f\u306a\u304f\u3001\u30e6\u30cb\u30fc\u30af\u306a\u5358\u8a9e\u3092\u62bd\u51fa\u306f\u4e0d\u5b8c\u5168\u306a\u7d50\u679c\u306b\u306a\u308b\u53ef\u80fd\u6027\u304c\u3042\u308a\u307e\u3059\u3002<br />\u305d\u308c\u3067\u3082\u30e6\u30cb\u30fc\u30af\u306a\u5358\u8a9e\u306e\u62bd\u51fa\u3092\u7d9a\u884c\u3057\u307e\u3059\u304b\uff1f</ html>
|
||||
ExtractAllTermsReport.search.noFilesInIdxMsg=\u307e\u3060\u30a4\u30f3\u30c7\u30c3\u30af\u30b9\u306b\u767b\u9332\u3055\u308c\u3066\u3044\u308b\u30d5\u30a1\u30a4\u30eb\u306f\u3042\u308a\u307e\u305b\u3093\u3002 \u3042\u3068\u3067\u3082\u3046\u4e00\u5ea6\u8a66\u3057\u3066\u307f\u3066\u304f\u3060\u3055\u3044\u3002 \u30a4\u30f3\u30c7\u30c3\u30af\u30b9\u306f{0}\u5206\u3054\u3068\u306b\u66f4\u65b0\u3055\u308c\u307e\u3059\u3002
|
||||
ExtractAllTermsReport.search.noFilesInIdxMsg2=\u307e\u3060\u30a4\u30f3\u30c7\u30c3\u30af\u30b9\u306b\u767b\u9332\u3055\u308c\u3066\u3044\u308b\u30d5\u30a1\u30a4\u30eb\u306f\u3042\u308a\u307e\u305b\u3093\u3002 \u3042\u3068\u3067\u3082\u3046\u4e00\u5ea6\u8a66\u3057\u3066\u307f\u3066\u304f\u3060\u3055\u3044\u3002
|
||||
ExtractAllTermsReport.search.searchIngestInProgressTitle=\u30ad\u30fc\u30ef\u30fc\u30c9\u691c\u7d22\u30a4\u30f3\u30b8\u30a7\u30b9\u30c8\u304c\u9032\u884c\u4e2d\u3067\u3059
|
||||
ExtractAllTermsReport.startExport=\u30e6\u30cb\u30fc\u30af\u306a\u5358\u8a9e\u62bd\u51fa\u306e\u958b\u59cb
|
||||
ExtractedContentPanel.SetMarkup.progress.loading={0} \u306e\u30c6\u30ad\u30b9\u30c8\u3092\u8aad\u307f\u8fbc\u3093\u3067\u3044\u307e\u3059
|
||||
@ -210,23 +206,12 @@ KeywordSearchGlobalSearchSettingsPanel.customizeComponents.windowsLimitedOCR=\u3
|
||||
KeywordSearchGlobalSearchSettingsPanel.customizeComponents.windowsOCR=OCR\u6587\u5b57\u8a8d\u8b58\u3092\u6709\u52b9\u306b\u3059\u308b\uff08Windows 64\u30d3\u30c3\u30c8\u304c\u5fc5\u8981\uff09
|
||||
KeywordSearchGlobalSearchSettingsPanel.filesIndexedLabel.text=\u30ad\u30fc\u30ef\u30fc\u30c9\u7d22\u5f15\u5185\u306e\u30d5\u30a1\u30a4\u30eb\:
|
||||
KeywordSearchGlobalSearchSettingsPanel.filesIndexedValue.text=0
|
||||
KeywordSearchGlobalSearchSettingsPanel.frequencyLabel.text=\u30a4\u30f3\u30b8\u30a7\u30b9\u30c8\u4e2d\u306e\u7d50\u679c\u66f4\u65b0\u983b\u5ea6\:
|
||||
KeywordSearchGlobalSearchSettingsPanel.informationLabel.text=\u60c5\u5831
|
||||
KeywordSearchGlobalSearchSettingsPanel.ingestWarningLabel.text=\u30a4\u30f3\u30b8\u30a7\u30b9\u30c8\u304c\u9032\u884c\u4e2d\u3067\u3059\u3002\u30a4\u30f3\u30b8\u30a7\u30b9\u30c8\u304c\u5b8c\u4e86\u3059\u308b\u307e\u3067\u4e00\u90e8\u306e\u8a2d\u5b9a\u3092\u5229\u7528\u3067\u304d\u307e\u305b\u3093\u3002
|
||||
KeywordSearchGlobalSearchSettingsPanel.settingsLabel.text=\u8a2d\u5b9a
|
||||
KeywordSearchGlobalSearchSettingsPanel.showSnippetsCB.text=\u30ad\u30fc\u30ef\u30fc\u30c9\u691c\u7d22\u7d50\u679c\u306b\u30ad\u30fc\u30ef\u30fc\u30c9\u30d7\u30ec\u30d3\u30e5\u30fc\u3092\u8868\u793a(\u691c\u7d22\u6642\u9593\u304c\u9577\u304f\u306a\u308a\u307e\u3059)
|
||||
KeywordSearchGlobalSearchSettingsPanel.skipNSRLCheckBox.text=\u30a4\u30f3\u30b8\u30a7\u30b9\u30c8\u4e2d\u306bNSRL(\u65e2\u77e5\u306e\u30d5\u30a1\u30a4\u30eb)\u306e\u30d5\u30a1\u30a4\u30eb\u3092\u30ad\u30fc\u30ef\u30fc\u30c9\u306b\u8ffd\u52a0\u3057\u306a\u3044\u3067\u304f\u3060\u3055\u3044
|
||||
KeywordSearchGlobalSearchSettingsPanel.skipNSRLCheckBox.toolTipText=\u30cf\u30c3\u30b7\u30e5\u30bb\u30c3\u30c8\u30b5\u30fc\u30d3\u30b9\u306b\u4ee5\u524d\u306b\u5b9f\u884c\u6e08\u307f\u3067\u3042\u308b\u3053\u3068\u3001\u307e\u305f\u306f\u6b21\u306e\u30a4\u30f3\u30b8\u30a7\u30b9\u30c8\u306b\u9078\u629e\u3055\u308c\u308b\u3053\u3068\u3092\u8981\u6c42\u3057\u307e\u3059\u3002
|
||||
KeywordSearchGlobalSearchSettingsPanel.timeRadioButton1.text=20\u5206(\u6700\u9045\u30d5\u30a3\u30fc\u30c9\u30d0\u30c3\u30af\u3001\u6700\u901f\u30a4\u30f3\u30b8\u30a7\u30b9\u30c8)
|
||||
KeywordSearchGlobalSearchSettingsPanel.timeRadioButton1.toolTipText=20\u5206(\u6700\u901f\u30a4\u30f3\u30b8\u30a7\u30b9\u30c8\u6642\u9593)
|
||||
KeywordSearchGlobalSearchSettingsPanel.timeRadioButton2.text=10\u5206(\u3088\u308a\u9045\u3044\u30d5\u30a3\u30fc\u30c9\u30d0\u30c3\u30af\u3001\u3088\u308a\u901f\u3044\u30a4\u30f3\u30b8\u30a7\u30b9\u30c8)
|
||||
KeywordSearchGlobalSearchSettingsPanel.timeRadioButton2.toolTipText=10\u5206(\u30c7\u30d5\u30a9\u30eb\u30c8\u3088\u308a\u3082\u901f\u3044\u7dcf\u30a4\u30f3\u30b8\u30a7\u30b9\u30c8\u6642\u9593)
|
||||
KeywordSearchGlobalSearchSettingsPanel.timeRadioButton3.text=5\u5206(\u30c7\u30d5\u30a9\u30eb\u30c8)
|
||||
KeywordSearchGlobalSearchSettingsPanel.timeRadioButton3.toolTipText=5\u5206(\u7dcf\u30a4\u30f3\u30b8\u30a7\u30b9\u30c8\u6642\u9593\u304c\u9577\u304f\u306a\u308a\u307e\u3059)
|
||||
KeywordSearchGlobalSearchSettingsPanel.timeRadioButton4.text_1=1\u5206(\u3088\u308a\u901f\u3044\u30d5\u30a3\u30fc\u30c9\u30d0\u30c3\u30af\u3001\u6700\u9577\u306e\u30a4\u30f3\u30b8\u30a7\u30b9\u30c8)
|
||||
KeywordSearchGlobalSearchSettingsPanel.timeRadioButton4.toolTipText=1\u5206(\u7dcf\u30a4\u30f3\u30b8\u30a7\u30b9\u30c8\u6642\u9593\u306f\u6700\u9577\u306b\u306a\u308a\u307e\u3059)
|
||||
KeywordSearchGlobalSearchSettingsPanel.timeRadioButton5.text=\u5b9a\u671f\u691c\u7d22\u306a\u3057
|
||||
KeywordSearchGlobalSearchSettingsPanel.timeRadioButton5.toolTipText=\u5168\u4f53\u3067\u6700\u901f\u3067\u3059\u304c\u3001\u6700\u5f8c\u307e\u3067\u7d50\u679c\u306f\u8868\u793a\u3055\u308c\u307e\u305b\u3093
|
||||
KeywordSearchGlobalSettingsPanel.Title=\u30ad\u30fc\u30ef\u30fc\u30c9\u4e00\u62ec\u691c\u7d22\u8a2d\u5b9a
|
||||
KeywordSearchIngestModule.doInBackGround.displayName=\u30ad\u30fc\u30ef\u30fc\u30c9\u5b9a\u671f\u691c\u7d22
|
||||
KeywordSearchIngestModule.doInBackGround.finalizeMsg=\u78ba\u5b9a
|
||||
@ -271,7 +256,6 @@ KeywordSearchJobSettingsPanel.languagesValLabel.toolTipText=
|
||||
KeywordSearchJobSettingsPanel.limitedOcrCheckbox.text=<html>\u51e6\u7406\u3092\u3059\u308bPDF\u3001MS Office\u30c9\u30ad\u30e5\u30e1\u30f3\u30c8\u3001\u3068\u753b\u50cf\u306f100KB\u4ee5\u4e0a\u304b\u307e\u305f\u306f\u30d5\u30a1\u30a4\u30eb\u304b\u3089\u62bd\u51fa\u3057\u305f\u3082\u306e\uff08\u30d9\u30fc\u30bf\u6a5f\u80fd\uff09\u306b\u5236\u9650\u3057\u307e\u3059\u3002</ html>
|
||||
KeywordSearchJobSettingsPanel.ocrCheckBox.text=OCR\u3092\u6709\u52b9\u306b\u3059\u308b
|
||||
KeywordSearchJobSettingsPanel.ocrOnlyCheckbox.text=OCR\u3092\u4f7f\u7528\u3057\u3066\u62bd\u51fa\u3055\u308c\u305f\u30a4\u30f3\u30c7\u30c3\u30af\u30b9\u30fb\u30c6\u30ad\u30b9\u30c8\u306e\u307f
|
||||
KeywordSearchJobSettingsPanel.titleLabel.text=\u30a4\u30f3\u30b8\u30a7\u30b9\u30c8\u4e2d\u306b\u6709\u52b9\u5316\u3059\u308b\u30ad\u30fc\u30ef\u30fc\u30c9\u30ea\u30b9\u30c8\u3092\u9078\u629e\:
|
||||
KeywordSearchListsAbstract.addList.errMsg1.msg=KeywordSearchListsAbstract\u66f4\u65b0\u306e\u30ea\u30c3\u30b9\u30f3\u4e2d\u306b\u30e2\u30b8\u30e5\u30fc\u30eb\u304c\u30a8\u30e9\u30fc\u3092\u767a\u751f\u3055\u305b\u307e\u3057\u305f\u3002\u30ed\u30b0\u3092\u78ba\u8a8d\u3057\u3066\u3069\u306e\u30e2\u30b8\u30e5\u30fc\u30eb\u304c\u5224\u65ad\u3057\u3066\u304f\u3060\u3055\u3044\u3002\u4e00\u90e8\u306e\u30c7\u30fc\u30bf\u304c\u4e0d\u5b8c\u5168\u3067\u3042\u308b\u53ef\u80fd\u6027\u304c\u3042\u308a\u307e\u3059\u3002
|
||||
KeywordSearchListsAbstract.addList.errMsg2.msg=KeywordSearchListsAbstract\u66f4\u65b0\u306e\u30ea\u30c3\u30b9\u30f3\u4e2d\u306b\u30e2\u30b8\u30e5\u30fc\u30eb\u304c\u30a8\u30e9\u30fc\u3092\u767a\u751f\u3055\u305b\u307e\u3057\u305f\u3002\u30ed\u30b0\u3092\u78ba\u8a8d\u3057\u3066\u3069\u306e\u30e2\u30b8\u30e5\u30fc\u30eb\u304c\u5224\u65ad\u3057\u3066\u304f\u3060\u3055\u3044\u3002\u4e00\u90e8\u306e\u30c7\u30fc\u30bf\u304c\u4e0d\u5b8c\u5168\u3067\u3042\u308b\u53ef\u80fd\u6027\u304c\u3042\u308a\u307e\u3059\u3002
|
||||
KeywordSearchListsAbstract.deleteList.errMsg1.msg=KeywordSearchListsAbstract\u66f4\u65b0\u306e\u30ea\u30c3\u30b9\u30f3\u4e2d\u306b\u30e2\u30b8\u30e5\u30fc\u30eb\u304c\u30a8\u30e9\u30fc\u3092\u767a\u751f\u3055\u305b\u307e\u3057\u305f\u3002\u30ed\u30b0\u3092\u78ba\u8a8d\u3057\u3066\u3069\u306e\u30e2\u30b8\u30e5\u30fc\u30eb\u304c\u5224\u65ad\u3057\u3066\u304f\u3060\u3055\u3044\u3002\u4e00\u90e8\u306e\u30c7\u30fc\u30bf\u304c\u4e0d\u5b8c\u5168\u3067\u3042\u308b\u53ef\u80fd\u6027\u304c\u3042\u308a\u307e\u3059\u3002
|
||||
|
@ -398,6 +398,8 @@ class Chunker implements Iterator<Chunk>, Iterable<Chunk> {
|
||||
private final StringBuilder sb;
|
||||
private final int baseChunkSizeChars;
|
||||
private final StringBuilder lowerCasedChunk;
|
||||
private boolean hasHit = false;
|
||||
private int chunkId = 0;
|
||||
|
||||
Chunk(StringBuilder sb, int baseChunkSizeChars, StringBuilder lowerCasedChunk) {
|
||||
this.sb = sb;
|
||||
@ -420,7 +422,7 @@ class Chunker implements Iterator<Chunk>, Iterable<Chunk> {
|
||||
*
|
||||
* @return The content of the chunk.
|
||||
*/
|
||||
public String geLowerCasedChunk() {
|
||||
public String getLowerCasedChunk() {
|
||||
return lowerCasedChunk.toString();
|
||||
}
|
||||
|
||||
@ -432,5 +434,21 @@ class Chunker implements Iterator<Chunk>, Iterable<Chunk> {
|
||||
int getBaseChunkLength() {
|
||||
return baseChunkSizeChars;
|
||||
}
|
||||
|
||||
boolean hasHit() {
|
||||
return hasHit;
|
||||
}
|
||||
|
||||
void setHasHit(boolean b) {
|
||||
hasHit = b;
|
||||
}
|
||||
|
||||
void setChunkId(int id) {
|
||||
chunkId = id;
|
||||
}
|
||||
|
||||
int getChunkId() {
|
||||
return chunkId;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
/*
|
||||
* Autopsy Forensic Browser
|
||||
*
|
||||
* Copyright 2011-2018 Basis Technology Corp.
|
||||
* Copyright 2011-2022 Basis Technology Corp.
|
||||
* Contact: carrier <at> sleuthkit <dot> org
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
@ -30,7 +30,6 @@ import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.logging.Level;
|
||||
import javax.swing.JCheckBox;
|
||||
import javax.swing.JTable;
|
||||
import javax.swing.ListSelectionModel;
|
||||
@ -143,10 +142,7 @@ class DropdownListSearchPanel extends AdHocSearchPanel {
|
||||
searchAddListener = new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
if (ingestRunning) {
|
||||
IngestSearchRunner.getInstance().addKeywordListsToAllJobs(listsTableModel.getSelectedLists());
|
||||
logger.log(Level.INFO, "Submitted enqueued lists to ingest"); //NON-NLS
|
||||
} else {
|
||||
if (!ingestRunning) {
|
||||
searchAction(e);
|
||||
}
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
/*
|
||||
* Autopsy Forensic Browser
|
||||
*
|
||||
* Copyright 2021 Basis Technology Corp.
|
||||
* Copyright 2022 Basis Technology Corp.
|
||||
* Contact: carrier <at> sleuthkit <dot> org
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
@ -51,9 +51,8 @@ public class ExtractAllTermsReport implements GeneralReportModule {
|
||||
|
||||
@NbBundle.Messages({
|
||||
"ExtractAllTermsReport.error.noOpenCase=No currently open case.",
|
||||
"# {0} - Keyword search commit frequency",
|
||||
"ExtractAllTermsReport.search.noFilesInIdxMsg=No files are in index yet. Try again later. Index is updated every {0} minutes.",
|
||||
"ExtractAllTermsReport.search.noFilesInIdxMsg2=No files are in index yet. Try again later",
|
||||
"ExtractAllTermsReport.search.noFilesInIdxMsg=No files are in index yet. If Solr keyword search indexing and Solr indexing were enabled, wait for ingest to complete.",
|
||||
"ExtractAllTermsReport.search.noFilesInIdxMsg2=No files are in index yet. Re-ingest the image with the Keyword Search Module and Solr indexing enabled.",
|
||||
"ExtractAllTermsReport.search.searchIngestInProgressTitle=Keyword Search Ingest in Progress",
|
||||
"ExtractAllTermsReport.search.ingestInProgressBody=<html>Keyword Search Ingest is currently running.<br />Not all files have been indexed and unique word extraction might yield incomplete results.<br />Do you want to proceed with unique word extraction anyway?</html>",
|
||||
"ExtractAllTermsReport.startExport=Starting Unique Word Extraction",
|
||||
@ -83,7 +82,7 @@ public class ExtractAllTermsReport implements GeneralReportModule {
|
||||
|
||||
if (filesIndexed == 0) {
|
||||
if (isIngestRunning) {
|
||||
progressPanel.complete(ReportProgressPanel.ReportStatus.ERROR, Bundle.ExtractAllTermsReport_search_noFilesInIdxMsg(KeywordSearchSettings.getUpdateFrequency().getTime()));
|
||||
progressPanel.complete(ReportProgressPanel.ReportStatus.ERROR, Bundle.ExtractAllTermsReport_search_noFilesInIdxMsg());
|
||||
} else {
|
||||
progressPanel.complete(ReportProgressPanel.ReportStatus.ERROR, Bundle.ExtractAllTermsReport_search_noFilesInIdxMsg2());
|
||||
}
|
||||
|
@ -1,705 +0,0 @@
|
||||
/*
|
||||
* Autopsy Forensic Browser
|
||||
*
|
||||
* Copyright 2014 - 2021 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.keywordsearch;
|
||||
|
||||
import com.google.common.util.concurrent.ThreadFactoryBuilder;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.CancellationException;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.Future;
|
||||
import java.util.concurrent.ScheduledThreadPoolExecutor;
|
||||
import static java.util.concurrent.TimeUnit.MILLISECONDS;
|
||||
import java.util.concurrent.atomic.AtomicLong;
|
||||
import java.util.logging.Level;
|
||||
import javax.annotation.concurrent.GuardedBy;
|
||||
import javax.swing.SwingUtilities;
|
||||
import javax.swing.SwingWorker;
|
||||
import org.netbeans.api.progress.ProgressHandle;
|
||||
import org.openide.util.Cancellable;
|
||||
import org.openide.util.NbBundle;
|
||||
import org.openide.util.NbBundle.Messages;
|
||||
import org.sleuthkit.autopsy.core.RuntimeProperties;
|
||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||
import org.sleuthkit.autopsy.coreutils.MessageNotifyUtil;
|
||||
import org.sleuthkit.autopsy.coreutils.StopWatch;
|
||||
import org.sleuthkit.autopsy.coreutils.ThreadConfined;
|
||||
import org.sleuthkit.autopsy.ingest.IngestJobContext;
|
||||
import org.sleuthkit.autopsy.ingest.IngestMessage;
|
||||
import org.sleuthkit.autopsy.ingest.IngestServices;
|
||||
|
||||
/**
|
||||
* Performs periodic and final keyword searches for ingest jobs. Periodic
|
||||
* searches are done in background tasks. This represents a careful working
|
||||
* around of the contract for IngestModule.process(). Final searches are done
|
||||
* synchronously in the calling thread, as required by the contract for
|
||||
* IngestModule.shutDown().
|
||||
*/
|
||||
final class IngestSearchRunner {
|
||||
|
||||
private static final Logger logger = Logger.getLogger(IngestSearchRunner.class.getName());
|
||||
private static IngestSearchRunner instance = null;
|
||||
private final IngestServices services = IngestServices.getInstance();
|
||||
private Ingester ingester = null;
|
||||
private long currentUpdateIntervalMs;
|
||||
private volatile boolean periodicSearchTaskRunning;
|
||||
private volatile Future<?> periodicSearchTaskHandle;
|
||||
private final ScheduledThreadPoolExecutor periodicSearchTaskExecutor;
|
||||
private static final int NUM_SEARCH_SCHEDULING_THREADS = 1;
|
||||
private static final String SEARCH_SCHEDULER_THREAD_NAME = "periodic-search-scheduling-%d";
|
||||
private final Map<Long, SearchJobInfo> jobs = new ConcurrentHashMap<>(); // Ingest job ID to search job info
|
||||
private final boolean usingNetBeansGUI = RuntimeProperties.runningWithGUI();
|
||||
|
||||
/*
|
||||
* Constructs a singleton object that performs periodic and final keyword
|
||||
* searches for ingest jobs. Periodic searches are done in background tasks.
|
||||
* This represents a careful working around of the contract for
|
||||
* IngestModule.process(). Final searches are done synchronously in the
|
||||
* calling thread, as required by the contract for IngestModule.shutDown().
|
||||
*/
|
||||
private IngestSearchRunner() {
|
||||
currentUpdateIntervalMs = ((long) KeywordSearchSettings.getUpdateFrequency().getTime()) * 60 * 1000;
|
||||
ingester = Ingester.getDefault();
|
||||
periodicSearchTaskExecutor = new ScheduledThreadPoolExecutor(NUM_SEARCH_SCHEDULING_THREADS, new ThreadFactoryBuilder().setNameFormat(SEARCH_SCHEDULER_THREAD_NAME).build());
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the ingest search runner singleton.
|
||||
*
|
||||
* @return The ingest search runner.
|
||||
*/
|
||||
public static synchronized IngestSearchRunner getInstance() {
|
||||
if (instance == null) {
|
||||
instance = new IngestSearchRunner();
|
||||
}
|
||||
return instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* Starts the search job for an ingest job.
|
||||
*
|
||||
* @param jobContext The ingest job context.
|
||||
* @param keywordListNames The names of the keyword search lists for the
|
||||
* ingest job.
|
||||
*/
|
||||
public synchronized void startJob(IngestJobContext jobContext, List<String> keywordListNames) {
|
||||
long jobId = jobContext.getJobId();
|
||||
if (jobs.containsKey(jobId) == false) {
|
||||
SearchJobInfo jobData = new SearchJobInfo(jobContext, keywordListNames);
|
||||
jobs.put(jobId, jobData);
|
||||
}
|
||||
|
||||
/*
|
||||
* Keep track of the number of keyword search file ingest modules that
|
||||
* are doing analysis for the ingest job, i.e., that have called this
|
||||
* method. This is needed by endJob().
|
||||
*/
|
||||
jobs.get(jobId).incrementModuleReferenceCount();
|
||||
|
||||
/*
|
||||
* Start a periodic search task in the
|
||||
*/
|
||||
if ((jobs.size() > 0) && (periodicSearchTaskRunning == false)) {
|
||||
currentUpdateIntervalMs = ((long) KeywordSearchSettings.getUpdateFrequency().getTime()) * 60 * 1000;
|
||||
periodicSearchTaskHandle = periodicSearchTaskExecutor.schedule(new PeriodicSearchTask(), currentUpdateIntervalMs, MILLISECONDS);
|
||||
periodicSearchTaskRunning = true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Finishes a search job for an ingest job.
|
||||
*
|
||||
* @param jobId The ingest job ID.
|
||||
*/
|
||||
public synchronized void endJob(long jobId) {
|
||||
/*
|
||||
* Only complete the job if this is the last keyword search file ingest
|
||||
* module doing annalysis for this job.
|
||||
*/
|
||||
SearchJobInfo job;
|
||||
job = jobs.get(jobId);
|
||||
if (job == null) {
|
||||
return; // RJCTODO: SEVERE
|
||||
}
|
||||
if (job.decrementModuleReferenceCount() != 0) {
|
||||
jobs.remove(jobId);
|
||||
}
|
||||
|
||||
/*
|
||||
* Commit the index and do the final search. The final search is done in
|
||||
* the ingest thread that shutDown() on the keyword search file ingest
|
||||
* module, per the contract of IngestModule.shutDwon().
|
||||
*/
|
||||
logger.log(Level.INFO, "Commiting search index before final search for search job {0}", job.getJobId()); //NON-NLS
|
||||
commit();
|
||||
logger.log(Level.INFO, "Starting final search for search job {0}", job.getJobId()); //NON-NLS
|
||||
doFinalSearch(job);
|
||||
logger.log(Level.INFO, "Final search for search job {0} completed", job.getJobId()); //NON-NLS
|
||||
|
||||
if (jobs.isEmpty()) {
|
||||
cancelPeriodicSearchSchedulingTask();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Stops the search job for an ingest job.
|
||||
*
|
||||
* @param jobId The ingest job ID.
|
||||
*/
|
||||
public synchronized void stopJob(long jobId) {
|
||||
logger.log(Level.INFO, "Stopping search job {0}", jobId); //NON-NLS
|
||||
commit();
|
||||
|
||||
SearchJobInfo job;
|
||||
job = jobs.get(jobId);
|
||||
if (job == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Request cancellation of the current keyword search, whether it is a
|
||||
* preiodic search or a final search.
|
||||
*/
|
||||
IngestSearchRunner.Searcher currentSearcher = job.getCurrentSearcher();
|
||||
if ((currentSearcher != null) && (!currentSearcher.isDone())) {
|
||||
logger.log(Level.INFO, "Cancelling search job {0}", jobId); //NON-NLS
|
||||
currentSearcher.cancel(true);
|
||||
}
|
||||
|
||||
jobs.remove(jobId);
|
||||
|
||||
if (jobs.isEmpty()) {
|
||||
cancelPeriodicSearchSchedulingTask();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the given keyword list names to the set of keyword lists to be
|
||||
* searched by ALL keyword search jobs. This supports adding one or more
|
||||
* keyword search lists to ingest jobs already in progress.
|
||||
*
|
||||
* @param keywordListNames The n ames of the additional keyword lists.
|
||||
*/
|
||||
public synchronized void addKeywordListsToAllJobs(List<String> keywordListNames) {
|
||||
for (String listName : keywordListNames) {
|
||||
logger.log(Level.INFO, "Adding keyword list {0} to all jobs", listName); //NON-NLS
|
||||
for (SearchJobInfo j : jobs.values()) {
|
||||
j.addKeywordListName(listName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Commits the Solr index for the current case and publishes an event
|
||||
* indicating the current number of indexed items (this is no longer just
|
||||
* files).
|
||||
*/
|
||||
private void commit() {
|
||||
ingester.commit();
|
||||
|
||||
/*
|
||||
* Publish an event advertising the number of indexed items. Note that
|
||||
* this is no longer the number of indexed files, since the text of many
|
||||
* items in addition to files is indexed.
|
||||
*/
|
||||
try {
|
||||
final int numIndexedFiles = KeywordSearch.getServer().queryNumIndexedFiles();
|
||||
KeywordSearch.fireNumIndexedFilesChange(null, numIndexedFiles);
|
||||
} catch (NoOpenCoreException | KeywordSearchModuleException ex) {
|
||||
logger.log(Level.SEVERE, "Error executing Solr query for number of indexed files", ex); //NON-NLS
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs the final keyword search for an ingest job. The search is done
|
||||
* synchronously, as required by the contract for IngestModule.shutDown().
|
||||
*
|
||||
* @param job The keyword search job info.
|
||||
*/
|
||||
private void doFinalSearch(SearchJobInfo job) {
|
||||
if (!job.getKeywordListNames().isEmpty()) {
|
||||
try {
|
||||
/*
|
||||
* Wait for any periodic searches being done in a SwingWorker
|
||||
* pool thread to finish.
|
||||
*/
|
||||
job.waitForCurrentWorker();
|
||||
IngestSearchRunner.Searcher finalSearcher = new IngestSearchRunner.Searcher(job, true);
|
||||
job.setCurrentSearcher(finalSearcher);
|
||||
/*
|
||||
* Do the final search synchronously on the current ingest
|
||||
* thread, per the contract specified
|
||||
*/
|
||||
finalSearcher.doInBackground();
|
||||
} catch (InterruptedException | CancellationException ex) {
|
||||
logger.log(Level.INFO, "Final search for search job {0} interrupted or cancelled", job.getJobId()); //NON-NLS
|
||||
} catch (Exception ex) {
|
||||
logger.log(Level.SEVERE, String.format("Final search for search job %d failed", job.getJobId()), ex); //NON-NLS
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Cancels the current periodic search scheduling task.
|
||||
*/
|
||||
private synchronized void cancelPeriodicSearchSchedulingTask() {
|
||||
if (periodicSearchTaskHandle != null) {
|
||||
logger.log(Level.INFO, "No more search jobs, stopping periodic search scheduling"); //NON-NLS
|
||||
periodicSearchTaskHandle.cancel(true);
|
||||
periodicSearchTaskRunning = false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Task that runs in ScheduledThreadPoolExecutor to periodically start and
|
||||
* wait for keyword search tasks for each keyword search job in progress.
|
||||
* The keyword search tasks for individual ingest jobs are implemented as
|
||||
* SwingWorkers to support legacy APIs.
|
||||
*/
|
||||
private final class PeriodicSearchTask implements Runnable {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
/*
|
||||
* If there are no more jobs or this task has been cancelled, exit.
|
||||
*/
|
||||
if (jobs.isEmpty() || periodicSearchTaskHandle.isCancelled()) {
|
||||
logger.log(Level.INFO, "Periodic search scheduling task has been cancelled, exiting"); //NON-NLS
|
||||
periodicSearchTaskRunning = false;
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Commit the Solr index for the current case before doing the
|
||||
* searches.
|
||||
*/
|
||||
commit();
|
||||
|
||||
/*
|
||||
* Do a keyword search for each ingest job in progress. When the
|
||||
* searches are done, recalculate the "hold off" time between
|
||||
* searches to prevent back-to-back periodic searches and schedule
|
||||
* the nect periodic search task.
|
||||
*/
|
||||
final StopWatch stopWatch = new StopWatch();
|
||||
stopWatch.start();
|
||||
for (Iterator<Entry<Long, SearchJobInfo>> iterator = jobs.entrySet().iterator(); iterator.hasNext();) {
|
||||
SearchJobInfo job = iterator.next().getValue();
|
||||
|
||||
if (periodicSearchTaskHandle.isCancelled()) {
|
||||
logger.log(Level.INFO, "Periodic search scheduling task has been cancelled, exiting"); //NON-NLS
|
||||
periodicSearchTaskRunning = false;
|
||||
return;
|
||||
}
|
||||
|
||||
if (!job.getKeywordListNames().isEmpty() && !job.isWorkerRunning()) {
|
||||
logger.log(Level.INFO, "Starting periodic search for search job {0}", job.getJobId());
|
||||
Searcher searcher = new Searcher(job, false);
|
||||
job.setCurrentSearcher(searcher);
|
||||
searcher.execute();
|
||||
job.setWorkerRunning(true);
|
||||
try {
|
||||
searcher.get();
|
||||
} catch (InterruptedException | ExecutionException ex) {
|
||||
logger.log(Level.SEVERE, String.format("Error performing keyword search for ingest job %d", job.getJobId()), ex); //NON-NLS
|
||||
services.postMessage(IngestMessage.createErrorMessage(
|
||||
KeywordSearchModuleFactory.getModuleName(),
|
||||
NbBundle.getMessage(this.getClass(), "SearchRunner.Searcher.done.err.msg"), ex.getMessage()));
|
||||
} catch (java.util.concurrent.CancellationException ex) {
|
||||
logger.log(Level.SEVERE, String.format("Keyword search for ingest job %d cancelled", job.getJobId()), ex); //NON-NLS
|
||||
}
|
||||
}
|
||||
}
|
||||
stopWatch.stop();
|
||||
logger.log(Level.INFO, "Periodic searches for all ingest jobs cumulatively took {0} secs", stopWatch.getElapsedTimeSecs()); //NON-NLS
|
||||
recalculateUpdateIntervalTime(stopWatch.getElapsedTimeSecs()); // ELDEBUG
|
||||
periodicSearchTaskHandle = periodicSearchTaskExecutor.schedule(new PeriodicSearchTask(), currentUpdateIntervalMs, MILLISECONDS);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the time interval between periodic keyword searches to avoid
|
||||
* running back-to-back searches. If the most recent round of searches
|
||||
* took longer that 1/4 of the current interval, doubles the interval.
|
||||
*
|
||||
* @param lastSerchTimeSec The time in seconds used to execute the most
|
||||
* recent round of keword searches.
|
||||
*/
|
||||
private void recalculateUpdateIntervalTime(long lastSerchTimeSec) {
|
||||
if (lastSerchTimeSec * 1000 < currentUpdateIntervalMs / 4) {
|
||||
return;
|
||||
}
|
||||
currentUpdateIntervalMs *= 2;
|
||||
logger.log(Level.WARNING, "Last periodic search took {0} sec. Increasing search interval to {1} sec", new Object[]{lastSerchTimeSec, currentUpdateIntervalMs / 1000});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A data structure to keep track of the keyword lists, current results, and
|
||||
* search running status for an ingest job.
|
||||
*/
|
||||
private class SearchJobInfo {
|
||||
|
||||
private final IngestJobContext jobContext;
|
||||
private final long jobId;
|
||||
private final long dataSourceId;
|
||||
private volatile boolean workerRunning;
|
||||
@GuardedBy("this")
|
||||
private final List<String> keywordListNames;
|
||||
@GuardedBy("this")
|
||||
private final Map<Keyword, Set<Long>> currentResults; // Keyword to object IDs of items with hits
|
||||
private IngestSearchRunner.Searcher currentSearcher;
|
||||
private final AtomicLong moduleReferenceCount = new AtomicLong(0);
|
||||
private final Object finalSearchLock = new Object();
|
||||
|
||||
private SearchJobInfo(IngestJobContext jobContext, List<String> keywordListNames) {
|
||||
this.jobContext = jobContext;
|
||||
jobId = jobContext.getJobId();
|
||||
dataSourceId = jobContext.getDataSource().getId();
|
||||
this.keywordListNames = new ArrayList<>(keywordListNames);
|
||||
currentResults = new HashMap<>();
|
||||
workerRunning = false;
|
||||
currentSearcher = null;
|
||||
}
|
||||
|
||||
private IngestJobContext getJobContext() {
|
||||
return jobContext;
|
||||
}
|
||||
|
||||
private long getJobId() {
|
||||
return jobId;
|
||||
}
|
||||
|
||||
private long getDataSourceId() {
|
||||
return dataSourceId;
|
||||
}
|
||||
|
||||
private synchronized List<String> getKeywordListNames() {
|
||||
return new ArrayList<>(keywordListNames);
|
||||
}
|
||||
|
||||
private synchronized void addKeywordListName(String keywordListName) {
|
||||
if (!keywordListNames.contains(keywordListName)) {
|
||||
keywordListNames.add(keywordListName);
|
||||
}
|
||||
}
|
||||
|
||||
private synchronized Set<Long> currentKeywordResults(Keyword k) {
|
||||
return currentResults.get(k);
|
||||
}
|
||||
|
||||
private synchronized void addKeywordResults(Keyword k, Set<Long> resultsIDs) {
|
||||
currentResults.put(k, resultsIDs);
|
||||
}
|
||||
|
||||
private boolean isWorkerRunning() {
|
||||
return workerRunning;
|
||||
}
|
||||
|
||||
private void setWorkerRunning(boolean flag) {
|
||||
workerRunning = flag;
|
||||
}
|
||||
|
||||
private synchronized IngestSearchRunner.Searcher getCurrentSearcher() {
|
||||
return currentSearcher;
|
||||
}
|
||||
|
||||
private synchronized void setCurrentSearcher(IngestSearchRunner.Searcher searchRunner) {
|
||||
currentSearcher = searchRunner;
|
||||
}
|
||||
|
||||
private void incrementModuleReferenceCount() {
|
||||
moduleReferenceCount.incrementAndGet();
|
||||
}
|
||||
|
||||
private long decrementModuleReferenceCount() {
|
||||
return moduleReferenceCount.decrementAndGet();
|
||||
}
|
||||
|
||||
/**
|
||||
* Waits for the current search task to complete.
|
||||
*
|
||||
* @throws InterruptedException
|
||||
*/
|
||||
private void waitForCurrentWorker() throws InterruptedException {
|
||||
synchronized (finalSearchLock) {
|
||||
while (workerRunning) {
|
||||
logger.log(Level.INFO, String.format("Waiting for previous search task for job %d to finish", jobId)); //NON-NLS
|
||||
finalSearchLock.wait();
|
||||
logger.log(Level.INFO, String.format("Notified previous search task for job %d to finish", jobId)); //NON-NLS
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Signals any threads waiting on the current search task to complete.
|
||||
*/
|
||||
private void searchNotify() {
|
||||
synchronized (finalSearchLock) {
|
||||
workerRunning = false;
|
||||
finalSearchLock.notify();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* A SwingWorker responsible for searching the Solr index of the current
|
||||
* case for the keywords for an ingest job. Keyword hit analysis results are
|
||||
* created and posted to the blackboard and notifications are sent to the
|
||||
* ingest inbox.
|
||||
*/
|
||||
private final class Searcher extends SwingWorker<Object, Void> {
|
||||
|
||||
/*
|
||||
* Searcher has private copies/snapshots of the lists and keywords
|
||||
*/
|
||||
private final SearchJobInfo job;
|
||||
private final List<Keyword> keywords; //keywords to search
|
||||
private final List<String> keywordListNames; // lists currently being searched
|
||||
private final List<KeywordList> keywordLists;
|
||||
private final Map<Keyword, KeywordList> keywordToList; //keyword to list name mapping
|
||||
@ThreadConfined(type = ThreadConfined.ThreadType.AWT)
|
||||
private ProgressHandle progressIndicator;
|
||||
private boolean finalRun = false;
|
||||
|
||||
Searcher(SearchJobInfo job, boolean finalRun) {
|
||||
this.job = job;
|
||||
this.finalRun = finalRun;
|
||||
keywordListNames = job.getKeywordListNames();
|
||||
keywords = new ArrayList<>();
|
||||
keywordToList = new HashMap<>();
|
||||
keywordLists = new ArrayList<>();
|
||||
}
|
||||
|
||||
@Override
|
||||
@Messages("SearchRunner.query.exception.msg=Error performing query:")
|
||||
protected Object doInBackground() throws Exception {
|
||||
try {
|
||||
if (usingNetBeansGUI) {
|
||||
/*
|
||||
* If running in the NetBeans thick client application
|
||||
* version of Autopsy, NetBeans progress handles (i.e.,
|
||||
* progress bars) are used to display search progress in the
|
||||
* lower right hand corner of the main application window.
|
||||
*
|
||||
* A layer of abstraction to allow alternate representations
|
||||
* of progress could be used here, as it is in other places
|
||||
* in the application (see implementations and usage of
|
||||
* org.sleuthkit.autopsy.progress.ProgressIndicator
|
||||
* interface), to better decouple keyword search from the
|
||||
* application's presentation layer.
|
||||
*/
|
||||
SwingUtilities.invokeAndWait(() -> {
|
||||
final String displayName = NbBundle.getMessage(this.getClass(), "KeywordSearchIngestModule.doInBackGround.displayName")
|
||||
+ (finalRun ? (" - " + NbBundle.getMessage(this.getClass(), "KeywordSearchIngestModule.doInBackGround.finalizeMsg")) : "");
|
||||
progressIndicator = ProgressHandle.createHandle(displayName, new Cancellable() {
|
||||
@Override
|
||||
public boolean cancel() {
|
||||
if (progressIndicator != null) {
|
||||
progressIndicator.setDisplayName(displayName + " " + NbBundle.getMessage(this.getClass(), "SearchRunner.doInBackGround.cancelMsg"));
|
||||
}
|
||||
logger.log(Level.INFO, "Search cancelled by user"); //NON-NLS
|
||||
new Thread(() -> {
|
||||
IngestSearchRunner.Searcher.this.cancel(true);
|
||||
}).start();
|
||||
return true;
|
||||
}
|
||||
});
|
||||
progressIndicator.start();
|
||||
progressIndicator.switchToIndeterminate();
|
||||
});
|
||||
}
|
||||
|
||||
updateKeywords();
|
||||
for (Keyword keyword : keywords) {
|
||||
if (isCancelled() || job.getJobContext().fileIngestIsCancelled()) {
|
||||
logger.log(Level.INFO, "Cancellation requested, exiting before new keyword processed: {0}", keyword.getSearchTerm()); //NON-NLS
|
||||
return null;
|
||||
}
|
||||
|
||||
KeywordList keywordList = keywordToList.get(keyword);
|
||||
if (usingNetBeansGUI) {
|
||||
String searchTermStr = keyword.getSearchTerm();
|
||||
if (searchTermStr.length() > 50) {
|
||||
searchTermStr = searchTermStr.substring(0, 49) + "...";
|
||||
}
|
||||
final String progressMessage = keywordList.getName() + ": " + searchTermStr;
|
||||
SwingUtilities.invokeLater(() -> {
|
||||
progressIndicator.progress(progressMessage);
|
||||
});
|
||||
}
|
||||
|
||||
// Filtering
|
||||
//limit search to currently ingested data sources
|
||||
//set up a filter with 1 or more image ids OR'ed
|
||||
KeywordSearchQuery keywordSearchQuery = KeywordSearchUtil.getQueryForKeyword(keyword, keywordList);
|
||||
KeywordQueryFilter dataSourceFilter = new KeywordQueryFilter(KeywordQueryFilter.FilterType.DATA_SOURCE, job.getDataSourceId());
|
||||
keywordSearchQuery.addFilter(dataSourceFilter);
|
||||
|
||||
// Do the actual search
|
||||
QueryResults queryResults;
|
||||
try {
|
||||
queryResults = keywordSearchQuery.performQuery();
|
||||
} catch (KeywordSearchModuleException | NoOpenCoreException ex) {
|
||||
logger.log(Level.SEVERE, "Error performing query: " + keyword.getSearchTerm(), ex); //NON-NLS
|
||||
if (usingNetBeansGUI) {
|
||||
final String userMessage = Bundle.SearchRunner_query_exception_msg() + keyword.getSearchTerm();
|
||||
SwingUtilities.invokeLater(() -> {
|
||||
MessageNotifyUtil.Notify.error(userMessage, ex.getCause().getMessage());
|
||||
});
|
||||
}
|
||||
//no reason to continue with next query if recovery failed
|
||||
//or wait for recovery to kick in and run again later
|
||||
//likely case has closed and threads are being interrupted
|
||||
return null;
|
||||
} catch (CancellationException e) {
|
||||
logger.log(Level.INFO, "Cancellation requested, exiting during keyword query: {0}", keyword.getSearchTerm()); //NON-NLS
|
||||
return null;
|
||||
}
|
||||
|
||||
// Reduce the results of the query to only those hits we
|
||||
// have not already seen.
|
||||
QueryResults newResults = filterResults(queryResults);
|
||||
|
||||
if (!newResults.getKeywords().isEmpty()) {
|
||||
// Create blackboard artifacts
|
||||
newResults.process(this, keywordList.getIngestMessages(), true, job.getJobId());
|
||||
}
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
logger.log(Level.SEVERE, String.format("Error performing keyword search for ingest job %d", job.getJobId()), ex); //NON-NLS
|
||||
} finally {
|
||||
if (progressIndicator != null) {
|
||||
SwingUtilities.invokeLater(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
progressIndicator.finish();
|
||||
progressIndicator = null;
|
||||
}
|
||||
});
|
||||
}
|
||||
// In case a thread is waiting on this worker to be done
|
||||
job.searchNotify();
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sync-up the updated keywords from the currently used lists in the XML
|
||||
*/
|
||||
private void updateKeywords() {
|
||||
XmlKeywordSearchList loader = XmlKeywordSearchList.getCurrent();
|
||||
|
||||
keywords.clear();
|
||||
keywordToList.clear();
|
||||
keywordLists.clear();
|
||||
|
||||
for (String name : keywordListNames) {
|
||||
KeywordList list = loader.getList(name);
|
||||
keywordLists.add(list);
|
||||
for (Keyword k : list.getKeywords()) {
|
||||
keywords.add(k);
|
||||
keywordToList.put(k, list);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This method filters out all of the hits found in earlier periodic
|
||||
* searches and returns only the results found by the most recent
|
||||
* search.
|
||||
*
|
||||
* This method will only return hits for objects for which we haven't
|
||||
* previously seen a hit for the keyword.
|
||||
*
|
||||
* @param queryResult The results returned by a keyword search.
|
||||
*
|
||||
* @return A unique set of hits found by the most recent search for
|
||||
* objects that have not previously had a hit. The hits will be
|
||||
* for the lowest numbered chunk associated with the object.
|
||||
*
|
||||
*/
|
||||
private QueryResults filterResults(QueryResults queryResult) {
|
||||
|
||||
// Create a new (empty) QueryResults object to hold the most recently
|
||||
// found hits.
|
||||
QueryResults newResults = new QueryResults(queryResult.getQuery());
|
||||
|
||||
// For each keyword represented in the results.
|
||||
for (Keyword keyword : queryResult.getKeywords()) {
|
||||
// These are all of the hits across all objects for the most recent search.
|
||||
// This may well include duplicates of hits we've seen in earlier periodic searches.
|
||||
List<KeywordHit> queryTermResults = queryResult.getResults(keyword);
|
||||
|
||||
// Sort the hits for this keyword so that we are always
|
||||
// guaranteed to return the hit for the lowest chunk.
|
||||
Collections.sort(queryTermResults);
|
||||
|
||||
// This will be used to build up the hits we haven't seen before
|
||||
// for this keyword.
|
||||
List<KeywordHit> newUniqueHits = new ArrayList<>();
|
||||
|
||||
// Get the set of object ids seen in the past by this searcher
|
||||
// for the given keyword.
|
||||
Set<Long> curTermResults = job.currentKeywordResults(keyword);
|
||||
if (curTermResults == null) {
|
||||
// We create a new empty set if we haven't seen results for
|
||||
// this keyword before.
|
||||
curTermResults = new HashSet<>();
|
||||
}
|
||||
|
||||
// For each hit for this keyword.
|
||||
for (KeywordHit hit : queryTermResults) {
|
||||
if (curTermResults.contains(hit.getSolrObjectId())) {
|
||||
// Skip the hit if we've already seen a hit for
|
||||
// this keyword in the object.
|
||||
continue;
|
||||
}
|
||||
|
||||
// We haven't seen the hit before so add it to list of new
|
||||
// unique hits.
|
||||
newUniqueHits.add(hit);
|
||||
|
||||
// Add the object id to the results we've seen for this
|
||||
// keyword.
|
||||
curTermResults.add(hit.getSolrObjectId());
|
||||
}
|
||||
|
||||
// Update the job with the list of objects for which we have
|
||||
// seen hits for the current keyword.
|
||||
job.addKeywordResults(keyword, curTermResults);
|
||||
|
||||
// Add the new hits for the current keyword into the results
|
||||
// to be returned.
|
||||
newResults.addResult(keyword, newUniqueHits);
|
||||
}
|
||||
|
||||
return newResults;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -19,9 +19,14 @@
|
||||
package org.sleuthkit.autopsy.keywordsearch;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.Reader;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.logging.Level;
|
||||
@ -29,9 +34,9 @@ import org.apache.commons.lang3.math.NumberUtils;
|
||||
import org.apache.solr.client.solrj.SolrServerException;
|
||||
import org.apache.solr.common.SolrInputDocument;
|
||||
import org.openide.util.NbBundle;
|
||||
import org.openide.util.io.ReaderInputStream;
|
||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||
import org.sleuthkit.autopsy.coreutils.TimeZoneUtils;
|
||||
import org.sleuthkit.autopsy.datamodel.ContentUtils;
|
||||
import org.sleuthkit.autopsy.healthmonitor.HealthMonitor;
|
||||
import org.sleuthkit.autopsy.healthmonitor.TimingMetric;
|
||||
import org.sleuthkit.autopsy.ingest.IngestJobContext;
|
||||
@ -146,10 +151,10 @@ class Ingester {
|
||||
* @throws org.sleuthkit.autopsy.keywordsearch.Ingester.IngesterException
|
||||
*/
|
||||
// TODO (JIRA-3118): Cancelled text indexing does not propagate cancellation to clients
|
||||
< T extends SleuthkitVisitableItem> boolean indexText(Reader sourceReader, long sourceID, String sourceName, T source, IngestJobContext context) throws Ingester.IngesterException {
|
||||
boolean doLanguageDetection = true;
|
||||
return indexText(sourceReader, sourceID, sourceName, source, context, doLanguageDetection);
|
||||
}
|
||||
// < T extends SleuthkitVisitableItem> boolean search(Reader sourceReader, long sourceID, String sourceName, T source, IngestJobContext context, boolean indexIntoSolr, List<String> keywordListNames) throws Ingester.IngesterException {
|
||||
// boolean doLanguageDetection = true;
|
||||
// return search(sourceReader, sourceID, sourceName, source, context, doLanguageDetection, indexIntoSolr, keywordListNames);
|
||||
// }
|
||||
|
||||
/**
|
||||
* Read and chunk the source text for indexing in Solr. Does NOT perform
|
||||
@ -170,11 +175,17 @@ class Ingester {
|
||||
* @throws org.sleuthkit.autopsy.keywordsearch.Ingester.IngesterException
|
||||
*/
|
||||
// TODO (JIRA-3118): Cancelled text indexing does not propagate cancellation to clients
|
||||
< T extends SleuthkitVisitableItem> boolean indexStrings(Reader sourceReader, long sourceID, String sourceName, T source, IngestJobContext context) throws Ingester.IngesterException {
|
||||
// Per JIRA-7100, it was determined that language detection on extracted strings can take a really long time.
|
||||
boolean doLanguageDetection = false;
|
||||
return indexText(sourceReader, sourceID, sourceName, source, context, doLanguageDetection);
|
||||
}
|
||||
// < T extends SleuthkitVisitableItem> boolean searchStrings(Reader sourceReader, long sourceID, String sourceName, T source, IngestJobContext context, boolean indexIntoSolr) throws Ingester.IngesterException {
|
||||
// // Per JIRA-7100, it was determined that language detection on extracted strings can take a really long time.
|
||||
// boolean doLanguageDetection = false;
|
||||
// return search(sourceReader, sourceID, sourceName, source, context, doLanguageDetection, indexIntoSolr, null);
|
||||
// }
|
||||
//
|
||||
// < T extends SleuthkitVisitableItem> boolean searchStrings(Reader sourceReader, long sourceID, String sourceName, T source, IngestJobContext context, boolean indexIntoSolr, List<String> keywordListNames) throws Ingester.IngesterException {
|
||||
// // Per JIRA-7100, it was determined that language detection on extracted strings can take a really long time.
|
||||
// boolean doLanguageDetection = false;
|
||||
// return search(sourceReader, sourceID, sourceName, source, context, doLanguageDetection, indexIntoSolr, keywordListNames);
|
||||
// }
|
||||
|
||||
/**
|
||||
* Read and chunk the source text for indexing in Solr.
|
||||
@ -195,60 +206,90 @@ class Ingester {
|
||||
* @throws org.sleuthkit.autopsy.keywordsearch.Ingester.IngesterException
|
||||
*/
|
||||
// TODO (JIRA-3118): Cancelled text indexing does not propagate cancellation to clients
|
||||
private < T extends SleuthkitVisitableItem> boolean indexText(Reader sourceReader, long sourceID, String sourceName, T source, IngestJobContext context, boolean doLanguageDetection) throws Ingester.IngesterException {
|
||||
< T extends SleuthkitVisitableItem> void search(Reader sourceReader, long sourceID, String sourceName, T source, IngestJobContext context, boolean doLanguageDetection, boolean indexIntoSolr, List<String> keywordListNames) throws Ingester.IngesterException, IOException, TskCoreException, Exception {
|
||||
int numChunks = 0; //unknown until chunking is done
|
||||
|
||||
Map<String, String> contentFields = Collections.unmodifiableMap(getContentFields(source));
|
||||
Optional<Language> language = Optional.empty();
|
||||
InlineSearcher searcher = new InlineSearcher(keywordListNames, context);
|
||||
List<Chunk> activeChunkList = new ArrayList<>();
|
||||
boolean fileIndexed = false;
|
||||
|
||||
//Get a reader for the content of the given source
|
||||
try (BufferedReader reader = new BufferedReader(sourceReader)) {
|
||||
Chunker chunker = new Chunker(reader);
|
||||
String name = sourceName;
|
||||
if(!(source instanceof BlackboardArtifact)) {
|
||||
searcher.searchString(name, sourceID, 0);
|
||||
}
|
||||
|
||||
while (chunker.hasNext()) {
|
||||
if (context != null && context.fileIngestIsCancelled()) {
|
||||
if ( context.fileIngestIsCancelled()) {
|
||||
logger.log(Level.INFO, "File ingest cancelled. Cancelling keyword search indexing of {0}", sourceName);
|
||||
return false;
|
||||
return;
|
||||
}
|
||||
|
||||
Chunk chunk = chunker.next();
|
||||
Map<String, Object> fields = new HashMap<>(contentFields);
|
||||
String chunkId = Server.getChunkIdString(sourceID, numChunks + 1);
|
||||
fields.put(Server.Schema.ID.toString(), chunkId);
|
||||
fields.put(Server.Schema.CHUNK_SIZE.toString(), String.valueOf(chunk.getBaseChunkLength()));
|
||||
|
||||
Chunk chunk = chunker.next();
|
||||
chunk.setChunkId(numChunks+1);
|
||||
|
||||
if (doLanguageDetection) {
|
||||
int size = Math.min(chunk.getBaseChunkLength(), LANGUAGE_DETECTION_STRING_SIZE);
|
||||
language = languageSpecificContentIndexingHelper.detectLanguageIfNeeded(chunk.toString().substring(0, size));
|
||||
|
||||
|
||||
// only do language detection on the first chunk of the document
|
||||
doLanguageDetection = false;
|
||||
}
|
||||
language.ifPresent(lang -> languageSpecificContentIndexingHelper.updateLanguageSpecificFields(fields, chunk, lang));
|
||||
try {
|
||||
//add the chunk text to Solr index
|
||||
indexChunk(chunk.toString(), chunk.geLowerCasedChunk(), sourceName, fields);
|
||||
// add mini chunk when there's a language specific field
|
||||
if (chunker.hasNext() && language.isPresent()) {
|
||||
languageSpecificContentIndexingHelper.indexMiniChunk(chunk, sourceName, new HashMap<>(contentFields), chunkId, language.get());
|
||||
|
||||
if(keywordListNames != null) {
|
||||
boolean hitFoundInChunk = searcher.searchChunk(chunk, sourceID, numChunks);
|
||||
if(!indexIntoSolr) {
|
||||
if(!hitFoundInChunk) {
|
||||
if(!activeChunkList.isEmpty() ) {
|
||||
if(activeChunkList.get(activeChunkList.size() - 1).hasHit()) {
|
||||
activeChunkList.add(chunk);
|
||||
// Write List
|
||||
for(Chunk c: activeChunkList) {
|
||||
indexChunk(c, sourceID, sourceName, language, contentFields, chunker.hasNext());
|
||||
}
|
||||
activeChunkList.clear();
|
||||
} else {
|
||||
activeChunkList.clear();
|
||||
activeChunkList.add(chunk);
|
||||
}
|
||||
} else {
|
||||
activeChunkList.add(chunk);
|
||||
}
|
||||
} else {
|
||||
fileIndexed = true;
|
||||
chunk.setHasHit(true);
|
||||
activeChunkList.add(chunk);
|
||||
}
|
||||
} else {
|
||||
indexChunk(chunk, sourceID, sourceName, language, contentFields, chunker.hasNext());
|
||||
}
|
||||
numChunks++;
|
||||
} catch (Ingester.IngesterException ingEx) {
|
||||
logger.log(Level.WARNING, "Ingester had a problem with extracted string from file '" //NON-NLS
|
||||
+ sourceName + "' (id: " + sourceID + ").", ingEx);//NON-NLS
|
||||
|
||||
throw ingEx; //need to rethrow to signal error and move on
|
||||
}
|
||||
|
||||
numChunks++;
|
||||
|
||||
}
|
||||
|
||||
if(activeChunkList.size() > 1 || (activeChunkList.size() == 1 && activeChunkList.get(0).hasHit())) {
|
||||
for(Chunk c: activeChunkList) {
|
||||
indexChunk(c, sourceID, sourceName, language, contentFields, true);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (chunker.hasException()) {
|
||||
logger.log(Level.WARNING, "Error chunking content from " + sourceID + ": " + sourceName, chunker.getException());
|
||||
return false;
|
||||
throw chunker.getException();
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
logger.log(Level.WARNING, "Unexpected error, can't read content stream from " + sourceID + ": " + sourceName, ex);//NON-NLS
|
||||
return false;
|
||||
} finally {
|
||||
if (context != null && context.fileIngestIsCancelled()) {
|
||||
return false;
|
||||
} else {
|
||||
|
||||
} finally {
|
||||
if (context.fileIngestIsCancelled()) {
|
||||
return ;
|
||||
}
|
||||
|
||||
if (fileIndexed) {
|
||||
Map<String, Object> fields = new HashMap<>(contentFields);
|
||||
//after all chunks, index just the meta data, including the numChunks, of the parent file
|
||||
fields.put(Server.Schema.NUM_CHUNKS.toString(), Integer.toString(numChunks));
|
||||
@ -259,8 +300,103 @@ class Ingester {
|
||||
indexChunk(null, null, sourceName, fields);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
< T extends SleuthkitVisitableItem> boolean indexFile(Reader sourceReader, long sourceID, String sourceName, T source, IngestJobContext context, boolean doLanguageDetection) throws Ingester.IngesterException {
|
||||
int numChunks = 0; //unknown until chunking is done
|
||||
Map<String, String> contentFields = Collections.unmodifiableMap(getContentFields(source));
|
||||
Optional<Language> language = Optional.empty();
|
||||
//Get a reader for the content of the given source
|
||||
try (BufferedReader reader = new BufferedReader(sourceReader)) {
|
||||
Chunker chunker = new Chunker(reader);
|
||||
while (chunker.hasNext()) {
|
||||
if ( context.fileIngestIsCancelled()) {
|
||||
logger.log(Level.INFO, "File ingest cancelled. Cancelling keyword search indexing of {0}", sourceName);
|
||||
return false;
|
||||
}
|
||||
|
||||
Chunk chunk = chunker.next();
|
||||
|
||||
if (doLanguageDetection) {
|
||||
int size = Math.min(chunk.getBaseChunkLength(), LANGUAGE_DETECTION_STRING_SIZE);
|
||||
language = languageSpecificContentIndexingHelper.detectLanguageIfNeeded(chunk.toString().substring(0, size));
|
||||
|
||||
// only do language detection on the first chunk of the document
|
||||
doLanguageDetection = false;
|
||||
}
|
||||
|
||||
Map<String, Object> fields = new HashMap<>(contentFields);
|
||||
String chunkId = Server.getChunkIdString(sourceID, numChunks + 1);
|
||||
fields.put(Server.Schema.ID.toString(), chunkId);
|
||||
fields.put(Server.Schema.CHUNK_SIZE.toString(), String.valueOf(chunk.getBaseChunkLength()));
|
||||
|
||||
language.ifPresent(lang -> languageSpecificContentIndexingHelper.updateLanguageSpecificFields(fields, chunk, lang));
|
||||
try {
|
||||
//add the chunk text to Solr index
|
||||
indexChunk(chunk.toString(), chunk.getLowerCasedChunk(), sourceName, fields);
|
||||
// add mini chunk when there's a language specific field
|
||||
if (chunker.hasNext() && language.isPresent()) {
|
||||
languageSpecificContentIndexingHelper.indexMiniChunk(chunk, sourceName, new HashMap<>(contentFields), chunkId, language.get());
|
||||
}
|
||||
numChunks++;
|
||||
|
||||
} catch (Ingester.IngesterException ingEx) {
|
||||
logger.log(Level.WARNING, "Ingester had a problem with extracted string from file '" //NON-NLS
|
||||
+ sourceName + "' (id: " + sourceID + ").", ingEx);//NON-NLS
|
||||
|
||||
throw ingEx; //need to rethrow to signal error and move on
|
||||
}
|
||||
}
|
||||
if (chunker.hasException()) {
|
||||
logger.log(Level.WARNING, "Error chunking content from " + sourceID + ": " + sourceName, chunker.getException());
|
||||
return false;
|
||||
}
|
||||
|
||||
} catch (Exception ex) {
|
||||
logger.log(Level.WARNING, "Unexpected error, can't read content stream from " + sourceID + ": " + sourceName, ex);//NON-NLS
|
||||
return false;
|
||||
} finally {
|
||||
if (context.fileIngestIsCancelled()) {
|
||||
return false;
|
||||
} else {
|
||||
Map<String, Object> fields = new HashMap<>(contentFields);
|
||||
//after all chunks, index just the meta data, including the numChunks, of the parent file
|
||||
fields.put(Server.Schema.NUM_CHUNKS.toString(), Integer.toString(numChunks));
|
||||
//reset id field to base document id
|
||||
fields.put(Server.Schema.ID.toString(), Long.toString(sourceID));
|
||||
//"parent" docs don't have chunk_size
|
||||
fields.remove(Server.Schema.CHUNK_SIZE.toString());
|
||||
indexChunk(null, null, sourceName, fields);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private void indexChunk(Chunk chunk, long sourceID, String sourceName, Optional<Language> language, Map<String, String> contentFields, boolean hasNext) throws IngesterException {
|
||||
Map<String, Object> fields = new HashMap<>(contentFields);
|
||||
String chunkId = Server.getChunkIdString(sourceID, chunk.getChunkId());
|
||||
fields.put(Server.Schema.ID.toString(), chunkId);
|
||||
fields.put(Server.Schema.CHUNK_SIZE.toString(), String.valueOf(chunk.getBaseChunkLength()));
|
||||
|
||||
|
||||
language.ifPresent(lang -> languageSpecificContentIndexingHelper.updateLanguageSpecificFields(fields, chunk, lang));
|
||||
try {
|
||||
//add the chunk text to Solr index
|
||||
indexChunk(chunk.toString(), chunk.getLowerCasedChunk(), sourceName, fields);
|
||||
// add mini chunk when there's a language specific field
|
||||
if (hasNext && language.isPresent()) {
|
||||
languageSpecificContentIndexingHelper.indexMiniChunk(chunk, sourceName, new HashMap<>(contentFields), chunkId, language.get());
|
||||
}
|
||||
|
||||
} catch (Ingester.IngesterException ingEx) {
|
||||
logger.log(Level.WARNING, "Ingester had a problem with extracted string from file '" //NON-NLS
|
||||
+ sourceName + "' (id: " + sourceID + ").", ingEx);//NON-NLS
|
||||
|
||||
throw ingEx; //need to rethrow to signal error and move on
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add one chunk as to the Solr index as a separate Solr document.
|
||||
|
619
KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/InlineSearcher.java
Executable file
619
KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/InlineSearcher.java
Executable file
@ -0,0 +1,619 @@
|
||||
/*
|
||||
* Autopsy Forensic Browser
|
||||
*
|
||||
* Copyright 2022 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.keywordsearch;
|
||||
|
||||
import com.twelvemonkeys.lang.StringUtil;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Comparator;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.logging.Level;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
import org.apache.commons.validator.routines.DomainValidator;
|
||||
import org.apache.lucene.analysis.Analyzer;
|
||||
import org.apache.lucene.analysis.TokenStream;
|
||||
import org.apache.lucene.analysis.standard.StandardAnalyzer;
|
||||
import org.apache.lucene.analysis.tokenattributes.CharTermAttribute;
|
||||
import org.apache.lucene.analysis.tokenattributes.OffsetAttribute;
|
||||
import org.sleuthkit.autopsy.casemodule.Case;
|
||||
import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException;
|
||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||
import org.sleuthkit.autopsy.ingest.IngestJobContext;
|
||||
import org.sleuthkit.autopsy.keywordsearch.Chunker.Chunk;
|
||||
import static org.sleuthkit.autopsy.keywordsearch.RegexQuery.CREDIT_CARD_NUM_PATTERN;
|
||||
import org.sleuthkit.datamodel.Blackboard;
|
||||
import org.sleuthkit.datamodel.BlackboardArtifact;
|
||||
import org.sleuthkit.datamodel.BlackboardAttribute;
|
||||
import org.sleuthkit.datamodel.Content;
|
||||
import org.sleuthkit.datamodel.SleuthkitCase;
|
||||
import org.sleuthkit.datamodel.TskCoreException;
|
||||
import org.sleuthkit.datamodel.TskException;
|
||||
|
||||
final class InlineSearcher {
|
||||
|
||||
private final List<KeywordList> keywordList;
|
||||
private static final int MIN_EMAIL_ADDR_LENGTH = 8;
|
||||
private static final Logger logger = Logger.getLogger(InlineSearcher.class.getName());
|
||||
|
||||
private final IngestJobContext context;
|
||||
|
||||
static final Map<Long, List<UniqueKeywordHit>> uniqueHitMap = new ConcurrentHashMap<>();
|
||||
|
||||
static final Map<Long, Map<Long, Map<Keyword, Map<Keyword, List<UniqueKeywordHit>>>>> uniqueHitMap2 = new ConcurrentHashMap<>();
|
||||
|
||||
// Uses mostly native java and the lucene api to search the a given chuck
|
||||
// for Keywords. Create unique KeywordHits for any unique hit.
|
||||
InlineSearcher(List<String> keywordListNames, IngestJobContext context) {
|
||||
this.keywordList = new ArrayList<>();
|
||||
this.context = context;
|
||||
|
||||
if (keywordListNames != null) {
|
||||
XmlKeywordSearchList loader = XmlKeywordSearchList.getCurrent();
|
||||
for (String name : keywordListNames) {
|
||||
keywordList.add(loader.getList(name));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Search the chunk for the currently selected keywords.
|
||||
*
|
||||
* @param chunk
|
||||
* @param sourceID
|
||||
*
|
||||
* @throws TskCoreException
|
||||
*/
|
||||
boolean searchChunk(Chunk chunk, long sourceID, int chunkId) throws TskCoreException {
|
||||
return searchString(chunk.getLowerCasedChunk(), sourceID, chunkId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Search a string for the currently selected keywords.
|
||||
*
|
||||
* @param text
|
||||
* @param sourceID
|
||||
*
|
||||
* @throws TskCoreException
|
||||
*/
|
||||
boolean searchString(String text, long sourceID, int chunkId) throws TskCoreException {
|
||||
boolean hitFound = false;
|
||||
Map<Keyword, Map<Keyword, List<UniqueKeywordHit>>> hitByKeyword = getMap(context.getJobId(), sourceID);
|
||||
for (KeywordList list : keywordList) {
|
||||
List<Keyword> keywords = list.getKeywords();
|
||||
for (Keyword originalKeyword : keywords) {
|
||||
Map<Keyword, List<UniqueKeywordHit>> hitMap = hitByKeyword.get(originalKeyword);
|
||||
if (hitMap == null) {
|
||||
hitMap = new HashMap<>();
|
||||
hitByKeyword.put(originalKeyword, hitMap);
|
||||
}
|
||||
|
||||
List<UniqueKeywordHit> keywordHits = new ArrayList<>();
|
||||
if (originalKeyword.searchTermIsLiteral()) {
|
||||
if (StringUtil.containsIgnoreCase(text, originalKeyword.getSearchTerm())) {
|
||||
keywordHits.addAll(createKeywordHits(text, originalKeyword, sourceID, chunkId, list.getName()));
|
||||
}
|
||||
} else {
|
||||
String regex = originalKeyword.getSearchTerm();
|
||||
|
||||
try {
|
||||
// validate the regex
|
||||
Pattern pattern = Pattern.compile(regex, Pattern.CASE_INSENSITIVE);
|
||||
Matcher matcher = pattern.matcher(text);
|
||||
|
||||
if (matcher.find()) {
|
||||
keywordHits.addAll(createKeywordHits(text, originalKeyword, sourceID, chunkId, list.getName()));
|
||||
}
|
||||
} catch (IllegalArgumentException ex) {
|
||||
//TODO What should we do here? Log and continue?
|
||||
}
|
||||
}
|
||||
|
||||
if (!keywordHits.isEmpty()) {
|
||||
hitFound = true;
|
||||
for (UniqueKeywordHit hit : keywordHits) {
|
||||
Keyword keywordCopy = new Keyword(hit.getHit(),
|
||||
originalKeyword.searchTermIsLiteral(),
|
||||
originalKeyword.searchTermIsWholeWord(),
|
||||
list.getName(),
|
||||
originalKeyword.getOriginalTerm());
|
||||
|
||||
List<UniqueKeywordHit> mapHitList = hitMap.get(keywordCopy);
|
||||
if (mapHitList == null) {
|
||||
mapHitList = new ArrayList<>();
|
||||
hitMap.put(keywordCopy, mapHitList);
|
||||
}
|
||||
|
||||
if (!mapHitList.contains(hit)) {
|
||||
mapHitList.add(hit);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (context.fileIngestIsCancelled()) {
|
||||
return hitFound;
|
||||
}
|
||||
}
|
||||
}
|
||||
return hitFound;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method very similar to RegexQuery createKeywordHits, with the
|
||||
* knowledge of solr removed.
|
||||
*
|
||||
* @param text
|
||||
* @param originalKeyword
|
||||
*
|
||||
* @return A list of KeywordHit objects.
|
||||
*
|
||||
* @throws TskCoreException
|
||||
*/
|
||||
private List<UniqueKeywordHit> createKeywordHits(String text, Keyword originalKeyword, long sourceID, int chunkId, String keywordListName) throws TskCoreException {
|
||||
|
||||
if (originalKeyword.searchTermIsLiteral() && originalKeyword.searchTermIsWholeWord()) {
|
||||
try {
|
||||
return getExactMatchHits(text, originalKeyword, sourceID, chunkId, keywordListName);
|
||||
} catch (IOException ex) {
|
||||
throw new TskCoreException("Failed to create exactMatch hits", ex);
|
||||
}
|
||||
}
|
||||
|
||||
final HashMap<String, String> keywordsFoundInThisDocument = new HashMap<>();
|
||||
|
||||
List<UniqueKeywordHit> hits = new ArrayList<>();
|
||||
String keywordString = originalKeyword.getSearchTerm();
|
||||
|
||||
boolean queryStringContainsWildcardSuffix = originalKeyword.getSearchTerm().endsWith(".*");
|
||||
|
||||
String searchPattern;
|
||||
if (originalKeyword.searchTermIsLiteral()) {
|
||||
/**
|
||||
* For substring searches, the following pattern was arrived at
|
||||
* through trial and error in an attempt to reproduce the same hits
|
||||
* we were getting when we were using the TermComponent approach.
|
||||
* This basically looks for zero of more word characters followed
|
||||
* optionally by a dot or apostrophe, followed by the quoted
|
||||
* lowercase substring following by zero or more word characters
|
||||
* followed optionally by a dot or apostrophe. The reason that the
|
||||
* dot and apostrophe characters are being handled here is because
|
||||
* the old code used to find hits in domain names (e.g. hacks.ie)
|
||||
* and possessives (e.g. hacker's). This obviously works for English
|
||||
* but is probably not sufficient for other languages.
|
||||
*/
|
||||
searchPattern = "[\\w[\\.']]*" + java.util.regex.Pattern.quote(keywordString.toLowerCase()) + "[\\w[\\.']]*";
|
||||
|
||||
} else {
|
||||
searchPattern = keywordString;
|
||||
}
|
||||
|
||||
final java.util.regex.Pattern pattern = java.util.regex.Pattern.compile(searchPattern, Pattern.CASE_INSENSITIVE);
|
||||
|
||||
try {
|
||||
String content = text;
|
||||
Matcher hitMatcher = pattern.matcher(content);
|
||||
int offset = 0;
|
||||
|
||||
while (hitMatcher.find(offset)) {
|
||||
|
||||
String hit = hitMatcher.group().toLowerCase();
|
||||
|
||||
/**
|
||||
* No need to continue on if the the string is "" nothing to
|
||||
* find or do.
|
||||
*/
|
||||
if ("".equals(hit)) {
|
||||
break;
|
||||
}
|
||||
|
||||
offset = hitMatcher.end();
|
||||
final BlackboardAttribute.ATTRIBUTE_TYPE artifactAttributeType = originalKeyword.getArtifactAttributeType();
|
||||
|
||||
// We attempt to reduce false positives for phone numbers and IP address hits
|
||||
// by querying Solr for hits delimited by a set of known boundary characters.
|
||||
// See KeywordSearchList.PHONE_NUMBER_REGEX for an example.
|
||||
// Because of this the hits may contain an extra character at the beginning or end that
|
||||
// needs to be chopped off, unless the user has supplied their own wildcard suffix
|
||||
// as part of the regex.
|
||||
if (!queryStringContainsWildcardSuffix
|
||||
&& (artifactAttributeType == BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PHONE_NUMBER
|
||||
|| artifactAttributeType == BlackboardAttribute.ATTRIBUTE_TYPE.TSK_IP_ADDRESS)) {
|
||||
if (artifactAttributeType == BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PHONE_NUMBER) {
|
||||
// For phone numbers replace all non numeric characters (except "(") at the start of the hit.
|
||||
hit = hit.replaceAll("^[^0-9\\(]", "");
|
||||
} else {
|
||||
// Replace all non numeric characters at the start of the hit.
|
||||
hit = hit.replaceAll("^[^0-9]", "");
|
||||
}
|
||||
// Replace all non numeric at the end of the hit.
|
||||
hit = hit.replaceAll("[^0-9]$", "");
|
||||
|
||||
if (offset > 1) {
|
||||
/*
|
||||
* NOTE: our IP and phone number regex patterns look for
|
||||
* boundary characters immediately before and after the
|
||||
* keyword hit. After a match, Java pattern mather
|
||||
* re-starts at the first character not matched by the
|
||||
* previous match. This basically requires two boundary
|
||||
* characters to be present between each pattern match.
|
||||
* To mitigate this we are resetting the offest one
|
||||
* character back.
|
||||
*/
|
||||
offset--;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Boundary characters are removed from the start and end of the
|
||||
* hit to normalize the hits. This is being done for substring
|
||||
* searches only at this point. We don't do it for real regular
|
||||
* expression searches because the user may have explicitly
|
||||
* included boundary characters in their regular expression.
|
||||
*/
|
||||
if (originalKeyword.searchTermIsLiteral()) {
|
||||
hit = hit.replaceAll("^" + KeywordSearchList.BOUNDARY_CHARACTERS + "*", "");
|
||||
hit = hit.replaceAll(KeywordSearchList.BOUNDARY_CHARACTERS + "*$", "");
|
||||
}
|
||||
|
||||
/**
|
||||
* The use of String interning is an optimization to ensure that
|
||||
* we reuse the same keyword hit String object across all hits.
|
||||
* Even though we benefit from G1GC String deduplication, the
|
||||
* overhead associated with creating a new String object for
|
||||
* every KeywordHit can be significant when the number of hits
|
||||
* gets large.
|
||||
*/
|
||||
hit = hit.intern();
|
||||
|
||||
// We will only create one KeywordHit instance per document for
|
||||
// a given hit.
|
||||
if (keywordsFoundInThisDocument.containsKey(hit)) {
|
||||
continue;
|
||||
}
|
||||
keywordsFoundInThisDocument.put(hit, hit);
|
||||
|
||||
if (artifactAttributeType == null) {
|
||||
hits.add(new UniqueKeywordHit(chunkId, sourceID, KeywordSearchUtil.makeSnippet(content, hitMatcher, hit), hit, keywordListName, originalKeyword.searchTermIsWholeWord(), originalKeyword.searchTermIsLiteral(), originalKeyword.getArtifactAttributeType(), originalKeyword.getSearchTerm()));
|
||||
} else {
|
||||
switch (artifactAttributeType) {
|
||||
case TSK_EMAIL:
|
||||
/*
|
||||
* Reduce false positives by eliminating email
|
||||
* address hits that are either too short or are not
|
||||
* for valid top level domains.
|
||||
*/
|
||||
if (hit.length() >= MIN_EMAIL_ADDR_LENGTH
|
||||
&& DomainValidator.getInstance(true).isValidTld(hit.substring(hit.lastIndexOf('.')))) {
|
||||
hits.add(new UniqueKeywordHit(chunkId, sourceID, KeywordSearchUtil.makeSnippet(content, hitMatcher, hit), hit, keywordListName, originalKeyword.searchTermIsWholeWord(), originalKeyword.searchTermIsLiteral(), originalKeyword.getArtifactAttributeType(), originalKeyword.getSearchTerm()));
|
||||
}
|
||||
|
||||
break;
|
||||
case TSK_CARD_NUMBER:
|
||||
/*
|
||||
* If searching for credit card account numbers, do
|
||||
* extra validation on the term and discard it if it
|
||||
* does not pass.
|
||||
*/
|
||||
Matcher ccnMatcher = CREDIT_CARD_NUM_PATTERN.matcher(hit);
|
||||
|
||||
for (int rLength = hit.length(); rLength >= 12; rLength--) {
|
||||
ccnMatcher.region(0, rLength);
|
||||
if (ccnMatcher.find()) {
|
||||
final String group = ccnMatcher.group("ccn");
|
||||
if (CreditCardValidator.isValidCCN(group)) {
|
||||
hits.add(new UniqueKeywordHit(chunkId, sourceID, KeywordSearchUtil.makeSnippet(content, hitMatcher, hit), hit, keywordListName, originalKeyword.searchTermIsWholeWord(), originalKeyword.searchTermIsLiteral(), originalKeyword.getArtifactAttributeType(), originalKeyword.getSearchTerm()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
default:
|
||||
hits.add(new UniqueKeywordHit(chunkId, sourceID, KeywordSearchUtil.makeSnippet(content, hitMatcher, hit), hit, keywordListName, originalKeyword.searchTermIsWholeWord(), originalKeyword.searchTermIsLiteral(), originalKeyword.getArtifactAttributeType(), originalKeyword.getSearchTerm()));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} catch (Throwable error) {
|
||||
/*
|
||||
* NOTE: Matcher.find() is known to throw StackOverflowError in rare
|
||||
* cases (see JIRA-2700). StackOverflowError is an error, not an
|
||||
* exception, and therefore needs to be caught as a Throwable. When
|
||||
* this occurs we should re-throw the error as TskCoreException so
|
||||
* that it is logged by the calling method and move on to the next
|
||||
* Solr document.
|
||||
*/
|
||||
throw new TskCoreException("Failed to create keyword hits for chunk due to " + error.getMessage());
|
||||
}
|
||||
return hits;
|
||||
}
|
||||
|
||||
/**
|
||||
* Clean up the memory that is being used for the given job.
|
||||
*
|
||||
* @param context
|
||||
*/
|
||||
static void cleanup(IngestJobContext context) {
|
||||
Map<Long, Map<Keyword, Map<Keyword, List<UniqueKeywordHit>>>> jobMap = uniqueHitMap2.get(context.getJobId());
|
||||
if (jobMap != null) {
|
||||
jobMap.clear();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates the artifacts for the found KeywordHits. This method should be
|
||||
* called once per content object.
|
||||
*
|
||||
* @param context
|
||||
*/
|
||||
static void makeArtifacts(IngestJobContext context) throws TskException {
|
||||
|
||||
Map<Long, Map<Keyword, Map<Keyword, List<UniqueKeywordHit>>>> jobMap = uniqueHitMap2.get(context.getJobId());
|
||||
if (jobMap == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (Map.Entry<Long, Map<Keyword, Map<Keyword, List<UniqueKeywordHit>>>> mapBySource : jobMap.entrySet()) {
|
||||
Long sourceId = mapBySource.getKey();
|
||||
Map<Keyword, Map<Keyword, List<UniqueKeywordHit>>> mapByKeyword = mapBySource.getValue();
|
||||
|
||||
for (Map.Entry<Keyword, Map<Keyword, List<UniqueKeywordHit>>> item : mapByKeyword.entrySet()) {
|
||||
Keyword originalKeyword = item.getKey();
|
||||
Map<Keyword, List<UniqueKeywordHit>> map = item.getValue();
|
||||
|
||||
List<BlackboardArtifact> hitArtifacts = new ArrayList<>();
|
||||
if (!map.isEmpty()) {
|
||||
for (Map.Entry<Keyword, List<UniqueKeywordHit>> entry : map.entrySet()) {
|
||||
Keyword hitKeyword = entry.getKey();
|
||||
List<UniqueKeywordHit> hitList = entry.getValue();
|
||||
// Only create one hit for the document.
|
||||
// The first hit in the list should be the first one that
|
||||
// was found.
|
||||
if (!hitList.isEmpty()) {
|
||||
UniqueKeywordHit hit = hitList.get(0);
|
||||
SleuthkitCase tskCase = Case.getCurrentCase().getSleuthkitCase();
|
||||
Content content = tskCase.getContentById(hit.getContentID());
|
||||
BlackboardArtifact artifact;
|
||||
if (hit.isLiteral() && hit.isWholeWord()) {
|
||||
artifact = LuceneQuery.createKeywordHitArtifact(content, originalKeyword, hitKeyword, hit, hit.getSnippet(), hitKeyword.getListName(), sourceId);
|
||||
} else {
|
||||
artifact = RegexQuery.createKeywordHitArtifact(content, originalKeyword, hitKeyword, hit, hit.getSnippet(), hitKeyword.getListName(), sourceId);
|
||||
}
|
||||
// createKeywordHitArtifact has the potential to return null
|
||||
// when a CCN account is created.
|
||||
if (artifact != null) {
|
||||
hitArtifacts.add(artifact);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
if (!hitArtifacts.isEmpty()) {
|
||||
try {
|
||||
SleuthkitCase tskCase = Case.getCurrentCaseThrows().getSleuthkitCase();
|
||||
Blackboard blackboard = tskCase.getBlackboard();
|
||||
|
||||
blackboard.postArtifacts(hitArtifacts, "KeywordSearch", context.getJobId());
|
||||
hitArtifacts.clear();
|
||||
} catch (NoCurrentCaseException | Blackboard.BlackboardException ex) {
|
||||
logger.log(Level.SEVERE, "Failed to post KWH artifact to blackboard.", ex); //NON-NLS
|
||||
}
|
||||
}
|
||||
|
||||
if (context.fileIngestIsCancelled()) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Searches the chunk for exact matches and creates the appropriate keyword
|
||||
* hits.
|
||||
*
|
||||
* @param text
|
||||
* @param originalKeyword
|
||||
* @param sourceID
|
||||
*
|
||||
* @return
|
||||
*
|
||||
* @throws IOException
|
||||
*/
|
||||
public List<UniqueKeywordHit> getExactMatchHits(String text, Keyword originalKeyword, long sourceID, int chunkId, String keywordListName) throws IOException {
|
||||
final HashMap<String, String> keywordsFoundInThisDocument = new HashMap<>();
|
||||
|
||||
List<UniqueKeywordHit> hits = new ArrayList<>();
|
||||
Analyzer analyzer = new StandardAnalyzer();
|
||||
|
||||
//Get the tokens of the keyword
|
||||
List<String> keywordTokens = new ArrayList<>();
|
||||
try (TokenStream keywordstream = analyzer.tokenStream("field", originalKeyword.getSearchTerm())) {
|
||||
CharTermAttribute attr = keywordstream.addAttribute(CharTermAttribute.class);
|
||||
keywordstream.reset();
|
||||
while (keywordstream.incrementToken()) {
|
||||
keywordTokens.add(attr.toString());
|
||||
}
|
||||
}
|
||||
|
||||
try (TokenStream stream = analyzer.tokenStream("field", text)) {
|
||||
CharTermAttribute attr = stream.addAttribute(CharTermAttribute.class);
|
||||
OffsetAttribute offset = stream.addAttribute(OffsetAttribute.class);
|
||||
stream.reset();
|
||||
while (stream.incrementToken()) {
|
||||
if (!attr.toString().equals(keywordTokens.get(0))) {
|
||||
continue;
|
||||
}
|
||||
|
||||
int startOffset = offset.startOffset();
|
||||
int endOffset = offset.endOffset();
|
||||
boolean match = true;
|
||||
|
||||
for (int index = 1; index < keywordTokens.size(); index++) {
|
||||
if (stream.incrementToken()) {
|
||||
if (!attr.toString().equals(keywordTokens.get(index))) {
|
||||
match = false;
|
||||
break;
|
||||
} else {
|
||||
endOffset = offset.endOffset();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (match) {
|
||||
String hit = text.subSequence(startOffset, endOffset).toString();
|
||||
|
||||
// We will only create one KeywordHit instance per document for
|
||||
// a given hit.
|
||||
if (keywordsFoundInThisDocument.containsKey(hit)) {
|
||||
continue;
|
||||
}
|
||||
keywordsFoundInThisDocument.put(hit, hit);
|
||||
|
||||
hits.add(new UniqueKeywordHit(chunkId, sourceID, KeywordSearchUtil.makeSnippet(text, startOffset, endOffset, hit), hit, keywordListName, originalKeyword.searchTermIsWholeWord(), originalKeyword.searchTermIsLiteral(), originalKeyword.getArtifactAttributeType(), originalKeyword.getOriginalTerm()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return hits;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the keyword map for the given job and source.
|
||||
*
|
||||
* @param jobId
|
||||
* @param sourceID
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
static private Map<Keyword, Map<Keyword, List<UniqueKeywordHit>>> getMap(long jobId, long sourceID) {
|
||||
Map<Long, Map<Keyword, Map<Keyword, List<UniqueKeywordHit>>>> jobMap = uniqueHitMap2.get(jobId);
|
||||
if (jobMap == null) {
|
||||
jobMap = new ConcurrentHashMap<>();
|
||||
uniqueHitMap2.put(jobId, jobMap);
|
||||
}
|
||||
|
||||
Map<Keyword, Map<Keyword, List<UniqueKeywordHit>>> sourceMap = jobMap.get(sourceID);
|
||||
if (sourceMap == null) {
|
||||
sourceMap = new ConcurrentHashMap<>();
|
||||
jobMap.put(sourceID, sourceMap);
|
||||
}
|
||||
|
||||
return sourceMap;
|
||||
}
|
||||
|
||||
// KeywordHit is not unique enough for finding duplicates, this class
|
||||
// extends the KeywordHit class to make truely unique hits.
|
||||
static class UniqueKeywordHit extends KeywordHit {
|
||||
|
||||
private final String listName;
|
||||
private final boolean isLiteral;
|
||||
private final boolean isWholeWord;
|
||||
private final BlackboardAttribute.ATTRIBUTE_TYPE artifactAtrributeType;
|
||||
private final String originalSearchTerm;
|
||||
|
||||
UniqueKeywordHit(int chunkId, long sourceID, String snippet, String hit, String listName, boolean isWholeWord, boolean isLiteral, BlackboardAttribute.ATTRIBUTE_TYPE artifactAtrributeType, String originalSearchTerm) {
|
||||
super(chunkId, sourceID, snippet, hit);
|
||||
|
||||
this.listName = listName;
|
||||
this.isWholeWord = isWholeWord;
|
||||
this.isLiteral = isLiteral;
|
||||
this.artifactAtrributeType = artifactAtrributeType;
|
||||
this.originalSearchTerm = originalSearchTerm;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compareTo(KeywordHit other) {
|
||||
return compare((UniqueKeywordHit) other);
|
||||
}
|
||||
|
||||
private int compare(UniqueKeywordHit other) {
|
||||
return Comparator.comparing(UniqueKeywordHit::getSolrObjectId)
|
||||
.thenComparing(UniqueKeywordHit::getChunkId)
|
||||
.thenComparing(UniqueKeywordHit::getHit)
|
||||
.thenComparing(UniqueKeywordHit::getSnippet)
|
||||
.thenComparing(UniqueKeywordHit::isWholeWord)
|
||||
.thenComparing(UniqueKeywordHit::isLiteral)
|
||||
.thenComparing(UniqueKeywordHit::getArtifactAtrributeType)
|
||||
.thenComparing(UniqueKeywordHit::getOriginalSearchTerm)
|
||||
.thenComparing(UniqueKeywordHit::getListName)
|
||||
.compare(this, other);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
|
||||
if (null == obj) {
|
||||
return false;
|
||||
}
|
||||
if (getClass() != obj.getClass()) {
|
||||
return false;
|
||||
}
|
||||
final UniqueKeywordHit other = (UniqueKeywordHit) obj;
|
||||
|
||||
return getSnippet().equalsIgnoreCase(other.getSnippet())
|
||||
&& getSolrObjectId().equals(other.getSolrObjectId())
|
||||
&& getChunkId().equals(other.getChunkId())
|
||||
&& getHit().equalsIgnoreCase(other.getHit())
|
||||
&& listName.equalsIgnoreCase(other.getListName())
|
||||
&& isLiteral == other.isLiteral()
|
||||
&& isWholeWord == other.isWholeWord()
|
||||
&& originalSearchTerm.equalsIgnoreCase(other.getOriginalSearchTerm())
|
||||
&& (artifactAtrributeType != null ? artifactAtrributeType.equals(other.getArtifactAtrributeType()) : true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int hash = 3;
|
||||
hash = 67 * hash + super.hashCode();
|
||||
hash = 67 * hash + Objects.hashCode(this.listName);
|
||||
hash = 67 * hash + (this.isLiteral ? 1 : 0);
|
||||
hash = 67 * hash + (this.isWholeWord ? 1 : 0);
|
||||
hash = 67 * hash + Objects.hashCode(this.artifactAtrributeType);
|
||||
hash = 67 * hash + Objects.hashCode(this.originalSearchTerm);
|
||||
return hash;
|
||||
}
|
||||
|
||||
String getListName() {
|
||||
return listName;
|
||||
}
|
||||
|
||||
Boolean isLiteral() {
|
||||
return isLiteral;
|
||||
}
|
||||
|
||||
Boolean isWholeWord() {
|
||||
return isWholeWord;
|
||||
}
|
||||
|
||||
BlackboardAttribute.ATTRIBUTE_TYPE getArtifactAtrributeType() {
|
||||
return artifactAtrributeType;
|
||||
}
|
||||
|
||||
String getOriginalSearchTerm() {
|
||||
return originalSearchTerm;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
@ -211,8 +211,10 @@ public class Keyword {
|
||||
public int hashCode() {
|
||||
int hash = 7;
|
||||
hash = 17 * hash + this.searchTerm.hashCode();
|
||||
hash = 17 * hash + this.listName.hashCode();
|
||||
hash = 17 * hash + (this.isLiteral ? 1 : 0);
|
||||
hash = 17 * hash + (this.isWholeWord ? 1 : 0);
|
||||
hash = 17 * hash + this.originalTerm.hashCode();
|
||||
return hash;
|
||||
}
|
||||
|
||||
|
@ -21,10 +21,12 @@ package org.sleuthkit.autopsy.keywordsearch;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.util.Comparator;
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.sleuthkit.autopsy.casemodule.Case;
|
||||
import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException;
|
||||
import org.sleuthkit.datamodel.BlackboardAttribute;
|
||||
import org.sleuthkit.datamodel.SleuthkitCase;
|
||||
import org.sleuthkit.datamodel.TskCoreException;
|
||||
|
||||
@ -43,7 +45,7 @@ class KeywordHit implements Comparable<KeywordHit> {
|
||||
private final int chunkId;
|
||||
private final String snippet;
|
||||
private final String hit;
|
||||
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
@ -54,7 +56,7 @@ class KeywordHit implements Comparable<KeywordHit> {
|
||||
* For some searches (ie substring, regex) this will be
|
||||
* different than the search term.
|
||||
*
|
||||
*/
|
||||
*/
|
||||
KeywordHit(String solrDocumentId, String snippet, String hit) {
|
||||
this.snippet = StringUtils.stripToEmpty(snippet);
|
||||
this.hit = hit;
|
||||
@ -68,17 +70,30 @@ class KeywordHit implements Comparable<KeywordHit> {
|
||||
* documents. One contains object metadata (chunk #1) and the second and
|
||||
* subsequent documents contain chunks of the text.
|
||||
*/
|
||||
String[] split = solrDocumentId.split(Server.CHUNK_ID_SEPARATOR);
|
||||
if (split.length == 1) {
|
||||
//chunk 0 has only the bare document id without the chunk id.
|
||||
this.solrObjectId = Long.parseLong(solrDocumentId);
|
||||
this.chunkId = 0;
|
||||
if(!solrDocumentId.isEmpty()) {
|
||||
String[] split = solrDocumentId.split(Server.CHUNK_ID_SEPARATOR);
|
||||
if (split.length == 1) {
|
||||
//chunk 0 has only the bare document id without the chunk id.
|
||||
this.solrObjectId = Long.parseLong(solrDocumentId);
|
||||
this.chunkId = 0;
|
||||
} else {
|
||||
this.solrObjectId = Long.parseLong(split[0]);
|
||||
this.chunkId = Integer.parseInt(split[1]);
|
||||
}
|
||||
} else {
|
||||
this.solrObjectId = Long.parseLong(split[0]);
|
||||
this.chunkId = Integer.parseInt(split[1]);
|
||||
this.solrObjectId = 0;
|
||||
this.chunkId = 0;
|
||||
}
|
||||
}
|
||||
|
||||
KeywordHit(int chunkId, long sourceID, String snippet, String hit) {
|
||||
this.snippet = StringUtils.stripToEmpty(snippet);
|
||||
this.hit = hit;
|
||||
this.chunkId = chunkId;
|
||||
this.solrObjectId = sourceID;
|
||||
}
|
||||
|
||||
|
||||
String getHit() {
|
||||
return hit;
|
||||
}
|
||||
@ -87,11 +102,11 @@ class KeywordHit implements Comparable<KeywordHit> {
|
||||
return Long.toString(solrObjectId) + Server.CHUNK_ID_SEPARATOR + Long.toString(chunkId);
|
||||
}
|
||||
|
||||
long getSolrObjectId() {
|
||||
Long getSolrObjectId() {
|
||||
return this.solrObjectId;
|
||||
}
|
||||
|
||||
int getChunkId() {
|
||||
Integer getChunkId() {
|
||||
return this.chunkId;
|
||||
}
|
||||
|
||||
@ -102,7 +117,7 @@ class KeywordHit implements Comparable<KeywordHit> {
|
||||
String getSnippet() {
|
||||
return this.snippet;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get the content id associated with the content underlying hit.
|
||||
* For hits on files this will be the same as the object id associated
|
||||
@ -172,20 +187,25 @@ class KeywordHit implements Comparable<KeywordHit> {
|
||||
return false;
|
||||
}
|
||||
final KeywordHit other = (KeywordHit) obj;
|
||||
return this.compareTo(other) == 0;
|
||||
return compareTo(other) == 0;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int hash = 3;
|
||||
hash = 41 * hash + (int) this.solrObjectId + this.chunkId;
|
||||
int hash = 7;
|
||||
hash = 37 * hash + (int) (this.solrObjectId ^ (this.solrObjectId >>> 32));
|
||||
hash = 37 * hash + this.chunkId;
|
||||
hash = 37 * hash + Objects.hashCode(this.snippet);
|
||||
hash = 37 * hash + Objects.hashCode(this.hit);
|
||||
return hash;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compareTo(KeywordHit o) {
|
||||
public int compareTo(KeywordHit other) {
|
||||
return Comparator.comparing(KeywordHit::getSolrObjectId)
|
||||
.thenComparing(KeywordHit::getChunkId)
|
||||
.compare(this, o);
|
||||
.thenComparing(KeywordHit::getHit)
|
||||
.thenComparing(KeywordHit::getSnippet)
|
||||
.compare(this, other);
|
||||
}
|
||||
}
|
||||
|
@ -1,10 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
|
||||
<Form version="1.5" maxVersion="1.7" type="org.netbeans.modules.form.forminfo.JPanelFormInfo">
|
||||
<NonVisualComponents>
|
||||
<Component class="javax.swing.ButtonGroup" name="timeGroup">
|
||||
</Component>
|
||||
</NonVisualComponents>
|
||||
<AuxValues>
|
||||
<AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="1"/>
|
||||
<AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/>
|
||||
@ -47,23 +43,13 @@
|
||||
<EmptySpace type="separate" max="-2" attributes="0"/>
|
||||
<Component id="filesIndexedValue" min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<Component id="frequencyLabel" alignment="0" min="-2" max="-2" attributes="0"/>
|
||||
<Group type="102" alignment="0" attributes="0">
|
||||
<Component id="chunksLabel" linkSize="1" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace type="separate" max="-2" attributes="0"/>
|
||||
<Component id="chunksValLabel" min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<Group type="102" alignment="0" attributes="0">
|
||||
<EmptySpace min="16" pref="16" max="-2" attributes="0"/>
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Component id="timeRadioButton2" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="timeRadioButton1" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="timeRadioButton3" alignment="0" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="timeRadioButton4" alignment="0" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="timeRadioButton5" alignment="0" min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
</Group>
|
||||
<EmptySpace min="-2" pref="132" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
<EmptySpace max="32767" attributes="0"/>
|
||||
@ -90,19 +76,7 @@
|
||||
<Component id="skipNSRLCheckBox" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="showSnippetsCB" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="frequencyLabel" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="timeRadioButton1" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="timeRadioButton2" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="timeRadioButton3" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="timeRadioButton4" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="timeRadioButton5" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<EmptySpace type="unrelated" max="-2" attributes="0"/>
|
||||
<Group type="103" groupAlignment="1" attributes="0">
|
||||
<Component id="informationLabel" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="informationSeparator" min="-2" pref="7" max="-2" attributes="0"/>
|
||||
@ -119,7 +93,7 @@
|
||||
</Group>
|
||||
<EmptySpace type="unrelated" max="-2" attributes="0"/>
|
||||
<Component id="ingestWarningLabel" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace max="32767" attributes="0"/>
|
||||
<EmptySpace pref="151" max="32767" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
@ -184,65 +158,6 @@
|
||||
</Component>
|
||||
<Component class="javax.swing.JSeparator" name="informationSeparator">
|
||||
</Component>
|
||||
<Component class="javax.swing.JLabel" name="frequencyLabel">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/keywordsearch/Bundle.properties" key="KeywordSearchGlobalSearchSettingsPanel.frequencyLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
</Component>
|
||||
<Component class="javax.swing.JRadioButton" name="timeRadioButton1">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/keywordsearch/Bundle.properties" key="KeywordSearchGlobalSearchSettingsPanel.timeRadioButton1.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
<Property name="toolTipText" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/keywordsearch/Bundle.properties" key="KeywordSearchGlobalSearchSettingsPanel.timeRadioButton1.toolTipText" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<Events>
|
||||
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="timeRadioButton1ActionPerformed"/>
|
||||
</Events>
|
||||
</Component>
|
||||
<Component class="javax.swing.JRadioButton" name="timeRadioButton2">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/keywordsearch/Bundle.properties" key="KeywordSearchGlobalSearchSettingsPanel.timeRadioButton2.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
<Property name="toolTipText" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/keywordsearch/Bundle.properties" key="KeywordSearchGlobalSearchSettingsPanel.timeRadioButton2.toolTipText" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<Events>
|
||||
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="timeRadioButton2ActionPerformed"/>
|
||||
</Events>
|
||||
</Component>
|
||||
<Component class="javax.swing.JRadioButton" name="timeRadioButton3">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/keywordsearch/Bundle.properties" key="KeywordSearchGlobalSearchSettingsPanel.timeRadioButton3.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
<Property name="toolTipText" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/keywordsearch/Bundle.properties" key="KeywordSearchGlobalSearchSettingsPanel.timeRadioButton3.toolTipText" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<Events>
|
||||
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="timeRadioButton3ActionPerformed"/>
|
||||
</Events>
|
||||
</Component>
|
||||
<Component class="javax.swing.JRadioButton" name="timeRadioButton4">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/keywordsearch/Bundle.properties" key="KeywordSearchGlobalSearchSettingsPanel.timeRadioButton4.text_1" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
<Property name="toolTipText" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/keywordsearch/Bundle.properties" key="KeywordSearchGlobalSearchSettingsPanel.timeRadioButton4.toolTipText" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<Events>
|
||||
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="timeRadioButton4ActionPerformed"/>
|
||||
</Events>
|
||||
</Component>
|
||||
<Component class="javax.swing.JCheckBox" name="showSnippetsCB">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
@ -253,19 +168,6 @@
|
||||
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="showSnippetsCBActionPerformed"/>
|
||||
</Events>
|
||||
</Component>
|
||||
<Component class="javax.swing.JRadioButton" name="timeRadioButton5">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/keywordsearch/Bundle.properties" key="KeywordSearchGlobalSearchSettingsPanel.timeRadioButton5.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
<Property name="toolTipText" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/keywordsearch/Bundle.properties" key="KeywordSearchGlobalSearchSettingsPanel.timeRadioButton5.toolTipText" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<Events>
|
||||
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="timeRadioButton5ActionPerformed"/>
|
||||
</Events>
|
||||
</Component>
|
||||
<Component class="javax.swing.JLabel" name="ingestWarningLabel">
|
||||
<Properties>
|
||||
<Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor">
|
||||
|
@ -1,7 +1,7 @@
|
||||
/*
|
||||
* Autopsy Forensic Browser
|
||||
*
|
||||
* Copyright 2012-2018 Basis Technology Corp.
|
||||
* Copyright 2012-2022 Basis Technology Corp.
|
||||
* Contact: carrier <at> sleuthkit <dot> org
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
@ -26,9 +26,7 @@ import org.netbeans.spi.options.OptionsPanelController;
|
||||
import org.openide.util.NbBundle;
|
||||
import org.sleuthkit.autopsy.corecomponents.OptionsPanel;
|
||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||
import org.sleuthkit.autopsy.coreutils.PlatformUtil;
|
||||
import org.sleuthkit.autopsy.ingest.IngestManager;
|
||||
import org.sleuthkit.autopsy.keywordsearch.KeywordSearchIngestModule.UpdateFrequency;
|
||||
|
||||
/**
|
||||
* General, not per list, keyword search configuration and status display widget
|
||||
@ -53,31 +51,6 @@ class KeywordSearchGlobalSearchSettingsPanel extends javax.swing.JPanel implemen
|
||||
boolean ingestRunning = IngestManager.getInstance().isIngestRunning();
|
||||
ingestWarningLabel.setVisible(ingestRunning);
|
||||
skipNSRLCheckBox.setEnabled(!ingestRunning);
|
||||
setTimeSettingEnabled(!ingestRunning);
|
||||
|
||||
final UpdateFrequency curFreq = KeywordSearchSettings.getUpdateFrequency();
|
||||
switch (curFreq) {
|
||||
case FAST:
|
||||
timeRadioButton1.setSelected(true);
|
||||
break;
|
||||
case AVG:
|
||||
timeRadioButton2.setSelected(true);
|
||||
break;
|
||||
case SLOW:
|
||||
timeRadioButton3.setSelected(true);
|
||||
break;
|
||||
case SLOWEST:
|
||||
timeRadioButton4.setSelected(true);
|
||||
break;
|
||||
case NONE:
|
||||
timeRadioButton5.setSelected(true);
|
||||
break;
|
||||
case DEFAULT:
|
||||
default:
|
||||
// default value
|
||||
timeRadioButton3.setSelected(true);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -89,7 +62,6 @@ class KeywordSearchGlobalSearchSettingsPanel extends javax.swing.JPanel implemen
|
||||
// <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
|
||||
private void initComponents() {
|
||||
|
||||
timeGroup = new javax.swing.ButtonGroup();
|
||||
skipNSRLCheckBox = new javax.swing.JCheckBox();
|
||||
filesIndexedLabel = new javax.swing.JLabel();
|
||||
filesIndexedValue = new javax.swing.JLabel();
|
||||
@ -99,13 +71,7 @@ class KeywordSearchGlobalSearchSettingsPanel extends javax.swing.JPanel implemen
|
||||
informationLabel = new javax.swing.JLabel();
|
||||
settingsSeparator = new javax.swing.JSeparator();
|
||||
informationSeparator = new javax.swing.JSeparator();
|
||||
frequencyLabel = new javax.swing.JLabel();
|
||||
timeRadioButton1 = new javax.swing.JRadioButton();
|
||||
timeRadioButton2 = new javax.swing.JRadioButton();
|
||||
timeRadioButton3 = new javax.swing.JRadioButton();
|
||||
timeRadioButton4 = new javax.swing.JRadioButton();
|
||||
showSnippetsCB = new javax.swing.JCheckBox();
|
||||
timeRadioButton5 = new javax.swing.JRadioButton();
|
||||
ingestWarningLabel = new javax.swing.JLabel();
|
||||
|
||||
skipNSRLCheckBox.setText(org.openide.util.NbBundle.getMessage(KeywordSearchGlobalSearchSettingsPanel.class, "KeywordSearchGlobalSearchSettingsPanel.skipNSRLCheckBox.text")); // NOI18N
|
||||
@ -128,40 +94,6 @@ class KeywordSearchGlobalSearchSettingsPanel extends javax.swing.JPanel implemen
|
||||
|
||||
informationLabel.setText(org.openide.util.NbBundle.getMessage(KeywordSearchGlobalSearchSettingsPanel.class, "KeywordSearchGlobalSearchSettingsPanel.informationLabel.text")); // NOI18N
|
||||
|
||||
frequencyLabel.setText(org.openide.util.NbBundle.getMessage(KeywordSearchGlobalSearchSettingsPanel.class, "KeywordSearchGlobalSearchSettingsPanel.frequencyLabel.text")); // NOI18N
|
||||
|
||||
timeRadioButton1.setText(org.openide.util.NbBundle.getMessage(KeywordSearchGlobalSearchSettingsPanel.class, "KeywordSearchGlobalSearchSettingsPanel.timeRadioButton1.text")); // NOI18N
|
||||
timeRadioButton1.setToolTipText(org.openide.util.NbBundle.getMessage(KeywordSearchGlobalSearchSettingsPanel.class, "KeywordSearchGlobalSearchSettingsPanel.timeRadioButton1.toolTipText")); // NOI18N
|
||||
timeRadioButton1.addActionListener(new java.awt.event.ActionListener() {
|
||||
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||
timeRadioButton1ActionPerformed(evt);
|
||||
}
|
||||
});
|
||||
|
||||
timeRadioButton2.setText(org.openide.util.NbBundle.getMessage(KeywordSearchGlobalSearchSettingsPanel.class, "KeywordSearchGlobalSearchSettingsPanel.timeRadioButton2.text")); // NOI18N
|
||||
timeRadioButton2.setToolTipText(org.openide.util.NbBundle.getMessage(KeywordSearchGlobalSearchSettingsPanel.class, "KeywordSearchGlobalSearchSettingsPanel.timeRadioButton2.toolTipText")); // NOI18N
|
||||
timeRadioButton2.addActionListener(new java.awt.event.ActionListener() {
|
||||
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||
timeRadioButton2ActionPerformed(evt);
|
||||
}
|
||||
});
|
||||
|
||||
timeRadioButton3.setText(org.openide.util.NbBundle.getMessage(KeywordSearchGlobalSearchSettingsPanel.class, "KeywordSearchGlobalSearchSettingsPanel.timeRadioButton3.text")); // NOI18N
|
||||
timeRadioButton3.setToolTipText(org.openide.util.NbBundle.getMessage(KeywordSearchGlobalSearchSettingsPanel.class, "KeywordSearchGlobalSearchSettingsPanel.timeRadioButton3.toolTipText")); // NOI18N
|
||||
timeRadioButton3.addActionListener(new java.awt.event.ActionListener() {
|
||||
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||
timeRadioButton3ActionPerformed(evt);
|
||||
}
|
||||
});
|
||||
|
||||
timeRadioButton4.setText(org.openide.util.NbBundle.getMessage(KeywordSearchGlobalSearchSettingsPanel.class, "KeywordSearchGlobalSearchSettingsPanel.timeRadioButton4.text_1")); // NOI18N
|
||||
timeRadioButton4.setToolTipText(org.openide.util.NbBundle.getMessage(KeywordSearchGlobalSearchSettingsPanel.class, "KeywordSearchGlobalSearchSettingsPanel.timeRadioButton4.toolTipText")); // NOI18N
|
||||
timeRadioButton4.addActionListener(new java.awt.event.ActionListener() {
|
||||
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||
timeRadioButton4ActionPerformed(evt);
|
||||
}
|
||||
});
|
||||
|
||||
showSnippetsCB.setText(org.openide.util.NbBundle.getMessage(KeywordSearchGlobalSearchSettingsPanel.class, "KeywordSearchGlobalSearchSettingsPanel.showSnippetsCB.text")); // NOI18N
|
||||
showSnippetsCB.addActionListener(new java.awt.event.ActionListener() {
|
||||
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||
@ -169,14 +101,6 @@ class KeywordSearchGlobalSearchSettingsPanel extends javax.swing.JPanel implemen
|
||||
}
|
||||
});
|
||||
|
||||
timeRadioButton5.setText(org.openide.util.NbBundle.getMessage(KeywordSearchGlobalSearchSettingsPanel.class, "KeywordSearchGlobalSearchSettingsPanel.timeRadioButton5.text")); // NOI18N
|
||||
timeRadioButton5.setToolTipText(org.openide.util.NbBundle.getMessage(KeywordSearchGlobalSearchSettingsPanel.class, "KeywordSearchGlobalSearchSettingsPanel.timeRadioButton5.toolTipText")); // NOI18N
|
||||
timeRadioButton5.addActionListener(new java.awt.event.ActionListener() {
|
||||
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||
timeRadioButton5ActionPerformed(evt);
|
||||
}
|
||||
});
|
||||
|
||||
ingestWarningLabel.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/modules/hashdatabase/warning16.png"))); // NOI18N
|
||||
ingestWarningLabel.setText(org.openide.util.NbBundle.getMessage(KeywordSearchGlobalSearchSettingsPanel.class, "KeywordSearchGlobalSearchSettingsPanel.ingestWarningLabel.text")); // NOI18N
|
||||
|
||||
@ -207,19 +131,11 @@ class KeywordSearchGlobalSearchSettingsPanel extends javax.swing.JPanel implemen
|
||||
.addComponent(filesIndexedLabel)
|
||||
.addGap(18, 18, 18)
|
||||
.addComponent(filesIndexedValue))
|
||||
.addComponent(frequencyLabel)
|
||||
.addGroup(layout.createSequentialGroup()
|
||||
.addComponent(chunksLabel)
|
||||
.addGap(18, 18, 18)
|
||||
.addComponent(chunksValLabel))
|
||||
.addGroup(layout.createSequentialGroup()
|
||||
.addGap(16, 16, 16)
|
||||
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addComponent(timeRadioButton2)
|
||||
.addComponent(timeRadioButton1)
|
||||
.addComponent(timeRadioButton3)
|
||||
.addComponent(timeRadioButton4)
|
||||
.addComponent(timeRadioButton5))))))
|
||||
.addComponent(chunksValLabel)))
|
||||
.addGap(132, 132, 132)))
|
||||
.addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
|
||||
.addGroup(layout.createSequentialGroup()
|
||||
.addComponent(settingsLabel)
|
||||
@ -241,19 +157,7 @@ class KeywordSearchGlobalSearchSettingsPanel extends javax.swing.JPanel implemen
|
||||
.addComponent(skipNSRLCheckBox)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(showSnippetsCB)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(frequencyLabel)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(timeRadioButton1)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(timeRadioButton2)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(timeRadioButton3)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(timeRadioButton4)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(timeRadioButton5)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
|
||||
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
|
||||
.addComponent(informationLabel)
|
||||
.addComponent(informationSeparator, javax.swing.GroupLayout.PREFERRED_SIZE, 7, javax.swing.GroupLayout.PREFERRED_SIZE))
|
||||
@ -267,14 +171,10 @@ class KeywordSearchGlobalSearchSettingsPanel extends javax.swing.JPanel implemen
|
||||
.addComponent(chunksValLabel))
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
|
||||
.addComponent(ingestWarningLabel)
|
||||
.addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
|
||||
.addContainerGap(151, Short.MAX_VALUE))
|
||||
);
|
||||
}// </editor-fold>//GEN-END:initComponents
|
||||
|
||||
private void timeRadioButton5ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_timeRadioButton5ActionPerformed
|
||||
firePropertyChange(OptionsPanelController.PROP_CHANGED, null, null);
|
||||
}//GEN-LAST:event_timeRadioButton5ActionPerformed
|
||||
|
||||
private void skipNSRLCheckBoxActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_skipNSRLCheckBoxActionPerformed
|
||||
firePropertyChange(OptionsPanelController.PROP_CHANGED, null, null);
|
||||
}//GEN-LAST:event_skipNSRLCheckBoxActionPerformed
|
||||
@ -283,28 +183,11 @@ class KeywordSearchGlobalSearchSettingsPanel extends javax.swing.JPanel implemen
|
||||
firePropertyChange(OptionsPanelController.PROP_CHANGED, null, null);
|
||||
}//GEN-LAST:event_showSnippetsCBActionPerformed
|
||||
|
||||
private void timeRadioButton1ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_timeRadioButton1ActionPerformed
|
||||
firePropertyChange(OptionsPanelController.PROP_CHANGED, null, null);
|
||||
}//GEN-LAST:event_timeRadioButton1ActionPerformed
|
||||
|
||||
private void timeRadioButton2ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_timeRadioButton2ActionPerformed
|
||||
firePropertyChange(OptionsPanelController.PROP_CHANGED, null, null);
|
||||
}//GEN-LAST:event_timeRadioButton2ActionPerformed
|
||||
|
||||
private void timeRadioButton3ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_timeRadioButton3ActionPerformed
|
||||
firePropertyChange(OptionsPanelController.PROP_CHANGED, null, null);
|
||||
}//GEN-LAST:event_timeRadioButton3ActionPerformed
|
||||
|
||||
private void timeRadioButton4ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_timeRadioButton4ActionPerformed
|
||||
firePropertyChange(OptionsPanelController.PROP_CHANGED, null, null);
|
||||
}//GEN-LAST:event_timeRadioButton4ActionPerformed
|
||||
|
||||
// Variables declaration - do not modify//GEN-BEGIN:variables
|
||||
private javax.swing.JLabel chunksLabel;
|
||||
private javax.swing.JLabel chunksValLabel;
|
||||
private javax.swing.JLabel filesIndexedLabel;
|
||||
private javax.swing.JLabel filesIndexedValue;
|
||||
private javax.swing.JLabel frequencyLabel;
|
||||
private javax.swing.JLabel informationLabel;
|
||||
private javax.swing.JSeparator informationSeparator;
|
||||
private javax.swing.JLabel ingestWarningLabel;
|
||||
@ -312,18 +195,11 @@ class KeywordSearchGlobalSearchSettingsPanel extends javax.swing.JPanel implemen
|
||||
private javax.swing.JSeparator settingsSeparator;
|
||||
private javax.swing.JCheckBox showSnippetsCB;
|
||||
private javax.swing.JCheckBox skipNSRLCheckBox;
|
||||
private javax.swing.ButtonGroup timeGroup;
|
||||
private javax.swing.JRadioButton timeRadioButton1;
|
||||
private javax.swing.JRadioButton timeRadioButton2;
|
||||
private javax.swing.JRadioButton timeRadioButton3;
|
||||
private javax.swing.JRadioButton timeRadioButton4;
|
||||
private javax.swing.JRadioButton timeRadioButton5;
|
||||
// End of variables declaration//GEN-END:variables
|
||||
|
||||
@Override
|
||||
public void store() {
|
||||
KeywordSearchSettings.setSkipKnown(skipNSRLCheckBox.isSelected());
|
||||
KeywordSearchSettings.setUpdateFrequency(getSelectedTimeValue());
|
||||
KeywordSearchSettings.setShowSnippets(showSnippetsCB.isSelected());
|
||||
}
|
||||
|
||||
@ -332,40 +208,10 @@ class KeywordSearchGlobalSearchSettingsPanel extends javax.swing.JPanel implemen
|
||||
activateWidgets();
|
||||
}
|
||||
|
||||
private void setTimeSettingEnabled(boolean enabled) {
|
||||
timeRadioButton1.setEnabled(enabled);
|
||||
timeRadioButton2.setEnabled(enabled);
|
||||
timeRadioButton3.setEnabled(enabled);
|
||||
timeRadioButton4.setEnabled(enabled);
|
||||
timeRadioButton5.setEnabled(enabled);
|
||||
frequencyLabel.setEnabled(enabled);
|
||||
}
|
||||
|
||||
private UpdateFrequency getSelectedTimeValue() {
|
||||
if (timeRadioButton1.isSelected()) {
|
||||
return UpdateFrequency.FAST;
|
||||
} else if (timeRadioButton2.isSelected()) {
|
||||
return UpdateFrequency.AVG;
|
||||
} else if (timeRadioButton3.isSelected()) {
|
||||
return UpdateFrequency.SLOW;
|
||||
} else if (timeRadioButton4.isSelected()) {
|
||||
return UpdateFrequency.SLOWEST;
|
||||
} else if (timeRadioButton5.isSelected()) {
|
||||
return UpdateFrequency.NONE;
|
||||
}
|
||||
return UpdateFrequency.DEFAULT;
|
||||
}
|
||||
|
||||
@NbBundle.Messages({"KeywordSearchGlobalSearchSettingsPanel.customizeComponents.windowsOCR=Enable Optical Character Recognition (OCR) (Requires Windows 64-bit)",
|
||||
"KeywordSearchGlobalSearchSettingsPanel.customizeComponents.windowsLimitedOCR=Only process images which are over 100KB in size or extracted from a document. (Beta) (Requires Windows 64-bit)"})
|
||||
private void customizeComponents() {
|
||||
|
||||
timeGroup.add(timeRadioButton1);
|
||||
timeGroup.add(timeRadioButton2);
|
||||
timeGroup.add(timeRadioButton3);
|
||||
timeGroup.add(timeRadioButton4);
|
||||
timeGroup.add(timeRadioButton5);
|
||||
|
||||
this.skipNSRLCheckBox.setSelected(KeywordSearchSettings.getSkipKnown());
|
||||
|
||||
try {
|
||||
|
@ -1,7 +1,7 @@
|
||||
/*
|
||||
* Autopsy Forensic Browser
|
||||
*
|
||||
* Copyright 2011-2021 Basis Technology Corp.
|
||||
* Copyright 2011-2023 Basis Technology Corp.
|
||||
* Contact: carrier <at> sleuthkit <dot> org
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
@ -38,6 +38,7 @@ import java.util.concurrent.atomic.AtomicInteger;
|
||||
import java.util.logging.Level;
|
||||
import java.util.stream.Collectors;
|
||||
import org.apache.tika.mime.MimeTypes;
|
||||
import org.openide.util.Exceptions;
|
||||
import org.openide.util.Lookup;
|
||||
import org.openide.util.NbBundle;
|
||||
import org.openide.util.NbBundle.Messages;
|
||||
@ -69,6 +70,7 @@ import org.sleuthkit.datamodel.BlackboardAttribute;
|
||||
import org.sleuthkit.datamodel.TskCoreException;
|
||||
import org.sleuthkit.datamodel.TskData;
|
||||
import org.sleuthkit.datamodel.TskData.FileKnown;
|
||||
import org.sleuthkit.datamodel.TskException;
|
||||
|
||||
/**
|
||||
* An ingest module on a file level Performs indexing of allocated and Solr
|
||||
@ -149,7 +151,7 @@ public final class KeywordSearchIngestModule implements FileIngestModule {
|
||||
.build();
|
||||
|
||||
private static final String IMAGE_MIME_TYPE_PREFIX = "image/";
|
||||
|
||||
|
||||
// documents where OCR is performed
|
||||
private static final ImmutableSet<String> OCR_DOCUMENTS = ImmutableSet.of(
|
||||
"application/pdf",
|
||||
@ -160,7 +162,7 @@ public final class KeywordSearchIngestModule implements FileIngestModule {
|
||||
"application/vnd.ms-excel",
|
||||
"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
|
||||
);
|
||||
|
||||
|
||||
/**
|
||||
* Options for this extractor
|
||||
*/
|
||||
@ -169,33 +171,13 @@ public final class KeywordSearchIngestModule implements FileIngestModule {
|
||||
EXTRACT_UTF8, ///< extract UTF8 text, true/false
|
||||
};
|
||||
|
||||
enum UpdateFrequency {
|
||||
|
||||
FAST(20),
|
||||
AVG(10),
|
||||
SLOW(5),
|
||||
SLOWEST(1),
|
||||
NONE(Integer.MAX_VALUE),
|
||||
DEFAULT(5);
|
||||
private final int time;
|
||||
|
||||
UpdateFrequency(int time) {
|
||||
this.time = time;
|
||||
}
|
||||
|
||||
int getTime() {
|
||||
return time;
|
||||
}
|
||||
};
|
||||
private static final Logger logger = Logger.getLogger(KeywordSearchIngestModule.class.getName());
|
||||
private final IngestServices services = IngestServices.getInstance();
|
||||
private Ingester ingester = null;
|
||||
private Indexer indexer;
|
||||
private FileTypeDetector fileTypeDetector;
|
||||
//only search images from current ingest, not images previously ingested/indexed
|
||||
//accessed read-only by searcher thread
|
||||
|
||||
private boolean startedSearching = false;
|
||||
private Lookup stringsExtractionContext;
|
||||
private final KeywordSearchJobSettings settings;
|
||||
private boolean initialized = false;
|
||||
@ -257,18 +239,21 @@ public final class KeywordSearchIngestModule implements FileIngestModule {
|
||||
initialized = false;
|
||||
jobId = context.getJobId();
|
||||
|
||||
Server server = KeywordSearch.getServer();
|
||||
if (server.coreIsOpen() == false) {
|
||||
throw new IngestModuleException(Bundle.KeywordSearchIngestModule_startUp_noOpenCore_msg());
|
||||
}
|
||||
|
||||
try {
|
||||
Index indexInfo = server.getIndexInfo();
|
||||
if (!indexInfo.isCompatible(IndexFinder.getCurrentSchemaVersion())) {
|
||||
throw new IngestModuleException(Bundle.KeywordSearchIngestModule_startupException_indexSchemaNotSupported(indexInfo.getSchemaVersion()));
|
||||
Server server = null;
|
||||
if (settings.isIndexToSolrEnabled()) {
|
||||
server = KeywordSearch.getServer();
|
||||
if (server.coreIsOpen() == false) {
|
||||
throw new IngestModuleException(Bundle.KeywordSearchIngestModule_startUp_noOpenCore_msg());
|
||||
}
|
||||
|
||||
try {
|
||||
Index indexInfo = server.getIndexInfo();
|
||||
if (!indexInfo.isCompatible(IndexFinder.getCurrentSchemaVersion())) {
|
||||
throw new IngestModuleException(Bundle.KeywordSearchIngestModule_startupException_indexSchemaNotSupported(indexInfo.getSchemaVersion()));
|
||||
}
|
||||
} catch (NoOpenCoreException ex) {
|
||||
throw new IngestModuleException(Bundle.KeywordSearchIngestModule_startupMessage_failedToGetIndexSchema(), ex);
|
||||
}
|
||||
} catch (NoOpenCoreException ex) {
|
||||
throw new IngestModuleException(Bundle.KeywordSearchIngestModule_startupMessage_failedToGetIndexSchema(), ex);
|
||||
}
|
||||
|
||||
try {
|
||||
@ -307,22 +292,24 @@ public final class KeywordSearchIngestModule implements FileIngestModule {
|
||||
}
|
||||
} else {
|
||||
// for single-user cases need to verify connection to local SOLR service
|
||||
try {
|
||||
if (!server.isLocalSolrRunning()) {
|
||||
throw new IngestModuleException(Bundle.KeywordSearchIngestModule_init_tryStopSolrMsg(Bundle.KeywordSearchIngestModule_init_badInitMsg()));
|
||||
// server will be null if indexing is disabled
|
||||
if (server != null) {
|
||||
try {
|
||||
if (!server.isLocalSolrRunning()) {
|
||||
throw new IngestModuleException(Bundle.KeywordSearchIngestModule_init_tryStopSolrMsg(Bundle.KeywordSearchIngestModule_init_badInitMsg()));
|
||||
}
|
||||
} catch (KeywordSearchModuleException ex) {
|
||||
//this means Solr is not properly initialized
|
||||
throw new IngestModuleException(Bundle.KeywordSearchIngestModule_init_tryStopSolrMsg(Bundle.KeywordSearchIngestModule_init_badInitMsg()), ex);
|
||||
}
|
||||
try {
|
||||
// make an actual query to verify that server is responding
|
||||
// we had cases where getStatus was OK, but the connection resulted in a 404
|
||||
server.queryNumIndexedDocuments();
|
||||
} catch (KeywordSearchModuleException | NoOpenCoreException ex) {
|
||||
throw new IngestModuleException(Bundle.KeywordSearchIngestModule_init_exception_errConnToSolr_msg(ex.getMessage()), ex);
|
||||
}
|
||||
} catch (KeywordSearchModuleException ex) {
|
||||
//this means Solr is not properly initialized
|
||||
throw new IngestModuleException(Bundle.KeywordSearchIngestModule_init_tryStopSolrMsg(Bundle.KeywordSearchIngestModule_init_badInitMsg()), ex);
|
||||
}
|
||||
try {
|
||||
// make an actual query to verify that server is responding
|
||||
// we had cases where getStatus was OK, but the connection resulted in a 404
|
||||
server.queryNumIndexedDocuments();
|
||||
} catch (KeywordSearchModuleException | NoOpenCoreException ex) {
|
||||
throw new IngestModuleException(Bundle.KeywordSearchIngestModule_init_exception_errConnToSolr_msg(ex.getMessage()), ex);
|
||||
}
|
||||
|
||||
// check if this job has any searchable keywords
|
||||
List<KeywordList> keywordLists = XmlKeywordSearchList.getCurrent().getListsL();
|
||||
boolean hasKeywordsForSearch = false;
|
||||
@ -347,7 +334,6 @@ public final class KeywordSearchIngestModule implements FileIngestModule {
|
||||
|
||||
stringsExtractionContext = Lookups.fixed(stringsConfig);
|
||||
|
||||
indexer = new Indexer();
|
||||
initialized = true;
|
||||
}
|
||||
|
||||
@ -389,7 +375,7 @@ public final class KeywordSearchIngestModule implements FileIngestModule {
|
||||
if (context.fileIngestIsCancelled()) {
|
||||
return ProcessResult.OK;
|
||||
}
|
||||
indexer.indexFile(extractorOpt, abstractFile, mimeType, false);
|
||||
searchFile(extractorOpt, abstractFile, mimeType, false);
|
||||
return ProcessResult.OK;
|
||||
}
|
||||
|
||||
@ -397,17 +383,7 @@ public final class KeywordSearchIngestModule implements FileIngestModule {
|
||||
if (context.fileIngestIsCancelled()) {
|
||||
return ProcessResult.OK;
|
||||
}
|
||||
indexer.indexFile(extractorOpt, abstractFile, mimeType, true);
|
||||
|
||||
// Start searching if it hasn't started already
|
||||
if (!startedSearching) {
|
||||
if (context.fileIngestIsCancelled()) {
|
||||
return ProcessResult.OK;
|
||||
}
|
||||
List<String> keywordListNames = settings.getNamesOfEnabledKeyWordLists();
|
||||
IngestSearchRunner.getInstance().startJob(context, keywordListNames);
|
||||
startedSearching = true;
|
||||
}
|
||||
searchFile(extractorOpt, abstractFile, mimeType, true);
|
||||
|
||||
return ProcessResult.OK;
|
||||
}
|
||||
@ -425,17 +401,22 @@ public final class KeywordSearchIngestModule implements FileIngestModule {
|
||||
}
|
||||
|
||||
if (context.fileIngestIsCancelled()) {
|
||||
logger.log(Level.INFO, "Keyword search ingest module instance {0} stopping search job due to ingest cancellation", instanceNum); //NON-NLS
|
||||
IngestSearchRunner.getInstance().stopJob(jobId);
|
||||
logger.log(Level.INFO, "Keyword search ingest module instance {0} stopping due to ingest cancellation", instanceNum); //NON-NLS
|
||||
cleanup();
|
||||
return;
|
||||
}
|
||||
|
||||
// Remove from the search list and trigger final commit and final search
|
||||
IngestSearchRunner.getInstance().endJob(jobId);
|
||||
|
||||
// We only need to post the summary msg from the last module per job
|
||||
if (refCounter.decrementAndGet(jobId) == 0) {
|
||||
|
||||
try {
|
||||
InlineSearcher.makeArtifacts(context);
|
||||
InlineSearcher.cleanup(context);
|
||||
Ingester.getDefault().commit();
|
||||
} catch (TskException ex) {
|
||||
logger.log(Level.SEVERE, String.format("Failed to create search ingest artifacts for job %d", context.getJobId()), ex);
|
||||
}
|
||||
|
||||
try {
|
||||
final int numIndexedFiles = KeywordSearch.getServer().queryNumIndexedFiles();
|
||||
logger.log(Level.INFO, "Indexed files count: {0}", numIndexedFiles); //NON-NLS
|
||||
@ -462,7 +443,7 @@ public final class KeywordSearchIngestModule implements FileIngestModule {
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if file should have OCR performed on it when limited OCR
|
||||
* Returns true if file should have OCR performed on it when limited OCR
|
||||
* setting is specified.
|
||||
*
|
||||
* @param aFile The abstract file.
|
||||
@ -475,12 +456,12 @@ public final class KeywordSearchIngestModule implements FileIngestModule {
|
||||
if (OCR_DOCUMENTS.contains(mimeType)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
if (mimeType.startsWith(IMAGE_MIME_TYPE_PREFIX)) {
|
||||
return aFile.getSize() > LIMITED_OCR_SIZE_MIN
|
||||
|| aFile.getType() == TskData.TSK_DB_FILES_TYPE_ENUM.DERIVED;
|
||||
|| aFile.getType() == TskData.TSK_DB_FILES_TYPE_ENUM.DERIVED;
|
||||
}
|
||||
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -562,317 +543,319 @@ public final class KeywordSearchIngestModule implements FileIngestModule {
|
||||
* File indexer, processes and indexes known/allocated files,
|
||||
* unknown/unallocated files and directories accordingly
|
||||
*/
|
||||
private class Indexer {
|
||||
|
||||
private final Logger logger = Logger.getLogger(Indexer.class.getName());
|
||||
|
||||
/**
|
||||
* Extract text with Tika or other text extraction modules (by
|
||||
* streaming) from the file Divide the file into chunks and index the
|
||||
* chunks
|
||||
*
|
||||
* @param extractorOptional The textExtractor to use with this file or
|
||||
* empty.
|
||||
* @param aFile file to extract strings from, divide into
|
||||
* chunks and index
|
||||
* @param extractedMetadata Map that will be populated with the file's
|
||||
* metadata.
|
||||
*
|
||||
* @return true if the file was text_ingested, false otherwise
|
||||
*
|
||||
* @throws IngesterException exception thrown if indexing failed
|
||||
*/
|
||||
private boolean extractTextAndIndex(Optional<TextExtractor> extractorOptional, AbstractFile aFile,
|
||||
/**
|
||||
* Extract text with Tika or other text extraction modules (by streaming)
|
||||
* from the file Divide the file into chunks and index the chunks
|
||||
*
|
||||
* @param extractorOptional The textExtractor to use with this file or
|
||||
* empty.
|
||||
* @param aFile file to extract strings from, divide into chunks
|
||||
* and index
|
||||
* @param extractedMetadata Map that will be populated with the file's
|
||||
* metadata.
|
||||
*
|
||||
* @return true if the file was text_ingested, false otherwise
|
||||
*
|
||||
* @throws IngesterException exception thrown if indexing failed
|
||||
*/
|
||||
private boolean extractTextAndSearch(Optional<TextExtractor> extractorOptional, AbstractFile aFile,
|
||||
Map<String, String> extractedMetadata) throws IngesterException {
|
||||
|
||||
try {
|
||||
if (!extractorOptional.isPresent()) {
|
||||
return false;
|
||||
}
|
||||
TextExtractor extractor = extractorOptional.get();
|
||||
Reader fileText = extractor.getReader();
|
||||
Reader finalReader;
|
||||
try {
|
||||
Map<String, String> metadata = extractor.getMetadata();
|
||||
if (!metadata.isEmpty()) {
|
||||
// Creating the metadata artifact here causes occasional problems
|
||||
// when indexing the text, so we save the metadata map to
|
||||
// use after this method is complete.
|
||||
extractedMetadata.putAll(metadata);
|
||||
}
|
||||
CharSource formattedMetadata = getMetaDataCharSource(metadata);
|
||||
//Append the metadata to end of the file text
|
||||
finalReader = CharSource.concat(new CharSource() {
|
||||
//Wrap fileText reader for concatenation
|
||||
@Override
|
||||
public Reader openStream() throws IOException {
|
||||
return fileText;
|
||||
}
|
||||
}, formattedMetadata).openStream();
|
||||
} catch (IOException ex) {
|
||||
logger.log(Level.WARNING, String.format("Could not format extracted metadata for file %s [id=%d]",
|
||||
try {
|
||||
if (!extractorOptional.isPresent()) {
|
||||
return false;
|
||||
}
|
||||
//divide into chunks and index
|
||||
Ingester.getDefault().search(getTikaOrTextExtractor(extractorOptional, aFile, extractedMetadata), aFile.getId(), aFile.getName(), aFile, context, true,settings.isIndexToSolrEnabled(), settings.getNamesOfEnabledKeyWordLists());
|
||||
|
||||
} catch (TextExtractor.InitReaderException ex) {
|
||||
return false;
|
||||
} catch(Exception ex) {
|
||||
logger.log(Level.WARNING, String.format("Failed to search file %s [id=%d]",
|
||||
aFile.getName(), aFile.getId()), ex);
|
||||
//Just send file text.
|
||||
finalReader = fileText;
|
||||
}
|
||||
//divide into chunks and index
|
||||
return Ingester.getDefault().indexText(finalReader, aFile.getId(), aFile.getName(), aFile, context);
|
||||
} catch (TextExtractor.InitReaderException ex) {
|
||||
// Text extractor could not be initialized. No text will be extracted.
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private void createMetadataArtifact(AbstractFile aFile, Map<String, String> metadata) {
|
||||
|
||||
String moduleName = KeywordSearchIngestModule.class.getName();
|
||||
|
||||
Collection<BlackboardAttribute> attributes = new ArrayList<>();
|
||||
Collection<BlackboardArtifact> bbartifacts = new ArrayList<>();
|
||||
for (Map.Entry<String, String> entry : metadata.entrySet()) {
|
||||
if (METADATA_TYPES_MAP.containsKey(entry.getKey())) {
|
||||
BlackboardAttribute bba = checkAttribute(entry.getKey(), entry.getValue());
|
||||
if (bba != null) {
|
||||
attributes.add(bba);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!attributes.isEmpty()) {
|
||||
try {
|
||||
BlackboardArtifact bbart = aFile.newDataArtifact(new BlackboardArtifact.Type(BlackboardArtifact.ARTIFACT_TYPE.TSK_METADATA), attributes);
|
||||
bbartifacts.add(bbart);
|
||||
} catch (TskCoreException ex) {
|
||||
// Log error and return to continue processing
|
||||
logger.log(Level.WARNING, String.format("Error creating or adding metadata artifact for file %s.", aFile.getParentPath() + aFile.getName()), ex); //NON-NLS
|
||||
return;
|
||||
}
|
||||
if (!bbartifacts.isEmpty()) {
|
||||
try {
|
||||
Case.getCurrentCaseThrows().getSleuthkitCase().getBlackboard().postArtifacts(bbartifacts, moduleName, jobId);
|
||||
} catch (NoCurrentCaseException | Blackboard.BlackboardException ex) {
|
||||
// Log error and return to continue processing
|
||||
logger.log(Level.WARNING, String.format("Unable to post blackboard artifacts for file $s.", aFile.getParentPath() + aFile.getName()), ex); //NON-NLS
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private BlackboardAttribute checkAttribute(String key, String value) {
|
||||
String moduleName = KeywordSearchIngestModule.class.getName();
|
||||
if (!value.isEmpty() && value.charAt(0) != ' ') {
|
||||
if (METADATA_DATE_TYPES.contains(key)) {
|
||||
SimpleDateFormat metadataDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", US);
|
||||
Long metadataDateTime = Long.valueOf(0);
|
||||
try {
|
||||
String metadataDate = value.replaceAll("T", " ").replaceAll("Z", "");
|
||||
Date usedDate = metadataDateFormat.parse(metadataDate);
|
||||
metadataDateTime = usedDate.getTime() / 1000;
|
||||
return new BlackboardAttribute(METADATA_TYPES_MAP.get(key), moduleName, metadataDateTime);
|
||||
} catch (ParseException ex) {
|
||||
// catching error and displaying date that could not be parsed then will continue on.
|
||||
logger.log(Level.WARNING, String.format("Failed to parse date/time %s for metadata attribute %s.", value, key), ex); //NON-NLS
|
||||
return null;
|
||||
}
|
||||
} else {
|
||||
return new BlackboardAttribute(METADATA_TYPES_MAP.get(key), moduleName, value);
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Pretty print the text extractor metadata.
|
||||
*
|
||||
* @param metadata The Metadata map to wrap as a CharSource
|
||||
*
|
||||
* @return A CharSource for the given Metadata
|
||||
*/
|
||||
@NbBundle.Messages({
|
||||
"KeywordSearchIngestModule.metadataTitle=METADATA"
|
||||
})
|
||||
private CharSource getMetaDataCharSource(Map<String, String> metadata) {
|
||||
return CharSource.wrap(new StringBuilder(
|
||||
String.format("\n\n------------------------------%s------------------------------\n\n",
|
||||
Bundle.KeywordSearchIngestModule_metadataTitle()))
|
||||
.append(metadata.entrySet().stream().sorted(Map.Entry.comparingByKey())
|
||||
.map(entry -> entry.getKey() + ": " + entry.getValue())
|
||||
.collect(Collectors.joining("\n"))
|
||||
));
|
||||
}
|
||||
|
||||
/**
|
||||
* Extract strings using heuristics from the file and add to index.
|
||||
*
|
||||
* @param aFile file to extract strings from, divide into chunks and
|
||||
* index
|
||||
*
|
||||
* @return true if the file was text_ingested, false otherwise
|
||||
*/
|
||||
private boolean extractStringsAndIndex(AbstractFile aFile) {
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private Reader getTikaOrTextExtractor(Optional<TextExtractor> extractorOptional, AbstractFile aFile,
|
||||
Map<String, String> extractedMetadata) throws TextExtractor.InitReaderException {
|
||||
|
||||
TextExtractor extractor = extractorOptional.get();
|
||||
Reader fileText = extractor.getReader();
|
||||
Reader finalReader;
|
||||
try {
|
||||
if (context.fileIngestIsCancelled()) {
|
||||
return true;
|
||||
Map<String, String> metadata = extractor.getMetadata();
|
||||
if (!metadata.isEmpty()) {
|
||||
// Creating the metadata artifact here causes occasional problems
|
||||
// when indexing the text, so we save the metadata map to
|
||||
// use after this method is complete.
|
||||
extractedMetadata.putAll(metadata);
|
||||
}
|
||||
TextExtractor stringsExtractor = TextExtractorFactory.getStringsExtractor(aFile, stringsExtractionContext);
|
||||
Reader extractedTextReader = stringsExtractor.getReader();
|
||||
if (Ingester.getDefault().indexStrings(extractedTextReader, aFile.getId(), aFile.getName(), aFile, KeywordSearchIngestModule.this.context)) {
|
||||
putIngestStatus(jobId, aFile.getId(), IngestStatus.STRINGS_INGESTED);
|
||||
return true;
|
||||
} else {
|
||||
logger.log(Level.WARNING, "Failed to extract strings and ingest, file ''{0}'' (id: {1}).", new Object[]{aFile.getName(), aFile.getId()}); //NON-NLS
|
||||
putIngestStatus(jobId, aFile.getId(), IngestStatus.SKIPPED_ERROR_TEXTEXTRACT);
|
||||
return false;
|
||||
CharSource formattedMetadata = getMetaDataCharSource(metadata);
|
||||
//Append the metadata to end of the file text
|
||||
finalReader = CharSource.concat(new CharSource() {
|
||||
//Wrap fileText reader for concatenation
|
||||
@Override
|
||||
public Reader openStream() throws IOException {
|
||||
return fileText;
|
||||
}
|
||||
}, formattedMetadata).openStream();
|
||||
} catch (IOException ex) {
|
||||
logger.log(Level.WARNING, String.format("Could not format extracted metadata for file %s [id=%d]",
|
||||
aFile.getName(), aFile.getId()), ex);
|
||||
//Just send file text.
|
||||
finalReader = fileText;
|
||||
}
|
||||
//divide into chunks and index
|
||||
return finalReader;
|
||||
|
||||
}
|
||||
|
||||
private void createMetadataArtifact(AbstractFile aFile, Map<String, String> metadata) {
|
||||
|
||||
String moduleName = KeywordSearchIngestModule.class.getName();
|
||||
|
||||
Collection<BlackboardAttribute> attributes = new ArrayList<>();
|
||||
Collection<BlackboardArtifact> bbartifacts = new ArrayList<>();
|
||||
for (Map.Entry<String, String> entry : metadata.entrySet()) {
|
||||
if (METADATA_TYPES_MAP.containsKey(entry.getKey())) {
|
||||
BlackboardAttribute bba = checkAttribute(entry.getKey(), entry.getValue());
|
||||
if (bba != null) {
|
||||
attributes.add(bba);
|
||||
}
|
||||
} catch (IngesterException | TextExtractor.InitReaderException ex) {
|
||||
logger.log(Level.WARNING, "Failed to extract strings and ingest, file '" + aFile.getName() + "' (id: " + aFile.getId() + ").", ex); //NON-NLS
|
||||
putIngestStatus(jobId, aFile.getId(), IngestStatus.SKIPPED_ERROR_INDEXING);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (!attributes.isEmpty()) {
|
||||
try {
|
||||
BlackboardArtifact bbart = aFile.newDataArtifact(new BlackboardArtifact.Type(BlackboardArtifact.ARTIFACT_TYPE.TSK_METADATA), attributes);
|
||||
bbartifacts.add(bbart);
|
||||
} catch (TskCoreException ex) {
|
||||
// Log error and return to continue processing
|
||||
logger.log(Level.WARNING, String.format("Error creating or adding metadata artifact for file %s.", aFile.getParentPath() + aFile.getName()), ex); //NON-NLS
|
||||
return;
|
||||
}
|
||||
if (!bbartifacts.isEmpty()) {
|
||||
try {
|
||||
Case.getCurrentCaseThrows().getSleuthkitCase().getBlackboard().postArtifacts(bbartifacts, moduleName, jobId);
|
||||
} catch (NoCurrentCaseException | Blackboard.BlackboardException ex) {
|
||||
// Log error and return to continue processing
|
||||
logger.log(Level.WARNING, String.format("Unable to post blackboard artifacts for file $s.", aFile.getParentPath() + aFile.getName()), ex); //NON-NLS
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private BlackboardAttribute checkAttribute(String key, String value) {
|
||||
String moduleName = KeywordSearchIngestModule.class.getName();
|
||||
if (!value.isEmpty() && value.charAt(0) != ' ') {
|
||||
if (METADATA_DATE_TYPES.contains(key)) {
|
||||
SimpleDateFormat metadataDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", US);
|
||||
Long metadataDateTime = Long.valueOf(0);
|
||||
try {
|
||||
String metadataDate = value.replaceAll("T", " ").replaceAll("Z", "");
|
||||
Date usedDate = metadataDateFormat.parse(metadataDate);
|
||||
metadataDateTime = usedDate.getTime() / 1000;
|
||||
return new BlackboardAttribute(METADATA_TYPES_MAP.get(key), moduleName, metadataDateTime);
|
||||
} catch (ParseException ex) {
|
||||
// catching error and displaying date that could not be parsed then will continue on.
|
||||
logger.log(Level.WARNING, String.format("Failed to parse date/time %s for metadata attribute %s.", value, key), ex); //NON-NLS
|
||||
return null;
|
||||
}
|
||||
} else {
|
||||
return new BlackboardAttribute(METADATA_TYPES_MAP.get(key), moduleName, value);
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Pretty print the text extractor metadata.
|
||||
*
|
||||
* @param metadata The Metadata map to wrap as a CharSource
|
||||
*
|
||||
* @return A CharSource for the given Metadata
|
||||
*/
|
||||
@NbBundle.Messages({
|
||||
"KeywordSearchIngestModule.metadataTitle=METADATA"
|
||||
})
|
||||
private CharSource getMetaDataCharSource(Map<String, String> metadata) {
|
||||
return CharSource.wrap(new StringBuilder(
|
||||
String.format("\n\n------------------------------%s------------------------------\n\n",
|
||||
Bundle.KeywordSearchIngestModule_metadataTitle()))
|
||||
.append(metadata.entrySet().stream().sorted(Map.Entry.comparingByKey())
|
||||
.map(entry -> entry.getKey() + ": " + entry.getValue())
|
||||
.collect(Collectors.joining("\n"))
|
||||
));
|
||||
}
|
||||
|
||||
/**
|
||||
* Extract strings using heuristics from the file and add to index.
|
||||
*
|
||||
* @param aFile file to extract strings from, divide into chunks and index
|
||||
*
|
||||
* @return true if the file was text_ingested, false otherwise
|
||||
*/
|
||||
private boolean extractStringsAndIndex(AbstractFile aFile) {
|
||||
try {
|
||||
if (context.fileIngestIsCancelled()) {
|
||||
return true;
|
||||
}
|
||||
Reader extractedTextReader = KeywordSearchUtil.getReader(aFile, stringsExtractionContext);
|
||||
Ingester.getDefault().search(extractedTextReader, aFile.getId(), aFile.getName(), aFile, KeywordSearchIngestModule.this.context, false, settings.isIndexToSolrEnabled(), settings.getNamesOfEnabledKeyWordLists());
|
||||
putIngestStatus(jobId, aFile.getId(), IngestStatus.STRINGS_INGESTED);
|
||||
} catch (Exception ex) {
|
||||
logger.log(Level.WARNING, "Failed to extract strings and ingest, file '" + aFile.getName() + "' (id: " + aFile.getId() + ").", ex); //NON-NLS
|
||||
putIngestStatus(jobId, aFile.getId(), IngestStatus.SKIPPED_ERROR_INDEXING);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the file to the index. Detects file type, calls extractors, etc.
|
||||
*
|
||||
* @param extractor The textExtractor to use with this file or empty if
|
||||
* no extractor found.
|
||||
* @param aFile File to analyze.
|
||||
* @param mimeType The file mime type.
|
||||
* @param indexContent False if only metadata should be text_ingested. True
|
||||
* if content and metadata should be index.
|
||||
*/
|
||||
private void searchFile(Optional<TextExtractor> extractor, AbstractFile aFile, String mimeType, boolean indexContent) {
|
||||
//logger.log(Level.INFO, "Processing AbstractFile: " + abstractFile.getName());
|
||||
|
||||
TskData.TSK_DB_FILES_TYPE_ENUM aType = aFile.getType();
|
||||
|
||||
/**
|
||||
* Adds the file to the index. Detects file type, calls extractors, etc.
|
||||
*
|
||||
* @param extractor The textExtractor to use with this file or empty
|
||||
* if no extractor found.
|
||||
* @param aFile File to analyze.
|
||||
* @param mimeType The file mime type.
|
||||
* @param indexContent False if only metadata should be text_ingested.
|
||||
* True if content and metadata should be index.
|
||||
* Extract unicode strings from unallocated and unused blocks and carved
|
||||
* text files. The reason for performing string extraction on these is
|
||||
* because they all may contain multiple encodings which can cause text
|
||||
* to be missed by the more specialized text extractors used below.
|
||||
*/
|
||||
private void indexFile(Optional<TextExtractor> extractor, AbstractFile aFile, String mimeType, boolean indexContent) {
|
||||
//logger.log(Level.INFO, "Processing AbstractFile: " + abstractFile.getName());
|
||||
|
||||
TskData.TSK_DB_FILES_TYPE_ENUM aType = aFile.getType();
|
||||
|
||||
/**
|
||||
* Extract unicode strings from unallocated and unused blocks and
|
||||
* carved text files. The reason for performing string extraction on
|
||||
* these is because they all may contain multiple encodings which
|
||||
* can cause text to be missed by the more specialized text
|
||||
* extractors used below.
|
||||
*/
|
||||
if ((aType.equals(TskData.TSK_DB_FILES_TYPE_ENUM.UNALLOC_BLOCKS)
|
||||
|| aType.equals(TskData.TSK_DB_FILES_TYPE_ENUM.UNUSED_BLOCKS))
|
||||
|| (aType.equals(TskData.TSK_DB_FILES_TYPE_ENUM.CARVED) && aFile.getNameExtension().equalsIgnoreCase("txt"))) {
|
||||
if (context.fileIngestIsCancelled()) {
|
||||
return;
|
||||
}
|
||||
extractStringsAndIndex(aFile);
|
||||
return;
|
||||
}
|
||||
|
||||
final long size = aFile.getSize();
|
||||
//if not to index content, or a dir, or 0 content, index meta data only
|
||||
|
||||
if ((indexContent == false || aFile.isDir() || size == 0)) {
|
||||
try {
|
||||
if (context.fileIngestIsCancelled()) {
|
||||
return;
|
||||
}
|
||||
ingester.indexMetaDataOnly(aFile);
|
||||
putIngestStatus(jobId, aFile.getId(), IngestStatus.METADATA_INGESTED);
|
||||
} catch (IngesterException ex) {
|
||||
putIngestStatus(jobId, aFile.getId(), IngestStatus.SKIPPED_ERROR_INDEXING);
|
||||
logger.log(Level.WARNING, "Unable to index meta-data for file: " + aFile.getId(), ex); //NON-NLS
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if ((aType.equals(TskData.TSK_DB_FILES_TYPE_ENUM.UNALLOC_BLOCKS)
|
||||
|| aType.equals(TskData.TSK_DB_FILES_TYPE_ENUM.UNUSED_BLOCKS))
|
||||
|| (aType.equals(TskData.TSK_DB_FILES_TYPE_ENUM.CARVED) && aFile.getNameExtension().equalsIgnoreCase("txt"))) {
|
||||
if (context.fileIngestIsCancelled()) {
|
||||
return;
|
||||
}
|
||||
extractStringsAndIndex(aFile);
|
||||
return;
|
||||
}
|
||||
|
||||
// we skip archive formats that are opened by the archive module.
|
||||
// @@@ We could have a check here to see if the archive module was enabled though...
|
||||
if (ARCHIVE_MIME_TYPES.contains(mimeType)) {
|
||||
try {
|
||||
if (context.fileIngestIsCancelled()) {
|
||||
return;
|
||||
}
|
||||
ingester.indexMetaDataOnly(aFile);
|
||||
putIngestStatus(jobId, aFile.getId(), IngestStatus.METADATA_INGESTED);
|
||||
} catch (IngesterException ex) {
|
||||
putIngestStatus(jobId, aFile.getId(), IngestStatus.SKIPPED_ERROR_INDEXING);
|
||||
logger.log(Level.WARNING, "Unable to index meta-data for file: " + aFile.getId(), ex); //NON-NLS
|
||||
}
|
||||
return;
|
||||
}
|
||||
final long size = aFile.getSize();
|
||||
//if not to index content, or a dir, or 0 content, index meta data only
|
||||
|
||||
boolean wasTextAdded = false;
|
||||
Map<String, String> extractedMetadata = new HashMap<>();
|
||||
|
||||
//extract text with one of the extractors, divide into chunks and index with Solr
|
||||
if ((indexContent == false || aFile.isDir() || size == 0)) {
|
||||
try {
|
||||
//logger.log(Level.INFO, "indexing: " + aFile.getName());
|
||||
if (context.fileIngestIsCancelled()) {
|
||||
return;
|
||||
}
|
||||
if (MimeTypes.OCTET_STREAM.equals(mimeType)) {
|
||||
extractStringsAndIndex(aFile);
|
||||
ingester.indexMetaDataOnly(aFile);
|
||||
putIngestStatus(jobId, aFile.getId(), IngestStatus.METADATA_INGESTED);
|
||||
} catch (IngesterException ex) {
|
||||
putIngestStatus(jobId, aFile.getId(), IngestStatus.SKIPPED_ERROR_INDEXING);
|
||||
logger.log(Level.WARNING, "Unable to index meta-data for file: " + aFile.getId(), ex); //NON-NLS
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (context.fileIngestIsCancelled()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// we skip archive formats that are opened by the archive module.
|
||||
// @@@ We could have a check here to see if the archive module was enabled though...
|
||||
if (ARCHIVE_MIME_TYPES.contains(mimeType)) {
|
||||
try {
|
||||
if (context.fileIngestIsCancelled()) {
|
||||
return;
|
||||
}
|
||||
if (!extractTextAndIndex(extractor, aFile, extractedMetadata)) {
|
||||
// Text extractor not found for file. Extract string only.
|
||||
putIngestStatus(jobId, aFile.getId(), IngestStatus.SKIPPED_ERROR_TEXTEXTRACT);
|
||||
} else {
|
||||
putIngestStatus(jobId, aFile.getId(), IngestStatus.TEXT_INGESTED);
|
||||
wasTextAdded = true;
|
||||
}
|
||||
|
||||
} catch (IngesterException e) {
|
||||
logger.log(Level.INFO, "Could not extract text with Tika, " + aFile.getId() + ", " //NON-NLS
|
||||
+ aFile.getName(), e);
|
||||
ingester.indexMetaDataOnly(aFile);
|
||||
putIngestStatus(jobId, aFile.getId(), IngestStatus.METADATA_INGESTED);
|
||||
} catch (IngesterException ex) {
|
||||
putIngestStatus(jobId, aFile.getId(), IngestStatus.SKIPPED_ERROR_INDEXING);
|
||||
} catch (Exception e) {
|
||||
logger.log(Level.WARNING, "Error extracting text with Tika, " + aFile.getId() + ", " //NON-NLS
|
||||
+ aFile.getName(), e);
|
||||
putIngestStatus(jobId, aFile.getId(), IngestStatus.SKIPPED_ERROR_TEXTEXTRACT);
|
||||
}
|
||||
|
||||
if ((wasTextAdded == false) && (aFile.getNameExtension().equalsIgnoreCase("txt") && !(aFile.getType().equals(TskData.TSK_DB_FILES_TYPE_ENUM.CARVED)))) {
|
||||
//Carved Files should be the only type of unallocated files capable of a txt extension and
|
||||
//should be ignored by the TextFileExtractor because they may contain more than one text encoding
|
||||
wasTextAdded = indexTextFile(aFile);
|
||||
}
|
||||
|
||||
// if it wasn't supported or had an error, default to strings
|
||||
if (wasTextAdded == false) {
|
||||
extractStringsAndIndex(aFile);
|
||||
}
|
||||
|
||||
// Now that the indexing is complete, create the metadata artifact (if applicable).
|
||||
// It is unclear why calling this from extractTextAndIndex() generates
|
||||
// errors.
|
||||
if (!extractedMetadata.isEmpty()) {
|
||||
createMetadataArtifact(aFile, extractedMetadata);
|
||||
logger.log(Level.WARNING, "Unable to index meta-data for file: " + aFile.getId(), ex); //NON-NLS
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the text file to the index given an encoding. Returns true if
|
||||
* indexing was successful and false otherwise.
|
||||
*
|
||||
* @param aFile Text file to analyze
|
||||
*/
|
||||
private boolean indexTextFile(AbstractFile aFile) {
|
||||
try {
|
||||
TextFileExtractor textFileExtractor = new TextFileExtractor(aFile);
|
||||
Reader textReader = textFileExtractor.getReader();
|
||||
if (textReader == null) {
|
||||
logger.log(Level.INFO, "Unable to extract with TextFileExtractor, Reader was null for file: {0}", aFile.getName());
|
||||
} else if (Ingester.getDefault().indexText(textReader, aFile.getId(), aFile.getName(), aFile, context)) {
|
||||
textReader.close();
|
||||
putIngestStatus(jobId, aFile.getId(), IngestStatus.TEXT_INGESTED);
|
||||
return true;
|
||||
}
|
||||
} catch (IngesterException | IOException | TextExtractor.InitReaderException ex) {
|
||||
logger.log(Level.WARNING, "Unable to index " + aFile.getName(), ex);
|
||||
boolean wasTextAdded = false;
|
||||
Map<String, String> extractedMetadata = new HashMap<>();
|
||||
|
||||
//extract text with one of the extractors, divide into chunks and index with Solr
|
||||
try {
|
||||
//logger.log(Level.INFO, "indexing: " + aFile.getName());
|
||||
if (context.fileIngestIsCancelled()) {
|
||||
return;
|
||||
}
|
||||
return false;
|
||||
if (MimeTypes.OCTET_STREAM.equals(mimeType)) {
|
||||
extractStringsAndIndex(aFile);
|
||||
return;
|
||||
}
|
||||
if (!extractTextAndSearch(extractor, aFile, extractedMetadata)) {
|
||||
// Text extractor not found for file. Extract string only.
|
||||
putIngestStatus(jobId, aFile.getId(), IngestStatus.SKIPPED_ERROR_TEXTEXTRACT);
|
||||
} else {
|
||||
putIngestStatus(jobId, aFile.getId(), IngestStatus.TEXT_INGESTED);
|
||||
wasTextAdded = true;
|
||||
}
|
||||
|
||||
} catch (IngesterException e) {
|
||||
logger.log(Level.INFO, "Could not extract text with Tika, " + aFile.getId() + ", " //NON-NLS
|
||||
+ aFile.getName(), e);
|
||||
putIngestStatus(jobId, aFile.getId(), IngestStatus.SKIPPED_ERROR_INDEXING);
|
||||
} catch (Exception e) {
|
||||
logger.log(Level.WARNING, "Error extracting text with Tika, " + aFile.getId() + ", " //NON-NLS
|
||||
+ aFile.getName(), e);
|
||||
putIngestStatus(jobId, aFile.getId(), IngestStatus.SKIPPED_ERROR_TEXTEXTRACT);
|
||||
}
|
||||
|
||||
if ((wasTextAdded == false) && (aFile.getNameExtension().equalsIgnoreCase("txt") && !(aFile.getType().equals(TskData.TSK_DB_FILES_TYPE_ENUM.CARVED)))) {
|
||||
//Carved Files should be the only type of unallocated files capable of a txt extension and
|
||||
//should be ignored by the TextFileExtractor because they may contain more than one text encoding
|
||||
wasTextAdded = searchTextFile(aFile);
|
||||
}
|
||||
|
||||
// if it wasn't supported or had an error, default to strings
|
||||
if (wasTextAdded == false) {
|
||||
extractStringsAndIndex(aFile);
|
||||
}
|
||||
|
||||
// Now that the indexing is complete, create the metadata artifact (if applicable).
|
||||
// It is unclear why calling this from extractTextAndIndex() generates
|
||||
// errors.
|
||||
if (!extractedMetadata.isEmpty()) {
|
||||
createMetadataArtifact(aFile, extractedMetadata);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the text file to the index given an encoding. Returns true if
|
||||
* indexing was successful and false otherwise.
|
||||
*
|
||||
* @param aFile Text file to analyze
|
||||
*/
|
||||
private boolean searchTextFile(AbstractFile aFile) {
|
||||
try {
|
||||
TextFileExtractor textFileExtractor = new TextFileExtractor(aFile);
|
||||
Reader textReader = textFileExtractor.getReader();
|
||||
if (textReader == null) {
|
||||
logger.log(Level.INFO, "Unable to extract with TextFileExtractor, Reader was null for file: {0}", aFile.getName());
|
||||
} else {
|
||||
Ingester.getDefault().search(textReader, aFile.getId(), aFile.getName(), aFile, context, true, settings.isIndexToSolrEnabled(), settings.getNamesOfEnabledKeyWordLists());
|
||||
textReader.close();
|
||||
putIngestStatus(jobId, aFile.getId(), IngestStatus.TEXT_INGESTED);
|
||||
return true;
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
logger.log(Level.WARNING, "Unable to index " + aFile.getName(), ex);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -30,7 +30,7 @@ public final class KeywordSearchJobSettings implements IngestModuleIngestJobSett
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private HashSet<String> namesOfEnabledKeywordLists;
|
||||
private final HashSet<String> namesOfEnabledKeywordLists;
|
||||
private HashSet<String> namesOfDisabledKeywordLists; // Added in version 1.1
|
||||
|
||||
/**
|
||||
@ -41,6 +41,8 @@ public final class KeywordSearchJobSettings implements IngestModuleIngestJobSett
|
||||
private Boolean limitedOCREnabled;
|
||||
|
||||
private boolean ocrOnly;
|
||||
|
||||
private boolean indexToSolr;
|
||||
|
||||
/**
|
||||
* Constructs ingest job settings for the keywords search module.
|
||||
@ -55,6 +57,7 @@ public final class KeywordSearchJobSettings implements IngestModuleIngestJobSett
|
||||
this.ocrEnabled = null;
|
||||
this.limitedOCREnabled = null;
|
||||
this.ocrOnly = false;
|
||||
this.indexToSolr = true;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -69,12 +72,13 @@ public final class KeywordSearchJobSettings implements IngestModuleIngestJobSett
|
||||
* @param ocrOnly True if keyword search ingest should
|
||||
* be solely limited to OCR.
|
||||
*/
|
||||
KeywordSearchJobSettings(List<String> namesOfEnabledKeywordLists, List<String> namesOfDisabledKeywordLists, boolean ocrEnabled, boolean limitedOCREnabled, boolean ocrOnly) {
|
||||
KeywordSearchJobSettings(List<String> namesOfEnabledKeywordLists, List<String> namesOfDisabledKeywordLists, boolean ocrEnabled, boolean limitedOCREnabled, boolean ocrOnly, boolean indexToSolr) {
|
||||
this.namesOfEnabledKeywordLists = new HashSet<>(namesOfEnabledKeywordLists);
|
||||
this.namesOfDisabledKeywordLists = new HashSet<>(namesOfDisabledKeywordLists);
|
||||
this.ocrEnabled = ocrEnabled;
|
||||
this.limitedOCREnabled = limitedOCREnabled;
|
||||
this.ocrOnly = ocrOnly;
|
||||
this.indexToSolr = indexToSolr;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -196,5 +200,13 @@ public final class KeywordSearchJobSettings implements IngestModuleIngestJobSett
|
||||
this.namesOfDisabledKeywordLists = new HashSet<>();
|
||||
}
|
||||
}
|
||||
|
||||
boolean isIndexToSolrEnabled() {
|
||||
return indexToSolr;
|
||||
}
|
||||
|
||||
void setIndexToSolrEnabled(boolean enabled){
|
||||
indexToSolr = enabled;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -2,8 +2,11 @@
|
||||
|
||||
<Form version="1.5" maxVersion="1.7" type="org.netbeans.modules.form.forminfo.JPanelFormInfo">
|
||||
<Properties>
|
||||
<Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||
<Dimension value="[250, 250]"/>
|
||||
</Property>
|
||||
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||
<Dimension value="[300, 170]"/>
|
||||
<Dimension value="[250, 250]"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<AuxValues>
|
||||
@ -16,70 +19,10 @@
|
||||
<AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/>
|
||||
<AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/>
|
||||
<AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/>
|
||||
<AuxValue name="designerSize" type="java.awt.Dimension" value="-84,-19,0,5,115,114,0,18,106,97,118,97,46,97,119,116,46,68,105,109,101,110,115,105,111,110,65,-114,-39,-41,-84,95,68,20,2,0,2,73,0,6,104,101,105,103,104,116,73,0,5,119,105,100,116,104,120,112,0,0,0,-4,0,0,0,-6"/>
|
||||
</AuxValues>
|
||||
|
||||
<Layout>
|
||||
<DimensionLayout dim="0">
|
||||
<Group type="103" groupAlignment="1" attributes="0">
|
||||
<Group type="102" attributes="0">
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Component id="languagesLabel" alignment="1" max="32767" attributes="0"/>
|
||||
<Group type="102" attributes="0">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Component id="listsScrollPane" pref="316" max="32767" attributes="1"/>
|
||||
<Component id="titleLabel" min="-2" max="-2" attributes="0"/>
|
||||
<Group type="102" alignment="0" attributes="0">
|
||||
<Component id="encodingsLabel" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace type="unrelated" max="-2" attributes="0"/>
|
||||
<Component id="keywordSearchEncodings" min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<Group type="102" alignment="0" attributes="0">
|
||||
<EmptySpace min="10" pref="10" max="-2" attributes="0"/>
|
||||
<Component id="languagesValLabel" min="-2" pref="274" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<Component id="ocrCheckBox" alignment="0" min="-2" max="-2" attributes="0"/>
|
||||
<Group type="102" alignment="0" attributes="0">
|
||||
<EmptySpace min="21" pref="21" max="-2" attributes="0"/>
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Component id="ocrOnlyCheckbox" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="limitedOcrCheckbox" min="-2" pref="288" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
</Group>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
</Group>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
<DimensionLayout dim="1">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Group type="102" alignment="0" attributes="0">
|
||||
<EmptySpace min="-2" pref="7" max="-2" attributes="0"/>
|
||||
<Component id="titleLabel" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace min="-2" max="-2" attributes="0"/>
|
||||
<Component id="listsScrollPane" max="32767" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="languagesLabel" min="-2" pref="13" max="-2" attributes="0"/>
|
||||
<EmptySpace min="-2" max="-2" attributes="0"/>
|
||||
<Component id="languagesValLabel" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace type="unrelated" min="-2" max="-2" attributes="0"/>
|
||||
<Group type="103" groupAlignment="3" attributes="0">
|
||||
<Component id="encodingsLabel" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="keywordSearchEncodings" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<EmptySpace type="unrelated" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="ocrCheckBox" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace min="-2" max="-2" attributes="0"/>
|
||||
<Component id="ocrOnlyCheckbox" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace min="-2" max="-2" attributes="0"/>
|
||||
<Component id="limitedOcrCheckbox" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
</Layout>
|
||||
<Layout class="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout"/>
|
||||
<SubComponents>
|
||||
<Container class="javax.swing.JScrollPane" name="listsScrollPane">
|
||||
<Properties>
|
||||
@ -88,13 +31,21 @@
|
||||
<EtchetBorder/>
|
||||
</Border>
|
||||
</Property>
|
||||
<Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||
<Dimension value="[250, 48]"/>
|
||||
</Property>
|
||||
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||
<Dimension value="[300, 100]"/>
|
||||
<Dimension value="[250, 48]"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<AuxValues>
|
||||
<AuxValue name="autoScrollPane" type="java.lang.Boolean" value="true"/>
|
||||
</AuxValues>
|
||||
<Constraints>
|
||||
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
|
||||
<GridBagConstraints gridX="0" gridY="1" gridWidth="2" gridHeight="1" fill="1" ipadX="0" ipadY="0" insetsTop="2" insetsLeft="10" insetsBottom="0" insetsRight="0" anchor="18" weightX="1.0" weightY="1.0"/>
|
||||
</Constraint>
|
||||
</Constraints>
|
||||
|
||||
<Layout class="org.netbeans.modules.form.compat2.layouts.support.JScrollPaneSupportLayout"/>
|
||||
<SubComponents>
|
||||
@ -128,6 +79,11 @@
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/keywordsearch/Bundle.properties" key="KeywordSearchJobSettingsPanel.titleLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<Constraints>
|
||||
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
|
||||
<GridBagConstraints gridX="0" gridY="0" gridWidth="2" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="2" insetsLeft="10" insetsBottom="0" insetsRight="0" anchor="18" weightX="0.0" weightY="0.0"/>
|
||||
</Constraint>
|
||||
</Constraints>
|
||||
</Component>
|
||||
<Component class="javax.swing.JLabel" name="languagesLabel">
|
||||
<Properties>
|
||||
@ -142,6 +98,11 @@
|
||||
</Property>
|
||||
<Property name="verticalTextPosition" type="int" value="3"/>
|
||||
</Properties>
|
||||
<Constraints>
|
||||
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
|
||||
<GridBagConstraints gridX="0" gridY="2" gridWidth="2" gridHeight="1" fill="0" ipadX="25" ipadY="-22" insetsTop="2" insetsLeft="10" insetsBottom="0" insetsRight="0" anchor="18" weightX="0.0" weightY="0.0"/>
|
||||
</Constraint>
|
||||
</Constraints>
|
||||
</Component>
|
||||
<Component class="javax.swing.JLabel" name="languagesValLabel">
|
||||
<Properties>
|
||||
@ -152,6 +113,11 @@
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/keywordsearch/Bundle.properties" key="KeywordSearchJobSettingsPanel.languagesValLabel.toolTipText" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<Constraints>
|
||||
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
|
||||
<GridBagConstraints gridX="0" gridY="3" gridWidth="2" gridHeight="1" fill="0" ipadX="270" ipadY="0" insetsTop="2" insetsLeft="10" insetsBottom="0" insetsRight="0" anchor="18" weightX="0.0" weightY="0.0"/>
|
||||
</Constraint>
|
||||
</Constraints>
|
||||
</Component>
|
||||
<Component class="javax.swing.JLabel" name="encodingsLabel">
|
||||
<Properties>
|
||||
@ -159,6 +125,11 @@
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/keywordsearch/Bundle.properties" key="KeywordSearchJobSettingsPanel.encodingsLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<Constraints>
|
||||
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
|
||||
<GridBagConstraints gridX="0" gridY="4" gridWidth="1" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="5" insetsLeft="10" insetsBottom="0" insetsRight="0" anchor="18" weightX="0.0" weightY="0.0"/>
|
||||
</Constraint>
|
||||
</Constraints>
|
||||
</Component>
|
||||
<Component class="javax.swing.JLabel" name="keywordSearchEncodings">
|
||||
<Properties>
|
||||
@ -166,6 +137,11 @@
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/keywordsearch/Bundle.properties" key="KeywordSearchJobSettingsPanel.keywordSearchEncodings.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<Constraints>
|
||||
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
|
||||
<GridBagConstraints gridX="1" gridY="4" gridWidth="1" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="5" insetsLeft="10" insetsBottom="0" insetsRight="0" anchor="18" weightX="0.0" weightY="0.0"/>
|
||||
</Constraint>
|
||||
</Constraints>
|
||||
</Component>
|
||||
<Component class="javax.swing.JCheckBox" name="ocrCheckBox">
|
||||
<Properties>
|
||||
@ -176,6 +152,11 @@
|
||||
<Events>
|
||||
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="ocrCheckBoxActionPerformed"/>
|
||||
</Events>
|
||||
<Constraints>
|
||||
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
|
||||
<GridBagConstraints gridX="0" gridY="5" gridWidth="2" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="2" insetsLeft="10" insetsBottom="0" insetsRight="0" anchor="18" weightX="0.0" weightY="0.0"/>
|
||||
</Constraint>
|
||||
</Constraints>
|
||||
</Component>
|
||||
<Component class="javax.swing.JCheckBox" name="limitedOcrCheckbox">
|
||||
<Properties>
|
||||
@ -187,6 +168,11 @@
|
||||
<Events>
|
||||
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="limitedOcrCheckboxActionPerformed"/>
|
||||
</Events>
|
||||
<Constraints>
|
||||
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
|
||||
<GridBagConstraints gridX="0" gridY="7" gridWidth="2" gridHeight="1" fill="0" ipadX="216" ipadY="0" insetsTop="0" insetsLeft="31" insetsBottom="0" insetsRight="0" anchor="18" weightX="0.0" weightY="0.0"/>
|
||||
</Constraint>
|
||||
</Constraints>
|
||||
</Component>
|
||||
<Component class="javax.swing.JCheckBox" name="ocrOnlyCheckbox">
|
||||
<Properties>
|
||||
@ -197,6 +183,24 @@
|
||||
<Events>
|
||||
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="ocrOnlyCheckboxActionPerformed"/>
|
||||
</Events>
|
||||
<Constraints>
|
||||
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
|
||||
<GridBagConstraints gridX="0" gridY="6" gridWidth="2" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="31" insetsBottom="0" insetsRight="0" anchor="18" weightX="0.0" weightY="0.0"/>
|
||||
</Constraint>
|
||||
</Constraints>
|
||||
</Component>
|
||||
<Component class="javax.swing.JCheckBox" name="solrCheckbox">
|
||||
<Properties>
|
||||
<Property name="selected" type="boolean" value="true"/>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/keywordsearch/Bundle.properties" key="KeywordSearchJobSettingsPanel.solrCheckbox.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<Constraints>
|
||||
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
|
||||
<GridBagConstraints gridX="0" gridY="8" gridWidth="2" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="2" insetsLeft="10" insetsBottom="0" insetsRight="0" anchor="18" weightX="0.0" weightY="0.0"/>
|
||||
</Constraint>
|
||||
</Constraints>
|
||||
</Component>
|
||||
</SubComponents>
|
||||
</Form>
|
||||
|
@ -40,6 +40,8 @@ import org.sleuthkit.autopsy.keywordsearch.KeywordSearchIngestModule.StringsExtr
|
||||
*/
|
||||
@SuppressWarnings("PMD.SingularField") // UI widgets cause lots of false positives
|
||||
public final class KeywordSearchJobSettingsPanel extends IngestModuleIngestJobSettingsPanel implements PropertyChangeListener {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
private final KeywordListsTableModel tableModel = new KeywordListsTableModel();
|
||||
private final List<String> keywordListNames = new ArrayList<>();
|
||||
private final Map<String, Boolean> keywordListStates = new HashMap<>();
|
||||
@ -65,6 +67,7 @@ public final class KeywordSearchJobSettingsPanel extends IngestModuleIngestJobSe
|
||||
ocrCheckBox.setSelected(settings.isOCREnabled());
|
||||
limitedOcrCheckbox.setSelected(settings.isLimitedOCREnabled());
|
||||
ocrOnlyCheckbox.setSelected(settings.isOCROnly());
|
||||
solrCheckbox.setSelected(settings.isIndexToSolrEnabled());
|
||||
|
||||
handleOcrEnabled(settings.isOCREnabled());
|
||||
}
|
||||
@ -194,7 +197,7 @@ public final class KeywordSearchJobSettingsPanel extends IngestModuleIngestJobSe
|
||||
}
|
||||
}
|
||||
return new KeywordSearchJobSettings(enabledListNames, disabledListNames,
|
||||
this.ocrCheckBox.isSelected(), this.limitedOcrCheckbox.isSelected(), this.ocrOnlyCheckbox.isSelected());
|
||||
this.ocrCheckBox.isSelected(), this.limitedOcrCheckbox.isSelected(), this.ocrOnlyCheckbox.isSelected(), this.solrCheckbox.isSelected());
|
||||
}
|
||||
|
||||
void reset(KeywordSearchJobSettings newSettings) {
|
||||
@ -253,6 +256,7 @@ public final class KeywordSearchJobSettingsPanel extends IngestModuleIngestJobSe
|
||||
@SuppressWarnings("unchecked")
|
||||
// <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
|
||||
private void initComponents() {
|
||||
java.awt.GridBagConstraints gridBagConstraints;
|
||||
|
||||
listsScrollPane = new javax.swing.JScrollPane();
|
||||
listsTable = new javax.swing.JTable();
|
||||
@ -264,11 +268,15 @@ public final class KeywordSearchJobSettingsPanel extends IngestModuleIngestJobSe
|
||||
ocrCheckBox = new javax.swing.JCheckBox();
|
||||
limitedOcrCheckbox = new javax.swing.JCheckBox();
|
||||
ocrOnlyCheckbox = new javax.swing.JCheckBox();
|
||||
solrCheckbox = new javax.swing.JCheckBox();
|
||||
|
||||
setPreferredSize(new java.awt.Dimension(300, 170));
|
||||
setMinimumSize(new java.awt.Dimension(250, 250));
|
||||
setPreferredSize(new java.awt.Dimension(250, 250));
|
||||
setLayout(new java.awt.GridBagLayout());
|
||||
|
||||
listsScrollPane.setBorder(javax.swing.BorderFactory.createEtchedBorder());
|
||||
listsScrollPane.setPreferredSize(new java.awt.Dimension(300, 100));
|
||||
listsScrollPane.setMinimumSize(new java.awt.Dimension(250, 48));
|
||||
listsScrollPane.setPreferredSize(new java.awt.Dimension(250, 48));
|
||||
|
||||
listsTable.setBackground(new java.awt.Color(240, 240, 240));
|
||||
listsTable.setModel(new javax.swing.table.DefaultTableModel(
|
||||
@ -285,19 +293,66 @@ public final class KeywordSearchJobSettingsPanel extends IngestModuleIngestJobSe
|
||||
listsScrollPane.setViewportView(listsTable);
|
||||
listsTable.setDefaultRenderer(String.class, new SimpleTableCellRenderer());
|
||||
|
||||
gridBagConstraints = new java.awt.GridBagConstraints();
|
||||
gridBagConstraints.gridx = 0;
|
||||
gridBagConstraints.gridy = 1;
|
||||
gridBagConstraints.gridwidth = 2;
|
||||
gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
|
||||
gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
|
||||
gridBagConstraints.weightx = 1.0;
|
||||
gridBagConstraints.weighty = 1.0;
|
||||
gridBagConstraints.insets = new java.awt.Insets(2, 10, 0, 0);
|
||||
add(listsScrollPane, gridBagConstraints);
|
||||
|
||||
titleLabel.setText(org.openide.util.NbBundle.getMessage(KeywordSearchJobSettingsPanel.class, "KeywordSearchJobSettingsPanel.titleLabel.text")); // NOI18N
|
||||
gridBagConstraints = new java.awt.GridBagConstraints();
|
||||
gridBagConstraints.gridx = 0;
|
||||
gridBagConstraints.gridy = 0;
|
||||
gridBagConstraints.gridwidth = 2;
|
||||
gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
|
||||
gridBagConstraints.insets = new java.awt.Insets(2, 10, 0, 0);
|
||||
add(titleLabel, gridBagConstraints);
|
||||
|
||||
languagesLabel.setText(org.openide.util.NbBundle.getMessage(KeywordSearchJobSettingsPanel.class, "KeywordSearchJobSettingsPanel.languagesLabel.text")); // NOI18N
|
||||
languagesLabel.setToolTipText(org.openide.util.NbBundle.getMessage(KeywordSearchJobSettingsPanel.class, "KeywordSearchJobSettingsPanel.languagesLabel.toolTipText")); // NOI18N
|
||||
languagesLabel.setPreferredSize(new java.awt.Dimension(294, 35));
|
||||
languagesLabel.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
|
||||
gridBagConstraints = new java.awt.GridBagConstraints();
|
||||
gridBagConstraints.gridx = 0;
|
||||
gridBagConstraints.gridy = 2;
|
||||
gridBagConstraints.gridwidth = 2;
|
||||
gridBagConstraints.ipadx = 25;
|
||||
gridBagConstraints.ipady = -22;
|
||||
gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
|
||||
gridBagConstraints.insets = new java.awt.Insets(2, 10, 0, 0);
|
||||
add(languagesLabel, gridBagConstraints);
|
||||
|
||||
languagesValLabel.setText(org.openide.util.NbBundle.getMessage(KeywordSearchJobSettingsPanel.class, "KeywordSearchJobSettingsPanel.languagesValLabel.text")); // NOI18N
|
||||
languagesValLabel.setToolTipText(org.openide.util.NbBundle.getMessage(KeywordSearchJobSettingsPanel.class, "KeywordSearchJobSettingsPanel.languagesValLabel.toolTipText")); // NOI18N
|
||||
gridBagConstraints = new java.awt.GridBagConstraints();
|
||||
gridBagConstraints.gridx = 0;
|
||||
gridBagConstraints.gridy = 3;
|
||||
gridBagConstraints.gridwidth = 2;
|
||||
gridBagConstraints.ipadx = 270;
|
||||
gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
|
||||
gridBagConstraints.insets = new java.awt.Insets(2, 10, 0, 0);
|
||||
add(languagesValLabel, gridBagConstraints);
|
||||
|
||||
encodingsLabel.setText(org.openide.util.NbBundle.getMessage(KeywordSearchJobSettingsPanel.class, "KeywordSearchJobSettingsPanel.encodingsLabel.text")); // NOI18N
|
||||
gridBagConstraints = new java.awt.GridBagConstraints();
|
||||
gridBagConstraints.gridx = 0;
|
||||
gridBagConstraints.gridy = 4;
|
||||
gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
|
||||
gridBagConstraints.insets = new java.awt.Insets(5, 10, 0, 0);
|
||||
add(encodingsLabel, gridBagConstraints);
|
||||
|
||||
keywordSearchEncodings.setText(org.openide.util.NbBundle.getMessage(KeywordSearchJobSettingsPanel.class, "KeywordSearchJobSettingsPanel.keywordSearchEncodings.text")); // NOI18N
|
||||
gridBagConstraints = new java.awt.GridBagConstraints();
|
||||
gridBagConstraints.gridx = 1;
|
||||
gridBagConstraints.gridy = 4;
|
||||
gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
|
||||
gridBagConstraints.insets = new java.awt.Insets(5, 10, 0, 0);
|
||||
add(keywordSearchEncodings, gridBagConstraints);
|
||||
|
||||
ocrCheckBox.setText(org.openide.util.NbBundle.getMessage(KeywordSearchJobSettingsPanel.class, "KeywordSearchJobSettingsPanel.ocrCheckBox.text")); // NOI18N
|
||||
ocrCheckBox.addActionListener(new java.awt.event.ActionListener() {
|
||||
@ -305,6 +360,13 @@ public final class KeywordSearchJobSettingsPanel extends IngestModuleIngestJobSe
|
||||
ocrCheckBoxActionPerformed(evt);
|
||||
}
|
||||
});
|
||||
gridBagConstraints = new java.awt.GridBagConstraints();
|
||||
gridBagConstraints.gridx = 0;
|
||||
gridBagConstraints.gridy = 5;
|
||||
gridBagConstraints.gridwidth = 2;
|
||||
gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
|
||||
gridBagConstraints.insets = new java.awt.Insets(2, 10, 0, 0);
|
||||
add(ocrCheckBox, gridBagConstraints);
|
||||
|
||||
limitedOcrCheckbox.setText(org.openide.util.NbBundle.getMessage(KeywordSearchJobSettingsPanel.class, "KeywordSearchJobSettingsPanel.limitedOcrCheckbox.text")); // NOI18N
|
||||
limitedOcrCheckbox.setVerticalTextPosition(javax.swing.SwingConstants.TOP);
|
||||
@ -313,6 +375,14 @@ public final class KeywordSearchJobSettingsPanel extends IngestModuleIngestJobSe
|
||||
limitedOcrCheckboxActionPerformed(evt);
|
||||
}
|
||||
});
|
||||
gridBagConstraints = new java.awt.GridBagConstraints();
|
||||
gridBagConstraints.gridx = 0;
|
||||
gridBagConstraints.gridy = 7;
|
||||
gridBagConstraints.gridwidth = 2;
|
||||
gridBagConstraints.ipadx = 216;
|
||||
gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
|
||||
gridBagConstraints.insets = new java.awt.Insets(0, 31, 0, 0);
|
||||
add(limitedOcrCheckbox, gridBagConstraints);
|
||||
|
||||
ocrOnlyCheckbox.setText(org.openide.util.NbBundle.getMessage(KeywordSearchJobSettingsPanel.class, "KeywordSearchJobSettingsPanel.ocrOnlyCheckbox.text")); // NOI18N
|
||||
ocrOnlyCheckbox.addActionListener(new java.awt.event.ActionListener() {
|
||||
@ -320,57 +390,23 @@ public final class KeywordSearchJobSettingsPanel extends IngestModuleIngestJobSe
|
||||
ocrOnlyCheckboxActionPerformed(evt);
|
||||
}
|
||||
});
|
||||
gridBagConstraints = new java.awt.GridBagConstraints();
|
||||
gridBagConstraints.gridx = 0;
|
||||
gridBagConstraints.gridy = 6;
|
||||
gridBagConstraints.gridwidth = 2;
|
||||
gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
|
||||
gridBagConstraints.insets = new java.awt.Insets(0, 31, 0, 0);
|
||||
add(ocrOnlyCheckbox, gridBagConstraints);
|
||||
|
||||
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
|
||||
this.setLayout(layout);
|
||||
layout.setHorizontalGroup(
|
||||
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
|
||||
.addGroup(layout.createSequentialGroup()
|
||||
.addContainerGap()
|
||||
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addComponent(languagesLabel, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
||||
.addGroup(layout.createSequentialGroup()
|
||||
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addComponent(listsScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, 316, Short.MAX_VALUE)
|
||||
.addComponent(titleLabel)
|
||||
.addGroup(layout.createSequentialGroup()
|
||||
.addComponent(encodingsLabel)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
|
||||
.addComponent(keywordSearchEncodings))
|
||||
.addGroup(layout.createSequentialGroup()
|
||||
.addGap(10, 10, 10)
|
||||
.addComponent(languagesValLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 274, javax.swing.GroupLayout.PREFERRED_SIZE))
|
||||
.addComponent(ocrCheckBox)
|
||||
.addGroup(layout.createSequentialGroup()
|
||||
.addGap(21, 21, 21)
|
||||
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addComponent(ocrOnlyCheckbox)
|
||||
.addComponent(limitedOcrCheckbox, javax.swing.GroupLayout.PREFERRED_SIZE, 288, javax.swing.GroupLayout.PREFERRED_SIZE))))
|
||||
.addContainerGap())))
|
||||
);
|
||||
layout.setVerticalGroup(
|
||||
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGroup(layout.createSequentialGroup()
|
||||
.addGap(7, 7, 7)
|
||||
.addComponent(titleLabel)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(listsScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(languagesLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 13, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(languagesValLabel)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
|
||||
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
|
||||
.addComponent(encodingsLabel)
|
||||
.addComponent(keywordSearchEncodings))
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
|
||||
.addComponent(ocrCheckBox)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(ocrOnlyCheckbox)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(limitedOcrCheckbox, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||
.addContainerGap())
|
||||
);
|
||||
solrCheckbox.setSelected(true);
|
||||
solrCheckbox.setText(org.openide.util.NbBundle.getMessage(KeywordSearchJobSettingsPanel.class, "KeywordSearchJobSettingsPanel.solrCheckbox.text")); // NOI18N
|
||||
gridBagConstraints = new java.awt.GridBagConstraints();
|
||||
gridBagConstraints.gridx = 0;
|
||||
gridBagConstraints.gridy = 8;
|
||||
gridBagConstraints.gridwidth = 2;
|
||||
gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
|
||||
gridBagConstraints.insets = new java.awt.Insets(2, 10, 0, 0);
|
||||
add(solrCheckbox, gridBagConstraints);
|
||||
}// </editor-fold>//GEN-END:initComponents
|
||||
|
||||
private void ocrCheckBoxActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_ocrCheckBoxActionPerformed
|
||||
@ -396,6 +432,7 @@ public final class KeywordSearchJobSettingsPanel extends IngestModuleIngestJobSe
|
||||
private javax.swing.JTable listsTable;
|
||||
private javax.swing.JCheckBox ocrCheckBox;
|
||||
private javax.swing.JCheckBox ocrOnlyCheckbox;
|
||||
private javax.swing.JCheckBox solrCheckbox;
|
||||
private javax.swing.JLabel titleLabel;
|
||||
// End of variables declaration//GEN-END:variables
|
||||
}
|
||||
|
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