mirror of
https://github.com/overcuriousity/autopsy-flatpak.git
synced 2025-07-06 21:00:22 +00:00
Merge branch 'develop' of github.com:sleuthkit/autopsy into 6461_nb_upgrade
This commit is contained in:
commit
b4a7bc6dc3
1
.gitignore
vendored
1
.gitignore
vendored
@ -81,6 +81,7 @@ hs_err_pid*.log
|
||||
/thunderbirdparser/release/
|
||||
/RecentActivity/release/
|
||||
/CentralRepository/release/
|
||||
/Tika/release
|
||||
|
||||
.idea/
|
||||
*.iml
|
||||
|
@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project name="BootstrapIvy" default="all" basedir="." xmlns:ivy="antlib:org.apache.ivy.ant">
|
||||
<property name="ivy.install.version" value="2.3.0-rc2" />
|
||||
<property name="ivy.install.version" value="2.5.0" />
|
||||
<condition property="ivy.home" value="${env.IVY_HOME}">
|
||||
<isset property="env.IVY_HOME" />
|
||||
</condition>
|
||||
@ -9,18 +9,13 @@
|
||||
<property name="ivy.jar.file" value="${ivy.jar.dir}/ivy.jar" />
|
||||
|
||||
<target name="download-ivy" unless="offline">
|
||||
<available file="${ivy.jar.file}" property="ivy.available"/>
|
||||
<antcall target="-download-ivy" />
|
||||
</target>
|
||||
|
||||
<target name="-download-ivy" unless="ivy.available">
|
||||
<mkdir dir="${ivy.jar.dir}"/>
|
||||
<get src="https://repo1.maven.org/maven2/org/apache/ivy/ivy/${ivy.install.version}/ivy-${ivy.install.version}.jar"
|
||||
dest="${ivy.jar.file}" usetimestamp="true"/>
|
||||
</target>
|
||||
|
||||
<!-- init-ivy will bootstrap Ivy if the user doesn't have it already -->
|
||||
<target name="init-ivy" depends="download-ivy" unless="ivy.lib.path">
|
||||
<target name="init-ivy" depends="download-ivy">
|
||||
<path id="ivy.lib.path">
|
||||
<fileset dir="${ivy.jar.dir}" includes="*.jar"/>
|
||||
</path>
|
||||
|
@ -64,6 +64,11 @@
|
||||
<fileset dir="${thirdparty.dir}/OfficialHashSets"/>
|
||||
</copy>
|
||||
|
||||
<!--Copy ImageMagick to release-->
|
||||
<copy todir="${basedir}/release/ImageMagick-7.0.10-27-portable-Q16-x64" >
|
||||
<fileset dir="${thirdparty.dir}/ImageMagick-7.0.10-27-portable-Q16-x64"/>
|
||||
</copy>
|
||||
|
||||
<!-- The 'libgstlibav.dll' file is too big to store on GitHub, so we
|
||||
have it stored in a ZIP file. We'll extract it in place and remove
|
||||
the ZIP file afterward. -->
|
||||
|
26
Core/ivy.xml
26
Core/ivy.xml
@ -1,5 +1,5 @@
|
||||
<ivy-module version="2.0">
|
||||
<info organisation="org.sleuthkit.autopsy" module="emailparser"/>
|
||||
<info organisation="org.sleuthkit.autopsy" module="core"/>
|
||||
<configurations >
|
||||
<!-- module dependencies -->
|
||||
<conf name="core"/>
|
||||
@ -14,16 +14,6 @@
|
||||
<dependency conf="core->default" org="org.apache.curator" name="curator-recipes" rev="2.8.0"/>
|
||||
|
||||
<dependency conf="core->default" org="org.python" name="jython-standalone" rev="2.7.0" />
|
||||
<dependency conf="core->default" org="org.apache.tika" name="tika-core" rev="1.20"/>
|
||||
<!-- Exclude the version of cxf-rt-rs-client from Tika 1.20, one of its depedencies breaks Ivy -->
|
||||
<dependency conf="core->default" org="org.apache.tika" name="tika-parsers" rev="1.20">
|
||||
<exclude module="cxf-rt-rs-client"/>
|
||||
<exclude module="cleartk-ml"/>
|
||||
</dependency>
|
||||
|
||||
<!-- Pull down the latest cxf-rt-rs-client which has the Ivy fix -->
|
||||
<dependency conf="core->default" org="org.apache.cxf" name="cxf-rt-rs-client" rev="3.3.0"/>
|
||||
<dependency conf="core->default" org="org.cleartk" name="cleartk-ml" rev="2.0.0"/>
|
||||
|
||||
<dependency conf="core->default" org="com.adobe.xmp" name="xmpcore" rev="5.1.2"/>
|
||||
<dependency conf="core->default" org="org.apache.zookeeper" name="zookeeper" rev="3.4.6"/>
|
||||
@ -37,25 +27,27 @@
|
||||
|
||||
<dependency conf="core->default" org="org.jsoup" name="jsoup" rev="1.10.3"/>
|
||||
|
||||
<dependency conf="core->default" org="com.fasterxml.jackson.core" name="jackson-core" rev="2.9.7"/>
|
||||
<dependency conf="core->default" org="com.fasterxml.jackson.core" name="jackson-databind" rev="2.9.7"/>
|
||||
<dependency conf="core->default" org="com.drewnoakes" name="metadata-extractor" rev="2.11.0"/>
|
||||
|
||||
<dependency conf="core->default" org="com.google.cloud" name="google-cloud-translate" rev="1.70.0"/>
|
||||
<dependency conf="core->default" org="org.apache.opennlp" name="opennlp-tools" rev="1.9.1"/>
|
||||
|
||||
<dependency conf="core->default" org="com.ethteck.decodetect" name="decodetect-core" rev="0.3"/>
|
||||
<dependency conf="core->default" org="com.beetstra.jutf7" name="jutf7" rev="1.0.0"/>
|
||||
|
||||
<dependency org="org.sejda.webp-imageio" name="webp-imageio-sejda" rev="0.1.0"/>
|
||||
<dependency org="com.googlecode.libphonenumber" name="libphonenumber" rev="3.5" />
|
||||
<dependency conf="core->default" org="org.sejda.webp-imageio" name="webp-imageio-sejda" rev="0.1.0"/>
|
||||
<dependency conf="core->default" org="com.googlecode.libphonenumber" name="libphonenumber" rev="3.5" />
|
||||
<dependency conf="core->default" org="commons-validator" name="commons-validator" rev="1.6"/>
|
||||
<dependency conf="core->default" org="net.htmlparser.jericho" name="jericho-html" rev="3.3"/>
|
||||
<dependency org="com.squareup.okhttp" name="okhttp" rev="2.7.5"/>
|
||||
|
||||
<dependency conf="core->default" org="com.squareup.okhttp" name="okhttp" rev="2.7.5"/>
|
||||
<dependency conf="core->default" org="org.jfree" name="jfreechart" rev="1.0.19"/>
|
||||
|
||||
<!-- map support for geolocation -->
|
||||
<dependency conf="core->default" org="org.jxmapviewer" name="jxmapviewer2" rev="2.4"/>
|
||||
|
||||
<!-- https://mvnrepository.com/artifact/javax.ws.rs/javax.ws.rs-api -->
|
||||
<dependency org="javax.ws.rs" name="javax.ws.rs-api" rev="2.0"/>
|
||||
<dependency conf="core->default" org="javax.ws.rs" name="javax.ws.rs-api" rev="2.0"/>
|
||||
<override org="jakarta.ws.rs" module="jakarta.ws.rs-api" rev="2.1.5"/>
|
||||
</dependencies>
|
||||
</ivy-module>
|
||||
|
@ -1,143 +1,123 @@
|
||||
file.reference.activemq-all-5.11.1.jar=release/modules/ext/activemq-all-5.11.1.jar
|
||||
file.reference.apache-mime4j-core-0.8.2.jar=release\\modules\\ext\\apache-mime4j-core-0.8.2.jar
|
||||
file.reference.apache-mime4j-dom-0.8.2.jar=release\\modules\\ext\\apache-mime4j-dom-0.8.2.jar
|
||||
file.reference.asm-7.0.jar=release\\modules\\ext\\asm-7.0.jar
|
||||
file.reference.batik-awt-util-1.6.jar=release/modules/ext/batik-awt-util-1.6.jar
|
||||
file.reference.batik-dom-1.6.jar=release/modules/ext/batik-dom-1.6.jar
|
||||
file.reference.batik-svg-dom-1.6.jar=release/modules/ext/batik-svg-dom-1.6.jar
|
||||
file.reference.batik-svggen-1.6.jar=release/modules/ext/batik-svggen-1.6.jar
|
||||
file.reference.batik-util-1.6.jar=release/modules/ext/batik-util-1.6.jar
|
||||
file.reference.batik-xml-1.6.jar=release/modules/ext/batik-xml-1.6.jar
|
||||
file.reference.bcmail-jdk15on-1.60.jar=release\\modules\\ext\\bcmail-jdk15on-1.60.jar
|
||||
file.reference.bcpkix-jdk15on-1.60.jar=release\\modules\\ext\\bcpkix-jdk15on-1.60.jar
|
||||
file.reference.bcprov-ext-jdk15on-1.54.jar=release/modules/ext/bcprov-ext-jdk15on-1.54.jar
|
||||
file.reference.bcprov-jdk15on-1.60.jar=release\\modules\\ext\\bcprov-jdk15on-1.60.jar
|
||||
file.reference.boilerpipe-1.1.0.jar=release\\modules\\ext\\boilerpipe-1.1.0.jar
|
||||
file.reference.c3p0-0.9.5.jar=release/modules/ext/c3p0-0.9.5.jar
|
||||
file.reference.cdm-4.5.5.jar=release\\modules\\ext\\cdm-4.5.5.jar
|
||||
file.reference.activemq-all-5.11.1.jar=release\\modules\\ext\\activemq-all-5.11.1.jar
|
||||
file.reference.animal-sniffer-annotations-1.17.jar=release\\modules\\ext\\animal-sniffer-annotations-1.17.jar
|
||||
file.reference.api-common-1.7.0.jar=release\\modules\\ext\\api-common-1.7.0.jar
|
||||
file.reference.batik-awt-util-1.6.jar=release\\modules\\ext\\batik-awt-util-1.6.jar
|
||||
file.reference.batik-dom-1.6.jar=release\\modules\\ext\\batik-dom-1.6.jar
|
||||
file.reference.batik-svg-dom-1.6.jar=release\\modules\\ext\\batik-svg-dom-1.6.jar
|
||||
file.reference.batik-svggen-1.6.jar=release\\modules\\ext\\batik-svggen-1.6.jar
|
||||
file.reference.batik-util-1.6.jar=release\\modules\\ext\\batik-util-1.6.jar
|
||||
file.reference.batik-xml-1.6.jar=release\\modules\\ext\\batik-xml-1.6.jar
|
||||
file.reference.bcpkix-jdk15on-1.54.jar=release\\modules\\ext\\bcpkix-jdk15on-1.54.jar
|
||||
file.reference.bcprov-ext-jdk15on-1.54.jar=release\\modules\\ext\\bcprov-ext-jdk15on-1.54.jar
|
||||
file.reference.bcprov-jdk15on-1.52.jar=release\\modules\\ext\\bcprov-jdk15on-1.52.jar
|
||||
file.reference.bcprov-jdk15on-1.54.jar=release\\modules\\ext\\bcprov-jdk15on-1.54.jar
|
||||
file.reference.c3p0-0.9.5.jar=release\\modules\\ext\\c3p0-0.9.5.jar
|
||||
file.reference.checker-compat-qual-2.5.3.jar=release\\modules\\ext\\checker-compat-qual-2.5.3.jar
|
||||
file.reference.commons-beanutils-1.9.2.jar=release\\modules\\ext\\commons-beanutils-1.9.2.jar
|
||||
file.reference.commons-codec-1.11.jar=release\\modules\\ext\\commons-codec-1.11.jar
|
||||
file.reference.commons-collections4-4.2.jar=release\\modules\\ext\\commons-collections4-4.2.jar
|
||||
file.reference.commons-csv-1.6.jar=release\\modules\\ext\\commons-csv-1.6.jar
|
||||
file.reference.commons-dbcp2-2.1.1.jar=release/modules/ext/commons-dbcp2-2.1.1.jar
|
||||
file.reference.commons-exec-1.3.jar=release\\modules\\ext\\commons-exec-1.3.jar
|
||||
file.reference.commons-io-2.6.jar=release\\modules\\ext\\commons-io-2.6.jar
|
||||
file.reference.commons-lang3-3.8.1.jar=release\\modules\\ext\\commons-lang3-3.8.1.jar
|
||||
file.reference.commons-pool2-2.4.2.jar=release/modules/ext/commons-pool2-2.4.2.jar
|
||||
file.reference.cxf-rt-rs-client-3.3.0.jar=release\\modules\\ext\\cxf-rt-rs-client-3.3.0.jar
|
||||
file.reference.DatCon.jar=release/modules/ext/DatCon.jar
|
||||
file.reference.dec-0.1.2.jar=release\\modules\\ext\\dec-0.1.2.jar
|
||||
file.reference.decodetect-core-0.3.jar=release/modules/ext/decodetect-core-0.3.jar
|
||||
file.reference.fontbox-2.0.13.jar=release\\modules\\ext\\fontbox-2.0.13.jar
|
||||
file.reference.geoapi-3.0.1.jar=release\\modules\\ext\\geoapi-3.0.1.jar
|
||||
file.reference.grib-4.5.5.jar=release\\modules\\ext\\grib-4.5.5.jar
|
||||
file.reference.httpclient-4.5.6.jar=release\\modules\\ext\\httpclient-4.5.6.jar
|
||||
file.reference.httpmime-4.5.6.jar=release\\modules\\ext\\httpmime-4.5.6.jar
|
||||
file.reference.httpservices-4.5.5.jar=release\\modules\\ext\\httpservices-4.5.5.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.isoparser-1.1.22.jar=release\\modules\\ext\\isoparser-1.1.22.jar
|
||||
file.reference.commons-collections-3.2.2.jar=release\\modules\\ext\\commons-collections-3.2.2.jar
|
||||
file.reference.commons-dbcp2-2.1.1.jar=release\\modules\\ext\\commons-dbcp2-2.1.1.jar
|
||||
file.reference.commons-digester-1.8.1.jar=release\\modules\\ext\\commons-digester-1.8.1.jar
|
||||
file.reference.commons-lang-2.6.jar=release\\modules\\ext\\commons-lang-2.6.jar
|
||||
file.reference.commons-lang3-3.5.jar=release\\modules\\ext\\commons-lang3-3.5.jar
|
||||
file.reference.commons-logging-1.2.jar=release\\modules\\ext\\commons-logging-1.2.jar
|
||||
file.reference.commons-pool2-2.4.2.jar=release\\modules\\ext\\commons-pool2-2.4.2.jar
|
||||
file.reference.commons-validator-1.6.jar=release\\modules\\ext\\commons-validator-1.6.jar
|
||||
file.reference.curator-client-2.8.0.jar=release\\modules\\ext\\curator-client-2.8.0.jar
|
||||
file.reference.curator-framework-2.8.0.jar=release\\modules\\ext\\curator-framework-2.8.0.jar
|
||||
file.reference.curator-recipes-2.8.0.jar=release\\modules\\ext\\curator-recipes-2.8.0.jar
|
||||
file.reference.DatCon.jar=release\\modules\\ext\\DatCon.jar
|
||||
file.reference.decodetect-core-0.3.jar=release\\modules\\ext\\decodetect-core-0.3.jar
|
||||
file.reference.error_prone_annotations-2.3.2.jar=release\\modules\\ext\\error_prone_annotations-2.3.2.jar
|
||||
file.reference.failureaccess-1.0.1.jar=release\\modules\\ext\\failureaccess-1.0.1.jar
|
||||
file.reference.gax-1.44.0.jar=release\\modules\\ext\\gax-1.44.0.jar
|
||||
file.reference.gax-grpc-1.44.0.jar=release\\modules\\ext\\gax-grpc-1.44.0.jar
|
||||
file.reference.gax-httpjson-0.61.0.jar=release\\modules\\ext\\gax-httpjson-0.61.0.jar
|
||||
file.reference.google-api-client-1.27.0.jar=release\\modules\\ext\\google-api-client-1.27.0.jar
|
||||
file.reference.google-api-services-translate-v2-rev20170525-1.27.0.jar=release\\modules\\ext\\google-api-services-translate-v2-rev20170525-1.27.0.jar
|
||||
file.reference.google-auth-library-credentials-0.15.0.jar=release\\modules\\ext\\google-auth-library-credentials-0.15.0.jar
|
||||
file.reference.google-auth-library-oauth2-http-0.15.0.jar=release\\modules\\ext\\google-auth-library-oauth2-http-0.15.0.jar
|
||||
file.reference.google-cloud-core-1.70.0.jar=release\\modules\\ext\\google-cloud-core-1.70.0.jar
|
||||
file.reference.google-cloud-core-grpc-1.70.0.jar=release\\modules\\ext\\google-cloud-core-grpc-1.70.0.jar
|
||||
file.reference.google-cloud-core-http-1.70.0.jar=release\\modules\\ext\\google-cloud-core-http-1.70.0.jar
|
||||
file.reference.google-cloud-translate-1.70.0.jar=release\\modules\\ext\\google-cloud-translate-1.70.0.jar
|
||||
file.reference.google-http-client-1.29.0.jar=release\\modules\\ext\\google-http-client-1.29.0.jar
|
||||
file.reference.google-http-client-appengine-1.29.0.jar=release\\modules\\ext\\google-http-client-appengine-1.29.0.jar
|
||||
file.reference.google-http-client-jackson2-1.29.0.jar=release\\modules\\ext\\google-http-client-jackson2-1.29.0.jar
|
||||
file.reference.google-oauth-client-1.28.0.jar=release\\modules\\ext\\google-oauth-client-1.28.0.jar
|
||||
file.reference.grpc-alts-1.19.0.jar=release\\modules\\ext\\grpc-alts-1.19.0.jar
|
||||
file.reference.grpc-auth-1.19.0.jar=release\\modules\\ext\\grpc-auth-1.19.0.jar
|
||||
file.reference.grpc-context-1.19.0.jar=release\\modules\\ext\\grpc-context-1.19.0.jar
|
||||
file.reference.grpc-core-1.19.0.jar=release\\modules\\ext\\grpc-core-1.19.0.jar
|
||||
file.reference.grpc-grpclb-1.19.0.jar=release\\modules\\ext\\grpc-grpclb-1.19.0.jar
|
||||
file.reference.grpc-netty-shaded-1.19.0.jar=release\\modules\\ext\\grpc-netty-shaded-1.19.0.jar
|
||||
file.reference.grpc-protobuf-1.19.0.jar=release\\modules\\ext\\grpc-protobuf-1.19.0.jar
|
||||
file.reference.grpc-protobuf-lite-1.19.0.jar=release\\modules\\ext\\grpc-protobuf-lite-1.19.0.jar
|
||||
file.reference.grpc-stub-1.19.0.jar=release\\modules\\ext\\grpc-stub-1.19.0.jar
|
||||
file.reference.gson-2.7.jar=release\\modules\\ext\\gson-2.7.jar
|
||||
file.reference.guava-27.1-android.jar=release\\modules\\ext\\guava-27.1-android.jar
|
||||
file.reference.httpclient-4.5.5.jar=release\\modules\\ext\\httpclient-4.5.5.jar
|
||||
file.reference.httpcore-4.4.9.jar=release\\modules\\ext\\httpcore-4.4.9.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.j2objc-annotations-1.1.jar=release\\modules\\ext\\j2objc-annotations-1.1.jar
|
||||
file.reference.jackcess-2.2.0.jar=release\\modules\\ext\\jackcess-2.2.0.jar
|
||||
file.reference.jackcess-encrypt-2.1.4.jar=release\\modules\\ext\\jackcess-encrypt-2.1.4.jar
|
||||
file.reference.jackson-annotations-2.9.7.jar=release\\modules\\ext\\jackson-annotations-2.9.7.jar
|
||||
file.reference.jackson-annotations-2.9.0.jar=release\\modules\\ext\\jackson-annotations-2.9.0.jar
|
||||
file.reference.jackson-core-2.9.7.jar=release\\modules\\ext\\jackson-core-2.9.7.jar
|
||||
file.reference.jackson-databind-2.9.7.jar=release\\modules\\ext\\jackson-databind-2.9.7.jar
|
||||
file.reference.jai-imageio-core-1.4.0.jar=release\\modules\\ext\\jai-imageio-core-1.4.0.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.java-libpst-0.8.1.jar=release\\modules\\ext\\java-libpst-0.8.1.jar
|
||||
file.reference.javax.activation-1.2.0.jar=release\\modules\\ext\\javax.activation-1.2.0.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.javax.annotation-api-1.3.2.jar=release\\modules\\ext\\javax.annotation-api-1.3.2.jar
|
||||
file.reference.jbig2-imageio-3.0.2.jar=release\\modules\\ext\\jbig2-imageio-3.0.2.jar
|
||||
file.reference.jcl-over-slf4j-1.7.25.jar=release\\modules\\ext\\jcl-over-slf4j-1.7.25.jar
|
||||
file.reference.jdom-2.0.5-contrib.jar=release/modules/ext/jdom-2.0.5-contrib.jar
|
||||
file.reference.jdom-2.0.5.jar=release/modules/ext/jdom-2.0.5.jar
|
||||
file.reference.jdom2-2.0.6.jar=release\\modules\\ext\\jdom2-2.0.6.jar
|
||||
file.reference.jempbox-1.8.16.jar=release\\modules\\ext\\jempbox-1.8.16.jar
|
||||
file.reference.jericho-html-3.3.jar=release/modules/ext/jericho-html-3.3.jar
|
||||
file.reference.jgraphx-4.1.0.jar=release/modules/ext/jgraphx-4.1.0.jar
|
||||
file.reference.jhighlight-1.0.3.jar=release\\modules\\ext\\jhighlight-1.0.3.jar
|
||||
file.reference.jmatio-1.5.jar=release\\modules\\ext\\jmatio-1.5.jar
|
||||
file.reference.json-simple-1.1.1.jar=release\\modules\\ext\\json-simple-1.1.1.jar
|
||||
file.reference.jsoup-1.11.3.jar=release\\modules\\ext\\jsoup-1.11.3.jar
|
||||
file.reference.jul-to-slf4j-1.7.25.jar=release\\modules\\ext\\jul-to-slf4j-1.7.25.jar
|
||||
file.reference.juniversalchardet-1.0.3.jar=release\\modules\\ext\\juniversalchardet-1.0.3.jar
|
||||
file.reference.junrar-2.0.0.jar=release\\modules\\ext\\junrar-2.0.0.jar
|
||||
file.reference.jutf7-1.0.0.jar=release/modules/ext/jutf7-1.0.0.jar
|
||||
file.reference.jxmapviewer2-2.4.jar=release/modules/ext/jxmapviewer2-2.4.jar
|
||||
file.reference.jython-standalone-2.7.0.jar=release/modules/ext/jython-standalone-2.7.0.jar
|
||||
file.reference.libphonenumber-3.5.jar=release/modules/ext/libphonenumber-3.5.jar
|
||||
file.reference.mchange-commons-java-0.2.9.jar=release/modules/ext/mchange-commons-java-0.2.9.jar
|
||||
file.reference.javax.ws.rs-api-2.0.jar=release\\modules\\ext\\javax.ws.rs-api-2.0.jar
|
||||
file.reference.jdom-2.0.5-contrib.jar=release\\modules\\ext\\jdom-2.0.5-contrib.jar
|
||||
file.reference.jdom-2.0.5.jar=release\\modules\\ext\\jdom-2.0.5.jar
|
||||
file.reference.jericho-html-3.3.jar=release\\modules\\ext\\jericho-html-3.3.jar
|
||||
file.reference.jgraphx-4.1.0.jar=release\\modules\\ext\\jgraphx-4.1.0.jar
|
||||
file.reference.jline-0.9.94.jar=release\\modules\\ext\\jline-0.9.94.jar
|
||||
file.reference.jsoup-1.10.3.jar=release\\modules\\ext\\jsoup-1.10.3.jar
|
||||
file.reference.jsr305-3.0.2.jar=release\\modules\\ext\\jsr305-3.0.2.jar
|
||||
file.reference.junit-3.8.1.jar=release\\modules\\ext\\junit-3.8.1.jar
|
||||
file.reference.jutf7-1.0.0.jar=release\\modules\\ext\\jutf7-1.0.0.jar
|
||||
file.reference.jxmapviewer2-2.4.jar=release\\modules\\ext\\jxmapviewer2-2.4.jar
|
||||
file.reference.jython-standalone-2.7.0.jar=release\\modules\\ext\\jython-standalone-2.7.0.jar
|
||||
file.reference.libphonenumber-3.5.jar=release\\modules\\ext\\libphonenumber-3.5.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-1.2.16.jar=release\\modules\\ext\\log4j-1.2.16.jar
|
||||
file.reference.mchange-commons-java-0.2.9.jar=release\\modules\\ext\\mchange-commons-java-0.2.9.jar
|
||||
file.reference.metadata-extractor-2.11.0.jar=release\\modules\\ext\\metadata-extractor-2.11.0.jar
|
||||
file.reference.netcdf4-4.5.5.jar=release\\modules\\ext\\netcdf4-4.5.5.jar
|
||||
file.reference.openjson-1.0.10.jar=release\\modules\\ext\\openjson-1.0.10.jar
|
||||
file.reference.netty-3.7.0.Final.jar=release\\modules\\ext\\netty-3.7.0.Final.jar
|
||||
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.opencensus-api-0.19.2.jar=release\\modules\\ext\\opencensus-api-0.19.2.jar
|
||||
file.reference.opencensus-contrib-grpc-metrics-0.19.2.jar=release\\modules\\ext\\opencensus-contrib-grpc-metrics-0.19.2.jar
|
||||
file.reference.opencensus-contrib-http-util-0.19.2.jar=release\\modules\\ext\\opencensus-contrib-http-util-0.19.2.jar
|
||||
file.reference.opennlp-tools-1.9.1.jar=release\\modules\\ext\\opennlp-tools-1.9.1.jar
|
||||
file.reference.parso-2.0.10.jar=release\\modules\\ext\\parso-2.0.10.jar
|
||||
file.reference.pdfbox-2.0.13.jar=release\\modules\\ext\\pdfbox-2.0.13.jar
|
||||
file.reference.pdfbox-tools-2.0.13.jar=release\\modules\\ext\\pdfbox-tools-2.0.13.jar
|
||||
file.reference.postgresql-9.4.1211.jre7.jar=release/modules/ext/postgresql-9.4.1211.jre7.jar
|
||||
file.reference.Rejistry-1.1-SNAPSHOT.jar=release/modules/ext/Rejistry-1.1-SNAPSHOT.jar
|
||||
file.reference.rome-1.12.0.jar=release\\modules\\ext\\rome-1.12.0.jar
|
||||
file.reference.sentiment-analysis-parser-0.1.jar=release\\modules\\ext\\sentiment-analysis-parser-0.1.jar
|
||||
file.reference.sevenzipjbinding-AllPlatforms.jar=release/modules/ext/sevenzipjbinding-AllPlatforms.jar
|
||||
file.reference.sevenzipjbinding.jar=release/modules/ext/sevenzipjbinding.jar
|
||||
file.reference.sis-metadata-0.8.jar=release\\modules\\ext\\sis-metadata-0.8.jar
|
||||
file.reference.sis-netcdf-0.8.jar=release\\modules\\ext\\sis-netcdf-0.8.jar
|
||||
file.reference.sis-utility-0.8.jar=release\\modules\\ext\\sis-utility-0.8.jar
|
||||
file.reference.sleuthkit-caseuco-4.10.0.jar=release/modules/ext/sleuthkit-caseuco-4.10.0.jar
|
||||
file.reference.slf4j-api-1.7.25.jar=release\\modules\\ext\\slf4j-api-1.7.25.jar
|
||||
file.reference.sqlite-jdbc-3.25.2.jar=release/modules/ext/sqlite-jdbc-3.25.2.jar
|
||||
file.reference.StixLib.jar=release/modules/ext/StixLib.jar
|
||||
file.reference.javax.ws.rs-api-2.0.1.jar=release/modules/ext/javax.ws.rs-api-2.0.1.jar
|
||||
file.reference.cxf-core-3.0.16.jar=release/modules/ext/cxf-core-3.0.16.jar
|
||||
file.reference.cxf-rt-frontend-jaxrs-3.0.16.jar=release/modules/ext/cxf-rt-frontend-jaxrs-3.0.16.jar
|
||||
file.reference.cxf-rt-transports-http-3.0.16.jar=release/modules/ext/cxf-rt-transports-http-3.0.16.jar
|
||||
file.reference.sleuthkit-4.10.0.jar=release/modules/ext/sleuthkit-4.10.0.jar
|
||||
file.reference.curator-client-2.8.0.jar=release/modules/ext/curator-client-2.8.0.jar
|
||||
file.reference.curator-framework-2.8.0.jar=release/modules/ext/curator-framework-2.8.0.jar
|
||||
file.reference.curator-recipes-2.8.0.jar=release/modules/ext/curator-recipes-2.8.0.jar
|
||||
file.reference.tagsoup-1.2.1.jar=release\\modules\\ext\\tagsoup-1.2.1.jar
|
||||
file.reference.tika-core-1.20.jar=release\\modules\\ext\\tika-core-1.20.jar
|
||||
file.reference.tika-parsers-1.20.jar=release\\modules\\ext\\tika-parsers-1.20.jar
|
||||
file.reference.uimafit-core-2.4.0.jar=release\\modules\\ext\\uimafit-core-2.4.0.jar
|
||||
file.reference.uimaj-core-3.0.1.jar=release\\modules\\ext\\uimaj-core-3.0.1.jar
|
||||
file.reference.vorbis-java-core-0.8.jar=release\\modules\\ext\\vorbis-java-core-0.8.jar
|
||||
file.reference.vorbis-java-tika-0.8.jar=release\\modules\\ext\\vorbis-java-tika-0.8.jar
|
||||
file.reference.webp-imageio-sejda-0.1.0.jar=release/modules/ext/webp-imageio-sejda-0.1.0.jar
|
||||
file.reference.xmlbeans-3.0.2.jar=release\\modules\\ext\\xmlbeans-3.0.2.jar
|
||||
file.reference.xmpcore-5.1.3.jar=release/modules/ext/xmpcore-5.1.3.jar
|
||||
file.reference.xz-1.8.jar=release\\modules\\ext\\xz-1.8.jar
|
||||
file.reference.zookeeper-3.4.6.jar=release/modules/ext/zookeeper-3.4.6.jar
|
||||
file.reference.SparseBitSet-1.1.jar=release/modules/ext/SparseBitSet-1.1.jar
|
||||
file.reference.commons-validator-1.6.jar=release/modules/ext/commons-validator-1.6.jar
|
||||
file.reference.api-common-1.7.0.jar=release/modules/ext/api-common-1.7.0.jar
|
||||
file.reference.gax-1.44.0.jar=release/modules/ext/gax-1.44.0.jar
|
||||
file.reference.gax-grpc-1.44.0.jar=release/modules/ext/gax-grpc-1.44.0.jar
|
||||
file.reference.gax-httpjson-0.61.0.jar=release/modules/ext/gax-httpjson-0.61.0.jar
|
||||
file.reference.google-api-client-1.27.0.jar=release/modules/ext/google-api-client-1.27.0.jar
|
||||
file.reference.google-api-services-translate-v2-rev20170525-1.27.0.jar=release/modules/ext/google-api-services-translate-v2-rev20170525-1.27.0.jar
|
||||
file.reference.google-auth-library-credentials-0.15.0.jar=release/modules/ext/google-auth-library-credentials-0.15.0.jar
|
||||
file.reference.google-auth-library-oauth2-http-0.15.0.jar=release/modules/ext/google-auth-library-oauth2-http-0.15.0.jar
|
||||
file.reference.google-cloud-core-1.70.0.jar=release/modules/ext/google-cloud-core-1.70.0.jar
|
||||
file.reference.google-cloud-core-http-1.70.0.jar=release/modules/ext/google-cloud-core-http-1.70.0.jar
|
||||
file.reference.google-cloud-translate-1.70.0.jar=release/modules/ext/google-cloud-translate-1.70.0.jar
|
||||
file.reference.google-http-client-1.29.0.jar=release/modules/ext/google-http-client-1.29.0.jar
|
||||
file.reference.google-http-client-appengine-1.29.0.jar=release/modules/ext/google-http-client-appengine-1.29.0.jar
|
||||
file.reference.google-http-client-jackson2-1.29.0.jar=release/modules/ext/google-http-client-jackson2-1.29.0.jar
|
||||
file.reference.grpc-context-1.19.0.jar=release/modules/ext/grpc-context-1.19.0.jar
|
||||
file.reference.opencensus-api-0.19.2.jar=release/modules/ext/opencensus-api-0.19.2.jar
|
||||
file.reference.opencensus-contrib-http-util-0.19.2.jar=release/modules/ext/opencensus-contrib-http-util-0.19.2.jar
|
||||
file.reference.threetenbp-1.3.3.jar=release/modules/ext/threetenbp-1.3.3.jar
|
||||
file.reference.okhttp-2.7.5-javadoc.jar=release/modules/ext/okhttp-2.7.5-javadoc.jar
|
||||
file.reference.okhttp-2.7.5-sources.jar=release/modules/ext/okhttp-2.7.5-sources.jar
|
||||
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.datcon.jar=release/modules/ext/DatCon.jar
|
||||
file.reference.postgresql-9.4.1211.jre7.jar=release\\modules\\ext\\postgresql-9.4.1211.jre7.jar
|
||||
file.reference.proto-google-cloud-translate-v3beta1-0.53.0.jar=release\\modules\\ext\\proto-google-cloud-translate-v3beta1-0.53.0.jar
|
||||
file.reference.proto-google-common-protos-1.15.0.jar=release\\modules\\ext\\proto-google-common-protos-1.15.0.jar
|
||||
file.reference.proto-google-iam-v1-0.12.0.jar=release\\modules\\ext\\proto-google-iam-v1-0.12.0.jar
|
||||
file.reference.protobuf-java-3.7.0.jar=release\\modules\\ext\\protobuf-java-3.7.0.jar
|
||||
file.reference.protobuf-java-util-3.7.0.jar=release\\modules\\ext\\protobuf-java-util-3.7.0.jar
|
||||
file.reference.Rejistry-1.1-SNAPSHOT.jar=release\\modules\\ext\\Rejistry-1.1-SNAPSHOT.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.10.0.jar=release\\modules\\ext\\sleuthkit-4.10.0.jar
|
||||
file.reference.sleuthkit-caseuco-4.10.0.jar=release\\modules\\ext\\sleuthkit-caseuco-4.10.0.jar
|
||||
file.reference.slf4j-api-1.7.6.jar=release\\modules\\ext\\slf4j-api-1.7.6.jar
|
||||
file.reference.slf4j-log4j12-1.7.6.jar=release\\modules\\ext\\slf4j-log4j12-1.7.6.jar
|
||||
file.reference.SparseBitSet-1.1.jar=release\\modules\\ext\\SparseBitSet-1.1.jar
|
||||
file.reference.sqlite-jdbc-3.25.2.jar=release\\modules\\ext\\sqlite-jdbc-3.25.2.jar
|
||||
file.reference.StixLib.jar=release\\modules\\ext\\StixLib.jar
|
||||
file.reference.threetenbp-1.3.3.jar=release\\modules\\ext\\threetenbp-1.3.3.jar
|
||||
file.reference.webp-imageio-sejda-0.1.0.jar=release\\modules\\ext\\webp-imageio-sejda-0.1.0.jar
|
||||
file.reference.xmpcore-5.1.3.jar=release\\modules\\ext\\xmpcore-5.1.3.jar
|
||||
file.reference.zookeeper-3.4.6.jar=release\\modules\\ext\\zookeeper-3.4.6.jar
|
||||
javac.source=1.8
|
||||
javac.compilerargs=-Xlint -Xlint:-serial
|
||||
license.file=../LICENSE-2.0.txt
|
||||
nbm.homepage=http://www.sleuthkit.org/
|
||||
nbm.module.author=Brian Carrier
|
||||
nbm.needs.restart=true
|
||||
source.reference.curator-recipes-2.8.0.jar=release/modules/ext/curator-recipes-2.8.0-sources.jar
|
||||
spec.version.base=10.20
|
||||
|
||||
|
@ -227,6 +227,14 @@
|
||||
<specification-version>6.55.1</specification-version>
|
||||
</run-dependency>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<code-name-base>org.sleuthkit.autopsy.Tika</code-name-base>
|
||||
<build-prerequisite/>
|
||||
<compile-dependency/>
|
||||
<run-dependency>
|
||||
<specification-version>1.0</specification-version>
|
||||
</run-dependency>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<code-name-base>org.sleuthkit.autopsy.corelibs</code-name-base>
|
||||
<build-prerequisite/>
|
||||
@ -291,8 +299,6 @@
|
||||
<package>net.sf.sevenzipjbinding.impl</package>
|
||||
<package>net.sf.sevenzipjbinding.simple</package>
|
||||
<package>net.sf.sevenzipjbinding.simple.impl</package>
|
||||
<package>org.apache.tika</package>
|
||||
<package>org.apache.tika.io</package>
|
||||
<package>org.sleuthkit.autopsy.actions</package>
|
||||
<package>org.sleuthkit.autopsy.appservices</package>
|
||||
<package>org.sleuthkit.autopsy.casemodule</package>
|
||||
@ -334,100 +340,88 @@
|
||||
<package>org.sleuthkit.datamodel.blackboardutils.attributes</package>
|
||||
</public-packages>
|
||||
<class-path-extension>
|
||||
<runtime-relative-path>ext/commons-lang3-3.8.1.jar</runtime-relative-path>
|
||||
<binary-origin>release\modules\ext\commons-lang3-3.8.1.jar</binary-origin>
|
||||
<runtime-relative-path>ext/batik-xml-1.6.jar</runtime-relative-path>
|
||||
<binary-origin>release\modules\ext\batik-xml-1.6.jar</binary-origin>
|
||||
</class-path-extension>
|
||||
<class-path-extension>
|
||||
<runtime-relative-path>ext/batik-xml-1.6.jar</runtime-relative-path>
|
||||
<binary-origin>release/modules/ext/batik-xml-1.6.jar</binary-origin>
|
||||
<runtime-relative-path>ext/commons-digester-1.8.1.jar</runtime-relative-path>
|
||||
<binary-origin>release\modules\ext\commons-digester-1.8.1.jar</binary-origin>
|
||||
</class-path-extension>
|
||||
<class-path-extension>
|
||||
<runtime-relative-path>ext/jai_core-1.1.3.jar</runtime-relative-path>
|
||||
<binary-origin>release/modules/ext/jai_core-1.1.3.jar</binary-origin>
|
||||
<binary-origin>release\modules\ext\jai_core-1.1.3.jar</binary-origin>
|
||||
</class-path-extension>
|
||||
<class-path-extension>
|
||||
<runtime-relative-path>ext/gax-grpc-1.44.0.jar</runtime-relative-path>
|
||||
<binary-origin>release/modules/ext/gax-grpc-1.44.0.jar</binary-origin>
|
||||
<binary-origin>release\modules\ext\gax-grpc-1.44.0.jar</binary-origin>
|
||||
</class-path-extension>
|
||||
<class-path-extension>
|
||||
<runtime-relative-path>ext/cdm-4.5.5.jar</runtime-relative-path>
|
||||
<binary-origin>release\modules\ext\cdm-4.5.5.jar</binary-origin>
|
||||
<runtime-relative-path>ext/failureaccess-1.0.1.jar</runtime-relative-path>
|
||||
<binary-origin>release\modules\ext\failureaccess-1.0.1.jar</binary-origin>
|
||||
</class-path-extension>
|
||||
<class-path-extension>
|
||||
<runtime-relative-path>ext/sis-utility-0.8.jar</runtime-relative-path>
|
||||
<binary-origin>release\modules\ext\sis-utility-0.8.jar</binary-origin>
|
||||
<runtime-relative-path>ext/grpc-protobuf-1.19.0.jar</runtime-relative-path>
|
||||
<binary-origin>release\modules\ext\grpc-protobuf-1.19.0.jar</binary-origin>
|
||||
</class-path-extension>
|
||||
<class-path-extension>
|
||||
<runtime-relative-path>ext/opencensus-api-0.19.2.jar</runtime-relative-path>
|
||||
<binary-origin>release/modules/ext/opencensus-api-0.19.2.jar</binary-origin>
|
||||
<binary-origin>release\modules\ext\opencensus-api-0.19.2.jar</binary-origin>
|
||||
</class-path-extension>
|
||||
<class-path-extension>
|
||||
<runtime-relative-path>ext/batik-svg-dom-1.6.jar</runtime-relative-path>
|
||||
<binary-origin>release/modules/ext/batik-svg-dom-1.6.jar</binary-origin>
|
||||
<binary-origin>release\modules\ext\batik-svg-dom-1.6.jar</binary-origin>
|
||||
</class-path-extension>
|
||||
<class-path-extension>
|
||||
<runtime-relative-path>ext/gax-httpjson-0.61.0.jar</runtime-relative-path>
|
||||
<binary-origin>release/modules/ext/gax-httpjson-0.61.0.jar</binary-origin>
|
||||
</class-path-extension>
|
||||
<class-path-extension>
|
||||
<runtime-relative-path>ext/boilerpipe-1.1.0.jar</runtime-relative-path>
|
||||
<binary-origin>release\modules\ext\boilerpipe-1.1.0.jar</binary-origin>
|
||||
</class-path-extension>
|
||||
<class-path-extension>
|
||||
<runtime-relative-path>ext/jsoup-1.11.3.jar</runtime-relative-path>
|
||||
<binary-origin>release\modules\ext\jsoup-1.11.3.jar</binary-origin>
|
||||
<binary-origin>release\modules\ext\gax-httpjson-0.61.0.jar</binary-origin>
|
||||
</class-path-extension>
|
||||
<class-path-extension>
|
||||
<runtime-relative-path>ext/sevenzipjbinding.jar</runtime-relative-path>
|
||||
<binary-origin>release/modules/ext/sevenzipjbinding.jar</binary-origin>
|
||||
<binary-origin>release\modules\ext\sevenzipjbinding.jar</binary-origin>
|
||||
</class-path-extension>
|
||||
<class-path-extension>
|
||||
<runtime-relative-path>ext/mchange-commons-java-0.2.9.jar</runtime-relative-path>
|
||||
<binary-origin>release/modules/ext/mchange-commons-java-0.2.9.jar</binary-origin>
|
||||
<binary-origin>release\modules\ext\mchange-commons-java-0.2.9.jar</binary-origin>
|
||||
</class-path-extension>
|
||||
<class-path-extension>
|
||||
<runtime-relative-path>ext/api-common-1.7.0.jar</runtime-relative-path>
|
||||
<binary-origin>release\modules\ext\api-common-1.7.0.jar</binary-origin>
|
||||
</class-path-extension>
|
||||
<class-path-extension>
|
||||
<runtime-relative-path>ext/jackson-databind-2.9.7.jar</runtime-relative-path>
|
||||
<binary-origin>release\modules\ext\jackson-databind-2.9.7.jar</binary-origin>
|
||||
</class-path-extension>
|
||||
<class-path-extension>
|
||||
<runtime-relative-path>ext/jai-imageio-core-1.4.0.jar</runtime-relative-path>
|
||||
<binary-origin>release\modules\ext\jai-imageio-core-1.4.0.jar</binary-origin>
|
||||
</class-path-extension>
|
||||
<class-path-extension>
|
||||
<runtime-relative-path>ext/api-common-1.7.0.jar</runtime-relative-path>
|
||||
<binary-origin>release/modules/ext/api-common-1.7.0.jar</binary-origin>
|
||||
</class-path-extension>
|
||||
<class-path-extension>
|
||||
<runtime-relative-path>ext/jcl-over-slf4j-1.7.25.jar</runtime-relative-path>
|
||||
<binary-origin>release\modules\ext\jcl-over-slf4j-1.7.25.jar</binary-origin>
|
||||
</class-path-extension>
|
||||
<class-path-extension>
|
||||
<runtime-relative-path>ext/okhttp-2.7.5.jar</runtime-relative-path>
|
||||
<binary-origin>release/modules/ext/okhttp-2.7.5.jar</binary-origin>
|
||||
<binary-origin>release\modules\ext\okhttp-2.7.5.jar</binary-origin>
|
||||
</class-path-extension>
|
||||
<class-path-extension>
|
||||
<runtime-relative-path>ext/proto-google-cloud-translate-v3beta1-0.53.0.jar</runtime-relative-path>
|
||||
<binary-origin>release\modules\ext\proto-google-cloud-translate-v3beta1-0.53.0.jar</binary-origin>
|
||||
</class-path-extension>
|
||||
<class-path-extension>
|
||||
<runtime-relative-path>ext/error_prone_annotations-2.3.2.jar</runtime-relative-path>
|
||||
<binary-origin>release\modules\ext\error_prone_annotations-2.3.2.jar</binary-origin>
|
||||
</class-path-extension>
|
||||
<class-path-extension>
|
||||
<runtime-relative-path>ext/libphonenumber-3.5.jar</runtime-relative-path>
|
||||
<binary-origin>release/modules/ext/libphonenumber-3.5.jar</binary-origin>
|
||||
</class-path-extension>
|
||||
<class-path-extension>
|
||||
<runtime-relative-path>ext/tika-core-1.20.jar</runtime-relative-path>
|
||||
<binary-origin>release\modules\ext\tika-core-1.20.jar</binary-origin>
|
||||
<binary-origin>release\modules\ext\libphonenumber-3.5.jar</binary-origin>
|
||||
</class-path-extension>
|
||||
<class-path-extension>
|
||||
<runtime-relative-path>ext/StixLib.jar</runtime-relative-path>
|
||||
<binary-origin>release/modules/ext/StixLib.jar</binary-origin>
|
||||
</class-path-extension>
|
||||
<class-path-extension>
|
||||
<runtime-relative-path>ext/bcprov-jdk15on-1.60.jar</runtime-relative-path>
|
||||
<binary-origin>release\modules\ext\bcprov-jdk15on-1.60.jar</binary-origin>
|
||||
<binary-origin>release\modules\ext\StixLib.jar</binary-origin>
|
||||
</class-path-extension>
|
||||
<class-path-extension>
|
||||
<runtime-relative-path>ext/google-auth-library-credentials-0.15.0.jar</runtime-relative-path>
|
||||
<binary-origin>release/modules/ext/google-auth-library-credentials-0.15.0.jar</binary-origin>
|
||||
<binary-origin>release\modules\ext\google-auth-library-credentials-0.15.0.jar</binary-origin>
|
||||
</class-path-extension>
|
||||
<class-path-extension>
|
||||
<runtime-relative-path>ext/json-simple-1.1.1.jar</runtime-relative-path>
|
||||
<binary-origin>release\modules\ext\json-simple-1.1.1.jar</binary-origin>
|
||||
<runtime-relative-path>ext/grpc-auth-1.19.0.jar</runtime-relative-path>
|
||||
<binary-origin>release\modules\ext\grpc-auth-1.19.0.jar</binary-origin>
|
||||
</class-path-extension>
|
||||
<class-path-extension>
|
||||
<runtime-relative-path>ext/j2objc-annotations-1.1.jar</runtime-relative-path>
|
||||
<binary-origin>release\modules\ext\j2objc-annotations-1.1.jar</binary-origin>
|
||||
</class-path-extension>
|
||||
<class-path-extension>
|
||||
<runtime-relative-path>ext/metadata-extractor-2.11.0.jar</runtime-relative-path>
|
||||
@ -437,157 +431,137 @@
|
||||
<runtime-relative-path>ext/commons-codec-1.11.jar</runtime-relative-path>
|
||||
<binary-origin>release\modules\ext\commons-codec-1.11.jar</binary-origin>
|
||||
</class-path-extension>
|
||||
<class-path-extension>
|
||||
<runtime-relative-path>ext/jmatio-1.5.jar</runtime-relative-path>
|
||||
<binary-origin>release\modules\ext\jmatio-1.5.jar</binary-origin>
|
||||
</class-path-extension>
|
||||
<class-path-extension>
|
||||
<runtime-relative-path>ext/tika-parsers-1.20.jar</runtime-relative-path>
|
||||
<binary-origin>release\modules\ext\tika-parsers-1.20.jar</binary-origin>
|
||||
</class-path-extension>
|
||||
<class-path-extension>
|
||||
<runtime-relative-path>ext/asm-7.0.jar</runtime-relative-path>
|
||||
<binary-origin>release\modules\ext\asm-7.0.jar</binary-origin>
|
||||
</class-path-extension>
|
||||
<class-path-extension>
|
||||
<runtime-relative-path>ext/commons-pool2-2.4.2.jar</runtime-relative-path>
|
||||
<binary-origin>release/modules/ext/commons-pool2-2.4.2.jar</binary-origin>
|
||||
<binary-origin>release\modules\ext\commons-pool2-2.4.2.jar</binary-origin>
|
||||
</class-path-extension>
|
||||
<class-path-extension>
|
||||
<runtime-relative-path>ext/jxmapviewer2-2.4.jar</runtime-relative-path>
|
||||
<binary-origin>release/modules/ext/jxmapviewer2-2.4.jar</binary-origin>
|
||||
<binary-origin>release\modules\ext\jxmapviewer2-2.4.jar</binary-origin>
|
||||
</class-path-extension>
|
||||
<class-path-extension>
|
||||
<runtime-relative-path>ext/jfreechart-1.0.19.jar</runtime-relative-path>
|
||||
<binary-origin>release/modules/ext/jfreechart-1.0.19.jar</binary-origin>
|
||||
</class-path-extension>
|
||||
<class-path-extension>
|
||||
<runtime-relative-path>ext/jcommon-1.0.23.jar</runtime-relative-path>
|
||||
<binary-origin>release/modules/ext/jcommon-1.0.23.jar</binary-origin>
|
||||
</class-path-extension>
|
||||
<class-path-extension>
|
||||
<runtime-relative-path>ext/jdom-2.0.5-contrib.jar</runtime-relative-path>
|
||||
<binary-origin>release/modules/ext/jdom-2.0.5-contrib.jar</binary-origin>
|
||||
</class-path-extension>
|
||||
<class-path-extension>
|
||||
<runtime-relative-path>ext/openjson-1.0.10.jar</runtime-relative-path>
|
||||
<binary-origin>release\modules\ext\openjson-1.0.10.jar</binary-origin>
|
||||
</class-path-extension>
|
||||
<class-path-extension>
|
||||
<runtime-relative-path>ext/isoparser-1.1.22.jar</runtime-relative-path>
|
||||
<binary-origin>release\modules\ext\isoparser-1.1.22.jar</binary-origin>
|
||||
<binary-origin>release\modules\ext\jdom-2.0.5-contrib.jar</binary-origin>
|
||||
</class-path-extension>
|
||||
<class-path-extension>
|
||||
<runtime-relative-path>ext/xmpcore-5.1.3.jar</runtime-relative-path>
|
||||
<binary-origin>release/modules/ext/xmpcore-5.1.3.jar</binary-origin>
|
||||
<binary-origin>release\modules\ext\xmpcore-5.1.3.jar</binary-origin>
|
||||
</class-path-extension>
|
||||
<class-path-extension>
|
||||
<runtime-relative-path>ext/batik-util-1.6.jar</runtime-relative-path>
|
||||
<binary-origin>release/modules/ext/batik-util-1.6.jar</binary-origin>
|
||||
</class-path-extension>
|
||||
<class-path-extension>
|
||||
<runtime-relative-path>ext/javax.activation-1.2.0.jar</runtime-relative-path>
|
||||
<binary-origin>release\modules\ext\javax.activation-1.2.0.jar</binary-origin>
|
||||
</class-path-extension>
|
||||
<class-path-extension>
|
||||
<runtime-relative-path>ext/rome-1.12.0.jar</runtime-relative-path>
|
||||
<binary-origin>release\modules\ext\rome-1.12.0.jar</binary-origin>
|
||||
<binary-origin>release\modules\ext\batik-util-1.6.jar</binary-origin>
|
||||
</class-path-extension>
|
||||
<class-path-extension>
|
||||
<runtime-relative-path>ext/javax.annotation-api-1.3.2.jar</runtime-relative-path>
|
||||
<binary-origin>release\modules\ext\javax.annotation-api-1.3.2.jar</binary-origin>
|
||||
</class-path-extension>
|
||||
<class-path-extension>
|
||||
<runtime-relative-path>ext/vorbis-java-core-0.8.jar</runtime-relative-path>
|
||||
<binary-origin>release\modules\ext\vorbis-java-core-0.8.jar</binary-origin>
|
||||
<runtime-relative-path>ext/jgraphx-4.1.0.jar</runtime-relative-path>
|
||||
<binary-origin>release\modules\ext\jgraphx-4.1.0.jar</binary-origin>
|
||||
</class-path-extension>
|
||||
<class-path-extension>
|
||||
<runtime-relative-path>ext/jgraphx-4.1.0.jar</runtime-relative-path>
|
||||
<binary-origin>release/modules/ext/jgraphx-4.1.0.jar</binary-origin>
|
||||
<runtime-relative-path>ext/jline-0.9.94.jar</runtime-relative-path>
|
||||
<binary-origin>release\modules\ext\jline-0.9.94.jar</binary-origin>
|
||||
</class-path-extension>
|
||||
<class-path-extension>
|
||||
<runtime-relative-path>ext/DatCon.jar</runtime-relative-path>
|
||||
<binary-origin>release/modules/ext/DatCon.jar</binary-origin>
|
||||
</class-path-extension>
|
||||
<class-path-extension>
|
||||
<runtime-relative-path>ext/java-libpst-0.8.1.jar</runtime-relative-path>
|
||||
<binary-origin>release\modules\ext\java-libpst-0.8.1.jar</binary-origin>
|
||||
<binary-origin>release\modules\ext\DatCon.jar</binary-origin>
|
||||
</class-path-extension>
|
||||
<class-path-extension>
|
||||
<runtime-relative-path>ext/okio-1.6.0.jar</runtime-relative-path>
|
||||
<binary-origin>release/modules/ext/okio-1.6.0.jar</binary-origin>
|
||||
<binary-origin>release\modules\ext\okio-1.6.0.jar</binary-origin>
|
||||
</class-path-extension>
|
||||
<class-path-extension>
|
||||
<runtime-relative-path>ext/bcprov-jdk15on-1.54.jar</runtime-relative-path>
|
||||
<binary-origin>release\modules\ext\bcprov-jdk15on-1.54.jar</binary-origin>
|
||||
</class-path-extension>
|
||||
<class-path-extension>
|
||||
<runtime-relative-path>ext/curator-framework-2.8.0.jar</runtime-relative-path>
|
||||
<binary-origin>release/modules/ext/curator-framework-2.8.0.jar</binary-origin>
|
||||
<binary-origin>release\modules\ext\curator-framework-2.8.0.jar</binary-origin>
|
||||
</class-path-extension>
|
||||
<class-path-extension>
|
||||
<runtime-relative-path>ext/commons-dbcp2-2.1.1.jar</runtime-relative-path>
|
||||
<binary-origin>release/modules/ext/commons-dbcp2-2.1.1.jar</binary-origin>
|
||||
<binary-origin>release\modules\ext\commons-dbcp2-2.1.1.jar</binary-origin>
|
||||
</class-path-extension>
|
||||
<class-path-extension>
|
||||
<runtime-relative-path>ext/google-http-client-appengine-1.29.0.jar</runtime-relative-path>
|
||||
<binary-origin>release/modules/ext/google-http-client-appengine-1.29.0.jar</binary-origin>
|
||||
<binary-origin>release\modules\ext\google-http-client-appengine-1.29.0.jar</binary-origin>
|
||||
</class-path-extension>
|
||||
<class-path-extension>
|
||||
<runtime-relative-path>ext/uimafit-core-2.4.0.jar</runtime-relative-path>
|
||||
<binary-origin>release\modules\ext\uimafit-core-2.4.0.jar</binary-origin>
|
||||
<runtime-relative-path>ext/proto-google-iam-v1-0.12.0.jar</runtime-relative-path>
|
||||
<binary-origin>release\modules\ext\proto-google-iam-v1-0.12.0.jar</binary-origin>
|
||||
</class-path-extension>
|
||||
<class-path-extension>
|
||||
<runtime-relative-path>ext/jackcess-encrypt-2.1.4.jar</runtime-relative-path>
|
||||
<binary-origin>release\modules\ext\jackcess-encrypt-2.1.4.jar</binary-origin>
|
||||
</class-path-extension>
|
||||
<class-path-extension>
|
||||
<runtime-relative-path>ext/junrar-2.0.0.jar</runtime-relative-path>
|
||||
<binary-origin>release\modules\ext\junrar-2.0.0.jar</binary-origin>
|
||||
</class-path-extension>
|
||||
<class-path-extension>
|
||||
<runtime-relative-path>ext/google-http-client-1.29.0.jar</runtime-relative-path>
|
||||
<binary-origin>release/modules/ext/google-http-client-1.29.0.jar</binary-origin>
|
||||
</class-path-extension>
|
||||
<class-path-extension>
|
||||
<runtime-relative-path>ext/bcpkix-jdk15on-1.60.jar</runtime-relative-path>
|
||||
<binary-origin>release\modules\ext\bcpkix-jdk15on-1.60.jar</binary-origin>
|
||||
<binary-origin>release\modules\ext\google-http-client-1.29.0.jar</binary-origin>
|
||||
</class-path-extension>
|
||||
<class-path-extension>
|
||||
<runtime-relative-path>ext/opennlp-tools-1.9.1.jar</runtime-relative-path>
|
||||
<binary-origin>release\modules\ext\opennlp-tools-1.9.1.jar</binary-origin>
|
||||
</class-path-extension>
|
||||
<class-path-extension>
|
||||
<runtime-relative-path>ext/slf4j-api-1.7.25.jar</runtime-relative-path>
|
||||
<binary-origin>release\modules\ext\slf4j-api-1.7.25.jar</binary-origin>
|
||||
</class-path-extension>
|
||||
<class-path-extension>
|
||||
<runtime-relative-path>ext/bcprov-ext-jdk15on-1.54.jar</runtime-relative-path>
|
||||
<binary-origin>release/modules/ext/bcprov-ext-jdk15on-1.54.jar</binary-origin>
|
||||
<binary-origin>release\modules\ext\bcprov-ext-jdk15on-1.54.jar</binary-origin>
|
||||
</class-path-extension>
|
||||
<class-path-extension>
|
||||
<runtime-relative-path>ext/google-cloud-core-1.70.0.jar</runtime-relative-path>
|
||||
<binary-origin>release/modules/ext/google-cloud-core-1.70.0.jar</binary-origin>
|
||||
<binary-origin>release\modules\ext\google-cloud-core-1.70.0.jar</binary-origin>
|
||||
</class-path-extension>
|
||||
<class-path-extension>
|
||||
<runtime-relative-path>ext/geoapi-3.0.1.jar</runtime-relative-path>
|
||||
<binary-origin>release\modules\ext\geoapi-3.0.1.jar</binary-origin>
|
||||
<runtime-relative-path>ext/protobuf-java-3.7.0.jar</runtime-relative-path>
|
||||
<binary-origin>release\modules\ext\protobuf-java-3.7.0.jar</binary-origin>
|
||||
</class-path-extension>
|
||||
<class-path-extension>
|
||||
<runtime-relative-path>ext/httpmime-4.5.6.jar</runtime-relative-path>
|
||||
<binary-origin>release\modules\ext\httpmime-4.5.6.jar</binary-origin>
|
||||
</class-path-extension>
|
||||
<class-path-extension>
|
||||
<runtime-relative-path>ext/jdom2-2.0.6.jar</runtime-relative-path>
|
||||
<binary-origin>release\modules\ext\jdom2-2.0.6.jar</binary-origin>
|
||||
</class-path-extension>
|
||||
<class-path-extension>
|
||||
<runtime-relative-path>ext/uimaj-core-3.0.1.jar</runtime-relative-path>
|
||||
<binary-origin>release\modules\ext\uimaj-core-3.0.1.jar</binary-origin>
|
||||
<runtime-relative-path>ext/bcpkix-jdk15on-1.54.jar</runtime-relative-path>
|
||||
<binary-origin>release\modules\ext\bcpkix-jdk15on-1.54.jar</binary-origin>
|
||||
</class-path-extension>
|
||||
<class-path-extension>
|
||||
<runtime-relative-path>ext/sqlite-jdbc-3.25.2.jar</runtime-relative-path>
|
||||
<binary-origin>release/modules/ext/sqlite-jdbc-3.25.2.jar</binary-origin>
|
||||
<binary-origin>release\modules\ext\sqlite-jdbc-3.25.2.jar</binary-origin>
|
||||
</class-path-extension>
|
||||
<class-path-extension>
|
||||
<runtime-relative-path>ext/cxf-rt-rs-client-3.3.0.jar</runtime-relative-path>
|
||||
<binary-origin>release\modules\ext\cxf-rt-rs-client-3.3.0.jar</binary-origin>
|
||||
<runtime-relative-path>ext/grpc-protobuf-lite-1.19.0.jar</runtime-relative-path>
|
||||
<binary-origin>release\modules\ext\grpc-protobuf-lite-1.19.0.jar</binary-origin>
|
||||
</class-path-extension>
|
||||
<class-path-extension>
|
||||
<runtime-relative-path>ext/pdfbox-tools-2.0.13.jar</runtime-relative-path>
|
||||
<binary-origin>release\modules\ext\pdfbox-tools-2.0.13.jar</binary-origin>
|
||||
<runtime-relative-path>ext/httpcore-4.4.9.jar</runtime-relative-path>
|
||||
<binary-origin>release\modules\ext\httpcore-4.4.9.jar</binary-origin>
|
||||
</class-path-extension>
|
||||
<class-path-extension>
|
||||
<runtime-relative-path>ext/grib-4.5.5.jar</runtime-relative-path>
|
||||
<binary-origin>release\modules\ext\grib-4.5.5.jar</binary-origin>
|
||||
<runtime-relative-path>ext/guava-27.1-android.jar</runtime-relative-path>
|
||||
<binary-origin>release\modules\ext\guava-27.1-android.jar</binary-origin>
|
||||
</class-path-extension>
|
||||
<class-path-extension>
|
||||
<runtime-relative-path>ext/bcprov-jdk15on-1.52.jar</runtime-relative-path>
|
||||
<binary-origin>release\modules\ext\bcprov-jdk15on-1.52.jar</binary-origin>
|
||||
</class-path-extension>
|
||||
<class-path-extension>
|
||||
<runtime-relative-path>ext/checker-compat-qual-2.5.3.jar</runtime-relative-path>
|
||||
<binary-origin>release\modules\ext\checker-compat-qual-2.5.3.jar</binary-origin>
|
||||
</class-path-extension>
|
||||
<class-path-extension>
|
||||
<runtime-relative-path>ext/sleuthkit-4.10.0.jar</runtime-relative-path>
|
||||
<binary-origin>release\modules\ext\sleuthkit-4.10.0.jar</binary-origin>
|
||||
</class-path-extension>
|
||||
<class-path-extension>
|
||||
<runtime-relative-path>ext/animal-sniffer-annotations-1.17.jar</runtime-relative-path>
|
||||
<binary-origin>release\modules\ext\animal-sniffer-annotations-1.17.jar</binary-origin>
|
||||
</class-path-extension>
|
||||
<class-path-extension>
|
||||
<runtime-relative-path>ext/sleuthkit-caseuco-4.10.0.jar</runtime-relative-path>
|
||||
<binary-origin>release\modules\ext\sleuthkit-caseuco-4.10.0.jar</binary-origin>
|
||||
</class-path-extension>
|
||||
<class-path-extension>
|
||||
<runtime-relative-path>ext/sleuthkit-4.10.0.jar</runtime-relative-path>
|
||||
@ -599,243 +573,247 @@
|
||||
</class-path-extension>
|
||||
<class-path-extension>
|
||||
<runtime-relative-path>ext/gax-1.44.0.jar</runtime-relative-path>
|
||||
<binary-origin>release/modules/ext/gax-1.44.0.jar</binary-origin>
|
||||
<binary-origin>release\modules\ext\gax-1.44.0.jar</binary-origin>
|
||||
</class-path-extension>
|
||||
<class-path-extension>
|
||||
<runtime-relative-path>ext/jempbox-1.8.16.jar</runtime-relative-path>
|
||||
<binary-origin>release\modules\ext\jempbox-1.8.16.jar</binary-origin>
|
||||
<runtime-relative-path>ext/jsoup-1.10.3.jar</runtime-relative-path>
|
||||
<binary-origin>release\modules\ext\jsoup-1.10.3.jar</binary-origin>
|
||||
</class-path-extension>
|
||||
<class-path-extension>
|
||||
<runtime-relative-path>ext/grpc-context-1.19.0.jar</runtime-relative-path>
|
||||
<binary-origin>release\modules\ext\grpc-context-1.19.0.jar</binary-origin>
|
||||
</class-path-extension>
|
||||
<class-path-extension>
|
||||
<runtime-relative-path>ext/jackcess-2.2.0.jar</runtime-relative-path>
|
||||
<binary-origin>release\modules\ext\jackcess-2.2.0.jar</binary-origin>
|
||||
</class-path-extension>
|
||||
<class-path-extension>
|
||||
<runtime-relative-path>ext/grpc-context-1.19.0.jar</runtime-relative-path>
|
||||
<binary-origin>release/modules/ext/grpc-context-1.19.0.jar</binary-origin>
|
||||
<runtime-relative-path>ext/slf4j-log4j12-1.7.6.jar</runtime-relative-path>
|
||||
<binary-origin>release\modules\ext\slf4j-log4j12-1.7.6.jar</binary-origin>
|
||||
</class-path-extension>
|
||||
<class-path-extension>
|
||||
<runtime-relative-path>ext/jericho-html-3.3.jar</runtime-relative-path>
|
||||
<binary-origin>release/modules/ext/jericho-html-3.3.jar</binary-origin>
|
||||
<binary-origin>release\modules\ext\jericho-html-3.3.jar</binary-origin>
|
||||
</class-path-extension>
|
||||
<class-path-extension>
|
||||
<runtime-relative-path>ext/httpservices-4.5.5.jar</runtime-relative-path>
|
||||
<binary-origin>release\modules\ext\httpservices-4.5.5.jar</binary-origin>
|
||||
</class-path-extension>
|
||||
<class-path-extension>
|
||||
<runtime-relative-path>ext/xz-1.8.jar</runtime-relative-path>
|
||||
<binary-origin>release\modules\ext\xz-1.8.jar</binary-origin>
|
||||
<runtime-relative-path>ext/google-cloud-core-grpc-1.70.0.jar</runtime-relative-path>
|
||||
<binary-origin>release\modules\ext\google-cloud-core-grpc-1.70.0.jar</binary-origin>
|
||||
</class-path-extension>
|
||||
<class-path-extension>
|
||||
<runtime-relative-path>ext/commons-validator-1.6.jar</runtime-relative-path>
|
||||
<binary-origin>release/modules/ext/commons-validator-1.6.jar</binary-origin>
|
||||
<binary-origin>release\modules\ext\commons-validator-1.6.jar</binary-origin>
|
||||
</class-path-extension>
|
||||
<class-path-extension>
|
||||
<runtime-relative-path>ext/slf4j-api-1.7.6.jar</runtime-relative-path>
|
||||
<binary-origin>release\modules\ext\slf4j-api-1.7.6.jar</binary-origin>
|
||||
</class-path-extension>
|
||||
<class-path-extension>
|
||||
<runtime-relative-path>ext/decodetect-core-0.3.jar</runtime-relative-path>
|
||||
<binary-origin>release/modules/ext/decodetect-core-0.3.jar</binary-origin>
|
||||
<binary-origin>release\modules\ext\decodetect-core-0.3.jar</binary-origin>
|
||||
</class-path-extension>
|
||||
<class-path-extension>
|
||||
<runtime-relative-path>ext/jbig2-imageio-3.0.2.jar</runtime-relative-path>
|
||||
<binary-origin>release\modules\ext\jbig2-imageio-3.0.2.jar</binary-origin>
|
||||
</class-path-extension>
|
||||
<class-path-extension>
|
||||
<runtime-relative-path>ext/apache-mime4j-dom-0.8.2.jar</runtime-relative-path>
|
||||
<binary-origin>release\modules\ext\apache-mime4j-dom-0.8.2.jar</binary-origin>
|
||||
</class-path-extension>
|
||||
<class-path-extension>
|
||||
<runtime-relative-path>ext/pdfbox-2.0.13.jar</runtime-relative-path>
|
||||
<binary-origin>release\modules\ext\pdfbox-2.0.13.jar</binary-origin>
|
||||
</class-path-extension>
|
||||
<class-path-extension>
|
||||
<runtime-relative-path>ext/xmlbeans-3.0.2.jar</runtime-relative-path>
|
||||
<binary-origin>release\modules\ext\xmlbeans-3.0.2.jar</binary-origin>
|
||||
<runtime-relative-path>ext/httpclient-4.5.5.jar</runtime-relative-path>
|
||||
<binary-origin>release\modules\ext\httpclient-4.5.5.jar</binary-origin>
|
||||
</class-path-extension>
|
||||
<class-path-extension>
|
||||
<runtime-relative-path>ext/curator-recipes-2.8.0.jar</runtime-relative-path>
|
||||
<binary-origin>release/modules/ext/curator-recipes-2.8.0.jar</binary-origin>
|
||||
<binary-origin>release\modules\ext\curator-recipes-2.8.0.jar</binary-origin>
|
||||
</class-path-extension>
|
||||
<class-path-extension>
|
||||
<runtime-relative-path>ext/tagsoup-1.2.1.jar</runtime-relative-path>
|
||||
<binary-origin>release\modules\ext\tagsoup-1.2.1.jar</binary-origin>
|
||||
<runtime-relative-path>ext/jackson-annotations-2.9.0.jar</runtime-relative-path>
|
||||
<binary-origin>release\modules\ext\jackson-annotations-2.9.0.jar</binary-origin>
|
||||
</class-path-extension>
|
||||
<class-path-extension>
|
||||
<runtime-relative-path>ext/jackson-core-2.9.7.jar</runtime-relative-path>
|
||||
<binary-origin>release\modules\ext\jackson-core-2.9.7.jar</binary-origin>
|
||||
</class-path-extension>
|
||||
<class-path-extension>
|
||||
<runtime-relative-path>ext/sis-metadata-0.8.jar</runtime-relative-path>
|
||||
<binary-origin>release\modules\ext\sis-metadata-0.8.jar</binary-origin>
|
||||
<runtime-relative-path>ext/commons-lang3-3.5.jar</runtime-relative-path>
|
||||
<binary-origin>release\modules\ext\commons-lang3-3.5.jar</binary-origin>
|
||||
</class-path-extension>
|
||||
<class-path-extension>
|
||||
<runtime-relative-path>ext/parso-2.0.10.jar</runtime-relative-path>
|
||||
<binary-origin>release\modules\ext\parso-2.0.10.jar</binary-origin>
|
||||
<runtime-relative-path>ext/log4j-1.2.16.jar</runtime-relative-path>
|
||||
<binary-origin>release\modules\ext\log4j-1.2.16.jar</binary-origin>
|
||||
</class-path-extension>
|
||||
<class-path-extension>
|
||||
<runtime-relative-path>ext/apache-mime4j-core-0.8.2.jar</runtime-relative-path>
|
||||
<binary-origin>release\modules\ext\apache-mime4j-core-0.8.2.jar</binary-origin>
|
||||
<runtime-relative-path>ext/commons-logging-1.2.jar</runtime-relative-path>
|
||||
<binary-origin>release\modules\ext\commons-logging-1.2.jar</binary-origin>
|
||||
</class-path-extension>
|
||||
<class-path-extension>
|
||||
<runtime-relative-path>ext/commons-io-2.6.jar</runtime-relative-path>
|
||||
<binary-origin>release\modules\ext\commons-io-2.6.jar</binary-origin>
|
||||
<runtime-relative-path>ext/listenablefuture-9999.0-empty-to-avoid-conflict-with-guava.jar</runtime-relative-path>
|
||||
<binary-origin>release\modules\ext\listenablefuture-9999.0-empty-to-avoid-conflict-with-guava.jar</binary-origin>
|
||||
</class-path-extension>
|
||||
<class-path-extension>
|
||||
<runtime-relative-path>ext/protobuf-java-util-3.7.0.jar</runtime-relative-path>
|
||||
<binary-origin>release\modules\ext\protobuf-java-util-3.7.0.jar</binary-origin>
|
||||
</class-path-extension>
|
||||
<class-path-extension>
|
||||
<runtime-relative-path>ext/commons-collections-3.2.2.jar</runtime-relative-path>
|
||||
<binary-origin>release\modules\ext\commons-collections-3.2.2.jar</binary-origin>
|
||||
</class-path-extension>
|
||||
<class-path-extension>
|
||||
<runtime-relative-path>ext/SparseBitSet-1.1.jar</runtime-relative-path>
|
||||
<binary-origin>release/modules/ext/SparseBitSet-1.1.jar</binary-origin>
|
||||
<binary-origin>release\modules\ext\SparseBitSet-1.1.jar</binary-origin>
|
||||
</class-path-extension>
|
||||
<class-path-extension>
|
||||
<runtime-relative-path>ext/grpc-grpclb-1.19.0.jar</runtime-relative-path>
|
||||
<binary-origin>release\modules\ext\grpc-grpclb-1.19.0.jar</binary-origin>
|
||||
</class-path-extension>
|
||||
<class-path-extension>
|
||||
<runtime-relative-path>ext/batik-svggen-1.6.jar</runtime-relative-path>
|
||||
<binary-origin>release/modules/ext/batik-svggen-1.6.jar</binary-origin>
|
||||
<binary-origin>release\modules\ext\batik-svggen-1.6.jar</binary-origin>
|
||||
</class-path-extension>
|
||||
<class-path-extension>
|
||||
<runtime-relative-path>ext/c3p0-0.9.5.jar</runtime-relative-path>
|
||||
<binary-origin>release/modules/ext/c3p0-0.9.5.jar</binary-origin>
|
||||
<binary-origin>release\modules\ext\c3p0-0.9.5.jar</binary-origin>
|
||||
</class-path-extension>
|
||||
<class-path-extension>
|
||||
<runtime-relative-path>ext/zookeeper-3.4.6.jar</runtime-relative-path>
|
||||
<binary-origin>release/modules/ext/zookeeper-3.4.6.jar</binary-origin>
|
||||
<binary-origin>release\modules\ext\zookeeper-3.4.6.jar</binary-origin>
|
||||
</class-path-extension>
|
||||
<class-path-extension>
|
||||
<runtime-relative-path>ext/commons-csv-1.6.jar</runtime-relative-path>
|
||||
<binary-origin>release\modules\ext\commons-csv-1.6.jar</binary-origin>
|
||||
<runtime-relative-path>ext/grpc-alts-1.19.0.jar</runtime-relative-path>
|
||||
<binary-origin>release\modules\ext\grpc-alts-1.19.0.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>
|
||||
<binary-origin>release\modules\ext\jdom-2.0.5.jar</binary-origin>
|
||||
</class-path-extension>
|
||||
<class-path-extension>
|
||||
<runtime-relative-path>ext/jackson-annotations-2.9.7.jar</runtime-relative-path>
|
||||
<binary-origin>release\modules\ext\jackson-annotations-2.9.7.jar</binary-origin>
|
||||
<runtime-relative-path>ext/gson-2.7.jar</runtime-relative-path>
|
||||
<binary-origin>release\modules\ext\gson-2.7.jar</binary-origin>
|
||||
</class-path-extension>
|
||||
<class-path-extension>
|
||||
<runtime-relative-path>ext/google-api-client-1.27.0.jar</runtime-relative-path>
|
||||
<binary-origin>release/modules/ext/google-api-client-1.27.0.jar</binary-origin>
|
||||
</class-path-extension>
|
||||
<class-path-extension>
|
||||
<runtime-relative-path>ext/netcdf4-4.5.5.jar</runtime-relative-path>
|
||||
<binary-origin>release\modules\ext\netcdf4-4.5.5.jar</binary-origin>
|
||||
</class-path-extension>
|
||||
<class-path-extension>
|
||||
<runtime-relative-path>ext/sis-netcdf-0.8.jar</runtime-relative-path>
|
||||
<binary-origin>release\modules\ext\sis-netcdf-0.8.jar</binary-origin>
|
||||
</class-path-extension>
|
||||
<class-path-extension>
|
||||
<runtime-relative-path>ext/sentiment-analysis-parser-0.1.jar</runtime-relative-path>
|
||||
<binary-origin>release\modules\ext\sentiment-analysis-parser-0.1.jar</binary-origin>
|
||||
</class-path-extension>
|
||||
<class-path-extension>
|
||||
<runtime-relative-path>ext/commons-collections4-4.2.jar</runtime-relative-path>
|
||||
<binary-origin>release\modules\ext\commons-collections4-4.2.jar</binary-origin>
|
||||
<binary-origin>release\modules\ext\google-api-client-1.27.0.jar</binary-origin>
|
||||
</class-path-extension>
|
||||
<class-path-extension>
|
||||
<runtime-relative-path>ext/opencensus-contrib-http-util-0.19.2.jar</runtime-relative-path>
|
||||
<binary-origin>release/modules/ext/opencensus-contrib-http-util-0.19.2.jar</binary-origin>
|
||||
<binary-origin>release\modules\ext\opencensus-contrib-http-util-0.19.2.jar</binary-origin>
|
||||
</class-path-extension>
|
||||
<class-path-extension>
|
||||
<runtime-relative-path>ext/google-auth-library-oauth2-http-0.15.0.jar</runtime-relative-path>
|
||||
<binary-origin>release/modules/ext/google-auth-library-oauth2-http-0.15.0.jar</binary-origin>
|
||||
</class-path-extension>
|
||||
<class-path-extension>
|
||||
<runtime-relative-path>ext/juniversalchardet-1.0.3.jar</runtime-relative-path>
|
||||
<binary-origin>release\modules\ext\juniversalchardet-1.0.3.jar</binary-origin>
|
||||
<binary-origin>release\modules\ext\google-auth-library-oauth2-http-0.15.0.jar</binary-origin>
|
||||
</class-path-extension>
|
||||
<class-path-extension>
|
||||
<runtime-relative-path>ext/jython-standalone-2.7.0.jar</runtime-relative-path>
|
||||
<binary-origin>release/modules/ext/jython-standalone-2.7.0.jar</binary-origin>
|
||||
<binary-origin>release\modules\ext\jython-standalone-2.7.0.jar</binary-origin>
|
||||
</class-path-extension>
|
||||
<class-path-extension>
|
||||
<runtime-relative-path>ext/jhighlight-1.0.3.jar</runtime-relative-path>
|
||||
<binary-origin>release\modules\ext\jhighlight-1.0.3.jar</binary-origin>
|
||||
<runtime-relative-path>ext/commons-lang-2.6.jar</runtime-relative-path>
|
||||
<binary-origin>release\modules\ext\commons-lang-2.6.jar</binary-origin>
|
||||
</class-path-extension>
|
||||
<class-path-extension>
|
||||
<runtime-relative-path>ext/jul-to-slf4j-1.7.25.jar</runtime-relative-path>
|
||||
<binary-origin>release\modules\ext\jul-to-slf4j-1.7.25.jar</binary-origin>
|
||||
<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/postgresql-9.4.1211.jre7.jar</runtime-relative-path>
|
||||
<binary-origin>release/modules/ext/postgresql-9.4.1211.jre7.jar</binary-origin>
|
||||
<runtime-relative-path>ext/proto-google-common-protos-1.15.0.jar</runtime-relative-path>
|
||||
<binary-origin>release\modules\ext\proto-google-common-protos-1.15.0.jar</binary-origin>
|
||||
</class-path-extension>
|
||||
<class-path-extension>
|
||||
<runtime-relative-path>ext/netty-3.7.0.Final.jar</runtime-relative-path>
|
||||
<binary-origin>release\modules\ext\netty-3.7.0.Final.jar</binary-origin>
|
||||
</class-path-extension>
|
||||
<class-path-extension>
|
||||
<runtime-relative-path>ext/opencensus-contrib-grpc-metrics-0.19.2.jar</runtime-relative-path>
|
||||
<binary-origin>release\modules\ext\opencensus-contrib-grpc-metrics-0.19.2.jar</binary-origin>
|
||||
</class-path-extension>
|
||||
<class-path-extension>
|
||||
<runtime-relative-path>ext/jai_imageio-1.1.jar</runtime-relative-path>
|
||||
<binary-origin>release/modules/ext/jai_imageio-1.1.jar</binary-origin>
|
||||
<binary-origin>release\modules\ext\jai_imageio-1.1.jar</binary-origin>
|
||||
</class-path-extension>
|
||||
<class-path-extension>
|
||||
<runtime-relative-path>ext/httpclient-4.5.6.jar</runtime-relative-path>
|
||||
<binary-origin>release\modules\ext\httpclient-4.5.6.jar</binary-origin>
|
||||
<runtime-relative-path>ext/postgresql-9.4.1211.jre7.jar</runtime-relative-path>
|
||||
<binary-origin>release\modules\ext\postgresql-9.4.1211.jre7.jar</binary-origin>
|
||||
</class-path-extension>
|
||||
<class-path-extension>
|
||||
<runtime-relative-path>ext/junit-3.8.1.jar</runtime-relative-path>
|
||||
<binary-origin>release\modules\ext\junit-3.8.1.jar</binary-origin>
|
||||
</class-path-extension>
|
||||
<class-path-extension>
|
||||
<runtime-relative-path>ext/curator-client-2.8.0.jar</runtime-relative-path>
|
||||
<binary-origin>release/modules/ext/curator-client-2.8.0.jar</binary-origin>
|
||||
<binary-origin>release\modules\ext\curator-client-2.8.0.jar</binary-origin>
|
||||
</class-path-extension>
|
||||
<class-path-extension>
|
||||
<runtime-relative-path>ext/fontbox-2.0.13.jar</runtime-relative-path>
|
||||
<binary-origin>release\modules\ext\fontbox-2.0.13.jar</binary-origin>
|
||||
<runtime-relative-path>ext/grpc-core-1.19.0.jar</runtime-relative-path>
|
||||
<binary-origin>release\modules\ext\grpc-core-1.19.0.jar</binary-origin>
|
||||
</class-path-extension>
|
||||
<class-path-extension>
|
||||
<runtime-relative-path>ext/javax.ws.rs-api-2.0.jar</runtime-relative-path>
|
||||
<binary-origin>release\modules\ext\javax.ws.rs-api-2.0.jar</binary-origin>
|
||||
</class-path-extension>
|
||||
<class-path-extension>
|
||||
<runtime-relative-path>ext/icepdf-core-6.2.2.jar</runtime-relative-path>
|
||||
<binary-origin>release/modules/ext/icepdf-core-6.2.2.jar</binary-origin>
|
||||
<binary-origin>release\modules\ext\icepdf-core-6.2.2.jar</binary-origin>
|
||||
</class-path-extension>
|
||||
<class-path-extension>
|
||||
<runtime-relative-path>ext/activemq-all-5.11.1.jar</runtime-relative-path>
|
||||
<binary-origin>release/modules/ext/activemq-all-5.11.1.jar</binary-origin>
|
||||
<binary-origin>release\modules\ext\activemq-all-5.11.1.jar</binary-origin>
|
||||
</class-path-extension>
|
||||
<class-path-extension>
|
||||
<runtime-relative-path>ext/google-cloud-core-http-1.70.0.jar</runtime-relative-path>
|
||||
<binary-origin>release/modules/ext/google-cloud-core-http-1.70.0.jar</binary-origin>
|
||||
<binary-origin>release\modules\ext\google-cloud-core-http-1.70.0.jar</binary-origin>
|
||||
</class-path-extension>
|
||||
<class-path-extension>
|
||||
<runtime-relative-path>ext/Rejistry-1.1-SNAPSHOT.jar</runtime-relative-path>
|
||||
<binary-origin>release/modules/ext/Rejistry-1.1-SNAPSHOT.jar</binary-origin>
|
||||
<binary-origin>release\modules\ext\Rejistry-1.1-SNAPSHOT.jar</binary-origin>
|
||||
</class-path-extension>
|
||||
<class-path-extension>
|
||||
<runtime-relative-path>ext/dec-0.1.2.jar</runtime-relative-path>
|
||||
<binary-origin>release\modules\ext\dec-0.1.2.jar</binary-origin>
|
||||
<runtime-relative-path>ext/commons-beanutils-1.9.2.jar</runtime-relative-path>
|
||||
<binary-origin>release\modules\ext\commons-beanutils-1.9.2.jar</binary-origin>
|
||||
</class-path-extension>
|
||||
<class-path-extension>
|
||||
<runtime-relative-path>ext/batik-dom-1.6.jar</runtime-relative-path>
|
||||
<binary-origin>release/modules/ext/batik-dom-1.6.jar</binary-origin>
|
||||
<binary-origin>release\modules\ext\batik-dom-1.6.jar</binary-origin>
|
||||
</class-path-extension>
|
||||
<class-path-extension>
|
||||
<runtime-relative-path>ext/google-http-client-jackson2-1.29.0.jar</runtime-relative-path>
|
||||
<binary-origin>release/modules/ext/google-http-client-jackson2-1.29.0.jar</binary-origin>
|
||||
<binary-origin>release\modules\ext\google-http-client-jackson2-1.29.0.jar</binary-origin>
|
||||
</class-path-extension>
|
||||
<class-path-extension>
|
||||
<runtime-relative-path>ext/threetenbp-1.3.3.jar</runtime-relative-path>
|
||||
<binary-origin>release/modules/ext/threetenbp-1.3.3.jar</binary-origin>
|
||||
<binary-origin>release\modules\ext\threetenbp-1.3.3.jar</binary-origin>
|
||||
</class-path-extension>
|
||||
<class-path-extension>
|
||||
<runtime-relative-path>ext/google-cloud-translate-1.70.0.jar</runtime-relative-path>
|
||||
<binary-origin>release/modules/ext/google-cloud-translate-1.70.0.jar</binary-origin>
|
||||
<binary-origin>release\modules\ext\google-cloud-translate-1.70.0.jar</binary-origin>
|
||||
</class-path-extension>
|
||||
<class-path-extension>
|
||||
<runtime-relative-path>ext/grpc-stub-1.19.0.jar</runtime-relative-path>
|
||||
<binary-origin>release\modules\ext\grpc-stub-1.19.0.jar</binary-origin>
|
||||
</class-path-extension>
|
||||
<class-path-extension>
|
||||
<runtime-relative-path>ext/google-oauth-client-1.28.0.jar</runtime-relative-path>
|
||||
<binary-origin>release\modules\ext\google-oauth-client-1.28.0.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>
|
||||
<binary-origin>release\modules\ext\sevenzipjbinding-AllPlatforms.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>
|
||||
<binary-origin>release\modules\ext\jutf7-1.0.0.jar</binary-origin>
|
||||
</class-path-extension>
|
||||
<class-path-extension>
|
||||
<runtime-relative-path>ext/batik-awt-util-1.6.jar</runtime-relative-path>
|
||||
<binary-origin>release/modules/ext/batik-awt-util-1.6.jar</binary-origin>
|
||||
<binary-origin>release\modules\ext\batik-awt-util-1.6.jar</binary-origin>
|
||||
</class-path-extension>
|
||||
<class-path-extension>
|
||||
<runtime-relative-path>ext/google-api-services-translate-v2-rev20170525-1.27.0.jar</runtime-relative-path>
|
||||
<binary-origin>release/modules/ext/google-api-services-translate-v2-rev20170525-1.27.0.jar</binary-origin>
|
||||
</class-path-extension>
|
||||
<class-path-extension>
|
||||
<runtime-relative-path>ext/webp-imageio-sejda-0.1.0.jar</runtime-relative-path>
|
||||
<binary-origin>release/modules/ext/webp-imageio-sejda-0.1.0.jar</binary-origin>
|
||||
<binary-origin>release\modules\ext\google-api-services-translate-v2-rev20170525-1.27.0.jar</binary-origin>
|
||||
</class-path-extension>
|
||||
<class-path-extension>
|
||||
<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>
|
||||
<binary-origin>release\modules\ext\icepdf-viewer-6.2.2.jar</binary-origin>
|
||||
</class-path-extension>
|
||||
<class-path-extension>
|
||||
<runtime-relative-path>ext/bcmail-jdk15on-1.60.jar</runtime-relative-path>
|
||||
<binary-origin>release\modules\ext\bcmail-jdk15on-1.60.jar</binary-origin>
|
||||
<runtime-relative-path>ext/webp-imageio-sejda-0.1.0.jar</runtime-relative-path>
|
||||
<binary-origin>release\modules\ext\webp-imageio-sejda-0.1.0.jar</binary-origin>
|
||||
</class-path-extension>
|
||||
<class-path-extension>
|
||||
<runtime-relative-path>ext/vorbis-java-tika-0.8.jar</runtime-relative-path>
|
||||
<binary-origin>release\modules\ext\vorbis-java-tika-0.8.jar</binary-origin>
|
||||
<runtime-relative-path>ext/grpc-netty-shaded-1.19.0.jar</runtime-relative-path>
|
||||
<binary-origin>release\modules\ext\grpc-netty-shaded-1.19.0.jar</binary-origin>
|
||||
</class-path-extension>
|
||||
</data>
|
||||
</configuration>
|
||||
|
@ -70,7 +70,7 @@ import org.sleuthkit.autopsy.actions.OpenOutputFolderAction;
|
||||
import org.sleuthkit.autopsy.appservices.AutopsyService;
|
||||
import org.sleuthkit.autopsy.appservices.AutopsyService.CaseContext;
|
||||
import org.sleuthkit.autopsy.casemodule.CaseMetadata.CaseMetadataException;
|
||||
import org.sleuthkit.autopsy.casemodule.datasourcesummary.DataSourceSummaryAction;
|
||||
import org.sleuthkit.autopsy.datasourcesummary.ui.DataSourceSummaryAction;
|
||||
import org.sleuthkit.autopsy.casemodule.events.AddingDataSourceEvent;
|
||||
import org.sleuthkit.autopsy.casemodule.events.AddingDataSourceFailedEvent;
|
||||
import org.sleuthkit.autopsy.casemodule.events.BlackBoardArtifactTagAddedEvent;
|
||||
@ -141,6 +141,7 @@ import org.sleuthkit.datamodel.TskUnsupportedSchemaVersionException;
|
||||
*/
|
||||
public class Case {
|
||||
|
||||
private static final String CASE_TEMP_DIR = Case.class.getSimpleName();
|
||||
private static final int CASE_LOCK_TIMEOUT_MINS = 1;
|
||||
private static final int CASE_RESOURCES_LOCK_TIMEOUT_HOURS = 1;
|
||||
private static final String SINGLE_USER_CASE_DB_NAME = "autopsy.db";
|
||||
@ -150,7 +151,6 @@ public class Case {
|
||||
private static final String LOG_FOLDER = "Log"; //NON-NLS
|
||||
private static final String REPORTS_FOLDER = "Reports"; //NON-NLS
|
||||
private static final String CONFIG_FOLDER = "Config"; // NON-NLS
|
||||
private static final String TEMP_FOLDER = "Temp"; //NON-NLS
|
||||
private static final String MODULE_FOLDER = "ModuleOutput"; //NON-NLS
|
||||
private static final String CASE_ACTION_THREAD_NAME = "%s-case-action";
|
||||
private static final String CASE_RESOURCES_THREAD_NAME = "%s-manage-case-resources";
|
||||
@ -988,11 +988,6 @@ public class Case {
|
||||
throw new CaseActionException(NbBundle.getMessage(Case.class, "Case.createCaseDir.exception.cantCreateCaseDir", logsDir));
|
||||
}
|
||||
|
||||
Path tempDir = Paths.get(caseDirPath, hostPathComponent, TEMP_FOLDER);
|
||||
if (!tempDir.toFile().mkdirs()) {
|
||||
throw new CaseActionException(NbBundle.getMessage(Case.class, "Case.createCaseDir.exception.cantCreateCaseDir", tempDir));
|
||||
}
|
||||
|
||||
Path cacheDir = Paths.get(caseDirPath, hostPathComponent, CACHE_FOLDER);
|
||||
if (!cacheDir.toFile().mkdirs()) {
|
||||
throw new CaseActionException(NbBundle.getMessage(Case.class, "Case.createCaseDir.exception.cantCreateCaseDir", cacheDir));
|
||||
@ -1196,25 +1191,6 @@ public class Case {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Empties the temp subdirectory for the current case.
|
||||
*/
|
||||
private static void clearTempSubDir(String tempSubDirPath) {
|
||||
File tempFolder = new File(tempSubDirPath);
|
||||
if (tempFolder.isDirectory()) {
|
||||
File[] files = tempFolder.listFiles();
|
||||
if (files.length > 0) {
|
||||
for (File file : files) {
|
||||
if (file.isDirectory()) {
|
||||
FileUtil.deleteDir(file);
|
||||
} else {
|
||||
file.delete();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the case database.
|
||||
*
|
||||
@ -1352,7 +1328,16 @@ public class Case {
|
||||
* @return The temp subdirectory path.
|
||||
*/
|
||||
public String getTempDirectory() {
|
||||
return getOrCreateSubdirectory(TEMP_FOLDER);
|
||||
// get temp folder scoped to the combination of case name and timestamp
|
||||
// provided by getName()
|
||||
Path path = Paths.get(UserPreferences.getAppTempDirectory(), CASE_TEMP_DIR, getName());
|
||||
File f = path.toFile();
|
||||
// verify that the folder exists
|
||||
if (!f.exists()) {
|
||||
f.mkdirs();
|
||||
}
|
||||
|
||||
return path.toAbsolutePath().toString();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -2396,7 +2381,7 @@ public class Case {
|
||||
* Clear the temp subdirectory of the case directory.
|
||||
*/
|
||||
progressIndicator.progress(Bundle.Case_progressMessage_clearingTempDirectory());
|
||||
Case.clearTempSubDir(this.getTempDirectory());
|
||||
FileUtil.deleteDir(new File(this.getTempDirectory()));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -2764,6 +2749,11 @@ public class Case {
|
||||
caseDb.close();
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete files from temp directory if any exist.
|
||||
*/
|
||||
deleteTempfilesFromCaseDirectory(progressIndicator);
|
||||
|
||||
/*
|
||||
* Switch the log directory.
|
||||
*/
|
||||
|
@ -31,7 +31,9 @@ import javax.swing.JOptionPane;
|
||||
import javax.swing.event.ListSelectionEvent;
|
||||
import javax.swing.table.AbstractTableModel;
|
||||
import org.openide.util.NbBundle.Messages;
|
||||
import static org.sleuthkit.autopsy.casemodule.Case.Events.CURRENT_CASE;
|
||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||
import org.sleuthkit.autopsy.events.AutopsyEvent;
|
||||
import org.sleuthkit.autopsy.ingest.IngestManager;
|
||||
import org.sleuthkit.datamodel.IngestJobInfo;
|
||||
import org.sleuthkit.datamodel.IngestModuleInfo;
|
||||
@ -47,6 +49,8 @@ public final class IngestJobInfoPanel extends javax.swing.JPanel {
|
||||
|
||||
private static final Logger logger = Logger.getLogger(IngestJobInfoPanel.class.getName());
|
||||
private static final Set<IngestManager.IngestJobEvent> INGEST_JOB_EVENTS_OF_INTEREST = EnumSet.of(IngestManager.IngestJobEvent.STARTED, IngestManager.IngestJobEvent.CANCELLED, IngestManager.IngestJobEvent.COMPLETED);
|
||||
private static final Set<Case.Events> CASE_EVENTS_OF_INTEREST = EnumSet.of(Case.Events.CURRENT_CASE);
|
||||
|
||||
private List<IngestJobInfo> ingestJobs;
|
||||
private final List<IngestJobInfo> ingestJobsForSelectedDataSource = new ArrayList<>();
|
||||
private IngestJobTableModel ingestJobTableModel = new IngestJobTableModel();
|
||||
@ -79,6 +83,16 @@ public final class IngestJobInfoPanel extends javax.swing.JPanel {
|
||||
refresh();
|
||||
}
|
||||
});
|
||||
|
||||
Case.addEventTypeSubscriber(CASE_EVENTS_OF_INTEREST, (PropertyChangeEvent evt) -> {
|
||||
if (!(evt instanceof AutopsyEvent) || (((AutopsyEvent) evt).getSourceType() != AutopsyEvent.SourceType.LOCAL)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (CURRENT_CASE == Case.Events.valueOf(evt.getPropertyName())) {
|
||||
refresh();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
@ -110,9 +124,15 @@ public final class IngestJobInfoPanel extends javax.swing.JPanel {
|
||||
*/
|
||||
private void refresh() {
|
||||
try {
|
||||
if (Case.isCaseOpen()) {
|
||||
SleuthkitCase skCase = Case.getCurrentCaseThrows().getSleuthkitCase();
|
||||
this.ingestJobs = skCase.getIngestJobs();
|
||||
setDataSource(selectedDataSource);
|
||||
} else {
|
||||
this.ingestJobs = new ArrayList<>();
|
||||
setDataSource(null);
|
||||
}
|
||||
|
||||
} catch (TskCoreException | NoCurrentCaseException ex) {
|
||||
logger.log(Level.SEVERE, "Failed to load ingest jobs.", ex);
|
||||
JOptionPane.showMessageDialog(this, Bundle.IngestJobInfoPanel_loadIngestJob_error_text(), Bundle.IngestJobInfoPanel_loadIngestJob_error_title(), JOptionPane.ERROR_MESSAGE);
|
||||
|
66
Core/src/org/sleuthkit/autopsy/casemodule/Installer.java
Normal file
66
Core/src/org/sleuthkit/autopsy/casemodule/Installer.java
Normal file
@ -0,0 +1,66 @@
|
||||
/*
|
||||
* Autopsy Forensic Browser
|
||||
*
|
||||
* Copyright 2020 Basis Technology Corp.
|
||||
* Contact: carrier <at> sleuthkit <dot> org
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.sleuthkit.autopsy.casemodule;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.logging.Level;
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.openide.modules.ModuleInstall;
|
||||
import org.sleuthkit.autopsy.core.UserPreferences;
|
||||
import org.sleuthkit.autopsy.coreutils.FileUtil;
|
||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||
|
||||
/**
|
||||
* Installer for casemodule that cleans out user specified temp directory.
|
||||
*/
|
||||
public final class Installer extends ModuleInstall {
|
||||
|
||||
private static final Logger logger = Logger.getLogger(Installer.class.getName());
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private static Installer instance;
|
||||
|
||||
public synchronized static Installer getDefault() {
|
||||
if (instance == null) {
|
||||
instance = new Installer();
|
||||
}
|
||||
return instance;
|
||||
}
|
||||
|
||||
private Installer() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void restored() {
|
||||
String tempDirStr = null;
|
||||
try {
|
||||
tempDirStr = UserPreferences.getAppTempDirectory();
|
||||
if (StringUtils.isNotBlank(tempDirStr)) {
|
||||
File tempDir = new File(tempDirStr);
|
||||
if (tempDir.exists()) {
|
||||
FileUtil.deleteDir(tempDir);
|
||||
}
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
// This is a firewall exception should any issues occur
|
||||
// during temp directory deletion
|
||||
logger.log(Level.WARNING, "There was an error while cleaning up temp directory: " + (tempDirStr == null ? "<null>" : tempDirStr), ex);
|
||||
}
|
||||
}
|
||||
}
|
@ -24,6 +24,7 @@ import java.util.logging.Level;
|
||||
import org.netbeans.spi.sendopts.OptionProcessor;
|
||||
import org.openide.util.Lookup;
|
||||
import org.sleuthkit.autopsy.commandlineingest.CommandLineIngestManager;
|
||||
import org.sleuthkit.autopsy.commandlineingest.CommandLineOpenCaseManager;
|
||||
import org.sleuthkit.autopsy.commandlineingest.CommandLineOptionProcessor;
|
||||
import org.sleuthkit.autopsy.commandlineingest.CommandLineStartupWindow;
|
||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||
@ -58,6 +59,12 @@ public class StartupWindowProvider implements StartupWindowInterface {
|
||||
|
||||
private void init() {
|
||||
if (startupWindowToUse == null) {
|
||||
|
||||
if (openCaseInUI()) {
|
||||
new CommandLineOpenCaseManager().start();
|
||||
return;
|
||||
}
|
||||
|
||||
// first check whether we are running from command line
|
||||
if (isRunningFromCommandLine()) {
|
||||
// Autopsy is running from command line
|
||||
@ -131,6 +138,28 @@ public class StartupWindowProvider implements StartupWindowInterface {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether Autopsy was launched from the command line with the option
|
||||
* to open an existing case.
|
||||
*
|
||||
* @return True if opening an existing case.
|
||||
*/
|
||||
private boolean openCaseInUI() {
|
||||
// first look up all OptionProcessors and see if running from command line option is set
|
||||
Collection<? extends OptionProcessor> optionProcessors = Lookup.getDefault().lookupAll(OptionProcessor.class);
|
||||
Iterator<? extends OptionProcessor> optionsIterator = optionProcessors.iterator();
|
||||
while (optionsIterator.hasNext()) {
|
||||
// find CommandLineOptionProcessor
|
||||
OptionProcessor processor = optionsIterator.next();
|
||||
if ((processor instanceof OpenFromArguments)) {
|
||||
// check if we are running from command line
|
||||
String arg = ((OpenFromArguments) processor).getDefaultArg();
|
||||
return arg != null && !arg.isEmpty();
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void open() {
|
||||
if (startupWindowToUse != null) {
|
||||
|
@ -1,366 +0,0 @@
|
||||
/*
|
||||
* Autopsy Forensic Browser
|
||||
*
|
||||
* Copyright 2019 Basis Technology Corp.
|
||||
* Contact: carrier <at> sleuthkit <dot> org
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.sleuthkit.autopsy.casemodule.datasourcesummary;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.logging.Level;
|
||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||
import org.sleuthkit.datamodel.SleuthkitCase;
|
||||
import org.sleuthkit.datamodel.TskCoreException;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Set;
|
||||
import org.sleuthkit.autopsy.casemodule.Case;
|
||||
import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException;
|
||||
import org.sleuthkit.datamodel.BlackboardArtifact;
|
||||
import org.sleuthkit.datamodel.TskData;
|
||||
import org.sleuthkit.datamodel.BlackboardAttribute;
|
||||
import org.sleuthkit.datamodel.DataSource;
|
||||
|
||||
/**
|
||||
* Utilities for getting information about a data source or all data sources
|
||||
* from the case database.
|
||||
*/
|
||||
final class DataSourceInfoUtilities {
|
||||
|
||||
private static final Logger logger = Logger.getLogger(DataSourceInfoUtilities.class.getName());
|
||||
|
||||
/**
|
||||
* Get a map containing the TSK_DATA_SOURCE_USAGE description attributes
|
||||
* associated with each data source in the current case.
|
||||
*
|
||||
* @return Collection which maps datasource id to a String which displays a
|
||||
* comma seperated list of values of data source usage types
|
||||
* expected to be in the datasource
|
||||
*/
|
||||
static Map<Long, String> getDataSourceTypes() {
|
||||
try {
|
||||
SleuthkitCase skCase = Case.getCurrentCaseThrows().getSleuthkitCase();
|
||||
List<BlackboardArtifact> listOfArtifacts = skCase.getBlackboardArtifacts(BlackboardArtifact.ARTIFACT_TYPE.TSK_DATA_SOURCE_USAGE);
|
||||
Map<Long, String> typeMap = new HashMap<>();
|
||||
for (BlackboardArtifact typeArtifact : listOfArtifacts) {
|
||||
BlackboardAttribute descriptionAttr = typeArtifact.getAttribute(new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DESCRIPTION));
|
||||
if (typeArtifact.getDataSource() != null && descriptionAttr != null) {
|
||||
long dsId = typeArtifact.getDataSource().getId();
|
||||
String type = typeMap.get(typeArtifact.getDataSource().getId());
|
||||
if (type == null) {
|
||||
type = descriptionAttr.getValueString();
|
||||
} else {
|
||||
type = type + ", " + descriptionAttr.getValueString();
|
||||
}
|
||||
typeMap.put(dsId, type);
|
||||
}
|
||||
}
|
||||
return typeMap;
|
||||
} catch (TskCoreException | NoCurrentCaseException ex) {
|
||||
logger.log(Level.WARNING, "Unable to get types of files for all datasources, providing empty results", ex);
|
||||
return Collections.emptyMap();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a map containing the number of files in each data source in the
|
||||
* current case.
|
||||
*
|
||||
* @return Collection which maps datasource id to a count for the number of
|
||||
* files in the datasource, will only contain entries for
|
||||
* datasources which have at least 1 file
|
||||
*/
|
||||
static Map<Long, Long> getCountsOfFiles() {
|
||||
try {
|
||||
final String countFilesQuery = "data_source_obj_id, COUNT(*) AS value"
|
||||
+ " FROM tsk_files WHERE type<>" + TskData.TSK_DB_FILES_TYPE_ENUM.VIRTUAL_DIR.getFileType()
|
||||
+ " AND dir_type<>" + TskData.TSK_FS_NAME_TYPE_ENUM.VIRT_DIR.getValue()
|
||||
+ " AND name<>'' GROUP BY data_source_obj_id"; //NON-NLS
|
||||
return getValuesMap(countFilesQuery);
|
||||
} catch (TskCoreException | NoCurrentCaseException ex) {
|
||||
logger.log(Level.WARNING, "Unable to get counts of files for all datasources, providing empty results", ex);
|
||||
return Collections.emptyMap();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a map containing the number of artifacts in each data source in the
|
||||
* current case.
|
||||
*
|
||||
* @return Collection which maps datasource id to a count for the number of
|
||||
* artifacts in the datasource, will only contain entries for
|
||||
* datasources which have at least 1 artifact
|
||||
*/
|
||||
static Map<Long, Long> getCountsOfArtifacts() {
|
||||
try {
|
||||
final String countArtifactsQuery = "data_source_obj_id, COUNT(*) AS value"
|
||||
+ " FROM blackboard_artifacts WHERE review_status_id !=" + BlackboardArtifact.ReviewStatus.REJECTED.getID()
|
||||
+ " GROUP BY data_source_obj_id"; //NON-NLS
|
||||
return getValuesMap(countArtifactsQuery);
|
||||
} catch (TskCoreException | NoCurrentCaseException ex) {
|
||||
logger.log(Level.WARNING, "Unable to get counts of artifacts for all datasources, providing empty results", ex);
|
||||
return Collections.emptyMap();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a map containing the number of tags which have been applied in each
|
||||
* data source in the current case. Not necessarily the same as the number
|
||||
* of items tagged, as an item can have any number of tags.
|
||||
*
|
||||
* @return Collection which maps datasource id to a count for the number of
|
||||
* tags which have been applied in the datasource, will only contain
|
||||
* entries for datasources which have at least 1 item tagged.
|
||||
*/
|
||||
static Map<Long, Long> getCountsOfTags() {
|
||||
try {
|
||||
final String countFileTagsQuery = "data_source_obj_id, COUNT(*) AS value"
|
||||
+ " FROM content_tags as content_tags, tsk_files as tsk_files"
|
||||
+ " WHERE content_tags.obj_id = tsk_files.obj_id"
|
||||
+ " GROUP BY data_source_obj_id"; //NON-NLS
|
||||
//new hashmap so it can be modifiable
|
||||
Map<Long, Long> tagCountMap = new HashMap<>(getValuesMap(countFileTagsQuery));
|
||||
final String countArtifactTagsQuery = "data_source_obj_id, COUNT(*) AS value"
|
||||
+ " FROM blackboard_artifact_tags as artifact_tags, blackboard_artifacts AS arts"
|
||||
+ " WHERE artifact_tags.artifact_id = arts.artifact_id"
|
||||
+ " GROUP BY data_source_obj_id"; //NON-NLS
|
||||
//combine the results from the count artifact tags query into the copy of the mapped results from the count file tags query
|
||||
getValuesMap(countArtifactTagsQuery).forEach((key, value) -> tagCountMap.merge(key, value, (value1, value2) -> value1 + value2));
|
||||
return tagCountMap;
|
||||
} catch (TskCoreException | NoCurrentCaseException ex) {
|
||||
logger.log(Level.WARNING, "Unable to get counts of tags for all datasources, providing empty results", ex);
|
||||
return Collections.emptyMap();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a map containing the names of operating systems joined in a comma
|
||||
* seperated list to the Data Source they exist on in the current case. No
|
||||
* item will exist in the map for data sources which do not contain
|
||||
* TS_OS_INFO artifacts which have a program name.
|
||||
*
|
||||
* @return Collection which maps datasource id to a String which is a comma
|
||||
* seperated list of Operating system names found on the data
|
||||
* source.
|
||||
*/
|
||||
static Map<Long, String> getOperatingSystems() {
|
||||
Map<Long, String> osDetailMap = new HashMap<>();
|
||||
try {
|
||||
SleuthkitCase skCase = Case.getCurrentCaseThrows().getSleuthkitCase();
|
||||
ArrayList<BlackboardArtifact> osInfoArtifacts = skCase.getBlackboardArtifacts(BlackboardArtifact.ARTIFACT_TYPE.TSK_OS_INFO);
|
||||
for (BlackboardArtifact osInfo : osInfoArtifacts) {
|
||||
BlackboardAttribute programName = osInfo.getAttribute(new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PROG_NAME));
|
||||
if (programName != null) {
|
||||
String currentOsString = osDetailMap.get(osInfo.getDataSource().getId());
|
||||
if (currentOsString == null || currentOsString.isEmpty()) {
|
||||
currentOsString = programName.getValueString();
|
||||
} else {
|
||||
currentOsString = currentOsString + ", " + programName.getValueString();
|
||||
}
|
||||
osDetailMap.put(osInfo.getDataSource().getId(), currentOsString);
|
||||
}
|
||||
}
|
||||
} catch (TskCoreException | NoCurrentCaseException ex) {
|
||||
logger.log(Level.SEVERE, "Failed to load OS info artifacts.", ex);
|
||||
}
|
||||
return osDetailMap;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the number of files in the case database for the current data source
|
||||
* which have the specified mimetypes.
|
||||
*
|
||||
* @param currentDataSource the data source which we are finding a file
|
||||
* count
|
||||
*
|
||||
* @param setOfMimeTypes the set of mime types which we are finding the
|
||||
* number of occurences of
|
||||
*
|
||||
* @return a Long value which represents the number of occurrences of the
|
||||
* specified mime types in the current case for the specified data
|
||||
* source, null if no count was retrieved
|
||||
*/
|
||||
static Long getCountOfFilesForMimeTypes(DataSource currentDataSource, Set<String> setOfMimeTypes) {
|
||||
if (currentDataSource != null) {
|
||||
try {
|
||||
String inClause = String.join("', '", setOfMimeTypes);
|
||||
SleuthkitCase skCase = Case.getCurrentCaseThrows().getSleuthkitCase();
|
||||
return skCase.countFilesWhere("data_source_obj_id=" + currentDataSource.getId()
|
||||
+ " AND type<>" + TskData.TSK_DB_FILES_TYPE_ENUM.VIRTUAL_DIR.getFileType()
|
||||
+ " AND dir_type<>" + TskData.TSK_FS_NAME_TYPE_ENUM.VIRT_DIR.getValue()
|
||||
+ " AND mime_type IN ('" + inClause + "')"
|
||||
+ " AND name<>''");
|
||||
} catch (TskCoreException | NoCurrentCaseException ex) {
|
||||
logger.log(Level.WARNING, "Unable to get count of files for specified mime types", ex);
|
||||
//unable to get count of files for the specified mimetypes cell will be displayed as empty
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a map containing the number of unallocated files in each data source
|
||||
* in the current case.
|
||||
*
|
||||
* @return Collection which maps datasource id to a count for the number of
|
||||
* unallocated files in the datasource, will only contain entries
|
||||
* for datasources which have at least 1 unallocated file
|
||||
*/
|
||||
static Map<Long, Long> getCountsOfUnallocatedFiles() {
|
||||
try {
|
||||
final String countUnallocatedFilesQuery = "data_source_obj_id, COUNT(*) AS value"
|
||||
+ " FROM tsk_files WHERE type<>" + TskData.TSK_DB_FILES_TYPE_ENUM.VIRTUAL_DIR.getFileType()
|
||||
+ " AND dir_type<>" + TskData.TSK_FS_NAME_TYPE_ENUM.VIRT_DIR.getValue()
|
||||
+ " AND dir_flags=" + TskData.TSK_FS_NAME_FLAG_ENUM.UNALLOC.getValue()
|
||||
+ " AND name<>'' GROUP BY data_source_obj_id"; //NON-NLS
|
||||
return getValuesMap(countUnallocatedFilesQuery);
|
||||
} catch (TskCoreException | NoCurrentCaseException ex) {
|
||||
logger.log(Level.WARNING, "Unable to get counts of unallocated files for all datasources, providing empty results", ex);
|
||||
return Collections.emptyMap();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a map containing the total size of unallocated files in each data
|
||||
* source in the current case.
|
||||
*
|
||||
* @return Collection which maps datasource id to a total size in bytes of
|
||||
* unallocated files in the datasource, will only contain entries
|
||||
* for datasources which have at least 1 unallocated file
|
||||
*/
|
||||
static Map<Long, Long> getSizeOfUnallocatedFiles() {
|
||||
try {
|
||||
final String countUnallocatedFilesQuery = "data_source_obj_id, sum(size) AS value"
|
||||
+ " FROM tsk_files WHERE type<>" + TskData.TSK_DB_FILES_TYPE_ENUM.VIRTUAL_DIR.getFileType()
|
||||
+ " AND dir_type<>" + TskData.TSK_FS_NAME_TYPE_ENUM.VIRT_DIR.getValue()
|
||||
+ " AND dir_flags=" + TskData.TSK_FS_NAME_FLAG_ENUM.UNALLOC.getValue()
|
||||
+ " AND name<>'' GROUP BY data_source_obj_id"; //NON-NLS
|
||||
return getValuesMap(countUnallocatedFilesQuery);
|
||||
} catch (TskCoreException | NoCurrentCaseException ex) {
|
||||
logger.log(Level.WARNING, "Unable to get size of unallocated files for all datasources, providing empty results", ex);
|
||||
return Collections.emptyMap();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a map containing the number of directories in each data source in the
|
||||
* current case.
|
||||
*
|
||||
* @return Collection which maps datasource id to a count for the number of
|
||||
* directories in the datasource, will only contain entries for
|
||||
* datasources which have at least 1 directory
|
||||
*/
|
||||
static Map<Long, Long> getCountsOfDirectories() {
|
||||
try {
|
||||
final String countDirectoriesQuery = "data_source_obj_id, COUNT(*) AS value"
|
||||
+ " FROM tsk_files WHERE type<>" + TskData.TSK_DB_FILES_TYPE_ENUM.VIRTUAL_DIR.getFileType()
|
||||
+ " AND dir_type<>" + TskData.TSK_FS_NAME_TYPE_ENUM.VIRT_DIR.getValue()
|
||||
+ " AND meta_type=" + TskData.TSK_FS_META_TYPE_ENUM.TSK_FS_META_TYPE_DIR.getValue()
|
||||
+ " AND name<>'' GROUP BY data_source_obj_id"; //NON-NLS
|
||||
return getValuesMap(countDirectoriesQuery);
|
||||
} catch (TskCoreException | NoCurrentCaseException ex) {
|
||||
logger.log(Level.WARNING, "Unable to get counts of directories for all datasources, providing empty results", ex);
|
||||
return Collections.emptyMap();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a map containing the number of slack files in each data source in the
|
||||
* current case.
|
||||
*
|
||||
* @return Collection which maps datasource id to a count for the number of
|
||||
* slack files in the datasource, will only contain entries for
|
||||
* datasources which have at least 1 slack file
|
||||
*/
|
||||
static Map<Long, Long> getCountsOfSlackFiles() {
|
||||
try {
|
||||
final String countSlackFilesQuery = "data_source_obj_id, COUNT(*) AS value"
|
||||
+ " FROM tsk_files WHERE type=" + TskData.TSK_DB_FILES_TYPE_ENUM.SLACK.getFileType()
|
||||
+ " AND dir_type<>" + TskData.TSK_FS_NAME_TYPE_ENUM.VIRT_DIR.getValue()
|
||||
+ " AND name<>'' GROUP BY data_source_obj_id"; //NON-NLS
|
||||
return getValuesMap(countSlackFilesQuery);
|
||||
} catch (TskCoreException | NoCurrentCaseException ex) {
|
||||
logger.log(Level.WARNING, "Unable to get counts of slack files for all datasources, providing empty results", ex);
|
||||
return Collections.emptyMap();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a map containing maps which map artifact type to the number of times
|
||||
* it exosts in each data source in the current case.
|
||||
*
|
||||
* @return Collection which maps datasource id to maps of artifact display
|
||||
* name to number of occurences in the datasource, will only contain
|
||||
* entries for artifacts which have at least one occurence in the
|
||||
* data source.
|
||||
*/
|
||||
static Map<Long, Map<String, Long>> getCountsOfArtifactsByType() {
|
||||
try {
|
||||
final String countArtifactsQuery = "blackboard_artifacts.data_source_obj_id, blackboard_artifact_types.display_name AS label, COUNT(*) AS value"
|
||||
+ " FROM blackboard_artifacts, blackboard_artifact_types"
|
||||
+ " WHERE blackboard_artifacts.artifact_type_id = blackboard_artifact_types.artifact_type_id"
|
||||
+ " GROUP BY blackboard_artifacts.data_source_obj_id, blackboard_artifact_types.display_name";
|
||||
return getLabeledValuesMap(countArtifactsQuery);
|
||||
} catch (TskCoreException | NoCurrentCaseException ex) {
|
||||
logger.log(Level.WARNING, "Unable to get counts of all artifact types for all datasources, providing empty results", ex);
|
||||
return Collections.emptyMap();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper method to execute a select query with a
|
||||
* DataSourceLabeledValueCallback.
|
||||
*
|
||||
* @param query the portion of the query which should follow the SELECT
|
||||
*
|
||||
* @return a map of datasource object IDs to maps of String labels to the
|
||||
* values associated with them.
|
||||
*
|
||||
* @throws TskCoreException
|
||||
* @throws NoCurrentCaseException
|
||||
*/
|
||||
private static Map<Long, Map<String, Long>> getLabeledValuesMap(String query) throws TskCoreException, NoCurrentCaseException {
|
||||
SleuthkitCase skCase = Case.getCurrentCaseThrows().getSleuthkitCase();
|
||||
DataSourceLabeledValueCallback callback = new DataSourceLabeledValueCallback();
|
||||
skCase.getCaseDbAccessManager().select(query, callback);
|
||||
return callback.getMapOfLabeledValues();
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper method to execute a select query with a
|
||||
* DataSourceSingleValueCallback.
|
||||
*
|
||||
* @param query the portion of the query which should follow the SELECT
|
||||
*
|
||||
* @return a map of datasource object ID to a value of type Long
|
||||
*
|
||||
* @throws TskCoreException
|
||||
* @throws NoCurrentCaseException
|
||||
*/
|
||||
private static Map<Long, Long> getValuesMap(String query) throws TskCoreException, NoCurrentCaseException {
|
||||
SleuthkitCase skCase = Case.getCurrentCaseThrows().getSleuthkitCase();
|
||||
DataSourceSingleValueCallback callback = new DataSourceSingleValueCallback();
|
||||
skCase.getCaseDbAccessManager().select(query, callback);
|
||||
return callback.getMapOfValues();
|
||||
}
|
||||
|
||||
/**
|
||||
* Empty private constructor
|
||||
*/
|
||||
private DataSourceInfoUtilities() {
|
||||
}
|
||||
}
|
@ -1,139 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
|
||||
<Form version="1.5" maxVersion="1.9" type="org.netbeans.modules.form.forminfo.JPanelFormInfo">
|
||||
<AuxValues>
|
||||
<AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="1"/>
|
||||
<AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/>
|
||||
<AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/>
|
||||
<AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="true"/>
|
||||
<AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="true"/>
|
||||
<AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/>
|
||||
<AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/>
|
||||
<AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/>
|
||||
<AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/>
|
||||
</AuxValues>
|
||||
|
||||
<Layout>
|
||||
<DimensionLayout dim="0">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Group type="102" alignment="0" attributes="0">
|
||||
<EmptySpace min="-2" max="-2" attributes="0"/>
|
||||
<Group type="103" groupAlignment="0" max="-2" attributes="0">
|
||||
<Component id="fileCountsByMimeTypeScrollPane" linkSize="1" pref="140" max="32767" attributes="0"/>
|
||||
<Component id="byMimeTypeLabel" max="32767" attributes="0"/>
|
||||
</Group>
|
||||
<EmptySpace type="separate" min="-2" max="-2" attributes="0"/>
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Component id="byCategoryLabel" alignment="0" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="fileCountsByCategoryScrollPane" linkSize="1" alignment="0" min="-2" pref="82" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<EmptySpace type="separate" min="-2" max="-2" attributes="0"/>
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Component id="jLabel1" min="-2" pref="79" max="-2" attributes="0"/>
|
||||
<Component id="artifactCountsScrollPane" min="-2" pref="244" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<EmptySpace max="32767" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
<DimensionLayout dim="1">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Group type="102" alignment="0" attributes="0">
|
||||
<EmptySpace min="-2" max="-2" attributes="0"/>
|
||||
<Group type="103" groupAlignment="3" attributes="0">
|
||||
<Component id="byMimeTypeLabel" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="byCategoryLabel" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="jLabel1" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<EmptySpace min="-2" max="-2" attributes="0"/>
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Component id="artifactCountsScrollPane" alignment="1" pref="0" max="32767" attributes="0"/>
|
||||
<Group type="102" attributes="0">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Component id="fileCountsByMimeTypeScrollPane" linkSize="2" min="-2" pref="107" max="-2" attributes="0"/>
|
||||
<Component id="fileCountsByCategoryScrollPane" linkSize="2" min="-2" pref="86" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<EmptySpace min="0" pref="0" max="32767" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
</Layout>
|
||||
<SubComponents>
|
||||
<Container class="javax.swing.JScrollPane" name="fileCountsByMimeTypeScrollPane">
|
||||
<AuxValues>
|
||||
<AuxValue name="autoScrollPane" type="java.lang.Boolean" value="true"/>
|
||||
</AuxValues>
|
||||
|
||||
<Layout class="org.netbeans.modules.form.compat2.layouts.support.JScrollPaneSupportLayout"/>
|
||||
<SubComponents>
|
||||
<Component class="javax.swing.JTable" name="fileCountsByMimeTypeTable">
|
||||
<Properties>
|
||||
<Property name="model" type="javax.swing.table.TableModel" editor="org.netbeans.modules.form.RADConnectionPropertyEditor">
|
||||
<Connection code="filesByMimeTypeTableModel" type="code"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
</Component>
|
||||
</SubComponents>
|
||||
</Container>
|
||||
<Component class="javax.swing.JLabel" name="byMimeTypeLabel">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/casemodule/datasourceSummary/Bundle.properties" key="DataSourceSummaryCountsPanel.byMimeTypeLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
</Component>
|
||||
<Container class="javax.swing.JScrollPane" name="fileCountsByCategoryScrollPane">
|
||||
<AuxValues>
|
||||
<AuxValue name="autoScrollPane" type="java.lang.Boolean" value="true"/>
|
||||
</AuxValues>
|
||||
|
||||
<Layout class="org.netbeans.modules.form.compat2.layouts.support.JScrollPaneSupportLayout"/>
|
||||
<SubComponents>
|
||||
<Component class="javax.swing.JTable" name="fileCountsByCategoryTable">
|
||||
<Properties>
|
||||
<Property name="model" type="javax.swing.table.TableModel" editor="org.netbeans.modules.form.RADConnectionPropertyEditor">
|
||||
<Connection code="filesByCategoryTableModel" type="code"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
</Component>
|
||||
</SubComponents>
|
||||
</Container>
|
||||
<Component class="javax.swing.JLabel" name="byCategoryLabel">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/casemodule/datasourceSummary/Bundle.properties" key="DataSourceSummaryCountsPanel.byCategoryLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
</Component>
|
||||
<Component class="javax.swing.JLabel" name="jLabel1">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/casemodule/datasourceSummary/Bundle.properties" key="DataSourceSummaryCountsPanel.jLabel1.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
</Component>
|
||||
<Container class="javax.swing.JScrollPane" name="artifactCountsScrollPane">
|
||||
<AuxValues>
|
||||
<AuxValue name="autoScrollPane" type="java.lang.Boolean" value="true"/>
|
||||
</AuxValues>
|
||||
|
||||
<Layout class="org.netbeans.modules.form.compat2.layouts.support.JScrollPaneSupportLayout"/>
|
||||
<SubComponents>
|
||||
<Component class="javax.swing.JTable" name="artifactCountsTable">
|
||||
<Properties>
|
||||
<Property name="autoCreateRowSorter" type="boolean" value="true"/>
|
||||
<Property name="model" type="javax.swing.table.TableModel" editor="org.netbeans.modules.form.editors2.TableModelEditor">
|
||||
<Table columnCount="2" rowCount="0">
|
||||
<Column editable="false" title="Result Type" type="java.lang.Object"/>
|
||||
<Column editable="false" title="Count" type="java.lang.Object"/>
|
||||
</Table>
|
||||
</Property>
|
||||
</Properties>
|
||||
</Component>
|
||||
</SubComponents>
|
||||
</Container>
|
||||
</SubComponents>
|
||||
</Form>
|
@ -1,395 +0,0 @@
|
||||
/*
|
||||
* Autopsy Forensic Browser
|
||||
*
|
||||
* Copyright 2019 Basis Technology Corp.
|
||||
* Contact: carrier <at> sleuthkit <dot> org
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.sleuthkit.autopsy.casemodule.datasourcesummary;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.table.AbstractTableModel;
|
||||
import javax.swing.table.DefaultTableCellRenderer;
|
||||
import javax.swing.table.DefaultTableModel;
|
||||
import org.openide.util.NbBundle.Messages;
|
||||
import org.sleuthkit.autopsy.coreutils.FileTypeUtils;
|
||||
import org.sleuthkit.datamodel.DataSource;
|
||||
|
||||
/**
|
||||
* Panel for displaying summary information on the known files present in the
|
||||
* specified DataSource
|
||||
*/
|
||||
class DataSourceSummaryCountsPanel extends javax.swing.JPanel {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
private FilesByMimeTypeTableModel filesByMimeTypeTableModel = new FilesByMimeTypeTableModel(null);
|
||||
private FilesByCategoryTableModel filesByCategoryTableModel = new FilesByCategoryTableModel(null);
|
||||
private static final Logger logger = Logger.getLogger(DataSourceSummaryCountsPanel.class.getName());
|
||||
private final Map<Long, Long> allFilesCountsMap;
|
||||
private final Map<Long, Long> slackFilesCountsMap;
|
||||
private final Map<Long, Long> directoriesCountsMap;
|
||||
private final Map<Long, Long> unallocatedFilesCountsMap;
|
||||
private final Map<Long, Map<String, Long>> artifactsByTypeCountsMap;
|
||||
private final DefaultTableCellRenderer rightAlignedRenderer = new DefaultTableCellRenderer();
|
||||
|
||||
/**
|
||||
* Creates new form DataSourceSummaryCountsPanel
|
||||
*/
|
||||
DataSourceSummaryCountsPanel(Map<Long, Long> fileCountsMap) {
|
||||
this.allFilesCountsMap = fileCountsMap;
|
||||
this.slackFilesCountsMap = DataSourceInfoUtilities.getCountsOfSlackFiles();
|
||||
this.directoriesCountsMap = DataSourceInfoUtilities.getCountsOfDirectories();
|
||||
this.unallocatedFilesCountsMap = DataSourceInfoUtilities.getCountsOfUnallocatedFiles();
|
||||
this.artifactsByTypeCountsMap = DataSourceInfoUtilities.getCountsOfArtifactsByType();
|
||||
rightAlignedRenderer.setHorizontalAlignment(JLabel.RIGHT);
|
||||
initComponents();
|
||||
fileCountsByMimeTypeTable.getTableHeader().setReorderingAllowed(false);
|
||||
fileCountsByCategoryTable.getTableHeader().setReorderingAllowed(false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Specify the DataSource to display file information for
|
||||
*
|
||||
* @param selectedDataSource the DataSource to display file information for
|
||||
*/
|
||||
void updateCountsTableData(DataSource selectedDataSource) {
|
||||
filesByMimeTypeTableModel = new FilesByMimeTypeTableModel(selectedDataSource);
|
||||
fileCountsByMimeTypeTable.setModel(filesByMimeTypeTableModel);
|
||||
fileCountsByMimeTypeTable.getColumnModel().getColumn(1).setCellRenderer(rightAlignedRenderer);
|
||||
fileCountsByMimeTypeTable.getColumnModel().getColumn(0).setPreferredWidth(130);
|
||||
filesByCategoryTableModel = new FilesByCategoryTableModel(selectedDataSource);
|
||||
fileCountsByCategoryTable.setModel(filesByCategoryTableModel);
|
||||
fileCountsByCategoryTable.getColumnModel().getColumn(1).setCellRenderer(rightAlignedRenderer);
|
||||
fileCountsByCategoryTable.getColumnModel().getColumn(0).setPreferredWidth(130);
|
||||
updateArtifactCounts(selectedDataSource);
|
||||
this.repaint();
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper method to update the artifact specific counts by clearing the
|
||||
* table and adding counts for the artifacts which exist in the selected
|
||||
* data source.
|
||||
*
|
||||
* @param selectedDataSource the data source to display artifact counts for
|
||||
*/
|
||||
private void updateArtifactCounts(DataSource selectedDataSource) {
|
||||
((DefaultTableModel) artifactCountsTable.getModel()).setRowCount(0);
|
||||
if (selectedDataSource != null && artifactsByTypeCountsMap.get(selectedDataSource.getId()) != null) {
|
||||
Map<String, Long> artifactCounts = artifactsByTypeCountsMap.get(selectedDataSource.getId());
|
||||
for (String key : artifactCounts.keySet()) {
|
||||
((DefaultTableModel) artifactCountsTable.getModel()).addRow(new Object[]{key, artifactCounts.get(key)});
|
||||
}
|
||||
}
|
||||
artifactCountsTable.getColumnModel().getColumn(0).setPreferredWidth(230);
|
||||
artifactCountsTable.getColumnModel().getColumn(1).setCellRenderer(rightAlignedRenderer);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is called from within the constructor to initialize the form.
|
||||
* WARNING: Do NOT modify this code. The content of this method is always
|
||||
* regenerated by the Form Editor.
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
// <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
|
||||
private void initComponents() {
|
||||
|
||||
fileCountsByMimeTypeScrollPane = new javax.swing.JScrollPane();
|
||||
fileCountsByMimeTypeTable = new javax.swing.JTable();
|
||||
byMimeTypeLabel = new javax.swing.JLabel();
|
||||
fileCountsByCategoryScrollPane = new javax.swing.JScrollPane();
|
||||
fileCountsByCategoryTable = new javax.swing.JTable();
|
||||
byCategoryLabel = new javax.swing.JLabel();
|
||||
jLabel1 = new javax.swing.JLabel();
|
||||
artifactCountsScrollPane = new javax.swing.JScrollPane();
|
||||
artifactCountsTable = new javax.swing.JTable();
|
||||
|
||||
fileCountsByMimeTypeTable.setModel(filesByMimeTypeTableModel);
|
||||
fileCountsByMimeTypeScrollPane.setViewportView(fileCountsByMimeTypeTable);
|
||||
|
||||
org.openide.awt.Mnemonics.setLocalizedText(byMimeTypeLabel, org.openide.util.NbBundle.getMessage(DataSourceSummaryCountsPanel.class, "DataSourceSummaryCountsPanel.byMimeTypeLabel.text")); // NOI18N
|
||||
|
||||
fileCountsByCategoryTable.setModel(filesByCategoryTableModel);
|
||||
fileCountsByCategoryScrollPane.setViewportView(fileCountsByCategoryTable);
|
||||
|
||||
org.openide.awt.Mnemonics.setLocalizedText(byCategoryLabel, org.openide.util.NbBundle.getMessage(DataSourceSummaryCountsPanel.class, "DataSourceSummaryCountsPanel.byCategoryLabel.text")); // NOI18N
|
||||
|
||||
org.openide.awt.Mnemonics.setLocalizedText(jLabel1, org.openide.util.NbBundle.getMessage(DataSourceSummaryCountsPanel.class, "DataSourceSummaryCountsPanel.jLabel1.text")); // NOI18N
|
||||
|
||||
artifactCountsTable.setAutoCreateRowSorter(true);
|
||||
artifactCountsTable.setModel(new javax.swing.table.DefaultTableModel(
|
||||
new Object [][] {
|
||||
|
||||
},
|
||||
new String [] {
|
||||
"Result Type", "Count"
|
||||
}
|
||||
) {
|
||||
boolean[] canEdit = new boolean [] {
|
||||
false, false
|
||||
};
|
||||
|
||||
public boolean isCellEditable(int rowIndex, int columnIndex) {
|
||||
return canEdit [columnIndex];
|
||||
}
|
||||
});
|
||||
artifactCountsScrollPane.setViewportView(artifactCountsTable);
|
||||
|
||||
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
|
||||
this.setLayout(layout);
|
||||
layout.setHorizontalGroup(
|
||||
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGroup(layout.createSequentialGroup()
|
||||
.addContainerGap()
|
||||
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
|
||||
.addComponent(fileCountsByMimeTypeScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, 140, Short.MAX_VALUE)
|
||||
.addComponent(byMimeTypeLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
|
||||
.addGap(18, 18, 18)
|
||||
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addComponent(byCategoryLabel)
|
||||
.addComponent(fileCountsByCategoryScrollPane, javax.swing.GroupLayout.PREFERRED_SIZE, 82, javax.swing.GroupLayout.PREFERRED_SIZE))
|
||||
.addGap(18, 18, 18)
|
||||
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addComponent(jLabel1, javax.swing.GroupLayout.PREFERRED_SIZE, 79, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||
.addComponent(artifactCountsScrollPane, javax.swing.GroupLayout.PREFERRED_SIZE, 244, javax.swing.GroupLayout.PREFERRED_SIZE))
|
||||
.addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
|
||||
);
|
||||
|
||||
layout.linkSize(javax.swing.SwingConstants.HORIZONTAL, new java.awt.Component[] {fileCountsByCategoryScrollPane, fileCountsByMimeTypeScrollPane});
|
||||
|
||||
layout.setVerticalGroup(
|
||||
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGroup(layout.createSequentialGroup()
|
||||
.addContainerGap()
|
||||
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
|
||||
.addComponent(byMimeTypeLabel)
|
||||
.addComponent(byCategoryLabel)
|
||||
.addComponent(jLabel1))
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addComponent(artifactCountsScrollPane, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.PREFERRED_SIZE, 0, Short.MAX_VALUE)
|
||||
.addGroup(layout.createSequentialGroup()
|
||||
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addComponent(fileCountsByMimeTypeScrollPane, javax.swing.GroupLayout.PREFERRED_SIZE, 107, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||
.addComponent(fileCountsByCategoryScrollPane, javax.swing.GroupLayout.PREFERRED_SIZE, 86, javax.swing.GroupLayout.PREFERRED_SIZE))
|
||||
.addGap(0, 0, Short.MAX_VALUE)))
|
||||
.addContainerGap())
|
||||
);
|
||||
|
||||
layout.linkSize(javax.swing.SwingConstants.VERTICAL, new java.awt.Component[] {fileCountsByCategoryScrollPane, fileCountsByMimeTypeScrollPane});
|
||||
|
||||
}// </editor-fold>//GEN-END:initComponents
|
||||
|
||||
|
||||
// Variables declaration - do not modify//GEN-BEGIN:variables
|
||||
private javax.swing.JScrollPane artifactCountsScrollPane;
|
||||
private javax.swing.JTable artifactCountsTable;
|
||||
private javax.swing.JLabel byCategoryLabel;
|
||||
private javax.swing.JLabel byMimeTypeLabel;
|
||||
private javax.swing.JScrollPane fileCountsByCategoryScrollPane;
|
||||
private javax.swing.JTable fileCountsByCategoryTable;
|
||||
private javax.swing.JScrollPane fileCountsByMimeTypeScrollPane;
|
||||
private javax.swing.JTable fileCountsByMimeTypeTable;
|
||||
private javax.swing.JLabel jLabel1;
|
||||
// End of variables declaration//GEN-END:variables
|
||||
|
||||
/**
|
||||
* Table model for the files table model to display counts of specific file
|
||||
* types by mime type found in the currently selected data source.
|
||||
*/
|
||||
@Messages({"DataSourceSummaryCountsPanel.FilesByMimeTypeTableModel.type.header=File Type",
|
||||
"DataSourceSummaryCountsPanel.FilesByMimeTypeTableModel.count.header=Count"})
|
||||
private class FilesByMimeTypeTableModel extends AbstractTableModel {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
private final DataSource currentDataSource;
|
||||
private final List<String> columnHeaders = new ArrayList<>();
|
||||
private static final int IMAGES_ROW_INDEX = 0;
|
||||
private static final int VIDEOS_ROW_INDEX = 1;
|
||||
private static final int AUDIO_ROW_INDEX = 2;
|
||||
private static final int DOCUMENTS_ROW_INDEX = 3;
|
||||
private static final int EXECUTABLES_ROW_INDEX = 4;
|
||||
|
||||
/**
|
||||
* Create a FilesByMimeTypeTableModel for the speicified datasource.
|
||||
*
|
||||
* @param selectedDataSource the datasource which this
|
||||
* FilesByMimeTypeTablemodel will represent
|
||||
*/
|
||||
FilesByMimeTypeTableModel(DataSource selectedDataSource) {
|
||||
columnHeaders.add(Bundle.DataSourceSummaryCountsPanel_FilesByMimeTypeTableModel_type_header());
|
||||
columnHeaders.add(Bundle.DataSourceSummaryCountsPanel_FilesByMimeTypeTableModel_count_header());
|
||||
currentDataSource = selectedDataSource;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getRowCount() {
|
||||
//should be kept equal to the number of types we are displaying in the tables
|
||||
return 5;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getColumnCount() {
|
||||
return columnHeaders.size();
|
||||
}
|
||||
|
||||
@Messages({
|
||||
"DataSourceSummaryCountsPanel.FilesByMimeTypeTableModel.images.row=Images",
|
||||
"DataSourceSummaryCountsPanel.FilesByMimeTypeTableModel.videos.row=Videos",
|
||||
"DataSourceSummaryCountsPanel.FilesByMimeTypeTableModel.audio.row=Audio",
|
||||
"DataSourceSummaryCountsPanel.FilesByMimeTypeTableModel.documents.row=Documents",
|
||||
"DataSourceSummaryCountsPanel.FilesByMimeTypeTableModel.executables.row=Executables"
|
||||
})
|
||||
@Override
|
||||
public Object getValueAt(int rowIndex, int columnIndex) {
|
||||
if (columnIndex == 0) {
|
||||
switch (rowIndex) {
|
||||
case IMAGES_ROW_INDEX:
|
||||
return Bundle.DataSourceSummaryCountsPanel_FilesByMimeTypeTableModel_images_row();
|
||||
case VIDEOS_ROW_INDEX:
|
||||
return Bundle.DataSourceSummaryCountsPanel_FilesByMimeTypeTableModel_videos_row();
|
||||
case AUDIO_ROW_INDEX:
|
||||
return Bundle.DataSourceSummaryCountsPanel_FilesByMimeTypeTableModel_audio_row();
|
||||
case DOCUMENTS_ROW_INDEX:
|
||||
return Bundle.DataSourceSummaryCountsPanel_FilesByMimeTypeTableModel_documents_row();
|
||||
case EXECUTABLES_ROW_INDEX:
|
||||
return Bundle.DataSourceSummaryCountsPanel_FilesByMimeTypeTableModel_executables_row();
|
||||
default:
|
||||
break;
|
||||
}
|
||||
} else if (columnIndex == 1) {
|
||||
switch (rowIndex) {
|
||||
case 0:
|
||||
return DataSourceInfoUtilities.getCountOfFilesForMimeTypes(currentDataSource, FileTypeUtils.FileTypeCategory.IMAGE.getMediaTypes());
|
||||
case 1:
|
||||
return DataSourceInfoUtilities.getCountOfFilesForMimeTypes(currentDataSource, FileTypeUtils.FileTypeCategory.VIDEO.getMediaTypes());
|
||||
case 2:
|
||||
return DataSourceInfoUtilities.getCountOfFilesForMimeTypes(currentDataSource, FileTypeUtils.FileTypeCategory.AUDIO.getMediaTypes());
|
||||
case 3:
|
||||
return DataSourceInfoUtilities.getCountOfFilesForMimeTypes(currentDataSource, FileTypeUtils.FileTypeCategory.DOCUMENTS.getMediaTypes());
|
||||
case 4:
|
||||
return DataSourceInfoUtilities.getCountOfFilesForMimeTypes(currentDataSource, FileTypeUtils.FileTypeCategory.EXECUTABLE.getMediaTypes());
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getColumnName(int column) {
|
||||
return columnHeaders.get(column);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Table model for the files table model to display counts of specific file
|
||||
* types by category found in the currently selected data source.
|
||||
*/
|
||||
@Messages({"DataSourceSummaryCountsPanel.FilesByCategoryTableModel.type.header=File Type",
|
||||
"DataSourceSummaryCountsPanel.FilesByCategoryTableModel.count.header=Count"})
|
||||
private class FilesByCategoryTableModel extends AbstractTableModel {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
private final DataSource currentDataSource;
|
||||
private final List<String> columnHeaders = new ArrayList<>();
|
||||
private static final int ALL_FILES_ROW_INDEX = 0;
|
||||
private static final int ALLOCATED_FILES_ROW_INDEX = 1;
|
||||
private static final int UNALLOCATED_FILES_ROW_INDEX = 2;
|
||||
private static final int SLACK_FILES_ROW_INDEX = 3;
|
||||
private static final int DIRECTORIES_ROW_INDEX = 4;
|
||||
/**
|
||||
* Create a FilesByCategoryTableModel for the speicified datasource.
|
||||
*
|
||||
* @param selectedDataSource the datasource which this
|
||||
* FilesByCategoryTablemodel will represent
|
||||
*/
|
||||
FilesByCategoryTableModel(DataSource selectedDataSource) {
|
||||
columnHeaders.add(Bundle.DataSourceSummaryCountsPanel_FilesByCategoryTableModel_type_header());
|
||||
columnHeaders.add(Bundle.DataSourceSummaryCountsPanel_FilesByCategoryTableModel_count_header());
|
||||
currentDataSource = selectedDataSource;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getRowCount() {
|
||||
//should be kept equal to the number of types we are displaying in the tables
|
||||
return 5;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getColumnCount() {
|
||||
return columnHeaders.size();
|
||||
}
|
||||
|
||||
@Messages({
|
||||
"DataSourceSummaryCountsPanel.FilesByCategoryTableModel.all.row=All",
|
||||
"DataSourceSummaryCountsPanel.FilesByCategoryTableModel.allocated.row=Allocated",
|
||||
"DataSourceSummaryCountsPanel.FilesByCategoryTableModel.unallocated.row=Unallocated",
|
||||
"DataSourceSummaryCountsPanel.FilesByCategoryTableModel.slack.row=Slack",
|
||||
"DataSourceSummaryCountsPanel.FilesByCategoryTableModel.directory.row=Directory"
|
||||
})
|
||||
@Override
|
||||
public Object getValueAt(int rowIndex, int columnIndex) {
|
||||
if (columnIndex == 0) {
|
||||
switch (rowIndex) {
|
||||
case ALL_FILES_ROW_INDEX:
|
||||
return Bundle.DataSourceSummaryCountsPanel_FilesByCategoryTableModel_all_row();
|
||||
case ALLOCATED_FILES_ROW_INDEX:
|
||||
return Bundle.DataSourceSummaryCountsPanel_FilesByCategoryTableModel_allocated_row();
|
||||
case UNALLOCATED_FILES_ROW_INDEX:
|
||||
return Bundle.DataSourceSummaryCountsPanel_FilesByCategoryTableModel_unallocated_row();
|
||||
case SLACK_FILES_ROW_INDEX:
|
||||
return Bundle.DataSourceSummaryCountsPanel_FilesByCategoryTableModel_slack_row();
|
||||
case DIRECTORIES_ROW_INDEX:
|
||||
return Bundle.DataSourceSummaryCountsPanel_FilesByCategoryTableModel_directory_row();
|
||||
default:
|
||||
break;
|
||||
}
|
||||
} else if (columnIndex == 1 && currentDataSource != null) {
|
||||
switch (rowIndex) {
|
||||
case 0:
|
||||
return allFilesCountsMap.get(currentDataSource.getId()) == null ? 0 : allFilesCountsMap.get(currentDataSource.getId());
|
||||
case 1:
|
||||
//All files should be either allocated or unallocated as dir_flags only has two values so any file that isn't unallocated is allocated
|
||||
Long unallocatedFilesCount = unallocatedFilesCountsMap.get(currentDataSource.getId());
|
||||
Long allFilesCount = allFilesCountsMap.get(currentDataSource.getId());
|
||||
if (allFilesCount == null) {
|
||||
return 0;
|
||||
} else if (unallocatedFilesCount == null) {
|
||||
return allFilesCount;
|
||||
} else {
|
||||
return allFilesCount - unallocatedFilesCount;
|
||||
}
|
||||
case 2:
|
||||
return unallocatedFilesCountsMap.get(currentDataSource.getId()) == null ? 0 : unallocatedFilesCountsMap.get(currentDataSource.getId());
|
||||
case 3:
|
||||
return slackFilesCountsMap.get(currentDataSource.getId()) == null ? 0 : slackFilesCountsMap.get(currentDataSource.getId());
|
||||
case 4:
|
||||
return directoriesCountsMap.get(currentDataSource.getId()) == null ? 0 : directoriesCountsMap.get(currentDataSource.getId());
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getColumnName(int column) {
|
||||
return columnHeaders.get(column);
|
||||
}
|
||||
}
|
||||
}
|
@ -12,7 +12,6 @@ CentralRepoDbChoice.PostgreSQL.Text=Custom PostgreSQL
|
||||
CentralRepoDbChoice.PostgreSQL_Multiuser.Text=PostgreSQL using multi-user settings
|
||||
CentralRepoDbChoice.Sqlite.Text=SQLite
|
||||
CentralRepoDbManager.connectionErrorMsg.text=Failed to connect to central repository database.
|
||||
CentralRepositoryService.progressMsg.updatingDataSourcesTable=Checking for v1.2 data updates...
|
||||
CentralRepositoryService.progressMsg.updatingSchema=Updating schema...
|
||||
CentralRepositoryService.serviceName=Central Repository Service
|
||||
CorrelationAttributeInstance.invalidName.message=Invalid database table name. Name must start with a lowercase letter and can only contain lowercase letters, numbers, and '_'.
|
||||
|
@ -42,8 +42,8 @@ public class CentralRepositoryService implements AutopsyService {
|
||||
}
|
||||
|
||||
@NbBundle.Messages({
|
||||
"CentralRepositoryService.progressMsg.updatingSchema=Updating schema...",
|
||||
"CentralRepositoryService.progressMsg.updatingDataSourcesTable=Checking for v1.2 data updates...",})
|
||||
"CentralRepositoryService.progressMsg.updatingSchema=Updating schema..."
|
||||
})
|
||||
@Override
|
||||
public void openCaseResources(CaseContext context) throws AutopsyServiceException {
|
||||
if (!CentralRepository.isEnabled()) {
|
||||
@ -58,7 +58,6 @@ public class CentralRepositoryService implements AutopsyService {
|
||||
return;
|
||||
}
|
||||
|
||||
progress.progress(Bundle.CentralRepositoryService_progressMsg_updatingDataSourcesTable());
|
||||
dataUpgradeForVersion1dot2(context.getCase());
|
||||
}
|
||||
|
||||
|
@ -2,11 +2,16 @@ OpenIDE-Module-Name=CommandLineAutopsy
|
||||
OptionsCategory_Keywords_Command_Line_Ingest_Settings=Command Line Ingest Settings
|
||||
OptionsCategory_Keywords_General=Options
|
||||
OptionsCategory_Name_Command_Line_Ingest=Command Line Ingest
|
||||
CommandLinePanel.jLabel1.text=Ingest is running from command line
|
||||
CommandLinePanel.jLabel1.text=Running command line taks.
|
||||
CommandLineStartupWindow.title.text=Running in Command Line Mode
|
||||
CommandLineIngestSettingsPanel.bnEditIngestSettings.text=Configure Ingest
|
||||
CommandLineIngestSettingsPanel.bnEditIngestSettings.text=Configure
|
||||
CommandLineIngestSettingsPanel.bnEditReportSettings.actionCommand=Report Module Settings
|
||||
CommandLineIngestSettingsPanel.bnEditReportSettings.toolTipText=Report generation settings for the command line processing mode context.
|
||||
CommandLineIngestSettingsPanel.bnEditReportSettings.text=Configure Reporting
|
||||
CommandLineIngestSettingsPanel.jLabelDescription.text=<html>You can create cases, add data sources, run ingest modules, and generate reports from the command line.<br>This options panel allows you to configure the settings to use when running ingest modules and generating reports.<br>See the user documentation for details.</html>
|
||||
CommandLineIngestSettingsPanel.bnEditReportSettings.text=Configure
|
||||
CommandLineIngestSettingsPanel.bnEditIngestSettings.toolTipText=Ingest job settings for the command line processing mode context.
|
||||
CommandLineIngestSettingsPanel.ingestDescriptionTextPane.text=Configure the profiles to use from the command line.
|
||||
CommandLineIngestSettingsPanel.reportDescriptionTextPane.text=Report profiles define which report module and configuration to use.
|
||||
CommandLineIngestSettingsPanel.reportProfileLabel.text=Report Profile:
|
||||
CommandLineIngestSettingsPanel.ingestProfileLabel.text=Ingest Profile:
|
||||
CommandLineIngestSettingsPanel.bnEditReportSettings.AccessibleContext.accessibleName=Configure
|
||||
CommandLineIngestSettingsPanel.jTextPane1.text=Ingest profiles define which ingest filters, modules and configuration to use.
|
||||
|
@ -1,12 +1,22 @@
|
||||
CommandLineIngestSettingPanel_empty_report_name_mgs=Report profile name was empty, no profile created.
|
||||
CommandLineIngestSettingPanel_existing_report_name_mgs=Report profile name was already exists, no profile created.
|
||||
CommandListIngestSettingsPanel_Default_Report_DisplayName=Default
|
||||
CommandListIngestSettingsPanel_Make_Config=Make new profile...
|
||||
CommandListIngestSettingsPanel_Report_Name_Msg=Please supply a report profile name:
|
||||
OpenIDE-Module-Name=CommandLineAutopsy
|
||||
OptionsCategory_Keywords_Command_Line_Ingest_Settings=Command Line Ingest Settings
|
||||
OptionsCategory_Keywords_General=Options
|
||||
OptionsCategory_Name_Command_Line_Ingest=Command Line Ingest
|
||||
CommandLinePanel.jLabel1.text=Ingest is running from command line
|
||||
CommandLinePanel.jLabel1.text=Running command line taks.
|
||||
CommandLineStartupWindow.title.text=Running in Command Line Mode
|
||||
CommandLineIngestSettingsPanel.bnEditIngestSettings.text=Configure Ingest
|
||||
CommandLineIngestSettingsPanel.bnEditIngestSettings.text=Configure
|
||||
CommandLineIngestSettingsPanel.bnEditReportSettings.actionCommand=Report Module Settings
|
||||
CommandLineIngestSettingsPanel.bnEditReportSettings.toolTipText=Report generation settings for the command line processing mode context.
|
||||
CommandLineIngestSettingsPanel.bnEditReportSettings.text=Configure Reporting
|
||||
CommandLineIngestSettingsPanel.jLabelDescription.text=<html>You can create cases, add data sources, run ingest modules, and generate reports from the command line.<br>This options panel allows you to configure the settings to use when running ingest modules and generating reports.<br>See the user documentation for details.</html>
|
||||
CommandLineIngestSettingsPanel.bnEditReportSettings.text=Configure
|
||||
CommandLineIngestSettingsPanel.bnEditIngestSettings.toolTipText=Ingest job settings for the command line processing mode context.
|
||||
CommandLineIngestSettingsPanel.ingestDescriptionTextPane.text=Configure the profiles to use from the command line.
|
||||
CommandLineIngestSettingsPanel.reportDescriptionTextPane.text=Report profiles define which report module and configuration to use.
|
||||
CommandLineIngestSettingsPanel.reportProfileLabel.text=Report Profile:
|
||||
CommandLineIngestSettingsPanel.ingestProfileLabel.text=Ingest Profile:
|
||||
CommandLineIngestSettingsPanel.bnEditReportSettings.AccessibleContext.accessibleName=Configure
|
||||
CommandLineIngestSettingsPanel.jTextPane1.text=Ingest profiles define which ingest filters, modules and configuration to use.
|
||||
|
@ -1,7 +1,7 @@
|
||||
/*
|
||||
* Autopsy Forensic Browser
|
||||
*
|
||||
* Copyright 2019-2019 Basis Technology Corp.
|
||||
* Copyright 2019-2020 Basis Technology Corp.
|
||||
* Contact: carrier <at> sleuthkit <dot> org
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
@ -34,7 +34,8 @@ class CommandLineCommand {
|
||||
ADD_DATA_SOURCE,
|
||||
RUN_INGEST,
|
||||
LIST_ALL_DATA_SOURCES,
|
||||
GENERATE_REPORTS;
|
||||
GENERATE_REPORTS,
|
||||
OPEN_CASE_IN_UI;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -47,7 +48,8 @@ class CommandLineCommand {
|
||||
CASE_FOLDER_PATH,
|
||||
DATA_SOURCE_PATH,
|
||||
DATA_SOURCE_ID,
|
||||
INGEST_PROFILE_NAME;
|
||||
INGEST_PROFILE_NAME,
|
||||
REPORT_PROFILE_NAME;
|
||||
}
|
||||
|
||||
private final CommandType type;
|
||||
|
@ -1,7 +1,7 @@
|
||||
/*
|
||||
* Autopsy Forensic Browser
|
||||
*
|
||||
* Copyright 2019-2019 Basis Technology Corp.
|
||||
* Copyright 2019-2020 Basis Technology Corp.
|
||||
* Contact: carrier <at> sleuthkit <dot> org
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
@ -42,7 +42,6 @@ import org.sleuthkit.autopsy.casemodule.Case.CaseType;
|
||||
import org.sleuthkit.autopsy.casemodule.CaseActionException;
|
||||
import org.sleuthkit.autopsy.casemodule.CaseDetails;
|
||||
import org.sleuthkit.autopsy.casemodule.CaseMetadata;
|
||||
import static org.sleuthkit.autopsy.casemodule.CaseMetadata.getFileExtension;
|
||||
import org.sleuthkit.autopsy.core.RuntimeProperties;
|
||||
import org.sleuthkit.autopsy.corecomponentinterfaces.DataSourceProcessorCallback;
|
||||
import static org.sleuthkit.autopsy.corecomponentinterfaces.DataSourceProcessorCallback.DataSourceProcessorResult.CRITICAL_ERRORS;
|
||||
@ -74,7 +73,7 @@ import org.sleuthkit.datamodel.TskCoreException;
|
||||
* cause Autopsy to create a case, add a specified data source, run ingest on
|
||||
* that data source, list all data sources in the case, and generate reports.
|
||||
*/
|
||||
public class CommandLineIngestManager {
|
||||
public class CommandLineIngestManager extends CommandLineManager{
|
||||
|
||||
private static final Logger LOGGER = Logger.getLogger(CommandLineIngestManager.class.getName());
|
||||
private static final Set<IngestManager.IngestJobEvent> INGEST_JOB_EVENTS_OF_INTEREST = EnumSet.of(IngestManager.IngestJobEvent.CANCELLED, IngestManager.IngestJobEvent.COMPLETED);
|
||||
@ -184,7 +183,7 @@ public class CommandLineIngestManager {
|
||||
// open the case, if it hasn't been already opened by CREATE_CASE command
|
||||
if (caseForJob == null) {
|
||||
String caseDirPath = inputs.get(CommandLineCommand.InputType.CASE_FOLDER_PATH.name());
|
||||
openCase(caseDirPath);
|
||||
caseForJob = CommandLineIngestManager.this.openCase(caseDirPath);
|
||||
}
|
||||
|
||||
String dataSourcePath = inputs.get(CommandLineCommand.InputType.DATA_SOURCE_PATH.name());
|
||||
@ -210,7 +209,7 @@ public class CommandLineIngestManager {
|
||||
// open the case, if it hasn't been already opened by CREATE_CASE or ADD_DATA_SOURCE commands
|
||||
if (caseForJob == null) {
|
||||
String caseDirPath = inputs.get(CommandLineCommand.InputType.CASE_FOLDER_PATH.name());
|
||||
openCase(caseDirPath);
|
||||
caseForJob = CommandLineIngestManager.this.openCase(caseDirPath);
|
||||
}
|
||||
|
||||
// populate the AutoIngestDataSource structure, if that hasn't been done by ADD_DATA_SOURCE command
|
||||
@ -265,7 +264,7 @@ public class CommandLineIngestManager {
|
||||
// open the case, if it hasn't been already opened by previous command
|
||||
if (caseForJob == null) {
|
||||
String caseDirPath = inputs.get(CommandLineCommand.InputType.CASE_FOLDER_PATH.name());
|
||||
openCase(caseDirPath);
|
||||
caseForJob = CommandLineIngestManager.this.openCase(caseDirPath);
|
||||
}
|
||||
|
||||
String outputDirPath = getOutputDirPath(caseForJob);
|
||||
@ -288,12 +287,17 @@ public class CommandLineIngestManager {
|
||||
// open the case, if it hasn't been already opened by previous command
|
||||
if (caseForJob == null) {
|
||||
String caseDirPath = inputs.get(CommandLineCommand.InputType.CASE_FOLDER_PATH.name());
|
||||
openCase(caseDirPath);
|
||||
caseForJob = CommandLineIngestManager.this.openCase(caseDirPath);
|
||||
}
|
||||
// generate reports
|
||||
String reportName = inputs.get(CommandLineCommand.InputType.REPORT_PROFILE_NAME.name());
|
||||
if (reportName == null) {
|
||||
reportName = CommandLineIngestSettingsPanel.getDefaultReportingConfigName();
|
||||
}
|
||||
|
||||
// generate reports
|
||||
ReportProgressIndicator progressIndicator = new ReportProgressIndicator(new LoggingProgressIndicator());
|
||||
ReportGenerator generator = new ReportGenerator(CommandLineIngestSettingsPanel.getReportingConfigName(), progressIndicator);
|
||||
ReportGenerator generator = new ReportGenerator(reportName, progressIndicator);
|
||||
generator.generateReports();
|
||||
} catch (CaseActionException ex) {
|
||||
String caseDirPath = command.getInputs().get(CommandLineCommand.InputType.CASE_FOLDER_PATH.name());
|
||||
@ -369,55 +373,6 @@ public class CommandLineIngestManager {
|
||||
LOGGER.log(Level.INFO, "Opened case {0}", caseForJob.getName());
|
||||
}
|
||||
|
||||
/**
|
||||
* Opens existing case.
|
||||
*
|
||||
* @param caseFolderPath full path to case directory
|
||||
*
|
||||
* @throws CaseActionException
|
||||
*/
|
||||
private void openCase(String caseFolderPath) throws CaseActionException {
|
||||
|
||||
LOGGER.log(Level.INFO, "Opening case in directory {0}", caseFolderPath);
|
||||
|
||||
String metadataFilePath = findAutFile(caseFolderPath);
|
||||
Case.openAsCurrentCase(metadataFilePath);
|
||||
|
||||
caseForJob = Case.getCurrentCase();
|
||||
LOGGER.log(Level.INFO, "Opened case {0}", caseForJob.getName());
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds the path to the .aut file for the specified case directory.
|
||||
*
|
||||
* @param caseDirectory the directory to check for a .aut file
|
||||
*
|
||||
* @return the path to the first .aut file found in the directory
|
||||
*
|
||||
* @throws CaseActionException if there was an issue finding a .aut file
|
||||
*/
|
||||
private String findAutFile(String caseDirectory) throws CaseActionException {
|
||||
File caseFolder = Paths.get(caseDirectory).toFile();
|
||||
if (caseFolder.exists()) {
|
||||
/*
|
||||
* Search for '*.aut' files.
|
||||
*/
|
||||
File[] fileArray = caseFolder.listFiles();
|
||||
if (fileArray == null) {
|
||||
throw new CaseActionException("No files found in case directory");
|
||||
}
|
||||
String autFilePath = null;
|
||||
for (File file : fileArray) {
|
||||
String name = file.getName().toLowerCase();
|
||||
if (autFilePath == null && name.endsWith(getFileExtension())) {
|
||||
return file.getAbsolutePath();
|
||||
}
|
||||
}
|
||||
throw new CaseActionException("No .aut files found in case directory");
|
||||
}
|
||||
throw new CaseActionException("Case directory was not found");
|
||||
}
|
||||
|
||||
/**
|
||||
* Passes the data source for the current job through a data source
|
||||
* processor that adds it to the case database.
|
||||
@ -425,17 +380,11 @@ public class CommandLineIngestManager {
|
||||
* @param caseForJob The case
|
||||
* @param dataSource The data source.
|
||||
*
|
||||
* @throws
|
||||
* AutoIngestDataSourceProcessor.AutoIngestDataSourceProcessorExceptioif
|
||||
* there
|
||||
* was
|
||||
* a
|
||||
* DSP
|
||||
* processing
|
||||
* error
|
||||
* @throws AutoIngestDataSourceProcessorException if there was a DSP
|
||||
* processing error.
|
||||
*
|
||||
* @throws ead running the job processing task is interrupted while
|
||||
* blocked, i.e., if auto ingest is shutting down.
|
||||
* @throws InterruptedException running the job processing task while
|
||||
* blocking, i.e., if auto ingest is shutting down.
|
||||
*/
|
||||
private void runDataSourceProcessor(Case caseForJob, AutoIngestDataSource dataSource) throws InterruptedException, AutoIngestDataSourceProcessor.AutoIngestDataSourceProcessorException {
|
||||
|
||||
|
@ -16,32 +16,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,1,44,0,0,1,-112"/>
|
||||
</AuxValues>
|
||||
|
||||
<Layout>
|
||||
<DimensionLayout dim="0">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Component id="nodeScrollPane" alignment="1" max="32767" attributes="0"/>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
<DimensionLayout dim="1">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Component id="nodeScrollPane" alignment="0" pref="421" max="32767" attributes="0"/>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
</Layout>
|
||||
<SubComponents>
|
||||
<Container class="javax.swing.JScrollPane" name="nodeScrollPane">
|
||||
<Properties>
|
||||
<Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||
<Dimension value="[0, 0]"/>
|
||||
</Property>
|
||||
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||
<Dimension value="[803, 553]"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
|
||||
<Layout class="org.netbeans.modules.form.compat2.layouts.support.JScrollPaneSupportLayout"/>
|
||||
<Layout class="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout"/>
|
||||
<SubComponents>
|
||||
<Container class="javax.swing.JPanel" name="nodePanel">
|
||||
<Properties>
|
||||
@ -52,35 +30,13 @@
|
||||
<Dimension value="[801, 551]"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<Constraints>
|
||||
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription">
|
||||
<BorderConstraints direction="Center"/>
|
||||
</Constraint>
|
||||
</Constraints>
|
||||
|
||||
<Layout>
|
||||
<DimensionLayout dim="0">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Group type="102" attributes="0">
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Component id="bnEditIngestSettings" alignment="0" min="-2" pref="155" max="-2" attributes="0"/>
|
||||
<Component id="jLabelDescription" alignment="0" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="bnEditReportSettings" alignment="0" min="-2" pref="155" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<EmptySpace pref="-34" max="32767" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
<DimensionLayout dim="1">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Group type="102" alignment="0" attributes="0">
|
||||
<EmptySpace min="-2" pref="27" max="-2" attributes="0"/>
|
||||
<Component id="jLabelDescription" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace type="unrelated" max="-2" attributes="0"/>
|
||||
<Component id="bnEditIngestSettings" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="bnEditReportSettings" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace pref="381" max="32767" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
</Layout>
|
||||
<Layout class="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout"/>
|
||||
<SubComponents>
|
||||
<Component class="javax.swing.JButton" name="bnEditIngestSettings">
|
||||
<Properties>
|
||||
@ -97,13 +53,11 @@
|
||||
<Events>
|
||||
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="bnEditIngestSettingsActionPerformed"/>
|
||||
</Events>
|
||||
</Component>
|
||||
<Component class="javax.swing.JLabel" name="jLabelDescription">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/commandlineingest/Bundle.properties" key="CommandLineIngestSettingsPanel.jLabelDescription.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="2" gridY="2" gridWidth="1" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="9" insetsBottom="0" insetsRight="0" anchor="18" weightX="0.0" weightY="0.0"/>
|
||||
</Constraint>
|
||||
</Constraints>
|
||||
</Component>
|
||||
<Component class="javax.swing.JButton" name="bnEditReportSettings">
|
||||
<Properties>
|
||||
@ -117,13 +71,153 @@
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/commandlineingest/Bundle.properties" key="CommandLineIngestSettingsPanel.bnEditReportSettings.actionCommand" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<AccessibilityProperties>
|
||||
<Property name="AccessibleContext.accessibleName" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/commandlineingest/Bundle.properties" key="CommandLineIngestSettingsPanel.bnEditReportSettings.AccessibleContext.accessibleName" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
</AccessibilityProperties>
|
||||
<Events>
|
||||
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="bnEditReportSettingsActionPerformed"/>
|
||||
</Events>
|
||||
<Constraints>
|
||||
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
|
||||
<GridBagConstraints gridX="2" gridY="4" gridWidth="1" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="9" insetsBottom="0" insetsRight="0" anchor="18" weightX="0.0" weightY="0.0"/>
|
||||
</Constraint>
|
||||
</Constraints>
|
||||
</Component>
|
||||
<Component class="javax.swing.JTextPane" name="ingestDescriptionTextPane">
|
||||
<Properties>
|
||||
<Property name="editable" type="boolean" value="false"/>
|
||||
<Property name="background" type="java.awt.Color" editor="org.netbeans.beaninfo.editors.ColorEditor">
|
||||
<Color blue="f0" green="f0" id="Label.background" palette="3" red="f0" type="palette"/>
|
||||
</Property>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/commandlineingest/Bundle.properties" key="CommandLineIngestSettingsPanel.ingestDescriptionTextPane.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<AuxValues>
|
||||
<AuxValue name="JavaCodeGenerator_VariableLocal" type="java.lang.Boolean" value="true"/>
|
||||
<AuxValue name="JavaCodeGenerator_VariableModifier" type="java.lang.Integer" value="0"/>
|
||||
</AuxValues>
|
||||
<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="3" gridHeight="1" fill="2" ipadX="0" ipadY="0" insetsTop="5" insetsLeft="5" insetsBottom="10" insetsRight="5" anchor="18" weightX="1.0" weightY="0.0"/>
|
||||
</Constraint>
|
||||
</Constraints>
|
||||
</Component>
|
||||
<Component class="javax.swing.JLabel" name="ingestProfileLabel">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/commandlineingest/Bundle.properties" key="CommandLineIngestSettingsPanel.ingestProfileLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<AuxValues>
|
||||
<AuxValue name="JavaCodeGenerator_VariableLocal" type="java.lang.Boolean" value="true"/>
|
||||
<AuxValue name="JavaCodeGenerator_VariableModifier" type="java.lang.Integer" value="0"/>
|
||||
</AuxValues>
|
||||
<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="1" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="25" insetsBottom="0" insetsRight="0" anchor="17" weightX="0.0" weightY="0.0"/>
|
||||
</Constraint>
|
||||
</Constraints>
|
||||
</Component>
|
||||
<Component class="javax.swing.JComboBox" name="ingestProfileCB">
|
||||
<Properties>
|
||||
<Property name="model" type="javax.swing.ComboBoxModel" editor="org.netbeans.modules.form.editors2.ComboBoxModelEditor">
|
||||
<StringArray count="1">
|
||||
<StringItem index="0" value="Default"/>
|
||||
</StringArray>
|
||||
</Property>
|
||||
<Property name="enabled" type="boolean" value="false"/>
|
||||
</Properties>
|
||||
<AuxValues>
|
||||
<AuxValue name="JavaCodeGenerator_TypeParameters" type="java.lang.String" value="<String>"/>
|
||||
</AuxValues>
|
||||
<Constraints>
|
||||
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
|
||||
<GridBagConstraints gridX="1" gridY="2" gridWidth="1" gridHeight="1" fill="2" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="5" insetsBottom="0" insetsRight="0" anchor="10" weightX="0.0" weightY="0.0"/>
|
||||
</Constraint>
|
||||
</Constraints>
|
||||
</Component>
|
||||
<Component class="javax.swing.JTextPane" name="reportDescriptionTextPane">
|
||||
<Properties>
|
||||
<Property name="editable" type="boolean" value="false"/>
|
||||
<Property name="background" type="java.awt.Color" editor="org.netbeans.beaninfo.editors.ColorEditor">
|
||||
<Color blue="f0" green="f0" id="Label.background" palette="3" red="f0" type="palette"/>
|
||||
</Property>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/commandlineingest/Bundle.properties" key="CommandLineIngestSettingsPanel.reportDescriptionTextPane.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<AuxValues>
|
||||
<AuxValue name="JavaCodeGenerator_VariableLocal" type="java.lang.Boolean" value="true"/>
|
||||
<AuxValue name="JavaCodeGenerator_VariableModifier" type="java.lang.Integer" value="0"/>
|
||||
</AuxValues>
|
||||
<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="3" gridHeight="1" fill="2" ipadX="0" ipadY="0" insetsTop="15" insetsLeft="5" insetsBottom="5" insetsRight="5" anchor="10" weightX="0.0" weightY="0.0"/>
|
||||
</Constraint>
|
||||
</Constraints>
|
||||
</Component>
|
||||
<Component class="javax.swing.JLabel" name="reportProfileLabel">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/commandlineingest/Bundle.properties" key="CommandLineIngestSettingsPanel.reportProfileLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<AuxValues>
|
||||
<AuxValue name="JavaCodeGenerator_VariableLocal" type="java.lang.Boolean" value="true"/>
|
||||
<AuxValue name="JavaCodeGenerator_VariableModifier" type="java.lang.Integer" value="0"/>
|
||||
</AuxValues>
|
||||
<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="0" insetsLeft="25" insetsBottom="0" insetsRight="0" anchor="17" weightX="0.0" weightY="0.0"/>
|
||||
</Constraint>
|
||||
</Constraints>
|
||||
</Component>
|
||||
<Component class="javax.swing.JComboBox" name="reportProfileCB">
|
||||
<Properties>
|
||||
<Property name="model" type="javax.swing.ComboBoxModel" editor="org.netbeans.modules.form.editors2.ComboBoxModelEditor">
|
||||
<StringArray count="0"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<AuxValues>
|
||||
<AuxValue name="JavaCodeGenerator_TypeParameters" type="java.lang.String" value="<String>"/>
|
||||
</AuxValues>
|
||||
<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="2" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="5" insetsBottom="0" insetsRight="0" anchor="10" weightX="0.0" weightY="0.0"/>
|
||||
</Constraint>
|
||||
</Constraints>
|
||||
</Component>
|
||||
<Component class="javax.swing.Box$Filler" name="bottomFiller">
|
||||
<AuxValues>
|
||||
<AuxValue name="JavaCodeGenerator_VariableLocal" type="java.lang.Boolean" value="true"/>
|
||||
<AuxValue name="JavaCodeGenerator_VariableModifier" type="java.lang.Integer" value="0"/>
|
||||
</AuxValues>
|
||||
<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="1" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="0" insetsBottom="0" insetsRight="0" anchor="10" weightX="0.0" weightY="1.0"/>
|
||||
</Constraint>
|
||||
</Constraints>
|
||||
</Component>
|
||||
<Component class="javax.swing.JTextPane" name="jTextPane1">
|
||||
<Properties>
|
||||
<Property name="editable" type="boolean" value="false"/>
|
||||
<Property name="background" type="java.awt.Color" editor="org.netbeans.beaninfo.editors.ColorEditor">
|
||||
<Color blue="f0" green="f0" id="Label.background" palette="3" red="f0" type="palette"/>
|
||||
</Property>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/commandlineingest/Bundle.properties" key="CommandLineIngestSettingsPanel.jTextPane1.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="1" gridWidth="3" gridHeight="1" fill="2" ipadX="0" ipadY="0" insetsTop="10" insetsLeft="5" insetsBottom="5" insetsRight="5" anchor="17" weightX="0.0" weightY="0.0"/>
|
||||
</Constraint>
|
||||
</Constraints>
|
||||
</Component>
|
||||
</SubComponents>
|
||||
</Container>
|
||||
</SubComponents>
|
||||
</Container>
|
||||
</SubComponents>
|
||||
</Form>
|
||||
|
@ -1,7 +1,7 @@
|
||||
/*
|
||||
* Autopsy Forensic Browser
|
||||
*
|
||||
* Copyright 2019-2019 Basis Technology Corp.
|
||||
* Copyright 2019-2020 Basis Technology Corp.
|
||||
* Contact: carrier <at> sleuthkit <dot> org
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
@ -21,12 +21,16 @@ package org.sleuthkit.autopsy.commandlineingest;
|
||||
import java.awt.BorderLayout;
|
||||
import java.awt.Cursor;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import javax.swing.DefaultComboBoxModel;
|
||||
import javax.swing.JOptionPane;
|
||||
import org.openide.util.NbBundle.Messages;
|
||||
import org.sleuthkit.autopsy.ingest.IngestJobSettings;
|
||||
import org.sleuthkit.autopsy.ingest.IngestJobSettingsPanel;
|
||||
import org.openide.windows.WindowManager;
|
||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||
import static org.sleuthkit.autopsy.report.infrastructure.ReportWizardAction.doReportWizard;
|
||||
import org.sleuthkit.autopsy.report.infrastructure.ReportWizardAction;
|
||||
|
||||
/**
|
||||
* Configuration panel for auto ingest settings.
|
||||
@ -48,12 +52,13 @@ public class CommandLineIngestSettingsPanel extends javax.swing.JPanel {
|
||||
*/
|
||||
public CommandLineIngestSettingsPanel(CommandLineIngestSettingsPanelController theController) {
|
||||
initComponents();
|
||||
setupReportList();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the REPORTING_CONFIGURATION_NAME
|
||||
*/
|
||||
public static String getReportingConfigName() {
|
||||
public static String getDefaultReportingConfigName() {
|
||||
return REPORTING_CONFIGURATION_NAME;
|
||||
}
|
||||
|
||||
@ -87,6 +92,58 @@ public class CommandLineIngestSettingsPanel extends javax.swing.JPanel {
|
||||
}
|
||||
}
|
||||
|
||||
@Messages({
|
||||
"CommandListIngestSettingsPanel_Default_Report_DisplayName=Default",
|
||||
"CommandListIngestSettingsPanel_Make_Config=Make new profile..."
|
||||
})
|
||||
/**
|
||||
* Initializes the report profile list combo box.
|
||||
*/
|
||||
private void setupReportList() {
|
||||
Set<String> configNames = ReportWizardAction.getReportConfigNames();
|
||||
configNames.remove(REPORTING_CONFIGURATION_NAME);
|
||||
|
||||
DefaultComboBoxModel<String> model = new DefaultComboBoxModel<>();
|
||||
model.addElement(Bundle.CommandListIngestSettingsPanel_Default_Report_DisplayName());
|
||||
for (String name : configNames) {
|
||||
model.addElement(name);
|
||||
}
|
||||
|
||||
model.addElement(Bundle.CommandListIngestSettingsPanel_Make_Config());
|
||||
|
||||
reportProfileCB.setModel(model);
|
||||
reportProfileCB.setSelectedIndex(0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks to see if there is currently a profile define with the given name.
|
||||
*
|
||||
* @param name Profile name to check.
|
||||
*
|
||||
* @return True if there is a report with the given name.
|
||||
*/
|
||||
private boolean doesReportProfileNameExist(String name) {
|
||||
Set<String> configNames = ReportWizardAction.getReportConfigNames();
|
||||
return configNames.contains(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the currently selected report profile name from the cb. For backwards
|
||||
* compatibility if Default is selected, the existing default
|
||||
* profile name of CommandLineIngest will be returned.
|
||||
*
|
||||
* @return The selected profile name.
|
||||
*/
|
||||
private String getReportName() {
|
||||
String reportName = (String) reportProfileCB.getSelectedItem();
|
||||
|
||||
if (reportName.equals(Bundle.CommandListIngestSettingsPanel_Default_Report_DisplayName())) {
|
||||
reportName = REPORTING_CONFIGURATION_NAME;
|
||||
}
|
||||
|
||||
return reportName;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is called from within the constructor to initialize the form.
|
||||
* WARNING: Do NOT modify this code. The content of this method is always
|
||||
@ -95,20 +152,26 @@ public class CommandLineIngestSettingsPanel extends javax.swing.JPanel {
|
||||
@SuppressWarnings("unchecked")
|
||||
// <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
|
||||
private void initComponents() {
|
||||
java.awt.GridBagConstraints gridBagConstraints;
|
||||
|
||||
nodeScrollPane = new javax.swing.JScrollPane();
|
||||
nodePanel = new javax.swing.JPanel();
|
||||
bnEditIngestSettings = new javax.swing.JButton();
|
||||
jLabelDescription = new javax.swing.JLabel();
|
||||
bnEditReportSettings = new javax.swing.JButton();
|
||||
javax.swing.JTextPane ingestDescriptionTextPane = new javax.swing.JTextPane();
|
||||
javax.swing.JLabel ingestProfileLabel = new javax.swing.JLabel();
|
||||
ingestProfileCB = new javax.swing.JComboBox<>();
|
||||
javax.swing.JTextPane reportDescriptionTextPane = new javax.swing.JTextPane();
|
||||
javax.swing.JLabel reportProfileLabel = new javax.swing.JLabel();
|
||||
reportProfileCB = new javax.swing.JComboBox<>();
|
||||
javax.swing.Box.Filler bottomFiller = new javax.swing.Box.Filler(new java.awt.Dimension(0, 0), new java.awt.Dimension(0, 0), new java.awt.Dimension(0, 0));
|
||||
jTextPane1 = new javax.swing.JTextPane();
|
||||
|
||||
setPreferredSize(new java.awt.Dimension(810, 422));
|
||||
|
||||
nodeScrollPane.setMinimumSize(new java.awt.Dimension(0, 0));
|
||||
nodeScrollPane.setPreferredSize(new java.awt.Dimension(803, 553));
|
||||
setLayout(new java.awt.BorderLayout());
|
||||
|
||||
nodePanel.setMinimumSize(new java.awt.Dimension(100, 100));
|
||||
nodePanel.setPreferredSize(new java.awt.Dimension(801, 551));
|
||||
nodePanel.setLayout(new java.awt.GridBagLayout());
|
||||
|
||||
org.openide.awt.Mnemonics.setLocalizedText(bnEditIngestSettings, org.openide.util.NbBundle.getMessage(CommandLineIngestSettingsPanel.class, "CommandLineIngestSettingsPanel.bnEditIngestSettings.text")); // NOI18N
|
||||
bnEditIngestSettings.setToolTipText(org.openide.util.NbBundle.getMessage(CommandLineIngestSettingsPanel.class, "CommandLineIngestSettingsPanel.bnEditIngestSettings.toolTipText")); // NOI18N
|
||||
@ -118,8 +181,12 @@ public class CommandLineIngestSettingsPanel extends javax.swing.JPanel {
|
||||
bnEditIngestSettingsActionPerformed(evt);
|
||||
}
|
||||
});
|
||||
|
||||
org.openide.awt.Mnemonics.setLocalizedText(jLabelDescription, org.openide.util.NbBundle.getMessage(CommandLineIngestSettingsPanel.class, "CommandLineIngestSettingsPanel.jLabelDescription.text")); // NOI18N
|
||||
gridBagConstraints = new java.awt.GridBagConstraints();
|
||||
gridBagConstraints.gridx = 2;
|
||||
gridBagConstraints.gridy = 2;
|
||||
gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
|
||||
gridBagConstraints.insets = new java.awt.Insets(0, 9, 0, 0);
|
||||
nodePanel.add(bnEditIngestSettings, gridBagConstraints);
|
||||
|
||||
org.openide.awt.Mnemonics.setLocalizedText(bnEditReportSettings, org.openide.util.NbBundle.getMessage(CommandLineIngestSettingsPanel.class, "CommandLineIngestSettingsPanel.bnEditReportSettings.text")); // NOI18N
|
||||
bnEditReportSettings.setToolTipText(org.openide.util.NbBundle.getMessage(CommandLineIngestSettingsPanel.class, "CommandLineIngestSettingsPanel.bnEditReportSettings.toolTipText")); // NOI18N
|
||||
@ -129,48 +196,120 @@ public class CommandLineIngestSettingsPanel extends javax.swing.JPanel {
|
||||
bnEditReportSettingsActionPerformed(evt);
|
||||
}
|
||||
});
|
||||
gridBagConstraints = new java.awt.GridBagConstraints();
|
||||
gridBagConstraints.gridx = 2;
|
||||
gridBagConstraints.gridy = 4;
|
||||
gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
|
||||
gridBagConstraints.insets = new java.awt.Insets(0, 9, 0, 0);
|
||||
nodePanel.add(bnEditReportSettings, gridBagConstraints);
|
||||
bnEditReportSettings.getAccessibleContext().setAccessibleName(org.openide.util.NbBundle.getMessage(CommandLineIngestSettingsPanel.class, "CommandLineIngestSettingsPanel.bnEditReportSettings.AccessibleContext.accessibleName")); // NOI18N
|
||||
|
||||
javax.swing.GroupLayout nodePanelLayout = new javax.swing.GroupLayout(nodePanel);
|
||||
nodePanel.setLayout(nodePanelLayout);
|
||||
nodePanelLayout.setHorizontalGroup(
|
||||
nodePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGroup(nodePanelLayout.createSequentialGroup()
|
||||
.addContainerGap()
|
||||
.addGroup(nodePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addComponent(bnEditIngestSettings, javax.swing.GroupLayout.PREFERRED_SIZE, 155, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||
.addComponent(jLabelDescription, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||
.addComponent(bnEditReportSettings, javax.swing.GroupLayout.PREFERRED_SIZE, 155, javax.swing.GroupLayout.PREFERRED_SIZE))
|
||||
.addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
|
||||
);
|
||||
nodePanelLayout.setVerticalGroup(
|
||||
nodePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGroup(nodePanelLayout.createSequentialGroup()
|
||||
.addGap(27, 27, 27)
|
||||
.addComponent(jLabelDescription, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
|
||||
.addComponent(bnEditIngestSettings)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(bnEditReportSettings)
|
||||
.addContainerGap(381, Short.MAX_VALUE))
|
||||
);
|
||||
ingestDescriptionTextPane.setEditable(false);
|
||||
ingestDescriptionTextPane.setBackground(javax.swing.UIManager.getDefaults().getColor("Label.background"));
|
||||
ingestDescriptionTextPane.setText(org.openide.util.NbBundle.getMessage(CommandLineIngestSettingsPanel.class, "CommandLineIngestSettingsPanel.ingestDescriptionTextPane.text")); // NOI18N
|
||||
gridBagConstraints = new java.awt.GridBagConstraints();
|
||||
gridBagConstraints.gridx = 0;
|
||||
gridBagConstraints.gridy = 0;
|
||||
gridBagConstraints.gridwidth = 3;
|
||||
gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
|
||||
gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
|
||||
gridBagConstraints.weightx = 1.0;
|
||||
gridBagConstraints.insets = new java.awt.Insets(5, 5, 10, 5);
|
||||
nodePanel.add(ingestDescriptionTextPane, gridBagConstraints);
|
||||
|
||||
nodeScrollPane.setViewportView(nodePanel);
|
||||
org.openide.awt.Mnemonics.setLocalizedText(ingestProfileLabel, org.openide.util.NbBundle.getMessage(CommandLineIngestSettingsPanel.class, "CommandLineIngestSettingsPanel.ingestProfileLabel.text")); // NOI18N
|
||||
gridBagConstraints = new java.awt.GridBagConstraints();
|
||||
gridBagConstraints.gridx = 0;
|
||||
gridBagConstraints.gridy = 2;
|
||||
gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
|
||||
gridBagConstraints.insets = new java.awt.Insets(0, 25, 0, 0);
|
||||
nodePanel.add(ingestProfileLabel, gridBagConstraints);
|
||||
|
||||
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
|
||||
this.setLayout(layout);
|
||||
layout.setHorizontalGroup(
|
||||
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addComponent(nodeScrollPane, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
||||
);
|
||||
layout.setVerticalGroup(
|
||||
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addComponent(nodeScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, 421, Short.MAX_VALUE)
|
||||
);
|
||||
ingestProfileCB.setModel(new javax.swing.DefaultComboBoxModel<>(new String[] { "Default" }));
|
||||
ingestProfileCB.setEnabled(false);
|
||||
gridBagConstraints = new java.awt.GridBagConstraints();
|
||||
gridBagConstraints.gridx = 1;
|
||||
gridBagConstraints.gridy = 2;
|
||||
gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
|
||||
gridBagConstraints.insets = new java.awt.Insets(0, 5, 0, 0);
|
||||
nodePanel.add(ingestProfileCB, gridBagConstraints);
|
||||
|
||||
reportDescriptionTextPane.setEditable(false);
|
||||
reportDescriptionTextPane.setBackground(javax.swing.UIManager.getDefaults().getColor("Label.background"));
|
||||
reportDescriptionTextPane.setText(org.openide.util.NbBundle.getMessage(CommandLineIngestSettingsPanel.class, "CommandLineIngestSettingsPanel.reportDescriptionTextPane.text")); // NOI18N
|
||||
gridBagConstraints = new java.awt.GridBagConstraints();
|
||||
gridBagConstraints.gridx = 0;
|
||||
gridBagConstraints.gridy = 3;
|
||||
gridBagConstraints.gridwidth = 3;
|
||||
gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
|
||||
gridBagConstraints.insets = new java.awt.Insets(15, 5, 5, 5);
|
||||
nodePanel.add(reportDescriptionTextPane, gridBagConstraints);
|
||||
|
||||
org.openide.awt.Mnemonics.setLocalizedText(reportProfileLabel, org.openide.util.NbBundle.getMessage(CommandLineIngestSettingsPanel.class, "CommandLineIngestSettingsPanel.reportProfileLabel.text")); // NOI18N
|
||||
gridBagConstraints = new java.awt.GridBagConstraints();
|
||||
gridBagConstraints.gridx = 0;
|
||||
gridBagConstraints.gridy = 4;
|
||||
gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
|
||||
gridBagConstraints.insets = new java.awt.Insets(0, 25, 0, 0);
|
||||
nodePanel.add(reportProfileLabel, gridBagConstraints);
|
||||
|
||||
gridBagConstraints = new java.awt.GridBagConstraints();
|
||||
gridBagConstraints.gridx = 1;
|
||||
gridBagConstraints.gridy = 4;
|
||||
gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
|
||||
gridBagConstraints.insets = new java.awt.Insets(0, 5, 0, 0);
|
||||
nodePanel.add(reportProfileCB, gridBagConstraints);
|
||||
gridBagConstraints = new java.awt.GridBagConstraints();
|
||||
gridBagConstraints.gridx = 0;
|
||||
gridBagConstraints.gridy = 5;
|
||||
gridBagConstraints.weighty = 1.0;
|
||||
nodePanel.add(bottomFiller, gridBagConstraints);
|
||||
|
||||
jTextPane1.setEditable(false);
|
||||
jTextPane1.setBackground(javax.swing.UIManager.getDefaults().getColor("Label.background"));
|
||||
jTextPane1.setText(org.openide.util.NbBundle.getMessage(CommandLineIngestSettingsPanel.class, "CommandLineIngestSettingsPanel.jTextPane1.text")); // NOI18N
|
||||
gridBagConstraints = new java.awt.GridBagConstraints();
|
||||
gridBagConstraints.gridx = 0;
|
||||
gridBagConstraints.gridy = 1;
|
||||
gridBagConstraints.gridwidth = 3;
|
||||
gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
|
||||
gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
|
||||
gridBagConstraints.insets = new java.awt.Insets(10, 5, 5, 5);
|
||||
nodePanel.add(jTextPane1, gridBagConstraints);
|
||||
|
||||
add(nodePanel, java.awt.BorderLayout.CENTER);
|
||||
}// </editor-fold>//GEN-END:initComponents
|
||||
|
||||
@Messages({
|
||||
"CommandListIngestSettingsPanel_Report_Name_Msg=Please supply a report profile name:",
|
||||
"CommandLineIngestSettingPanel_empty_report_name_mgs=Report profile name was empty, no profile created.",
|
||||
"CommandLineIngestSettingPanel_existing_report_name_mgs=Report profile name was already exists, no profile created."
|
||||
})
|
||||
private void bnEditReportSettingsActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_bnEditReportSettingsActionPerformed
|
||||
String reportName = getReportName();
|
||||
if (reportName.equals(Bundle.CommandListIngestSettingsPanel_Make_Config())) {
|
||||
reportName = JOptionPane.showInputDialog(this, Bundle.CommandListIngestSettingsPanel_Report_Name_Msg());
|
||||
|
||||
// User hit cancel
|
||||
if (reportName == null) {
|
||||
return;
|
||||
} else if (reportName.isEmpty()) {
|
||||
JOptionPane.showMessageDialog(WindowManager.getDefault().getMainWindow(), Bundle.CommandLineIngestSettingPanel_empty_report_name_mgs());
|
||||
return;
|
||||
} else if (doesReportProfileNameExist(reportName)) {
|
||||
JOptionPane.showMessageDialog(WindowManager.getDefault().getMainWindow(), Bundle.CommandLineIngestSettingPanel_existing_report_name_mgs());
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
this.getParent().setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
|
||||
doReportWizard(getReportingConfigName(), DISPLAY_CASE_SPECIFIC_DATA, RUN_REPORTS);
|
||||
doReportWizard(reportName, DISPLAY_CASE_SPECIFIC_DATA, RUN_REPORTS);
|
||||
|
||||
setupReportList();
|
||||
|
||||
if (((DefaultComboBoxModel) reportProfileCB.getModel()).getIndexOf(reportName) >= 0) {
|
||||
reportProfileCB.setSelectedItem(reportName);
|
||||
}
|
||||
|
||||
this.getParent().setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
|
||||
}//GEN-LAST:event_bnEditReportSettingsActionPerformed
|
||||
|
||||
@ -181,8 +320,9 @@ public class CommandLineIngestSettingsPanel extends javax.swing.JPanel {
|
||||
// Variables declaration - do not modify//GEN-BEGIN:variables
|
||||
private javax.swing.JButton bnEditIngestSettings;
|
||||
private javax.swing.JButton bnEditReportSettings;
|
||||
private javax.swing.JLabel jLabelDescription;
|
||||
private javax.swing.JComboBox<String> ingestProfileCB;
|
||||
private javax.swing.JTextPane jTextPane1;
|
||||
private javax.swing.JPanel nodePanel;
|
||||
private javax.swing.JScrollPane nodeScrollPane;
|
||||
private javax.swing.JComboBox<String> reportProfileCB;
|
||||
// End of variables declaration//GEN-END:variables
|
||||
}
|
||||
|
87
Core/src/org/sleuthkit/autopsy/commandlineingest/CommandLineManager.java
Executable file
87
Core/src/org/sleuthkit/autopsy/commandlineingest/CommandLineManager.java
Executable file
@ -0,0 +1,87 @@
|
||||
/*
|
||||
* Autopsy Forensic Browser
|
||||
*
|
||||
* Copyright 2020 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.commandlineingest;
|
||||
|
||||
import java.io.File;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.logging.Level;
|
||||
import org.sleuthkit.autopsy.casemodule.Case;
|
||||
import org.sleuthkit.autopsy.casemodule.CaseActionException;
|
||||
import static org.sleuthkit.autopsy.casemodule.CaseMetadata.getFileExtension;
|
||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||
|
||||
/**
|
||||
* Base class for the command line managers.
|
||||
*/
|
||||
class CommandLineManager {
|
||||
|
||||
private static final Logger LOGGER = Logger.getLogger(CommandLineOpenCaseManager.class.getName());
|
||||
|
||||
/**
|
||||
* Opens existing case.
|
||||
*
|
||||
* @param caseFolderPath full path to case directory
|
||||
*
|
||||
* @throws CaseActionException
|
||||
*/
|
||||
Case openCase(String caseFolderPath) throws CaseActionException {
|
||||
|
||||
LOGGER.log(Level.INFO, "Opening case in directory {0}", caseFolderPath);
|
||||
|
||||
String metadataFilePath = findAutFile(caseFolderPath);
|
||||
Case.openAsCurrentCase(metadataFilePath);
|
||||
|
||||
Case newCase = Case.getCurrentCase();
|
||||
LOGGER.log(Level.INFO, "Opened case {0}", newCase.getName());
|
||||
|
||||
return newCase;
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds the path to the .aut file for the specified case directory.
|
||||
*
|
||||
* @param caseDirectory the directory to check for a .aut file
|
||||
*
|
||||
* @return the path to the first .aut file found in the directory
|
||||
*
|
||||
* @throws CaseActionException if there was an issue finding a .aut file
|
||||
*/
|
||||
private String findAutFile(String caseDirectory) throws CaseActionException {
|
||||
File caseFolder = Paths.get(caseDirectory).toFile();
|
||||
if (caseFolder.exists()) {
|
||||
/*
|
||||
* Search for '*.aut' files.
|
||||
*/
|
||||
File[] fileArray = caseFolder.listFiles();
|
||||
if (fileArray == null) {
|
||||
throw new CaseActionException("No files found in case directory");
|
||||
}
|
||||
String autFilePath = null;
|
||||
for (File file : fileArray) {
|
||||
String name = file.getName().toLowerCase();
|
||||
if (autFilePath == null && name.endsWith(getFileExtension())) {
|
||||
return file.getAbsolutePath();
|
||||
}
|
||||
}
|
||||
throw new CaseActionException("No .aut files found in case directory");
|
||||
}
|
||||
throw new CaseActionException("Case directory was not found");
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,85 @@
|
||||
/*
|
||||
* Autopsy Forensic Browser
|
||||
*
|
||||
* Copyright 2020 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.commandlineingest;
|
||||
|
||||
import java.nio.file.Paths;
|
||||
import java.util.Collection;
|
||||
import java.util.Iterator;
|
||||
import java.util.logging.Level;
|
||||
import org.netbeans.spi.sendopts.OptionProcessor;
|
||||
import org.openide.util.Lookup;
|
||||
import org.sleuthkit.autopsy.casemodule.CaseActionException;
|
||||
import org.sleuthkit.autopsy.casemodule.OpenFromArguments;
|
||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||
|
||||
/**
|
||||
* Handles the opening of a case from the command line.
|
||||
*
|
||||
*/
|
||||
public class CommandLineOpenCaseManager extends CommandLineManager {
|
||||
|
||||
private static final Logger LOGGER = Logger.getLogger(CommandLineOpenCaseManager.class.getName());
|
||||
|
||||
/**
|
||||
* Starts the thread to open the case.
|
||||
*/
|
||||
public void start() {
|
||||
new Thread(new CommandLineOpenCaseManager.JobProcessingTask()).start();
|
||||
}
|
||||
|
||||
/**
|
||||
* A runnable class that open the given class in the list of command line
|
||||
* options.
|
||||
*/
|
||||
private final class JobProcessingTask implements Runnable {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
String casePath = "";
|
||||
|
||||
// first look up all OptionProcessors and get input data from CommandLineOptionProcessor
|
||||
Collection<? extends OptionProcessor> optionProcessors = Lookup.getDefault().lookupAll(OptionProcessor.class);
|
||||
Iterator<? extends OptionProcessor> optionsIterator = optionProcessors.iterator();
|
||||
while (optionsIterator.hasNext()) {
|
||||
// find CommandLineOptionProcessor
|
||||
OptionProcessor processor = optionsIterator.next();
|
||||
if (processor instanceof OpenFromArguments) {
|
||||
// check if we are running from command line
|
||||
casePath = Paths.get(((OpenFromArguments) processor).getDefaultArg()).toAbsolutePath().toString();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (casePath == null || casePath.isEmpty()) {
|
||||
LOGGER.log(Level.SEVERE, "No command line commands specified");
|
||||
System.err.println("No command line commands specified");
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
CommandLineOpenCaseManager.this.openCase(casePath);
|
||||
LOGGER.log(Level.INFO, "Opening case at " + casePath);
|
||||
} catch (CaseActionException ex) {
|
||||
LOGGER.log(Level.SEVERE, "Error opening case from command line ", ex);
|
||||
System.err.println("Error opening case ");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
@ -1,7 +1,7 @@
|
||||
/*
|
||||
* Autopsy Forensic Browser
|
||||
*
|
||||
* Copyright 2019-2019 Basis Technology Corp.
|
||||
* Copyright 2019-2020 Basis Technology Corp.
|
||||
* Contact: carrier <at> sleuthkit <dot> org
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
@ -51,7 +51,7 @@ public class CommandLineOptionProcessor extends OptionProcessor {
|
||||
private final Option runIngestCommandOption = Option.withoutArgument('r', "runIngest");
|
||||
private final Option ingestProfileOption = Option.requiredArgument('p', "ingestProfile");
|
||||
private final Option listAllDataSourcesCommandOption = Option.withoutArgument('l', "listAllDataSources");
|
||||
private final Option generateReportsOption = Option.withoutArgument('g', "generateReports");
|
||||
private final Option generateReportsOption = Option.optionalArgument('g', "generateReports");
|
||||
|
||||
private boolean runFromCommandLine = false;
|
||||
|
||||
@ -113,7 +113,6 @@ public class CommandLineOptionProcessor extends OptionProcessor {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
String caseType = "";
|
||||
if (values.containsKey(caseTypeOption)) {
|
||||
argDirs = values.get(caseTypeOption);
|
||||
@ -358,6 +357,7 @@ public class CommandLineOptionProcessor extends OptionProcessor {
|
||||
}
|
||||
|
||||
// Add "GENERATE_REPORTS" command, if present
|
||||
String reportProfile = null;
|
||||
if (values.containsKey(generateReportsOption)) {
|
||||
|
||||
// 'caseDir' must only be specified if the case is not being created during the current run
|
||||
@ -369,8 +369,26 @@ public class CommandLineOptionProcessor extends OptionProcessor {
|
||||
return;
|
||||
}
|
||||
|
||||
argDirs = values.get(generateReportsOption);
|
||||
if (argDirs.length > 0) {
|
||||
reportProfile = argDirs[0];
|
||||
}
|
||||
|
||||
// If the user doesn't supply an options for generateReports the
|
||||
// argsDirs length will be 0, so if reportProfile is empty
|
||||
// something is not right.
|
||||
if (reportProfile != null && reportProfile.isEmpty()) {
|
||||
logger.log(Level.SEVERE, "'generateReports' argument is empty");
|
||||
System.err.println("'generateReports' argument is empty");
|
||||
runFromCommandLine = false;
|
||||
return;
|
||||
}
|
||||
|
||||
CommandLineCommand newCommand = new CommandLineCommand(CommandLineCommand.CommandType.GENERATE_REPORTS);
|
||||
newCommand.addInputValue(CommandLineCommand.InputType.CASE_FOLDER_PATH.name(), caseDir);
|
||||
if (reportProfile != null) {
|
||||
newCommand.addInputValue(CommandLineCommand.InputType.REPORT_PROFILE_NAME.name(), reportProfile);
|
||||
}
|
||||
commands.add(newCommand);
|
||||
runFromCommandLine = true;
|
||||
}
|
||||
|
@ -26,7 +26,7 @@
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Group type="102" alignment="1" attributes="0">
|
||||
<EmptySpace min="-2" pref="20" max="-2" attributes="0"/>
|
||||
<Component id="jLabel1" pref="305" max="32767" attributes="0"/>
|
||||
<Component id="jLabel1" max="32767" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
|
@ -1,7 +1,7 @@
|
||||
/*
|
||||
* Autopsy Forensic Browser
|
||||
*
|
||||
* Copyright 2019-2019 Basis Technology Corp.
|
||||
* Copyright 2019-2020 Basis Technology Corp.
|
||||
* Contact: carrier <at> sleuthkit <dot> org
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
@ -52,7 +52,7 @@ class CommandLinePanel extends JPanel {
|
||||
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
|
||||
.addGap(20, 20, 20)
|
||||
.addComponent(jLabel1, javax.swing.GroupLayout.DEFAULT_SIZE, 305, Short.MAX_VALUE)
|
||||
.addComponent(jLabel1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
||||
.addContainerGap())
|
||||
);
|
||||
layout.setVerticalGroup(
|
||||
|
@ -35,8 +35,12 @@ import org.sleuthkit.autopsy.coreutils.Logger;
|
||||
import org.sleuthkit.autopsy.datamodel.NodeProperty;
|
||||
import org.sleuthkit.datamodel.Account;
|
||||
import org.sleuthkit.datamodel.AccountDeviceInstance;
|
||||
import org.sleuthkit.datamodel.BlackboardArtifact;
|
||||
import org.sleuthkit.datamodel.BlackboardAttribute;
|
||||
import static org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_NAME;
|
||||
import org.sleuthkit.datamodel.CommunicationsFilter;
|
||||
import org.sleuthkit.datamodel.CommunicationsManager;
|
||||
import org.sleuthkit.datamodel.TskCoreException;
|
||||
|
||||
/**
|
||||
* Node to represent an Account Device Instance in the CVT
|
||||
@ -49,6 +53,8 @@ final class AccountDeviceInstanceNode extends AbstractNode {
|
||||
private final CommunicationsManager commsManager;
|
||||
private final Account account;
|
||||
|
||||
private static final BlackboardAttribute.Type NAME_ATTRIBUTE = new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.fromID(TSK_NAME.getTypeID()));
|
||||
|
||||
AccountDeviceInstanceNode(AccountDeviceInstanceKey accountDeviceInstanceKey, CommunicationsManager commsManager) {
|
||||
super(Children.LEAF, Lookups.fixed(accountDeviceInstanceKey, commsManager));
|
||||
this.accountDeviceInstanceKey = accountDeviceInstanceKey;
|
||||
@ -122,15 +128,17 @@ final class AccountDeviceInstanceNode extends AbstractNode {
|
||||
@Override
|
||||
public String getShortDescription() {
|
||||
List<PersonaAccount> personaList;
|
||||
List<BlackboardArtifact> contactArtifactList;
|
||||
try {
|
||||
personaList = CVTPersonaCache.getPersonaAccounts(account);
|
||||
contactArtifactList = ContactCache.getContacts(account);
|
||||
} catch (ExecutionException ex) {
|
||||
logger.log(Level.WARNING, "Failed to retrieve Persona details for node.", ex);
|
||||
return getDisplayName();
|
||||
}
|
||||
|
||||
String personaName;
|
||||
if (!personaList.isEmpty()) {
|
||||
if (personaList != null && !personaList.isEmpty()) {
|
||||
personaName = personaList.get(0).getPersona().getName();
|
||||
if (personaList.size() > 1) {
|
||||
personaName += Bundle.AccountInstanceNode_Tooltip_suffix(Integer.toString(personaList.size()));
|
||||
@ -139,6 +147,19 @@ final class AccountDeviceInstanceNode extends AbstractNode {
|
||||
personaName = "None";
|
||||
}
|
||||
|
||||
return Bundle.AccountInstanceNode_Tooltip_Template(getDisplayName(), personaName);
|
||||
String contactName = getDisplayName();
|
||||
if (contactArtifactList != null && !contactArtifactList.isEmpty()) {
|
||||
try {
|
||||
BlackboardArtifact contactArtifact = contactArtifactList.get(0);
|
||||
BlackboardAttribute attribute = contactArtifact.getAttribute(NAME_ATTRIBUTE);
|
||||
if (attribute != null) {
|
||||
contactName = attribute.getValueString();
|
||||
}
|
||||
} catch (TskCoreException ex) {
|
||||
logger.log(Level.WARNING, "Failed to retrive name attribute from contact artifact.", ex);
|
||||
}
|
||||
}
|
||||
|
||||
return Bundle.AccountInstanceNode_Tooltip_Template(contactName, personaName);
|
||||
}
|
||||
}
|
||||
|
@ -21,7 +21,6 @@ CVTTopComponent.accountsBrowser.TabConstraints.tabTitle_1=Browse
|
||||
CVTTopComponent.browseVisualizeTabPane.AccessibleContext.accessibleName=Visualize
|
||||
CVTTopComponent.vizPanel.TabConstraints.tabTitle_1=Visualize
|
||||
VisualizationPanel.fitGraphButton.text=
|
||||
VisualizationPanel.jTextArea1.text=Right-click an account in the Browse Accounts table, and select 'Visualize' to begin.
|
||||
VisualizationPanel.fitZoomButton.toolTipText=Fit visualization to available space.
|
||||
VisualizationPanel.fitZoomButton.text=
|
||||
VisualizationPanel.zoomActualButton.toolTipText=Reset visualization default zoom state.
|
||||
@ -51,3 +50,4 @@ VisualizationPanel.zoomLabel.text=Zoom:
|
||||
VisualizationPanel.snapshotButton.toolTipText=Generate Snapshot report.
|
||||
CVTTopComponent.filtersPane.TabConstraints.tabTitle=Filters
|
||||
CVTTopComponent.filterTabPanel.TabConstraints.tabTitle=Filters
|
||||
VisualizationPanel.jTextPane1.text=Right-click an account in the Browse Accounts table, and select 'Visualize' to begin.
|
||||
|
@ -61,7 +61,6 @@ CVTTopComponent.accountsBrowser.TabConstraints.tabTitle_1=Browse
|
||||
CVTTopComponent.browseVisualizeTabPane.AccessibleContext.accessibleName=Visualize
|
||||
CVTTopComponent.vizPanel.TabConstraints.tabTitle_1=Visualize
|
||||
VisualizationPanel.fitGraphButton.text=
|
||||
VisualizationPanel.jTextArea1.text=Right-click an account in the Browse Accounts table, and select 'Visualize' to begin.
|
||||
VisualizationPanel.fitZoomButton.toolTipText=Fit visualization to available space.
|
||||
VisualizationPanel.fitZoomButton.text=
|
||||
# {0} - layout name
|
||||
@ -99,6 +98,7 @@ VisualizationPanel.zoomLabel.text=Zoom:
|
||||
VisualizationPanel.snapshotButton.toolTipText=Generate Snapshot report.
|
||||
CVTTopComponent.filtersPane.TabConstraints.tabTitle=Filters
|
||||
CVTTopComponent.filterTabPanel.TabConstraints.tabTitle=Filters
|
||||
VisualizationPanel.jTextPane1.text=Right-click an account in the Browse Accounts table, and select 'Visualize' to begin.
|
||||
VisualizationPanel_action_dialogs_title=Communications
|
||||
VisualizationPanel_action_name_text=Snapshot Report
|
||||
VisualizationPanel_module_name=Communications
|
||||
|
@ -56,7 +56,7 @@ CVTTopComponent.accountsBrowser.TabConstraints.tabTitle_1=\u53c2\u7167
|
||||
CVTTopComponent.browseVisualizeTabPane.AccessibleContext.accessibleName=\u53ef\u8996\u5316
|
||||
CVTTopComponent.vizPanel.TabConstraints.tabTitle_1=\u53ef\u8996\u5316
|
||||
VisualizationPanel.fitGraphButton.text=
|
||||
VisualizationPanel.jTextArea1.text=[\u30a2\u30ab\u30a6\u30f3\u30c8\u53c2\u7167] \u30c6\u30fc\u30d6\u30eb\u3067\u30a2\u30ab\u30a6\u30f3\u30c8\u3092\u53f3\u30af\u30ea\u30c3\u30af\u3057\u3001[\u53ef\u8996\u5316] \u3092\u9078\u629e\u3057\u3066\u958b\u59cb\u3057\u307e\u3059\u3002
|
||||
VisualizationPanel.jTextPane1.text=[\u30a2\u30ab\u30a6\u30f3\u30c8\u53c2\u7167] \u30c6\u30fc\u30d6\u30eb\u3067\u30a2\u30ab\u30a6\u30f3\u30c8\u3092\u53f3\u30af\u30ea\u30c3\u30af\u3057\u3001[\u53ef\u8996\u5316] \u3092\u9078\u629e\u3057\u3066\u958b\u59cb\u3057\u307e\u3059\u3002
|
||||
# {0} - \u30ec\u30a4\u30a2\u30a6\u30c8\u540d
|
||||
VisualizationPanel.layoutFail.text={0} \u30ec\u30a4\u30a2\u30a6\u30c8\u304c\u5931\u6557\u3057\u307e\u3057\u305f\u3002\u5225\u306e\u30ec\u30a4\u30a2\u30a6\u30c8\u3092\u304a\u8a66\u3057\u304f\u3060\u3055\u3044\u3002
|
||||
# {0} - \u30ec\u30a4\u30a2\u30a6\u30c8\u540d
|
||||
|
166
Core/src/org/sleuthkit/autopsy/communications/ContactCache.java
Executable file
166
Core/src/org/sleuthkit/autopsy/communications/ContactCache.java
Executable file
@ -0,0 +1,166 @@
|
||||
/*
|
||||
* Autopsy Forensic Browser
|
||||
*
|
||||
* Copyright 2020 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.communications;
|
||||
|
||||
import com.google.common.cache.CacheBuilder;
|
||||
import com.google.common.cache.CacheLoader;
|
||||
import com.google.common.cache.LoadingCache;
|
||||
import java.beans.PropertyChangeEvent;
|
||||
import java.beans.PropertyChangeListener;
|
||||
import java.sql.SQLException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.EnumSet;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.logging.Level;
|
||||
import org.sleuthkit.autopsy.casemodule.Case;
|
||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||
import org.sleuthkit.autopsy.ingest.IngestManager;
|
||||
import static org.sleuthkit.autopsy.ingest.IngestManager.IngestModuleEvent.DATA_ADDED;
|
||||
import org.sleuthkit.autopsy.ingest.ModuleDataEvent;
|
||||
import org.sleuthkit.datamodel.Account;
|
||||
import org.sleuthkit.datamodel.BlackboardArtifact;
|
||||
import org.sleuthkit.datamodel.BlackboardAttribute;
|
||||
import org.sleuthkit.datamodel.TskCoreException;
|
||||
|
||||
/**
|
||||
* A singleton cache of the Contact artifacts for accounts. The map of account
|
||||
* unique ids to list of contact artifacts is stored in a LoadingCache which
|
||||
* expires after 10 of non-use.
|
||||
*
|
||||
*/
|
||||
final class ContactCache {
|
||||
|
||||
private static final Logger logger = Logger.getLogger(ContactCache.class.getName());
|
||||
|
||||
private static ContactCache instance;
|
||||
|
||||
private final LoadingCache<String, Map<String, List<BlackboardArtifact>>> accountMap;
|
||||
|
||||
/**
|
||||
* Returns the list of Contacts for the given Account.
|
||||
*
|
||||
* @param account Account instance.
|
||||
*
|
||||
* @return List of TSK_CONTACT artifacts that references the given Account.
|
||||
* An empty list is returned if no contacts are found.
|
||||
*
|
||||
* @throws ExecutionException
|
||||
*/
|
||||
static synchronized List<BlackboardArtifact> getContacts(Account account) throws ExecutionException {
|
||||
return getInstance().accountMap.get("realMap").get(account.getTypeSpecificID());
|
||||
}
|
||||
|
||||
/**
|
||||
* Force the cache to invalidate all entries.
|
||||
*/
|
||||
static synchronized void invalidateCache() {
|
||||
getInstance().accountMap.invalidateAll();
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct a new instance.
|
||||
*/
|
||||
private ContactCache() {
|
||||
|
||||
accountMap = CacheBuilder.newBuilder().expireAfterAccess(10, TimeUnit.MINUTES).build(
|
||||
new CacheLoader<String, Map<String, List<BlackboardArtifact>>>() {
|
||||
@Override
|
||||
public Map<String, List<BlackboardArtifact>> load(String key) {
|
||||
try {
|
||||
return buildMap();
|
||||
} catch (SQLException | TskCoreException ex) {
|
||||
logger.log(Level.WARNING, "Failed to build account to contact map", ex);
|
||||
}
|
||||
return new HashMap<>(); // Return an empty map if there is an exception to avoid NPE and continual trying.
|
||||
}
|
||||
});
|
||||
|
||||
PropertyChangeListener ingestListener = pce -> {
|
||||
String eventType = pce.getPropertyName();
|
||||
if (eventType.equals(DATA_ADDED.toString())) {
|
||||
ModuleDataEvent eventData = (ModuleDataEvent) pce.getOldValue();
|
||||
if (eventData.getBlackboardArtifactType().getTypeID() == BlackboardArtifact.ARTIFACT_TYPE.TSK_CONTACT.getTypeID()) {
|
||||
invalidateCache();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
Case.addEventTypeSubscriber(EnumSet.of(Case.Events.CURRENT_CASE), (PropertyChangeEvent event) -> {
|
||||
if (event.getNewValue() == null) {
|
||||
invalidateCache();
|
||||
}
|
||||
});
|
||||
|
||||
IngestManager.getInstance().addIngestModuleEventListener(EnumSet.of(DATA_ADDED), ingestListener);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the singleton instance of the cache object.
|
||||
*
|
||||
* @return AccountCache instance.
|
||||
*/
|
||||
private static synchronized ContactCache getInstance() {
|
||||
if (instance == null) {
|
||||
instance = new ContactCache();
|
||||
}
|
||||
|
||||
return instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds the map of account IDs to contacts that reference them.
|
||||
*
|
||||
* @return A map of account IDs to contact artifacts.
|
||||
*
|
||||
* @throws TskCoreException
|
||||
* @throws SQLException
|
||||
*/
|
||||
private Map<String, List<BlackboardArtifact>> buildMap() throws TskCoreException, SQLException {
|
||||
Map<String, List<BlackboardArtifact>> acctMap = new HashMap<>();
|
||||
List<BlackboardArtifact> contactList = Case.getCurrentCase().getSleuthkitCase().getBlackboardArtifacts(BlackboardArtifact.ARTIFACT_TYPE.TSK_CONTACT);
|
||||
|
||||
for (BlackboardArtifact contactArtifact : contactList) {
|
||||
List<BlackboardAttribute> contactAttributes = contactArtifact.getAttributes();
|
||||
for (BlackboardAttribute attribute : contactAttributes) {
|
||||
String typeName = attribute.getAttributeType().getTypeName();
|
||||
|
||||
if (typeName.startsWith("TSK_EMAIL")
|
||||
|| typeName.startsWith("TSK_PHONE")
|
||||
|| typeName.startsWith("TSK_NAME")
|
||||
|| typeName.startsWith("TSK_ID")) {
|
||||
String accountID = attribute.getValueString();
|
||||
List<BlackboardArtifact> artifactList = acctMap.getOrDefault(accountID, new ArrayList<>());
|
||||
|
||||
acctMap.put(accountID, artifactList);
|
||||
|
||||
if (!artifactList.contains(contactArtifact)) {
|
||||
artifactList.add(contactArtifact);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return acctMap;
|
||||
}
|
||||
}
|
@ -18,9 +18,12 @@
|
||||
*/
|
||||
package org.sleuthkit.autopsy.communications;
|
||||
|
||||
import java.awt.Component;
|
||||
import java.time.ZoneId;
|
||||
import java.time.ZoneOffset;
|
||||
import java.util.TimeZone;
|
||||
import javax.swing.table.TableCellRenderer;
|
||||
import org.netbeans.swing.outline.Outline;
|
||||
import org.sleuthkit.autopsy.core.UserPreferences;
|
||||
import org.sleuthkit.autopsy.datamodel.accounts.Accounts;
|
||||
import org.sleuthkit.datamodel.Account;
|
||||
@ -48,4 +51,28 @@ public final class Utils {
|
||||
return Accounts.getIconFilePath(type);
|
||||
}
|
||||
|
||||
static public void setColumnWidths(Outline outline) {
|
||||
int margin = 4;
|
||||
int padding = 8;
|
||||
|
||||
final int rows = Math.min(100, outline.getRowCount());
|
||||
|
||||
for (int column = 0; column < outline.getColumnCount(); column++) {
|
||||
int columnWidthLimit = 500;
|
||||
int columnWidth = 0;
|
||||
|
||||
// find the maximum width needed to fit the values for the first 100 rows, at most
|
||||
for (int row = 0; row < rows; row++) {
|
||||
TableCellRenderer renderer = outline.getCellRenderer(row, column);
|
||||
Component comp = outline.prepareRenderer(renderer, row, column);
|
||||
columnWidth = Math.max(comp.getPreferredSize().width, columnWidth);
|
||||
}
|
||||
|
||||
columnWidth += 2 * margin + padding; // add margin and regular padding
|
||||
columnWidth = Math.min(columnWidth, columnWidthLimit);
|
||||
|
||||
outline.getColumnModel().getColumn(column).setPreferredWidth(columnWidth);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -32,39 +32,21 @@
|
||||
</Constraint>
|
||||
</Constraints>
|
||||
|
||||
<Layout>
|
||||
<DimensionLayout dim="0">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Group type="102" alignment="0" attributes="0">
|
||||
<EmptySpace pref="316" max="32767" attributes="0"/>
|
||||
<Component id="jTextArea1" min="-2" pref="424" max="-2" attributes="0"/>
|
||||
<EmptySpace pref="481" max="32767" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
<DimensionLayout dim="1">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Group type="102" alignment="0" attributes="0">
|
||||
<EmptySpace max="32767" attributes="0"/>
|
||||
<Component id="jTextArea1" min="-2" pref="47" max="-2" attributes="0"/>
|
||||
<EmptySpace max="32767" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
</Layout>
|
||||
<Layout class="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout"/>
|
||||
<SubComponents>
|
||||
<Component class="javax.swing.JTextArea" name="jTextArea1">
|
||||
<Component class="javax.swing.JTextPane" name="jTextPane1">
|
||||
<Properties>
|
||||
<Property name="background" type="java.awt.Color" editor="org.netbeans.beaninfo.editors.ColorEditor">
|
||||
<Color blue="f0" green="f0" red="f0" type="rgb"/>
|
||||
</Property>
|
||||
<Property name="columns" type="int" value="20"/>
|
||||
<Property name="lineWrap" type="boolean" value="true"/>
|
||||
<Property name="rows" type="int" value="5"/>
|
||||
<Property name="editable" type="boolean" value="false"/>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/communications/Bundle.properties" key="VisualizationPanel.jTextArea1.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/communications/Bundle.properties" key="VisualizationPanel.jTextPane1.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
<Property name="opaque" type="boolean" value="false"/>
|
||||
</Properties>
|
||||
<Constraints>
|
||||
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
|
||||
<GridBagConstraints gridX="-1" gridY="-1" gridWidth="1" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="50" insetsLeft="0" insetsBottom="0" insetsRight="0" anchor="11" weightX="0.0" weightY="1.0"/>
|
||||
</Constraint>
|
||||
</Constraints>
|
||||
</Component>
|
||||
</SubComponents>
|
||||
</Container>
|
||||
|
@ -46,7 +46,10 @@ import java.awt.Dimension;
|
||||
import java.awt.Font;
|
||||
import java.awt.Frame;
|
||||
import java.awt.Graphics;
|
||||
import java.awt.GridBagConstraints;
|
||||
import java.awt.GridBagLayout;
|
||||
import java.awt.GridLayout;
|
||||
import java.awt.Insets;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.awt.event.MouseAdapter;
|
||||
@ -86,8 +89,8 @@ import javax.swing.JMenuItem;
|
||||
import javax.swing.JOptionPane;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.JPopupMenu;
|
||||
import javax.swing.JTextArea;
|
||||
import javax.swing.JTextField;
|
||||
import javax.swing.JTextPane;
|
||||
import javax.swing.JToolBar;
|
||||
import javax.swing.SwingConstants;
|
||||
import javax.swing.SwingUtilities;
|
||||
@ -370,10 +373,11 @@ final public class VisualizationPanel extends JPanel {
|
||||
@SuppressWarnings("unchecked")
|
||||
// <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
|
||||
private void initComponents() {
|
||||
GridBagConstraints gridBagConstraints;
|
||||
|
||||
borderLayoutPanel = new JPanel();
|
||||
placeHolderPanel = new JPanel();
|
||||
jTextArea1 = new JTextArea();
|
||||
jTextPane1 = new JTextPane();
|
||||
notificationsJFXPanel = new JFXPanel();
|
||||
toolbar = new JToolBar();
|
||||
backButton = new JButton();
|
||||
@ -395,26 +399,16 @@ final public class VisualizationPanel extends JPanel {
|
||||
|
||||
borderLayoutPanel.setLayout(new BorderLayout());
|
||||
|
||||
jTextArea1.setBackground(new Color(240, 240, 240));
|
||||
jTextArea1.setColumns(20);
|
||||
jTextArea1.setLineWrap(true);
|
||||
jTextArea1.setRows(5);
|
||||
jTextArea1.setText(NbBundle.getMessage(VisualizationPanel.class, "VisualizationPanel.jTextArea1.text")); // NOI18N
|
||||
placeHolderPanel.setLayout(new GridBagLayout());
|
||||
|
||||
GroupLayout placeHolderPanelLayout = new GroupLayout(placeHolderPanel);
|
||||
placeHolderPanel.setLayout(placeHolderPanelLayout);
|
||||
placeHolderPanelLayout.setHorizontalGroup(placeHolderPanelLayout.createParallelGroup(GroupLayout.Alignment.LEADING)
|
||||
.addGroup(placeHolderPanelLayout.createSequentialGroup()
|
||||
.addContainerGap(316, Short.MAX_VALUE)
|
||||
.addComponent(jTextArea1, GroupLayout.PREFERRED_SIZE, 424, GroupLayout.PREFERRED_SIZE)
|
||||
.addContainerGap(481, Short.MAX_VALUE))
|
||||
);
|
||||
placeHolderPanelLayout.setVerticalGroup(placeHolderPanelLayout.createParallelGroup(GroupLayout.Alignment.LEADING)
|
||||
.addGroup(placeHolderPanelLayout.createSequentialGroup()
|
||||
.addContainerGap(GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
||||
.addComponent(jTextArea1, GroupLayout.PREFERRED_SIZE, 47, GroupLayout.PREFERRED_SIZE)
|
||||
.addContainerGap(GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
|
||||
);
|
||||
jTextPane1.setEditable(false);
|
||||
jTextPane1.setText(NbBundle.getMessage(VisualizationPanel.class, "VisualizationPanel.jTextPane1.text")); // NOI18N
|
||||
jTextPane1.setOpaque(false);
|
||||
gridBagConstraints = new GridBagConstraints();
|
||||
gridBagConstraints.anchor = GridBagConstraints.NORTH;
|
||||
gridBagConstraints.weighty = 1.0;
|
||||
gridBagConstraints.insets = new Insets(50, 0, 0, 0);
|
||||
placeHolderPanel.add(jTextPane1, gridBagConstraints);
|
||||
|
||||
borderLayoutPanel.add(placeHolderPanel, BorderLayout.CENTER);
|
||||
borderLayoutPanel.add(notificationsJFXPanel, BorderLayout.PAGE_END);
|
||||
@ -854,7 +848,7 @@ final public class VisualizationPanel extends JPanel {
|
||||
private JToolBar.Separator jSeparator1;
|
||||
private JToolBar.Separator jSeparator2;
|
||||
private JToolBar.Separator jSeparator3;
|
||||
private JTextArea jTextArea1;
|
||||
private JTextPane jTextPane1;
|
||||
private JFXPanel notificationsJFXPanel;
|
||||
private JPanel placeHolderPanel;
|
||||
private JButton snapshotButton;
|
||||
|
@ -73,5 +73,5 @@ SummaryViewer.referencesLabel.text=Communication References:
|
||||
SummaryViewer.referencesDataLabel.text=<reference count>
|
||||
SummaryViewer.contactsLabel.text=Book Entries:
|
||||
SummaryViewer.accountCountry.text=<account country>
|
||||
SummaryViewer.fileRefPane.border.title=File Referernce(s) in Current Case
|
||||
SummaryViewer.fileRefPane.border.title=File References in Current Case
|
||||
SummaryViewer.selectAccountFileRefLabel.text=<Select a single account to see File References>
|
||||
|
@ -38,6 +38,8 @@ import javax.swing.JPanel;
|
||||
import javax.swing.ListSelectionModel;
|
||||
import javax.swing.SwingUtilities;
|
||||
import static javax.swing.SwingUtilities.isDescendingFrom;
|
||||
import javax.swing.event.TableModelEvent;
|
||||
import javax.swing.event.TableModelListener;
|
||||
import org.netbeans.swing.outline.DefaultOutlineModel;
|
||||
import org.netbeans.swing.outline.Outline;
|
||||
import org.openide.explorer.ExplorerManager;
|
||||
@ -50,6 +52,7 @@ import org.openide.nodes.Node.PropertySet;
|
||||
import org.openide.util.Lookup;
|
||||
import org.openide.util.NbBundle.Messages;
|
||||
import org.sleuthkit.autopsy.communications.ModifiableProxyLookup;
|
||||
import org.sleuthkit.autopsy.communications.Utils;
|
||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||
|
||||
/**
|
||||
@ -116,6 +119,13 @@ final class MessageViewer extends JPanel implements RelationshipsViewer {
|
||||
}
|
||||
});
|
||||
|
||||
rootTablePane.getOutlineView().getOutline().getModel().addTableModelListener(new TableModelListener() {
|
||||
@Override
|
||||
public void tableChanged(TableModelEvent e) {
|
||||
Utils.setColumnWidths(rootTablePane.getOutlineView().getOutline());
|
||||
}
|
||||
});
|
||||
|
||||
threadMessagesPanel.setChildFactory(threadMessageNodeFactory);
|
||||
|
||||
rootTablePane.setTableColumnsWidth(10, 20, 70);
|
||||
|
@ -26,6 +26,9 @@ CallLogArtifactViewer_label_from=From
|
||||
CallLogArtifactViewer_label_to=To
|
||||
CallLogArtifactViewer_suffix_local=(Local)
|
||||
CallLogArtifactViewer_value_unknown=Unknown
|
||||
#{0} - contact name
|
||||
CommunicationArtifactViewerHelper_contact_label=Contact: {0}
|
||||
CommunicationArtifactViewerHelper_contact_label_unknown=Unknown
|
||||
CommunicationArtifactViewerHelper_menuitem_copy=Copy
|
||||
CommunicationArtifactViewerHelper_persona_button_create=Create
|
||||
CommunicationArtifactViewerHelper_persona_button_view=View
|
||||
@ -51,7 +54,6 @@ ContactArtifactViewer_persona_no_match=No matches found
|
||||
ContactArtifactViewer_persona_searching=Searching...
|
||||
ContactArtifactViewer_persona_unknown=Unknown
|
||||
ContactArtifactViewer_phones_header=Phone
|
||||
ContactArtifactViewer_plural_suffix=s
|
||||
DataContentViewerArtifact.failedToGetAttributes.message=Failed to get some or all attributes from case database
|
||||
DataContentViewerArtifact.failedToGetSourcePath.message=Failed to get source file path from case database
|
||||
DefaultArtifactContentViewer.attrsTableHeader.sources=Source(s)
|
||||
@ -61,6 +63,7 @@ DefaultArtifactContentViewer.copyMenuItem.text=Copy
|
||||
DefaultArtifactContentViewer.selectAllMenuItem.text=Select All
|
||||
MessageAccountPanel_button_create_label=Create
|
||||
MessageAccountPanel_button_view_label=View
|
||||
MessageAccountPanel_contact_label=Contact:
|
||||
MessageAccountPanel_no_matches=No matches found.
|
||||
MessageAccountPanel_persona_label=Persona:
|
||||
MessageAccountPanel_unknown_label=Unknown
|
||||
|
@ -36,6 +36,7 @@ import org.openide.util.NbBundle;
|
||||
import org.openide.util.lookup.ServiceProvider;
|
||||
import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepository;
|
||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||
import org.sleuthkit.autopsy.guiutils.ContactCache;
|
||||
import org.sleuthkit.datamodel.BlackboardArtifact;
|
||||
import org.sleuthkit.datamodel.BlackboardAttribute;
|
||||
import org.sleuthkit.datamodel.Content;
|
||||
@ -143,6 +144,8 @@ public class CallLogArtifactViewer extends javax.swing.JPanel implements Artifac
|
||||
String fromAccountIdentifier = null;
|
||||
String toAccountIdentifier = null;
|
||||
List<String> otherParties = null;
|
||||
List<String> toContactNames = null;
|
||||
List<String> fromContactNames = null;
|
||||
|
||||
Content dataSource = artifact.getDataSource();
|
||||
String deviceId = ((DataSource) dataSource).getDeviceId();
|
||||
@ -186,6 +189,7 @@ public class CallLogArtifactViewer extends javax.swing.JPanel implements Artifac
|
||||
String fromAccountAttrValue = fromAccountAttr.getValueString();
|
||||
if (fromAccountAttrValue.equalsIgnoreCase(deviceId) == false) {
|
||||
fromAccountIdentifier = fromAccountAttrValue;
|
||||
fromContactNames = ContactCache.getContactNameList(fromAccountIdentifier);
|
||||
}
|
||||
}
|
||||
|
||||
@ -195,6 +199,7 @@ public class CallLogArtifactViewer extends javax.swing.JPanel implements Artifac
|
||||
String toAccountAttrValue = StringUtils.trim(numbers[0]);
|
||||
if (toAccountAttrValue.equalsIgnoreCase(deviceId) == false) {
|
||||
toAccountIdentifier = toAccountAttrValue;
|
||||
toContactNames = ContactCache.getContactNameList(toAccountIdentifier);
|
||||
}
|
||||
|
||||
// if more than one To address, then stick the rest of them in the
|
||||
@ -228,6 +233,9 @@ public class CallLogArtifactViewer extends javax.swing.JPanel implements Artifac
|
||||
}
|
||||
|
||||
callLogViewData.setOtherAttributes(extractOtherAttributes(artifact));
|
||||
|
||||
callLogViewData.setFromContactNameList(fromContactNames);
|
||||
callLogViewData.setToContactNameList(toContactNames);
|
||||
}
|
||||
|
||||
return callLogViewData;
|
||||
@ -312,6 +320,11 @@ public class CallLogArtifactViewer extends javax.swing.JPanel implements Artifac
|
||||
String accountDisplayString = getAccountDisplayString(callLogViewData.getFromAccount(), callLogViewData);
|
||||
CommunicationArtifactViewerHelper.addValue(this, m_gridBagLayout, this.m_constraints, accountDisplayString);
|
||||
|
||||
List<String> contactNames = callLogViewData.getFromContactNameList();
|
||||
for (String name : contactNames) {
|
||||
CommunicationArtifactViewerHelper.addContactRow(this, m_gridBagLayout, m_constraints, name);
|
||||
}
|
||||
|
||||
// show persona
|
||||
dataList.addAll(CommunicationArtifactViewerHelper.addPersonaRow(this, m_gridBagLayout, this.m_constraints, callLogViewData.getFromAccount()));
|
||||
} else {
|
||||
@ -324,6 +337,11 @@ public class CallLogArtifactViewer extends javax.swing.JPanel implements Artifac
|
||||
String accountDisplayString = getAccountDisplayString(callLogViewData.getToAccount(), callLogViewData);
|
||||
CommunicationArtifactViewerHelper.addValue(this, m_gridBagLayout, this.m_constraints, accountDisplayString);
|
||||
|
||||
List<String> contactNames = callLogViewData.getToContactNameList();
|
||||
for (String name : contactNames) {
|
||||
CommunicationArtifactViewerHelper.addContactRow(this, m_gridBagLayout, m_constraints, name);
|
||||
}
|
||||
|
||||
dataList.addAll(CommunicationArtifactViewerHelper.addPersonaRow(this, m_gridBagLayout, this.m_constraints, callLogViewData.getToAccount()));
|
||||
|
||||
} else {
|
||||
|
@ -22,6 +22,7 @@ import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
@ -47,6 +48,9 @@ final class CallLogViewData {
|
||||
|
||||
private String dataSourceName = null;
|
||||
|
||||
private List<String> toContactNameList = null;
|
||||
private List<String> fromContactNameList = null;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
@ -146,4 +150,28 @@ final class CallLogViewData {
|
||||
this.localAccountId = localAccountId;
|
||||
}
|
||||
|
||||
public void setToContactNameList(List<String> contactNameList) {
|
||||
if (contactNameList != null) {
|
||||
this.toContactNameList = new ArrayList<>(contactNameList);
|
||||
} else {
|
||||
this.toContactNameList = new ArrayList<>();
|
||||
}
|
||||
}
|
||||
|
||||
public List<String> getToContactNameList() {
|
||||
return Collections.unmodifiableList(this.toContactNameList);
|
||||
}
|
||||
|
||||
public void setFromContactNameList(List<String> contactNameList) {
|
||||
if (contactNameList != null) {
|
||||
this.fromContactNameList = new ArrayList<>(contactNameList);
|
||||
} else {
|
||||
this.fromContactNameList = new ArrayList<>();
|
||||
}
|
||||
}
|
||||
|
||||
public List<String> getFromContactNameList() {
|
||||
return Collections.unmodifiableList(this.fromContactNameList);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -429,6 +429,35 @@ final class CommunicationArtifactViewerHelper {
|
||||
return dataList;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a contact row to the panel.
|
||||
*
|
||||
* @param panel Panel to update.
|
||||
* @param gridbagLayout Layout to use.
|
||||
* @param constraints Constrains to use.
|
||||
* @param contactId Contact name to display.
|
||||
*
|
||||
* @return A JLabel with the contact information.
|
||||
*/
|
||||
@NbBundle.Messages({
|
||||
"#{0} - contact name",
|
||||
"CommunicationArtifactViewerHelper_contact_label=Contact: {0}",
|
||||
"CommunicationArtifactViewerHelper_contact_label_unknown=Unknown"
|
||||
})
|
||||
static JLabel addContactRow(JPanel panel, GridBagLayout gridbagLayout, GridBagConstraints constraints, String contactId) {
|
||||
// Increase the y value because we are not calling the addKey
|
||||
constraints.gridy++;
|
||||
//Don't change the origian constraints, just make a copy to modify
|
||||
GridBagConstraints indentedConstraints = (GridBagConstraints) constraints.clone();
|
||||
|
||||
// Add an indent to match persona labels
|
||||
indentedConstraints.insets = new java.awt.Insets(0, 2 * LEFT_INSET, 0, 0);
|
||||
|
||||
String contactInfo = Bundle.CommunicationArtifactViewerHelper_contact_label(contactId != null && !contactId.isEmpty() ? contactId : Bundle.CommunicationArtifactViewerHelper_contact_label_unknown());
|
||||
|
||||
return addValueAtCol(panel, gridbagLayout, indentedConstraints, contactInfo, 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Event handler for mouse click event. Attaches a 'Copy' menu item to right
|
||||
* click.
|
||||
|
@ -293,8 +293,6 @@ public class ContactArtifactViewer extends javax.swing.JPanel implements Artifac
|
||||
* @param contactPanelConstraints Layout constraints.
|
||||
*
|
||||
*/
|
||||
@NbBundle.Messages({
|
||||
"ContactArtifactViewer_plural_suffix=s",})
|
||||
private void updateContactMethodSection(List<BlackboardAttribute> sectionAttributesList, String sectionHeader, GridBagLayout contactPanelLayout, GridBagConstraints contactPanelConstraints) {
|
||||
|
||||
// If there are no attributes for this section, do nothing
|
||||
@ -302,11 +300,7 @@ public class ContactArtifactViewer extends javax.swing.JPanel implements Artifac
|
||||
return;
|
||||
}
|
||||
|
||||
String sectionHeaderString = sectionHeader;
|
||||
if (sectionAttributesList.size() > 1) {
|
||||
sectionHeaderString = sectionHeaderString.concat(Bundle.ContactArtifactViewer_plural_suffix());
|
||||
}
|
||||
CommunicationArtifactViewerHelper.addHeader(this, contactPanelLayout, contactPanelConstraints, sectionHeaderString);
|
||||
CommunicationArtifactViewerHelper.addHeader(this, contactPanelLayout, contactPanelConstraints, sectionHeader);
|
||||
for (BlackboardAttribute bba : sectionAttributesList) {
|
||||
CommunicationArtifactViewerHelper.addKey(this, contactPanelLayout, contactPanelConstraints, bba.getAttributeType().getDisplayName());
|
||||
CommunicationArtifactViewerHelper.addValue(this, contactPanelLayout, contactPanelConstraints, bba.getDisplayString());
|
||||
|
@ -16,7 +16,6 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.sleuthkit.autopsy.contentviewers.artifactviewers;
|
||||
|
||||
import java.awt.event.ActionEvent;
|
||||
@ -39,6 +38,7 @@ import javax.swing.SwingUtilities;
|
||||
import javax.swing.SwingWorker;
|
||||
import org.openide.util.NbBundle.Messages;
|
||||
import org.sleuthkit.autopsy.casemodule.Case;
|
||||
import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepository;
|
||||
import org.sleuthkit.autopsy.centralrepository.datamodel.Persona;
|
||||
import org.sleuthkit.autopsy.centralrepository.datamodel.PersonaAccount;
|
||||
import org.sleuthkit.autopsy.centralrepository.persona.PersonaDetailsDialog;
|
||||
@ -46,8 +46,10 @@ import org.sleuthkit.autopsy.centralrepository.persona.PersonaDetailsDialogCallb
|
||||
import org.sleuthkit.autopsy.centralrepository.persona.PersonaDetailsMode;
|
||||
import org.sleuthkit.autopsy.centralrepository.persona.PersonaDetailsPanel;
|
||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||
import org.sleuthkit.autopsy.guiutils.ContactCache;
|
||||
import org.sleuthkit.datamodel.Account;
|
||||
import org.sleuthkit.datamodel.BlackboardArtifact;
|
||||
import org.sleuthkit.datamodel.BlackboardAttribute;
|
||||
import org.sleuthkit.datamodel.CommunicationsManager;
|
||||
import org.sleuthkit.datamodel.TskCoreException;
|
||||
|
||||
@ -113,13 +115,24 @@ final class MessageAccountPanel extends JPanel {
|
||||
return new ArrayList<>();
|
||||
}
|
||||
|
||||
List<BlackboardArtifact> contactList = ContactCache.getContacts(account);
|
||||
BlackboardArtifact contact = null;
|
||||
|
||||
if (contactList != null && !contactList.isEmpty()) {
|
||||
contact = contactList.get(0);
|
||||
}
|
||||
|
||||
if (CentralRepository.isEnabled()) {
|
||||
Collection<PersonaAccount> personAccounts = PersonaAccount.getPersonaAccountsForAccount(account);
|
||||
if (personAccounts != null && !personAccounts.isEmpty()) {
|
||||
for (PersonaAccount personaAccount : PersonaAccount.getPersonaAccountsForAccount(account)) {
|
||||
dataList.add(new AccountContainer(account, personaAccount));
|
||||
dataList.add(new AccountContainer(account, personaAccount, contact));
|
||||
}
|
||||
} else {
|
||||
dataList.add(new AccountContainer(account, null));
|
||||
dataList.add(new AccountContainer(account, null, contact));
|
||||
}
|
||||
} else {
|
||||
dataList.add(new AccountContainer(account, null, contact));
|
||||
}
|
||||
}
|
||||
|
||||
@ -127,8 +140,7 @@ final class MessageAccountPanel extends JPanel {
|
||||
}
|
||||
|
||||
@Messages({
|
||||
"MessageAccountPanel_no_matches=No matches found.",
|
||||
})
|
||||
"MessageAccountPanel_no_matches=No matches found.",})
|
||||
@Override
|
||||
protected void done() {
|
||||
try {
|
||||
@ -199,6 +211,7 @@ final class MessageAccountPanel extends JPanel {
|
||||
for (AccountContainer o : data) {
|
||||
group.addGap(5)
|
||||
.addComponent(o.getAccountLabel())
|
||||
.addGroup(o.getContactLineVerticalGroup(layout))
|
||||
.addGroup(o.getPersonLineVerticalGroup(layout));
|
||||
}
|
||||
|
||||
@ -234,6 +247,7 @@ final class MessageAccountPanel extends JPanel {
|
||||
group.addGap(10);
|
||||
for (AccountContainer o : data) {
|
||||
pgroup.addGroup(o.getPersonaSequentialGroup(layout));
|
||||
pgroup.addGroup(o.getContactSequentialGroup(layout));
|
||||
}
|
||||
group.addGap(10)
|
||||
.addGroup(pgroup)
|
||||
@ -253,10 +267,13 @@ final class MessageAccountPanel extends JPanel {
|
||||
|
||||
private final Account account;
|
||||
private Persona persona = null;
|
||||
private final String contactName;
|
||||
|
||||
private JLabel accountLabel;
|
||||
private JLabel personaHeader;
|
||||
private JLabel personaDisplayName;
|
||||
private JLabel contactHeader;
|
||||
private JLabel contactDisplayName;
|
||||
private JButton button;
|
||||
|
||||
/**
|
||||
@ -265,16 +282,22 @@ final class MessageAccountPanel extends JPanel {
|
||||
* @param account
|
||||
* @param personaAccount
|
||||
*/
|
||||
AccountContainer(Account account, PersonaAccount personaAccount) {
|
||||
AccountContainer(Account account, PersonaAccount personaAccount, BlackboardArtifact contactArtifact) throws TskCoreException {
|
||||
if (contactArtifact != null && contactArtifact.getArtifactTypeID() != BlackboardArtifact.ARTIFACT_TYPE.TSK_CONTACT.getTypeID()) {
|
||||
throw new IllegalArgumentException("Failed to create AccountContainer object, passed in artifact was not a TSK_CONTACT");
|
||||
}
|
||||
|
||||
this.account = account;
|
||||
this.persona = personaAccount != null ? personaAccount.getPersona() : null;
|
||||
this.contactName = getNameFromContactArtifact(contactArtifact);
|
||||
}
|
||||
|
||||
@Messages({
|
||||
"MessageAccountPanel_persona_label=Persona:",
|
||||
"MessageAccountPanel_unknown_label=Unknown",
|
||||
"MessageAccountPanel_button_view_label=View",
|
||||
"MessageAccountPanel_button_create_label=Create"
|
||||
"MessageAccountPanel_button_create_label=Create",
|
||||
"MessageAccountPanel_contact_label=Contact:"
|
||||
})
|
||||
/**
|
||||
* Swing components will not be initialized until this method is called.
|
||||
@ -282,16 +305,29 @@ final class MessageAccountPanel extends JPanel {
|
||||
private void initalizeSwingControls() {
|
||||
accountLabel = new JLabel();
|
||||
personaHeader = new JLabel(Bundle.MessageAccountPanel_persona_label());
|
||||
contactHeader = new JLabel(Bundle.MessageAccountPanel_contact_label());
|
||||
personaDisplayName = new JLabel();
|
||||
contactDisplayName = new JLabel();
|
||||
button = new JButton();
|
||||
button.addActionListener(new PersonaButtonListener(this));
|
||||
|
||||
accountLabel.setText(account.getTypeSpecificID());
|
||||
|
||||
contactDisplayName.setText(contactName);
|
||||
personaDisplayName.setText(persona != null ? persona.getName() : Bundle.MessageAccountPanel_unknown_label());
|
||||
button.setText(persona != null ? Bundle.MessageAccountPanel_button_view_label() : Bundle.MessageAccountPanel_button_create_label());
|
||||
}
|
||||
|
||||
private String getNameFromContactArtifact(BlackboardArtifact contactArtifact) throws TskCoreException {
|
||||
if (contactArtifact != null) {
|
||||
BlackboardAttribute attribute = contactArtifact.getAttribute(new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_NAME));
|
||||
if (attribute != null) {
|
||||
return attribute.getValueString();
|
||||
}
|
||||
}
|
||||
|
||||
return Bundle.MessageAccountPanel_unknown_label();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a new persona for this object and update the controls.
|
||||
*
|
||||
@ -366,6 +402,17 @@ final class MessageAccountPanel extends JPanel {
|
||||
return group;
|
||||
}
|
||||
|
||||
private SequentialGroup getContactSequentialGroup(GroupLayout layout) {
|
||||
SequentialGroup group = layout.createSequentialGroup();
|
||||
|
||||
group
|
||||
.addComponent(contactHeader)
|
||||
.addPreferredGap(ComponentPlacement.RELATED)
|
||||
.addComponent(contactDisplayName);
|
||||
|
||||
return group;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates the vertical layout code for the persona line.
|
||||
*
|
||||
@ -379,6 +426,12 @@ final class MessageAccountPanel extends JPanel {
|
||||
.addComponent(personaDisplayName)
|
||||
.addComponent(button);
|
||||
}
|
||||
|
||||
private ParallelGroup getContactLineVerticalGroup(GroupLayout layout) {
|
||||
return layout.createParallelGroup(Alignment.BASELINE)
|
||||
.addComponent(contactHeader)
|
||||
.addComponent(contactDisplayName);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -447,11 +447,9 @@ public class MessageArtifactViewer extends javax.swing.JPanel implements Artifac
|
||||
resetComponent();
|
||||
}
|
||||
|
||||
msgbodyTabbedPane.setEnabledAt(ACCT_TAB_INDEX, CentralRepository.isEnabled());
|
||||
if(CentralRepository.isEnabled()) {
|
||||
msgbodyTabbedPane.setEnabledAt(ACCT_TAB_INDEX, true);
|
||||
accountsPanel.setArtifact(artifact);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the artifact associated with the given artifact, if there is one.
|
||||
|
@ -230,6 +230,7 @@ public class Installer extends ModuleInstall {
|
||||
packageInstallers.add(org.sleuthkit.autopsy.ingest.Installer.getDefault());
|
||||
packageInstallers.add(org.sleuthkit.autopsy.centralrepository.eventlisteners.Installer.getDefault());
|
||||
packageInstallers.add(org.sleuthkit.autopsy.healthmonitor.Installer.getDefault());
|
||||
packageInstallers.add(org.sleuthkit.autopsy.casemodule.Installer.getDefault());
|
||||
|
||||
/**
|
||||
* This is a temporary workaround for the following bug in Tika that
|
||||
|
@ -26,6 +26,7 @@ import java.util.prefs.PreferenceChangeListener;
|
||||
import java.util.prefs.Preferences;
|
||||
import org.openide.util.NbPreferences;
|
||||
import org.python.icu.util.TimeZone;
|
||||
import org.sleuthkit.autopsy.machinesettings.UserMachinePreferences;
|
||||
import org.sleuthkit.autopsy.coreutils.ModuleSettings;
|
||||
import org.sleuthkit.autopsy.coreutils.TextConverterException;
|
||||
import org.sleuthkit.autopsy.coreutils.Version;
|
||||
@ -612,4 +613,14 @@ public final class UserPreferences {
|
||||
public static String getGeolocationMBTilesFilePath() {
|
||||
return preferences.get(GEO_MBTILES_FILE_PATH, "");
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the root application temp directory.
|
||||
*
|
||||
* @return The absolute path to the application temp directory.
|
||||
*/
|
||||
public static String getAppTempDirectory() {
|
||||
return Paths.get(UserMachinePreferences.getBaseTempDirectory(), getAppName())
|
||||
.toAbsolutePath().toString();
|
||||
}
|
||||
}
|
||||
|
@ -11,7 +11,7 @@
|
||||
</NonVisualComponents>
|
||||
<Properties>
|
||||
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||
<Dimension value="[1022, 488]"/>
|
||||
<Dimension value="null"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<AuxValues>
|
||||
@ -29,15 +29,12 @@
|
||||
<Layout>
|
||||
<DimensionLayout dim="0">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Component id="jScrollPane1" alignment="0" max="32767" attributes="0"/>
|
||||
<Component id="jScrollPane1" alignment="0" pref="648" max="32767" attributes="0"/>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
<DimensionLayout dim="1">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Group type="102" alignment="0" attributes="0">
|
||||
<Component id="jScrollPane1" max="32767" attributes="0"/>
|
||||
<EmptySpace min="0" pref="0" max="32767" attributes="0"/>
|
||||
</Group>
|
||||
<Component id="jScrollPane1" alignment="0" pref="382" max="32767" attributes="0"/>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
</Layout>
|
||||
@ -48,7 +45,7 @@
|
||||
<Border info="null"/>
|
||||
</Property>
|
||||
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||
<Dimension value="[1022, 407]"/>
|
||||
<Dimension value="null"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
|
||||
@ -56,21 +53,24 @@
|
||||
<SubComponents>
|
||||
<Container class="javax.swing.JPanel" name="jPanel1">
|
||||
<Properties>
|
||||
<Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||
<Dimension value="[648, 382]"/>
|
||||
</Property>
|
||||
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||
<Dimension value="[1022, 407]"/>
|
||||
<Dimension value="null"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
|
||||
<Layout>
|
||||
<DimensionLayout dim="0">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Group type="102" attributes="0">
|
||||
<Group type="102" alignment="0" attributes="0">
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Component id="runtimePanel" max="32767" attributes="0"/>
|
||||
<Component id="logoPanel" alignment="0" pref="1002" max="32767" attributes="0"/>
|
||||
<Group type="103" groupAlignment="1" max="-2" attributes="0">
|
||||
<Component id="logoPanel" max="32767" attributes="0"/>
|
||||
<Component id="tempDirectoryPanel" alignment="0" max="32767" attributes="0"/>
|
||||
<Component id="runtimePanel" min="-2" pref="631" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
@ -79,9 +79,11 @@
|
||||
<Group type="102" alignment="0" attributes="0">
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="runtimePanel" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace type="unrelated" max="-2" attributes="0"/>
|
||||
<EmptySpace min="-2" pref="3" max="-2" attributes="0"/>
|
||||
<Component id="tempDirectoryPanel" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="logoPanel" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace pref="171" max="32767" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
@ -96,9 +98,6 @@
|
||||
</TitledBorder>
|
||||
</Border>
|
||||
</Property>
|
||||
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||
<Dimension value="[533, 87]"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
|
||||
<Layout>
|
||||
@ -112,16 +111,16 @@
|
||||
</Group>
|
||||
<EmptySpace type="unrelated" max="-2" attributes="0"/>
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Component id="agencyLogoPathFieldValidationLabel" min="-2" max="-2" attributes="0"/>
|
||||
<Group type="102" attributes="0">
|
||||
<Component id="agencyLogoPathField" min="-2" pref="259" max="-2" attributes="0"/>
|
||||
<Component id="agencyLogoPathField" min="-2" pref="270" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="browseLogosButton" min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<Component id="agencyLogoPathFieldValidationLabel" min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<EmptySpace type="unrelated" max="-2" attributes="0"/>
|
||||
<Component id="agencyLogoPreview" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace pref="456" max="32767" attributes="0"/>
|
||||
<EmptySpace max="32767" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
@ -142,7 +141,7 @@
|
||||
</Group>
|
||||
<Group type="102" alignment="1" attributes="0">
|
||||
<Component id="agencyLogoPreview" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace min="0" pref="0" max="32767" attributes="0"/>
|
||||
<EmptySpace min="0" pref="12" max="32767" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
@ -266,18 +265,18 @@
|
||||
<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="246" max="32767" attributes="0"/>
|
||||
<EmptySpace max="32767" attributes="0"/>
|
||||
</Group>
|
||||
<Group type="102" alignment="0" attributes="0">
|
||||
<EmptySpace min="-2" pref="18" max="-2" attributes="0"/>
|
||||
<Component id="solrJVMHeapWarning" pref="717" max="32767" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="solrJVMHeapWarning" min="-2" pref="331" max="-2" attributes="0"/>
|
||||
<EmptySpace min="-2" pref="44" max="-2" attributes="0"/>
|
||||
<Component id="logNumAlert" max="32767" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
</Group>
|
||||
<Component id="restartNecessaryWarning" alignment="0" pref="994" max="32767" attributes="0"/>
|
||||
<Component id="restartNecessaryWarning" alignment="0" min="-2" pref="615" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
</Group>
|
||||
@ -317,7 +316,7 @@
|
||||
</Group>
|
||||
<EmptySpace type="unrelated" max="-2" attributes="0"/>
|
||||
<Component id="restartNecessaryWarning" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace max="32767" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
@ -438,6 +437,87 @@
|
||||
</Component>
|
||||
</SubComponents>
|
||||
</Container>
|
||||
<Container class="javax.swing.JPanel" name="tempDirectoryPanel">
|
||||
<Properties>
|
||||
<Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor">
|
||||
<Border info="org.netbeans.modules.form.compat2.border.TitledBorderInfo">
|
||||
<TitledBorder title="Temp Directory">
|
||||
<ResourceString PropertyName="titleX" bundle="org/sleuthkit/autopsy/corecomponents/Bundle.properties" key="AutopsyOptionsPanel.tempDirectoryPanel.border.title" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</TitledBorder>
|
||||
</Border>
|
||||
</Property>
|
||||
<Property name="name" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/corecomponents/Bundle.properties" key="AutopsyOptionsPanel.tempDirectoryPanel.name" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<AccessibilityProperties>
|
||||
<Property name="AccessibleContext.accessibleName" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/corecomponents/Bundle.properties" key="AutopsyOptionsPanel.tempDirectoryPanel.AccessibleContext.accessibleName" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
</AccessibilityProperties>
|
||||
|
||||
<Layout>
|
||||
<DimensionLayout dim="0">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Group type="102" attributes="0">
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Component id="tempDirectoryWarningLabel" min="-2" pref="615" max="-2" attributes="0"/>
|
||||
<Group type="102" attributes="0">
|
||||
<Component id="tempDirectoryField" min="-2" pref="367" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="tempDirectoryBrowseButton" min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
<EmptySpace min="0" pref="0" max="32767" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
<DimensionLayout dim="1">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Group type="102" alignment="0" attributes="0">
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Group type="103" groupAlignment="3" attributes="0">
|
||||
<Component id="tempDirectoryField" alignment="3" max="32767" attributes="0"/>
|
||||
<Component id="tempDirectoryBrowseButton" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<EmptySpace type="separate" max="-2" attributes="0"/>
|
||||
<Component id="tempDirectoryWarningLabel" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
</Layout>
|
||||
<SubComponents>
|
||||
<Component class="javax.swing.JTextField" name="tempDirectoryField">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/corecomponents/Bundle.properties" key="AutopsyOptionsPanel.tempDirectoryField.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
</Component>
|
||||
<Component class="javax.swing.JButton" name="tempDirectoryBrowseButton">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/corecomponents/Bundle.properties" key="AutopsyOptionsPanel.tempDirectoryBrowseButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<Events>
|
||||
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="tempDirectoryBrowseButtonActionPerformed"/>
|
||||
</Events>
|
||||
</Component>
|
||||
<Component class="javax.swing.JLabel" name="tempDirectoryWarningLabel">
|
||||
<Properties>
|
||||
<Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor">
|
||||
<Image iconType="3" name="/org/sleuthkit/autopsy/corecomponents/warning16.png"/>
|
||||
</Property>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/corecomponents/Bundle.properties" key="AutopsyOptionsPanel.tempDirectoryWarningLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
</Component>
|
||||
</SubComponents>
|
||||
</Container>
|
||||
</SubComponents>
|
||||
</Container>
|
||||
</SubComponents>
|
||||
|
@ -24,6 +24,7 @@ import java.io.IOException;
|
||||
import java.lang.management.ManagementFactory;
|
||||
import java.nio.charset.Charset;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.InvalidPathException;
|
||||
import java.nio.file.Path;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
@ -34,13 +35,17 @@ import javax.imageio.ImageIO;
|
||||
import javax.swing.ImageIcon;
|
||||
import javax.swing.JFileChooser;
|
||||
import javax.swing.JOptionPane;
|
||||
import javax.swing.SwingUtilities;
|
||||
import javax.swing.event.DocumentEvent;
|
||||
import javax.swing.event.DocumentListener;
|
||||
import org.netbeans.spi.options.OptionsPanelController;
|
||||
import org.openide.util.NbBundle;
|
||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||
import org.openide.util.NbBundle.Messages;
|
||||
import org.sleuthkit.autopsy.casemodule.Case;
|
||||
import org.sleuthkit.autopsy.casemodule.GeneralFilter;
|
||||
import org.sleuthkit.autopsy.machinesettings.UserMachinePreferences;
|
||||
import org.sleuthkit.autopsy.machinesettings.UserMachinePreferencesException;
|
||||
import org.sleuthkit.autopsy.core.UserPreferences;
|
||||
import org.sleuthkit.autopsy.coreutils.ModuleSettings;
|
||||
import org.sleuthkit.autopsy.coreutils.PlatformUtil;
|
||||
@ -70,7 +75,8 @@ import org.sleuthkit.autopsy.report.ReportBranding;
|
||||
final class AutopsyOptionsPanel extends javax.swing.JPanel {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
private final JFileChooser fileChooser;
|
||||
private final JFileChooser logoFileChooser;
|
||||
private final JFileChooser tempDirChooser;
|
||||
private final TextFieldListener textFieldListener;
|
||||
private static final String ETC_FOLDER_NAME = "etc";
|
||||
private static final String CONFIG_FILE_EXTENSION = ".conf";
|
||||
@ -85,11 +91,16 @@ final class AutopsyOptionsPanel extends javax.swing.JPanel {
|
||||
*/
|
||||
AutopsyOptionsPanel() {
|
||||
initComponents();
|
||||
fileChooser = new JFileChooser();
|
||||
fileChooser.setFileSelectionMode(JFileChooser.FILES_ONLY);
|
||||
fileChooser.setMultiSelectionEnabled(false);
|
||||
fileChooser.setAcceptAllFileFilterUsed(false);
|
||||
fileChooser.setFileFilter(new GeneralFilter(GeneralFilter.GRAPHIC_IMAGE_EXTS, GeneralFilter.GRAPHIC_IMG_DECR));
|
||||
logoFileChooser = new JFileChooser();
|
||||
logoFileChooser.setFileSelectionMode(JFileChooser.FILES_ONLY);
|
||||
logoFileChooser.setMultiSelectionEnabled(false);
|
||||
logoFileChooser.setAcceptAllFileFilterUsed(false);
|
||||
logoFileChooser.setFileFilter(new GeneralFilter(GeneralFilter.GRAPHIC_IMAGE_EXTS, GeneralFilter.GRAPHIC_IMG_DECR));
|
||||
|
||||
tempDirChooser = new JFileChooser();
|
||||
tempDirChooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
|
||||
tempDirChooser.setMultiSelectionEnabled(false);
|
||||
|
||||
if (!PlatformUtil.is64BitJVM() || Version.getBuildType() == Version.Type.DEVELOPMENT) {
|
||||
//32 bit JVM has a max heap size of 1.4 gb to 4 gb depending on OS
|
||||
//So disabling the setting of heap size when the JVM is not 64 bit
|
||||
@ -106,6 +117,7 @@ final class AutopsyOptionsPanel extends javax.swing.JPanel {
|
||||
|
||||
textFieldListener = new TextFieldListener();
|
||||
agencyLogoPathField.getDocument().addDocumentListener(textFieldListener);
|
||||
tempDirectoryField.getDocument().addDocumentListener(textFieldListener);
|
||||
logFileCount.setText(String.valueOf(UserPreferences.getLogFileCount()));
|
||||
}
|
||||
|
||||
@ -296,8 +308,10 @@ final class AutopsyOptionsPanel extends javax.swing.JPanel {
|
||||
specifyLogoRB.setSelected(!useDefault);
|
||||
agencyLogoPathField.setEnabled(!useDefault);
|
||||
browseLogosButton.setEnabled(!useDefault);
|
||||
tempDirectoryField.setText(UserMachinePreferences.getBaseTempDirectory());
|
||||
logFileCount.setText(String.valueOf(UserPreferences.getLogFileCount()));
|
||||
solrMaxHeapSpinner.setValue(UserPreferences.getMaxSolrVMSize());
|
||||
tempDirectoryField.setText(UserMachinePreferences.getBaseTempDirectory());
|
||||
try {
|
||||
updateAgencyLogo(path);
|
||||
} catch (IOException ex) {
|
||||
@ -312,10 +326,17 @@ final class AutopsyOptionsPanel extends javax.swing.JPanel {
|
||||
}
|
||||
memField.setText(initialMemValue);
|
||||
}
|
||||
|
||||
setTempDirEnabled();
|
||||
valid(); //ensure the error messages are up to date
|
||||
}
|
||||
|
||||
private void setTempDirEnabled() {
|
||||
boolean enabled = !Case.isCaseOpen();
|
||||
this.tempDirectoryBrowseButton.setEnabled(enabled);
|
||||
this.tempDirectoryField.setEnabled(enabled);
|
||||
this.tempDirectoryWarningLabel.setVisible(!enabled);
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the agency logo with the image specified by the path.
|
||||
*
|
||||
@ -342,11 +363,34 @@ final class AutopsyOptionsPanel extends javax.swing.JPanel {
|
||||
agencyLogoPreview.repaint();
|
||||
}
|
||||
|
||||
@Messages({
|
||||
"AutopsyOptionsPanel_storeTempDir_onError_title=Error Saving Temporary Directory",
|
||||
"# {0} - path",
|
||||
"AutopsyOptionsPanel_storeTempDir_onError_description=There was an error creating the temporary directory on the filesystem at: {0}.",})
|
||||
private void storeTempDir() {
|
||||
String tempDirectoryPath = tempDirectoryField.getText();
|
||||
if (!UserMachinePreferences.getBaseTempDirectory().equals(tempDirectoryPath)) {
|
||||
try {
|
||||
UserMachinePreferences.setBaseTempDirectory(tempDirectoryPath);
|
||||
} catch (UserMachinePreferencesException ex) {
|
||||
logger.log(Level.WARNING, "There was an error creating the temporary directory defined by the user: " + tempDirectoryPath, ex);
|
||||
SwingUtilities.invokeLater(() -> {
|
||||
JOptionPane.showMessageDialog(this,
|
||||
String.format("<html>%s</html>", Bundle.AutopsyOptionsPanel_storeTempDir_onError_description(tempDirectoryPath)),
|
||||
Bundle.AutopsyOptionsPanel_storeTempDir_onError_title(),
|
||||
JOptionPane.ERROR_MESSAGE);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Store the current user preferences.
|
||||
*/
|
||||
void store() {
|
||||
UserPreferences.setLogFileCount(Integer.parseInt(logFileCount.getText()));
|
||||
storeTempDir();
|
||||
|
||||
if (!agencyLogoPathField.getText().isEmpty()) {
|
||||
File file = new File(agencyLogoPathField.getText());
|
||||
if (file.exists()) {
|
||||
@ -372,7 +416,6 @@ final class AutopsyOptionsPanel extends javax.swing.JPanel {
|
||||
*/
|
||||
boolean valid() {
|
||||
boolean valid = true;
|
||||
|
||||
if (!isAgencyLogoPathValid()) {
|
||||
valid = false;
|
||||
}
|
||||
@ -484,6 +527,7 @@ final class AutopsyOptionsPanel extends javax.swing.JPanel {
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Listens for registered text fields that have changed and fires a
|
||||
* PropertyChangeEvent accordingly.
|
||||
@ -542,16 +586,20 @@ final class AutopsyOptionsPanel extends javax.swing.JPanel {
|
||||
maxMemoryUnitsLabel2 = new javax.swing.JLabel();
|
||||
solrMaxHeapSpinner = new javax.swing.JSpinner();
|
||||
solrJVMHeapWarning = new javax.swing.JLabel();
|
||||
tempDirectoryPanel = new javax.swing.JPanel();
|
||||
tempDirectoryField = new javax.swing.JTextField();
|
||||
tempDirectoryBrowseButton = new javax.swing.JButton();
|
||||
tempDirectoryWarningLabel = new javax.swing.JLabel();
|
||||
|
||||
setPreferredSize(new java.awt.Dimension(1022, 488));
|
||||
setPreferredSize(null);
|
||||
|
||||
jScrollPane1.setBorder(null);
|
||||
jScrollPane1.setPreferredSize(new java.awt.Dimension(1022, 407));
|
||||
jScrollPane1.setPreferredSize(null);
|
||||
|
||||
jPanel1.setPreferredSize(new java.awt.Dimension(1022, 407));
|
||||
jPanel1.setMinimumSize(new java.awt.Dimension(648, 382));
|
||||
jPanel1.setPreferredSize(null);
|
||||
|
||||
logoPanel.setBorder(javax.swing.BorderFactory.createTitledBorder(org.openide.util.NbBundle.getMessage(AutopsyOptionsPanel.class, "AutopsyOptionsPanel.logoPanel.border.title"))); // NOI18N
|
||||
logoPanel.setPreferredSize(new java.awt.Dimension(533, 87));
|
||||
|
||||
agencyLogoPathField.setText(org.openide.util.NbBundle.getMessage(AutopsyOptionsPanel.class, "AutopsyOptionsPanel.agencyLogoPathField.text")); // NOI18N
|
||||
|
||||
@ -599,14 +647,14 @@ final class AutopsyOptionsPanel extends javax.swing.JPanel {
|
||||
.addComponent(defaultLogoRB))
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
|
||||
.addGroup(logoPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addComponent(agencyLogoPathFieldValidationLabel)
|
||||
.addGroup(logoPanelLayout.createSequentialGroup()
|
||||
.addComponent(agencyLogoPathField, javax.swing.GroupLayout.PREFERRED_SIZE, 259, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||
.addComponent(agencyLogoPathField, javax.swing.GroupLayout.PREFERRED_SIZE, 270, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(browseLogosButton))
|
||||
.addComponent(agencyLogoPathFieldValidationLabel))
|
||||
.addComponent(browseLogosButton)))
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
|
||||
.addComponent(agencyLogoPreview, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||
.addContainerGap(456, Short.MAX_VALUE))
|
||||
.addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
|
||||
);
|
||||
logoPanelLayout.setVerticalGroup(
|
||||
logoPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
@ -622,7 +670,7 @@ final class AutopsyOptionsPanel extends javax.swing.JPanel {
|
||||
.addComponent(browseLogosButton)))
|
||||
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, logoPanelLayout.createSequentialGroup()
|
||||
.addComponent(agencyLogoPreview, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||
.addGap(0, 0, Short.MAX_VALUE))
|
||||
.addGap(0, 12, Short.MAX_VALUE))
|
||||
);
|
||||
|
||||
runtimePanel.setBorder(javax.swing.BorderFactory.createTitledBorder(org.openide.util.NbBundle.getMessage(AutopsyOptionsPanel.class, "AutopsyOptionsPanel.runtimePanel.border.title"))); // NOI18N
|
||||
@ -703,14 +751,14 @@ 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(246, Short.MAX_VALUE))
|
||||
.addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
|
||||
.addGroup(runtimePanelLayout.createSequentialGroup()
|
||||
.addGap(18, 18, 18)
|
||||
.addComponent(solrJVMHeapWarning, javax.swing.GroupLayout.DEFAULT_SIZE, 717, Short.MAX_VALUE)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(solrJVMHeapWarning, javax.swing.GroupLayout.PREFERRED_SIZE, 331, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||
.addGap(44, 44, 44)
|
||||
.addComponent(logNumAlert)
|
||||
.addContainerGap())))
|
||||
.addComponent(restartNecessaryWarning, javax.swing.GroupLayout.DEFAULT_SIZE, 994, Short.MAX_VALUE)))
|
||||
.addComponent(restartNecessaryWarning, javax.swing.GroupLayout.PREFERRED_SIZE, 615, javax.swing.GroupLayout.PREFERRED_SIZE)))
|
||||
);
|
||||
|
||||
runtimePanelLayout.linkSize(javax.swing.SwingConstants.HORIZONTAL, new java.awt.Component[] {maxLogFileCount, maxMemoryLabel, totalMemoryLabel});
|
||||
@ -746,7 +794,48 @@ final class AutopsyOptionsPanel extends javax.swing.JPanel {
|
||||
.addComponent(logFileCount, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
|
||||
.addComponent(restartNecessaryWarning)
|
||||
.addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
|
||||
.addContainerGap())
|
||||
);
|
||||
|
||||
tempDirectoryPanel.setBorder(javax.swing.BorderFactory.createTitledBorder(org.openide.util.NbBundle.getMessage(AutopsyOptionsPanel.class, "AutopsyOptionsPanel.tempDirectoryPanel.border.title"))); // NOI18N
|
||||
tempDirectoryPanel.setName(org.openide.util.NbBundle.getMessage(AutopsyOptionsPanel.class, "AutopsyOptionsPanel.tempDirectoryPanel.name")); // NOI18N
|
||||
|
||||
tempDirectoryField.setText(org.openide.util.NbBundle.getMessage(AutopsyOptionsPanel.class, "AutopsyOptionsPanel.tempDirectoryField.text")); // NOI18N
|
||||
|
||||
org.openide.awt.Mnemonics.setLocalizedText(tempDirectoryBrowseButton, org.openide.util.NbBundle.getMessage(AutopsyOptionsPanel.class, "AutopsyOptionsPanel.tempDirectoryBrowseButton.text")); // NOI18N
|
||||
tempDirectoryBrowseButton.addActionListener(new java.awt.event.ActionListener() {
|
||||
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||
tempDirectoryBrowseButtonActionPerformed(evt);
|
||||
}
|
||||
});
|
||||
|
||||
tempDirectoryWarningLabel.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/corecomponents/warning16.png"))); // NOI18N
|
||||
org.openide.awt.Mnemonics.setLocalizedText(tempDirectoryWarningLabel, org.openide.util.NbBundle.getMessage(AutopsyOptionsPanel.class, "AutopsyOptionsPanel.tempDirectoryWarningLabel.text")); // NOI18N
|
||||
|
||||
javax.swing.GroupLayout tempDirectoryPanelLayout = new javax.swing.GroupLayout(tempDirectoryPanel);
|
||||
tempDirectoryPanel.setLayout(tempDirectoryPanelLayout);
|
||||
tempDirectoryPanelLayout.setHorizontalGroup(
|
||||
tempDirectoryPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGroup(tempDirectoryPanelLayout.createSequentialGroup()
|
||||
.addContainerGap()
|
||||
.addGroup(tempDirectoryPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addComponent(tempDirectoryWarningLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 615, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||
.addGroup(tempDirectoryPanelLayout.createSequentialGroup()
|
||||
.addComponent(tempDirectoryField, javax.swing.GroupLayout.PREFERRED_SIZE, 367, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(tempDirectoryBrowseButton)))
|
||||
.addGap(0, 0, Short.MAX_VALUE))
|
||||
);
|
||||
tempDirectoryPanelLayout.setVerticalGroup(
|
||||
tempDirectoryPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGroup(tempDirectoryPanelLayout.createSequentialGroup()
|
||||
.addContainerGap()
|
||||
.addGroup(tempDirectoryPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
|
||||
.addComponent(tempDirectoryField)
|
||||
.addComponent(tempDirectoryBrowseButton))
|
||||
.addGap(18, 18, 18)
|
||||
.addComponent(tempDirectoryWarningLabel)
|
||||
.addContainerGap())
|
||||
);
|
||||
|
||||
javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1);
|
||||
@ -755,54 +844,63 @@ final class AutopsyOptionsPanel extends javax.swing.JPanel {
|
||||
jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGroup(jPanel1Layout.createSequentialGroup()
|
||||
.addContainerGap()
|
||||
.addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addComponent(runtimePanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
||||
.addComponent(logoPanel, javax.swing.GroupLayout.DEFAULT_SIZE, 1002, Short.MAX_VALUE))
|
||||
.addContainerGap())
|
||||
.addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING, false)
|
||||
.addComponent(logoPanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
||||
.addComponent(tempDirectoryPanel, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
||||
.addComponent(runtimePanel, javax.swing.GroupLayout.PREFERRED_SIZE, 631, javax.swing.GroupLayout.PREFERRED_SIZE)))
|
||||
);
|
||||
jPanel1Layout.setVerticalGroup(
|
||||
jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGroup(jPanel1Layout.createSequentialGroup()
|
||||
.addContainerGap()
|
||||
.addComponent(runtimePanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
|
||||
.addGap(3, 3, 3)
|
||||
.addComponent(tempDirectoryPanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(logoPanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||
.addContainerGap(171, Short.MAX_VALUE))
|
||||
.addContainerGap())
|
||||
);
|
||||
|
||||
tempDirectoryPanel.getAccessibleContext().setAccessibleName(org.openide.util.NbBundle.getMessage(AutopsyOptionsPanel.class, "AutopsyOptionsPanel.tempDirectoryPanel.AccessibleContext.accessibleName")); // NOI18N
|
||||
|
||||
jScrollPane1.setViewportView(jPanel1);
|
||||
|
||||
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
|
||||
this.setLayout(layout);
|
||||
layout.setHorizontalGroup(
|
||||
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
||||
.addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 648, Short.MAX_VALUE)
|
||||
);
|
||||
layout.setVerticalGroup(
|
||||
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGroup(layout.createSequentialGroup()
|
||||
.addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
||||
.addGap(0, 0, Short.MAX_VALUE))
|
||||
.addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 382, Short.MAX_VALUE)
|
||||
);
|
||||
}// </editor-fold>//GEN-END:initComponents
|
||||
|
||||
private void logFileCountKeyReleased(java.awt.event.KeyEvent evt) {//GEN-FIRST:event_logFileCountKeyReleased
|
||||
String count = logFileCount.getText();
|
||||
if (count.equals(String.valueOf(UserPreferences.getDefaultLogFileCount()))) {
|
||||
//if it is still the default value don't fire change
|
||||
return;
|
||||
@Messages({
|
||||
"AutopsyOptionsPanel_tempDirectoryBrowseButtonActionPerformed_onInvalidPath_title=Path cannot be used",
|
||||
"# {0} - path",
|
||||
"AutopsyOptionsPanel_tempDirectoryBrowseButtonActionPerformed_onInvalidPath_description=Unable to create temporary directory within specified path: {0}",})
|
||||
private void tempDirectoryBrowseButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_tempDirectoryBrowseButtonActionPerformed
|
||||
int returnState = tempDirChooser.showOpenDialog(this);
|
||||
if (returnState == JFileChooser.APPROVE_OPTION) {
|
||||
String specifiedPath = tempDirChooser.getSelectedFile().getPath();
|
||||
try {
|
||||
File f = new File(specifiedPath);
|
||||
if (!f.exists() && !f.mkdirs()) {
|
||||
throw new InvalidPathException(specifiedPath, "Unable to create parent directories leading to " + specifiedPath);
|
||||
}
|
||||
tempDirectoryField.setText(specifiedPath);
|
||||
firePropertyChange(OptionsPanelController.PROP_CHANGED, null, null);
|
||||
}//GEN-LAST:event_logFileCountKeyReleased
|
||||
|
||||
private void memFieldKeyReleased(java.awt.event.KeyEvent evt) {//GEN-FIRST:event_memFieldKeyReleased
|
||||
String memText = memField.getText();
|
||||
if (memText.equals(initialMemValue)) {
|
||||
//if it is still the initial value don't fire change
|
||||
return;
|
||||
} catch (InvalidPathException ex) {
|
||||
logger.log(Level.WARNING, "Unable to create temporary directory in " + specifiedPath, ex);
|
||||
JOptionPane.showMessageDialog(this,
|
||||
Bundle.AutopsyOptionsPanel_tempDirectoryBrowseButtonActionPerformed_onInvalidPath_description(specifiedPath),
|
||||
Bundle.AutopsyOptionsPanel_tempDirectoryBrowseButtonActionPerformed_onInvalidPath_title(),
|
||||
JOptionPane.ERROR_MESSAGE);
|
||||
}
|
||||
firePropertyChange(OptionsPanelController.PROP_CHANGED, null, null);
|
||||
}//GEN-LAST:event_memFieldKeyReleased
|
||||
}
|
||||
}//GEN-LAST:event_tempDirectoryBrowseButtonActionPerformed
|
||||
|
||||
private void specifyLogoRBActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_specifyLogoRBActionPerformed
|
||||
agencyLogoPathField.setEnabled(true);
|
||||
@ -834,9 +932,9 @@ final class AutopsyOptionsPanel extends javax.swing.JPanel {
|
||||
|
||||
private void browseLogosButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_browseLogosButtonActionPerformed
|
||||
String oldLogoPath = agencyLogoPathField.getText();
|
||||
int returnState = fileChooser.showOpenDialog(this);
|
||||
int returnState = logoFileChooser.showOpenDialog(this);
|
||||
if (returnState == JFileChooser.APPROVE_OPTION) {
|
||||
String path = fileChooser.getSelectedFile().getPath();
|
||||
String path = logoFileChooser.getSelectedFile().getPath();
|
||||
try {
|
||||
updateAgencyLogo(path);
|
||||
firePropertyChange(OptionsPanelController.PROP_CHANGED, null, null);
|
||||
@ -864,6 +962,24 @@ final class AutopsyOptionsPanel extends javax.swing.JPanel {
|
||||
firePropertyChange(OptionsPanelController.PROP_CHANGED, null, null);
|
||||
}//GEN-LAST:event_solrMaxHeapSpinnerStateChanged
|
||||
|
||||
private void logFileCountKeyReleased(java.awt.event.KeyEvent evt) {//GEN-FIRST:event_logFileCountKeyReleased
|
||||
String count = logFileCount.getText();
|
||||
if (count.equals(String.valueOf(UserPreferences.getDefaultLogFileCount()))) {
|
||||
//if it is still the default value don't fire change
|
||||
return;
|
||||
}
|
||||
firePropertyChange(OptionsPanelController.PROP_CHANGED, null, null);
|
||||
}//GEN-LAST:event_logFileCountKeyReleased
|
||||
|
||||
private void memFieldKeyReleased(java.awt.event.KeyEvent evt) {//GEN-FIRST:event_memFieldKeyReleased
|
||||
String memText = memField.getText();
|
||||
if (memText.equals(initialMemValue)) {
|
||||
//if it is still the initial value don't fire change
|
||||
return;
|
||||
}
|
||||
firePropertyChange(OptionsPanelController.PROP_CHANGED, null, null);
|
||||
}//GEN-LAST:event_memFieldKeyReleased
|
||||
|
||||
// Variables declaration - do not modify//GEN-BEGIN:variables
|
||||
private javax.swing.JTextField agencyLogoPathField;
|
||||
private javax.swing.JLabel agencyLogoPathFieldValidationLabel;
|
||||
@ -892,6 +1008,10 @@ final class AutopsyOptionsPanel extends javax.swing.JPanel {
|
||||
private javax.swing.JSpinner solrMaxHeapSpinner;
|
||||
private javax.swing.JRadioButton specifyLogoRB;
|
||||
private javax.swing.JLabel systemMemoryTotal;
|
||||
private javax.swing.JButton tempDirectoryBrowseButton;
|
||||
private javax.swing.JTextField tempDirectoryField;
|
||||
private javax.swing.JPanel tempDirectoryPanel;
|
||||
private javax.swing.JLabel tempDirectoryWarningLabel;
|
||||
private javax.swing.JLabel totalMemoryLabel;
|
||||
// End of variables declaration//GEN-END:variables
|
||||
|
||||
|
@ -120,26 +120,12 @@ MultiUserSettingsPanel.lbTestDbWarning.text=
|
||||
MultiUserSettingsPanel.KeywordSearchNull=Cannot find keyword search service
|
||||
MultiUserSettingsPanel.InvalidPortNumber=Invalid port number
|
||||
AutopsyOptionsPanel.agencyLogoImageLabel.toolTipText=
|
||||
AutopsyOptionsPanel.agencyLogoPathField.text=
|
||||
SortChooserDialog.label=remove
|
||||
SortChooser.addCriteriaButton.text=Add Sort Criteria
|
||||
DataResultViewerThumbnail.sortButton.text=Sort
|
||||
CriterionChooser.ascendingRadio.text=\u25b2 Ascending\n
|
||||
CriterionChooser.removeButton.text=Remove
|
||||
CriterionChooser.descendingRadio.text=\u25bc Descending
|
||||
AutopsyOptionsPanel.agencyLogoPathFieldValidationLabel.text=
|
||||
AutopsyOptionsPanel.logNumAlert.text=
|
||||
AutopsyOptionsPanel.totalMemoryLabel.text=Total System Memory:
|
||||
AutopsyOptionsPanel.maxMemoryLabel.text=Maximum JVM Memory:
|
||||
AutopsyOptionsPanel.maxLogFileCount.text=Maximum Log Files:
|
||||
AutopsyOptionsPanel.maxMemoryUnitsLabel.text=GB
|
||||
AutopsyOptionsPanel.restartNecessaryWarning.text=A restart is necessary for any memory changes to take effect.
|
||||
AutopsyOptionsPanel.browseLogosButton.text=Browse
|
||||
AutopsyOptionsPanel.defaultLogoRB.text=Use default
|
||||
AutopsyOptionsPanel.specifyLogoRB.text=Specify a logo
|
||||
AutopsyOptionsPanel.agencyLogoPreview.text=<html><div style='text-align: center;'>No logo<br>selected</div></html>
|
||||
AutopsyOptionsPanel.logoPanel.border.title=Logo
|
||||
AutopsyOptionsPanel.runtimePanel.border.title=Runtime
|
||||
DataResultPanel.matchLabel.text=Results
|
||||
DataResultPanel.numberOfChildNodesLabel.text=0
|
||||
DataResultPanel.descriptionLabel.text=directoryPath
|
||||
@ -199,9 +185,6 @@ ExternalViewerGlobalSettingsPanel.deleteRuleButton.text_1=Delete Rule
|
||||
ExternalViewerGlobalSettingsPanel.externalViewerTitleLabel.text_1=Set aplication viewer to use for files with specific mime types/extensions:
|
||||
ExternalViewerGlobalSettingsPanel.jTable1.columnModel.title1_1=Application
|
||||
ExternalViewerGlobalSettingsPanel.jTable1.columnModel.title0_1=Mime type/Extension
|
||||
AutopsyOptionsPanel.maxSolrMemoryLabel.text=Maximum Solr JVM Memory:
|
||||
AutopsyOptionsPanel.maxMemoryUnitsLabel2.text=MB
|
||||
AutopsyOptionsPanel.solrJVMHeapWarning.text=NOTE: Setting this too large may impact overall performance.
|
||||
DataResultViewerTable.gotoPageTextField.text=
|
||||
DataResultViewerTable.gotoPageLabel.AccessibleContext.accessibleName=
|
||||
DataResultViewerTable.gotoPageLabel.text=Go to Page:
|
||||
@ -216,3 +199,27 @@ DataResultViewerTable.exportCSVButton.text=Save Table as CSV
|
||||
ViewPreferencesPanel.scoColumnsCheckbox.text=S(core), C(omments), and O(ccurences)
|
||||
ViewPreferencesPanel.scoColumnsWrapAroundText.text=to reduce loading times
|
||||
ViewPreferencesPanel.scoColumnsLabel.text=Do not add columns for:
|
||||
AutopsyOptionsPanel.logoPanel.border.title=Logo
|
||||
AutopsyOptionsPanel.agencyLogoPathFieldValidationLabel.text=
|
||||
AutopsyOptionsPanel.specifyLogoRB.text=Specify a logo
|
||||
AutopsyOptionsPanel.defaultLogoRB.text=Use default
|
||||
AutopsyOptionsPanel.agencyLogoPreview.text=<html><div style='text-align: center;'>No logo<br>selected</div></html>
|
||||
AutopsyOptionsPanel.browseLogosButton.text=Browse
|
||||
AutopsyOptionsPanel.agencyLogoPathField.text=
|
||||
AutopsyOptionsPanel.tempDirectoryField.text=
|
||||
AutopsyOptionsPanel.tempDirectoryBrowseButton.text=Browse
|
||||
AutopsyOptionsPanel.a.AccessibleContext.accessibleName=Temp Directory
|
||||
AutopsyOptionsPanel.tempDirectoryPanel.AccessibleContext.accessibleName=Temp Directory
|
||||
AutopsyOptionsPanel.tempDirectoryPanel.name=Temp Directory
|
||||
AutopsyOptionsPanel.tempDirectoryPanel.border.title=Temp Directory
|
||||
AutopsyOptionsPanel.tempDirectoryWarningLabel.text=Close the current case to change the temporary directory.
|
||||
AutopsyOptionsPanel.solrJVMHeapWarning.text=NOTE: Setting this too large may impact overall performance.
|
||||
AutopsyOptionsPanel.maxMemoryUnitsLabel2.text=MB
|
||||
AutopsyOptionsPanel.maxSolrMemoryLabel.text=Maximum Solr JVM Memory:
|
||||
AutopsyOptionsPanel.logNumAlert.text=
|
||||
AutopsyOptionsPanel.maxLogFileCount.text=Maximum Log Files:
|
||||
AutopsyOptionsPanel.restartNecessaryWarning.text=A restart is necessary for any memory changes to take effect.
|
||||
AutopsyOptionsPanel.totalMemoryLabel.text=Total System Memory:
|
||||
AutopsyOptionsPanel.maxMemoryUnitsLabel.text=GB
|
||||
AutopsyOptionsPanel.maxMemoryLabel.text=Maximum JVM Memory:
|
||||
AutopsyOptionsPanel.runtimePanel.border.title=Runtime
|
||||
|
@ -12,6 +12,12 @@ AutopsyOptionsPanel.memFieldValidationLabel.noValueEntered.text=No value entered
|
||||
AutopsyOptionsPanel.memFieldValidationLabel.overMaxMemory.text=Value must be less than the total system memory of {0}GB
|
||||
# {0} - minimumMemory
|
||||
AutopsyOptionsPanel.memFieldValidationLabel.underMinMemory.text=Value must be at least {0}GB
|
||||
# {0} - path
|
||||
AutopsyOptionsPanel_storeTempDir_onError_description=There was an error creating the temporary directory on the filesystem at: {0}.
|
||||
AutopsyOptionsPanel_storeTempDir_onError_title=Error Saving Temporary Directory
|
||||
# {0} - path
|
||||
AutopsyOptionsPanel_tempDirectoryBrowseButtonActionPerformed_onInvalidPath_description=Unable to create temporary directory within specified path: {0}
|
||||
AutopsyOptionsPanel_tempDirectoryBrowseButtonActionPerformed_onInvalidPath_title=Path cannot be used
|
||||
CTL_DataContentAction=DataContent
|
||||
CTL_DataContentTopComponent=Data Content
|
||||
CTL_CustomAboutAction=About
|
||||
@ -169,26 +175,12 @@ MultiUserSettingsPanel.lbTestDbWarning.text=
|
||||
MultiUserSettingsPanel.KeywordSearchNull=Cannot find keyword search service
|
||||
MultiUserSettingsPanel.InvalidPortNumber=Invalid port number
|
||||
AutopsyOptionsPanel.agencyLogoImageLabel.toolTipText=
|
||||
AutopsyOptionsPanel.agencyLogoPathField.text=
|
||||
SortChooserDialog.label=remove
|
||||
SortChooser.addCriteriaButton.text=Add Sort Criteria
|
||||
DataResultViewerThumbnail.sortButton.text=Sort
|
||||
CriterionChooser.ascendingRadio.text=\u25b2 Ascending\n
|
||||
CriterionChooser.removeButton.text=Remove
|
||||
CriterionChooser.descendingRadio.text=\u25bc Descending
|
||||
AutopsyOptionsPanel.agencyLogoPathFieldValidationLabel.text=
|
||||
AutopsyOptionsPanel.logNumAlert.text=
|
||||
AutopsyOptionsPanel.totalMemoryLabel.text=Total System Memory:
|
||||
AutopsyOptionsPanel.maxMemoryLabel.text=Maximum JVM Memory:
|
||||
AutopsyOptionsPanel.maxLogFileCount.text=Maximum Log Files:
|
||||
AutopsyOptionsPanel.maxMemoryUnitsLabel.text=GB
|
||||
AutopsyOptionsPanel.restartNecessaryWarning.text=A restart is necessary for any memory changes to take effect.
|
||||
AutopsyOptionsPanel.browseLogosButton.text=Browse
|
||||
AutopsyOptionsPanel.defaultLogoRB.text=Use default
|
||||
AutopsyOptionsPanel.specifyLogoRB.text=Specify a logo
|
||||
AutopsyOptionsPanel.agencyLogoPreview.text=<html><div style='text-align: center;'>No logo<br>selected</div></html>
|
||||
AutopsyOptionsPanel.logoPanel.border.title=Logo
|
||||
AutopsyOptionsPanel.runtimePanel.border.title=Runtime
|
||||
DataResultPanel.matchLabel.text=Results
|
||||
DataResultPanel.numberOfChildNodesLabel.text=0
|
||||
DataResultPanel.descriptionLabel.text=directoryPath
|
||||
@ -250,9 +242,6 @@ ExternalViewerGlobalSettingsPanel.deleteRuleButton.text_1=Delete Rule
|
||||
ExternalViewerGlobalSettingsPanel.externalViewerTitleLabel.text_1=Set aplication viewer to use for files with specific mime types/extensions:
|
||||
ExternalViewerGlobalSettingsPanel.jTable1.columnModel.title1_1=Application
|
||||
ExternalViewerGlobalSettingsPanel.jTable1.columnModel.title0_1=Mime type/Extension
|
||||
AutopsyOptionsPanel.maxSolrMemoryLabel.text=Maximum Solr JVM Memory:
|
||||
AutopsyOptionsPanel.maxMemoryUnitsLabel2.text=MB
|
||||
AutopsyOptionsPanel.solrJVMHeapWarning.text=NOTE: Setting this too large may impact overall performance.
|
||||
DataResultViewerTable.gotoPageTextField.text=
|
||||
DataResultViewerTable.gotoPageLabel.AccessibleContext.accessibleName=
|
||||
DataResultViewerTable.gotoPageLabel.text=Go to Page:
|
||||
@ -267,3 +256,27 @@ DataResultViewerTable.exportCSVButton.text=Save Table as CSV
|
||||
ViewPreferencesPanel.scoColumnsCheckbox.text=S(core), C(omments), and O(ccurences)
|
||||
ViewPreferencesPanel.scoColumnsWrapAroundText.text=to reduce loading times
|
||||
ViewPreferencesPanel.scoColumnsLabel.text=Do not add columns for:
|
||||
AutopsyOptionsPanel.logoPanel.border.title=Logo
|
||||
AutopsyOptionsPanel.agencyLogoPathFieldValidationLabel.text=
|
||||
AutopsyOptionsPanel.specifyLogoRB.text=Specify a logo
|
||||
AutopsyOptionsPanel.defaultLogoRB.text=Use default
|
||||
AutopsyOptionsPanel.agencyLogoPreview.text=<html><div style='text-align: center;'>No logo<br>selected</div></html>
|
||||
AutopsyOptionsPanel.browseLogosButton.text=Browse
|
||||
AutopsyOptionsPanel.agencyLogoPathField.text=
|
||||
AutopsyOptionsPanel.tempDirectoryField.text=
|
||||
AutopsyOptionsPanel.tempDirectoryBrowseButton.text=Browse
|
||||
AutopsyOptionsPanel.a.AccessibleContext.accessibleName=Temp Directory
|
||||
AutopsyOptionsPanel.tempDirectoryPanel.AccessibleContext.accessibleName=Temp Directory
|
||||
AutopsyOptionsPanel.tempDirectoryPanel.name=Temp Directory
|
||||
AutopsyOptionsPanel.tempDirectoryPanel.border.title=Temp Directory
|
||||
AutopsyOptionsPanel.tempDirectoryWarningLabel.text=Close the current case to change the temporary directory.
|
||||
AutopsyOptionsPanel.solrJVMHeapWarning.text=NOTE: Setting this too large may impact overall performance.
|
||||
AutopsyOptionsPanel.maxMemoryUnitsLabel2.text=MB
|
||||
AutopsyOptionsPanel.maxSolrMemoryLabel.text=Maximum Solr JVM Memory:
|
||||
AutopsyOptionsPanel.logNumAlert.text=
|
||||
AutopsyOptionsPanel.maxLogFileCount.text=Maximum Log Files:
|
||||
AutopsyOptionsPanel.restartNecessaryWarning.text=A restart is necessary for any memory changes to take effect.
|
||||
AutopsyOptionsPanel.totalMemoryLabel.text=Total System Memory:
|
||||
AutopsyOptionsPanel.maxMemoryUnitsLabel.text=GB
|
||||
AutopsyOptionsPanel.maxMemoryLabel.text=Maximum JVM Memory:
|
||||
AutopsyOptionsPanel.runtimePanel.border.title=Runtime
|
||||
|
@ -36,7 +36,7 @@ import org.openide.util.NbBundle.Messages;
|
||||
import org.sleuthkit.autopsy.casemodule.Case;
|
||||
import org.sleuthkit.autopsy.casemodule.DeleteDataSourceAction;
|
||||
import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException;
|
||||
import org.sleuthkit.autopsy.casemodule.datasourcesummary.ViewSummaryInformationAction;
|
||||
import org.sleuthkit.autopsy.datasourcesummary.ui.ViewSummaryInformationAction;
|
||||
import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationAttributeInstance;
|
||||
import org.sleuthkit.autopsy.corecomponents.DataResultViewerTable;
|
||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||
|
@ -24,7 +24,7 @@ import java.util.List;
|
||||
import javax.swing.Action;
|
||||
import org.openide.util.NbBundle;
|
||||
import org.sleuthkit.autopsy.casemodule.DeleteDataSourceAction;
|
||||
import org.sleuthkit.autopsy.casemodule.datasourcesummary.ViewSummaryInformationAction;
|
||||
import org.sleuthkit.autopsy.datasourcesummary.ui.ViewSummaryInformationAction;
|
||||
import org.sleuthkit.autopsy.coreutils.ContextMenuExtensionPoint;
|
||||
import org.sleuthkit.autopsy.directorytree.ExportCSVAction;
|
||||
import org.sleuthkit.autopsy.directorytree.ExtractAction;
|
||||
|
@ -0,0 +1,168 @@
|
||||
/*
|
||||
* Autopsy Forensic Browser
|
||||
*
|
||||
* Copyright 2020 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.datasourcesummary.datamodel;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.logging.Level;
|
||||
import org.sleuthkit.autopsy.casemodule.Case;
|
||||
import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException;
|
||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||
import org.sleuthkit.datamodel.BlackboardArtifact;
|
||||
import org.sleuthkit.datamodel.BlackboardAttribute;
|
||||
import org.sleuthkit.datamodel.SleuthkitCase;
|
||||
import org.sleuthkit.datamodel.TskCoreException;
|
||||
import org.sleuthkit.datamodel.TskData;
|
||||
|
||||
/**
|
||||
* Provides methods to query for information for all datasources in a case.
|
||||
*/
|
||||
public class CaseDataSourcesSummary {
|
||||
|
||||
private static final Logger logger = Logger.getLogger(CaseDataSourcesSummary.class.getName());
|
||||
|
||||
/**
|
||||
* Get a map containing the TSK_DATA_SOURCE_USAGE description attributes
|
||||
* associated with each data source in the current case.
|
||||
*
|
||||
* @return Collection which maps datasource id to a String which displays a
|
||||
* comma seperated list of values of data source usage types
|
||||
* expected to be in the datasource
|
||||
*/
|
||||
public static Map<Long, String> getDataSourceTypes() {
|
||||
try {
|
||||
SleuthkitCase skCase = Case.getCurrentCaseThrows().getSleuthkitCase();
|
||||
List<BlackboardArtifact> listOfArtifacts = skCase.getBlackboardArtifacts(BlackboardArtifact.ARTIFACT_TYPE.TSK_DATA_SOURCE_USAGE);
|
||||
Map<Long, String> typeMap = new HashMap<>();
|
||||
for (BlackboardArtifact typeArtifact : listOfArtifacts) {
|
||||
BlackboardAttribute descriptionAttr = typeArtifact.getAttribute(new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DESCRIPTION));
|
||||
if (typeArtifact.getDataSource() != null && descriptionAttr != null) {
|
||||
long dsId = typeArtifact.getDataSource().getId();
|
||||
String type = typeMap.get(typeArtifact.getDataSource().getId());
|
||||
if (type == null) {
|
||||
type = descriptionAttr.getValueString();
|
||||
} else {
|
||||
type = type + ", " + descriptionAttr.getValueString();
|
||||
}
|
||||
typeMap.put(dsId, type);
|
||||
}
|
||||
}
|
||||
return typeMap;
|
||||
} catch (TskCoreException | NoCurrentCaseException ex) {
|
||||
logger.log(Level.WARNING, "Unable to get types of files for all datasources, providing empty results", ex);
|
||||
return Collections.emptyMap();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a map containing the number of files in each data source in the
|
||||
* current case.
|
||||
*
|
||||
* @return Collection which maps datasource id to a count for the number of
|
||||
* files in the datasource, will only contain entries for
|
||||
* datasources which have at least 1 file
|
||||
*/
|
||||
public static Map<Long, Long> getCountsOfFiles() {
|
||||
try {
|
||||
final String countFilesQuery = "data_source_obj_id, COUNT(*) AS value FROM tsk_files"
|
||||
+ " WHERE meta_type=" + TskData.TSK_FS_META_TYPE_ENUM.TSK_FS_META_TYPE_REG.getValue()
|
||||
+ " AND type<>" + TskData.TSK_DB_FILES_TYPE_ENUM.VIRTUAL_DIR.getFileType()
|
||||
+ " AND dir_type<>" + TskData.TSK_FS_NAME_TYPE_ENUM.VIRT_DIR.getValue()
|
||||
+ " AND name<>''"
|
||||
+ " GROUP BY data_source_obj_id"; //NON-NLS
|
||||
return getValuesMap(countFilesQuery);
|
||||
} catch (TskCoreException | NoCurrentCaseException ex) {
|
||||
logger.log(Level.WARNING, "Unable to get counts of files for all datasources, providing empty results", ex);
|
||||
return Collections.emptyMap();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a map containing the number of artifacts in each data source in the
|
||||
* current case.
|
||||
*
|
||||
* @return Collection which maps datasource id to a count for the number of
|
||||
* artifacts in the datasource, will only contain entries for
|
||||
* datasources which have at least 1 artifact
|
||||
*/
|
||||
public static Map<Long, Long> getCountsOfArtifacts() {
|
||||
try {
|
||||
final String countArtifactsQuery = "data_source_obj_id, COUNT(*) AS value"
|
||||
+ " FROM blackboard_artifacts WHERE review_status_id !=" + BlackboardArtifact.ReviewStatus.REJECTED.getID()
|
||||
+ " GROUP BY data_source_obj_id"; //NON-NLS
|
||||
return getValuesMap(countArtifactsQuery);
|
||||
} catch (TskCoreException | NoCurrentCaseException ex) {
|
||||
logger.log(Level.WARNING, "Unable to get counts of artifacts for all datasources, providing empty results", ex);
|
||||
return Collections.emptyMap();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a map containing the number of tags which have been applied in each
|
||||
* data source in the current case. Not necessarily the same as the number
|
||||
* of items tagged, as an item can have any number of tags.
|
||||
*
|
||||
* @return Collection which maps datasource id to a count for the number of
|
||||
* tags which have been applied in the datasource, will only contain
|
||||
* entries for datasources which have at least 1 item tagged.
|
||||
*/
|
||||
public static Map<Long, Long> getCountsOfTags() {
|
||||
try {
|
||||
final String countFileTagsQuery = "data_source_obj_id, COUNT(*) AS value"
|
||||
+ " FROM content_tags as content_tags, tsk_files as tsk_files"
|
||||
+ " WHERE content_tags.obj_id = tsk_files.obj_id"
|
||||
+ " GROUP BY data_source_obj_id"; //NON-NLS
|
||||
//new hashmap so it can be modifiable
|
||||
Map<Long, Long> tagCountMap = new HashMap<>(getValuesMap(countFileTagsQuery));
|
||||
final String countArtifactTagsQuery = "data_source_obj_id, COUNT(*) AS value"
|
||||
+ " FROM blackboard_artifact_tags as artifact_tags, blackboard_artifacts AS arts"
|
||||
+ " WHERE artifact_tags.artifact_id = arts.artifact_id"
|
||||
+ " GROUP BY data_source_obj_id"; //NON-NLS
|
||||
//combine the results from the count artifact tags query into the copy of the mapped results from the count file tags query
|
||||
getValuesMap(countArtifactTagsQuery).forEach((key, value) -> tagCountMap.merge(key, value, (value1, value2) -> value1 + value2));
|
||||
return tagCountMap;
|
||||
} catch (TskCoreException | NoCurrentCaseException ex) {
|
||||
logger.log(Level.WARNING, "Unable to get counts of tags for all datasources, providing empty results", ex);
|
||||
return Collections.emptyMap();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper method to execute a select query with a
|
||||
* DataSourceSingleValueCallback.
|
||||
*
|
||||
* @param query the portion of the query which should follow the SELECT
|
||||
*
|
||||
* @return a map of datasource object ID to a value of type Long
|
||||
*
|
||||
* @throws TskCoreException
|
||||
* @throws NoCurrentCaseException
|
||||
*/
|
||||
private static Map<Long, Long> getValuesMap(String query) throws TskCoreException, NoCurrentCaseException {
|
||||
SleuthkitCase skCase = Case.getCurrentCaseThrows().getSleuthkitCase();
|
||||
DataSourceSingleValueCallback callback = new DataSourceSingleValueCallback();
|
||||
skCase.getCaseDbAccessManager().select(query, callback);
|
||||
return callback.getMapOfValues();
|
||||
}
|
||||
|
||||
private CaseDataSourcesSummary() {
|
||||
}
|
||||
}
|
@ -0,0 +1,160 @@
|
||||
/*
|
||||
* Autopsy Forensic Browser
|
||||
*
|
||||
* Copyright 2019 - 2020 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.datasourcesummary.datamodel;
|
||||
|
||||
import java.sql.SQLException;
|
||||
import java.util.Collections;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
import java.util.logging.Level;
|
||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||
import org.sleuthkit.autopsy.datasourcesummary.datamodel.DataSourceInfoUtilities.ResultSetHandler;
|
||||
import org.sleuthkit.datamodel.DataSource;
|
||||
import org.sleuthkit.datamodel.TskData;
|
||||
|
||||
/**
|
||||
* Provides information for the DataSourceSummaryCountsPanel.
|
||||
*/
|
||||
public class DataSourceCountsSummary {
|
||||
|
||||
private static final Logger logger = Logger.getLogger(DataSourceCountsSummary.class.getName());
|
||||
|
||||
/**
|
||||
* Get count of regular files (not directories) in a data source.
|
||||
*
|
||||
* @param currentDataSource The data source.
|
||||
*
|
||||
* @return The count.
|
||||
*/
|
||||
public static Long getCountOfFiles(DataSource currentDataSource) {
|
||||
return DataSourceInfoUtilities.getCountOfRegularFiles(currentDataSource, null,
|
||||
"Unable to get count of files, providing empty results");
|
||||
}
|
||||
|
||||
/**
|
||||
* Get count of allocated files in a data source.
|
||||
*
|
||||
* @param currentDataSource The data source.
|
||||
*
|
||||
* @return The count.
|
||||
*/
|
||||
public static Long getCountOfAllocatedFiles(DataSource currentDataSource) {
|
||||
return DataSourceInfoUtilities.getCountOfRegularFiles(currentDataSource,
|
||||
DataSourceInfoUtilities.getMetaFlagsContainsStatement(TskData.TSK_FS_META_FLAG_ENUM.ALLOC),
|
||||
"Unable to get counts of unallocated files for datasource, providing empty results");
|
||||
}
|
||||
|
||||
/**
|
||||
* Get count of unallocated files in a data source.
|
||||
*
|
||||
* @param currentDataSource The data source.
|
||||
*
|
||||
* @return The count.
|
||||
*/
|
||||
public static Long getCountOfUnallocatedFiles(DataSource currentDataSource) {
|
||||
return DataSourceInfoUtilities.getCountOfRegularFiles(currentDataSource,
|
||||
DataSourceInfoUtilities.getMetaFlagsContainsStatement(TskData.TSK_FS_META_FLAG_ENUM.UNALLOC)
|
||||
+ " AND type<>" + TskData.TSK_DB_FILES_TYPE_ENUM.SLACK.getFileType(),
|
||||
"Unable to get counts of unallocated files for datasource, providing empty results");
|
||||
}
|
||||
|
||||
/**
|
||||
* Get count of directories in a data source.
|
||||
*
|
||||
* @param currentDataSource The data source.
|
||||
*
|
||||
* @return The count.
|
||||
*/
|
||||
public static Long getCountOfDirectories(DataSource currentDataSource) {
|
||||
return DataSourceInfoUtilities.getCountOfTskFiles(currentDataSource,
|
||||
"meta_type=" + TskData.TSK_FS_META_TYPE_ENUM.TSK_FS_META_TYPE_DIR.getValue()
|
||||
+ " AND type<>" + TskData.TSK_DB_FILES_TYPE_ENUM.VIRTUAL_DIR.getFileType(),
|
||||
"Unable to get count of directories for datasource, providing empty results");
|
||||
}
|
||||
|
||||
/**
|
||||
* Get count of slack files in a data source.
|
||||
*
|
||||
* @param currentDataSource The data source.
|
||||
*
|
||||
* @return The count.
|
||||
*/
|
||||
public static Long getCountOfSlackFiles(DataSource currentDataSource) {
|
||||
return DataSourceInfoUtilities.getCountOfRegularFiles(currentDataSource,
|
||||
DataSourceInfoUtilities.getMetaFlagsContainsStatement(TskData.TSK_FS_META_FLAG_ENUM.UNALLOC)
|
||||
+ " AND type=" + TskData.TSK_DB_FILES_TYPE_ENUM.SLACK.getFileType(),
|
||||
"Unable to get count of slack files for datasources, providing empty results");
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves counts for each artifact type in a data source.
|
||||
*
|
||||
* @param selectedDataSource The data source.
|
||||
*
|
||||
* @return A mapping of artifact type name to the counts or null if there
|
||||
* was an error executing the query.
|
||||
*/
|
||||
public static Map<String, Long> getCountsOfArtifactsByType(DataSource selectedDataSource) {
|
||||
if (selectedDataSource == null) {
|
||||
return Collections.emptyMap();
|
||||
}
|
||||
|
||||
final String nameParam = "name";
|
||||
final String valueParam = "value";
|
||||
String query
|
||||
= "SELECT bbt.display_name AS " + nameParam + ", COUNT(*) AS " + valueParam
|
||||
+ " FROM blackboard_artifacts bba "
|
||||
+ " INNER JOIN blackboard_artifact_types bbt ON bba.artifact_type_id = bbt.artifact_type_id"
|
||||
+ " WHERE bba.data_source_obj_id =" + selectedDataSource.getId()
|
||||
+ " GROUP BY bbt.display_name";
|
||||
|
||||
String errorMessage = "Unable to get artifact type counts; returning null.";
|
||||
return DataSourceInfoUtilities.getBaseQueryResult(query,
|
||||
getStringLongResultSetHandler(nameParam, valueParam),
|
||||
errorMessage);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a result set handler that will return a map of string to long.
|
||||
*
|
||||
* @param keyParam The named parameter in the result set representing the
|
||||
* key.
|
||||
* @param valueParam The named parameter in the result set representing the
|
||||
* value.
|
||||
*
|
||||
* @return The result set handler to generate the map of string to long.
|
||||
*/
|
||||
private static ResultSetHandler<LinkedHashMap<String, Long>> getStringLongResultSetHandler(String keyParam, String valueParam) {
|
||||
return (resultSet) -> {
|
||||
LinkedHashMap<String, Long> toRet = new LinkedHashMap<>();
|
||||
while (resultSet.next()) {
|
||||
try {
|
||||
toRet.put(resultSet.getString(keyParam), resultSet.getLong(valueParam));
|
||||
} catch (SQLException ex) {
|
||||
logger.log(Level.WARNING, "Failed to get a result pair from the result set.", ex);
|
||||
}
|
||||
}
|
||||
|
||||
return toRet;
|
||||
};
|
||||
}
|
||||
|
||||
private DataSourceCountsSummary() {
|
||||
}
|
||||
}
|
@ -0,0 +1,178 @@
|
||||
/*
|
||||
* Autopsy Forensic Browser
|
||||
*
|
||||
* Copyright 2020 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.datasourcesummary.datamodel;
|
||||
|
||||
import java.sql.SQLException;
|
||||
import java.util.logging.Level;
|
||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||
import static org.sleuthkit.autopsy.datasourcesummary.datamodel.DataSourceInfoUtilities.getBaseQueryResult;
|
||||
import org.sleuthkit.datamodel.BlackboardArtifact;
|
||||
import org.sleuthkit.datamodel.BlackboardAttribute;
|
||||
import org.sleuthkit.datamodel.DataSource;
|
||||
import org.sleuthkit.datamodel.TskData;
|
||||
|
||||
/**
|
||||
* Provides methods to query for data source overview details.
|
||||
*/
|
||||
public class DataSourceDetailsSummary {
|
||||
|
||||
private static final Logger logger = Logger.getLogger(DataSourceDetailsSummary.class.getName());
|
||||
|
||||
/**
|
||||
* Gets the size of unallocated files in a particular datasource.
|
||||
*
|
||||
* @param currentDataSource The data source.
|
||||
*
|
||||
* @return The size or null if the query could not be executed.
|
||||
*/
|
||||
public static Long getSizeOfUnallocatedFiles(DataSource currentDataSource) {
|
||||
if (currentDataSource == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
final String valueParam = "value";
|
||||
final String countParam = "count";
|
||||
String query = "SELECT SUM(size) AS " + valueParam + ", COUNT(*) AS " + countParam
|
||||
+ " FROM tsk_files"
|
||||
+ " WHERE " + DataSourceInfoUtilities.getMetaFlagsContainsStatement(TskData.TSK_FS_META_FLAG_ENUM.UNALLOC)
|
||||
+ " AND type<>" + TskData.TSK_DB_FILES_TYPE_ENUM.SLACK.getFileType()
|
||||
+ " AND type<>" + TskData.TSK_DB_FILES_TYPE_ENUM.VIRTUAL_DIR.getFileType()
|
||||
+ " AND dir_type<>" + TskData.TSK_FS_NAME_TYPE_ENUM.VIRT_DIR.getValue()
|
||||
+ " AND name<>''"
|
||||
+ " AND data_source_obj_id=" + currentDataSource.getId();
|
||||
|
||||
DataSourceInfoUtilities.ResultSetHandler<Long> handler = (resultSet) -> {
|
||||
if (resultSet.next()) {
|
||||
// ensure that there is an unallocated count result that is attached to this data source
|
||||
long resultCount = resultSet.getLong(valueParam);
|
||||
return (resultCount > 0) ? resultSet.getLong(valueParam) : null;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
};
|
||||
String errorMessage = "Unable to get size of unallocated files; returning null.";
|
||||
|
||||
return DataSourceInfoUtilities.getBaseQueryResult(query, handler, errorMessage);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the concatenation of operating system attributes for a
|
||||
* particular data source.
|
||||
*
|
||||
* @param dataSource The data source.
|
||||
*
|
||||
* @return The concatenated value or null if the query could not be
|
||||
* executed.
|
||||
*/
|
||||
public static String getOperatingSystems(DataSource dataSource) {
|
||||
if (dataSource == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return getConcattedAttrValue(dataSource.getId(),
|
||||
BlackboardArtifact.ARTIFACT_TYPE.TSK_OS_INFO.getTypeID(),
|
||||
BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PROG_NAME.getTypeID());
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the concatenation of data source usage for a particular data
|
||||
* source.
|
||||
*
|
||||
* @param dataSource The data source.
|
||||
*
|
||||
* @return The concatenated value or null if the query could not be
|
||||
* executed.
|
||||
*/
|
||||
public static String getDataSourceType(DataSource dataSource) {
|
||||
if (dataSource == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return getConcattedAttrValue(dataSource.getId(),
|
||||
BlackboardArtifact.ARTIFACT_TYPE.TSK_DATA_SOURCE_USAGE.getTypeID(),
|
||||
BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DESCRIPTION.getTypeID());
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a string which is a concatenation of the value received from
|
||||
* the result set.
|
||||
*
|
||||
* @param query The query.
|
||||
* @param valueParam The parameter for the value in the result set.
|
||||
* @param separator The string separator used in concatenation.
|
||||
* @param errorMessage The error message if the result set could not
|
||||
* be received.
|
||||
* @param singleErrorMessage The error message if a single result could not
|
||||
* be obtained.
|
||||
*
|
||||
* @return The concatenated string or null if the query could not be
|
||||
* executed.
|
||||
*/
|
||||
private static String getConcattedStringsResult(String query, String valueParam, String separator, String errorMessage, String singleErrorMessage) {
|
||||
DataSourceInfoUtilities.ResultSetHandler<String> handler = (resultSet) -> {
|
||||
String toRet = "";
|
||||
boolean first = true;
|
||||
while (resultSet.next()) {
|
||||
try {
|
||||
if (first) {
|
||||
first = false;
|
||||
} else {
|
||||
toRet += separator;
|
||||
}
|
||||
toRet += resultSet.getString(valueParam);
|
||||
} catch (SQLException ex) {
|
||||
logger.log(Level.WARNING, singleErrorMessage, ex);
|
||||
}
|
||||
}
|
||||
|
||||
return toRet;
|
||||
};
|
||||
|
||||
return getBaseQueryResult(query, handler, errorMessage);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a concatenated string value based on the text value of a
|
||||
* particular attribute in a particular artifact for a specific data source.
|
||||
*
|
||||
* @param dataSourceId The data source id.
|
||||
* @param artifactTypeId The artifact type id.
|
||||
* @param attributeTypeId The attribute type id.
|
||||
*
|
||||
* @return The concatenated value or null if the query could not be
|
||||
* executed.
|
||||
*/
|
||||
private static String getConcattedAttrValue(long dataSourceId, int artifactTypeId, int attributeTypeId) {
|
||||
final String valueParam = "concatted_attribute_value";
|
||||
String query = "SELECT attr.value_text AS " + valueParam
|
||||
+ " FROM blackboard_artifacts bba "
|
||||
+ " INNER JOIN blackboard_attributes attr ON bba.artifact_id = attr.artifact_id "
|
||||
+ " WHERE bba.data_source_obj_id = " + dataSourceId
|
||||
+ " AND bba.artifact_type_id = " + artifactTypeId
|
||||
+ " AND attr.attribute_type_id = " + attributeTypeId;
|
||||
|
||||
String errorMessage = "Unable to execute query to retrieve concatted attribute values.";
|
||||
String singleErrorMessage = "There was an error retrieving one of the results. That result will be omitted from concatted value.";
|
||||
String separator = ", ";
|
||||
return getConcattedStringsResult(query, valueParam, separator, errorMessage, singleErrorMessage);
|
||||
}
|
||||
|
||||
private DataSourceDetailsSummary() {
|
||||
}
|
||||
}
|
@ -0,0 +1,141 @@
|
||||
/*
|
||||
* Autopsy Forensic Browser
|
||||
*
|
||||
* Copyright 2019 - 2020 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.datasourcesummary.datamodel;
|
||||
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.util.logging.Level;
|
||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||
import org.sleuthkit.datamodel.SleuthkitCase;
|
||||
import org.sleuthkit.datamodel.TskCoreException;
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.sleuthkit.autopsy.casemodule.Case;
|
||||
import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException;
|
||||
import org.sleuthkit.datamodel.TskData;
|
||||
import org.sleuthkit.datamodel.DataSource;
|
||||
import org.sleuthkit.datamodel.TskData.TSK_FS_META_FLAG_ENUM;
|
||||
import org.sleuthkit.datamodel.TskData.TSK_FS_META_TYPE_ENUM;
|
||||
|
||||
/**
|
||||
* Utilities for getting information about a data source or all data sources
|
||||
* from the case database.
|
||||
*/
|
||||
final class DataSourceInfoUtilities {
|
||||
|
||||
private static final Logger logger = Logger.getLogger(DataSourceInfoUtilities.class.getName());
|
||||
|
||||
/**
|
||||
* Gets a count of tsk_files for a particular datasource where dir_type is
|
||||
* not a virtual directory and has a name.
|
||||
*
|
||||
* @param currentDataSource The datasource.
|
||||
* @param additionalWhere Additional sql where clauses.
|
||||
* @param onError The message to log on error.
|
||||
*
|
||||
* @return The count of files or null on error.
|
||||
*/
|
||||
static Long getCountOfTskFiles(DataSource currentDataSource, String additionalWhere, String onError) {
|
||||
if (currentDataSource != null) {
|
||||
try {
|
||||
SleuthkitCase skCase = Case.getCurrentCaseThrows().getSleuthkitCase();
|
||||
return skCase.countFilesWhere(
|
||||
"data_source_obj_id=" + currentDataSource.getId()
|
||||
+ " AND dir_type<>" + TskData.TSK_FS_NAME_TYPE_ENUM.VIRT_DIR.getValue()
|
||||
+ " AND name<>''"
|
||||
+ (StringUtils.isBlank(additionalWhere) ? "" : (" AND " + additionalWhere)));
|
||||
} catch (TskCoreException | NoCurrentCaseException ex) {
|
||||
logger.log(Level.WARNING, onError, ex);
|
||||
//unable to get count of files for the specified types cell will be displayed as empty
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a count of regular files for a particular datasource where the
|
||||
* dir_type and type are not a virtual directory and has a name.
|
||||
*
|
||||
* @param currentDataSource The datasource.
|
||||
* @param additionalWhere Additional sql where clauses.
|
||||
* @param onError The message to log on error.
|
||||
*
|
||||
* @return The count of files or null on error.
|
||||
*/
|
||||
static Long getCountOfRegularFiles(DataSource currentDataSource, String additionalWhere, String onError) {
|
||||
String whereClause = "meta_type=" + TSK_FS_META_TYPE_ENUM.TSK_FS_META_TYPE_REG.getValue()
|
||||
+ " AND type<>" + TskData.TSK_DB_FILES_TYPE_ENUM.VIRTUAL_DIR.getFileType();
|
||||
|
||||
if (StringUtils.isNotBlank(additionalWhere)) {
|
||||
whereClause += " AND " + additionalWhere;
|
||||
}
|
||||
|
||||
return getCountOfTskFiles(currentDataSource, whereClause, onError);
|
||||
}
|
||||
|
||||
/**
|
||||
* An interface for handling a result set and returning a value.
|
||||
*/
|
||||
interface ResultSetHandler<T> {
|
||||
|
||||
T process(ResultSet resultset) throws SQLException;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves a result based on the provided query.
|
||||
*
|
||||
* @param query The query.
|
||||
* @param processor The result set handler.
|
||||
* @param errorMessage The error message to display if there is an error
|
||||
* retrieving the resultset.
|
||||
*
|
||||
* @return The ResultSetHandler value or null if no ResultSet could be
|
||||
* obtained.
|
||||
*/
|
||||
static <T> T getBaseQueryResult(String query, ResultSetHandler<T> processor, String errorMessage) {
|
||||
try (SleuthkitCase.CaseDbQuery dbQuery = Case.getCurrentCaseThrows().getSleuthkitCase().executeQuery(query)) {
|
||||
ResultSet resultSet = dbQuery.getResultSet();
|
||||
try {
|
||||
return processor.process(resultSet);
|
||||
} catch (SQLException ex) {
|
||||
logger.log(Level.WARNING, errorMessage, ex);
|
||||
}
|
||||
} catch (TskCoreException | NoCurrentCaseException ex) {
|
||||
logger.log(Level.WARNING, errorMessage, ex);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates sql where clause that does a bitwise check to see if flag is
|
||||
* present.
|
||||
*
|
||||
* @param flag The flag for which to check.
|
||||
*
|
||||
* @return The clause.
|
||||
*/
|
||||
static String getMetaFlagsContainsStatement(TSK_FS_META_FLAG_ENUM flag) {
|
||||
return "meta_flags & " + flag.getValue() + " > 0";
|
||||
}
|
||||
|
||||
/**
|
||||
* Empty private constructor
|
||||
*/
|
||||
private DataSourceInfoUtilities() {
|
||||
}
|
||||
}
|
@ -16,7 +16,7 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.sleuthkit.autopsy.casemodule.datasourcesummary;
|
||||
package org.sleuthkit.autopsy.datasourcesummary.datamodel;
|
||||
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
@ -0,0 +1,107 @@
|
||||
/*
|
||||
* Autopsy Forensic Browser
|
||||
*
|
||||
* Copyright 2020 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.datasourcesummary.datamodel;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
import org.sleuthkit.datamodel.DataSource;
|
||||
|
||||
/**
|
||||
* Provides methods to query for datasource files by mime type.
|
||||
*/
|
||||
public class DataSourceMimeTypeSummary {
|
||||
|
||||
/**
|
||||
* Get the number of files in the case database for the current data source
|
||||
* which have the specified mimetypes.
|
||||
*
|
||||
* @param currentDataSource the data source which we are finding a file
|
||||
* count
|
||||
*
|
||||
* @param setOfMimeTypes the set of mime types which we are finding the
|
||||
* number of occurences of
|
||||
*
|
||||
* @return a Long value which represents the number of occurrences of the
|
||||
* specified mime types in the current case for the specified data
|
||||
* source, null if no count was retrieved
|
||||
*/
|
||||
public static Long getCountOfFilesForMimeTypes(DataSource currentDataSource, Set<String> setOfMimeTypes) {
|
||||
return DataSourceInfoUtilities.getCountOfRegularFiles(currentDataSource,
|
||||
"mime_type IN " + getSqlSet(setOfMimeTypes),
|
||||
"Unable to get count of files for specified mime types");
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the number of files in the case database for the current data source
|
||||
* which do not have the specified mimetypes.
|
||||
*
|
||||
* @param currentDataSource the data source which we are finding a file
|
||||
* count
|
||||
*
|
||||
* @param setOfMimeTypes the set of mime types that should be excluded.
|
||||
*
|
||||
* @return a Long value which represents the number of files that do not
|
||||
* have the specific mime type, but do have a mime type.
|
||||
*/
|
||||
public static Long getCountOfFilesNotInMimeTypes(DataSource currentDataSource, Set<String> setOfMimeTypes) {
|
||||
return DataSourceInfoUtilities.getCountOfRegularFiles(currentDataSource,
|
||||
"mime_type NOT IN " + getSqlSet(setOfMimeTypes)
|
||||
+ " AND mime_type IS NOT NULL AND mime_type <> '' ",
|
||||
"Unable to get count of files without specified mime types");
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the number of files in the data source with no assigned mime type.
|
||||
*
|
||||
* @param currentDataSource The data source.
|
||||
*
|
||||
* @return The number of files with no mime type or null if there is an
|
||||
* issue searching the data source.
|
||||
*
|
||||
*/
|
||||
public static Long getCountOfFilesWithNoMimeType(DataSource currentDataSource) {
|
||||
return DataSourceInfoUtilities.getCountOfRegularFiles(currentDataSource,
|
||||
"(mime_type IS NULL OR mime_type = '') ",
|
||||
"Unable to get count of files without a mime type");
|
||||
}
|
||||
|
||||
/**
|
||||
* Derives a sql set string (i.e. "('val1', 'val2', 'val3')"). A naive
|
||||
* attempt is made to sanitize the strings by removing single quotes from
|
||||
* values.
|
||||
*
|
||||
* @param setValues The values that should be present in the set. Single
|
||||
* quotes are removed.
|
||||
*
|
||||
* @return The sql set string.
|
||||
*/
|
||||
private static String getSqlSet(Set<String> setValues) {
|
||||
List<String> quotedValues = setValues
|
||||
.stream()
|
||||
.map(str -> String.format("'%s'", str.replace("'", "")))
|
||||
.collect(Collectors.toList());
|
||||
|
||||
String commaSeparatedQuoted = String.join(", ", quotedValues);
|
||||
return String.format("(%s) ", commaSeparatedQuoted);
|
||||
}
|
||||
|
||||
private DataSourceMimeTypeSummary() {
|
||||
}
|
||||
}
|
@ -16,7 +16,7 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.sleuthkit.autopsy.casemodule.datasourcesummary;
|
||||
package org.sleuthkit.autopsy.datasourcesummary.datamodel;
|
||||
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
@ -0,0 +1,295 @@
|
||||
/*
|
||||
* Autopsy Forensic Browser
|
||||
*
|
||||
* Copyright 2020 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.datasourcesummary.datamodel;
|
||||
|
||||
import java.io.File;
|
||||
import java.sql.SQLException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.function.Function;
|
||||
import java.util.logging.Level;
|
||||
import java.util.stream.Collectors;
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||
import static org.sleuthkit.autopsy.datasourcesummary.datamodel.DataSourceInfoUtilities.getBaseQueryResult;
|
||||
import org.sleuthkit.datamodel.BlackboardArtifact;
|
||||
import org.sleuthkit.datamodel.BlackboardAttribute;
|
||||
import org.sleuthkit.datamodel.DataSource;
|
||||
|
||||
/**
|
||||
* Provides information to populate Top Programs Summary queries.
|
||||
*/
|
||||
public class DataSourceTopProgramsSummary {
|
||||
|
||||
private static final Logger logger = Logger.getLogger(DataSourceTopProgramsSummary.class.getName());
|
||||
|
||||
/**
|
||||
* A SQL join type.
|
||||
*/
|
||||
private enum JoinType {
|
||||
LEFT,
|
||||
RIGHT,
|
||||
INNER,
|
||||
OUTER
|
||||
}
|
||||
|
||||
/**
|
||||
* A blackboard attribute value column.
|
||||
*/
|
||||
private enum AttributeColumn {
|
||||
value_text,
|
||||
value_int32,
|
||||
value_int64
|
||||
}
|
||||
|
||||
/**
|
||||
* The suffix joined to a key name for use as an identifier of a query.
|
||||
*/
|
||||
private static final String QUERY_SUFFIX = "_query";
|
||||
|
||||
/**
|
||||
* Creates a sql statement querying the blackboard attributes table for a
|
||||
* particular attribute type and returning a specified value. That query
|
||||
* also joins with the blackboard artifact table.
|
||||
*
|
||||
* @param joinType The type of join statement to create.
|
||||
* @param attributeColumn The blackboard attribute column that should be
|
||||
* returned.
|
||||
* @param attrType The attribute type to query for.
|
||||
* @param keyName The aliased name of the attribute to return. This
|
||||
* is also used to calculate the alias of the query
|
||||
* same as getFullKey.
|
||||
* @param bbaName The blackboard artifact table alias.
|
||||
*
|
||||
* @return The generated sql statement.
|
||||
*/
|
||||
private static String getAttributeJoin(JoinType joinType, AttributeColumn attributeColumn, BlackboardAttribute.ATTRIBUTE_TYPE attrType, String keyName, String bbaName) {
|
||||
String queryName = keyName + QUERY_SUFFIX;
|
||||
String innerQueryName = "inner_attribute_" + queryName;
|
||||
|
||||
return "\n" + joinType + " JOIN (\n"
|
||||
+ " SELECT \n"
|
||||
+ " " + innerQueryName + ".artifact_id,\n"
|
||||
+ " " + innerQueryName + "." + attributeColumn + " AS " + keyName + "\n"
|
||||
+ " FROM blackboard_attributes " + innerQueryName + "\n"
|
||||
+ " WHERE " + innerQueryName + ".attribute_type_id = " + attrType.getTypeID() + " -- " + attrType.name() + "\n"
|
||||
+ ") " + queryName + " ON " + queryName + ".artifact_id = " + bbaName + ".artifact_id\n";
|
||||
}
|
||||
|
||||
/**
|
||||
* Given a column key, creates the full name for the column key.
|
||||
*
|
||||
* @param key The column key.
|
||||
*
|
||||
* @return The full identifier for the column key.
|
||||
*/
|
||||
private static String getFullKey(String key) {
|
||||
return key + QUERY_SUFFIX + "." + key;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a SQL 'where' statement from a list of clauses and puts
|
||||
* parenthesis around each clause.
|
||||
*
|
||||
* @param clauses The clauses
|
||||
*
|
||||
* @return The generated 'where' statement.
|
||||
*/
|
||||
private static String getWhereString(List<String> clauses) {
|
||||
if (clauses.isEmpty()) {
|
||||
return "";
|
||||
}
|
||||
|
||||
List<String> parenthesized = clauses.stream()
|
||||
.map(c -> "(" + c + ")")
|
||||
.collect(Collectors.toList());
|
||||
|
||||
return "\nWHERE " + String.join("\n AND ", parenthesized) + "\n";
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a [column] LIKE sql clause.
|
||||
*
|
||||
* @param column The column identifier.
|
||||
* @param likeString The string that will be used as column comparison.
|
||||
* @param isLike if false, the statement becomes NOT LIKE.
|
||||
*
|
||||
* @return The generated statement.
|
||||
*/
|
||||
private static String getLikeClause(String column, String likeString, boolean isLike) {
|
||||
return column + (isLike ? "" : " NOT") + " LIKE '" + likeString + "'";
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves a list of the top programs used on the data source. Currently
|
||||
* determines this based off of which prefetch results return the highest
|
||||
* count.
|
||||
*
|
||||
* @param dataSource The data source.
|
||||
* @param count The number of programs to return.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public static List<TopProgramsResult> getTopPrograms(DataSource dataSource, int count) {
|
||||
if (dataSource == null || count <= 0) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
// ntosboot should be ignored
|
||||
final String ntosBootIdentifier = "NTOSBOOT";
|
||||
// programs in windows directory to be ignored
|
||||
final String windowsDir = "/WINDOWS%";
|
||||
|
||||
final String nameParam = "name";
|
||||
final String pathParam = "path";
|
||||
final String runCountParam = "run_count";
|
||||
final String lastRunParam = "last_run";
|
||||
|
||||
String bbaQuery = "bba";
|
||||
|
||||
final String query = "SELECT\n"
|
||||
+ " " + getFullKey(nameParam) + " AS " + nameParam + ",\n"
|
||||
+ " " + getFullKey(pathParam) + " AS " + pathParam + ",\n"
|
||||
+ " MAX(" + getFullKey(runCountParam) + ") AS " + runCountParam + ",\n"
|
||||
+ " MAX(" + getFullKey(lastRunParam) + ") AS " + lastRunParam + "\n"
|
||||
+ "FROM blackboard_artifacts " + bbaQuery + "\n"
|
||||
+ getAttributeJoin(JoinType.INNER, AttributeColumn.value_text, BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PROG_NAME, nameParam, bbaQuery)
|
||||
+ getAttributeJoin(JoinType.LEFT, AttributeColumn.value_text, BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PATH, pathParam, bbaQuery)
|
||||
+ getAttributeJoin(JoinType.LEFT, AttributeColumn.value_int32, BlackboardAttribute.ATTRIBUTE_TYPE.TSK_COUNT, runCountParam, bbaQuery)
|
||||
+ getAttributeJoin(JoinType.LEFT, AttributeColumn.value_int64, BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME, lastRunParam, bbaQuery)
|
||||
+ getWhereString(Arrays.asList(
|
||||
bbaQuery + ".artifact_type_id = " + BlackboardArtifact.ARTIFACT_TYPE.TSK_PROG_RUN.getTypeID(),
|
||||
bbaQuery + ".data_source_obj_id = " + dataSource.getId(),
|
||||
// exclude ntosBootIdentifier from results
|
||||
getLikeClause(getFullKey(nameParam), ntosBootIdentifier, false),
|
||||
// exclude windows directory items from results
|
||||
getFullKey(pathParam) + " IS NULL OR " + getLikeClause(getFullKey(pathParam), windowsDir, false)
|
||||
))
|
||||
+ "GROUP BY " + getFullKey(nameParam) + ", " + getFullKey(pathParam) + "\n"
|
||||
+ "ORDER BY \n"
|
||||
+ " MAX(" + getFullKey(runCountParam) + ") DESC,\n"
|
||||
+ " MAX(" + getFullKey(lastRunParam) + ") DESC,\n"
|
||||
+ " " + getFullKey(nameParam) + " ASC";
|
||||
|
||||
final String errorMessage = "Unable to get top program results; returning null.";
|
||||
|
||||
DataSourceInfoUtilities.ResultSetHandler<List<TopProgramsResult>> handler = (resultSet) -> {
|
||||
List<TopProgramsResult> progResults = new ArrayList<>();
|
||||
|
||||
boolean quitAtCount = false;
|
||||
|
||||
while (resultSet.next() && (!quitAtCount || progResults.size() < count)) {
|
||||
try {
|
||||
long lastRunEpoch = resultSet.getLong(lastRunParam);
|
||||
Date lastRun = (resultSet.wasNull()) ? null : new Date(lastRunEpoch * 1000);
|
||||
|
||||
Long runCount = resultSet.getLong(runCountParam);
|
||||
if (resultSet.wasNull()) {
|
||||
runCount = null;
|
||||
}
|
||||
|
||||
if (lastRun != null || runCount != null) {
|
||||
quitAtCount = true;
|
||||
}
|
||||
|
||||
progResults.add(new TopProgramsResult(
|
||||
resultSet.getString(nameParam),
|
||||
resultSet.getString(pathParam),
|
||||
runCount,
|
||||
lastRun));
|
||||
|
||||
} catch (SQLException ex) {
|
||||
logger.log(Level.WARNING, "Failed to get a top program result from the result set.", ex);
|
||||
}
|
||||
}
|
||||
|
||||
return progResults;
|
||||
};
|
||||
|
||||
return getBaseQueryResult(query, handler, errorMessage);
|
||||
}
|
||||
|
||||
/**
|
||||
* Functions that determine the folder name of a list of path elements. If
|
||||
* not matched, function returns null.
|
||||
*/
|
||||
private static final List<Function<List<String>, String>> SHORT_FOLDER_MATCHERS = Arrays.asList(
|
||||
// handle Program Files and Program Files (x86) - if true, return the next folder
|
||||
(pathList) -> {
|
||||
if (pathList.size() < 2) {
|
||||
return null;
|
||||
}
|
||||
|
||||
String rootParent = pathList.get(0).toUpperCase();
|
||||
if ("PROGRAM FILES".equals(rootParent) || "PROGRAM FILES (X86)".equals(rootParent)) {
|
||||
return pathList.get(1);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
},
|
||||
// if there is a folder named "APPLICATION DATA" or "APPDATA"
|
||||
(pathList) -> {
|
||||
for (String pathEl : pathList) {
|
||||
String uppered = pathEl.toUpperCase();
|
||||
if ("APPLICATION DATA".equals(uppered) || "APPDATA".equals(uppered)) {
|
||||
return "AppData";
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
);
|
||||
|
||||
/**
|
||||
* Determines a short folder name if any. Otherwise, returns empty string.
|
||||
*
|
||||
* @param strPath The string path.
|
||||
*
|
||||
* @return The short folder name or empty string if not found.
|
||||
*/
|
||||
public static String getShortFolderName(String strPath, String applicationName) {
|
||||
if (strPath == null) {
|
||||
return "";
|
||||
}
|
||||
|
||||
List<String> pathEls = new ArrayList<>(Arrays.asList(applicationName));
|
||||
|
||||
File file = new File(strPath);
|
||||
while (file != null && StringUtils.isNotBlank(file.getName())) {
|
||||
pathEls.add(file.getName());
|
||||
file = file.getParentFile();
|
||||
}
|
||||
|
||||
Collections.reverse(pathEls);
|
||||
|
||||
for (Function<List<String>, String> matchEntry : SHORT_FOLDER_MATCHERS) {
|
||||
String result = matchEntry.apply(pathEls);
|
||||
if (StringUtils.isNotBlank(result)) {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
private DataSourceTopProgramsSummary() {
|
||||
}
|
||||
}
|
@ -0,0 +1,74 @@
|
||||
/*
|
||||
* Autopsy Forensic Browser
|
||||
*
|
||||
* Copyright 2020 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.datasourcesummary.datamodel;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* Describes a result of a program run on a datasource.
|
||||
*/
|
||||
public class TopProgramsResult {
|
||||
|
||||
private final String programName;
|
||||
private final String programPath;
|
||||
private final Long runTimes;
|
||||
private final Date lastRun;
|
||||
|
||||
/**
|
||||
* Main constructor.
|
||||
*
|
||||
* @param programName The name of the program.
|
||||
* @param programPath The path of the program.
|
||||
* @param runTimes The number of runs.
|
||||
*/
|
||||
TopProgramsResult(String programName, String programPath, Long runTimes, Date lastRun) {
|
||||
this.programName = programName;
|
||||
this.programPath = programPath;
|
||||
this.runTimes = runTimes;
|
||||
this.lastRun = lastRun;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The name of the program
|
||||
*/
|
||||
public String getProgramName() {
|
||||
return programName;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The path of the program.
|
||||
*/
|
||||
public String getProgramPath() {
|
||||
return programPath;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The number of run times or null if not present.
|
||||
*/
|
||||
public Long getRunTimes() {
|
||||
return runTimes;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The last time the program was run or null if not present.
|
||||
*/
|
||||
public Date getLastRun() {
|
||||
return lastRun;
|
||||
}
|
||||
}
|
@ -33,6 +33,6 @@ DataSourceSummaryDetailsPanel.acquisitionDetailsTextArea.text=
|
||||
DataSourceSummaryDetailsPanel.acquisitionDetailsLabel.text=Acquisition Details:
|
||||
DataSourceSummaryDetailsPanel.unallocatedSizeLabel.text=Unallocated Space:
|
||||
DataSourceSummaryDetailsPanel.unallocatedSizeValue.text=
|
||||
DataSourceSummaryCountsPanel.byMimeTypeLabel.text=Files by MIME Type
|
||||
DataSourceSummaryCountsPanel.byCategoryLabel.text=Files by Category
|
||||
DataSourceSummaryCountsPanel.jLabel1.text=Results by Type
|
||||
DataSourceSummaryCountsPanel.resultsByTypeLabel.text=Results by Type
|
||||
DataSourceSummaryUserActivityPanel.programsRunLabel.text=Top Programs Run
|
@ -1,4 +1,7 @@
|
||||
CTL_DataSourceSummaryAction=Data Source Summary
|
||||
DataSourceSummaryCountsPanel.ArtifactCountsTableModel.count.header=Count
|
||||
DataSourceSummaryCountsPanel.ArtifactCountsTableModel.type.header=Result Type
|
||||
DataSourceSummaryCountsPanel.byMimeTypeLabel.text=Files by MIME Type
|
||||
DataSourceSummaryCountsPanel.FilesByCategoryTableModel.all.row=All
|
||||
DataSourceSummaryCountsPanel.FilesByCategoryTableModel.allocated.row=Allocated
|
||||
DataSourceSummaryCountsPanel.FilesByCategoryTableModel.count.header=Count
|
||||
@ -7,12 +10,12 @@ DataSourceSummaryCountsPanel.FilesByCategoryTableModel.slack.row=Slack
|
||||
DataSourceSummaryCountsPanel.FilesByCategoryTableModel.type.header=File Type
|
||||
DataSourceSummaryCountsPanel.FilesByCategoryTableModel.unallocated.row=Unallocated
|
||||
DataSourceSummaryCountsPanel.FilesByMimeTypeTableModel.audio.row=Audio
|
||||
DataSourceSummaryCountsPanel.FilesByMimeTypeTableModel.count.header=Count
|
||||
DataSourceSummaryCountsPanel.FilesByMimeTypeTableModel.documents.row=Documents
|
||||
DataSourceSummaryCountsPanel.FilesByMimeTypeTableModel.executables.row=Executables
|
||||
DataSourceSummaryCountsPanel.FilesByMimeTypeTableModel.images.row=Images
|
||||
DataSourceSummaryCountsPanel.FilesByMimeTypeTableModel.type.header=File Type
|
||||
DataSourceSummaryCountsPanel.FilesByMimeTypeTableModel.videos.row=Videos
|
||||
DataSourceSummaryCountsPanel_FilesByMimeTypeTableModel_notAnalyzed_label=Not Analyzed
|
||||
DataSourceSummaryCountsPanel_FilesByMimeTypeTableModel_other_label=Other
|
||||
DataSourceSummaryDetailsPanel.getDataSources.error.text=Failed to get the list of datasources for the current case.
|
||||
DataSourceSummaryDetailsPanel.getDataSources.error.title=Load Failure
|
||||
DataSourceSummaryDetailsPanel.units.bytes=\ bytes
|
||||
@ -56,12 +59,8 @@ DataSourceSummaryDetailsPanel.acquisitionDetailsTextArea.text=
|
||||
DataSourceSummaryDetailsPanel.acquisitionDetailsLabel.text=Acquisition Details:
|
||||
DataSourceSummaryDetailsPanel.unallocatedSizeLabel.text=Unallocated Space:
|
||||
DataSourceSummaryDetailsPanel.unallocatedSizeValue.text=
|
||||
DataSourceSummaryCountsPanel.byMimeTypeLabel.text=Files by MIME Type
|
||||
DataSourceSummaryCountsPanel.byCategoryLabel.text=Files by Category
|
||||
DataSourceSummaryCountsPanel.jLabel1.text=Results by Type
|
||||
DataSourceSummaryDialog.countsTab.title=Counts
|
||||
DataSourceSummaryDialog.detailsTab.title=Details
|
||||
DataSourceSummaryDialog.ingestHistoryTab.title=Ingest History
|
||||
DataSourceSummaryCountsPanel.resultsByTypeLabel.text=Results by Type
|
||||
DataSourceSummaryDialog.window.title=Data Sources Summary
|
||||
DataSourceSummaryNode.column.dataSourceName.header=Data Source Name
|
||||
DataSourceSummaryNode.column.files.header=Files
|
||||
@ -70,4 +69,14 @@ DataSourceSummaryNode.column.status.header=Ingest Status
|
||||
DataSourceSummaryNode.column.tags.header=Tags
|
||||
DataSourceSummaryNode.column.type.header=Type
|
||||
DataSourceSummaryNode.viewDataSourceAction.text=Go to Data Source
|
||||
DataSourceSummaryTabbedPane_countsTab_title=Counts
|
||||
DataSourceSummaryTabbedPane_detailsTab_title=Details
|
||||
DataSourceSummaryTabbedPane_ingestHistoryTab_title=Ingest History
|
||||
DataSourceSummaryTabbedPane_userActivityTab_title=User Activity
|
||||
DataSourceSummaryUserActivityPanel.programsRunLabel.text=Top Programs Run
|
||||
DataSourceSummaryUserActivityPanel_tab_title=User Activity
|
||||
DataSourceSummaryUserActivityPanel_TopProgramsTableModel_count_header=Run Times
|
||||
DataSourceSummaryUserActivityPanel_TopProgramsTableModel_folder_header=Folder
|
||||
DataSourceSummaryUserActivityPanel_TopProgramsTableModel_lastrun_header=Last Run
|
||||
DataSourceSummaryUserActivityPanel_TopProgramsTableModel_name_header=Program
|
||||
ViewSummaryInformationAction.name.text=View Summary Information
|
@ -16,7 +16,7 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.sleuthkit.autopsy.casemodule.datasourcesummary;
|
||||
package org.sleuthkit.autopsy.datasourcesummary.ui;
|
||||
|
||||
import java.awt.EventQueue;
|
||||
import java.beans.PropertyVetoException;
|
||||
@ -35,10 +35,11 @@ import javax.swing.event.ListSelectionListener;
|
||||
import org.openide.nodes.Node;
|
||||
import org.sleuthkit.autopsy.casemodule.Case;
|
||||
import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException;
|
||||
import org.sleuthkit.autopsy.casemodule.datasourcesummary.DataSourceSummaryNode.DataSourceSummaryEntryNode;
|
||||
import org.sleuthkit.autopsy.datasourcesummary.ui.DataSourceSummaryNode.DataSourceSummaryEntryNode;
|
||||
import static javax.swing.SwingConstants.RIGHT;
|
||||
import javax.swing.SwingUtilities;
|
||||
import javax.swing.table.TableColumn;
|
||||
import org.sleuthkit.autopsy.datasourcesummary.datamodel.CaseDataSourcesSummary;
|
||||
import org.sleuthkit.datamodel.DataSource;
|
||||
import org.sleuthkit.datamodel.IngestJobInfo;
|
||||
import org.sleuthkit.datamodel.SleuthkitCase;
|
||||
@ -152,8 +153,8 @@ final class DataSourceBrowser extends javax.swing.JPanel implements ExplorerMana
|
||||
private List<DataSourceSummary> getDataSourceSummaryList(Map<Long, String> usageMap, Map<Long, Long> fileCountsMap) {
|
||||
List<DataSourceSummary> summaryList = new ArrayList<>();
|
||||
|
||||
final Map<Long, Long> artifactCountsMap = DataSourceInfoUtilities.getCountsOfArtifacts();
|
||||
final Map<Long, Long> tagCountsMap = DataSourceInfoUtilities.getCountsOfTags();
|
||||
final Map<Long, Long> artifactCountsMap = CaseDataSourcesSummary.getCountsOfArtifacts();
|
||||
final Map<Long, Long> tagCountsMap = CaseDataSourcesSummary.getCountsOfTags();
|
||||
try {
|
||||
SleuthkitCase skCase = Case.getCurrentCaseThrows().getSleuthkitCase();
|
||||
for (DataSource dataSource : skCase.getDataSources()) {
|
@ -16,7 +16,7 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.sleuthkit.autopsy.casemodule.datasourcesummary;
|
||||
package org.sleuthkit.autopsy.datasourcesummary.ui;
|
||||
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
@ -16,7 +16,7 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.sleuthkit.autopsy.casemodule.datasourcesummary;
|
||||
package org.sleuthkit.autopsy.datasourcesummary.ui;
|
||||
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.beans.PropertyChangeEvent;
|
||||
@ -28,6 +28,7 @@ import org.openide.util.HelpCtx;
|
||||
import org.openide.util.NbBundle.Messages;
|
||||
import org.openide.util.actions.CallableSystemAction;
|
||||
import org.sleuthkit.autopsy.casemodule.Case;
|
||||
import org.sleuthkit.autopsy.datasourcesummary.ui.Bundle;
|
||||
|
||||
@ActionID(category = "Case", id = "org.sleuthkit.autopsy.casemodule.datasourcesummary.DataSourceSummaryAction")
|
||||
@ActionRegistration(displayName = "#CTL_DataSourceSummaryAction", lazy = false)
|
@ -0,0 +1,222 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
|
||||
<Form version="1.8" maxVersion="1.9" type="org.netbeans.modules.form.forminfo.JPanelFormInfo">
|
||||
<AuxValues>
|
||||
<AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="1"/>
|
||||
<AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/>
|
||||
<AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/>
|
||||
<AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="true"/>
|
||||
<AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="true"/>
|
||||
<AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/>
|
||||
<AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/>
|
||||
<AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/>
|
||||
<AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/>
|
||||
</AuxValues>
|
||||
|
||||
<Layout>
|
||||
<DimensionLayout dim="0">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Component id="scrollParent" alignment="0" max="32767" attributes="0"/>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
<DimensionLayout dim="1">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Component id="scrollParent" alignment="0" max="32767" attributes="0"/>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
</Layout>
|
||||
<SubComponents>
|
||||
<Container class="javax.swing.JScrollPane" name="scrollParent">
|
||||
<AuxValues>
|
||||
<AuxValue name="JavaCodeGenerator_VariableLocal" type="java.lang.Boolean" value="true"/>
|
||||
<AuxValue name="JavaCodeGenerator_VariableModifier" type="java.lang.Integer" value="0"/>
|
||||
</AuxValues>
|
||||
|
||||
<Layout class="org.netbeans.modules.form.compat2.layouts.support.JScrollPaneSupportLayout"/>
|
||||
<SubComponents>
|
||||
<Container class="javax.swing.JPanel" name="parentPanel">
|
||||
<Properties>
|
||||
<Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||
<Dimension value="[840, 320]"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<AuxValues>
|
||||
<AuxValue name="JavaCodeGenerator_VariableLocal" type="java.lang.Boolean" value="true"/>
|
||||
<AuxValue name="JavaCodeGenerator_VariableModifier" type="java.lang.Integer" value="0"/>
|
||||
</AuxValues>
|
||||
|
||||
<Layout>
|
||||
<DimensionLayout dim="0">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Group type="102" attributes="0">
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="fileTypePiePanel" min="-2" pref="400" max="-2" attributes="0"/>
|
||||
<EmptySpace type="separate" max="-2" attributes="0"/>
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Component id="fileCountsByCategoryScrollPane" alignment="0" min="-2" pref="140" max="-2" attributes="0"/>
|
||||
<Component id="byCategoryLabel" alignment="0" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="filesByCatParent" min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<EmptySpace type="separate" max="-2" attributes="0"/>
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Component id="resultsByTypeLabel" min="-2" pref="79" max="-2" attributes="0"/>
|
||||
<Group type="102" attributes="0">
|
||||
<Component id="artifactCountsScrollPane" min="-2" pref="244" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="resultsByTypeParent" min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
<EmptySpace max="32767" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
<DimensionLayout dim="1">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Group type="102" attributes="0">
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Group type="102" alignment="0" attributes="0">
|
||||
<Component id="fileTypePiePanel" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace max="32767" attributes="0"/>
|
||||
</Group>
|
||||
<Group type="102" alignment="0" attributes="0">
|
||||
<Group type="103" groupAlignment="3" attributes="0">
|
||||
<Component id="byCategoryLabel" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="resultsByTypeLabel" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Group type="102" alignment="1" attributes="0">
|
||||
<EmptySpace max="32767" attributes="0"/>
|
||||
<Component id="resultsByTypeParent" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace min="-2" pref="148" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<Group type="102" alignment="0" attributes="0">
|
||||
<EmptySpace min="-2" max="-2" attributes="0"/>
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Component id="artifactCountsScrollPane" pref="0" max="32767" attributes="0"/>
|
||||
<Group type="102" attributes="0">
|
||||
<Component id="fileCountsByCategoryScrollPane" min="-2" pref="107" max="-2" attributes="0"/>
|
||||
<EmptySpace min="-2" pref="31" max="-2" attributes="0"/>
|
||||
<Component id="filesByCatParent" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace min="0" pref="0" max="32767" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
</Group>
|
||||
</Group>
|
||||
</Group>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
</Layout>
|
||||
<SubComponents>
|
||||
<Container class="javax.swing.JScrollPane" name="fileCountsByCategoryScrollPane">
|
||||
<AuxValues>
|
||||
<AuxValue name="JavaCodeGenerator_VariableLocal" type="java.lang.Boolean" value="true"/>
|
||||
<AuxValue name="JavaCodeGenerator_VariableModifier" type="java.lang.Integer" value="0"/>
|
||||
<AuxValue name="autoScrollPane" type="java.lang.Boolean" value="true"/>
|
||||
</AuxValues>
|
||||
|
||||
<Layout class="org.netbeans.modules.form.compat2.layouts.support.JScrollPaneSupportLayout"/>
|
||||
<SubComponents>
|
||||
<Component class="javax.swing.JTable" name="fileCountsByCategoryTable">
|
||||
</Component>
|
||||
</SubComponents>
|
||||
</Container>
|
||||
<Component class="javax.swing.JLabel" name="byCategoryLabel">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/datasourcesummary/ui/Bundle.properties" key="DataSourceSummaryCountsPanel.byCategoryLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<AuxValues>
|
||||
<AuxValue name="JavaCodeGenerator_VariableLocal" type="java.lang.Boolean" value="true"/>
|
||||
<AuxValue name="JavaCodeGenerator_VariableModifier" type="java.lang.Integer" value="0"/>
|
||||
</AuxValues>
|
||||
</Component>
|
||||
<Component class="javax.swing.JLabel" name="resultsByTypeLabel">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/datasourcesummary/ui/Bundle.properties" key="DataSourceSummaryCountsPanel.resultsByTypeLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<AuxValues>
|
||||
<AuxValue name="JavaCodeGenerator_VariableLocal" type="java.lang.Boolean" value="true"/>
|
||||
<AuxValue name="JavaCodeGenerator_VariableModifier" type="java.lang.Integer" value="0"/>
|
||||
</AuxValues>
|
||||
</Component>
|
||||
<Container class="javax.swing.JScrollPane" name="artifactCountsScrollPane">
|
||||
<AuxValues>
|
||||
<AuxValue name="JavaCodeGenerator_VariableLocal" type="java.lang.Boolean" value="true"/>
|
||||
<AuxValue name="JavaCodeGenerator_VariableModifier" type="java.lang.Integer" value="0"/>
|
||||
<AuxValue name="autoScrollPane" type="java.lang.Boolean" value="true"/>
|
||||
</AuxValues>
|
||||
|
||||
<Layout class="org.netbeans.modules.form.compat2.layouts.support.JScrollPaneSupportLayout"/>
|
||||
<SubComponents>
|
||||
<Component class="javax.swing.JTable" name="artifactCountsTable">
|
||||
<Properties>
|
||||
<Property name="autoCreateRowSorter" type="boolean" value="true"/>
|
||||
</Properties>
|
||||
</Component>
|
||||
</SubComponents>
|
||||
</Container>
|
||||
<Container class="javax.swing.JPanel" name="fileTypePiePanel">
|
||||
<Properties>
|
||||
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||
<Dimension value="[400, 300]"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<AuxValues>
|
||||
<AuxValue name="JavaCodeGenerator_CreateCodeCustom" type="java.lang.String" value="fileTypePieChart"/>
|
||||
<AuxValue name="JavaCodeGenerator_VariableLocal" type="java.lang.Boolean" value="true"/>
|
||||
<AuxValue name="JavaCodeGenerator_VariableModifier" type="java.lang.Integer" value="0"/>
|
||||
</AuxValues>
|
||||
|
||||
<Layout class="org.netbeans.modules.form.compat2.layouts.DesignFlowLayout"/>
|
||||
</Container>
|
||||
<Container class="javax.swing.JPanel" name="filesByCatParent">
|
||||
<AuxValues>
|
||||
<AuxValue name="JavaCodeGenerator_VariableLocal" type="java.lang.Boolean" value="true"/>
|
||||
<AuxValue name="JavaCodeGenerator_VariableModifier" type="java.lang.Integer" value="0"/>
|
||||
</AuxValues>
|
||||
|
||||
<Layout>
|
||||
<DimensionLayout dim="0">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<EmptySpace min="0" pref="0" max="32767" attributes="0"/>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
<DimensionLayout dim="1">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<EmptySpace min="0" pref="0" max="32767" attributes="0"/>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
</Layout>
|
||||
</Container>
|
||||
<Container class="javax.swing.JPanel" name="resultsByTypeParent">
|
||||
<AuxValues>
|
||||
<AuxValue name="JavaCodeGenerator_VariableLocal" type="java.lang.Boolean" value="true"/>
|
||||
<AuxValue name="JavaCodeGenerator_VariableModifier" type="java.lang.Integer" value="0"/>
|
||||
</AuxValues>
|
||||
|
||||
<Layout>
|
||||
<DimensionLayout dim="0">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<EmptySpace min="0" pref="0" max="32767" attributes="0"/>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
<DimensionLayout dim="1">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<EmptySpace min="0" pref="0" max="32767" attributes="0"/>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
</Layout>
|
||||
</Container>
|
||||
</SubComponents>
|
||||
</Container>
|
||||
</SubComponents>
|
||||
</Container>
|
||||
</SubComponents>
|
||||
</Form>
|
@ -0,0 +1,304 @@
|
||||
/*
|
||||
* Autopsy Forensic Browser
|
||||
*
|
||||
* Copyright 2019 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.datasourcesummary.ui;
|
||||
|
||||
import java.util.Map;
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.table.DefaultTableCellRenderer;
|
||||
import org.openide.util.NbBundle.Messages;
|
||||
import org.sleuthkit.autopsy.casemodule.Case;
|
||||
import org.sleuthkit.autopsy.datasourcesummary.datamodel.DataSourceCountsSummary;
|
||||
|
||||
import org.sleuthkit.datamodel.DataSource;
|
||||
|
||||
/**
|
||||
* Panel for displaying summary information on the known files present in the
|
||||
* specified DataSource
|
||||
*/
|
||||
@Messages({
|
||||
"DataSourceSummaryCountsPanel.ArtifactCountsTableModel.type.header=Result Type",
|
||||
"DataSourceSummaryCountsPanel.ArtifactCountsTableModel.count.header=Count",
|
||||
"DataSourceSummaryCountsPanel.FilesByCategoryTableModel.type.header=File Type",
|
||||
"DataSourceSummaryCountsPanel.FilesByCategoryTableModel.count.header=Count"
|
||||
})
|
||||
final class DataSourceSummaryCountsPanel extends javax.swing.JPanel {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
// Result returned for a data model if no data found.
|
||||
private static final Object[][] EMPTY_PAIRS = new Object[][]{};
|
||||
|
||||
// column headers for file by category table
|
||||
private static final Object[] FILE_BY_CATEGORY_COLUMN_HEADERS = new Object[]{
|
||||
Bundle.DataSourceSummaryCountsPanel_FilesByCategoryTableModel_type_header(),
|
||||
Bundle.DataSourceSummaryCountsPanel_FilesByCategoryTableModel_count_header()
|
||||
};
|
||||
|
||||
// column headers for artifact counts table
|
||||
private static final Object[] ARTIFACT_COUNTS_COLUMN_HEADERS = new Object[]{
|
||||
Bundle.DataSourceSummaryCountsPanel_ArtifactCountsTableModel_type_header(),
|
||||
Bundle.DataSourceSummaryCountsPanel_ArtifactCountsTableModel_count_header()
|
||||
};
|
||||
|
||||
private final DefaultTableCellRenderer rightAlignedRenderer = new DefaultTableCellRenderer();
|
||||
|
||||
private final FileTypePieChart fileTypePieChart = new FileTypePieChart();
|
||||
|
||||
private DataSource dataSource;
|
||||
|
||||
/**
|
||||
* Creates new form DataSourceSummaryCountsPanel
|
||||
*/
|
||||
DataSourceSummaryCountsPanel() {
|
||||
rightAlignedRenderer.setHorizontalAlignment(JLabel.RIGHT);
|
||||
initComponents();
|
||||
fileCountsByCategoryTable.getTableHeader().setReorderingAllowed(false);
|
||||
artifactCountsTable.getTableHeader().setReorderingAllowed(false);
|
||||
setDataSource(null);
|
||||
}
|
||||
|
||||
/**
|
||||
* The datasource currently used as the model in this panel.
|
||||
*
|
||||
* @return The datasource currently being used as the model in this panel.
|
||||
*/
|
||||
public DataSource getDataSource() {
|
||||
return dataSource;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets datasource to visualize in the panel.
|
||||
*
|
||||
* @param dataSource The datasource to use in this panel.
|
||||
*/
|
||||
public void setDataSource(DataSource dataSource) {
|
||||
this.dataSource = dataSource;
|
||||
if (dataSource == null || !Case.isCaseOpen()) {
|
||||
updateCountsTableData(EMPTY_PAIRS, EMPTY_PAIRS);
|
||||
} else {
|
||||
updateCountsTableData(getFileCategoryModel(dataSource), getArtifactCountsModel(dataSource));
|
||||
}
|
||||
this.fileTypePieChart.setDataSource(dataSource);
|
||||
}
|
||||
|
||||
/**
|
||||
* Specify the DataSource to display file information for.
|
||||
*
|
||||
* @param fileCategoryDataModel The file category data model.
|
||||
* @param artifactDataModel The artifact type data model.
|
||||
*/
|
||||
private void updateCountsTableData(Object[][] fileCategoryDataModel, Object[][] artifactDataModel) {
|
||||
fileCountsByCategoryTable.setModel(new NonEditableTableModel(fileCategoryDataModel, FILE_BY_CATEGORY_COLUMN_HEADERS));
|
||||
fileCountsByCategoryTable.getColumnModel().getColumn(1).setCellRenderer(rightAlignedRenderer);
|
||||
fileCountsByCategoryTable.getColumnModel().getColumn(0).setPreferredWidth(130);
|
||||
|
||||
artifactCountsTable.setModel(new NonEditableTableModel(artifactDataModel, ARTIFACT_COUNTS_COLUMN_HEADERS));
|
||||
artifactCountsTable.getColumnModel().getColumn(0).setPreferredWidth(230);
|
||||
artifactCountsTable.getColumnModel().getColumn(1).setCellRenderer(rightAlignedRenderer);
|
||||
|
||||
this.repaint();
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines the JTable data model for datasource file categories.
|
||||
*
|
||||
* @param dataSource The DataSource.
|
||||
*
|
||||
* @return The model to be used with a JTable.
|
||||
*/
|
||||
@Messages({
|
||||
"DataSourceSummaryCountsPanel.FilesByCategoryTableModel.all.row=All",
|
||||
"DataSourceSummaryCountsPanel.FilesByCategoryTableModel.allocated.row=Allocated",
|
||||
"DataSourceSummaryCountsPanel.FilesByCategoryTableModel.unallocated.row=Unallocated",
|
||||
"DataSourceSummaryCountsPanel.FilesByCategoryTableModel.slack.row=Slack",
|
||||
"DataSourceSummaryCountsPanel.FilesByCategoryTableModel.directory.row=Directory"
|
||||
})
|
||||
private static Object[][] getFileCategoryModel(DataSource selectedDataSource) {
|
||||
Long fileCount = zeroIfNull(DataSourceCountsSummary.getCountOfFiles(selectedDataSource));
|
||||
Long unallocatedFiles = zeroIfNull(DataSourceCountsSummary.getCountOfUnallocatedFiles(selectedDataSource));
|
||||
Long allocatedFiles = zeroIfNull(DataSourceCountsSummary.getCountOfAllocatedFiles(selectedDataSource));
|
||||
Long slackFiles = zeroIfNull(DataSourceCountsSummary.getCountOfSlackFiles(selectedDataSource));
|
||||
Long directories = zeroIfNull(DataSourceCountsSummary.getCountOfDirectories(selectedDataSource));
|
||||
|
||||
return new Object[][]{
|
||||
new Object[]{Bundle.DataSourceSummaryCountsPanel_FilesByCategoryTableModel_all_row(), fileCount},
|
||||
new Object[]{Bundle.DataSourceSummaryCountsPanel_FilesByCategoryTableModel_allocated_row(), allocatedFiles},
|
||||
new Object[]{Bundle.DataSourceSummaryCountsPanel_FilesByCategoryTableModel_unallocated_row(), unallocatedFiles},
|
||||
new Object[]{Bundle.DataSourceSummaryCountsPanel_FilesByCategoryTableModel_slack_row(), slackFiles},
|
||||
new Object[]{Bundle.DataSourceSummaryCountsPanel_FilesByCategoryTableModel_directory_row(), directories}
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns 0 if value is null.
|
||||
*
|
||||
* @param origValue The original value.
|
||||
*
|
||||
* @return The value or 0 if null.
|
||||
*/
|
||||
private static Long zeroIfNull(Long origValue) {
|
||||
return origValue == null ? 0 : origValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* The counts of different artifact types found in a DataSource.
|
||||
*
|
||||
* @param selectedDataSource The DataSource.
|
||||
*
|
||||
* @return The JTable data model of counts of artifact types.
|
||||
*/
|
||||
private static Object[][] getArtifactCountsModel(DataSource selectedDataSource) {
|
||||
Map<String, Long> artifactMapping = DataSourceCountsSummary.getCountsOfArtifactsByType(selectedDataSource);
|
||||
if (artifactMapping == null) {
|
||||
return EMPTY_PAIRS;
|
||||
}
|
||||
|
||||
return artifactMapping.entrySet().stream()
|
||||
.filter((entrySet) -> entrySet != null && entrySet.getKey() != null)
|
||||
.sorted((a, b) -> a.getKey().compareTo(b.getKey()))
|
||||
.map((entrySet) -> new Object[]{entrySet.getKey(), entrySet.getValue()})
|
||||
.toArray(Object[][]::new);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is called from within the constructor to initialize the form.
|
||||
* WARNING: Do NOT modify this code. The content of this method is always
|
||||
* regenerated by the Form Editor.
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
// <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
|
||||
private void initComponents() {
|
||||
|
||||
javax.swing.JScrollPane scrollParent = new javax.swing.JScrollPane();
|
||||
javax.swing.JPanel parentPanel = new javax.swing.JPanel();
|
||||
javax.swing.JScrollPane fileCountsByCategoryScrollPane = new javax.swing.JScrollPane();
|
||||
fileCountsByCategoryTable = new javax.swing.JTable();
|
||||
javax.swing.JLabel byCategoryLabel = new javax.swing.JLabel();
|
||||
javax.swing.JLabel resultsByTypeLabel = new javax.swing.JLabel();
|
||||
javax.swing.JScrollPane artifactCountsScrollPane = new javax.swing.JScrollPane();
|
||||
artifactCountsTable = new javax.swing.JTable();
|
||||
javax.swing.JPanel fileTypePiePanel = fileTypePieChart;
|
||||
javax.swing.JPanel filesByCatParent = new javax.swing.JPanel();
|
||||
javax.swing.JPanel resultsByTypeParent = new javax.swing.JPanel();
|
||||
|
||||
parentPanel.setMinimumSize(new java.awt.Dimension(840, 320));
|
||||
|
||||
fileCountsByCategoryScrollPane.setViewportView(fileCountsByCategoryTable);
|
||||
|
||||
org.openide.awt.Mnemonics.setLocalizedText(byCategoryLabel, org.openide.util.NbBundle.getMessage(DataSourceSummaryCountsPanel.class, "DataSourceSummaryCountsPanel.byCategoryLabel.text")); // NOI18N
|
||||
|
||||
org.openide.awt.Mnemonics.setLocalizedText(resultsByTypeLabel, org.openide.util.NbBundle.getMessage(DataSourceSummaryCountsPanel.class, "DataSourceSummaryCountsPanel.resultsByTypeLabel.text")); // NOI18N
|
||||
|
||||
artifactCountsTable.setAutoCreateRowSorter(true);
|
||||
artifactCountsScrollPane.setViewportView(artifactCountsTable);
|
||||
|
||||
fileTypePiePanel.setPreferredSize(new java.awt.Dimension(400, 300));
|
||||
|
||||
javax.swing.GroupLayout filesByCatParentLayout = new javax.swing.GroupLayout(filesByCatParent);
|
||||
filesByCatParent.setLayout(filesByCatParentLayout);
|
||||
filesByCatParentLayout.setHorizontalGroup(
|
||||
filesByCatParentLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGap(0, 0, Short.MAX_VALUE)
|
||||
);
|
||||
filesByCatParentLayout.setVerticalGroup(
|
||||
filesByCatParentLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGap(0, 0, Short.MAX_VALUE)
|
||||
);
|
||||
|
||||
javax.swing.GroupLayout resultsByTypeParentLayout = new javax.swing.GroupLayout(resultsByTypeParent);
|
||||
resultsByTypeParent.setLayout(resultsByTypeParentLayout);
|
||||
resultsByTypeParentLayout.setHorizontalGroup(
|
||||
resultsByTypeParentLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGap(0, 0, Short.MAX_VALUE)
|
||||
);
|
||||
resultsByTypeParentLayout.setVerticalGroup(
|
||||
resultsByTypeParentLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGap(0, 0, Short.MAX_VALUE)
|
||||
);
|
||||
|
||||
javax.swing.GroupLayout parentPanelLayout = new javax.swing.GroupLayout(parentPanel);
|
||||
parentPanel.setLayout(parentPanelLayout);
|
||||
parentPanelLayout.setHorizontalGroup(
|
||||
parentPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGroup(parentPanelLayout.createSequentialGroup()
|
||||
.addContainerGap()
|
||||
.addComponent(fileTypePiePanel, javax.swing.GroupLayout.PREFERRED_SIZE, 400, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||
.addGap(18, 18, 18)
|
||||
.addGroup(parentPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addComponent(fileCountsByCategoryScrollPane, javax.swing.GroupLayout.PREFERRED_SIZE, 140, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||
.addComponent(byCategoryLabel)
|
||||
.addComponent(filesByCatParent, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
|
||||
.addGap(18, 18, 18)
|
||||
.addGroup(parentPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addComponent(resultsByTypeLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 79, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||
.addGroup(parentPanelLayout.createSequentialGroup()
|
||||
.addComponent(artifactCountsScrollPane, javax.swing.GroupLayout.PREFERRED_SIZE, 244, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(resultsByTypeParent, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)))
|
||||
.addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
|
||||
);
|
||||
parentPanelLayout.setVerticalGroup(
|
||||
parentPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGroup(parentPanelLayout.createSequentialGroup()
|
||||
.addContainerGap()
|
||||
.addGroup(parentPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGroup(parentPanelLayout.createSequentialGroup()
|
||||
.addComponent(fileTypePiePanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||
.addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
|
||||
.addGroup(parentPanelLayout.createSequentialGroup()
|
||||
.addGroup(parentPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
|
||||
.addComponent(byCategoryLabel)
|
||||
.addComponent(resultsByTypeLabel))
|
||||
.addGroup(parentPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, parentPanelLayout.createSequentialGroup()
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
||||
.addComponent(resultsByTypeParent, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||
.addGap(148, 148, 148))
|
||||
.addGroup(parentPanelLayout.createSequentialGroup()
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addGroup(parentPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addComponent(artifactCountsScrollPane, javax.swing.GroupLayout.PREFERRED_SIZE, 0, Short.MAX_VALUE)
|
||||
.addGroup(parentPanelLayout.createSequentialGroup()
|
||||
.addComponent(fileCountsByCategoryScrollPane, javax.swing.GroupLayout.PREFERRED_SIZE, 107, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||
.addGap(31, 31, 31)
|
||||
.addComponent(filesByCatParent, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||
.addGap(0, 0, Short.MAX_VALUE)))
|
||||
.addContainerGap())))))
|
||||
);
|
||||
|
||||
scrollParent.setViewportView(parentPanel);
|
||||
|
||||
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
|
||||
this.setLayout(layout);
|
||||
layout.setHorizontalGroup(
|
||||
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addComponent(scrollParent)
|
||||
);
|
||||
layout.setVerticalGroup(
|
||||
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addComponent(scrollParent)
|
||||
);
|
||||
}// </editor-fold>//GEN-END:initComponents
|
||||
|
||||
|
||||
// Variables declaration - do not modify//GEN-BEGIN:variables
|
||||
private javax.swing.JTable artifactCountsTable;
|
||||
private javax.swing.JTable fileCountsByCategoryTable;
|
||||
// End of variables declaration//GEN-END:variables
|
||||
}
|
@ -40,7 +40,7 @@
|
||||
<Component class="javax.swing.JLabel" name="operatingSystemLabel">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/casemodule/datasourcesummary/Bundle.properties" key="DataSourceSummaryDetailsPanel.operatingSystemLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/datasourcesummary/ui/Bundle.properties" key="DataSourceSummaryDetailsPanel.operatingSystemLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<Constraints>
|
||||
@ -52,7 +52,7 @@
|
||||
<Component class="javax.swing.JLabel" name="displayNameLabel">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/casemodule/datasourcesummary/Bundle.properties" key="DataSourceSummaryDetailsPanel.displayNameLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/datasourcesummary/ui/Bundle.properties" key="DataSourceSummaryDetailsPanel.displayNameLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<Constraints>
|
||||
@ -64,7 +64,7 @@
|
||||
<Component class="javax.swing.JLabel" name="originalNameLabel">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/casemodule/datasourcesummary/Bundle.properties" key="DataSourceSummaryDetailsPanel.originalNameLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/datasourcesummary/ui/Bundle.properties" key="DataSourceSummaryDetailsPanel.originalNameLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<Constraints>
|
||||
@ -76,7 +76,7 @@
|
||||
<Component class="javax.swing.JLabel" name="sha1HashValue">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/casemodule/datasourcesummary/Bundle.properties" key="DataSourceSummaryDetailsPanel.sha1HashValue.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/datasourcesummary/ui/Bundle.properties" key="DataSourceSummaryDetailsPanel.sha1HashValue.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<Constraints>
|
||||
@ -88,10 +88,10 @@
|
||||
<Component class="javax.swing.JLabel" name="operatingSystemValue">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/casemodule/datasourcesummary/Bundle.properties" key="DataSourceSummaryDetailsPanel.operatingSystemValue.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/datasourcesummary/ui/Bundle.properties" key="DataSourceSummaryDetailsPanel.operatingSystemValue.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/casemodule/datasourcesummary/Bundle.properties" key="DataSourceSummaryDetailsPanel.operatingSystemValue.toolTipText" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/datasourcesummary/ui/Bundle.properties" key="DataSourceSummaryDetailsPanel.operatingSystemValue.toolTipText" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<Constraints>
|
||||
@ -103,7 +103,7 @@
|
||||
<Component class="javax.swing.JLabel" name="displayNameValue">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/casemodule/datasourcesummary/Bundle.properties" key="DataSourceSummaryDetailsPanel.displayNameValue.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/datasourcesummary/ui/Bundle.properties" key="DataSourceSummaryDetailsPanel.displayNameValue.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<Constraints>
|
||||
@ -115,7 +115,7 @@
|
||||
<Component class="javax.swing.JLabel" name="sha256HashValue">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/casemodule/datasourcesummary/Bundle.properties" key="DataSourceSummaryDetailsPanel.sha256HashValue.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/datasourcesummary/ui/Bundle.properties" key="DataSourceSummaryDetailsPanel.sha256HashValue.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<Constraints>
|
||||
@ -127,7 +127,7 @@
|
||||
<Component class="javax.swing.JLabel" name="originalNameValue">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/casemodule/datasourcesummary/Bundle.properties" key="DataSourceSummaryDetailsPanel.originalNameValue.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/datasourcesummary/ui/Bundle.properties" key="DataSourceSummaryDetailsPanel.originalNameValue.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<Constraints>
|
||||
@ -139,10 +139,10 @@
|
||||
<Component class="javax.swing.JLabel" name="deviceIdValue">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/casemodule/datasourcesummary/Bundle.properties" key="DataSourceSummaryDetailsPanel.deviceIdValue.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/datasourcesummary/ui/Bundle.properties" key="DataSourceSummaryDetailsPanel.deviceIdValue.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/casemodule/datasourcesummary/Bundle.properties" key="DataSourceSummaryDetailsPanel.deviceIdValue.toolTipText" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/datasourcesummary/ui/Bundle.properties" key="DataSourceSummaryDetailsPanel.deviceIdValue.toolTipText" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<Constraints>
|
||||
@ -179,7 +179,7 @@
|
||||
<TableColumnModel selectionModel="0">
|
||||
<Column maxWidth="-1" minWidth="-1" prefWidth="-1" resizable="true">
|
||||
<Title editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/casemodule/datasourcesummary/Bundle.properties" key="DataSourceSummaryDetailsPanel.filePathsTable.columnModel.title0" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/datasourcesummary/ui/Bundle.properties" key="DataSourceSummaryDetailsPanel.filePathsTable.columnModel.title0" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Title>
|
||||
<Editor/>
|
||||
<Renderer/>
|
||||
@ -196,7 +196,7 @@
|
||||
<Component class="javax.swing.JLabel" name="dataSourceUsageValue">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/casemodule/datasourcesummary/Bundle.properties" key="DataSourceSummaryDetailsPanel.dataSourceUsageValue.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/datasourcesummary/ui/Bundle.properties" key="DataSourceSummaryDetailsPanel.dataSourceUsageValue.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<Constraints>
|
||||
@ -208,7 +208,7 @@
|
||||
<Component class="javax.swing.JLabel" name="timeZoneValue">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/casemodule/datasourcesummary/Bundle.properties" key="DataSourceSummaryDetailsPanel.timeZoneValue.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/datasourcesummary/ui/Bundle.properties" key="DataSourceSummaryDetailsPanel.timeZoneValue.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<Constraints>
|
||||
@ -220,10 +220,10 @@
|
||||
<Component class="javax.swing.JLabel" name="imageTypeValue">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/casemodule/datasourcesummary/Bundle.properties" key="DataSourceSummaryDetailsPanel.imageTypeValue.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/datasourcesummary/ui/Bundle.properties" key="DataSourceSummaryDetailsPanel.imageTypeValue.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/casemodule/datasourcesummary/Bundle.properties" key="DataSourceSummaryDetailsPanel.imageTypeValue.toolTipText" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/datasourcesummary/ui/Bundle.properties" key="DataSourceSummaryDetailsPanel.imageTypeValue.toolTipText" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<Constraints>
|
||||
@ -235,10 +235,10 @@
|
||||
<Component class="javax.swing.JLabel" name="md5HashValue">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/casemodule/datasourcesummary/Bundle.properties" key="DataSourceSummaryDetailsPanel.md5HashValue.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/datasourcesummary/ui/Bundle.properties" key="DataSourceSummaryDetailsPanel.md5HashValue.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/casemodule/datasourcesummary/Bundle.properties" key="DataSourceSummaryDetailsPanel.md5HashValue.toolTipText" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/datasourcesummary/ui/Bundle.properties" key="DataSourceSummaryDetailsPanel.md5HashValue.toolTipText" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<Constraints>
|
||||
@ -250,7 +250,7 @@
|
||||
<Component class="javax.swing.JLabel" name="sectorSizeValue">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/casemodule/datasourcesummary/Bundle.properties" key="DataSourceSummaryDetailsPanel.sectorSizeValue.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/datasourcesummary/ui/Bundle.properties" key="DataSourceSummaryDetailsPanel.sectorSizeValue.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<Constraints>
|
||||
@ -262,7 +262,7 @@
|
||||
<Component class="javax.swing.JLabel" name="sizeValue">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/casemodule/datasourcesummary/Bundle.properties" key="DataSourceSummaryDetailsPanel.sizeValue.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/datasourcesummary/ui/Bundle.properties" key="DataSourceSummaryDetailsPanel.sizeValue.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<Constraints>
|
||||
@ -274,7 +274,7 @@
|
||||
<Component class="javax.swing.JLabel" name="filePathsLabel">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/casemodule/datasourcesummary/Bundle.properties" key="DataSourceSummaryDetailsPanel.filePathsLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/datasourcesummary/ui/Bundle.properties" key="DataSourceSummaryDetailsPanel.filePathsLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<Constraints>
|
||||
@ -286,7 +286,7 @@
|
||||
<Component class="javax.swing.JLabel" name="sha256HashLabel">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/casemodule/datasourcesummary/Bundle.properties" key="DataSourceSummaryDetailsPanel.sha256HashLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/datasourcesummary/ui/Bundle.properties" key="DataSourceSummaryDetailsPanel.sha256HashLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<Constraints>
|
||||
@ -298,7 +298,7 @@
|
||||
<Component class="javax.swing.JLabel" name="sha1HashLabel">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/casemodule/datasourcesummary/Bundle.properties" key="DataSourceSummaryDetailsPanel.sha1HashLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/datasourcesummary/ui/Bundle.properties" key="DataSourceSummaryDetailsPanel.sha1HashLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<Constraints>
|
||||
@ -310,7 +310,7 @@
|
||||
<Component class="javax.swing.JLabel" name="md5HashLabel">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/casemodule/datasourcesummary/Bundle.properties" key="DataSourceSummaryDetailsPanel.md5HashLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/datasourcesummary/ui/Bundle.properties" key="DataSourceSummaryDetailsPanel.md5HashLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<Constraints>
|
||||
@ -322,7 +322,7 @@
|
||||
<Component class="javax.swing.JLabel" name="sectorSizeLabel">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/casemodule/datasourcesummary/Bundle.properties" key="DataSourceSummaryDetailsPanel.sectorSizeLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/datasourcesummary/ui/Bundle.properties" key="DataSourceSummaryDetailsPanel.sectorSizeLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<Constraints>
|
||||
@ -334,7 +334,7 @@
|
||||
<Component class="javax.swing.JLabel" name="sizeLabel">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/casemodule/datasourcesummary/Bundle.properties" key="DataSourceSummaryDetailsPanel.sizeLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/datasourcesummary/ui/Bundle.properties" key="DataSourceSummaryDetailsPanel.sizeLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<Constraints>
|
||||
@ -346,7 +346,7 @@
|
||||
<Component class="javax.swing.JLabel" name="imageTypeLabel">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/casemodule/datasourcesummary/Bundle.properties" key="DataSourceSummaryDetailsPanel.imageTypeLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/datasourcesummary/ui/Bundle.properties" key="DataSourceSummaryDetailsPanel.imageTypeLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<Constraints>
|
||||
@ -358,7 +358,7 @@
|
||||
<Component class="javax.swing.JLabel" name="acquisitionDetailsLabel">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/casemodule/datasourcesummary/Bundle.properties" key="DataSourceSummaryDetailsPanel.acquisitionDetailsLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/datasourcesummary/ui/Bundle.properties" key="DataSourceSummaryDetailsPanel.acquisitionDetailsLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<Constraints>
|
||||
@ -370,7 +370,7 @@
|
||||
<Component class="javax.swing.JLabel" name="timeZoneLabel">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/casemodule/datasourcesummary/Bundle.properties" key="DataSourceSummaryDetailsPanel.timeZoneLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/datasourcesummary/ui/Bundle.properties" key="DataSourceSummaryDetailsPanel.timeZoneLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<Constraints>
|
||||
@ -382,7 +382,7 @@
|
||||
<Component class="javax.swing.JLabel" name="dataSourceUsageLabel">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/casemodule/datasourcesummary/Bundle.properties" key="DataSourceSummaryDetailsPanel.dataSourceUsageLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/datasourcesummary/ui/Bundle.properties" key="DataSourceSummaryDetailsPanel.dataSourceUsageLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<Constraints>
|
||||
@ -394,7 +394,7 @@
|
||||
<Component class="javax.swing.JLabel" name="deviceIdLabel">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/casemodule/datasourcesummary/Bundle.properties" key="DataSourceSummaryDetailsPanel.deviceIdLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/datasourcesummary/ui/Bundle.properties" key="DataSourceSummaryDetailsPanel.deviceIdLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<Constraints>
|
||||
@ -424,7 +424,7 @@
|
||||
<Property name="columns" type="int" value="20"/>
|
||||
<Property name="rows" type="int" value="4"/>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/casemodule/datasourcesummary/Bundle.properties" key="DataSourceSummaryDetailsPanel.acquisitionDetailsTextArea.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/datasourcesummary/ui/Bundle.properties" key="DataSourceSummaryDetailsPanel.acquisitionDetailsTextArea.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
<Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor">
|
||||
<Border info="null"/>
|
||||
@ -466,7 +466,7 @@
|
||||
<Component class="javax.swing.JLabel" name="unallocatedSizeLabel">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/casemodule/datasourcesummary/Bundle.properties" key="DataSourceSummaryDetailsPanel.unallocatedSizeLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/datasourcesummary/ui/Bundle.properties" key="DataSourceSummaryDetailsPanel.unallocatedSizeLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<Constraints>
|
||||
@ -478,7 +478,7 @@
|
||||
<Component class="javax.swing.JLabel" name="unallocatedSizeValue">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/casemodule/datasourcesummary/Bundle.properties" key="DataSourceSummaryDetailsPanel.unallocatedSizeValue.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/datasourcesummary/ui/Bundle.properties" key="DataSourceSummaryDetailsPanel.unallocatedSizeValue.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<Constraints>
|
@ -16,15 +16,16 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.sleuthkit.autopsy.casemodule.datasourcesummary;
|
||||
package org.sleuthkit.autopsy.datasourcesummary.ui;
|
||||
|
||||
import java.text.DecimalFormat;
|
||||
import java.util.Map;
|
||||
import java.util.HashMap;
|
||||
import java.util.logging.Level;
|
||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||
import javax.swing.table.DefaultTableModel;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.openide.util.NbBundle.Messages;
|
||||
import org.sleuthkit.autopsy.casemodule.Case;
|
||||
import org.sleuthkit.autopsy.datasourcesummary.datamodel.DataSourceDetailsSummary;
|
||||
import org.sleuthkit.datamodel.DataSource;
|
||||
import org.sleuthkit.datamodel.Image;
|
||||
import org.sleuthkit.datamodel.TskCoreException;
|
||||
@ -36,23 +37,47 @@ class DataSourceSummaryDetailsPanel extends javax.swing.JPanel {
|
||||
|
||||
//Because this panel was made using the gridbaglayout and netbean's Customize Layout tool it will be best to continue to modify it through that
|
||||
private static final long serialVersionUID = 1L;
|
||||
private Map<Long, String> osDetailMap = new HashMap<>();
|
||||
private static final Integer SIZE_COVERSION_CONSTANT = 1000;
|
||||
private static final DecimalFormat APPROXIMATE_SIZE_FORMAT = new DecimalFormat("#.##");
|
||||
private final Map<Long, Long> unallocatedFilesSizeMap;
|
||||
private final Map<Long, String> usageMap;
|
||||
private static final Logger logger = Logger.getLogger(DataSourceSummaryDetailsPanel.class.getName());
|
||||
|
||||
private DataSource dataSource;
|
||||
|
||||
/**
|
||||
* Creates new form DataSourceSummaryDetailsPanel
|
||||
*/
|
||||
@Messages({"DataSourceSummaryDetailsPanel.getDataSources.error.text=Failed to get the list of datasources for the current case.",
|
||||
"DataSourceSummaryDetailsPanel.getDataSources.error.title=Load Failure"})
|
||||
DataSourceSummaryDetailsPanel(Map<Long, String> usageMap) {
|
||||
DataSourceSummaryDetailsPanel() {
|
||||
initComponents();
|
||||
this.usageMap = usageMap;
|
||||
this.unallocatedFilesSizeMap = DataSourceInfoUtilities.getSizeOfUnallocatedFiles();
|
||||
osDetailMap = DataSourceInfoUtilities.getOperatingSystems();
|
||||
setDataSource(null);
|
||||
}
|
||||
|
||||
/**
|
||||
* The datasource currently used as the model in this panel.
|
||||
*
|
||||
* @return The datasource currently being used as the model in this panel.
|
||||
*/
|
||||
public DataSource getDataSource() {
|
||||
return dataSource;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets datasource to visualize in the panel.
|
||||
*
|
||||
* @param dataSource The datasource to use in this panel.
|
||||
*/
|
||||
public void setDataSource(DataSource dataSource) {
|
||||
this.dataSource = dataSource;
|
||||
|
||||
if (dataSource == null || !Case.isCaseOpen()) {
|
||||
updateDetailsPanelData(null, null, null, null);
|
||||
} else {
|
||||
updateDetailsPanelData(dataSource,
|
||||
DataSourceDetailsSummary.getSizeOfUnallocatedFiles(dataSource),
|
||||
DataSourceDetailsSummary.getOperatingSystems(dataSource),
|
||||
DataSourceDetailsSummary.getDataSourceType(dataSource));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -60,77 +85,80 @@ class DataSourceSummaryDetailsPanel extends javax.swing.JPanel {
|
||||
*
|
||||
* @param selectedDataSource the DataSource to display details about.
|
||||
*/
|
||||
void updateDetailsPanelData(DataSource selectedDataSource) {
|
||||
private void updateDetailsPanelData(DataSource selectedDataSource, Long unallocatedFilesSize, String osDetails, String usage) {
|
||||
clearTableValues();
|
||||
if (selectedDataSource != null) {
|
||||
String sizeString = "";
|
||||
String sectorSizeString = "";
|
||||
String md5String = "";
|
||||
String sha1String = "";
|
||||
String sha256String = "";
|
||||
String acquisitionDetailsString = "";
|
||||
String imageTypeString = "";
|
||||
String[] filePaths = new String[0];
|
||||
String osDetailString = osDetailMap.get(selectedDataSource.getId()) == null ? "" : osDetailMap.get(selectedDataSource.getId());
|
||||
String dataSourceTypeString = usageMap.get(selectedDataSource.getId()) == null ? "" : usageMap.get(selectedDataSource.getId());
|
||||
try {
|
||||
acquisitionDetailsString = selectedDataSource.getAcquisitionDetails();
|
||||
} catch (TskCoreException ex) {
|
||||
logger.log(Level.WARNING, "Unable to get aquisition details for selected data source", ex);
|
||||
}
|
||||
if (selectedDataSource instanceof Image) {
|
||||
imageTypeString = ((Image) selectedDataSource).getType().getName();
|
||||
filePaths = ((Image) selectedDataSource).getPaths();
|
||||
sizeString = getSizeString(selectedDataSource.getSize());
|
||||
sectorSizeString = getSizeString(((Image) selectedDataSource).getSsize());
|
||||
try {
|
||||
//older databases may have null as the hash values
|
||||
md5String = ((Image) selectedDataSource).getMd5();
|
||||
if (md5String == null) {
|
||||
md5String = "";
|
||||
}
|
||||
} catch (TskCoreException ex) {
|
||||
logger.log(Level.WARNING, "Unable to get MD5 for selected data source", ex);
|
||||
}
|
||||
try {
|
||||
sha1String = ((Image) selectedDataSource).getSha1();
|
||||
if (sha1String == null) {
|
||||
sha1String = "";
|
||||
}
|
||||
} catch (TskCoreException ex) {
|
||||
logger.log(Level.WARNING, "Unable to get SHA1 for selected data source", ex);
|
||||
}
|
||||
try {
|
||||
sha256String = ((Image) selectedDataSource).getSha256();
|
||||
if (sha256String == null) {
|
||||
sha256String = "";
|
||||
}
|
||||
} catch (TskCoreException ex) {
|
||||
logger.log(Level.WARNING, "Unable to get SHA256 for selected data source", ex);
|
||||
}
|
||||
}
|
||||
unallocatedSizeValue.setText(getSizeString(unallocatedFilesSize));
|
||||
operatingSystemValue.setText(StringUtils.isBlank(osDetails) ? "" : osDetails);
|
||||
dataSourceUsageValue.setText(StringUtils.isBlank(usage) ? "" : usage);
|
||||
|
||||
timeZoneValue.setText(selectedDataSource.getTimeZone());
|
||||
displayNameValue.setText(selectedDataSource.getName());
|
||||
originalNameValue.setText(selectedDataSource.getName());
|
||||
deviceIdValue.setText(selectedDataSource.getDeviceId());
|
||||
dataSourceUsageValue.setText(dataSourceTypeString);
|
||||
operatingSystemValue.setText(osDetailString);
|
||||
timeZoneValue.setText(selectedDataSource.getTimeZone());
|
||||
acquisitionDetailsTextArea.setText(acquisitionDetailsString);
|
||||
imageTypeValue.setText(imageTypeString);
|
||||
sizeValue.setText(sizeString);
|
||||
unallocatedSizeValue.setText(getSizeString(unallocatedFilesSizeMap.get(selectedDataSource.getId())));
|
||||
sectorSizeValue.setText(sectorSizeString);
|
||||
md5HashValue.setText(md5String);
|
||||
sha1HashValue.setText(sha1String);
|
||||
sha256HashValue.setText(sha256String);
|
||||
for (String path : filePaths) {
|
||||
((DefaultTableModel) filePathsTable.getModel()).addRow(new Object[]{path});
|
||||
|
||||
try {
|
||||
acquisitionDetailsTextArea.setText(selectedDataSource.getAcquisitionDetails());
|
||||
} catch (TskCoreException ex) {
|
||||
logger.log(Level.WARNING, "Unable to get aquisition details for selected data source", ex);
|
||||
}
|
||||
|
||||
if (selectedDataSource instanceof Image) {
|
||||
setFieldsForImage((Image) selectedDataSource);
|
||||
}
|
||||
}
|
||||
updateFieldVisibility();
|
||||
this.repaint();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets text fields for an image. This should be called after
|
||||
* clearTableValues and before updateFieldVisibility to ensure the proper
|
||||
* rendering.
|
||||
*
|
||||
* @param selectedImage The selected image.
|
||||
*/
|
||||
private void setFieldsForImage(Image selectedImage) {
|
||||
imageTypeValue.setText(selectedImage.getType().getName());
|
||||
sizeValue.setText(getSizeString(selectedImage.getSize()));
|
||||
sectorSizeValue.setText(getSizeString(selectedImage.getSsize()));
|
||||
|
||||
for (String path : selectedImage.getPaths()) {
|
||||
((DefaultTableModel) filePathsTable.getModel()).addRow(new Object[]{path});
|
||||
}
|
||||
|
||||
try {
|
||||
//older databases may have null as the hash values
|
||||
String md5String = selectedImage.getMd5();
|
||||
if (md5String == null) {
|
||||
md5String = "";
|
||||
}
|
||||
md5HashValue.setText(md5String);
|
||||
} catch (TskCoreException ex) {
|
||||
logger.log(Level.WARNING, "Unable to get MD5 for selected data source", ex);
|
||||
}
|
||||
|
||||
try {
|
||||
String sha1String = selectedImage.getSha1();
|
||||
if (sha1String == null) {
|
||||
sha1String = "";
|
||||
}
|
||||
sha1HashValue.setText(sha1String);
|
||||
} catch (TskCoreException ex) {
|
||||
logger.log(Level.WARNING, "Unable to get SHA1 for selected data source", ex);
|
||||
}
|
||||
|
||||
try {
|
||||
String sha256String = selectedImage.getSha256();
|
||||
if (sha256String == null) {
|
||||
sha256String = "";
|
||||
}
|
||||
sha256HashValue.setText(sha256String);
|
||||
} catch (TskCoreException ex) {
|
||||
logger.log(Level.WARNING, "Unable to get SHA256 for selected data source", ex);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a long size in bytes as a string formated to be read by users.
|
||||
*
|
||||
@ -147,7 +175,7 @@ class DataSourceSummaryDetailsPanel extends javax.swing.JPanel {
|
||||
"DataSourceSummaryDetailsPanel.units.terabytes= TB",
|
||||
"DataSourceSummaryDetailsPanel.units.petabytes= PB"
|
||||
})
|
||||
private String getSizeString(Long size) {
|
||||
private static String getSizeString(Long size) {
|
||||
if (size == null) {
|
||||
return "";
|
||||
}
|
@ -22,7 +22,7 @@
|
||||
<Group type="102" alignment="1" attributes="0">
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Group type="103" groupAlignment="1" attributes="0">
|
||||
<Component id="dataSourceSummarySplitPane" pref="668" max="32767" attributes="0"/>
|
||||
<Component id="dataSourceSummarySplitPane" pref="860" max="32767" attributes="0"/>
|
||||
<Group type="102" attributes="0">
|
||||
<EmptySpace min="0" pref="0" max="32767" attributes="0"/>
|
||||
<Component id="closeButton" min="-2" max="-2" attributes="0"/>
|
||||
@ -36,7 +36,7 @@
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Group type="102" alignment="0" attributes="0">
|
||||
<EmptySpace min="-2" max="-2" attributes="0"/>
|
||||
<Component id="dataSourceSummarySplitPane" pref="362" max="32767" attributes="0"/>
|
||||
<Component id="dataSourceSummarySplitPane" pref="540" max="32767" attributes="0"/>
|
||||
<EmptySpace min="-2" max="-2" attributes="0"/>
|
||||
<Component id="closeButton" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace min="-2" max="-2" attributes="0"/>
|
||||
@ -48,7 +48,7 @@
|
||||
<Component class="javax.swing.JButton" name="closeButton">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/casemodule/datasourcesummary/Bundle.properties" key="DataSourceSummaryDialog.closeButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/datasourcesummary/ui/Bundle.properties" key="DataSourceSummaryDialog.closeButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<Events>
|
||||
@ -68,6 +68,11 @@
|
||||
<Layout class="org.netbeans.modules.form.compat2.layouts.support.JSplitPaneSupportLayout"/>
|
||||
<SubComponents>
|
||||
<Container class="javax.swing.JTabbedPane" name="dataSourceTabbedPane">
|
||||
<AuxValues>
|
||||
<AuxValue name="JavaCodeGenerator_CreateCodeCustom" type="java.lang.String" value="dataSourceSummaryTabbedPane"/>
|
||||
<AuxValue name="JavaCodeGenerator_VariableLocal" type="java.lang.Boolean" value="true"/>
|
||||
<AuxValue name="JavaCodeGenerator_VariableModifier" type="java.lang.Integer" value="0"/>
|
||||
</AuxValues>
|
||||
<Constraints>
|
||||
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.support.JSplitPaneSupportLayout" value="org.netbeans.modules.form.compat2.layouts.support.JSplitPaneSupportLayout$JSplitPaneConstraintsDescription">
|
||||
<JSplitPaneConstraints position="right"/>
|
@ -16,7 +16,7 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.sleuthkit.autopsy.casemodule.datasourcesummary;
|
||||
package org.sleuthkit.autopsy.datasourcesummary.ui;
|
||||
|
||||
import java.awt.Frame;
|
||||
import java.beans.PropertyChangeEvent;
|
||||
@ -27,7 +27,7 @@ import java.util.Observer;
|
||||
import java.util.Set;
|
||||
import javax.swing.event.ListSelectionEvent;
|
||||
import org.openide.util.NbBundle.Messages;
|
||||
import org.sleuthkit.autopsy.casemodule.IngestJobInfoPanel;
|
||||
import org.sleuthkit.autopsy.datasourcesummary.datamodel.CaseDataSourcesSummary;
|
||||
import org.sleuthkit.autopsy.ingest.IngestManager;
|
||||
import org.sleuthkit.autopsy.ingest.events.DataSourceAnalysisCompletedEvent;
|
||||
import org.sleuthkit.autopsy.ingest.events.DataSourceAnalysisCompletedEvent.Reason;
|
||||
@ -41,10 +41,8 @@ final class DataSourceSummaryDialog extends javax.swing.JDialog implements Obser
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
private static final Set<IngestManager.IngestJobEvent> INGEST_JOB_EVENTS_OF_INTEREST = EnumSet.of(IngestManager.IngestJobEvent.DATA_SOURCE_ANALYSIS_COMPLETED);
|
||||
private final DataSourceSummaryCountsPanel countsPanel;
|
||||
private final DataSourceSummaryDetailsPanel detailsPanel;
|
||||
private final DataSourceBrowser dataSourcesPanel;
|
||||
private final IngestJobInfoPanel ingestHistoryPanel;
|
||||
private final DataSourceSummaryTabbedPane dataSourceSummaryTabbedPane;
|
||||
|
||||
/**
|
||||
* Creates new form DataSourceSummaryDialog for displaying a summary of the
|
||||
@ -52,30 +50,20 @@ final class DataSourceSummaryDialog extends javax.swing.JDialog implements Obser
|
||||
* datasource.
|
||||
*/
|
||||
@Messages({
|
||||
"DataSourceSummaryDialog.window.title=Data Sources Summary",
|
||||
"DataSourceSummaryDialog.countsTab.title=Counts",
|
||||
"DataSourceSummaryDialog.detailsTab.title=Details",
|
||||
"DataSourceSummaryDialog.ingestHistoryTab.title=Ingest History"
|
||||
"DataSourceSummaryDialog.window.title=Data Sources Summary"
|
||||
})
|
||||
DataSourceSummaryDialog(Frame owner) {
|
||||
super(owner, Bundle.DataSourceSummaryDialog_window_title(), true);
|
||||
Map<Long, String> usageMap = DataSourceInfoUtilities.getDataSourceTypes();
|
||||
Map<Long, Long> fileCountsMap = DataSourceInfoUtilities.getCountsOfFiles();
|
||||
countsPanel = new DataSourceSummaryCountsPanel(fileCountsMap);
|
||||
detailsPanel = new DataSourceSummaryDetailsPanel(usageMap);
|
||||
Map<Long, String> usageMap = CaseDataSourcesSummary.getDataSourceTypes();
|
||||
Map<Long, Long> fileCountsMap = CaseDataSourcesSummary.getCountsOfFiles();
|
||||
dataSourcesPanel = new DataSourceBrowser(usageMap, fileCountsMap);
|
||||
ingestHistoryPanel = new IngestJobInfoPanel();
|
||||
dataSourceSummaryTabbedPane = new DataSourceSummaryTabbedPane();
|
||||
initComponents();
|
||||
dataSourceSummarySplitPane.setLeftComponent(dataSourcesPanel);
|
||||
dataSourceTabbedPane.addTab(Bundle.DataSourceSummaryDialog_detailsTab_title(), detailsPanel);
|
||||
dataSourceTabbedPane.addTab(Bundle.DataSourceSummaryDialog_countsTab_title(), countsPanel);
|
||||
dataSourceTabbedPane.addTab(Bundle.DataSourceSummaryDialog_ingestHistoryTab_title(), ingestHistoryPanel);
|
||||
dataSourcesPanel.addListSelectionListener((ListSelectionEvent e) -> {
|
||||
if (!e.getValueIsAdjusting()) {
|
||||
DataSource selectedDataSource = dataSourcesPanel.getSelectedDataSource();
|
||||
countsPanel.updateCountsTableData(selectedDataSource);
|
||||
detailsPanel.updateDetailsPanelData(selectedDataSource);
|
||||
ingestHistoryPanel.setDataSource(selectedDataSource);
|
||||
dataSourceSummaryTabbedPane.setDataSource(selectedDataSource);
|
||||
this.repaint();
|
||||
}
|
||||
});
|
||||
@ -116,7 +104,7 @@ final class DataSourceSummaryDialog extends javax.swing.JDialog implements Obser
|
||||
|
||||
closeButton = new javax.swing.JButton();
|
||||
dataSourceSummarySplitPane = new javax.swing.JSplitPane();
|
||||
dataSourceTabbedPane = new javax.swing.JTabbedPane();
|
||||
javax.swing.JTabbedPane dataSourceTabbedPane = dataSourceSummaryTabbedPane;
|
||||
|
||||
org.openide.awt.Mnemonics.setLocalizedText(closeButton, org.openide.util.NbBundle.getMessage(DataSourceSummaryDialog.class, "DataSourceSummaryDialog.closeButton.text")); // NOI18N
|
||||
closeButton.addActionListener(new java.awt.event.ActionListener() {
|
||||
@ -138,7 +126,7 @@ final class DataSourceSummaryDialog extends javax.swing.JDialog implements Obser
|
||||
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
|
||||
.addContainerGap()
|
||||
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
|
||||
.addComponent(dataSourceSummarySplitPane, javax.swing.GroupLayout.DEFAULT_SIZE, 668, Short.MAX_VALUE)
|
||||
.addComponent(dataSourceSummarySplitPane, javax.swing.GroupLayout.DEFAULT_SIZE, 860, Short.MAX_VALUE)
|
||||
.addGroup(layout.createSequentialGroup()
|
||||
.addGap(0, 0, Short.MAX_VALUE)
|
||||
.addComponent(closeButton)))
|
||||
@ -148,7 +136,7 @@ final class DataSourceSummaryDialog extends javax.swing.JDialog implements Obser
|
||||
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGroup(layout.createSequentialGroup()
|
||||
.addContainerGap()
|
||||
.addComponent(dataSourceSummarySplitPane, javax.swing.GroupLayout.DEFAULT_SIZE, 362, Short.MAX_VALUE)
|
||||
.addComponent(dataSourceSummarySplitPane, javax.swing.GroupLayout.DEFAULT_SIZE, 540, Short.MAX_VALUE)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(closeButton)
|
||||
.addContainerGap())
|
||||
@ -173,6 +161,5 @@ final class DataSourceSummaryDialog extends javax.swing.JDialog implements Obser
|
||||
// Variables declaration - do not modify//GEN-BEGIN:variables
|
||||
private javax.swing.JButton closeButton;
|
||||
private javax.swing.JSplitPane dataSourceSummarySplitPane;
|
||||
private javax.swing.JTabbedPane dataSourceTabbedPane;
|
||||
// End of variables declaration//GEN-END:variables
|
||||
}
|
@ -16,7 +16,7 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.sleuthkit.autopsy.casemodule.datasourcesummary;
|
||||
package org.sleuthkit.autopsy.datasourcesummary.ui;
|
||||
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.util.ArrayList;
|
||||
@ -30,6 +30,7 @@ import org.openide.nodes.Children;
|
||||
import org.openide.nodes.Node;
|
||||
import org.openide.nodes.Sheet;
|
||||
import org.openide.util.NbBundle.Messages;
|
||||
import org.sleuthkit.autopsy.datasourcesummary.ui.Bundle;
|
||||
import org.sleuthkit.autopsy.datamodel.NodeProperty;
|
||||
import org.sleuthkit.autopsy.directorytree.ViewContextAction;
|
||||
import org.sleuthkit.datamodel.DataSource;
|
@ -0,0 +1,82 @@
|
||||
/*
|
||||
* Autopsy Forensic Browser
|
||||
*
|
||||
* Copyright 2020 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.datasourcesummary.ui;
|
||||
|
||||
import javax.swing.JTabbedPane;
|
||||
import org.openide.util.NbBundle.Messages;
|
||||
import org.sleuthkit.autopsy.casemodule.IngestJobInfoPanel;
|
||||
import org.sleuthkit.autopsy.datasourcesummary.ui.Bundle;
|
||||
import org.sleuthkit.datamodel.DataSource;
|
||||
|
||||
/**
|
||||
* A tabbed pane showing the summary of a data source including tabs of:
|
||||
* DataSourceSummaryCountsPanel, DataSourceSummaryDetailsPanel, and
|
||||
* IngestJobInfoPanel.
|
||||
*/
|
||||
@Messages({
|
||||
"DataSourceSummaryTabbedPane_countsTab_title=Counts",
|
||||
"DataSourceSummaryTabbedPane_detailsTab_title=Details",
|
||||
"DataSourceSummaryTabbedPane_userActivityTab_title=User Activity",
|
||||
"DataSourceSummaryTabbedPane_ingestHistoryTab_title=Ingest History"
|
||||
})
|
||||
public class DataSourceSummaryTabbedPane extends JTabbedPane {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private final DataSourceSummaryCountsPanel countsPanel = new DataSourceSummaryCountsPanel();
|
||||
private final DataSourceSummaryDetailsPanel detailsPanel = new DataSourceSummaryDetailsPanel();
|
||||
private final DataSourceSummaryUserActivityPanel userActivityPanel = new DataSourceSummaryUserActivityPanel();
|
||||
private final IngestJobInfoPanel ingestHistoryPanel = new IngestJobInfoPanel();
|
||||
|
||||
private DataSource dataSource = null;
|
||||
|
||||
/**
|
||||
* Constructs a tabbed pane showing the summary of a data source.
|
||||
*/
|
||||
public DataSourceSummaryTabbedPane() {
|
||||
|
||||
addTab(Bundle.DataSourceSummaryTabbedPane_detailsTab_title(), detailsPanel);
|
||||
addTab(Bundle.DataSourceSummaryTabbedPane_countsTab_title(), countsPanel);
|
||||
addTab(Bundle.DataSourceSummaryTabbedPane_userActivityTab_title(), userActivityPanel);
|
||||
addTab(Bundle.DataSourceSummaryTabbedPane_ingestHistoryTab_title(), ingestHistoryPanel);
|
||||
}
|
||||
|
||||
/**
|
||||
* The datasource currently used as the model in this panel.
|
||||
*
|
||||
* @return The datasource currently being used as the model in this panel.
|
||||
*/
|
||||
public DataSource getDataSource() {
|
||||
return dataSource;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets datasource to visualize in the tabbed panel.
|
||||
*
|
||||
* @param dataSource The datasource to use in this panel.
|
||||
*/
|
||||
public void setDataSource(DataSource dataSource) {
|
||||
this.dataSource = dataSource;
|
||||
|
||||
detailsPanel.setDataSource(dataSource);
|
||||
countsPanel.setDataSource(dataSource);
|
||||
userActivityPanel.setDataSource(dataSource);
|
||||
ingestHistoryPanel.setDataSource(dataSource);
|
||||
}
|
||||
}
|
@ -0,0 +1,70 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
|
||||
<Form version="1.5" maxVersion="1.9" type="org.netbeans.modules.form.forminfo.JPanelFormInfo">
|
||||
<AuxValues>
|
||||
<AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="1"/>
|
||||
<AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/>
|
||||
<AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/>
|
||||
<AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="true"/>
|
||||
<AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="true"/>
|
||||
<AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/>
|
||||
<AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/>
|
||||
<AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/>
|
||||
<AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/>
|
||||
</AuxValues>
|
||||
|
||||
<Layout>
|
||||
<DimensionLayout dim="0">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Group type="102" alignment="0" attributes="0">
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Component id="programsRunLabel" min="-2" pref="155" max="-2" attributes="0"/>
|
||||
<Component id="topProgramsScrollPane" min="-2" pref="460" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<EmptySpace pref="128" max="32767" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
<DimensionLayout dim="1">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Group type="102" alignment="0" attributes="0">
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="programsRunLabel" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="topProgramsScrollPane" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace max="32767" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
</Layout>
|
||||
<SubComponents>
|
||||
<Component class="javax.swing.JLabel" name="programsRunLabel">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/datasourcesummary/ui/Bundle.properties" key="DataSourceSummaryUserActivityPanel.programsRunLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<AuxValues>
|
||||
<AuxValue name="JavaCodeGenerator_VariableLocal" type="java.lang.Boolean" value="true"/>
|
||||
<AuxValue name="JavaCodeGenerator_VariableModifier" type="java.lang.Integer" value="0"/>
|
||||
</AuxValues>
|
||||
</Component>
|
||||
<Container class="javax.swing.JScrollPane" name="topProgramsScrollPane">
|
||||
<Properties>
|
||||
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||
<Dimension value="[750, 187]"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<AuxValues>
|
||||
<AuxValue name="autoScrollPane" type="java.lang.Boolean" value="true"/>
|
||||
</AuxValues>
|
||||
|
||||
<Layout class="org.netbeans.modules.form.compat2.layouts.support.JScrollPaneSupportLayout"/>
|
||||
<SubComponents>
|
||||
<Component class="javax.swing.JTable" name="topProgramsTable">
|
||||
</Component>
|
||||
</SubComponents>
|
||||
</Container>
|
||||
</SubComponents>
|
||||
</Form>
|
@ -0,0 +1,293 @@
|
||||
/*
|
||||
* Autopsy Forensic Browser
|
||||
*
|
||||
* Copyright 2020 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.datasourcesummary.ui;
|
||||
|
||||
import java.awt.Component;
|
||||
import java.text.DateFormat;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.JTable;
|
||||
import javax.swing.table.AbstractTableModel;
|
||||
import javax.swing.table.DefaultTableCellRenderer;
|
||||
import javax.swing.table.TableCellRenderer;
|
||||
import org.openide.util.NbBundle.Messages;
|
||||
import org.sleuthkit.autopsy.casemodule.Case;
|
||||
import org.sleuthkit.autopsy.datasourcesummary.datamodel.DataSourceTopProgramsSummary;
|
||||
import org.sleuthkit.autopsy.datasourcesummary.datamodel.TopProgramsResult;
|
||||
import org.sleuthkit.datamodel.DataSource;
|
||||
|
||||
/**
|
||||
* A panel to display user activity.
|
||||
*/
|
||||
@Messages({
|
||||
"DataSourceSummaryUserActivityPanel_tab_title=User Activity",
|
||||
"DataSourceSummaryUserActivityPanel_TopProgramsTableModel_name_header=Program",
|
||||
"DataSourceSummaryUserActivityPanel_TopProgramsTableModel_folder_header=Folder",
|
||||
"DataSourceSummaryUserActivityPanel_TopProgramsTableModel_count_header=Run Times",
|
||||
"DataSourceSummaryUserActivityPanel_TopProgramsTableModel_lastrun_header=Last Run"
|
||||
})
|
||||
public class DataSourceSummaryUserActivityPanel extends javax.swing.JPanel {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
private static final DateFormat DATETIME_FORMAT = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss", Locale.getDefault());
|
||||
private static final int TOP_PROGS_COUNT = 10;
|
||||
private static final DefaultTableCellRenderer RIGHT_ALIGNED_RENDERER = new DefaultTableCellRenderer();
|
||||
|
||||
static {
|
||||
RIGHT_ALIGNED_RENDERER.setHorizontalAlignment(JLabel.RIGHT);
|
||||
}
|
||||
|
||||
private DataSource dataSource;
|
||||
|
||||
/**
|
||||
* Creates new form DataSourceUserActivityPanel
|
||||
*/
|
||||
public DataSourceSummaryUserActivityPanel() {
|
||||
initComponents();
|
||||
topProgramsTable.getTableHeader().setReorderingAllowed(false);
|
||||
}
|
||||
|
||||
/**
|
||||
* The datasource currently used as the model in this panel.
|
||||
*
|
||||
* @return The datasource currently being used as the model in this panel.
|
||||
*/
|
||||
public DataSource getDataSource() {
|
||||
return dataSource;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets datasource to visualize in the panel.
|
||||
*
|
||||
* @param dataSource The datasource to use in this panel.
|
||||
*/
|
||||
public void setDataSource(DataSource dataSource) {
|
||||
this.dataSource = dataSource;
|
||||
if (dataSource == null || !Case.isCaseOpen()) {
|
||||
updateTopPrograms(new TopProgramsModel(null));
|
||||
} else {
|
||||
updateTopPrograms(getTopProgramsModel(dataSource));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the Top Programs Table in the gui.
|
||||
*
|
||||
* @param data The data in Object[][] form to be used by the
|
||||
* DefaultTableModel.
|
||||
*/
|
||||
private void updateTopPrograms(TopProgramsModel model) {
|
||||
topProgramsTable.setModel(model);
|
||||
topProgramsTable.getColumnModel().getColumn(0).setPreferredWidth(250);
|
||||
topProgramsTable.getColumnModel().getColumn(0).setCellRenderer(PATH_CELL_RENDERER);
|
||||
topProgramsTable.getColumnModel().getColumn(1).setPreferredWidth(150);
|
||||
topProgramsTable.getColumnModel().getColumn(2).setCellRenderer(RIGHT_ALIGNED_RENDERER);
|
||||
topProgramsTable.getColumnModel().getColumn(2).setPreferredWidth(80);
|
||||
topProgramsTable.getColumnModel().getColumn(3).setPreferredWidth(150);
|
||||
topProgramsScrollPane.getVerticalScrollBar().setValue(0);
|
||||
this.repaint();
|
||||
}
|
||||
|
||||
/**
|
||||
* The counts of top programs run.
|
||||
*
|
||||
* @param selectedDataSource The DataSource.
|
||||
*
|
||||
* @return The JTable data model of counts of program runs.
|
||||
*/
|
||||
private static TopProgramsModel getTopProgramsModel(DataSource selectedDataSource) {
|
||||
List<TopProgramsResult> topProgramList
|
||||
= DataSourceTopProgramsSummary.getTopPrograms(selectedDataSource, TOP_PROGS_COUNT);
|
||||
|
||||
if (topProgramList == null) {
|
||||
return new TopProgramsModel(null);
|
||||
} else {
|
||||
return new TopProgramsModel(topProgramList);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A POJO defining the values present in the name cell. Defines the name as
|
||||
* well as the path for the tooltip.
|
||||
*/
|
||||
private static class ProgramNameCellValue {
|
||||
|
||||
private final String programName;
|
||||
private final String programPath;
|
||||
|
||||
ProgramNameCellValue(String programName, String programPath) {
|
||||
this.programName = programName;
|
||||
this.programPath = programPath;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
// override so that the value in the cell reads as programName
|
||||
return programName;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The program name.
|
||||
*/
|
||||
String getProgramName() {
|
||||
return programName;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The path of the program.
|
||||
*/
|
||||
String getProgramPath() {
|
||||
return programPath;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Defines a cell renderer for the first cell rendering the name as the text
|
||||
* and path as the tooltip.
|
||||
*/
|
||||
private static TableCellRenderer PATH_CELL_RENDERER = new DefaultTableCellRenderer() {
|
||||
|
||||
public Component getTableCellRendererComponent(
|
||||
JTable table, Object value,
|
||||
boolean isSelected, boolean hasFocus,
|
||||
int row, int column) {
|
||||
JLabel c = (JLabel) super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
|
||||
if (value instanceof ProgramNameCellValue) {
|
||||
ProgramNameCellValue cellValue = (ProgramNameCellValue) value;
|
||||
c.setToolTipText(cellValue.getProgramPath());
|
||||
}
|
||||
return c;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Defines the table model for a JTable of the programs. Accepts a list of
|
||||
* TopProgramsResult objects as rows data source.
|
||||
*/
|
||||
private static class TopProgramsModel extends AbstractTableModel {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
// column headers for artifact counts table
|
||||
private static final String[] TOP_PROGS_COLUMN_HEADERS = new String[]{
|
||||
Bundle.DataSourceSummaryUserActivityPanel_TopProgramsTableModel_name_header(),
|
||||
Bundle.DataSourceSummaryUserActivityPanel_TopProgramsTableModel_folder_header(),
|
||||
Bundle.DataSourceSummaryUserActivityPanel_TopProgramsTableModel_count_header(),
|
||||
Bundle.DataSourceSummaryUserActivityPanel_TopProgramsTableModel_lastrun_header()
|
||||
};
|
||||
|
||||
private final List<TopProgramsResult> programResults;
|
||||
|
||||
/**
|
||||
* Main constructor.
|
||||
*
|
||||
* @param programResults The results to display.
|
||||
*/
|
||||
TopProgramsModel(List<TopProgramsResult> programResults) {
|
||||
this.programResults = programResults == null ? new ArrayList<>() : Collections.unmodifiableList(programResults);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getColumnName(int column) {
|
||||
return column < 0 || column >= TOP_PROGS_COLUMN_HEADERS.length ? null : TOP_PROGS_COLUMN_HEADERS[column];
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getRowCount() {
|
||||
return programResults.size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getColumnCount() {
|
||||
return TOP_PROGS_COLUMN_HEADERS.length;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getValueAt(int rowIndex, int columnIndex) {
|
||||
if (rowIndex < 0 || rowIndex >= programResults.size()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
TopProgramsResult result = programResults.get(rowIndex);
|
||||
switch (columnIndex) {
|
||||
case 0:
|
||||
return new ProgramNameCellValue(result.getProgramName(), result.getProgramPath());
|
||||
case 1:
|
||||
return DataSourceTopProgramsSummary.getShortFolderName(result.getProgramPath(), result.getProgramName());
|
||||
case 2:
|
||||
return result.getRunTimes();
|
||||
case 3:
|
||||
return result.getLastRun() == null ? null : DATETIME_FORMAT.format(result.getLastRun());
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is called from within the constructor to initialize the form.
|
||||
* WARNING: Do NOT modify this code. The content of this method is always
|
||||
* regenerated by the Form Editor.
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
// <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
|
||||
private void initComponents() {
|
||||
|
||||
javax.swing.JLabel programsRunLabel = new javax.swing.JLabel();
|
||||
topProgramsScrollPane = new javax.swing.JScrollPane();
|
||||
topProgramsTable = new javax.swing.JTable();
|
||||
|
||||
org.openide.awt.Mnemonics.setLocalizedText(programsRunLabel, org.openide.util.NbBundle.getMessage(DataSourceSummaryUserActivityPanel.class, "DataSourceSummaryUserActivityPanel.programsRunLabel.text")); // NOI18N
|
||||
|
||||
topProgramsScrollPane.setPreferredSize(new java.awt.Dimension(750, 187));
|
||||
topProgramsScrollPane.setViewportView(topProgramsTable);
|
||||
|
||||
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
|
||||
this.setLayout(layout);
|
||||
layout.setHorizontalGroup(
|
||||
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGroup(layout.createSequentialGroup()
|
||||
.addContainerGap()
|
||||
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addComponent(programsRunLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 155, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||
.addComponent(topProgramsScrollPane, javax.swing.GroupLayout.PREFERRED_SIZE, 460, javax.swing.GroupLayout.PREFERRED_SIZE))
|
||||
.addContainerGap(128, Short.MAX_VALUE))
|
||||
);
|
||||
layout.setVerticalGroup(
|
||||
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGroup(layout.createSequentialGroup()
|
||||
.addContainerGap()
|
||||
.addComponent(programsRunLabel)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(topProgramsScrollPane, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||
.addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
|
||||
);
|
||||
}// </editor-fold>//GEN-END:initComponents
|
||||
|
||||
|
||||
// Variables declaration - do not modify//GEN-BEGIN:variables
|
||||
private javax.swing.JScrollPane topProgramsScrollPane;
|
||||
private javax.swing.JTable topProgramsTable;
|
||||
// End of variables declaration//GEN-END:variables
|
||||
}
|
@ -0,0 +1,190 @@
|
||||
/*
|
||||
* Autopsy Forensic Browser
|
||||
*
|
||||
* Copyright 2020 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.datasourcesummary.ui;
|
||||
|
||||
import java.awt.BorderLayout;
|
||||
import java.awt.Font;
|
||||
import javax.swing.JPanel;
|
||||
import org.sleuthkit.datamodel.DataSource;
|
||||
|
||||
import org.jfree.chart.ChartFactory;
|
||||
import org.jfree.chart.ChartPanel;
|
||||
import org.jfree.chart.JFreeChart;
|
||||
import org.jfree.chart.labels.PieSectionLabelGenerator;
|
||||
import org.jfree.chart.labels.StandardPieSectionLabelGenerator;
|
||||
import org.jfree.chart.plot.PiePlot;
|
||||
import org.jfree.data.general.DefaultPieDataset;
|
||||
|
||||
import java.text.DecimalFormat;
|
||||
import java.util.Arrays;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
import javax.swing.JLabel;
|
||||
import org.openide.util.NbBundle.Messages;
|
||||
import org.sleuthkit.autopsy.coreutils.FileTypeUtils;
|
||||
import org.sleuthkit.autopsy.datasourcesummary.datamodel.DataSourceMimeTypeSummary;
|
||||
import static org.sleuthkit.autopsy.coreutils.FileTypeUtils.FileTypeCategory;
|
||||
|
||||
/**
|
||||
* A Pie Chart that shows file mime types in a data source.
|
||||
*/
|
||||
class FileTypePieChart extends JPanel {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private static final Font DEFAULT_FONT = new JLabel().getFont();
|
||||
private static final Font DEFAULT_HEADER_FONT = new Font(DEFAULT_FONT.getName(), DEFAULT_FONT.getStyle(), (int) (DEFAULT_FONT.getSize() * 1.5));
|
||||
|
||||
private final DefaultPieDataset dataset = new DefaultPieDataset();
|
||||
private DataSource dataSource;
|
||||
|
||||
// used for determining mime types that fall in the 'other' category
|
||||
private static final Set<String> ALL_CATEGORY_MIME_TYPES = Arrays.asList(
|
||||
FileTypeCategory.IMAGE,
|
||||
FileTypeCategory.VIDEO,
|
||||
FileTypeCategory.AUDIO,
|
||||
FileTypeCategory.DOCUMENTS,
|
||||
FileTypeCategory.EXECUTABLE)
|
||||
.stream()
|
||||
.flatMap((cat) -> cat.getMediaTypes().stream())
|
||||
.collect(Collectors.toSet());
|
||||
|
||||
/**
|
||||
* Default constructor for the pie chart.
|
||||
*/
|
||||
@Messages({
|
||||
"DataSourceSummaryCountsPanel.byMimeTypeLabel.text=Files by MIME Type",
|
||||
"DataSourceSummaryCountsPanel.FilesByMimeTypeTableModel.audio.row=Audio",
|
||||
"DataSourceSummaryCountsPanel.FilesByMimeTypeTableModel.documents.row=Documents",
|
||||
"DataSourceSummaryCountsPanel.FilesByMimeTypeTableModel.executables.row=Executables",
|
||||
"DataSourceSummaryCountsPanel.FilesByMimeTypeTableModel.images.row=Images",
|
||||
"DataSourceSummaryCountsPanel.FilesByMimeTypeTableModel.videos.row=Videos",
|
||||
"DataSourceSummaryCountsPanel_FilesByMimeTypeTableModel_other_label=Other",
|
||||
"DataSourceSummaryCountsPanel_FilesByMimeTypeTableModel_notAnalyzed_label=Not Analyzed"
|
||||
})
|
||||
FileTypePieChart() {
|
||||
// Create chart
|
||||
JFreeChart chart = ChartFactory.createPieChart(
|
||||
Bundle.DataSourceSummaryCountsPanel_byMimeTypeLabel_text(),
|
||||
dataset,
|
||||
true,
|
||||
true,
|
||||
false);
|
||||
|
||||
chart.setBackgroundPaint(null);
|
||||
chart.getLegend().setItemFont(DEFAULT_FONT);
|
||||
chart.getTitle().setFont(DEFAULT_HEADER_FONT);
|
||||
|
||||
PiePlot plot = ((PiePlot) chart.getPlot());
|
||||
|
||||
//Format Label
|
||||
PieSectionLabelGenerator labelGenerator = new StandardPieSectionLabelGenerator(
|
||||
"{0}: {1} ({2})", new DecimalFormat("0"), new DecimalFormat("0.0%"));
|
||||
|
||||
plot.setLabelGenerator(labelGenerator);
|
||||
plot.setLabelFont(DEFAULT_FONT);
|
||||
|
||||
plot.setBackgroundPaint(null);
|
||||
plot.setOutlinePaint(null);
|
||||
|
||||
// Create Panel
|
||||
ChartPanel panel = new ChartPanel(chart);
|
||||
this.setLayout(new BorderLayout());
|
||||
this.add(panel, BorderLayout.CENTER);
|
||||
}
|
||||
|
||||
/**
|
||||
* The datasource currently used as the model with this pie chart.
|
||||
*
|
||||
* @return The datasource currently being used as the model in this pie
|
||||
* chart.
|
||||
*/
|
||||
DataSource getDataSource() {
|
||||
return dataSource;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets datasource to visualize in the pie chart.
|
||||
*
|
||||
* @param dataSource The datasource to use in this pie chart.
|
||||
*/
|
||||
void setDataSource(DataSource dataSource) {
|
||||
this.dataSource = dataSource;
|
||||
this.dataset.clear();
|
||||
|
||||
if (dataSource != null) {
|
||||
addIfPresent(Bundle.DataSourceSummaryCountsPanel_FilesByMimeTypeTableModel_images_row(),
|
||||
this.dataSource, FileTypeCategory.IMAGE);
|
||||
addIfPresent(Bundle.DataSourceSummaryCountsPanel_FilesByMimeTypeTableModel_videos_row(),
|
||||
this.dataSource, FileTypeCategory.VIDEO);
|
||||
addIfPresent(Bundle.DataSourceSummaryCountsPanel_FilesByMimeTypeTableModel_audio_row(),
|
||||
this.dataSource, FileTypeCategory.AUDIO);
|
||||
addIfPresent(Bundle.DataSourceSummaryCountsPanel_FilesByMimeTypeTableModel_documents_row(),
|
||||
this.dataSource, FileTypeCategory.DOCUMENTS);
|
||||
addIfPresent(Bundle.DataSourceSummaryCountsPanel_FilesByMimeTypeTableModel_executables_row(),
|
||||
this.dataSource, FileTypeCategory.EXECUTABLE);
|
||||
addIfPresent(Bundle.DataSourceSummaryCountsPanel_FilesByMimeTypeTableModel_other_label(),
|
||||
DataSourceMimeTypeSummary.getCountOfFilesNotInMimeTypes(this.dataSource, ALL_CATEGORY_MIME_TYPES));
|
||||
addIfPresent(Bundle.DataSourceSummaryCountsPanel_FilesByMimeTypeTableModel_notAnalyzed_label(),
|
||||
DataSourceMimeTypeSummary.getCountOfFilesWithNoMimeType(this.dataSource));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds count for file type category if there is a value. Uses fields
|
||||
* 'dataSource' and 'dataset'.
|
||||
*
|
||||
* @param label The label for this pie slice.
|
||||
* @param dataSource The data source.
|
||||
* @param category The category for the pie slice.
|
||||
*/
|
||||
private void addIfPresent(String label, DataSource dataSource, FileTypeUtils.FileTypeCategory category) {
|
||||
if (dataSource == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
Long count = getCount(dataSource, category);
|
||||
addIfPresent(label, count);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds count for a a label if the count is non-null and greater than 0.
|
||||
*
|
||||
* @param label The label.
|
||||
* @param count The count.
|
||||
*/
|
||||
private void addIfPresent(String label, Long count) {
|
||||
if (count != null && count > 0) {
|
||||
this.dataset.setValue(label, count);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the counts of files of a particular mime type for a particular
|
||||
* DataSource.
|
||||
*
|
||||
* @param dataSource The DataSource.
|
||||
* @param category The mime type category.
|
||||
*
|
||||
* @return The count.
|
||||
*/
|
||||
private static Long getCount(DataSource dataSource, FileTypeUtils.FileTypeCategory category) {
|
||||
return DataSourceMimeTypeSummary.getCountOfFilesForMimeTypes(dataSource, category.getMediaTypes());
|
||||
}
|
||||
}
|
@ -0,0 +1,37 @@
|
||||
/*
|
||||
* Autopsy Forensic Browser
|
||||
*
|
||||
* Copyright 2020 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.datasourcesummary.ui;
|
||||
|
||||
import javax.swing.table.DefaultTableModel;
|
||||
|
||||
/**
|
||||
* A Table model where cells are not editable.
|
||||
*/
|
||||
class NonEditableTableModel extends DefaultTableModel {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
NonEditableTableModel(Object[][] data, Object[] columnNames) {
|
||||
super(data, columnNames);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCellEditable(int row, int column) {
|
||||
return false;
|
||||
}
|
||||
}
|
@ -16,7 +16,7 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.sleuthkit.autopsy.casemodule.datasourcesummary;
|
||||
package org.sleuthkit.autopsy.datasourcesummary.ui;
|
||||
|
||||
import java.awt.Component;
|
||||
import java.lang.reflect.InvocationTargetException;
|
@ -16,7 +16,7 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.sleuthkit.autopsy.casemodule.datasourcesummary;
|
||||
package org.sleuthkit.autopsy.datasourcesummary.ui;
|
||||
|
||||
import java.awt.Frame;
|
||||
import java.awt.event.ActionEvent;
|
||||
@ -24,6 +24,7 @@ import javax.swing.AbstractAction;
|
||||
import javax.swing.SwingUtilities;
|
||||
import org.openide.util.NbBundle.Messages;
|
||||
import org.openide.windows.WindowManager;
|
||||
import org.sleuthkit.autopsy.datasourcesummary.ui.Bundle;
|
||||
|
||||
/**
|
||||
* ViewSummaryInformationAction action for opening a Data Sources Summary Dialog
|
@ -19,9 +19,9 @@
|
||||
package org.sleuthkit.autopsy.discovery;
|
||||
|
||||
import org.openide.util.NbBundle.Messages;
|
||||
import org.sleuthkit.autopsy.modules.exif.ExifParserModuleFactory;
|
||||
import org.sleuthkit.autopsy.modules.filetypeid.FileTypeIdModuleFactory;
|
||||
import org.sleuthkit.autopsy.modules.hashdatabase.HashLookupModuleFactory;
|
||||
import org.sleuthkit.autopsy.modules.pictureanalyzer.PictureAnalyzerIngestModuleFactory;
|
||||
import org.sleuthkit.datamodel.IngestJobInfo;
|
||||
import org.sleuthkit.datamodel.IngestModuleInfo;
|
||||
|
||||
@ -118,7 +118,7 @@ class DataSourceModulesWrapper {
|
||||
* data source.
|
||||
*/
|
||||
private void updateExifStatus(IngestModuleInfo moduleInfo) {
|
||||
if (!exifModuleRun && moduleInfo.getDisplayName().equals(ExifParserModuleFactory.getModuleName())) {
|
||||
if (!exifModuleRun && moduleInfo.getDisplayName().equals(PictureAnalyzerIngestModuleFactory.getModuleName())) {
|
||||
exifModuleRun = true;
|
||||
}
|
||||
}
|
||||
|
192
Core/src/org/sleuthkit/autopsy/guiutils/ContactCache.java
Executable file
192
Core/src/org/sleuthkit/autopsy/guiutils/ContactCache.java
Executable file
@ -0,0 +1,192 @@
|
||||
/*
|
||||
* Autopsy Forensic Browser
|
||||
*
|
||||
* Copyright 2020 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.guiutils;
|
||||
|
||||
import com.google.common.cache.CacheBuilder;
|
||||
import com.google.common.cache.CacheLoader;
|
||||
import com.google.common.cache.LoadingCache;
|
||||
import java.beans.PropertyChangeListener;
|
||||
import java.sql.SQLException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.EnumSet;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.logging.Level;
|
||||
import org.sleuthkit.autopsy.casemodule.Case;
|
||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||
import org.sleuthkit.autopsy.ingest.IngestManager;
|
||||
import static org.sleuthkit.autopsy.ingest.IngestManager.IngestModuleEvent.DATA_ADDED;
|
||||
import org.sleuthkit.autopsy.ingest.ModuleDataEvent;
|
||||
import org.sleuthkit.datamodel.Account;
|
||||
import org.sleuthkit.datamodel.BlackboardArtifact;
|
||||
import org.sleuthkit.datamodel.BlackboardAttribute;
|
||||
import static org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_NAME;
|
||||
import org.sleuthkit.datamodel.TskCoreException;
|
||||
|
||||
/**
|
||||
* A singleton cache of the Contact artifacts for accounts. The map of account
|
||||
* unique ids to list of contact artifacts is stored in a LoadingCache which
|
||||
* expires after 10 of non-use.
|
||||
*
|
||||
*/
|
||||
public final class ContactCache {
|
||||
|
||||
private static final Logger logger = Logger.getLogger(ContactCache.class.getName());
|
||||
|
||||
private static ContactCache instance;
|
||||
|
||||
private final LoadingCache<String, Map<String, List<BlackboardArtifact>>> accountMap;
|
||||
|
||||
/**
|
||||
* Returns the list of Contacts for the given Account.
|
||||
*
|
||||
* @param account Account instance.
|
||||
*
|
||||
* @return List of TSK_CONTACT artifacts that references the given Account.
|
||||
* An empty list is returned if no contacts are found.
|
||||
*
|
||||
* @throws ExecutionException
|
||||
*/
|
||||
public static synchronized List<BlackboardArtifact> getContacts(Account account) throws ExecutionException {
|
||||
return getInstance().accountMap.get("realMap").get(account.getTypeSpecificID());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a list of Contact TSK_NAME values for the given account type
|
||||
* specific id.
|
||||
*
|
||||
* @param accountTypeSpecificID Account type specific id
|
||||
*
|
||||
* @return List of contact string names or empty list if none were found.
|
||||
*
|
||||
* @throws TskCoreException
|
||||
*/
|
||||
public static synchronized List<String> getContactNameList(String accountTypeSpecificID) throws TskCoreException {
|
||||
List<BlackboardArtifact> contactList;
|
||||
try {
|
||||
contactList = getInstance().accountMap.get("realMap").get(accountTypeSpecificID);
|
||||
} catch (ExecutionException ex) {
|
||||
throw new TskCoreException("Unable to get contact list from cache", ex);
|
||||
}
|
||||
List<String> contactNameList = new ArrayList<>();
|
||||
|
||||
if (contactList != null) {
|
||||
for (BlackboardArtifact artifact : contactList) {
|
||||
BlackboardAttribute attribute = artifact.getAttribute(new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.fromID(TSK_NAME.getTypeID())));
|
||||
if (attribute != null && !contactNameList.contains(attribute.getValueString())) {
|
||||
contactNameList.add(attribute.getValueString());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return contactNameList;
|
||||
}
|
||||
|
||||
/**
|
||||
* Force the cache to invalidate all entries.
|
||||
*/
|
||||
static synchronized void invalidateCache() {
|
||||
getInstance().accountMap.invalidateAll();
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct a new instance.
|
||||
*/
|
||||
private ContactCache() {
|
||||
|
||||
accountMap = CacheBuilder.newBuilder().expireAfterAccess(10, TimeUnit.MINUTES).build(
|
||||
new CacheLoader<String, Map<String, List<BlackboardArtifact>>>() {
|
||||
@Override
|
||||
public Map<String, List<BlackboardArtifact>> load(String key) {
|
||||
try {
|
||||
return buildMap();
|
||||
} catch (SQLException | TskCoreException ex) {
|
||||
logger.log(Level.WARNING, "Failed to build account to contact map", ex);
|
||||
}
|
||||
return new HashMap<>(); // Return an empty map if there is an exception to avoid NPE and continual trying.
|
||||
}
|
||||
});
|
||||
|
||||
PropertyChangeListener ingestListener = pce -> {
|
||||
String eventType = pce.getPropertyName();
|
||||
if (eventType.equals(DATA_ADDED.toString())) {
|
||||
ModuleDataEvent eventData = (ModuleDataEvent) pce.getOldValue();
|
||||
if (eventData.getBlackboardArtifactType().getTypeID() == BlackboardArtifact.ARTIFACT_TYPE.TSK_CONTACT.getTypeID()) {
|
||||
invalidateCache();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
IngestManager.getInstance().addIngestModuleEventListener(EnumSet.of(DATA_ADDED), ingestListener);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the singleton instance of the cache object.
|
||||
*
|
||||
* @return AccountCache instance.
|
||||
*/
|
||||
private static synchronized ContactCache getInstance() {
|
||||
if (instance == null) {
|
||||
instance = new ContactCache();
|
||||
}
|
||||
|
||||
return instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds the map of account IDs to contacts that reference them.
|
||||
*
|
||||
* @return A map of account IDs to contact artifacts.
|
||||
*
|
||||
* @throws TskCoreException
|
||||
* @throws SQLException
|
||||
*/
|
||||
private Map<String, List<BlackboardArtifact>> buildMap() throws TskCoreException, SQLException {
|
||||
Map<String, List<BlackboardArtifact>> acctMap = new HashMap<>();
|
||||
List<BlackboardArtifact> contactList = Case.getCurrentCase().getSleuthkitCase().getBlackboardArtifacts(BlackboardArtifact.ARTIFACT_TYPE.TSK_CONTACT);
|
||||
|
||||
for (BlackboardArtifact contactArtifact : contactList) {
|
||||
List<BlackboardAttribute> contactAttributes = contactArtifact.getAttributes();
|
||||
for (BlackboardAttribute attribute : contactAttributes) {
|
||||
String typeName = attribute.getAttributeType().getTypeName();
|
||||
|
||||
if (typeName.startsWith("TSK_EMAIL")
|
||||
|| typeName.startsWith("TSK_PHONE")
|
||||
|| typeName.startsWith("TSK_NAME")
|
||||
|| typeName.startsWith("TSK_ID")) {
|
||||
String accountID = attribute.getValueString();
|
||||
List<BlackboardArtifact> artifactList = acctMap.get(accountID);
|
||||
if (artifactList == null) {
|
||||
artifactList = new ArrayList<>();
|
||||
acctMap.put(accountID, artifactList);
|
||||
}
|
||||
if (!artifactList.contains(contactArtifact)) {
|
||||
artifactList.add(contactArtifact);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return acctMap;
|
||||
}
|
||||
}
|
@ -474,6 +474,9 @@ public final class IngestJobSettings {
|
||||
case "Correlation Engine": //NON-NLS
|
||||
moduleNames.add("Central Repository"); //NON-NLS
|
||||
break;
|
||||
case "Exif Parser": //NON-NLS
|
||||
moduleNames.add("Picture Analyzer"); //NON-NLS
|
||||
break;
|
||||
default:
|
||||
moduleNames.add(name);
|
||||
}
|
||||
|
@ -31,7 +31,6 @@ import org.openide.util.NbBundle;
|
||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||
import org.sleuthkit.autopsy.examples.SampleIngestModuleFactory;
|
||||
import org.sleuthkit.autopsy.modules.dataSourceIntegrity.DataSourceIntegrityModuleFactory;
|
||||
import org.sleuthkit.autopsy.modules.exif.ExifParserModuleFactory;
|
||||
import org.sleuthkit.autopsy.modules.fileextmismatch.FileExtMismatchDetectorModuleFactory;
|
||||
import org.sleuthkit.autopsy.modules.filetypeid.FileTypeIdModuleFactory;
|
||||
import org.sleuthkit.autopsy.modules.hashdatabase.HashLookupModuleFactory;
|
||||
@ -40,6 +39,7 @@ import org.sleuthkit.autopsy.modules.photoreccarver.PhotoRecCarverIngestModuleFa
|
||||
import org.sleuthkit.autopsy.modules.embeddedfileextractor.EmbeddedFileExtractorModuleFactory;
|
||||
import org.sleuthkit.autopsy.modules.encryptiondetection.EncryptionDetectionModuleFactory;
|
||||
import org.sleuthkit.autopsy.centralrepository.ingestmodule.CentralRepoIngestModuleFactory;
|
||||
import org.sleuthkit.autopsy.modules.pictureanalyzer.PictureAnalyzerIngestModuleFactory;
|
||||
import org.sleuthkit.autopsy.modules.vmextractor.VMExtractorIngestModuleFactory;
|
||||
import org.sleuthkit.autopsy.python.JythonModuleLoader;
|
||||
|
||||
@ -60,7 +60,7 @@ final class IngestModuleFactoryLoader {
|
||||
add(FileTypeIdModuleFactory.class.getCanonicalName());
|
||||
add(FileExtMismatchDetectorModuleFactory.class.getCanonicalName());
|
||||
add(EmbeddedFileExtractorModuleFactory.class.getCanonicalName());
|
||||
add(ExifParserModuleFactory.class.getCanonicalName());
|
||||
add(PictureAnalyzerIngestModuleFactory.class.getCanonicalName());
|
||||
add("org.sleuthkit.autopsy.keywordsearch.KeywordSearchModuleFactory"); //NON-NLS
|
||||
add("org.sleuthkit.autopsy.thunderbirdparser.EmailParserModuleFactory"); //NON-NLS
|
||||
add(EncryptionDetectionModuleFactory.class.getCanonicalName());
|
||||
|
@ -0,0 +1,4 @@
|
||||
# {0} - path
|
||||
UserMachinePreferences_validateTempDirectory_errorOnCreate_text=There was an error creating the temp directory for path: {0}
|
||||
# {0} - path
|
||||
UserMachinePreferences_validateTempDirectory_errorOnReadWrite_text=There was an error reading or writing to temp directory path: {0}
|
@ -0,0 +1,108 @@
|
||||
/*
|
||||
* Autopsy Forensic Browser
|
||||
*
|
||||
* Copyright 2020 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.machinesettings;
|
||||
|
||||
import java.io.File;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.prefs.Preferences;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.openide.util.NbBundle;
|
||||
import org.openide.util.NbPreferences;
|
||||
import org.sleuthkit.autopsy.coreutils.FileUtil;
|
||||
|
||||
/**
|
||||
* Provides case-specific settings like the user-specified temp folder.
|
||||
*/
|
||||
public final class UserMachinePreferences {
|
||||
|
||||
private static final Preferences preferences = NbPreferences.forModule(UserMachinePreferences.class);
|
||||
|
||||
private static final String TEMP_DIR_KEY = "TempDirectory";
|
||||
|
||||
/**
|
||||
* Retrieves a default temporary directory that is a subdirectory of
|
||||
* java.io.tmpdir.
|
||||
*
|
||||
* @return The absolute path to the temp directory.
|
||||
*/
|
||||
private static String getDefaultTempDirectory() {
|
||||
return Paths.get(System.getProperty("java.io.tmpdir")).toAbsolutePath().toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the base user-specified temporary directory.
|
||||
*
|
||||
* @return The base user-specified temporary directory.
|
||||
*/
|
||||
public static String getBaseTempDirectory() {
|
||||
String tempDir = preferences.get(TEMP_DIR_KEY, null);
|
||||
return StringUtils.isBlank(tempDir) ? getDefaultTempDirectory() : tempDir;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks to see if temporary directory location can be created and is
|
||||
* read/write.
|
||||
*
|
||||
* @param path The location.
|
||||
*
|
||||
* @return True if this is a valid location for a temp directory.
|
||||
*
|
||||
* @throws UserMachinePreferencesException If path could not be validated
|
||||
* due to mkdirs failure or the
|
||||
* directory is not read/write.
|
||||
*/
|
||||
@NbBundle.Messages({
|
||||
"# {0} - path",
|
||||
"UserMachinePreferences_validateTempDirectory_errorOnCreate_text=There was an error creating the temp directory for path: {0}",
|
||||
"# {0} - path",
|
||||
"UserMachinePreferences_validateTempDirectory_errorOnReadWrite_text=There was an error reading or writing to temp directory path: {0}"
|
||||
})
|
||||
private static boolean validateTempDirectory(String path) throws UserMachinePreferencesException {
|
||||
if (StringUtils.isBlank(path)) {
|
||||
// in this instance, the default path will be used.
|
||||
return true;
|
||||
}
|
||||
|
||||
File f = new File(path);
|
||||
if (!f.exists() && !f.mkdirs()) {
|
||||
throw new UserMachinePreferencesException(Bundle.UserMachinePreferences_validateTempDirectory_errorOnCreate_text(path));
|
||||
}
|
||||
|
||||
if (!FileUtil.hasReadWriteAccess(Paths.get(path))) {
|
||||
throw new UserMachinePreferencesException(Bundle.UserMachinePreferences_validateTempDirectory_errorOnReadWrite_text(path));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the base user-specified temporary directory.
|
||||
*
|
||||
* @param path The path to the directory.
|
||||
*
|
||||
* @throws UserMachinePreferencesException If the directory cannot be
|
||||
* accessed or created.
|
||||
*/
|
||||
public static void setBaseTempDirectory(String path) throws UserMachinePreferencesException {
|
||||
validateTempDirectory(path);
|
||||
preferences.put(TEMP_DIR_KEY, path);
|
||||
}
|
||||
|
||||
private UserMachinePreferences() {
|
||||
}
|
||||
}
|
@ -0,0 +1,45 @@
|
||||
/*
|
||||
* Autopsy Forensic Browser
|
||||
*
|
||||
* Copyright 2020 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.machinesettings;
|
||||
|
||||
/**
|
||||
* Exception class for UserMachinePreferences.
|
||||
*/
|
||||
public class UserMachinePreferencesException extends Exception {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* Main constructor.
|
||||
*
|
||||
* @param string The message for the exception.
|
||||
*/
|
||||
UserMachinePreferencesException(String string) {
|
||||
super(string);
|
||||
}
|
||||
|
||||
/**
|
||||
* Main constructor.
|
||||
*
|
||||
* @param string The message for the exception.
|
||||
* @param thrwbl The inner exception.
|
||||
*/
|
||||
UserMachinePreferencesException(String string, Throwable thrwbl) {
|
||||
super(string, thrwbl);
|
||||
}
|
||||
}
|
@ -1,8 +0,0 @@
|
||||
OpenIDE-Module-Display-Category=Ingest Module
|
||||
OpenIDE-Module-Long-Description=\
|
||||
Exif metadata ingest module. \n\n\
|
||||
The ingest module analyzes image files, extracts Exif information and posts the Exif data as results.
|
||||
OpenIDE-Module-Name=ExifParser
|
||||
OpenIDE-Module-Short-Description=Exif metadata ingest module
|
||||
ExifParserFileIngestModule.moduleName.text=Exif Parser
|
||||
ExifParserFileIngestModule.getDesc.text=Ingests JPEG files and retrieves their EXIF metadata.
|
@ -1,11 +0,0 @@
|
||||
CannotRunFileTypeDetection=Cannot run file type detection.
|
||||
ExifParserFileIngestModule.indexError.message=Failed to post EXIF Metadata artifact(s).
|
||||
ExifParserFileIngestModule.userContent.description=EXIF metadata exists for this file.
|
||||
OpenIDE-Module-Display-Category=Ingest Module
|
||||
OpenIDE-Module-Long-Description=\
|
||||
Exif metadata ingest module. \n\n\
|
||||
The ingest module analyzes image files, extracts Exif information and posts the Exif data as results.
|
||||
OpenIDE-Module-Name=ExifParser
|
||||
OpenIDE-Module-Short-Description=Exif metadata ingest module
|
||||
ExifParserFileIngestModule.moduleName.text=Exif Parser
|
||||
ExifParserFileIngestModule.getDesc.text=Ingests JPEG files and retrieves their EXIF metadata.
|
@ -1,10 +0,0 @@
|
||||
CannotRunFileTypeDetection=\u30d5\u30a1\u30a4\u30eb\u30bf\u30a4\u30d7\u306e\u691c\u51fa\u3092\u5b9f\u884c\u3067\u304d\u307e\u305b\u3093\u3002
|
||||
ExifParserFileIngestModule.indexError.message=\u30ad\u30fc\u30ef\u30fc\u30c9\u3092\u691c\u7d22\u3059\u308b\u305f\u3081\u306e\u3001EXIF\u30e1\u30bf\u30c7\u30fc\u30bf\u30a2\u30fc\u30c6\u30a3\u30d5\u30a1\u30af\u30c8\u3092\u30a4\u30f3\u30c7\u30c3\u30af\u30b9\u3067\u304d\u307e\u305b\u3093\u3067\u3057\u305f\u3002
|
||||
OpenIDE-Module-Display-Category=\u30a4\u30f3\u30b8\u30a7\u30b9\u30c8\u30e2\u30b8\u30e5\u30fc\u30eb
|
||||
OpenIDE-Module-Long-Description=\
|
||||
EXIF\u30e1\u30bf\u30c7\u30fc\u30bf\u30a4\u30f3\u30b8\u30a7\u30b9\u30c8\u30e2\u30b8\u30e5\u30fc\u30eb\u3067\u3059\u3002 \n\n\
|
||||
\u30a4\u30f3\u30b8\u30a7\u30b9\u30c8\u30e2\u30b8\u30e5\u30fc\u30eb\u304c\u30a4\u30e1\u30fc\u30b8\u30d5\u30a1\u30a4\u30eb\u3092\u89e3\u6790\u3057\u3001Exif\u60c5\u5831\u3092\u62bd\u51fa\u3057\u3001Exif\u30c7\u30fc\u30bf\u3092\u7d50\u679c\u3068\u3057\u3066\u6295\u7a3f\u3057\u307e\u3059\u3002
|
||||
OpenIDE-Module-Name=ExifParser
|
||||
OpenIDE-Module-Short-Description=Exif\u30e1\u30bf\u30c7\u30fc\u30bf\u30a4\u30f3\u30b8\u30a7\u30b9\u30c8\u30e2\u30b8\u30e5\u30fc\u30eb\u3067\u3059\u3002
|
||||
ExifParserFileIngestModule.moduleName.text=Exif\u89e3\u6790\u30c4\u30fc\u30eb
|
||||
ExifParserFileIngestModule.getDesc.text=Ingests JPEG\u30d5\u30a1\u30a4\u30eb\u3092\u30a4\u30f3\u30b8\u30a7\u30b9\u30c8\u3057\u3001EXIF\u30e1\u30bf\u30c7\u30fc\u30bf\u3092\u56de\u53ce\u3057\u307e\u3059\u3002
|
@ -1,249 +0,0 @@
|
||||
/*
|
||||
* Autopsy Forensic Browser
|
||||
*
|
||||
* Copyright 2011-2018 Basis Technology Corp.
|
||||
* Contact: carrier <at> sleuthkit <dot> org
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.sleuthkit.autopsy.modules.exif;
|
||||
|
||||
import com.drew.imaging.ImageMetadataReader;
|
||||
import com.drew.imaging.ImageProcessingException;
|
||||
import com.drew.lang.GeoLocation;
|
||||
import com.drew.lang.Rational;
|
||||
import com.drew.metadata.Metadata;
|
||||
import com.drew.metadata.exif.ExifIFD0Directory;
|
||||
import com.drew.metadata.exif.ExifSubIFDDirectory;
|
||||
import com.drew.metadata.exif.GpsDirectory;
|
||||
import java.io.BufferedInputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Date;
|
||||
import java.util.HashSet;
|
||||
import java.util.TimeZone;
|
||||
import java.util.logging.Level;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.openide.util.NbBundle;
|
||||
import org.openide.util.NbBundle.Messages;
|
||||
import org.sleuthkit.autopsy.casemodule.Case;
|
||||
import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException;
|
||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||
import org.sleuthkit.autopsy.coreutils.MessageNotifyUtil;
|
||||
import org.sleuthkit.autopsy.ingest.FileIngestModule;
|
||||
import org.sleuthkit.autopsy.ingest.IngestJobContext;
|
||||
import org.sleuthkit.autopsy.ingest.IngestModuleReferenceCounter;
|
||||
import org.sleuthkit.autopsy.modules.filetypeid.FileTypeDetector;
|
||||
import org.sleuthkit.datamodel.AbstractFile;
|
||||
import org.sleuthkit.datamodel.Blackboard;
|
||||
import org.sleuthkit.datamodel.BlackboardArtifact;
|
||||
import static org.sleuthkit.datamodel.BlackboardArtifact.ARTIFACT_TYPE.TSK_METADATA_EXIF;
|
||||
import static org.sleuthkit.datamodel.BlackboardArtifact.ARTIFACT_TYPE.TSK_USER_CONTENT_SUSPECTED;
|
||||
import org.sleuthkit.datamodel.BlackboardAttribute;
|
||||
import static org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME_CREATED;
|
||||
import static org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DEVICE_MAKE;
|
||||
import static org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DEVICE_MODEL;
|
||||
import static org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_GEO_ALTITUDE;
|
||||
import static org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_GEO_LATITUDE;
|
||||
import static org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_GEO_LONGITUDE;
|
||||
import org.sleuthkit.datamodel.Content;
|
||||
import org.sleuthkit.datamodel.Image;
|
||||
import org.sleuthkit.datamodel.ReadContentInputStream;
|
||||
import org.sleuthkit.datamodel.ReadContentInputStream.ReadContentInputStreamException;
|
||||
import org.sleuthkit.datamodel.TskCoreException;
|
||||
import org.sleuthkit.datamodel.TskData;
|
||||
import org.sleuthkit.datamodel.TskData.TSK_DB_FILES_TYPE_ENUM;
|
||||
|
||||
/**
|
||||
* Ingest module to parse image Exif metadata. Currently only supports JPEG
|
||||
* files. Ingests an image file and, if available, adds it's date, latitude,
|
||||
* longitude, altitude, device model, and device make to a blackboard artifact.
|
||||
*/
|
||||
@NbBundle.Messages({"CannotRunFileTypeDetection=Cannot run file type detection."})
|
||||
public final class ExifParserFileIngestModule implements FileIngestModule {
|
||||
|
||||
private static final Logger logger = Logger.getLogger(ExifParserFileIngestModule.class.getName());
|
||||
private static final String MODULE_NAME = ExifParserModuleFactory.getModuleName();
|
||||
private long jobId;
|
||||
private static final IngestModuleReferenceCounter refCounter = new IngestModuleReferenceCounter();
|
||||
private FileTypeDetector fileTypeDetector;
|
||||
private final HashSet<String> supportedMimeTypes = new HashSet<>();
|
||||
private TimeZone timeZone = null;
|
||||
private Blackboard blackboard;
|
||||
|
||||
ExifParserFileIngestModule() {
|
||||
supportedMimeTypes.add("audio/x-wav"); //NON-NLS
|
||||
supportedMimeTypes.add("image/jpeg"); //NON-NLS
|
||||
supportedMimeTypes.add("image/tiff"); //NON-NLS
|
||||
}
|
||||
|
||||
@Override
|
||||
public void startUp(IngestJobContext context) throws IngestModuleException {
|
||||
jobId = context.getJobId();
|
||||
refCounter.incrementAndGet(jobId);
|
||||
try {
|
||||
fileTypeDetector = new FileTypeDetector();
|
||||
} catch (FileTypeDetector.FileTypeDetectorInitException ex) {
|
||||
throw new IngestModuleException(Bundle.CannotRunFileTypeDetection(), ex);
|
||||
}
|
||||
}
|
||||
|
||||
@Messages({"ExifParserFileIngestModule.indexError.message=Failed to post EXIF Metadata artifact(s)."})
|
||||
@Override
|
||||
public ProcessResult process(AbstractFile content) {
|
||||
try {
|
||||
blackboard = Case.getCurrentCaseThrows().getSleuthkitCase().getBlackboard();
|
||||
} catch (NoCurrentCaseException ex) {
|
||||
logger.log(Level.INFO, "Exception while getting open case.", ex); //NON-NLS
|
||||
return ProcessResult.ERROR;
|
||||
}
|
||||
//skip unalloc
|
||||
if ((content.getType().equals(TSK_DB_FILES_TYPE_ENUM.UNALLOC_BLOCKS)
|
||||
|| (content.getType().equals(TSK_DB_FILES_TYPE_ENUM.SLACK)))) {
|
||||
return ProcessResult.OK;
|
||||
}
|
||||
|
||||
if (content.isFile() == false) {
|
||||
return ProcessResult.OK;
|
||||
}
|
||||
|
||||
// skip known
|
||||
if (content.getKnown().equals(TskData.FileKnown.KNOWN)) {
|
||||
return ProcessResult.OK;
|
||||
}
|
||||
|
||||
//skip unsupported
|
||||
if (!parsableFormat(content)) {
|
||||
return ProcessResult.OK;
|
||||
}
|
||||
|
||||
return processFile(content);
|
||||
}
|
||||
|
||||
@Messages({"ExifParserFileIngestModule.userContent.description=EXIF metadata exists for this file."})
|
||||
private ProcessResult processFile(AbstractFile file) {
|
||||
|
||||
try (BufferedInputStream bin = new BufferedInputStream(new ReadContentInputStream(file));) {
|
||||
|
||||
Collection<BlackboardAttribute> attributes = new ArrayList<>();
|
||||
Metadata metadata = ImageMetadataReader.readMetadata(bin);
|
||||
|
||||
// Date
|
||||
ExifSubIFDDirectory exifDir = metadata.getFirstDirectoryOfType(ExifSubIFDDirectory.class);
|
||||
if (exifDir != null) {
|
||||
|
||||
// set the timeZone for the current datasource.
|
||||
if (timeZone == null) {
|
||||
try {
|
||||
Content dataSource = file.getDataSource();
|
||||
if ((dataSource != null) && (dataSource instanceof Image)) {
|
||||
Image image = (Image) dataSource;
|
||||
timeZone = TimeZone.getTimeZone(image.getTimeZone());
|
||||
}
|
||||
} catch (TskCoreException ex) {
|
||||
logger.log(Level.INFO, "Error getting time zones", ex); //NON-NLS
|
||||
}
|
||||
}
|
||||
Date date = exifDir.getDate(ExifSubIFDDirectory.TAG_DATETIME_ORIGINAL, timeZone);
|
||||
if (date != null) {
|
||||
attributes.add(new BlackboardAttribute(TSK_DATETIME_CREATED, MODULE_NAME, date.getTime() / 1000));
|
||||
}
|
||||
}
|
||||
|
||||
// GPS Stuff
|
||||
GpsDirectory gpsDir = metadata.getFirstDirectoryOfType(GpsDirectory.class);
|
||||
if (gpsDir != null) {
|
||||
GeoLocation loc = gpsDir.getGeoLocation();
|
||||
if (loc != null) {
|
||||
attributes.add(new BlackboardAttribute(TSK_GEO_LATITUDE, MODULE_NAME, loc.getLatitude()));
|
||||
attributes.add(new BlackboardAttribute(TSK_GEO_LONGITUDE, MODULE_NAME, loc.getLongitude()));
|
||||
}
|
||||
|
||||
Rational altitude = gpsDir.getRational(GpsDirectory.TAG_ALTITUDE);
|
||||
if (altitude != null) {
|
||||
attributes.add(new BlackboardAttribute(TSK_GEO_ALTITUDE, MODULE_NAME, altitude.doubleValue()));
|
||||
}
|
||||
}
|
||||
|
||||
// Device info
|
||||
ExifIFD0Directory devDir = metadata.getFirstDirectoryOfType(ExifIFD0Directory.class);
|
||||
if (devDir != null) {
|
||||
String model = devDir.getString(ExifIFD0Directory.TAG_MODEL);
|
||||
if (StringUtils.isNotBlank(model)) {
|
||||
attributes.add(new BlackboardAttribute(TSK_DEVICE_MODEL, MODULE_NAME, model));
|
||||
}
|
||||
|
||||
String make = devDir.getString(ExifIFD0Directory.TAG_MAKE);
|
||||
if (StringUtils.isNotBlank(make)) {
|
||||
attributes.add(new BlackboardAttribute(TSK_DEVICE_MAKE, MODULE_NAME, make));
|
||||
}
|
||||
}
|
||||
|
||||
// Add the attributes, if there are any, to a new artifact
|
||||
if (!attributes.isEmpty()) {
|
||||
// Create artifact if it doesn't already exist.
|
||||
if (!blackboard.artifactExists(file, TSK_METADATA_EXIF, attributes)) {
|
||||
BlackboardArtifact bba = file.newArtifact(TSK_METADATA_EXIF);
|
||||
BlackboardArtifact bba2 = file.newArtifact(TSK_USER_CONTENT_SUSPECTED);
|
||||
bba.addAttributes(attributes);
|
||||
bba2.addAttribute(new BlackboardAttribute(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_COMMENT, MODULE_NAME, Bundle.ExifParserFileIngestModule_userContent_description()));
|
||||
try {
|
||||
// index the artifact for keyword search
|
||||
blackboard.postArtifact(bba, MODULE_NAME);
|
||||
blackboard.postArtifact(bba2, MODULE_NAME);
|
||||
} catch (Blackboard.BlackboardException ex) {
|
||||
logger.log(Level.SEVERE, "Unable to index blackboard artifact " + bba.getArtifactID(), ex); //NON-NLS
|
||||
MessageNotifyUtil.Notify.error(
|
||||
Bundle.ExifParserFileIngestModule_indexError_message(), bba.getDisplayName());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ProcessResult.OK;
|
||||
} catch (TskCoreException ex) {
|
||||
logger.log(Level.WARNING, "Failed to create blackboard artifact for exif metadata ({0}).", ex.getLocalizedMessage()); //NON-NLS
|
||||
return ProcessResult.ERROR;
|
||||
} catch (ImageProcessingException ex) {
|
||||
logger.log(Level.WARNING, String.format("Failed to process the image file '%s/%s' (id=%d).", file.getParentPath(), file.getName(), file.getId()), ex);
|
||||
return ProcessResult.ERROR;
|
||||
} catch (ReadContentInputStreamException ex) {
|
||||
logger.log(Level.WARNING, String.format("Error while trying to read image file '%s/%s' (id=%d).", file.getParentPath(), file.getName(), file.getId()), ex); //NON-NLS
|
||||
return ProcessResult.ERROR;
|
||||
} catch (IOException ex) {
|
||||
logger.log(Level.WARNING, String.format("IOException when parsing image file '%s/%s' (id=%d).", file.getParentPath(), file.getName(), file.getId()), ex); //NON-NLS
|
||||
return ProcessResult.ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if should try to attempt to extract exif. Currently checks if
|
||||
* JPEG, TIFF or X-WAV (by signature)
|
||||
*
|
||||
* @param f file to be checked
|
||||
*
|
||||
* @return true if to be processed
|
||||
*/
|
||||
private boolean parsableFormat(AbstractFile f) {
|
||||
String mimeType = fileTypeDetector.getMIMEType(f);
|
||||
return supportedMimeTypes.contains(mimeType);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void shutDown() {
|
||||
// We only need to check for this final event on the last module per job
|
||||
if (refCounter.decrementAndGet(jobId) == 0) {
|
||||
timeZone = null;
|
||||
}
|
||||
}
|
||||
}
|
@ -1,3 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE filesystem PUBLIC "-//NetBeans//DTD Filesystem 1.2//EN" "http://www.netbeans.org/dtds/filesystem-1_2.dtd">
|
||||
<filesystem />
|
@ -72,7 +72,10 @@ public final class HashDatabaseOptionsPanelController extends OptionsPanelContro
|
||||
*/
|
||||
@Override
|
||||
public void cancel() {
|
||||
if(changed) {
|
||||
getPanel().cancel();
|
||||
changed = false;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -326,6 +326,7 @@ public class HashDbManager implements PropertyChangeListener {
|
||||
}
|
||||
|
||||
// Add the hash database to the collection
|
||||
if(!hashSets.contains(db)) {
|
||||
hashSets.add(db);
|
||||
|
||||
// Let any external listeners know that there's a new set
|
||||
@ -338,6 +339,7 @@ public class HashDbManager implements PropertyChangeListener {
|
||||
NbBundle.getMessage(this.getClass(), "HashDbManager.moduleErrorListeningToUpdatesMsg"),
|
||||
MessageNotifyUtil.MessageType.ERROR);
|
||||
}
|
||||
}
|
||||
return db;
|
||||
|
||||
}
|
||||
|
@ -18,14 +18,17 @@
|
||||
*/
|
||||
package org.sleuthkit.autopsy.modules.hashdatabase;
|
||||
|
||||
import java.awt.Component;
|
||||
import java.beans.PropertyChangeEvent;
|
||||
import java.beans.PropertyChangeListener;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.logging.Level;
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.JScrollPane;
|
||||
import javax.swing.JTable;
|
||||
import javax.swing.table.AbstractTableModel;
|
||||
import javax.swing.table.DefaultTableCellRenderer;
|
||||
import javax.swing.table.TableColumn;
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||
@ -78,6 +81,7 @@ public final class HashLookupModuleSettingsPanel extends IngestModuleIngestJobSe
|
||||
if (i == 0) {
|
||||
column.setPreferredWidth(((int) (width1 * 0.07)));
|
||||
} else {
|
||||
column.setCellRenderer(new HashSetTableCellRenderer());
|
||||
column.setPreferredWidth(((int) (width1 * 0.92)));
|
||||
}
|
||||
}
|
||||
@ -226,6 +230,24 @@ public final class HashLookupModuleSettingsPanel extends IngestModuleIngestJobSe
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Simple TableCellRenderer to add tool tips to the cells
|
||||
*/
|
||||
private static final class HashSetTableCellRenderer extends DefaultTableCellRenderer{
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
@Override
|
||||
public Component getTableCellRendererComponent(
|
||||
JTable table, Object value,
|
||||
boolean isSelected, boolean hasFocus,
|
||||
int row, int column) {
|
||||
JLabel label = (JLabel)super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
|
||||
label.setToolTipText(label.getText());
|
||||
return label;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static final class HashSetsTableModel extends AbstractTableModel {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
@ -18,13 +18,16 @@
|
||||
*/
|
||||
package org.sleuthkit.autopsy.modules.interestingitems;
|
||||
|
||||
import java.awt.Component;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Observable;
|
||||
import java.util.Observer;
|
||||
import java.util.TreeMap;
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.JTable;
|
||||
import javax.swing.table.AbstractTableModel;
|
||||
import javax.swing.table.DefaultTableCellRenderer;
|
||||
import javax.swing.table.TableColumn;
|
||||
import org.openide.util.NbBundle.Messages;
|
||||
import org.sleuthkit.autopsy.coreutils.MessageNotifyUtil;
|
||||
@ -110,6 +113,7 @@ final class FilesIdentifierIngestJobSettingsPanel extends IngestModuleIngestJobS
|
||||
if (i == 0) {
|
||||
column.setPreferredWidth(((int) (width * 0.07)));
|
||||
} else {
|
||||
column.setCellRenderer(new FileSetsTableCellRenderer());
|
||||
column.setPreferredWidth(((int) (width * 0.92)));
|
||||
}
|
||||
}
|
||||
@ -159,6 +163,24 @@ final class FilesIdentifierIngestJobSettingsPanel extends IngestModuleIngestJobS
|
||||
this.filesSetSnapshot = newFilesSetSnapshot;
|
||||
}
|
||||
|
||||
/**
|
||||
* Simple TableCellRenderer to add tool tips to cells.
|
||||
*/
|
||||
private static final class FileSetsTableCellRenderer extends DefaultTableCellRenderer {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@Override
|
||||
public Component getTableCellRendererComponent(
|
||||
JTable table, Object value,
|
||||
boolean isSelected, boolean hasFocus,
|
||||
int row, int column) {
|
||||
JLabel label = (JLabel) super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
|
||||
label.setToolTipText(label.getText());
|
||||
return label;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Table model for a JTable component that allows users to enable and
|
||||
* disable interesting files set definitions for an ingest job.
|
||||
|
@ -19,3 +19,10 @@ PhotoRecIngestModule.error.msg=Error processing {0} with PhotoRec carver.
|
||||
PhotoRecIngestModule.complete.numberOfErrors=Number of Errors while Carving:
|
||||
PhotoRecCarverIngestJobSettingsPanel.detectionSettingsLabel.text=PhotoRec Settings
|
||||
PhotoRecCarverIngestJobSettingsPanel.keepCorruptedFilesCheckbox.text=Keep corrupted files
|
||||
PhotoRecCarverIngestJobSettingsPanel.includeExcludeCheckbox.text=Focus on certain file types
|
||||
PhotoRecCarverIngestJobSettingsPanel.fullListOfTypesLabel.text=Full List of Types:
|
||||
PhotoRecCarverIngestJobSettingsPanel.exampleLabel.text=Example: jpg,png,zip
|
||||
PhotoRecCarverIngestJobSettingsPanel.extensionListTextfield.text=
|
||||
PhotoRecCarverIngestJobSettingsPanel.extensionListLabel.text=Types (comma separated list of extensions)
|
||||
PhotoRecCarverIngestJobSettingsPanel.excludeRadioButton.text=Exclude the specified types
|
||||
PhotoRecCarverIngestJobSettingsPanel.includeRadioButton.text=Include only the specified types
|
||||
|
@ -8,6 +8,9 @@ OpenIDE-Module-Long-Description=PhotoRec Carver ingest module. \n\n Carves unall
|
||||
OpenIDE-Module-Short-Description=Carves unallocated space and feeds carved files back into the system for processing.
|
||||
moduleDisplayName.text=PhotoRec Carver
|
||||
moduleDescription.text=Runs PhotoRec carver against unallocated space in the data source.
|
||||
# {0} - extensions
|
||||
PhotoRecCarverFileIngestModule_startUp_invalidExtensions_description=The following extensions are invalid: {0}
|
||||
PhotoRecCarverFileIngestModule_startUp_noExtensionsProvided_description=No extensions provided for PhotoRec to carve.
|
||||
PhotoRecIngestModule.nonHostnameUNCPathUsed=PhotoRec cannot operate with a UNC path containing IP addresses.
|
||||
PhotoRecIngestModule.PermissionsNotSufficient=Insufficient permissions accessing
|
||||
PhotoRecIngestModule.PermissionsNotSufficientSeeReference=See 'Shared Drive Authentication' in Autopsy help.
|
||||
@ -26,5 +29,12 @@ PhotoRecIngestModule.error.msg=Error processing {0} with PhotoRec carver.
|
||||
PhotoRecIngestModule.complete.numberOfErrors=Number of Errors while Carving:
|
||||
PhotoRecCarverIngestJobSettingsPanel.detectionSettingsLabel.text=PhotoRec Settings
|
||||
PhotoRecCarverIngestJobSettingsPanel.keepCorruptedFilesCheckbox.text=Keep corrupted files
|
||||
PhotoRecCarverIngestJobSettingsPanel.includeExcludeCheckbox.text=Focus on certain file types
|
||||
PhotoRecCarverIngestJobSettingsPanel.fullListOfTypesLabel.text=Full List of Types:
|
||||
PhotoRecCarverIngestJobSettingsPanel.exampleLabel.text=Example: jpg,png,zip
|
||||
PhotoRecCarverIngestJobSettingsPanel.extensionListTextfield.text=
|
||||
PhotoRecCarverIngestJobSettingsPanel.extensionListLabel.text=Types (comma separated list of extensions)
|
||||
PhotoRecCarverIngestJobSettingsPanel.excludeRadioButton.text=Exclude the specified types
|
||||
PhotoRecCarverIngestJobSettingsPanel.includeRadioButton.text=Include only the specified types
|
||||
unallocatedSpaceProcessingSettingsError.message=The selected file ingest filter ignores unallocated space. This module carves unallocated space. Please choose a filter which does not ignore unallocated space or disable this module.
|
||||
unsupportedOS.message=PhotoRec module is supported on Windows platforms only.
|
||||
|
@ -29,6 +29,7 @@ import java.nio.file.Paths;
|
||||
import java.text.DateFormat;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
@ -36,6 +37,7 @@ import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.atomic.AtomicLong;
|
||||
import java.util.logging.Level;
|
||||
import java.util.stream.Collectors;
|
||||
import org.openide.modules.InstalledFileLocator;
|
||||
import org.openide.util.NbBundle;
|
||||
import org.sleuthkit.autopsy.casemodule.Case;
|
||||
@ -79,7 +81,12 @@ import org.sleuthkit.datamodel.TskData;
|
||||
final class PhotoRecCarverFileIngestModule implements FileIngestModule {
|
||||
|
||||
static final boolean DEFAULT_CONFIG_KEEP_CORRUPTED_FILES = false;
|
||||
static final PhotoRecCarverIngestJobSettings.ExtensionFilterOption DEFAULT_CONFIG_EXTENSION_FILTER
|
||||
= PhotoRecCarverIngestJobSettings.ExtensionFilterOption.NO_FILTER;
|
||||
|
||||
static final boolean DEFAULT_CONFIG_INCLUDE_ELSE_EXCLUDE = false;
|
||||
|
||||
private static final String PHOTOREC_TEMP_SUBDIR = "Photorec";
|
||||
private static final String PHOTOREC_DIRECTORY = "photorec_exec"; //NON-NLS
|
||||
private static final String PHOTOREC_SUBDIRECTORY = "bin"; //NON-NLS
|
||||
private static final String PHOTOREC_EXECUTABLE = "photorec_win.exe"; //NON-NLS
|
||||
@ -88,7 +95,6 @@ final class PhotoRecCarverFileIngestModule implements FileIngestModule {
|
||||
private static final String PHOTOREC_RESULTS_EXTENDED = "results.1"; //NON-NLS
|
||||
private static final String PHOTOREC_REPORT = "report.xml"; //NON-NLS
|
||||
private static final String LOG_FILE = "run_log.txt"; //NON-NLS
|
||||
private static final String TEMP_DIR_NAME = "temp"; // NON-NLS
|
||||
private static final String SEP = System.getProperty("line.separator");
|
||||
private static final Logger logger = Logger.getLogger(PhotoRecCarverFileIngestModule.class.getName());
|
||||
private static final HashMap<Long, IngestJobTotals> totalsForIngestJobs = new HashMap<>();
|
||||
@ -96,26 +102,74 @@ final class PhotoRecCarverFileIngestModule implements FileIngestModule {
|
||||
private static final Map<Long, WorkingPaths> pathsByJob = new ConcurrentHashMap<>();
|
||||
private IngestJobContext context;
|
||||
private Path rootOutputDirPath;
|
||||
private Path rootTempDirPath;
|
||||
private File executableFile;
|
||||
private IngestServices services;
|
||||
private final UNCPathUtilities uncPathUtilities = new UNCPathUtilities();
|
||||
private final PhotoRecCarverIngestJobSettings settings;
|
||||
private String optionsString;
|
||||
private long jobId;
|
||||
|
||||
private final boolean keepCorruptedFiles;
|
||||
|
||||
private static class IngestJobTotals {
|
||||
|
||||
private final AtomicLong totalItemsRecovered = new AtomicLong(0);
|
||||
private final AtomicLong totalItemsWithErrors = new AtomicLong(0);
|
||||
private final AtomicLong totalWritetime = new AtomicLong(0);
|
||||
private final AtomicLong totalParsetime = new AtomicLong(0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a PhotoRec Carver ingest module instance.
|
||||
*
|
||||
* @param settings Ingest job settings used to configure the module.
|
||||
*/
|
||||
PhotoRecCarverFileIngestModule(PhotoRecCarverIngestJobSettings settings) {
|
||||
keepCorruptedFiles = settings.isKeepCorruptedFiles();
|
||||
this.settings = settings;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a photorec command line options string based on the settings.
|
||||
*
|
||||
* @param settings The settings.
|
||||
*
|
||||
* @return The options string to be provided to Photorec on the command
|
||||
* line.
|
||||
*/
|
||||
private String getPhotorecOptions(PhotoRecCarverIngestJobSettings settings) {
|
||||
List<String> toRet = new ArrayList<String>();
|
||||
|
||||
if (settings.isKeepCorruptedFiles()) {
|
||||
toRet.addAll(Arrays.asList("options", "keep_corrupted_file"));
|
||||
}
|
||||
|
||||
if (settings.getExtensionFilterOption()
|
||||
!= PhotoRecCarverIngestJobSettings.ExtensionFilterOption.NO_FILTER) {
|
||||
|
||||
// add the file opt menu item
|
||||
toRet.add("fileopt");
|
||||
|
||||
String enable = "enable";
|
||||
String disable = "disable";
|
||||
|
||||
// if we are including file extensions, then we are excluding
|
||||
// everything else and vice-versa.
|
||||
String everythingEnable = settings.getExtensionFilterOption()
|
||||
== PhotoRecCarverIngestJobSettings.ExtensionFilterOption.INCLUDE
|
||||
? disable : enable;
|
||||
|
||||
toRet.addAll(Arrays.asList("everything", everythingEnable));
|
||||
|
||||
final String itemEnable = settings.getExtensionFilterOption()
|
||||
== PhotoRecCarverIngestJobSettings.ExtensionFilterOption.INCLUDE
|
||||
? enable : disable;
|
||||
|
||||
settings.getExtensions().forEach((extension) -> {
|
||||
toRet.addAll(Arrays.asList(extension, itemEnable));
|
||||
});
|
||||
}
|
||||
|
||||
toRet.add("search");
|
||||
return String.join(",", toRet);
|
||||
}
|
||||
|
||||
private static synchronized IngestJobTotals getTotalsForIngestJobs(long ingestJobId) {
|
||||
@ -136,7 +190,34 @@ final class PhotoRecCarverFileIngestModule implements FileIngestModule {
|
||||
* @inheritDoc
|
||||
*/
|
||||
@Override
|
||||
@NbBundle.Messages({
|
||||
"# {0} - extensions",
|
||||
"PhotoRecCarverFileIngestModule_startUp_invalidExtensions_description=The following extensions are invalid: {0}",
|
||||
"PhotoRecCarverFileIngestModule_startUp_noExtensionsProvided_description=No extensions provided for PhotoRec to carve."
|
||||
})
|
||||
public void startUp(IngestJobContext context) throws IngestModule.IngestModuleException {
|
||||
// validate settings
|
||||
if (this.settings.getExtensionFilterOption() != PhotoRecCarverIngestJobSettings.ExtensionFilterOption.NO_FILTER) {
|
||||
if (this.settings.getExtensions().isEmpty()
|
||||
&& this.settings.getExtensionFilterOption() == PhotoRecCarverIngestJobSettings.ExtensionFilterOption.INCLUDE) {
|
||||
|
||||
throw new IngestModule.IngestModuleException(
|
||||
Bundle.PhotoRecCarverFileIngestModule_startUp_noExtensionsProvided_description());
|
||||
}
|
||||
|
||||
List<String> invalidExtensions = this.settings.getExtensions().stream()
|
||||
.filter((ext) -> !PhotoRecCarverFileOptExtensions.isValidExtension(ext))
|
||||
.collect(Collectors.toList());
|
||||
|
||||
if (!invalidExtensions.isEmpty()) {
|
||||
throw new IngestModule.IngestModuleException(
|
||||
Bundle.PhotoRecCarverFileIngestModule_startUp_invalidExtensions_description(
|
||||
String.join(",", invalidExtensions)));
|
||||
}
|
||||
}
|
||||
|
||||
this.optionsString = getPhotorecOptions(this.settings);
|
||||
|
||||
this.context = context;
|
||||
this.services = IngestServices.getInstance();
|
||||
this.jobId = this.context.getJobId();
|
||||
@ -150,6 +231,7 @@ final class PhotoRecCarverFileIngestModule implements FileIngestModule {
|
||||
}
|
||||
|
||||
this.rootOutputDirPath = createModuleOutputDirectoryForCase();
|
||||
this.rootTempDirPath = createTempOutputDirectoryForCase();
|
||||
|
||||
//Set photorec executable directory based on operating system.
|
||||
executableFile = locateExecutable();
|
||||
@ -164,7 +246,7 @@ final class PhotoRecCarverFileIngestModule implements FileIngestModule {
|
||||
Files.createDirectories(outputDirPath);
|
||||
|
||||
// A temp subdirectory is also created as a location for writing unallocated space files to disk.
|
||||
Path tempDirPath = Paths.get(outputDirPath.toString(), PhotoRecCarverFileIngestModule.TEMP_DIR_NAME);
|
||||
Path tempDirPath = Paths.get(this.rootTempDirPath.toString(), folder);
|
||||
Files.createDirectory(tempDirPath);
|
||||
|
||||
// Save the directories for the current job.
|
||||
@ -242,11 +324,8 @@ final class PhotoRecCarverFileIngestModule implements FileIngestModule {
|
||||
outputDirPath.toAbsolutePath().toString() + File.separator + PHOTOREC_RESULTS_BASE,
|
||||
"/cmd", // NON-NLS
|
||||
tempFilePath.toFile().toString());
|
||||
if (keepCorruptedFiles) {
|
||||
processAndSettings.command().add("options,keep_corrupted_file,search"); // NON-NLS
|
||||
} else {
|
||||
processAndSettings.command().add("search"); // NON-NLS
|
||||
}
|
||||
|
||||
processAndSettings.command().add(this.optionsString);
|
||||
|
||||
// Add environment variable to force PhotoRec to run with the same permissions Autopsy uses
|
||||
processAndSettings.environment().put("__COMPAT_LAYER", "RunAsInvoker"); //NON-NLS
|
||||
@ -389,8 +468,7 @@ final class PhotoRecCarverFileIngestModule implements FileIngestModule {
|
||||
try {
|
||||
// The last instance of this module for an ingest job cleans out
|
||||
// the working paths map entry for the job and deletes the temp dir.
|
||||
WorkingPaths paths = PhotoRecCarverFileIngestModule.pathsByJob.remove(this.jobId);
|
||||
FileUtil.deleteDir(new File(paths.getTempDirPath().toString()));
|
||||
FileUtil.deleteDir(this.rootTempDirPath.toFile());
|
||||
postSummary(jobId);
|
||||
} catch (SecurityException ex) {
|
||||
logger.log(Level.SEVERE, "Error shutting down PhotoRec carver module", ex); // NON-NLS
|
||||
@ -418,20 +496,51 @@ final class PhotoRecCarverFileIngestModule implements FileIngestModule {
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates the output directory for this module for the current case, if it
|
||||
* does not already exist.
|
||||
* Creates the output directory for this module for the current case's temp
|
||||
* directory, if it does not already exist.
|
||||
*
|
||||
* @return The absolute path of the output directory.
|
||||
*
|
||||
* @throws org.sleuthkit.autopsy.ingest.IngestModule.IngestModuleException
|
||||
*/
|
||||
synchronized Path createTempOutputDirectoryForCase() throws IngestModule.IngestModuleException {
|
||||
try {
|
||||
Path path = Paths.get(Case.getCurrentCaseThrows().getTempDirectory(), PHOTOREC_TEMP_SUBDIR);
|
||||
return createOutputDirectoryForCase(path);
|
||||
} catch (NoCurrentCaseException ex) {
|
||||
throw new IngestModule.IngestModuleException(Bundle.cannotCreateOutputDir_message(ex.getLocalizedMessage()), ex);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates the output directory for this module for the current case's
|
||||
* module directory, if it does not already exist.
|
||||
*
|
||||
* @return The absolute path of the output directory.
|
||||
*
|
||||
* @throws org.sleuthkit.autopsy.ingest.IngestModule.IngestModuleException
|
||||
*/
|
||||
synchronized Path createModuleOutputDirectoryForCase() throws IngestModule.IngestModuleException {
|
||||
Path path;
|
||||
try {
|
||||
path = Paths.get(Case.getCurrentCaseThrows().getModuleDirectory(), PhotoRecCarverIngestModuleFactory.getModuleName());
|
||||
Path path = Paths.get(Case.getCurrentCaseThrows().getModuleDirectory(), PhotoRecCarverIngestModuleFactory.getModuleName());
|
||||
return createOutputDirectoryForCase(path);
|
||||
} catch (NoCurrentCaseException ex) {
|
||||
throw new IngestModule.IngestModuleException(Bundle.cannotCreateOutputDir_message(ex.getLocalizedMessage()), ex);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates the output directory for this module for the current case, if it
|
||||
* does not already exist.
|
||||
*
|
||||
* @param providedPath The absolute path to be created.
|
||||
*
|
||||
* @return The absolute path of the output directory.
|
||||
*
|
||||
* @throws org.sleuthkit.autopsy.ingest.IngestModule.IngestModuleException
|
||||
*/
|
||||
private synchronized Path createOutputDirectoryForCase(Path providedPath) throws IngestModule.IngestModuleException {
|
||||
Path path = providedPath;
|
||||
try {
|
||||
Files.createDirectory(path);
|
||||
if (UNCPathUtilities.isUNC(path)) {
|
||||
@ -455,7 +564,6 @@ final class PhotoRecCarverFileIngestModule implements FileIngestModule {
|
||||
return path;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Finds and returns the path to the executable, if able.
|
||||
*
|
||||
@ -490,7 +598,6 @@ final class PhotoRecCarverFileIngestModule implements FileIngestModule {
|
||||
throw new IngestModule.IngestModuleException(Bundle.missingExecutable_message());
|
||||
}
|
||||
|
||||
|
||||
if (!exeFile.canExecute()) {
|
||||
throw new IngestModule.IngestModuleException(Bundle.cannotRunExecutable_message());
|
||||
}
|
||||
|
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