Merge branch 'sleuthkit:develop' into develop

This commit is contained in:
Seb2lyon 2021-05-29 12:22:42 +02:00
commit fa7cbf407e
30 changed files with 376 additions and 286 deletions

View File

@ -105,6 +105,7 @@ Metadata.nodeText.exceptionNotice.text=Error getting file metadata:
MessageArtifactViewer.textbodyScrollPane.TabConstraints.tabTitle=Text MessageArtifactViewer.textbodyScrollPane.TabConstraints.tabTitle=Text
JPEGViewerDummy.jLabel1.text=You are looking at a JPEG file: JPEGViewerDummy.jLabel1.text=You are looking at a JPEG file:
JPEGViewerDummy.jTextField1.text=jTextField1 JPEGViewerDummy.jTextField1.text=jTextField1
Metadata_dataArtifactTitle=Source File Metadata
PDFViewer.encryptedDialog=This document is password protected. PDFViewer.encryptedDialog=This document is password protected.
PDFViewer.errorDialog=An error occurred while opening this PDF document. Check the logs for more information. You may continue to use this feature on other PDF documents. PDFViewer.errorDialog=An error occurred while opening this PDF document. Check the logs for more information. You may continue to use this feature on other PDF documents.
PListNode.KeyCol=Key PListNode.KeyCol=Key

View File

@ -1,7 +1,7 @@
/* /*
* Autopsy Forensic Browser * Autopsy Forensic Browser
* *
* Copyright 2013-2018 Basis Technology Corp. * Copyright 2013-2021 Basis Technology Corp.
* Contact: carrier <at> sleuthkit <dot> org * Contact: carrier <at> sleuthkit <dot> org
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
@ -26,18 +26,18 @@ import java.util.logging.Level;
import javax.swing.SwingWorker; import javax.swing.SwingWorker;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.openide.nodes.Node; import org.openide.nodes.Node;
import org.openide.util.Exceptions;
import org.openide.util.NbBundle; import org.openide.util.NbBundle;
import org.openide.util.NbBundle.Messages; import org.openide.util.NbBundle.Messages;
import org.openide.util.lookup.ServiceProvider; import org.openide.util.lookup.ServiceProvider;
import org.sleuthkit.autopsy.corecomponentinterfaces.DataContentViewer; import org.sleuthkit.autopsy.corecomponentinterfaces.DataContentViewer;
import org.sleuthkit.autopsy.datamodel.ContentUtils;
import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.autopsy.coreutils.Logger;
import org.sleuthkit.autopsy.coreutils.TimeZoneUtils;
import org.sleuthkit.datamodel.AbstractFile; import org.sleuthkit.datamodel.AbstractFile;
import org.sleuthkit.datamodel.BlackboardArtifact; import org.sleuthkit.datamodel.BlackboardArtifact;
import org.sleuthkit.datamodel.BlackboardArtifact.ARTIFACT_TYPE; import org.sleuthkit.datamodel.BlackboardArtifact.ARTIFACT_TYPE;
import org.sleuthkit.datamodel.BlackboardAttribute; import org.sleuthkit.datamodel.BlackboardAttribute;
import org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE; import org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE;
import org.sleuthkit.datamodel.DataArtifact;
import org.sleuthkit.datamodel.DataSource; import org.sleuthkit.datamodel.DataSource;
import org.sleuthkit.datamodel.Image; import org.sleuthkit.datamodel.Image;
import org.sleuthkit.datamodel.FsContent; import org.sleuthkit.datamodel.FsContent;
@ -229,9 +229,23 @@ public class Metadata extends javax.swing.JPanel implements DataContentViewer {
@Override @Override
public String getTitle() { public String getTitle() {
return NbBundle.getMessage(this.getClass(), "Metadata.title"); return getTitle(null);
} }
@Messages({
"Metadata_dataArtifactTitle=Source File Metadata"
})
@Override
public String getTitle(Node node) {
if (node != null && !node.getLookup().lookupAll(DataArtifact.class).isEmpty()) {
return Bundle.Metadata_dataArtifactTitle();
} else {
return NbBundle.getMessage(this.getClass(), "Metadata.title");
}
}
@Override @Override
public String getToolTip() { public String getToolTip() {
return NbBundle.getMessage(this.getClass(), "Metadata.toolTip"); return NbBundle.getMessage(this.getClass(), "Metadata.toolTip");
@ -299,10 +313,10 @@ public class Metadata extends javax.swing.JPanel implements DataContentViewer {
addRow(sb, NbBundle.getMessage(this.getClass(), "Metadata.tableRowTitle.size"), Long.toString(file.getSize())); addRow(sb, NbBundle.getMessage(this.getClass(), "Metadata.tableRowTitle.size"), Long.toString(file.getSize()));
addRow(sb, NbBundle.getMessage(this.getClass(), "Metadata.tableRowTitle.fileNameAlloc"), file.getDirFlagAsString()); addRow(sb, NbBundle.getMessage(this.getClass(), "Metadata.tableRowTitle.fileNameAlloc"), file.getDirFlagAsString());
addRow(sb, NbBundle.getMessage(this.getClass(), "Metadata.tableRowTitle.metadataAlloc"), file.getMetaFlagsAsString()); addRow(sb, NbBundle.getMessage(this.getClass(), "Metadata.tableRowTitle.metadataAlloc"), file.getMetaFlagsAsString());
addRow(sb, NbBundle.getMessage(this.getClass(), "Metadata.tableRowTitle.modified"), ContentUtils.getStringTime(file.getMtime(), file)); addRow(sb, NbBundle.getMessage(this.getClass(), "Metadata.tableRowTitle.modified"), TimeZoneUtils.getFormattedTime(file.getMtime()));
addRow(sb, NbBundle.getMessage(this.getClass(), "Metadata.tableRowTitle.accessed"), ContentUtils.getStringTime(file.getAtime(), file)); addRow(sb, NbBundle.getMessage(this.getClass(), "Metadata.tableRowTitle.accessed"), TimeZoneUtils.getFormattedTime(file.getAtime()));
addRow(sb, NbBundle.getMessage(this.getClass(), "Metadata.tableRowTitle.created"), ContentUtils.getStringTime(file.getCrtime(), file)); addRow(sb, NbBundle.getMessage(this.getClass(), "Metadata.tableRowTitle.created"), TimeZoneUtils.getFormattedTime(file.getCrtime()));
addRow(sb, NbBundle.getMessage(this.getClass(), "Metadata.tableRowTitle.changed"), ContentUtils.getStringTime(file.getCtime(), file)); addRow(sb, NbBundle.getMessage(this.getClass(), "Metadata.tableRowTitle.changed"), TimeZoneUtils.getFormattedTime(file.getCtime()));
String md5 = file.getMd5Hash(); String md5 = file.getMd5Hash();
if (md5 == null) { if (md5 == null) {

View File

@ -1,7 +1,7 @@
/* /*
* Autopsy Forensic Browser * Autopsy Forensic Browser
* *
* Copyright 2011-2020 Basis Technology Corp. * Copyright 2011-2021 Basis Technology Corp.
* Contact: carrier <at> sleuthkit <dot> org * Contact: carrier <at> sleuthkit <dot> org
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
@ -41,7 +41,6 @@ import javax.swing.text.View;
import org.apache.commons.lang.StringUtils; import org.apache.commons.lang.StringUtils;
import org.openide.util.NbBundle; import org.openide.util.NbBundle;
import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.autopsy.coreutils.Logger;
import org.sleuthkit.autopsy.datamodel.ContentUtils;
import org.sleuthkit.datamodel.BlackboardArtifact; import org.sleuthkit.datamodel.BlackboardArtifact;
import org.sleuthkit.datamodel.BlackboardAttribute; import org.sleuthkit.datamodel.BlackboardAttribute;
import org.sleuthkit.datamodel.Content; import org.sleuthkit.datamodel.Content;
@ -54,6 +53,7 @@ import com.google.gson.JsonArray;
import java.util.Locale; import java.util.Locale;
import java.util.Map; import java.util.Map;
import javax.swing.SwingUtilities; import javax.swing.SwingUtilities;
import org.sleuthkit.autopsy.coreutils.TimeZoneUtils;
import org.sleuthkit.autopsy.discovery.ui.AbstractArtifactDetailsPanel; import org.sleuthkit.autopsy.discovery.ui.AbstractArtifactDetailsPanel;
//import org.sleuthkit.autopsy.contentviewers.Bundle; //import org.sleuthkit.autopsy.contentviewers.Bundle;
@ -343,7 +343,7 @@ public class DefaultTableArtifactContentViewer extends AbstractArtifactDetailsPa
// Use Autopsy date formatting settings, not TSK defaults // Use Autopsy date formatting settings, not TSK defaults
case DATETIME: case DATETIME:
value = epochTimeToString(attr.getValueLong()); value = TimeZoneUtils.getFormattedTime(attr.getValueLong());
break; break;
case JSON: case JSON:
// Get the attribute's JSON value and convert to indented multiline display string // Get the attribute's JSON value and convert to indented multiline display string
@ -454,7 +454,7 @@ public class DefaultTableArtifactContentViewer extends AbstractArtifactDetailsPa
String attributeName = jsonKey; String attributeName = jsonKey;
String attributeValue; String attributeValue;
if (attributeName.toUpperCase().contains("DATETIME")) { if (attributeName.toUpperCase().contains("DATETIME")) {
attributeValue = epochTimeToString(Long.parseLong(jsonElement.getAsString())); attributeValue = TimeZoneUtils.getFormattedTime(Long.parseLong(jsonElement.getAsString()));
} else { } else {
attributeValue = jsonElement.getAsString(); attributeValue = jsonElement.getAsString();
} }
@ -463,23 +463,6 @@ public class DefaultTableArtifactContentViewer extends AbstractArtifactDetailsPa
sb.append(NEW_LINE).append(String.format("%s%s = null", startIndent, jsonKey)); sb.append(NEW_LINE).append(String.format("%s%s = null", startIndent, jsonKey));
} }
} }
/**
* Converts epoch time to readable string.
*
* @param epochTime epoch time value to be converted to string.
*
* @return String with human readable time.
*/
private String epochTimeToString(long epochTime) {
String dateTimeString = "0000-00-00 00:00:00";
if (null != content && 0 != epochTime) {
dateFormatter.setTimeZone(ContentUtils.getTimeZone(content));
dateTimeString = dateFormatter.format(new java.util.Date(epochTime * 1000));
}
return dateTimeString;
}
} }
/** /**

View File

@ -1,7 +1,7 @@
/* /*
* Autopsy * Autopsy
* *
* Copyright 2020 Basis Technology Corp. * Copyright 2020-2021 Basis Technology Corp.
* Contact: carrier <at> sleuthkit <dot> org * Contact: carrier <at> sleuthkit <dot> org
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
@ -44,11 +44,10 @@ import org.openide.util.NbBundle;
import org.openide.util.lookup.ServiceProvider; import org.openide.util.lookup.ServiceProvider;
import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.autopsy.coreutils.Logger;
import org.sleuthkit.autopsy.coreutils.ThreadConfined; import org.sleuthkit.autopsy.coreutils.ThreadConfined;
import org.sleuthkit.autopsy.datamodel.ContentUtils; import org.sleuthkit.autopsy.coreutils.TimeZoneUtils;
import org.sleuthkit.autopsy.discovery.ui.AbstractArtifactDetailsPanel; import org.sleuthkit.autopsy.discovery.ui.AbstractArtifactDetailsPanel;
import org.sleuthkit.datamodel.BlackboardArtifact; import org.sleuthkit.datamodel.BlackboardArtifact;
import org.sleuthkit.datamodel.BlackboardAttribute; import org.sleuthkit.datamodel.BlackboardAttribute;
import org.sleuthkit.datamodel.TimeUtilities;
import org.sleuthkit.datamodel.TskCoreException; import org.sleuthkit.datamodel.TskCoreException;
/** /**
@ -263,9 +262,9 @@ public class GeneralPurposeArtifactViewer extends AbstractArtifactDetailsPanel i
for (BlackboardAttribute bba : attrList) { for (BlackboardAttribute bba : attrList) {
if (bba.getAttributeType().getTypeName().startsWith("TSK_DATETIME")) { if (bba.getAttributeType().getTypeName().startsWith("TSK_DATETIME")) {
if (artifact.getArtifactTypeID() == BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_SEARCH_QUERY.getTypeID()) { if (artifact.getArtifactTypeID() == BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_SEARCH_QUERY.getTypeID()) {
addNameValueRow(Bundle.GeneralPurposeArtifactViewer_dates_time(), TimeUtilities.epochToTime(bba.getValueLong(), ContentUtils.getTimeZone(artifact))); addNameValueRow(Bundle.GeneralPurposeArtifactViewer_dates_time(), TimeZoneUtils.getFormattedTime(bba.getValueLong()));
} else { } else {
addNameValueRow(bba.getAttributeType().getDisplayName(), TimeUtilities.epochToTime(bba.getValueLong(), ContentUtils.getTimeZone(artifact))); addNameValueRow(bba.getAttributeType().getDisplayName(), TimeZoneUtils.getFormattedTime(bba.getValueLong()));
} }
} else if (bba.getAttributeType().getTypeID() == BlackboardAttribute.ATTRIBUTE_TYPE.TSK_TEXT.getTypeID() && artifact.getArtifactTypeID() == BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_SEARCH_QUERY.getTypeID()) { } else if (bba.getAttributeType().getTypeID() == BlackboardAttribute.ATTRIBUTE_TYPE.TSK_TEXT.getTypeID() && artifact.getArtifactTypeID() == BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_SEARCH_QUERY.getTypeID()) {
addNameValueRow(Bundle.GeneralPurposeArtifactViewer_term_label(), bba.getDisplayString()); addNameValueRow(Bundle.GeneralPurposeArtifactViewer_term_label(), bba.getDisplayString());
@ -293,7 +292,7 @@ public class GeneralPurposeArtifactViewer extends AbstractArtifactDetailsPanel i
for (int key : attributeMap.keySet()) { for (int key : attributeMap.keySet()) {
for (BlackboardAttribute bba : attributeMap.get(key)) { for (BlackboardAttribute bba : attributeMap.get(key)) {
if (bba.getAttributeType().getTypeName().startsWith("TSK_DATETIME")) { if (bba.getAttributeType().getTypeName().startsWith("TSK_DATETIME")) {
addNameValueRow(bba.getAttributeType().getDisplayName(), TimeUtilities.epochToTime(bba.getValueLong(), ContentUtils.getTimeZone(artifact))); addNameValueRow(bba.getAttributeType().getDisplayName(), TimeZoneUtils.getFormattedTime(bba.getValueLong()));
} else { } else {
addNameValueRow(bba.getAttributeType().getDisplayName(), bba.getDisplayString()); addNameValueRow(bba.getAttributeType().getDisplayName(), bba.getDisplayString());
} }

View File

@ -51,6 +51,16 @@ public interface DataContentViewer {
* *
*/ */
public String getTitle(); public String getTitle();
/**
* Returns the title of this viewer to display in the tab.
*
* @param node The node to be viewed in the DataContentViewer.
* @return the title of DataContentViewer.
*/
public default String getTitle(Node node) {
return getTitle();
}
/** /**
* Returns a short description of this viewer to use as a tool tip for its * Returns a short description of this viewer to use as a tool tip for its

View File

@ -23,13 +23,13 @@ INDEX_FOR_LOCAL_HELP=/docs/index.html
LBL_Close=Close LBL_Close=Close
DataContentViewerHex.copyMenuItem.text=Copy DataContentViewerHex.copyMenuItem.text=Copy
DataContentViewerHex.selectAllMenuItem.text=Select All DataContentViewerHex.selectAllMenuItem.text=Select All
DataContentViewerArtifact.totalPageLabel.text=100 DataArtifactContentViewer.totalPageLabel.text=100
DataContentViewerArtifact.prevPageButton.text= DataArtifactContentViewer.prevPageButton.text=
DataContentViewerArtifact.pageLabel2.text=Result DataArtifactContentViewer.pageLabel2.text=Result
DataContentViewerArtifact.nextPageButton.text= DataArtifactContentViewer.nextPageButton.text=
DataContentViewerArtifact.currentPageLabel.text=1 DataArtifactContentViewer.currentPageLabel.text=1
DataContentViewerArtifact.ofLabel.text=of DataArtifactContentViewer.ofLabel.text=of
DataContentViewerArtifact.pageLabel.text=Result: DataArtifactContentViewer.pageLabel.text=Result:
AdvancedConfigurationDialog.applyButton.text=OK AdvancedConfigurationDialog.applyButton.text=OK
DataContentViewerHex.goToPageTextField.text= DataContentViewerHex.goToPageTextField.text=
DataContentViewerHex.goToPageLabel.text=Go to Page: DataContentViewerHex.goToPageLabel.text=Go to Page:
@ -44,10 +44,10 @@ DataResultViewerThumbnail.filePathLabel.text=\ \ \
DataResultViewerThumbnail.goToPageLabel.text=Go to Page: DataResultViewerThumbnail.goToPageLabel.text=Go to Page:
DataResultViewerThumbnail.goToPageField.text= DataResultViewerThumbnail.goToPageField.text=
AdvancedConfigurationDialog.cancelButton.text=Cancel AdvancedConfigurationDialog.cancelButton.text=Cancel
DataContentViewerArtifact.waitText=Retrieving and preparing data, please wait... DataArtifactContentViewer.waitText=Retrieving and preparing data, please wait...
DataContentViewerArtifact.errorText=Error retrieving result DataArtifactContentViewer.errorText=Error retrieving result
DataContentViewerArtifact.title=Results DataArtifactContentViewer.title=Data Artifacts
DataContentViewerArtifact.toolTip=Displays Results associated with the file DataArtifactContentViewer.toolTip=Displays Results associated with the file
DataContentViewerHex.goToPageTextField.msgDlg=Please enter a valid page number between 1 and {0} DataContentViewerHex.goToPageTextField.msgDlg=Please enter a valid page number between 1 and {0}
DataContentViewerHex.goToPageTextField.err=Invalid page number DataContentViewerHex.goToPageTextField.err=Invalid page number
DataContentViewerHex.setDataView.errorText=(offset {0}-{1} could not be read) DataContentViewerHex.setDataView.errorText=(offset {0}-{1} could not be read)

View File

@ -30,8 +30,8 @@ CTL_DataContentAction=DataContent
CTL_DataContentTopComponent=Data Content CTL_DataContentTopComponent=Data Content
CTL_OfflineHelpAction=Offline Autopsy Documentation CTL_OfflineHelpAction=Offline Autopsy Documentation
CTL_OnlineHelpAction=Online Autopsy Documentation CTL_OnlineHelpAction=Online Autopsy Documentation
DataContentViewerArtifact.failedToGetAttributes.message=Failed to get some or all attributes from case database DataArtifactContentViewer.failedToGetAttributes.message=Failed to get some or all attributes from case database
DataContentViewerArtifact.failedToGetSourcePath.message=Failed to get source file path from case database DataArtifactContentViewer.failedToGetSourcePath.message=Failed to get source file path from case database
DataContentViewerHex.copyingFile=Copying file to open in HxD... DataContentViewerHex.copyingFile=Copying file to open in HxD...
DataContentViewerHex.launchError=Unable to launch HxD Editor. Please specify the HxD install location in Tools -> Options -> External Viewer DataContentViewerHex.launchError=Unable to launch HxD Editor. Please specify the HxD install location in Tools -> Options -> External Viewer
DataContentViewerHex_loading_text=Loading hex from file... DataContentViewerHex_loading_text=Loading hex from file...
@ -88,13 +88,13 @@ INDEX_FOR_LOCAL_HELP=/docs/index.html
LBL_Close=Close LBL_Close=Close
DataContentViewerHex.copyMenuItem.text=Copy DataContentViewerHex.copyMenuItem.text=Copy
DataContentViewerHex.selectAllMenuItem.text=Select All DataContentViewerHex.selectAllMenuItem.text=Select All
DataContentViewerArtifact.totalPageLabel.text=100 DataArtifactContentViewer.totalPageLabel.text=100
DataContentViewerArtifact.prevPageButton.text= DataArtifactContentViewer.prevPageButton.text=
DataContentViewerArtifact.pageLabel2.text=Result DataArtifactContentViewer.pageLabel2.text=Result
DataContentViewerArtifact.nextPageButton.text= DataArtifactContentViewer.nextPageButton.text=
DataContentViewerArtifact.currentPageLabel.text=1 DataArtifactContentViewer.currentPageLabel.text=1
DataContentViewerArtifact.ofLabel.text=of DataArtifactContentViewer.ofLabel.text=of
DataContentViewerArtifact.pageLabel.text=Result: DataArtifactContentViewer.pageLabel.text=Result:
AdvancedConfigurationDialog.applyButton.text=OK AdvancedConfigurationDialog.applyButton.text=OK
DataContentViewerHex.goToPageTextField.text= DataContentViewerHex.goToPageTextField.text=
DataContentViewerHex.goToPageLabel.text=Go to Page: DataContentViewerHex.goToPageLabel.text=Go to Page:
@ -109,10 +109,10 @@ DataResultViewerThumbnail.filePathLabel.text=\ \ \
DataResultViewerThumbnail.goToPageLabel.text=Go to Page: DataResultViewerThumbnail.goToPageLabel.text=Go to Page:
DataResultViewerThumbnail.goToPageField.text= DataResultViewerThumbnail.goToPageField.text=
AdvancedConfigurationDialog.cancelButton.text=Cancel AdvancedConfigurationDialog.cancelButton.text=Cancel
DataContentViewerArtifact.waitText=Retrieving and preparing data, please wait... DataArtifactContentViewer.waitText=Retrieving and preparing data, please wait...
DataContentViewerArtifact.errorText=Error retrieving result DataArtifactContentViewer.errorText=Error retrieving result
DataContentViewerArtifact.title=Results DataArtifactContentViewer.title=Data Artifacts
DataContentViewerArtifact.toolTip=Displays Results associated with the file DataArtifactContentViewer.toolTip=Displays Results associated with the file
DataContentViewerHex.goToPageTextField.msgDlg=Please enter a valid page number between 1 and {0} DataContentViewerHex.goToPageTextField.msgDlg=Please enter a valid page number between 1 and {0}
DataContentViewerHex.goToPageTextField.err=Invalid page number DataContentViewerHex.goToPageTextField.err=Invalid page number
DataContentViewerHex.setDataView.errorText=(offset {0}-{1} could not be read) DataContentViewerHex.setDataView.errorText=(offset {0}-{1} could not be read)

View File

@ -59,19 +59,19 @@ CTL_OnlineHelpAction=Autopsy\u30aa\u30f3\u30e9\u30a4\u30f3\u30c9\u30ad\u30e5\u30
CriterionChooser.ascendingRadio.text=\u25b2 \u6607\u9806\n CriterionChooser.ascendingRadio.text=\u25b2 \u6607\u9806\n
CriterionChooser.descendingRadio.text=\u25bc \u964d\u9806 CriterionChooser.descendingRadio.text=\u25bc \u964d\u9806
CriterionChooser.removeButton.text=\u524a\u9664 CriterionChooser.removeButton.text=\u524a\u9664
DataContentViewerArtifact.currentPageLabel.text=1 DataArtifactContentViewer.currentPageLabel.text=1
DataContentViewerArtifact.errorText=\u7d50\u679c\u306e\u691c\u7d22\u4e2d\u306b\u30a8\u30e9\u30fc\u304c\u767a\u751f\u3057\u307e\u3057\u305f DataArtifactContentViewer.errorText=\u7d50\u679c\u306e\u691c\u7d22\u4e2d\u306b\u30a8\u30e9\u30fc\u304c\u767a\u751f\u3057\u307e\u3057\u305f
DataContentViewerArtifact.failedToGetAttributes.message=\u30b1\u30fc\u30b9\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u304b\u3089\u4e00\u90e8\u307e\u305f\u306f\u3059\u3079\u3066\u306e\u5c5e\u6027\u3092\u53d6\u5f97\u3067\u304d\u307e\u305b\u3093\u3067\u3057\u305f DataArtifactContentViewer.failedToGetAttributes.message=\u30b1\u30fc\u30b9\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u304b\u3089\u4e00\u90e8\u307e\u305f\u306f\u3059\u3079\u3066\u306e\u5c5e\u6027\u3092\u53d6\u5f97\u3067\u304d\u307e\u305b\u3093\u3067\u3057\u305f
DataContentViewerArtifact.failedToGetSourcePath.message=\u30b1\u30fc\u30b9\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u304b\u3089\u30bd\u30fc\u30b9\u30d5\u30a1\u30a4\u30eb\u30d1\u30b9\u3092\u53d6\u5f97\u3067\u304d\u307e\u305b\u3093\u3067\u3057\u305f DataArtifactContentViewer.failedToGetSourcePath.message=\u30b1\u30fc\u30b9\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u304b\u3089\u30bd\u30fc\u30b9\u30d5\u30a1\u30a4\u30eb\u30d1\u30b9\u3092\u53d6\u5f97\u3067\u304d\u307e\u305b\u3093\u3067\u3057\u305f
DataContentViewerArtifact.nextPageButton.text= DataArtifactContentViewer.nextPageButton.text=
DataContentViewerArtifact.ofLabel.text=/ DataArtifactContentViewer.ofLabel.text=/
DataContentViewerArtifact.pageLabel.text=\u7d50\u679c\: DataArtifactContentViewer.pageLabel.text=\u7d50\u679c\:
DataContentViewerArtifact.pageLabel2.text=\u7d50\u679c DataArtifactContentViewer.pageLabel2.text=\u7d50\u679c
DataContentViewerArtifact.prevPageButton.text= DataArtifactContentViewer.prevPageButton.text=
DataContentViewerArtifact.title=\u7d50\u679c DataArtifactContentViewer.title=\u7d50\u679c
DataContentViewerArtifact.toolTip=\u30d5\u30a1\u30a4\u30eb\u3068\u95a2\u9023\u4ed8\u3051\u3089\u308c\u3066\u3044\u308b\u7d50\u679c\u3092\u8868\u793a DataArtifactContentViewer.toolTip=\u30d5\u30a1\u30a4\u30eb\u3068\u95a2\u9023\u4ed8\u3051\u3089\u308c\u3066\u3044\u308b\u7d50\u679c\u3092\u8868\u793a
DataContentViewerArtifact.totalPageLabel.text=100 DataArtifactContentViewer.totalPageLabel.text=100
DataContentViewerArtifact.waitText=\u30c7\u30fc\u30bf\u3092\u691c\u7d22\u3057\u3066\u6e96\u5099\u4e2d\u3067\u3059\u3002\u304a\u5f85\u3061\u304f\u3060\u3055\u3044... DataArtifactContentViewer.waitText=\u30c7\u30fc\u30bf\u3092\u691c\u7d22\u3057\u3066\u6e96\u5099\u4e2d\u3067\u3059\u3002\u304a\u5f85\u3061\u304f\u3060\u3055\u3044...
DataContentViewerHex.copyMenuItem.text=\u30b3\u30d4\u30fc DataContentViewerHex.copyMenuItem.text=\u30b3\u30d4\u30fc
DataContentViewerHex.copyingFile=HxD\u3067\u958b\u304f\u30d5\u30a1\u30a4\u30eb\u3092\u30b3\u30d4\u30fc\u4e2d\u3067\u3059... DataContentViewerHex.copyingFile=HxD\u3067\u958b\u304f\u30d5\u30a1\u30a4\u30eb\u3092\u30b3\u30d4\u30fc\u4e2d\u3067\u3059...
DataContentViewerHex.currentPageLabel.text_1=1 DataContentViewerHex.currentPageLabel.text_1=1

View File

@ -2,8 +2,11 @@
<Form version="1.9" maxVersion="1.9" type="org.netbeans.modules.form.forminfo.JPanelFormInfo"> <Form version="1.9" maxVersion="1.9" type="org.netbeans.modules.form.forminfo.JPanelFormInfo">
<Properties> <Properties>
<Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[300, 60]"/>
</Property>
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[100, 58]"/> <Dimension value="[300, 60]"/>
</Property> </Property>
</Properties> </Properties>
<AuxValues> <AuxValues>
@ -21,33 +24,42 @@
<Layout> <Layout>
<DimensionLayout dim="0"> <DimensionLayout dim="0">
<Group type="103" groupAlignment="0" attributes="0"> <Group type="103" groupAlignment="0" attributes="0">
<Component id="jScrollPane1" pref="561" max="32767" attributes="0"/> <Component id="scrollPane" pref="300" max="32767" attributes="0"/>
<Component id="artifactContentPanel" alignment="0" max="32767" attributes="0"/> <Component id="artifactContentPanel" alignment="0" max="32767" attributes="0"/>
</Group> </Group>
</DimensionLayout> </DimensionLayout>
<DimensionLayout dim="1"> <DimensionLayout dim="1">
<Group type="103" groupAlignment="0" attributes="0"> <Group type="103" groupAlignment="0" attributes="0">
<Group type="102" alignment="0" attributes="0"> <Group type="102" alignment="0" attributes="0">
<Component id="jScrollPane1" min="-2" pref="24" max="-2" attributes="0"/> <Component id="scrollPane" min="-2" pref="24" max="-2" attributes="0"/>
<EmptySpace min="-2" max="-2" attributes="0"/> <EmptySpace min="-2" max="-2" attributes="0"/>
<Component id="artifactContentPanel" pref="397" max="32767" attributes="0"/> <Component id="artifactContentPanel" pref="30" max="32767" attributes="0"/>
</Group> </Group>
</Group> </Group>
</DimensionLayout> </DimensionLayout>
</Layout> </Layout>
<SubComponents> <SubComponents>
<Container class="javax.swing.JScrollPane" name="jScrollPane1"> <Container class="javax.swing.JScrollPane" name="scrollPane">
<Properties> <Properties>
<Property name="horizontalScrollBarPolicy" type="int" value="31"/> <Property name="horizontalScrollBarPolicy" type="int" value="31"/>
<Property name="verticalScrollBarPolicy" type="int" value="21"/> <Property name="verticalScrollBarPolicy" type="int" value="21"/>
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[6, 60]"/>
</Property>
</Properties> </Properties>
<Layout class="org.netbeans.modules.form.compat2.layouts.support.JScrollPaneSupportLayout"/> <Layout class="org.netbeans.modules.form.compat2.layouts.support.JScrollPaneSupportLayout"/>
<SubComponents> <SubComponents>
<Container class="javax.swing.JPanel" name="jPanel1"> <Container class="javax.swing.JPanel" name="menuBar">
<Properties> <Properties>
<Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="null"/>
</Property>
<Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="null"/>
</Property>
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[620, 58]"/> <Dimension value="null"/>
</Property> </Property>
</Properties> </Properties>
@ -56,13 +68,13 @@
<Component class="javax.swing.JLabel" name="totalPageLabel"> <Component class="javax.swing.JLabel" name="totalPageLabel">
<Properties> <Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/corecomponents/Bundle.properties" key="DataContentViewerArtifact.totalPageLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/> <ResourceString bundle="org/sleuthkit/autopsy/corecomponents/Bundle.properties" key="DataArtifactContentViewer.totalPageLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property> </Property>
<Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> <Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[40, 16]"/> <Dimension value="null"/>
</Property> </Property>
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[25, 16]"/> <Dimension value="null"/>
</Property> </Property>
</Properties> </Properties>
<Constraints> <Constraints>
@ -74,7 +86,7 @@
<Component class="javax.swing.JLabel" name="ofLabel"> <Component class="javax.swing.JLabel" name="ofLabel">
<Properties> <Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/corecomponents/Bundle.properties" key="DataContentViewerArtifact.ofLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/> <ResourceString bundle="org/sleuthkit/autopsy/corecomponents/Bundle.properties" key="DataArtifactContentViewer.ofLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property> </Property>
</Properties> </Properties>
<Constraints> <Constraints>
@ -86,28 +98,25 @@
<Component class="javax.swing.JLabel" name="currentPageLabel"> <Component class="javax.swing.JLabel" name="currentPageLabel">
<Properties> <Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/corecomponents/Bundle.properties" key="DataContentViewerArtifact.currentPageLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/> <ResourceString bundle="org/sleuthkit/autopsy/corecomponents/Bundle.properties" key="DataArtifactContentViewer.currentPageLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property> </Property>
<Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> <Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[38, 14]"/> <Dimension value="null"/>
</Property>
<Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[18, 14]"/>
</Property> </Property>
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[20, 14]"/> <Dimension value="null"/>
</Property> </Property>
</Properties> </Properties>
<Constraints> <Constraints>
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription"> <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
<GridBagConstraints gridX="1" gridY="0" gridWidth="1" gridHeight="1" fill="2" ipadX="0" ipadY="0" insetsTop="4" insetsLeft="7" insetsBottom="0" insetsRight="0" anchor="18" weightX="0.0" weightY="0.0"/> <GridBagConstraints gridX="1" gridY="0" gridWidth="1" gridHeight="1" fill="2" ipadX="0" ipadY="0" insetsTop="3" insetsLeft="7" insetsBottom="0" insetsRight="0" anchor="18" weightX="0.0" weightY="0.0"/>
</Constraint> </Constraint>
</Constraints> </Constraints>
</Component> </Component>
<Component class="javax.swing.JLabel" name="pageLabel"> <Component class="javax.swing.JLabel" name="pageLabel">
<Properties> <Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/corecomponents/Bundle.properties" key="DataContentViewerArtifact.pageLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/> <ResourceString bundle="org/sleuthkit/autopsy/corecomponents/Bundle.properties" key="DataArtifactContentViewer.pageLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property> </Property>
</Properties> </Properties>
<Constraints> <Constraints>
@ -122,7 +131,7 @@
<Image iconType="3" name="/org/sleuthkit/autopsy/corecomponents/btn_step_forward.png"/> <Image iconType="3" name="/org/sleuthkit/autopsy/corecomponents/btn_step_forward.png"/>
</Property> </Property>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/corecomponents/Bundle.properties" key="DataContentViewerArtifact.nextPageButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/> <ResourceString bundle="org/sleuthkit/autopsy/corecomponents/Bundle.properties" key="DataArtifactContentViewer.nextPageButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property> </Property>
<Property name="borderPainted" type="boolean" value="false"/> <Property name="borderPainted" type="boolean" value="false"/>
<Property name="contentAreaFilled" type="boolean" value="false"/> <Property name="contentAreaFilled" type="boolean" value="false"/>
@ -151,7 +160,7 @@
<Component class="javax.swing.JLabel" name="pageLabel2"> <Component class="javax.swing.JLabel" name="pageLabel2">
<Properties> <Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/corecomponents/Bundle.properties" key="DataContentViewerArtifact.pageLabel2.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/> <ResourceString bundle="org/sleuthkit/autopsy/corecomponents/Bundle.properties" key="DataArtifactContentViewer.pageLabel2.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property> </Property>
<Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> <Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[29, 14]"/> <Dimension value="[29, 14]"/>
@ -162,7 +171,7 @@
</Properties> </Properties>
<Constraints> <Constraints>
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription"> <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
<GridBagConstraints gridX="4" gridY="0" gridWidth="1" gridHeight="1" fill="2" ipadX="0" ipadY="0" insetsTop="3" insetsLeft="41" insetsBottom="0" insetsRight="0" anchor="18" weightX="0.0" weightY="0.0"/> <GridBagConstraints gridX="4" gridY="0" gridWidth="1" gridHeight="1" fill="2" ipadX="0" ipadY="0" insetsTop="3" insetsLeft="30" insetsBottom="0" insetsRight="0" anchor="18" weightX="0.0" weightY="0.0"/>
</Constraint> </Constraint>
</Constraints> </Constraints>
</Component> </Component>
@ -172,7 +181,7 @@
<Image iconType="3" name="/org/sleuthkit/autopsy/corecomponents/btn_step_back.png"/> <Image iconType="3" name="/org/sleuthkit/autopsy/corecomponents/btn_step_back.png"/>
</Property> </Property>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/corecomponents/Bundle.properties" key="DataContentViewerArtifact.prevPageButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/> <ResourceString bundle="org/sleuthkit/autopsy/corecomponents/Bundle.properties" key="DataArtifactContentViewer.prevPageButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property> </Property>
<Property name="borderPainted" type="boolean" value="false"/> <Property name="borderPainted" type="boolean" value="false"/>
<Property name="contentAreaFilled" type="boolean" value="false"/> <Property name="contentAreaFilled" type="boolean" value="false"/>

View File

@ -32,18 +32,22 @@ import org.openide.util.NbBundle;
import org.openide.util.lookup.ServiceProvider; import org.openide.util.lookup.ServiceProvider;
import org.sleuthkit.autopsy.corecomponentinterfaces.DataContentViewer; import org.sleuthkit.autopsy.corecomponentinterfaces.DataContentViewer;
import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.autopsy.coreutils.Logger;
import org.sleuthkit.datamodel.BlackboardArtifact;
import org.sleuthkit.datamodel.BlackboardAttribute; import org.sleuthkit.datamodel.BlackboardAttribute;
import org.sleuthkit.datamodel.Content; import org.sleuthkit.datamodel.Content;
import org.sleuthkit.datamodel.TskCoreException; import org.sleuthkit.datamodel.TskCoreException;
import org.sleuthkit.datamodel.TskException; import org.sleuthkit.datamodel.TskException;
import java.util.Collections; import java.util.Collections;
import java.util.HashSet; import java.util.HashSet;
import org.sleuthkit.autopsy.casemodule.Case;
import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException;
import org.sleuthkit.autopsy.contentviewers.artifactviewers.ArtifactContentViewer; import org.sleuthkit.autopsy.contentviewers.artifactviewers.ArtifactContentViewer;
import org.sleuthkit.autopsy.contentviewers.artifactviewers.DefaultTableArtifactContentViewer; import org.sleuthkit.autopsy.contentviewers.artifactviewers.DefaultTableArtifactContentViewer;
import org.sleuthkit.datamodel.AnalysisResult;
import org.sleuthkit.datamodel.BlackboardArtifact;
import org.sleuthkit.datamodel.DataArtifact;
/** /**
* Instances of this class display the BlackboardArtifacts associated with the * Instances of this class display the DataArtifact associated with the
* Content represented by a Node. * Content represented by a Node.
* *
* It goes through a list of known ArtifactContentViewer to find a viewer that * It goes through a list of known ArtifactContentViewer to find a viewer that
@ -51,17 +55,17 @@ import org.sleuthkit.autopsy.contentviewers.artifactviewers.DefaultTableArtifact
*/ */
@ServiceProvider(service = DataContentViewer.class, position = 7) @ServiceProvider(service = DataContentViewer.class, position = 7)
@SuppressWarnings("PMD.SingularField") // UI widgets cause lots of false positives @SuppressWarnings("PMD.SingularField") // UI widgets cause lots of false positives
public class DataContentViewerArtifact extends javax.swing.JPanel implements DataContentViewer { public class DataArtifactContentViewer extends javax.swing.JPanel implements DataContentViewer {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
@NbBundle.Messages({ @NbBundle.Messages({
"DataContentViewerArtifact.failedToGetSourcePath.message=Failed to get source file path from case database", "DataArtifactContentViewer.failedToGetSourcePath.message=Failed to get source file path from case database",
"DataContentViewerArtifact.failedToGetAttributes.message=Failed to get some or all attributes from case database" "DataArtifactContentViewer.failedToGetAttributes.message=Failed to get some or all attributes from case database"
}) })
private final static Logger logger = Logger.getLogger(DataContentViewerArtifact.class.getName()); private final static Logger logger = Logger.getLogger(DataArtifactContentViewer.class.getName());
private final static String WAIT_TEXT = NbBundle.getMessage(DataContentViewerArtifact.class, "DataContentViewerArtifact.waitText"); private final static String WAIT_TEXT = NbBundle.getMessage(DataArtifactContentViewer.class, "DataArtifactContentViewer.waitText");
private final static String ERROR_TEXT = NbBundle.getMessage(DataContentViewerArtifact.class, "DataContentViewerArtifact.errorText"); private final static String ERROR_TEXT = NbBundle.getMessage(DataArtifactContentViewer.class, "DataArtifactContentViewer.errorText");
// Value to return in isPreferred if this viewer is less preferred. // Value to return in isPreferred if this viewer is less preferred.
private static final int LESS_PREFERRED = 3; private static final int LESS_PREFERRED = 3;
@ -71,12 +75,12 @@ public class DataContentViewerArtifact extends javax.swing.JPanel implements Dat
private Node currentNode; // @@@ Remove this when the redundant setNode() calls problem is fixed. private Node currentNode; // @@@ Remove this when the redundant setNode() calls problem is fixed.
private int currentPage = 1; private int currentPage = 1;
private final Object lock = new Object(); private final Object lock = new Object();
private List<BlackboardArtifact> artifactTableContents; // Accessed by multiple threads, use getArtifactContents() and setArtifactContents() private List<DataArtifact> artifactTableContents; // Accessed by multiple threads, use getArtifactContents() and setArtifactContents()
private SwingWorker<ViewUpdate, Void> currentTask; // Accessed by multiple threads, use startNewTask() private SwingWorker<ViewUpdate, Void> currentTask; // Accessed by multiple threads, use startNewTask()
private final Collection<ArtifactContentViewer> knowArtifactViewers = new HashSet<>(Lookup.getDefault().lookupAll(ArtifactContentViewer.class)); private final Collection<ArtifactContentViewer> knowArtifactViewers = new HashSet<>(Lookup.getDefault().lookupAll(ArtifactContentViewer.class));
public DataContentViewerArtifact() { public DataArtifactContentViewer() {
initComponents(); initComponents();
@ -93,8 +97,8 @@ public class DataContentViewerArtifact extends javax.swing.JPanel implements Dat
private void initComponents() { private void initComponents() {
java.awt.GridBagConstraints gridBagConstraints; java.awt.GridBagConstraints gridBagConstraints;
jScrollPane1 = new javax.swing.JScrollPane(); scrollPane = new javax.swing.JScrollPane();
jPanel1 = new javax.swing.JPanel(); menuBar = new javax.swing.JPanel();
totalPageLabel = new javax.swing.JLabel(); totalPageLabel = new javax.swing.JLabel();
ofLabel = new javax.swing.JLabel(); ofLabel = new javax.swing.JLabel();
currentPageLabel = new javax.swing.JLabel(); currentPageLabel = new javax.swing.JLabel();
@ -106,57 +110,60 @@ public class DataContentViewerArtifact extends javax.swing.JPanel implements Dat
filler1 = new javax.swing.Box.Filler(new java.awt.Dimension(0, 0), new java.awt.Dimension(0, 0), new java.awt.Dimension(32767, 0)); filler1 = new javax.swing.Box.Filler(new java.awt.Dimension(0, 0), new java.awt.Dimension(0, 0), new java.awt.Dimension(32767, 0));
artifactContentPanel = new javax.swing.JPanel(); artifactContentPanel = new javax.swing.JPanel();
setPreferredSize(new java.awt.Dimension(100, 58)); setMinimumSize(new java.awt.Dimension(300, 60));
setPreferredSize(new java.awt.Dimension(300, 60));
jScrollPane1.setHorizontalScrollBarPolicy(javax.swing.ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER); scrollPane.setHorizontalScrollBarPolicy(javax.swing.ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
jScrollPane1.setVerticalScrollBarPolicy(javax.swing.ScrollPaneConstants.VERTICAL_SCROLLBAR_NEVER); scrollPane.setVerticalScrollBarPolicy(javax.swing.ScrollPaneConstants.VERTICAL_SCROLLBAR_NEVER);
scrollPane.setPreferredSize(new java.awt.Dimension(6, 60));
jPanel1.setPreferredSize(new java.awt.Dimension(620, 58)); menuBar.setMaximumSize(null);
jPanel1.setLayout(new java.awt.GridBagLayout()); menuBar.setMinimumSize(null);
menuBar.setPreferredSize(null);
menuBar.setLayout(new java.awt.GridBagLayout());
totalPageLabel.setText(org.openide.util.NbBundle.getMessage(DataContentViewerArtifact.class, "DataContentViewerArtifact.totalPageLabel.text")); // NOI18N totalPageLabel.setText(org.openide.util.NbBundle.getMessage(DataArtifactContentViewer.class, "DataArtifactContentViewer.totalPageLabel.text")); // NOI18N
totalPageLabel.setMaximumSize(new java.awt.Dimension(40, 16)); totalPageLabel.setMaximumSize(null);
totalPageLabel.setPreferredSize(new java.awt.Dimension(25, 16)); totalPageLabel.setPreferredSize(null);
gridBagConstraints = new java.awt.GridBagConstraints(); gridBagConstraints = new java.awt.GridBagConstraints();
gridBagConstraints.gridx = 3; gridBagConstraints.gridx = 3;
gridBagConstraints.gridy = 0; gridBagConstraints.gridy = 0;
gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST; gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
gridBagConstraints.insets = new java.awt.Insets(3, 12, 0, 0); gridBagConstraints.insets = new java.awt.Insets(3, 12, 0, 0);
jPanel1.add(totalPageLabel, gridBagConstraints); menuBar.add(totalPageLabel, gridBagConstraints);
ofLabel.setText(org.openide.util.NbBundle.getMessage(DataContentViewerArtifact.class, "DataContentViewerArtifact.ofLabel.text")); // NOI18N ofLabel.setText(org.openide.util.NbBundle.getMessage(DataArtifactContentViewer.class, "DataArtifactContentViewer.ofLabel.text")); // NOI18N
gridBagConstraints = new java.awt.GridBagConstraints(); gridBagConstraints = new java.awt.GridBagConstraints();
gridBagConstraints.gridx = 2; gridBagConstraints.gridx = 2;
gridBagConstraints.gridy = 0; gridBagConstraints.gridy = 0;
gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST; gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
gridBagConstraints.insets = new java.awt.Insets(3, 12, 0, 0); gridBagConstraints.insets = new java.awt.Insets(3, 12, 0, 0);
jPanel1.add(ofLabel, gridBagConstraints); menuBar.add(ofLabel, gridBagConstraints);
currentPageLabel.setText(org.openide.util.NbBundle.getMessage(DataContentViewerArtifact.class, "DataContentViewerArtifact.currentPageLabel.text")); // NOI18N currentPageLabel.setText(org.openide.util.NbBundle.getMessage(DataArtifactContentViewer.class, "DataArtifactContentViewer.currentPageLabel.text")); // NOI18N
currentPageLabel.setMaximumSize(new java.awt.Dimension(38, 14)); currentPageLabel.setMaximumSize(null);
currentPageLabel.setMinimumSize(new java.awt.Dimension(18, 14)); currentPageLabel.setPreferredSize(null);
currentPageLabel.setPreferredSize(new java.awt.Dimension(20, 14));
gridBagConstraints = new java.awt.GridBagConstraints(); gridBagConstraints = new java.awt.GridBagConstraints();
gridBagConstraints.gridx = 1; gridBagConstraints.gridx = 1;
gridBagConstraints.gridy = 0; gridBagConstraints.gridy = 0;
gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST; gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
gridBagConstraints.insets = new java.awt.Insets(4, 7, 0, 0); gridBagConstraints.insets = new java.awt.Insets(3, 7, 0, 0);
jPanel1.add(currentPageLabel, gridBagConstraints); menuBar.add(currentPageLabel, gridBagConstraints);
pageLabel.setText(org.openide.util.NbBundle.getMessage(DataContentViewerArtifact.class, "DataContentViewerArtifact.pageLabel.text")); // NOI18N pageLabel.setText(org.openide.util.NbBundle.getMessage(DataArtifactContentViewer.class, "DataArtifactContentViewer.pageLabel.text")); // NOI18N
gridBagConstraints = new java.awt.GridBagConstraints(); gridBagConstraints = new java.awt.GridBagConstraints();
gridBagConstraints.gridx = 0; gridBagConstraints.gridx = 0;
gridBagConstraints.gridy = 0; gridBagConstraints.gridy = 0;
gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST; gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
gridBagConstraints.insets = new java.awt.Insets(3, 12, 0, 0); gridBagConstraints.insets = new java.awt.Insets(3, 12, 0, 0);
jPanel1.add(pageLabel, gridBagConstraints); menuBar.add(pageLabel, gridBagConstraints);
nextPageButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/corecomponents/btn_step_forward.png"))); // NOI18N nextPageButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/corecomponents/btn_step_forward.png"))); // NOI18N
nextPageButton.setText(org.openide.util.NbBundle.getMessage(DataContentViewerArtifact.class, "DataContentViewerArtifact.nextPageButton.text")); // NOI18N nextPageButton.setText(org.openide.util.NbBundle.getMessage(DataArtifactContentViewer.class, "DataArtifactContentViewer.nextPageButton.text")); // NOI18N
nextPageButton.setBorderPainted(false); nextPageButton.setBorderPainted(false);
nextPageButton.setContentAreaFilled(false); nextPageButton.setContentAreaFilled(false);
nextPageButton.setDisabledIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/corecomponents/btn_step_forward_disabled.png"))); // NOI18N nextPageButton.setDisabledIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/corecomponents/btn_step_forward_disabled.png"))); // NOI18N
@ -173,9 +180,9 @@ public class DataContentViewerArtifact extends javax.swing.JPanel implements Dat
gridBagConstraints.gridy = 0; gridBagConstraints.gridy = 0;
gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST; gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
gridBagConstraints.insets = new java.awt.Insets(0, 0, 35, 0); gridBagConstraints.insets = new java.awt.Insets(0, 0, 35, 0);
jPanel1.add(nextPageButton, gridBagConstraints); menuBar.add(nextPageButton, gridBagConstraints);
pageLabel2.setText(org.openide.util.NbBundle.getMessage(DataContentViewerArtifact.class, "DataContentViewerArtifact.pageLabel2.text")); // NOI18N pageLabel2.setText(org.openide.util.NbBundle.getMessage(DataArtifactContentViewer.class, "DataArtifactContentViewer.pageLabel2.text")); // NOI18N
pageLabel2.setMaximumSize(new java.awt.Dimension(29, 14)); pageLabel2.setMaximumSize(new java.awt.Dimension(29, 14));
pageLabel2.setMinimumSize(new java.awt.Dimension(29, 14)); pageLabel2.setMinimumSize(new java.awt.Dimension(29, 14));
gridBagConstraints = new java.awt.GridBagConstraints(); gridBagConstraints = new java.awt.GridBagConstraints();
@ -183,11 +190,11 @@ public class DataContentViewerArtifact extends javax.swing.JPanel implements Dat
gridBagConstraints.gridy = 0; gridBagConstraints.gridy = 0;
gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST; gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
gridBagConstraints.insets = new java.awt.Insets(3, 41, 0, 0); gridBagConstraints.insets = new java.awt.Insets(3, 30, 0, 0);
jPanel1.add(pageLabel2, gridBagConstraints); menuBar.add(pageLabel2, gridBagConstraints);
prevPageButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/corecomponents/btn_step_back.png"))); // NOI18N prevPageButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/corecomponents/btn_step_back.png"))); // NOI18N
prevPageButton.setText(org.openide.util.NbBundle.getMessage(DataContentViewerArtifact.class, "DataContentViewerArtifact.prevPageButton.text")); // NOI18N prevPageButton.setText(org.openide.util.NbBundle.getMessage(DataArtifactContentViewer.class, "DataArtifactContentViewer.prevPageButton.text")); // NOI18N
prevPageButton.setBorderPainted(false); prevPageButton.setBorderPainted(false);
prevPageButton.setContentAreaFilled(false); prevPageButton.setContentAreaFilled(false);
prevPageButton.setDisabledIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/corecomponents/btn_step_back_disabled.png"))); // NOI18N prevPageButton.setDisabledIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/corecomponents/btn_step_back_disabled.png"))); // NOI18N
@ -204,22 +211,22 @@ public class DataContentViewerArtifact extends javax.swing.JPanel implements Dat
gridBagConstraints.gridy = 0; gridBagConstraints.gridy = 0;
gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST; gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
gridBagConstraints.insets = new java.awt.Insets(0, 5, 35, 0); gridBagConstraints.insets = new java.awt.Insets(0, 5, 35, 0);
jPanel1.add(prevPageButton, gridBagConstraints); menuBar.add(prevPageButton, gridBagConstraints);
gridBagConstraints = new java.awt.GridBagConstraints(); gridBagConstraints = new java.awt.GridBagConstraints();
gridBagConstraints.gridx = 8; gridBagConstraints.gridx = 8;
gridBagConstraints.gridy = 0; gridBagConstraints.gridy = 0;
gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHEAST; gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHEAST;
gridBagConstraints.insets = new java.awt.Insets(3, 0, 0, 8); gridBagConstraints.insets = new java.awt.Insets(3, 0, 0, 8);
jPanel1.add(artifactLabel, gridBagConstraints); menuBar.add(artifactLabel, gridBagConstraints);
gridBagConstraints = new java.awt.GridBagConstraints(); gridBagConstraints = new java.awt.GridBagConstraints();
gridBagConstraints.gridx = 7; gridBagConstraints.gridx = 7;
gridBagConstraints.gridy = 0; gridBagConstraints.gridy = 0;
gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
gridBagConstraints.weightx = 0.1; gridBagConstraints.weightx = 0.1;
jPanel1.add(filler1, gridBagConstraints); menuBar.add(filler1, gridBagConstraints);
jScrollPane1.setViewportView(jPanel1); scrollPane.setViewportView(menuBar);
artifactContentPanel.setLayout(new javax.swing.OverlayLayout(artifactContentPanel)); artifactContentPanel.setLayout(new javax.swing.OverlayLayout(artifactContentPanel));
@ -227,15 +234,15 @@ public class DataContentViewerArtifact extends javax.swing.JPanel implements Dat
this.setLayout(layout); this.setLayout(layout);
layout.setHorizontalGroup( layout.setHorizontalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 561, Short.MAX_VALUE) .addComponent(scrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, 300, Short.MAX_VALUE)
.addComponent(artifactContentPanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addComponent(artifactContentPanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
); );
layout.setVerticalGroup( layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup() .addGroup(layout.createSequentialGroup()
.addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 24, javax.swing.GroupLayout.PREFERRED_SIZE) .addComponent(scrollPane, javax.swing.GroupLayout.PREFERRED_SIZE, 24, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(artifactContentPanel, javax.swing.GroupLayout.DEFAULT_SIZE, 397, Short.MAX_VALUE)) .addComponent(artifactContentPanel, javax.swing.GroupLayout.DEFAULT_SIZE, 30, Short.MAX_VALUE))
); );
}// </editor-fold>//GEN-END:initComponents }// </editor-fold>//GEN-END:initComponents
@ -258,13 +265,13 @@ public class DataContentViewerArtifact extends javax.swing.JPanel implements Dat
private javax.swing.JLabel artifactLabel; private javax.swing.JLabel artifactLabel;
private javax.swing.JLabel currentPageLabel; private javax.swing.JLabel currentPageLabel;
private javax.swing.Box.Filler filler1; private javax.swing.Box.Filler filler1;
private javax.swing.JPanel jPanel1; private javax.swing.JPanel menuBar;
private javax.swing.JScrollPane jScrollPane1;
private javax.swing.JButton nextPageButton; private javax.swing.JButton nextPageButton;
private javax.swing.JLabel ofLabel; private javax.swing.JLabel ofLabel;
private javax.swing.JLabel pageLabel; private javax.swing.JLabel pageLabel;
private javax.swing.JLabel pageLabel2; private javax.swing.JLabel pageLabel2;
private javax.swing.JButton prevPageButton; private javax.swing.JButton prevPageButton;
private javax.swing.JScrollPane scrollPane;
private javax.swing.JLabel totalPageLabel; private javax.swing.JLabel totalPageLabel;
// End of variables declaration//GEN-END:variables // End of variables declaration//GEN-END:variables
@ -308,17 +315,17 @@ public class DataContentViewerArtifact extends javax.swing.JPanel implements Dat
@Override @Override
public String getTitle() { public String getTitle() {
return NbBundle.getMessage(this.getClass(), "DataContentViewerArtifact.title"); return NbBundle.getMessage(this.getClass(), "DataArtifactContentViewer.title");
} }
@Override @Override
public String getToolTip() { public String getToolTip() {
return NbBundle.getMessage(this.getClass(), "DataContentViewerArtifact.toolTip"); return NbBundle.getMessage(this.getClass(), "DataArtifactContentViewer.toolTip");
} }
@Override @Override
public DataContentViewer createInstance() { public DataContentViewer createInstance() {
return new DataContentViewerArtifact(); return new DataArtifactContentViewer();
} }
@Override @Override
@ -338,21 +345,22 @@ public class DataContentViewerArtifact extends javax.swing.JPanel implements Dat
} }
for (Content content : node.getLookup().lookupAll(Content.class)) { for (Content content : node.getLookup().lookupAll(Content.class)) {
if ((content != null) && (!(content instanceof BlackboardArtifact))) { if ((content != null) && (!(content instanceof DataArtifact)) && (!(content instanceof AnalysisResult))) {
try { try {
return content.getAllArtifactsCount() > 0; return Case.getCurrentCaseThrows().getSleuthkitCase().getBlackboard().hasDataArtifacts(content.getId());
} catch (TskException ex) { } catch (NoCurrentCaseException | TskException ex) {
logger.log(Level.SEVERE, "Couldn't get count of BlackboardArtifacts for content", ex); //NON-NLS logger.log(Level.SEVERE, "Couldn't get count of DataArtifacts for content", ex); //NON-NLS
} }
} }
} }
return false; return false;
} }
@Override @Override
public int isPreferred(Node node) { public int isPreferred(Node node) {
// get the artifact from the lookup // get the artifact from the lookup
BlackboardArtifact artifact = node.getLookup().lookup(BlackboardArtifact.class); DataArtifact artifact = node.getLookup().lookup(DataArtifact.class);
if (artifact == null) { if (artifact == null) {
return LESS_PREFERRED; return LESS_PREFERRED;
} }
@ -386,7 +394,7 @@ public class DataContentViewerArtifact extends javax.swing.JPanel implements Dat
} }
} }
private ArtifactContentViewer getSupportingViewer(BlackboardArtifact artifact) { private ArtifactContentViewer getSupportingViewer(DataArtifact artifact) {
for (ArtifactContentViewer viewer : knowArtifactViewers) { for (ArtifactContentViewer viewer : knowArtifactViewers) {
if (viewer.isSupported(artifact)) { if (viewer.isSupported(artifact)) {
return viewer; return viewer;
@ -403,10 +411,10 @@ public class DataContentViewerArtifact extends javax.swing.JPanel implements Dat
int numberOfPages; int numberOfPages;
int currentPage; int currentPage;
BlackboardArtifact artifact; DataArtifact artifact;
String errorMsg; String errorMsg;
ViewUpdate(int numberOfPages, int currentPage, BlackboardArtifact artifact) { ViewUpdate(int numberOfPages, int currentPage, DataArtifact artifact) {
this.currentPage = currentPage; this.currentPage = currentPage;
this.numberOfPages = numberOfPages; this.numberOfPages = numberOfPages;
this.artifact = artifact; this.artifact = artifact;
@ -442,7 +450,7 @@ public class DataContentViewerArtifact extends javax.swing.JPanel implements Dat
if (viewUpdate.artifact != null) { if (viewUpdate.artifact != null) {
artifactLabel.setText(viewUpdate.artifact.getDisplayName()); artifactLabel.setText(viewUpdate.artifact.getDisplayName());
BlackboardArtifact artifact = viewUpdate.artifact; DataArtifact artifact = viewUpdate.artifact;
ArtifactContentViewer viewer = this.getSupportingViewer(artifact); ArtifactContentViewer viewer = this.getSupportingViewer(artifact);
viewer.setArtifact(artifact); viewer.setArtifact(artifact);
@ -484,7 +492,7 @@ public class DataContentViewerArtifact extends javax.swing.JPanel implements Dat
* @param artifactList A list of ResultsTableArtifact representations of * @param artifactList A list of ResultsTableArtifact representations of
* artifacts. * artifacts.
*/ */
private void setArtifactContents(List<BlackboardArtifact> artifactList) { private void setArtifactContents(List<DataArtifact> artifactList) {
synchronized (lock) { synchronized (lock) {
this.artifactTableContents = artifactList; this.artifactTableContents = artifactList;
} }
@ -495,11 +503,22 @@ public class DataContentViewerArtifact extends javax.swing.JPanel implements Dat
* *
* @return A list of artifacts. * @return A list of artifacts.
*/ */
private List<BlackboardArtifact> getArtifactContents() { private List<DataArtifact> getArtifactContents() {
synchronized (lock) { synchronized (lock) {
return Collections.unmodifiableList(artifactTableContents); return Collections.unmodifiableList(artifactTableContents);
} }
} }
/**
* Metric for determining if content is parent source content.
* @param content The content.
* @return True if this content should be used for source content.
*/
private static boolean isSourceContent(Content content) {
return (content != null) &&
(!(content instanceof DataArtifact)) &&
(!(content instanceof AnalysisResult));
}
/** /**
* Instances of this class use a background thread to generate a ViewUpdate * Instances of this class use a background thread to generate a ViewUpdate
@ -520,20 +539,18 @@ public class DataContentViewerArtifact extends javax.swing.JPanel implements Dat
// blackboard artifact, if any. // blackboard artifact, if any.
Lookup lookup = selectedNode.getLookup(); Lookup lookup = selectedNode.getLookup();
// Get the content. We may get BlackboardArtifacts, ignore those here. // Get the content. We may get DataArtifacts, ignore those here.
ArrayList<BlackboardArtifact> artifacts = new ArrayList<>(); List<DataArtifact> artifacts = Collections.emptyList();
Collection<? extends Content> contents = lookup.lookupAll(Content.class); Collection<? extends Content> contents = lookup.lookupAll(Content.class);
if (contents.isEmpty()) { if (contents.isEmpty()) {
return new ViewUpdate(getArtifactContents().size(), currentPage, ERROR_TEXT); return new ViewUpdate(getArtifactContents().size(), currentPage, ERROR_TEXT);
} }
Content underlyingContent = null;
for (Content content : contents) { for (Content content : contents) {
if ((content != null) && (!(content instanceof BlackboardArtifact))) { if (isSourceContent(content)) {
// Get all of the blackboard artifacts associated with the content. These are what this // Get all of the blackboard artifacts associated with the content. These are what this
// viewer displays. // viewer displays.
try { try {
artifacts = content.getAllArtifacts(); artifacts = content.getAllDataArtifacts();
underlyingContent = content;
break; break;
} catch (TskException ex) { } catch (TskException ex) {
logger.log(Level.SEVERE, "Couldn't get artifacts", ex); //NON-NLS logger.log(Level.SEVERE, "Couldn't get artifacts", ex); //NON-NLS
@ -547,15 +564,15 @@ public class DataContentViewerArtifact extends javax.swing.JPanel implements Dat
} }
// Build the new artifact contents cache. // Build the new artifact contents cache.
ArrayList<BlackboardArtifact> artifactContents = new ArrayList<>(); ArrayList<DataArtifact> artifactContents = new ArrayList<>();
for (BlackboardArtifact artifact : artifacts) { for (DataArtifact artifact : artifacts) {
artifactContents.add(artifact); artifactContents.add(artifact);
} }
// If the node has an underlying blackboard artifact, show it. If not, // If the node has an underlying data artifact, show it. If not,
// show the first artifact. // show the first artifact.
int index = 0; int index = 0;
BlackboardArtifact artifact = lookup.lookup(BlackboardArtifact.class); DataArtifact artifact = lookup.lookup(DataArtifact.class);
if (artifact != null) { if (artifact != null) {
index = artifacts.indexOf(artifact); index = artifacts.indexOf(artifact);
if (index == -1) { if (index == -1) {
@ -567,7 +584,7 @@ public class DataContentViewerArtifact extends javax.swing.JPanel implements Dat
if (attr.getAttributeType().getTypeID() == BlackboardAttribute.ATTRIBUTE_TYPE.TSK_ASSOCIATED_ARTIFACT.getTypeID()) { if (attr.getAttributeType().getTypeID() == BlackboardAttribute.ATTRIBUTE_TYPE.TSK_ASSOCIATED_ARTIFACT.getTypeID()) {
long assocArtifactId = attr.getValueLong(); long assocArtifactId = attr.getValueLong();
int assocArtifactIndex = -1; int assocArtifactIndex = -1;
for (BlackboardArtifact art : artifacts) { for (DataArtifact art : artifacts) {
if (assocArtifactId == art.getArtifactID()) { if (assocArtifactId == art.getArtifactID()) {
assocArtifactIndex = artifacts.indexOf(art); assocArtifactIndex = artifacts.indexOf(art);
break; break;
@ -636,14 +653,14 @@ public class DataContentViewerArtifact extends javax.swing.JPanel implements Dat
protected ViewUpdate doInBackground() { protected ViewUpdate doInBackground() {
// Get the artifact content to display from the cache. Note that one must be subtracted from the // Get the artifact content to display from the cache. Note that one must be subtracted from the
// page index to get the corresponding artifact content index. // page index to get the corresponding artifact content index.
List<BlackboardArtifact> artifactContents = getArtifactContents(); List<DataArtifact> artifactContents = getArtifactContents();
// It may take a considerable amount of time to fetch the attributes of the selected artifact so check for cancellation. // It may take a considerable amount of time to fetch the attributes of the selected artifact so check for cancellation.
if (isCancelled()) { if (isCancelled()) {
return null; return null;
} }
BlackboardArtifact artifactContent = artifactContents.get(pageIndex - 1); DataArtifact artifactContent = artifactContents.get(pageIndex - 1);
return new ViewUpdate(artifactContents.size(), pageIndex, artifactContent); return new ViewUpdate(artifactContents.size(), pageIndex, artifactContent);
} }

View File

@ -145,6 +145,12 @@ public class DataContentPanel extends javax.swing.JPanel implements DataContent,
// Reset everything // Reset everything
for (int index = 0; index < jTabbedPane1.getTabCount(); index++) { for (int index = 0; index < jTabbedPane1.getTabCount(); index++) {
jTabbedPane1.setEnabledAt(index, false); jTabbedPane1.setEnabledAt(index, false);
String tabTitle = viewers.get(index).getTitle(selectedNode);
tabTitle = tabTitle == null ? "" : tabTitle;
if (!tabTitle.equals(jTabbedPane1.getTitleAt(index))) {
jTabbedPane1.setTitleAt(index, tabTitle);
}
viewers.get(index).resetComponent(); viewers.get(index).resetComponent();
} }
@ -245,6 +251,10 @@ public class DataContentPanel extends javax.swing.JPanel implements DataContent,
int isPreferred(Node node) { int isPreferred(Node node) {
return this.wrapped.isPreferred(node); return this.wrapped.isPreferred(node);
} }
String getTitle(Node node) {
return this.wrapped.getTitle(node);
}
} }
/** /**

View File

@ -1,7 +1,7 @@
/* /*
* Autopsy Forensic Browser * Autopsy Forensic Browser
* *
* Copyright 2011-2018 Basis Technology Corp. * Copyright 2011-2021 Basis Technology Corp.
* Contact: carrier <at> sleuthkit <dot> org * Contact: carrier <at> sleuthkit <dot> org
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
@ -27,6 +27,8 @@ import java.util.GregorianCalendar;
import java.util.List; import java.util.List;
import java.util.SimpleTimeZone; import java.util.SimpleTimeZone;
import java.util.TimeZone; import java.util.TimeZone;
import org.sleuthkit.autopsy.core.UserPreferences;
import org.sleuthkit.datamodel.TimeUtilities;
/** /**
* Utility methods for workig with time zones. * Utility methods for workig with time zones.
@ -52,7 +54,7 @@ public class TimeZoneUtils {
DateFormat dfm = new SimpleDateFormat("z"); DateFormat dfm = new SimpleDateFormat("z");
dfm.setTimeZone(zone); dfm.setTimeZone(zone);
boolean hasDaylight = zone.useDaylightTime(); boolean hasDaylight = zone.useDaylightTime();
String first = dfm.format(new GregorianCalendar(2010, 1, 1).getTime()).substring(0, 3); String first = dfm.format(new GregorianCalendar(2010, 1, 1).getTime()).substring(0, 3);
String second = dfm.format(new GregorianCalendar(2011, 6, 6).getTime()).substring(0, 3); String second = dfm.format(new GregorianCalendar(2011, 6, 6).getTime()).substring(0, 3);
int mid = hour * -1; int mid = hour * -1;
String result = first + Integer.toString(mid); String result = first + Integer.toString(mid);
@ -65,19 +67,19 @@ public class TimeZoneUtils {
return result; return result;
} }
/** /**
* Generate a time zone string containing the GMT offset and ID. * Generate a time zone string containing the GMT offset and ID.
* *
* @param timeZone The time zone. * @param timeZone The time zone.
* *
* @return The time zone string. * @return The time zone string.
*/ */
public static String createTimeZoneString(TimeZone timeZone) { public static String createTimeZoneString(TimeZone timeZone) {
int offset = timeZone.getRawOffset() / 1000; int offset = timeZone.getRawOffset() / 1000;
int hour = offset / 3600; int hour = offset / 3600;
int minutes = Math.abs((offset % 3600) / 60); int minutes = Math.abs((offset % 3600) / 60);
return String.format("(GMT%+d:%02d) %s", hour, minutes, timeZone.getID()); //NON-NLS return String.format("(GMT%+d:%02d) %s", hour, minutes, timeZone.getID()); //NON-NLS
} }
@ -89,7 +91,7 @@ public class TimeZoneUtils {
* Create a list of time zones. * Create a list of time zones.
*/ */
List<TimeZone> timeZoneList = new ArrayList<>(); List<TimeZone> timeZoneList = new ArrayList<>();
String[] ids = SimpleTimeZone.getAvailableIDs(); String[] ids = SimpleTimeZone.getAvailableIDs();
for (String id : ids) { for (String id : ids) {
/* /*
@ -103,36 +105,72 @@ public class TimeZoneUtils {
*/ */
timeZoneList.add(TimeZone.getTimeZone(id)); timeZoneList.add(TimeZone.getTimeZone(id));
} }
/* /*
* Sort the list of time zones first by offset, then by ID. * Sort the list of time zones first by offset, then by ID.
*/ */
Collections.sort(timeZoneList, new Comparator<TimeZone>(){ Collections.sort(timeZoneList, new Comparator<TimeZone>() {
@Override @Override
public int compare(TimeZone o1, TimeZone o2){ public int compare(TimeZone o1, TimeZone o2) {
int offsetDelta = Integer.compare(o1.getRawOffset(), o2.getRawOffset()); int offsetDelta = Integer.compare(o1.getRawOffset(), o2.getRawOffset());
if (offsetDelta == 0) { if (offsetDelta == 0) {
return o1.getID().compareToIgnoreCase(o2.getID()); return o1.getID().compareToIgnoreCase(o2.getID());
} }
return offsetDelta; return offsetDelta;
} }
}); });
/* /*
* Create a list of Strings encompassing both the GMT offset and the * Create a list of Strings encompassing both the GMT offset and the
* time zone ID. * time zone ID.
*/ */
List<String> outputList = new ArrayList<>(); List<String> outputList = new ArrayList<>();
for (TimeZone timeZone : timeZoneList) { for (TimeZone timeZone : timeZoneList) {
outputList.add(createTimeZoneString(timeZone)); outputList.add(createTimeZoneString(timeZone));
} }
return outputList; return outputList;
} }
/**
* Returns the time formatted in the user selected time zone.
*
* @param epochTime
*
* @return
*/
public static String getFormattedTime(long epochTime) {
return TimeUtilities.epochToTime(epochTime, getTimeZone());
}
/**
* Returns the formatted time in the user selected time zone in ISO8601
* format.
*
* @param epochTime Seconds from java epoch
*
* @return Formatted date time string in ISO8601
*/
public static String getFormattedTimeISO8601(long epochTime) {
return TimeUtilities.epochToTimeISO8601(epochTime, getTimeZone());
}
/**
* Returns the user preferred timezone.
*
* @return TimeZone to use when formatting time values.
*/
public static TimeZone getTimeZone() {
if (UserPreferences.displayTimesInLocalTime()) {
return TimeZone.getDefault();
}
return TimeZone.getTimeZone(UserPreferences.getTimeZoneForDisplays());
}
/** /**
* Prevents instantiation. * Prevents instantiation.
*/ */

View File

@ -1,7 +1,7 @@
/* /*
* Autopsy Forensic Browser * Autopsy Forensic Browser
* *
* Copyright 2012-2020 Basis Technology Corp. * Copyright 2012-2021 Basis Technology Corp.
* Contact: carrier <at> sleuthkit <dot> org * Contact: carrier <at> sleuthkit <dot> org
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
@ -63,6 +63,7 @@ import org.sleuthkit.datamodel.ContentTag;
import org.sleuthkit.datamodel.Tag; import org.sleuthkit.datamodel.Tag;
import org.sleuthkit.datamodel.TskCoreException; import org.sleuthkit.datamodel.TskCoreException;
import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepository; import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepository;
import org.sleuthkit.autopsy.coreutils.TimeZoneUtils;
import org.sleuthkit.autopsy.texttranslation.utils.FileNameTranslationUtil; import org.sleuthkit.autopsy.texttranslation.utils.FileNameTranslationUtil;
import org.sleuthkit.datamodel.Score; import org.sleuthkit.datamodel.Score;
@ -348,10 +349,10 @@ public abstract class AbstractAbstractFileNode<T extends AbstractFile> extends A
new WeakReference<>(this), weakPcl)); new WeakReference<>(this), weakPcl));
} }
properties.add(new NodeProperty<>(MOD_TIME.toString(), MOD_TIME.toString(), NO_DESCR, ContentUtils.getStringTime(content.getMtime(), content))); properties.add(new NodeProperty<>(MOD_TIME.toString(), MOD_TIME.toString(), NO_DESCR, TimeZoneUtils.getFormattedTime(content.getMtime())));
properties.add(new NodeProperty<>(CHANGED_TIME.toString(), CHANGED_TIME.toString(), NO_DESCR, ContentUtils.getStringTime(content.getCtime(), content))); properties.add(new NodeProperty<>(CHANGED_TIME.toString(), CHANGED_TIME.toString(), NO_DESCR, TimeZoneUtils.getFormattedTime(content.getCtime())));
properties.add(new NodeProperty<>(ACCESS_TIME.toString(), ACCESS_TIME.toString(), NO_DESCR, ContentUtils.getStringTime(content.getAtime(), content))); properties.add(new NodeProperty<>(ACCESS_TIME.toString(), ACCESS_TIME.toString(), NO_DESCR, TimeZoneUtils.getFormattedTime(content.getAtime())));
properties.add(new NodeProperty<>(CREATED_TIME.toString(), CREATED_TIME.toString(), NO_DESCR, ContentUtils.getStringTime(content.getCrtime(), content))); properties.add(new NodeProperty<>(CREATED_TIME.toString(), CREATED_TIME.toString(), NO_DESCR, TimeZoneUtils.getFormattedTime(content.getCrtime())));
properties.add(new NodeProperty<>(SIZE.toString(), SIZE.toString(), NO_DESCR, content.getSize())); properties.add(new NodeProperty<>(SIZE.toString(), SIZE.toString(), NO_DESCR, content.getSize()));
properties.add(new NodeProperty<>(FLAGS_DIR.toString(), FLAGS_DIR.toString(), NO_DESCR, content.getDirFlagAsString())); properties.add(new NodeProperty<>(FLAGS_DIR.toString(), FLAGS_DIR.toString(), NO_DESCR, content.getDirFlagAsString()));
properties.add(new NodeProperty<>(FLAGS_META.toString(), FLAGS_META.toString(), NO_DESCR, content.getMetaFlagsAsString())); properties.add(new NodeProperty<>(FLAGS_META.toString(), FLAGS_META.toString(), NO_DESCR, content.getMetaFlagsAsString()));
@ -532,10 +533,10 @@ public abstract class AbstractAbstractFileNode<T extends AbstractFile> extends A
static public void fillPropertyMap(Map<String, Object> map, AbstractFile content) { static public void fillPropertyMap(Map<String, Object> map, AbstractFile content) {
map.put(NAME.toString(), getContentDisplayName(content)); map.put(NAME.toString(), getContentDisplayName(content));
map.put(LOCATION.toString(), getContentPath(content)); map.put(LOCATION.toString(), getContentPath(content));
map.put(MOD_TIME.toString(), ContentUtils.getStringTime(content.getMtime(), content)); map.put(MOD_TIME.toString(), TimeZoneUtils.getFormattedTime(content.getMtime()));
map.put(CHANGED_TIME.toString(), ContentUtils.getStringTime(content.getCtime(), content)); map.put(CHANGED_TIME.toString(), TimeZoneUtils.getFormattedTime(content.getCtime()));
map.put(ACCESS_TIME.toString(), ContentUtils.getStringTime(content.getAtime(), content)); map.put(ACCESS_TIME.toString(), TimeZoneUtils.getFormattedTime(content.getAtime()));
map.put(CREATED_TIME.toString(), ContentUtils.getStringTime(content.getCrtime(), content)); map.put(CREATED_TIME.toString(), TimeZoneUtils.getFormattedTime(content.getCrtime()));
map.put(SIZE.toString(), content.getSize()); map.put(SIZE.toString(), content.getSize());
map.put(FLAGS_DIR.toString(), content.getDirFlagAsString()); map.put(FLAGS_DIR.toString(), content.getDirFlagAsString());
map.put(FLAGS_META.toString(), content.getMetaFlagsAsString()); map.put(FLAGS_META.toString(), content.getMetaFlagsAsString());

View File

@ -1,7 +1,7 @@
/* /*
* Autopsy Forensic Browser * Autopsy Forensic Browser
* *
* Copyright 2011-2017 Basis Technology Corp. * Copyright 2011-2021 Basis Technology Corp.
* Contact: carrier <at> sleuthkit <dot> org * Contact: carrier <at> sleuthkit <dot> org
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
@ -18,12 +18,12 @@
*/ */
package org.sleuthkit.autopsy.datamodel; package org.sleuthkit.autopsy.datamodel;
import java.text.SimpleDateFormat;
import java.util.logging.Level; import java.util.logging.Level;
import org.apache.commons.lang.StringUtils; import org.apache.commons.lang.StringUtils;
import org.openide.util.NbBundle; import org.openide.util.NbBundle;
import org.openide.util.NbBundle.Messages; import org.openide.util.NbBundle.Messages;
import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.autopsy.coreutils.Logger;
import org.sleuthkit.autopsy.coreutils.TimeZoneUtils;
import org.sleuthkit.datamodel.BlackboardArtifact; import org.sleuthkit.datamodel.BlackboardArtifact;
import org.sleuthkit.datamodel.BlackboardAttribute; import org.sleuthkit.datamodel.BlackboardAttribute;
import org.sleuthkit.datamodel.Content; import org.sleuthkit.datamodel.Content;
@ -39,8 +39,7 @@ import org.sleuthkit.datamodel.TskCoreException;
*/ */
@Deprecated @Deprecated
public class ArtifactStringContent implements StringContent { public class ArtifactStringContent implements StringContent {
private final static SimpleDateFormat dateFormatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
private final static Logger logger = Logger.getLogger(ArtifactStringContent.class.getName()); private final static Logger logger = Logger.getLogger(ArtifactStringContent.class.getName());
private final BlackboardArtifact artifact; private final BlackboardArtifact artifact;
private String stringContent = ""; private String stringContent = "";
@ -130,11 +129,7 @@ public class ArtifactStringContent implements StringContent {
// Use Autopsy date formatting settings, not TSK defaults // Use Autopsy date formatting settings, not TSK defaults
case DATETIME: case DATETIME:
long epoch = attr.getValueLong(); long epoch = attr.getValueLong();
value = "0000-00-00 00:00:00"; value = TimeZoneUtils.getFormattedTime(epoch * 1000);
if (null != content && 0 != epoch) {
dateFormatter.setTimeZone(ContentUtils.getTimeZone(content));
value = dateFormatter.format(new java.util.Date(epoch * 1000));
}
break; break;
} }

View File

@ -1,7 +1,7 @@
/* /*
* Autopsy Forensic Browser * Autopsy Forensic Browser
* *
* Copyright 2012-2020 Basis Technology Corp. * Copyright 2012-2021 Basis Technology Corp.
* Contact: carrier <at> sleuthkit <dot> org * Contact: carrier <at> sleuthkit <dot> org
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
@ -75,6 +75,7 @@ import org.sleuthkit.datamodel.Tag;
import org.sleuthkit.datamodel.TskCoreException; import org.sleuthkit.datamodel.TskCoreException;
import org.sleuthkit.autopsy.datamodel.utils.IconsUtil; import org.sleuthkit.autopsy.datamodel.utils.IconsUtil;
import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepository; import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepository;
import org.sleuthkit.autopsy.coreutils.TimeZoneUtils;
import static org.sleuthkit.autopsy.datamodel.AbstractContentNode.NO_DESCR; import static org.sleuthkit.autopsy.datamodel.AbstractContentNode.NO_DESCR;
import org.sleuthkit.autopsy.texttranslation.TextTranslationService; import org.sleuthkit.autopsy.texttranslation.TextTranslationService;
import org.sleuthkit.autopsy.datamodel.utils.FileNameTransTask; import org.sleuthkit.autopsy.datamodel.utils.FileNameTransTask;
@ -678,22 +679,22 @@ public class BlackboardArtifactNode extends AbstractContentNode<BlackboardArtifa
NbBundle.getMessage(BlackboardArtifactNode.class, "ContentTagNode.createSheet.fileModifiedTime.name"), NbBundle.getMessage(BlackboardArtifactNode.class, "ContentTagNode.createSheet.fileModifiedTime.name"),
NbBundle.getMessage(BlackboardArtifactNode.class, "ContentTagNode.createSheet.fileModifiedTime.displayName"), NbBundle.getMessage(BlackboardArtifactNode.class, "ContentTagNode.createSheet.fileModifiedTime.displayName"),
"", "",
file == null ? "" : ContentUtils.getStringTime(file.getMtime(), file))); file == null ? "" : TimeZoneUtils.getFormattedTime(file.getMtime())));
sheetSet.put(new NodeProperty<>( sheetSet.put(new NodeProperty<>(
NbBundle.getMessage(BlackboardArtifactNode.class, "ContentTagNode.createSheet.fileChangedTime.name"), NbBundle.getMessage(BlackboardArtifactNode.class, "ContentTagNode.createSheet.fileChangedTime.name"),
NbBundle.getMessage(BlackboardArtifactNode.class, "ContentTagNode.createSheet.fileChangedTime.displayName"), NbBundle.getMessage(BlackboardArtifactNode.class, "ContentTagNode.createSheet.fileChangedTime.displayName"),
"", "",
file == null ? "" : ContentUtils.getStringTime(file.getCtime(), file))); file == null ? "" : TimeZoneUtils.getFormattedTime(file.getCtime())));
sheetSet.put(new NodeProperty<>( sheetSet.put(new NodeProperty<>(
NbBundle.getMessage(BlackboardArtifactNode.class, "ContentTagNode.createSheet.fileAccessedTime.name"), NbBundle.getMessage(BlackboardArtifactNode.class, "ContentTagNode.createSheet.fileAccessedTime.name"),
NbBundle.getMessage(BlackboardArtifactNode.class, "ContentTagNode.createSheet.fileAccessedTime.displayName"), NbBundle.getMessage(BlackboardArtifactNode.class, "ContentTagNode.createSheet.fileAccessedTime.displayName"),
"", "",
file == null ? "" : ContentUtils.getStringTime(file.getAtime(), file))); file == null ? "" : TimeZoneUtils.getFormattedTime(file.getAtime())));
sheetSet.put(new NodeProperty<>( sheetSet.put(new NodeProperty<>(
NbBundle.getMessage(BlackboardArtifactNode.class, "ContentTagNode.createSheet.fileCreatedTime.name"), NbBundle.getMessage(BlackboardArtifactNode.class, "ContentTagNode.createSheet.fileCreatedTime.name"),
NbBundle.getMessage(BlackboardArtifactNode.class, "ContentTagNode.createSheet.fileCreatedTime.displayName"), NbBundle.getMessage(BlackboardArtifactNode.class, "ContentTagNode.createSheet.fileCreatedTime.displayName"),
"", "",
file == null ? "" : ContentUtils.getStringTime(file.getCrtime(), file))); file == null ? "" : TimeZoneUtils.getFormattedTime(file.getCrtime())));
sheetSet.put(new NodeProperty<>( sheetSet.put(new NodeProperty<>(
NbBundle.getMessage(BlackboardArtifactNode.class, "ContentTagNode.createSheet.fileSize.name"), NbBundle.getMessage(BlackboardArtifactNode.class, "ContentTagNode.createSheet.fileSize.name"),
NbBundle.getMessage(BlackboardArtifactNode.class, "ContentTagNode.createSheet.fileSize.displayName"), NbBundle.getMessage(BlackboardArtifactNode.class, "ContentTagNode.createSheet.fileSize.displayName"),
@ -943,7 +944,7 @@ public class BlackboardArtifactNode extends AbstractContentNode<BlackboardArtifa
} else if (artifact.getArtifactTypeID() == BlackboardArtifact.ARTIFACT_TYPE.TSK_EMAIL_MSG.getTypeID()) { } else if (artifact.getArtifactTypeID() == BlackboardArtifact.ARTIFACT_TYPE.TSK_EMAIL_MSG.getTypeID()) {
addEmailMsgProperty(map, attribute); addEmailMsgProperty(map, attribute);
} else if (attribute.getAttributeType().getValueType() == BlackboardAttribute.TSK_BLACKBOARD_ATTRIBUTE_VALUE_TYPE.DATETIME) { } else if (attribute.getAttributeType().getValueType() == BlackboardAttribute.TSK_BLACKBOARD_ATTRIBUTE_VALUE_TYPE.DATETIME) {
map.put(attribute.getAttributeType().getDisplayName(), ContentUtils.getStringTime(attribute.getValueLong(), srcContent)); map.put(attribute.getAttributeType().getDisplayName(), TimeZoneUtils.getFormattedTime(attribute.getValueLong()));
} else if (artifact.getArtifactTypeID() == ARTIFACT_TYPE.TSK_TOOL_OUTPUT.getTypeID() } else if (artifact.getArtifactTypeID() == ARTIFACT_TYPE.TSK_TOOL_OUTPUT.getTypeID()
&& attributeTypeID == ATTRIBUTE_TYPE.TSK_TEXT.getTypeID()) { && attributeTypeID == ATTRIBUTE_TYPE.TSK_TEXT.getTypeID()) {
/* /*
@ -1009,7 +1010,7 @@ public class BlackboardArtifactNode extends AbstractContentNode<BlackboardArtifa
} }
map.put(attribute.getAttributeType().getDisplayName(), value); map.put(attribute.getAttributeType().getDisplayName(), value);
} else if (attribute.getAttributeType().getValueType() == BlackboardAttribute.TSK_BLACKBOARD_ATTRIBUTE_VALUE_TYPE.DATETIME) { } else if (attribute.getAttributeType().getValueType() == BlackboardAttribute.TSK_BLACKBOARD_ATTRIBUTE_VALUE_TYPE.DATETIME) {
map.put(attribute.getAttributeType().getDisplayName(), ContentUtils.getStringTime(attribute.getValueLong(), srcContent)); map.put(attribute.getAttributeType().getDisplayName(), TimeZoneUtils.getFormattedTime(attribute.getValueLong()));
} else { } else {
map.put(attribute.getAttributeType().getDisplayName(), attribute.getDisplayString()); map.put(attribute.getAttributeType().getDisplayName(), attribute.getDisplayString());
} }

View File

@ -1,7 +1,7 @@
/* /*
* Autopsy Forensic Browser * Autopsy Forensic Browser
* *
* Copyright 2013-2020 Basis Technology Corp. * Copyright 2013-2021 Basis Technology Corp.
* Contact: carrier <at> sleuthkit <dot> org * Contact: carrier <at> sleuthkit <dot> org
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
@ -29,6 +29,7 @@ import org.openide.util.NbBundle;
import org.openide.util.NbBundle.Messages; import org.openide.util.NbBundle.Messages;
import org.openide.util.lookup.Lookups; import org.openide.util.lookup.Lookups;
import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.autopsy.coreutils.Logger;
import org.sleuthkit.autopsy.coreutils.TimeZoneUtils;
import org.sleuthkit.autopsy.timeline.actions.ViewFileInTimelineAction; import org.sleuthkit.autopsy.timeline.actions.ViewFileInTimelineAction;
import org.sleuthkit.datamodel.AbstractFile; import org.sleuthkit.datamodel.AbstractFile;
import org.sleuthkit.datamodel.Content; import org.sleuthkit.datamodel.Content;
@ -96,22 +97,22 @@ class ContentTagNode extends TagNode {
properties.put(new NodeProperty<>(NbBundle.getMessage(this.getClass(), "ContentTagNode.createSheet.fileModifiedTime.name"), properties.put(new NodeProperty<>(NbBundle.getMessage(this.getClass(), "ContentTagNode.createSheet.fileModifiedTime.name"),
NbBundle.getMessage(this.getClass(), "ContentTagNode.createSheet.fileModifiedTime.displayName"), NbBundle.getMessage(this.getClass(), "ContentTagNode.createSheet.fileModifiedTime.displayName"),
"", "",
file != null ? ContentUtils.getStringTime(file.getMtime(), file) : "")); file != null ? TimeZoneUtils.getFormattedTime(file.getMtime()) : ""));
properties.put(new NodeProperty<>( properties.put(new NodeProperty<>(
NbBundle.getMessage(this.getClass(), "ContentTagNode.createSheet.fileChangedTime.name"), NbBundle.getMessage(this.getClass(), "ContentTagNode.createSheet.fileChangedTime.name"),
NbBundle.getMessage(this.getClass(), "ContentTagNode.createSheet.fileChangedTime.displayName"), NbBundle.getMessage(this.getClass(), "ContentTagNode.createSheet.fileChangedTime.displayName"),
"", "",
file != null ? ContentUtils.getStringTime(file.getCtime(), file) : "")); file != null ? TimeZoneUtils.getFormattedTime(file.getCtime()) : ""));
properties.put(new NodeProperty<>( properties.put(new NodeProperty<>(
NbBundle.getMessage(this.getClass(), "ContentTagNode.createSheet.fileAccessedTime.name"), NbBundle.getMessage(this.getClass(), "ContentTagNode.createSheet.fileAccessedTime.name"),
NbBundle.getMessage(this.getClass(), "ContentTagNode.createSheet.fileAccessedTime.displayName"), NbBundle.getMessage(this.getClass(), "ContentTagNode.createSheet.fileAccessedTime.displayName"),
"", "",
file != null ? ContentUtils.getStringTime(file.getAtime(), file) : "")); file != null ? TimeZoneUtils.getFormattedTime(file.getAtime()) : ""));
properties.put(new NodeProperty<>( properties.put(new NodeProperty<>(
NbBundle.getMessage(this.getClass(), "ContentTagNode.createSheet.fileCreatedTime.name"), NbBundle.getMessage(this.getClass(), "ContentTagNode.createSheet.fileCreatedTime.name"),
NbBundle.getMessage(this.getClass(), "ContentTagNode.createSheet.fileCreatedTime.displayName"), NbBundle.getMessage(this.getClass(), "ContentTagNode.createSheet.fileCreatedTime.displayName"),
"", "",
file != null ? ContentUtils.getStringTime(file.getCrtime(), file) : "")); file != null ? TimeZoneUtils.getFormattedTime(file.getCrtime()) : ""));
properties.put(new NodeProperty<>( properties.put(new NodeProperty<>(
NbBundle.getMessage(this.getClass(), "ContentTagNode.createSheet.fileSize.name"), NbBundle.getMessage(this.getClass(), "ContentTagNode.createSheet.fileSize.name"),
NbBundle.getMessage(this.getClass(), "ContentTagNode.createSheet.fileSize.displayName"), NbBundle.getMessage(this.getClass(), "ContentTagNode.createSheet.fileSize.displayName"),

View File

@ -26,8 +26,6 @@ import java.util.TimeZone;
import java.util.concurrent.Future; import java.util.concurrent.Future;
import java.util.function.Supplier; import java.util.function.Supplier;
import java.util.logging.Level; import java.util.logging.Level;
import java.util.prefs.PreferenceChangeEvent;
import java.util.prefs.PreferenceChangeListener;
import javax.swing.SwingWorker; import javax.swing.SwingWorker;
import org.netbeans.api.progress.ProgressHandle; import org.netbeans.api.progress.ProgressHandle;
import org.openide.util.NbBundle; import org.openide.util.NbBundle;
@ -39,7 +37,6 @@ import org.sleuthkit.datamodel.ContentVisitor;
import org.sleuthkit.datamodel.DerivedFile; import org.sleuthkit.datamodel.DerivedFile;
import org.sleuthkit.datamodel.Directory; import org.sleuthkit.datamodel.Directory;
import org.sleuthkit.datamodel.File; import org.sleuthkit.datamodel.File;
import org.sleuthkit.datamodel.Image;
import org.sleuthkit.datamodel.LayoutFile; import org.sleuthkit.datamodel.LayoutFile;
import org.sleuthkit.datamodel.LocalFile; import org.sleuthkit.datamodel.LocalFile;
import org.sleuthkit.datamodel.LocalDirectory; import org.sleuthkit.datamodel.LocalDirectory;
@ -55,21 +52,9 @@ import org.sleuthkit.datamodel.VirtualDirectory;
public final class ContentUtils { public final class ContentUtils {
private final static Logger logger = Logger.getLogger(ContentUtils.class.getName()); private final static Logger logger = Logger.getLogger(ContentUtils.class.getName());
private static boolean displayTimesInLocalTime = UserPreferences.displayTimesInLocalTime();
private static final SimpleDateFormat dateFormatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss z"); private static final SimpleDateFormat dateFormatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss z");
private static final SimpleDateFormat dateFormatterISO8601 = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'"); private static final SimpleDateFormat dateFormatterISO8601 = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'");
static {
UserPreferences.addChangeListener(new PreferenceChangeListener() {
@Override
public void preferenceChange(PreferenceChangeEvent evt) {
if (evt.getKey().equals(UserPreferences.DISPLAY_TIMES_IN_LOCAL_TIME)) {
displayTimesInLocalTime = UserPreferences.displayTimesInLocalTime();
}
}
});
}
/** /**
* Don't instantiate * Don't instantiate
*/ */
@ -85,6 +70,7 @@ public final class ContentUtils {
* *
* @return The time * @return The time
*/ */
@Deprecated
public static String getStringTime(long epochSeconds, TimeZone tzone) { public static String getStringTime(long epochSeconds, TimeZone tzone) {
String time = "0000-00-00 00:00:00"; String time = "0000-00-00 00:00:00";
if (epochSeconds != 0) { if (epochSeconds != 0) {
@ -104,6 +90,7 @@ public final class ContentUtils {
* *
* @return The time * @return The time
*/ */
@Deprecated
public static String getStringTimeISO8601(long epochSeconds, TimeZone tzone) { public static String getStringTimeISO8601(long epochSeconds, TimeZone tzone) {
String time = "0000-00-00T00:00:00Z"; //NON-NLS String time = "0000-00-00T00:00:00Z"; //NON-NLS
if (epochSeconds != 0) { if (epochSeconds != 0) {
@ -123,7 +110,10 @@ public final class ContentUtils {
* @param content * @param content
* *
* @return * @return
*
* @deprecated Use org.sleuthkit.autopsy.coreutils.TimeZoneUtils.getFormattedTime instead
*/ */
@Deprecated
public static String getStringTime(long epochSeconds, Content content) { public static String getStringTime(long epochSeconds, Content content) {
return getStringTime(epochSeconds, getTimeZone(content)); return getStringTime(epochSeconds, getTimeZone(content));
} }
@ -136,29 +126,30 @@ public final class ContentUtils {
* @param c * @param c
* *
* @return * @return
*
* @deprecated Use org.sleuthkit.autopsy.coreutils.TimeZoneUtils.getFormattedTimeISO8601 instead
*/ */
@Deprecated
public static String getStringTimeISO8601(long epochSeconds, Content c) { public static String getStringTimeISO8601(long epochSeconds, Content c) {
return getStringTimeISO8601(epochSeconds, getTimeZone(c)); return getStringTimeISO8601(epochSeconds, getTimeZone(c));
} }
/**
* Returns either the user selected time zone or the system time zone.
*
* @param content
*
* @return
*
* @deprecated Use org.sleuthkit.autopsy.coreutils.TimeZoneUtils.getTimeZone instead
*/
@Deprecated
public static TimeZone getTimeZone(Content content) { public static TimeZone getTimeZone(Content content) {
if (!shouldDisplayTimesInLocalTime()) {
try { return TimeZone.getTimeZone(UserPreferences.getTimeZoneForDisplays());
if (!shouldDisplayTimesInLocalTime()) { } else {
return TimeZone.getTimeZone(UserPreferences.getTimeZoneForDisplays());
} else {
final Content dataSource = content.getDataSource();
if ((dataSource != null) && (dataSource instanceof Image)) {
Image image = (Image) dataSource;
return TimeZone.getTimeZone(image.getTimeZone());
} else {
//case such as top level VirtualDirectory
return TimeZone.getDefault();
}
}
} catch (TskCoreException ex) {
return TimeZone.getDefault(); return TimeZone.getDefault();
} }
} }
private static final SystemNameVisitor systemName = new SystemNameVisitor(); private static final SystemNameVisitor systemName = new SystemNameVisitor();
@ -553,9 +544,12 @@ public final class ContentUtils {
* Indicates whether or not times should be displayed using local time. * Indicates whether or not times should be displayed using local time.
* *
* @return True or false. * @return True or false.
*
* @deprecated Call UserPreferences.displayTimesInLocalTime instead.
*/ */
@Deprecated
public static boolean shouldDisplayTimesInLocalTime() { public static boolean shouldDisplayTimesInLocalTime() {
return displayTimesInLocalTime; return UserPreferences.displayTimesInLocalTime();
} }
} }

View File

@ -481,5 +481,10 @@ public final class FileTypes implements AutopsyVisitableItem {
public List<AnalysisResult> getAllAnalysisResults() throws TskCoreException { public List<AnalysisResult> getAllAnalysisResults() throws TskCoreException {
return content.getAllAnalysisResults(); return content.getAllAnalysisResults();
} }
@Override
public List<DataArtifact> getAllDataArtifacts() throws TskCoreException {
return content.getAllDataArtifacts();
}
} }
} }

View File

@ -1,7 +1,7 @@
/* /*
* Autopsy Forensic Browser * Autopsy Forensic Browser
* *
* Copyright 2011-2020 Basis Technology Corp. * Copyright 2011-2021 Basis Technology Corp.
* Contact: carrier <at> sleuthkit <dot> org * Contact: carrier <at> sleuthkit <dot> org
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
@ -46,6 +46,7 @@ import org.openide.util.lookup.Lookups;
import org.sleuthkit.autopsy.casemodule.Case; import org.sleuthkit.autopsy.casemodule.Case;
import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException; import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException;
import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.autopsy.coreutils.Logger;
import org.sleuthkit.autopsy.coreutils.TimeZoneUtils;
import static org.sleuthkit.autopsy.datamodel.Bundle.*; import static org.sleuthkit.autopsy.datamodel.Bundle.*;
import org.sleuthkit.autopsy.ingest.IngestManager; import org.sleuthkit.autopsy.ingest.IngestManager;
import org.sleuthkit.autopsy.ingest.ModuleDataEvent; import org.sleuthkit.autopsy.ingest.ModuleDataEvent;
@ -889,17 +890,17 @@ public class KeywordHits implements AutopsyVisitableItem {
KeywordHits_createNodeForKey_modTime_name(), KeywordHits_createNodeForKey_modTime_name(),
KeywordHits_createNodeForKey_modTime_displayName(), KeywordHits_createNodeForKey_modTime_displayName(),
KeywordHits_createNodeForKey_modTime_desc(), KeywordHits_createNodeForKey_modTime_desc(),
ContentUtils.getStringTime(file.getMtime(), file))); TimeZoneUtils.getFormattedTime(file.getMtime())));
n.addNodeProperty(new NodeProperty<>( n.addNodeProperty(new NodeProperty<>(
KeywordHits_createNodeForKey_accessTime_name(), KeywordHits_createNodeForKey_accessTime_name(),
KeywordHits_createNodeForKey_accessTime_displayName(), KeywordHits_createNodeForKey_accessTime_displayName(),
KeywordHits_createNodeForKey_accessTime_desc(), KeywordHits_createNodeForKey_accessTime_desc(),
ContentUtils.getStringTime(file.getAtime(), file))); TimeZoneUtils.getFormattedTime(file.getAtime())));
n.addNodeProperty(new NodeProperty<>( n.addNodeProperty(new NodeProperty<>(
KeywordHits_createNodeForKey_chgTime_name(), KeywordHits_createNodeForKey_chgTime_name(),
KeywordHits_createNodeForKey_chgTime_displayName(), KeywordHits_createNodeForKey_chgTime_displayName(),
KeywordHits_createNodeForKey_chgTime_desc(), KeywordHits_createNodeForKey_chgTime_desc(),
ContentUtils.getStringTime(file.getCtime(), file))); TimeZoneUtils.getFormattedTime(file.getCtime())));
return n; return n;
} }

View File

@ -43,6 +43,7 @@ import org.sleuthkit.autopsy.casemodule.events.OsAccountChangedEvent;
import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationAttributeInstance; import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationAttributeInstance;
import org.sleuthkit.autopsy.corecomponents.DataResultViewerTable; import org.sleuthkit.autopsy.corecomponents.DataResultViewerTable;
import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.autopsy.coreutils.Logger;
import org.sleuthkit.autopsy.coreutils.TimeZoneUtils;
import static org.sleuthkit.autopsy.datamodel.AbstractContentNode.backgroundTasksPool; import static org.sleuthkit.autopsy.datamodel.AbstractContentNode.backgroundTasksPool;
import org.sleuthkit.autopsy.events.AutopsyEvent; import org.sleuthkit.autopsy.events.AutopsyEvent;
import org.sleuthkit.datamodel.Host; import org.sleuthkit.datamodel.Host;
@ -301,7 +302,7 @@ public final class OsAccounts implements AutopsyVisitableItem {
Optional<Long> creationTimeValue = account.getCreationTime(); Optional<Long> creationTimeValue = account.getCreationTime();
String timeDisplayStr String timeDisplayStr
= creationTimeValue.isPresent() ? DATE_FORMATTER.format(new java.util.Date(creationTimeValue.get() * 1000)) : ""; = creationTimeValue.isPresent() ? TimeZoneUtils.getFormattedTime(creationTimeValue.get() * 1000) : "";
propertiesSet.put(new NodeProperty<>( propertiesSet.put(new NodeProperty<>(
Bundle.OsAccounts_createdTimeProperty_name(), Bundle.OsAccounts_createdTimeProperty_name(),

View File

@ -1,7 +1,7 @@
/* /*
* Autopsy * Autopsy
* *
* Copyright 2020 Basis Technology Corp. * Copyright 2020-2021 Basis Technology Corp.
* Contact: carrier <at> sleuthkit <dot> org * Contact: carrier <at> sleuthkit <dot> org
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
@ -32,7 +32,7 @@ import java.util.logging.Level;
import org.openide.util.NbBundle; import org.openide.util.NbBundle;
import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepository; import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepository;
import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.autopsy.coreutils.Logger;
import org.sleuthkit.autopsy.datamodel.ContentUtils; import org.sleuthkit.autopsy.coreutils.TimeZoneUtils;
import org.sleuthkit.autopsy.discovery.search.SearchData.PageViews; import org.sleuthkit.autopsy.discovery.search.SearchData.PageViews;
import org.sleuthkit.autopsy.discovery.ui.MonthAbbreviation; import org.sleuthkit.autopsy.discovery.ui.MonthAbbreviation;
import org.sleuthkit.datamodel.AbstractFile; import org.sleuthkit.datamodel.AbstractFile;
@ -1217,7 +1217,7 @@ public class DiscoveryKeyUtils {
Instant startActivityAsInsant = Instant.ofEpochSecond(epochSeconds); Instant startActivityAsInsant = Instant.ofEpochSecond(epochSeconds);
// Determines the timezone using the settings panel or value parsed from the // Determines the timezone using the settings panel or value parsed from the
// parent data source // parent data source
TimeZone currentTimeZone = ContentUtils.getTimeZone(domainResult.getDataSource()); TimeZone currentTimeZone = TimeZoneUtils.getTimeZone();
// Convert to a datetime using epoch and timezone. // Convert to a datetime using epoch and timezone.
ZonedDateTime startActivityAsDateTime = ZonedDateTime.ofInstant(startActivityAsInsant, currentTimeZone.toZoneId()); ZonedDateTime startActivityAsDateTime = ZonedDateTime.ofInstant(startActivityAsInsant, currentTimeZone.toZoneId());
// Get the closest Sunday, which is the cut off for the current week. // Get the closest Sunday, which is the cut off for the current week.

View File

@ -1,7 +1,7 @@
/* /*
* Autopsy * Autopsy
* *
* Copyright 2020 Basis Technology Corp. * Copyright 2020-2021 Basis Technology Corp.
* Contact: carrier <at> sleuthkit <dot> org * Contact: carrier <at> sleuthkit <dot> org
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
@ -24,15 +24,13 @@ import java.util.HashMap;
import java.util.LinkedHashMap; import java.util.LinkedHashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.TimeZone;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepository; import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepository;
import org.sleuthkit.autopsy.datamodel.ContentUtils; import org.sleuthkit.autopsy.coreutils.TimeZoneUtils;
import org.sleuthkit.autopsy.discovery.search.DiscoveryKeyUtils.GroupKey; import org.sleuthkit.autopsy.discovery.search.DiscoveryKeyUtils.GroupKey;
import org.sleuthkit.datamodel.BlackboardArtifact; import org.sleuthkit.datamodel.BlackboardArtifact;
import org.sleuthkit.datamodel.BlackboardAttribute; import org.sleuthkit.datamodel.BlackboardAttribute;
import org.sleuthkit.datamodel.SleuthkitCase; import org.sleuthkit.datamodel.SleuthkitCase;
import org.sleuthkit.datamodel.TimeUtilities;
import org.sleuthkit.datamodel.TskCoreException; import org.sleuthkit.datamodel.TskCoreException;
/** /**
@ -246,8 +244,7 @@ public class DomainSearch {
private String getDate(BlackboardArtifact artifact) throws TskCoreException { private String getDate(BlackboardArtifact artifact) throws TskCoreException {
for (BlackboardAttribute attribute : artifact.getAttributes()) { for (BlackboardAttribute attribute : artifact.getAttributes()) {
if (attribute.getAttributeType().getTypeName().startsWith("TSK_DATETIME")) { if (attribute.getAttributeType().getTypeName().startsWith("TSK_DATETIME")) {
TimeZone timeZone = ContentUtils.getTimeZone(artifact); String dateString = TimeZoneUtils.getFormattedTime(attribute.getValueLong());
String dateString = TimeUtilities.epochToTime(attribute.getValueLong(), timeZone);
if (dateString.length() >= 10) { if (dateString.length() >= 10) {
return dateString.substring(0, 10); return dateString.substring(0, 10);
} }

View File

@ -1,7 +1,7 @@
/* /*
* Autopsy * Autopsy
* *
* Copyright 2020 Basis Technology Corp. * Copyright 2020-2021 Basis Technology Corp.
* Contact: carrier <at> sleuthkit <dot> org * Contact: carrier <at> sleuthkit <dot> org
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
@ -33,11 +33,10 @@ import org.openide.util.NbBundle;
import org.sleuthkit.autopsy.casemodule.Case; import org.sleuthkit.autopsy.casemodule.Case;
import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.autopsy.coreutils.Logger;
import org.sleuthkit.autopsy.coreutils.ThreadConfined; import org.sleuthkit.autopsy.coreutils.ThreadConfined;
import org.sleuthkit.autopsy.datamodel.ContentUtils; import org.sleuthkit.autopsy.coreutils.TimeZoneUtils;
import org.sleuthkit.autopsy.guiutils.SimpleTableCellRenderer; import org.sleuthkit.autopsy.guiutils.SimpleTableCellRenderer;
import org.sleuthkit.datamodel.BlackboardArtifact; import org.sleuthkit.datamodel.BlackboardArtifact;
import org.sleuthkit.datamodel.BlackboardAttribute; import org.sleuthkit.datamodel.BlackboardAttribute;
import org.sleuthkit.datamodel.TimeUtilities;
import org.sleuthkit.datamodel.TskCoreException; import org.sleuthkit.datamodel.TskCoreException;
/** /**
@ -303,7 +302,7 @@ final class ArtifactsListPanel extends AbstractArtifactListPanel {
@ThreadConfined(type = ThreadConfined.ThreadType.AWT) @ThreadConfined(type = ThreadConfined.ThreadType.AWT)
private String getStringForColumn(BlackboardArtifact artifact, BlackboardAttribute bba, int columnIndex) throws TskCoreException { private String getStringForColumn(BlackboardArtifact artifact, BlackboardAttribute bba, int columnIndex) throws TskCoreException {
if (columnIndex == 0 && bba.getAttributeType().getTypeID() == BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME_ACCESSED.getTypeID()) { if (columnIndex == 0 && bba.getAttributeType().getTypeID() == BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME_ACCESSED.getTypeID()) {
return TimeUtilities.epochToTime(bba.getValueLong(), ContentUtils.getTimeZone(artifact)); return TimeZoneUtils.getFormattedTime(bba.getValueLong());
} else if (columnIndex == 1) { } else if (columnIndex == 1) {
if (artifactType == BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_DOWNLOAD || artifactType == BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_CACHE) { if (artifactType == BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_DOWNLOAD || artifactType == BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_CACHE) {
if (bba.getAttributeType().getTypeID() == BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PATH_ID.getTypeID()) { if (bba.getAttributeType().getTypeID() == BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PATH_ID.getTypeID()) {
@ -339,7 +338,7 @@ final class ArtifactsListPanel extends AbstractArtifactListPanel {
final BlackboardArtifact artifact = getArtifactByRow(rowIndex); final BlackboardArtifact artifact = getArtifactByRow(rowIndex);
for (BlackboardAttribute bba : artifact.getAttributes()) { for (BlackboardAttribute bba : artifact.getAttributes()) {
if (columnIndex == 0 && bba.getAttributeType().getTypeName().startsWith("TSK_DATETIME") && !StringUtils.isBlank(bba.getDisplayString())) { if (columnIndex == 0 && bba.getAttributeType().getTypeName().startsWith("TSK_DATETIME") && !StringUtils.isBlank(bba.getDisplayString())) {
return TimeUtilities.epochToTime(bba.getValueLong(), ContentUtils.getTimeZone(artifact)); return TimeZoneUtils.getFormattedTime(bba.getValueLong());
} else if (columnIndex == 1 && bba.getAttributeType().getTypeID() == BlackboardAttribute.ATTRIBUTE_TYPE.TSK_URL.getTypeID() && !StringUtils.isBlank(bba.getDisplayString())) { } else if (columnIndex == 1 && bba.getAttributeType().getTypeID() == BlackboardAttribute.ATTRIBUTE_TYPE.TSK_URL.getTypeID() && !StringUtils.isBlank(bba.getDisplayString())) {
return bba.getDisplayString(); return bba.getDisplayString();
} else if (columnIndex == 1 && bba.getAttributeType().getTypeID() == BlackboardAttribute.ATTRIBUTE_TYPE.TSK_NAME.getTypeID() && !StringUtils.isBlank(bba.getDisplayString())) { } else if (columnIndex == 1 && bba.getAttributeType().getTypeID() == BlackboardAttribute.ATTRIBUTE_TYPE.TSK_NAME.getTypeID() && !StringUtils.isBlank(bba.getDisplayString())) {

View File

@ -33,7 +33,7 @@ import javax.swing.JList;
import javax.swing.ListCellRenderer; import javax.swing.ListCellRenderer;
import org.openide.util.NbBundle; import org.openide.util.NbBundle;
import org.sleuthkit.autopsy.coreutils.ThreadConfined; import org.sleuthkit.autopsy.coreutils.ThreadConfined;
import org.sleuthkit.autopsy.datamodel.ContentUtils; import org.sleuthkit.autopsy.coreutils.TimeZoneUtils;
import org.sleuthkit.autopsy.discovery.search.SearchData; import org.sleuthkit.autopsy.discovery.search.SearchData;
/** /**
@ -180,7 +180,7 @@ class DomainSummaryPanel extends javax.swing.JPanel implements ListCellRenderer<
@Override @Override
public Component getListCellRendererComponent(JList<? extends DomainWrapper> list, DomainWrapper value, int index, boolean isSelected, boolean cellHasFocus) { public Component getListCellRendererComponent(JList<? extends DomainWrapper> list, DomainWrapper value, int index, boolean isSelected, boolean cellHasFocus) {
domainNameLabel.setText(value.getResultDomain().getDomain()); domainNameLabel.setText(value.getResultDomain().getDomain());
TimeZone timeZone = ContentUtils.getTimeZone(value.getResultDomain().getDataSource()); TimeZone timeZone = TimeZoneUtils.getTimeZone();
String startDate = formatDate(value.getResultDomain().getActivityStart(), timeZone); String startDate = formatDate(value.getResultDomain().getActivityStart(), timeZone);
String endDate = formatDate(value.getResultDomain().getActivityEnd(), timeZone); String endDate = formatDate(value.getResultDomain().getActivityEnd(), timeZone);
String notability = Bundle.DomainSummaryPanel_notability_text(); String notability = Bundle.DomainSummaryPanel_notability_text();

View File

@ -1309,13 +1309,29 @@ class SevenZipExtractor {
} }
if (tokens.size() != byteTokens.size()) { if (tokens.size() != byteTokens.size()) {
logger.log(Level.WARNING, "Could not map path bytes to path string"); logger.log(Level.WARNING, "Could not map path bytes to path string (path string: \"{0}\", bytes: {1})",
new Object[]{filePath, bytesToString(filePathBytes)});
return addNode(rootNode, tokens, null); return addNode(rootNode, tokens, null);
} }
} }
return addNode(rootNode, tokens, byteTokens); return addNode(rootNode, tokens, byteTokens);
} }
/**
* Convert byte array to string representation.
*
* @param bytes Byte array
*
* @return Byte array as lower case hex string.
*/
private String bytesToString(byte[] bytes) {
StringBuilder result = new StringBuilder();
for (byte b : bytes) {
result.append(String.format("%02x", b));
}
return result.toString();
}
/** /**
* recursive method that traverses the path * recursive method that traverses the path

View File

@ -1,7 +1,7 @@
/* /*
* Autopsy Forensic Browser * Autopsy Forensic Browser
* *
* Copyright 2013-2020 Basis Technology Corp. * Copyright 2013-2021 Basis Technology Corp.
* Contact: carrier <at> sleuthkit <dot> org * Contact: carrier <at> sleuthkit <dot> org
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
@ -48,6 +48,7 @@ import org.sleuthkit.autopsy.coreutils.Logger;
import org.sleuthkit.autopsy.datamodel.ContentUtils; import org.sleuthkit.autopsy.datamodel.ContentUtils;
import org.sleuthkit.autopsy.report.ReportProgressPanel; import org.sleuthkit.autopsy.report.ReportProgressPanel;
import static org.sleuthkit.autopsy.casemodule.services.TagsManager.getNotableTagLabel; import static org.sleuthkit.autopsy.casemodule.services.TagsManager.getNotableTagLabel;
import org.sleuthkit.autopsy.coreutils.TimeZoneUtils;
import org.sleuthkit.datamodel.AbstractFile; import org.sleuthkit.datamodel.AbstractFile;
import org.sleuthkit.datamodel.Account; import org.sleuthkit.datamodel.Account;
import org.sleuthkit.datamodel.BlackboardArtifact; import org.sleuthkit.datamodel.BlackboardArtifact;
@ -1919,7 +1920,7 @@ class TableReportGenerator {
if (attribute.getAttributeType().getValueType() != BlackboardAttribute.TSK_BLACKBOARD_ATTRIBUTE_VALUE_TYPE.DATETIME) { if (attribute.getAttributeType().getValueType() != BlackboardAttribute.TSK_BLACKBOARD_ATTRIBUTE_VALUE_TYPE.DATETIME) {
return attribute.getDisplayString(); return attribute.getDisplayString();
} else { } else {
return ContentUtils.getStringTime(attribute.getValueLong(), artData.getContent()); return TimeZoneUtils.getFormattedTime(attribute.getValueLong());
} }
} }
} }

View File

@ -1,7 +1,7 @@
/* /*
* Autopsy Forensic Browser * Autopsy Forensic Browser
* *
* Copyright 2011-2018 Basis Technology Corp. * Copyright 2011-2021 Basis Technology Corp.
* Contact: carrier <at> sleuthkit <dot> org * Contact: carrier <at> sleuthkit <dot> org
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
@ -22,10 +22,9 @@ import java.io.InputStreamReader;
import java.io.Reader; import java.io.Reader;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import org.apache.commons.io.IOUtils; import org.apache.commons.io.IOUtils;
import org.sleuthkit.autopsy.datamodel.ContentUtils; import org.sleuthkit.autopsy.coreutils.TimeZoneUtils;
import org.sleuthkit.datamodel.BlackboardArtifact; import org.sleuthkit.datamodel.BlackboardArtifact;
import org.sleuthkit.datamodel.BlackboardAttribute; import org.sleuthkit.datamodel.BlackboardAttribute;
import org.sleuthkit.datamodel.Content;
import org.sleuthkit.datamodel.TskCoreException; import org.sleuthkit.datamodel.TskCoreException;
/** /**
@ -57,7 +56,7 @@ class ArtifactTextExtractor implements TextExtractor {
// in the Autopsy datamodel. // in the Autopsy datamodel.
switch (attribute.getValueType()) { switch (attribute.getValueType()) {
case DATETIME: case DATETIME:
artifactContents.append(ContentUtils.getStringTime(attribute.getValueLong(), artifact)); artifactContents.append(TimeZoneUtils.getFormattedTime(attribute.getValueLong()));
break; break;
default: default:
artifactContents.append(attribute.getDisplayString()); artifactContents.append(attribute.getDisplayString());

View File

@ -33,6 +33,7 @@ import javafx.scene.image.ImageView;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.openide.util.NbBundle; import org.openide.util.NbBundle;
import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.autopsy.coreutils.Logger;
import org.sleuthkit.autopsy.coreutils.TimeZoneUtils;
import org.sleuthkit.autopsy.datamodel.ContentUtils; import org.sleuthkit.autopsy.datamodel.ContentUtils;
import org.sleuthkit.datamodel.TagName; import org.sleuthkit.datamodel.TagName;
@ -118,13 +119,13 @@ public class DrawableAttribute<T extends Comparable<T>> {
= new DrawableAttribute<>(AttributeName.CREATED_TIME, Bundle.DrawableAttribute_createdTime(), = new DrawableAttribute<>(AttributeName.CREATED_TIME, Bundle.DrawableAttribute_createdTime(),
true, true,
"clock--plus.png", //NON-NLS "clock--plus.png", //NON-NLS
f -> Collections.singleton(ContentUtils.getStringTime(f.getCrtime(), f.getAbstractFile()))); f -> Collections.singleton(TimeZoneUtils.getFormattedTime(f.getCrtime())));
public final static DrawableAttribute<String> MODIFIED_TIME public final static DrawableAttribute<String> MODIFIED_TIME
= new DrawableAttribute<>(AttributeName.MODIFIED_TIME, Bundle.DrawableAttribute_modifiedTime(), = new DrawableAttribute<>(AttributeName.MODIFIED_TIME, Bundle.DrawableAttribute_modifiedTime(),
true, true,
"clock--pencil.png", //NON-NLS "clock--pencil.png", //NON-NLS
f -> Collections.singleton(ContentUtils.getStringTime(f.getMtime(), f.getAbstractFile()))); f -> Collections.singleton(TimeZoneUtils.getFormattedTime(f.getMtime())));
public final static DrawableAttribute<String> MAKE public final static DrawableAttribute<String> MAKE
= new DrawableAttribute<>(AttributeName.MAKE, Bundle.DrawableAttribute_cameraMake(), = new DrawableAttribute<>(AttributeName.MAKE, Bundle.DrawableAttribute_cameraMake(),

View File

@ -30,6 +30,7 @@ import org.apache.solr.client.solrj.SolrServerException;
import org.apache.solr.common.SolrInputDocument; import org.apache.solr.common.SolrInputDocument;
import org.openide.util.NbBundle; import org.openide.util.NbBundle;
import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.autopsy.coreutils.Logger;
import org.sleuthkit.autopsy.coreutils.TimeZoneUtils;
import org.sleuthkit.autopsy.datamodel.ContentUtils; import org.sleuthkit.autopsy.datamodel.ContentUtils;
import org.sleuthkit.autopsy.healthmonitor.HealthMonitor; import org.sleuthkit.autopsy.healthmonitor.HealthMonitor;
import org.sleuthkit.autopsy.healthmonitor.TimingMetric; import org.sleuthkit.autopsy.healthmonitor.TimingMetric;
@ -389,10 +390,10 @@ class Ingester {
*/ */
private Map<String, String> getCommonAndMACTimeFields(AbstractFile file) { private Map<String, String> getCommonAndMACTimeFields(AbstractFile file) {
Map<String, String> params = getCommonFields(file); Map<String, String> params = getCommonFields(file);
params.put(Server.Schema.CTIME.toString(), ContentUtils.getStringTimeISO8601(file.getCtime(), file)); params.put(Server.Schema.CTIME.toString(), TimeZoneUtils.getFormattedTimeISO8601(file.getCtime()));
params.put(Server.Schema.ATIME.toString(), ContentUtils.getStringTimeISO8601(file.getAtime(), file)); params.put(Server.Schema.ATIME.toString(), TimeZoneUtils.getFormattedTimeISO8601(file.getAtime()));
params.put(Server.Schema.MTIME.toString(), ContentUtils.getStringTimeISO8601(file.getMtime(), file)); params.put(Server.Schema.MTIME.toString(), TimeZoneUtils.getFormattedTimeISO8601(file.getMtime()));
params.put(Server.Schema.CRTIME.toString(), ContentUtils.getStringTimeISO8601(file.getCrtime(), file)); params.put(Server.Schema.CRTIME.toString(), TimeZoneUtils.getFormattedTimeISO8601(file.getCrtime()));
return params; return params;
} }

View File

@ -924,13 +924,9 @@ def normalize_tsk_files_path(guid_util: TskGuidUtils, row: Dict[str, any]) -> Di
if module_output_idx >= 0: if module_output_idx >= 0:
# remove everything up to and including ModuleOutput if ModuleOutput present # remove everything up to and including ModuleOutput if ModuleOutput present
path_parts = path_parts[module_output_idx:] path_parts = path_parts[module_output_idx:]
if len(path_parts) > 1 and path_parts[1] == 'Embedded File Extractor': if len(path_parts) > 2 and path_parts[1] == 'EFE':
# Takes a folder like ModuleOutput\Embedded File Extractor/f_000168_4435\f_000168 # for embedded file extractor, the next folder is the object id and should be omitted
# and fixes the folder after 'Embedded File Extractor', 'f_000168_4435' to remove the last number del path_parts[2]
# to become 'f_000168'
match = re.match(r'^(.+?)_\d*$', path_parts[2])
if match:
path_parts[2] = match.group(1)
row_copy['path'] = os.path.join(*path_parts) if len(path_parts) > 0 else '/' row_copy['path'] = os.path.join(*path_parts) if len(path_parts) > 0 else '/'