19 package org.sleuthkit.autopsy.contentviewers;
 
   21 import java.awt.Component;
 
   22 import java.util.Arrays;
 
   23 import java.util.List;
 
   24 import java.util.Optional;
 
   26 import java.util.logging.Level;
 
   27 import java.util.stream.Collectors;
 
   28 import javax.swing.text.JTextComponent;
 
   29 import org.apache.commons.lang3.StringUtils;
 
   30 import org.jsoup.Jsoup;
 
   31 import org.jsoup.nodes.Document;
 
   32 import org.openide.explorer.ExplorerManager;
 
   33 import org.openide.nodes.AbstractNode;
 
   34 import org.openide.nodes.Children;
 
   35 import org.openide.nodes.Node;
 
   36 import org.openide.nodes.Sheet;
 
   37 import org.openide.util.NbBundle;
 
   38 import org.openide.util.lookup.ServiceProvider;
 
   49 import static org.
sleuthkit.datamodel.BlackboardArtifact.ARTIFACT_TYPE.TSK_EMAIL_MSG;
 
   50 import static org.
sleuthkit.datamodel.BlackboardArtifact.ARTIFACT_TYPE.TSK_KEYWORD_HIT;
 
   51 import static org.
sleuthkit.datamodel.BlackboardArtifact.ARTIFACT_TYPE.TSK_MESSAGE;
 
   53 import static org.
sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_ASSOCIATED_ARTIFACT;
 
   54 import static org.
sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME;
 
   55 import static org.
sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME_RCVD;
 
   56 import static org.
sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DIRECTION;
 
   57 import static org.
sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_EMAIL_CC;
 
   58 import static org.
sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_EMAIL_CONTENT_HTML;
 
   59 import static org.
sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_EMAIL_CONTENT_PLAIN;
 
   60 import static org.
sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_EMAIL_CONTENT_RTF;
 
   61 import static org.
sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_EMAIL_FROM;
 
   62 import static org.
sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_EMAIL_TO;
 
   63 import static org.
sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_HEADERS;
 
   64 import static org.
sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PHONE_NUMBER_FROM;
 
   65 import static org.
sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PHONE_NUMBER_TO;
 
   66 import static org.
sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_SUBJECT;
 
   67 import static org.
sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_TEXT;
 
   73 @ServiceProvider(service = DataContentViewer.class, position = 5)
 
   76     private static final long serialVersionUID = 1L;
 
   78     private static final BlackboardAttribute.Type TSK_ASSOCIATED_TYPE = 
new BlackboardAttribute.Type(TSK_ASSOCIATED_ARTIFACT);
 
   80     private static final int HDR_TAB_INDEX = 0;
 
   81     private static final int TEXT_TAB_INDEX = 1;
 
   82     private static final int HTML_TAB_INDEX = 2;
 
   83     private static final int RTF_TAB_INDEX = 3;
 
   84     private static final int ATTM_TAB_INDEX = 4;
 
   98     @NbBundle.Messages(
"MessageContentViewer.AtrachmentsPanel.title=Attachments")
 
  102         attachmentsScrollPane.setViewportView(drp);
 
  103         msgbodyTabbedPane.setEnabledAt(ATTM_TAB_INDEX, 
true);
 
  105         textAreas = Arrays.asList(headersTextArea, textbodyTextArea, htmlbodyTextPane, rtfbodyTextPane);
 
  119         drpExplorerManager.addPropertyChangeListener(evt ->
 
  120                 viewInNewWindowButton.setEnabled(drpExplorerManager.getSelectedNodes().length == 1));
 
  128     @SuppressWarnings(
"unchecked")
 
  130     private 
void initComponents() {
 
  132         envelopePanel = 
new javax.swing.JPanel();
 
  133         fromLabel = 
new javax.swing.JLabel();
 
  134         datetimeText = 
new javax.swing.JLabel();
 
  135         fromText = 
new javax.swing.JLabel();
 
  136         toLabel = 
new javax.swing.JLabel();
 
  137         toText = 
new javax.swing.JLabel();
 
  138         ccLabel = 
new javax.swing.JLabel();
 
  139         ccText = 
new javax.swing.JLabel();
 
  140         subjectLabel = 
new javax.swing.JLabel();
 
  141         subjectText = 
new javax.swing.JLabel();
 
  142         directionText = 
new javax.swing.JLabel();
 
  143         msgbodyTabbedPane = 
new javax.swing.JTabbedPane();
 
  144         headersScrollPane = 
new javax.swing.JScrollPane();
 
  145         headersTextArea = 
new javax.swing.JTextArea();
 
  146         textbodyScrollPane = 
new javax.swing.JScrollPane();
 
  147         textbodyTextArea = 
new javax.swing.JTextArea();
 
  148         htmlPane = 
new javax.swing.JPanel();
 
  149         htmlScrollPane = 
new javax.swing.JScrollPane();
 
  150         htmlbodyTextPane = 
new javax.swing.JTextPane();
 
  151         showImagesToggleButton = 
new javax.swing.JToggleButton();
 
  152         rtfbodyScrollPane = 
new javax.swing.JScrollPane();
 
  153         rtfbodyTextPane = 
new javax.swing.JTextPane();
 
  154         attachmentsPanel = 
new javax.swing.JPanel();
 
  155         viewInNewWindowButton = 
new javax.swing.JButton();
 
  156         attachmentsScrollPane = 
new javax.swing.JScrollPane();
 
  158         envelopePanel.setBackground(
new java.awt.Color(204, 204, 204));
 
  160         org.openide.awt.Mnemonics.setLocalizedText(fromLabel, 
org.openide.util.NbBundle.getMessage(
MessageContentViewer.class, 
"MessageContentViewer.fromLabel.text")); 
 
  162         datetimeText.setHorizontalAlignment(javax.swing.SwingConstants.RIGHT);
 
  163         org.openide.awt.Mnemonics.setLocalizedText(datetimeText, 
org.openide.util.NbBundle.getMessage(
MessageContentViewer.class, 
"MessageContentViewer.datetimeText.text")); 
 
  165         org.openide.awt.Mnemonics.setLocalizedText(fromText, 
org.openide.util.NbBundle.getMessage(
MessageContentViewer.class, 
"MessageContentViewer.fromText.text")); 
 
  167         org.openide.awt.Mnemonics.setLocalizedText(toLabel, 
org.openide.util.NbBundle.getMessage(
MessageContentViewer.class, 
"MessageContentViewer.toLabel.text")); 
 
  169         org.openide.awt.Mnemonics.setLocalizedText(toText, 
org.openide.util.NbBundle.getMessage(
MessageContentViewer.class, 
"MessageContentViewer.toText.text")); 
 
  170         toText.setAutoscrolls(
true);
 
  171         toText.setMinimumSize(
new java.awt.Dimension(27, 14));
 
  173         org.openide.awt.Mnemonics.setLocalizedText(ccLabel, 
org.openide.util.NbBundle.getMessage(
MessageContentViewer.class, 
"MessageContentViewer.ccLabel.text")); 
 
  175         org.openide.awt.Mnemonics.setLocalizedText(ccText, 
org.openide.util.NbBundle.getMessage(
MessageContentViewer.class, 
"MessageContentViewer.ccText.text")); 
 
  176         ccText.setMinimumSize(
new java.awt.Dimension(27, 14));
 
  178         org.openide.awt.Mnemonics.setLocalizedText(subjectLabel, 
org.openide.util.NbBundle.getMessage(
MessageContentViewer.class, 
"MessageContentViewer.subjectLabel.text")); 
 
  180         org.openide.awt.Mnemonics.setLocalizedText(subjectText, 
org.openide.util.NbBundle.getMessage(
MessageContentViewer.class, 
"MessageContentViewer.subjectText.text")); 
 
  181         subjectText.setMinimumSize(
new java.awt.Dimension(26, 14));
 
  183         directionText.setHorizontalAlignment(javax.swing.SwingConstants.RIGHT);
 
  184         org.openide.awt.Mnemonics.setLocalizedText(directionText, 
org.openide.util.NbBundle.getMessage(
MessageContentViewer.class, 
"MessageContentViewer.directionText.text")); 
 
  186         javax.swing.GroupLayout envelopePanelLayout = 
new javax.swing.GroupLayout(envelopePanel);
 
  187         envelopePanel.setLayout(envelopePanelLayout);
 
  188         envelopePanelLayout.setHorizontalGroup(
 
  189             envelopePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
 
  190             .addGroup(envelopePanelLayout.createSequentialGroup()
 
  192                 .addGroup(envelopePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
 
  193                     .addGroup(envelopePanelLayout.createSequentialGroup()
 
  194                         .addGroup(envelopePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
 
  195                             .addComponent(fromLabel)
 
  196                             .addComponent(toLabel))
 
  197                         .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
 
  198                         .addGroup(envelopePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
 
  199                             .addGroup(envelopePanelLayout.createSequentialGroup()
 
  200                                 .addComponent(toText, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
 
  201                                 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
 
  202                                 .addComponent(directionText, javax.swing.GroupLayout.PREFERRED_SIZE, 66, javax.swing.GroupLayout.PREFERRED_SIZE))
 
  203                             .addGroup(envelopePanelLayout.createSequentialGroup()
 
  204                                 .addComponent(fromText, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
 
  205                                 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
 
  206                                 .addComponent(datetimeText, javax.swing.GroupLayout.PREFERRED_SIZE, 140, javax.swing.GroupLayout.PREFERRED_SIZE))))
 
  207                     .addGroup(envelopePanelLayout.createSequentialGroup()
 
  208                         .addComponent(ccLabel)
 
  210                         .addComponent(ccText, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
 
  211                     .addGroup(envelopePanelLayout.createSequentialGroup()
 
  212                         .addComponent(subjectLabel)
 
  213                         .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
 
  214                         .addComponent(subjectText, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)))
 
  217         envelopePanelLayout.setVerticalGroup(
 
  218             envelopePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
 
  219             .addGroup(envelopePanelLayout.createSequentialGroup()
 
  221                 .addGroup(envelopePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
 
  222                     .addComponent(fromLabel)
 
  223                     .addComponent(datetimeText)
 
  224                     .addComponent(fromText))
 
  225                 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
 
  226                 .addGroup(envelopePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
 
  227                     .addComponent(toLabel)
 
  228                     .addComponent(toText, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
 
  229                     .addComponent(directionText))
 
  230                 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
 
  231                 .addGroup(envelopePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
 
  232                     .addComponent(ccLabel)
 
  233                     .addComponent(ccText, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
 
  234                 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
 
  235                 .addGroup(envelopePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
 
  236                     .addComponent(subjectLabel)
 
  237                     .addComponent(subjectText, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
 
  241         headersScrollPane.setHorizontalScrollBarPolicy(javax.swing.ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
 
  242         headersScrollPane.setVerticalScrollBarPolicy(javax.swing.ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);
 
  244         headersTextArea.setEditable(
false);
 
  245         headersTextArea.setColumns(20);
 
  246         headersTextArea.setLineWrap(
true);
 
  247         headersTextArea.setRows(5);
 
  248         headersTextArea.setWrapStyleWord(
true);
 
  249         headersScrollPane.setViewportView(headersTextArea);
 
  251         msgbodyTabbedPane.addTab(
org.openide.util.NbBundle.getMessage(
MessageContentViewer.class, 
"MessageContentViewer.headersScrollPane.TabConstraints.tabTitle"), headersScrollPane); 
 
  253         textbodyScrollPane.setHorizontalScrollBarPolicy(javax.swing.ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
 
  254         textbodyScrollPane.setVerticalScrollBarPolicy(javax.swing.ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);
 
  256         textbodyTextArea.setEditable(
false);
 
  257         textbodyTextArea.setLineWrap(
true);
 
  258         textbodyTextArea.setRows(5);
 
  259         textbodyTextArea.setWrapStyleWord(
true);
 
  260         textbodyScrollPane.setViewportView(textbodyTextArea);
 
  262         msgbodyTabbedPane.addTab(
org.openide.util.NbBundle.getMessage(
MessageContentViewer.class, 
"MessageContentViewer.textbodyScrollPane.TabConstraints.tabTitle"), textbodyScrollPane); 
 
  264         htmlScrollPane.setVerticalScrollBarPolicy(javax.swing.ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);
 
  266         htmlbodyTextPane.setEditable(
false);
 
  267         htmlScrollPane.setViewportView(htmlbodyTextPane);
 
  269         org.openide.awt.Mnemonics.setLocalizedText(showImagesToggleButton, 
"Show Images");
 
  270         showImagesToggleButton.addActionListener(
new java.awt.event.ActionListener() {
 
  271             public void actionPerformed(java.awt.event.ActionEvent evt) {
 
  272                 showImagesToggleButtonActionPerformed(evt);
 
  276         javax.swing.GroupLayout htmlPaneLayout = 
new javax.swing.GroupLayout(htmlPane);
 
  277         htmlPane.setLayout(htmlPaneLayout);
 
  278         htmlPaneLayout.setHorizontalGroup(
 
  279             htmlPaneLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
 
  280             .addComponent(htmlScrollPane)
 
  281             .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, htmlPaneLayout.createSequentialGroup()
 
  282                 .addContainerGap(533, Short.MAX_VALUE)
 
  283                 .addComponent(showImagesToggleButton)
 
  286         htmlPaneLayout.setVerticalGroup(
 
  287             htmlPaneLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
 
  288             .addGroup(htmlPaneLayout.createSequentialGroup()
 
  289                 .addComponent(showImagesToggleButton)
 
  290                 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
 
  291                 .addComponent(htmlScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, 333, Short.MAX_VALUE)
 
  295         msgbodyTabbedPane.addTab(
org.openide.util.NbBundle.getMessage(
MessageContentViewer.class, 
"MessageContentViewer.htmlPane.TabConstraints.tabTitle"), htmlPane); 
 
  297         rtfbodyScrollPane.setVerticalScrollBarPolicy(javax.swing.ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);
 
  299         rtfbodyTextPane.setEditable(
false);
 
  300         rtfbodyScrollPane.setViewportView(rtfbodyTextPane);
 
  302         msgbodyTabbedPane.addTab(
org.openide.util.NbBundle.getMessage(
MessageContentViewer.class, 
"MessageContentViewer.rtfbodyScrollPane.TabConstraints.tabTitle"), rtfbodyScrollPane); 
 
  304         org.openide.awt.Mnemonics.setLocalizedText(viewInNewWindowButton, 
org.openide.util.NbBundle.getMessage(
MessageContentViewer.class, 
"MessageContentViewer.viewInNewWindowButton.text")); 
 
  305         viewInNewWindowButton.addActionListener(
new java.awt.event.ActionListener() {
 
  306             public void actionPerformed(java.awt.event.ActionEvent evt) {
 
  307                 viewInNewWindowButtonActionPerformed(evt);
 
  311         javax.swing.GroupLayout attachmentsPanelLayout = 
new javax.swing.GroupLayout(attachmentsPanel);
 
  312         attachmentsPanel.setLayout(attachmentsPanelLayout);
 
  313         attachmentsPanelLayout.setHorizontalGroup(
 
  314             attachmentsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
 
  315             .addGroup(attachmentsPanelLayout.createSequentialGroup()
 
  317                 .addGroup(attachmentsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
 
  318                     .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, attachmentsPanelLayout.createSequentialGroup()
 
  319                         .addComponent(viewInNewWindowButton)
 
  321                     .addComponent(attachmentsScrollPane, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, 647, Short.MAX_VALUE)))
 
  323         attachmentsPanelLayout.setVerticalGroup(
 
  324             attachmentsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
 
  325             .addGroup(attachmentsPanelLayout.createSequentialGroup()
 
  327                 .addComponent(viewInNewWindowButton)
 
  328                 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
 
  329                 .addComponent(attachmentsScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, 333, Short.MAX_VALUE)
 
  333         msgbodyTabbedPane.addTab(
org.openide.util.NbBundle.getMessage(
MessageContentViewer.class, 
"MessageContentViewer.attachmentsPanel.TabConstraints.tabTitle"), attachmentsPanel); 
 
  335         javax.swing.GroupLayout layout = 
new javax.swing.GroupLayout(
this);
 
  336         this.setLayout(layout);
 
  337         layout.setHorizontalGroup(
 
  338             layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
 
  339             .addGroup(layout.createSequentialGroup()
 
  341                 .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
 
  342                     .addComponent(msgbodyTabbedPane)
 
  343                     .addComponent(envelopePanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
 
  346         layout.setVerticalGroup(
 
  347             layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
 
  348             .addGroup(layout.createSequentialGroup()
 
  350                 .addComponent(envelopePanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
 
  351                 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
 
  352                 .addComponent(msgbodyTabbedPane)
 
  358         "MessageContentViewer.showImagesToggleButton.hide.text=Hide Images",
 
  359         "MessageContentViewer.showImagesToggleButton.text=Show Images"})
 
  362             String htmlText = getAttributeValueSafe(artifact, TSK_EMAIL_CONTENT_HTML);
 
  363             if (
false == htmlText.isEmpty()) {
 
  364                 if (showImagesToggleButton.isSelected()) {
 
  365                     showImagesToggleButton.setText(Bundle.MessageContentViewer_showImagesToggleButton_hide_text());
 
  366                     this.htmlbodyTextPane.setText(wrapInHtmlBody(htmlText));
 
  368                     showImagesToggleButton.setText(Bundle.MessageContentViewer_showImagesToggleButton_text());
 
  369                     this.htmlbodyTextPane.setText(wrapInHtmlBody(cleanseHTML(htmlText)));
 
  372         } 
catch (TskCoreException ex) {
 
  373             LOGGER.log(Level.WARNING, 
"Failed to get attributes for email message.", ex); 
 
  378         new NewWindowViewAction(
"View in new window", drpExplorerManager.getSelectedNodes()[0]).actionPerformed(evt);
 
  417         artifact = node.getLookup().lookup(BlackboardArtifact.class);
 
  418         if (artifact == null) {
 
  427         if (artifact.getArtifactTypeID() == TSK_KEYWORD_HIT.getTypeID()) {
 
  429                 getAssociatedArtifact(artifact).ifPresent(associatedArtifact -> {
 
  430                     artifact = associatedArtifact;
 
  432             } 
catch (TskCoreException ex) {
 
  433                 LOGGER.log(Level.SEVERE, 
"error getting associated artifact", ex);
 
  437         if (artifact.getArtifactTypeID() == TSK_MESSAGE.getTypeID()) {
 
  439         } 
else if (artifact.getArtifactTypeID() == TSK_EMAIL_MSG.getTypeID()) {
 
  456     private static Optional<BlackboardArtifact> 
getAssociatedArtifact(
final BlackboardArtifact artifact) 
throws TskCoreException {
 
  457         BlackboardAttribute attribute = artifact.getAttribute(TSK_ASSOCIATED_TYPE);
 
  458         if (attribute != null) {
 
  459             return Optional.of(artifact.getSleuthkitCase().getArtifactByArtifactId(attribute.getValueLong()));
 
  461         return Optional.empty();
 
  465     @NbBundle.Messages(
"MessageContentViewer.title=Message")
 
  467         return Bundle.MessageContentViewer_title();
 
  471     @NbBundle.Messages(
"MessageContentViewer.toolTip=Displays messages.")
 
  473         return Bundle.MessageContentViewer_toolTip();
 
  489         fromText.setText(
"");
 
  490         fromLabel.setEnabled(
false);
 
  492         toLabel.setEnabled(
false);
 
  494         ccLabel.setEnabled(
false);
 
  495         subjectText.setText(
"");
 
  496         subjectLabel.setEnabled(
false);
 
  497         datetimeText.setText(
"");
 
  498         datetimeText.setEnabled(
false);
 
  499         directionText.setText(
"");
 
  500         directionText.setEnabled(
false);
 
  502         headersTextArea.setText(
"");
 
  503         rtfbodyTextPane.setText(
"");
 
  504         htmlbodyTextPane.setText(
"");
 
  505         textbodyTextArea.setText(
"");
 
  506         showImagesToggleButton.setEnabled(
false);
 
  507         msgbodyTabbedPane.setEnabled(
false);
 
  512         BlackboardArtifact nodeArtifact = node.getLookup().lookup(BlackboardArtifact.class);
 
  514         if (nodeArtifact == null) {
 
  518         if (nodeArtifact.getArtifactTypeID() == TSK_KEYWORD_HIT.getTypeID()) {
 
  523             } 
catch (TskCoreException ex) {
 
  524                 LOGGER.log(Level.SEVERE, 
"error getting associated artifact", ex);
 
  527         return isMessageArtifact(nodeArtifact);
 
  540         final int artifactTypeID = nodeArtifact.getArtifactTypeID();
 
  541         return artifactTypeID == TSK_EMAIL_MSG.getTypeID()
 
  542                 || artifactTypeID == TSK_MESSAGE.getTypeID();
 
  547         if (isSupported(node)) {
 
  562     private void configureTextArea(BlackboardAttribute.ATTRIBUTE_TYPE type, 
int index) 
throws TskCoreException {
 
  563         String attributeText = getAttributeValueSafe(artifact, type);
 
  565         if (index == HTML_TAB_INDEX && StringUtils.isNotBlank(attributeText)) {
 
  567             attributeText = wrapInHtmlBody(cleanseHTML(attributeText));
 
  569         JTextComponent textComponent = textAreas.get(index);
 
  570         textComponent.setText(attributeText);
 
  571         textComponent.setCaretPosition(0); 
 
  572         final boolean hasText = attributeText.length() > 0;
 
  574         msgbodyTabbedPane.setEnabledAt(index, hasText);
 
  576             msgbodyTabbedPane.setSelectedIndex(index);
 
  581         msgbodyTabbedPane.setEnabled(
true);
 
  582         fromLabel.setEnabled(
true);
 
  583         toLabel.setEnabled(
true);
 
  584         subjectLabel.setEnabled(
true);
 
  585         datetimeText.setEnabled(
true);
 
  590         final Set<AbstractFile> attachments = artifact.getChildren().stream()
 
  591                 .filter(AbstractFile.class::isInstance)
 
  592                 .map(AbstractFile.class::cast)
 
  593                 .collect(Collectors.toSet());
 
  594         final int numberOfAttachments = attachments.size();
 
  596         msgbodyTabbedPane.setEnabledAt(ATTM_TAB_INDEX, numberOfAttachments > 0);
 
  597         msgbodyTabbedPane.setTitleAt(ATTM_TAB_INDEX, 
"Attachments (" + numberOfAttachments + 
")");
 
  603         return "<html><body>" + htmlText + 
"</body></html>";
 
  607         enableCommonFields();
 
  609         directionText.setEnabled(
false);
 
  610         ccLabel.setEnabled(
true);
 
  612         showImagesToggleButton.setEnabled(
true);
 
  613         showImagesToggleButton.setText(
"Show Images");
 
  614         showImagesToggleButton.setSelected(
false);
 
  617             this.fromText.setText(getAttributeValueSafe(artifact, TSK_EMAIL_FROM));
 
  618             this.fromText.setToolTipText(getAttributeValueSafe(artifact, TSK_EMAIL_FROM));
 
  619             this.toText.setText(getAttributeValueSafe(artifact, TSK_EMAIL_TO));
 
  620             this.toText.setToolTipText(getAttributeValueSafe(artifact, TSK_EMAIL_TO));
 
  621             this.directionText.setText(
"");
 
  622             this.ccText.setText(getAttributeValueSafe(artifact, TSK_EMAIL_CC));
 
  623             this.ccText.setToolTipText(getAttributeValueSafe(artifact, TSK_EMAIL_CC));
 
  624             this.subjectText.setText(getAttributeValueSafe(artifact, TSK_SUBJECT));
 
  625             this.datetimeText.setText(getAttributeValueSafe(artifact, TSK_DATETIME_RCVD));
 
  627             configureTextArea(TSK_HEADERS, HDR_TAB_INDEX);
 
  628             configureTextArea(TSK_EMAIL_CONTENT_PLAIN, TEXT_TAB_INDEX);
 
  629             configureTextArea(TSK_EMAIL_CONTENT_HTML, HTML_TAB_INDEX);
 
  630             configureTextArea(TSK_EMAIL_CONTENT_RTF, RTF_TAB_INDEX);
 
  631             configureAttachments();
 
  632         } 
catch (TskCoreException ex) {
 
  633             LOGGER.log(Level.WARNING, 
"Failed to get attributes for email message.", ex); 
 
  638         enableCommonFields();
 
  640         directionText.setEnabled(
true);
 
  641         ccLabel.setEnabled(
false);
 
  644             this.fromText.setText(getAttributeValueSafe(artifact, TSK_PHONE_NUMBER_FROM));
 
  645             this.toText.setText(getAttributeValueSafe(artifact, TSK_PHONE_NUMBER_TO));
 
  646             this.directionText.setText(getAttributeValueSafe(artifact, TSK_DIRECTION));
 
  647             this.ccText.setText(
"");
 
  648             this.subjectText.setText(getAttributeValueSafe(artifact, TSK_SUBJECT));
 
  649             this.datetimeText.setText(getAttributeValueSafe(artifact, TSK_DATETIME));
 
  651             msgbodyTabbedPane.setEnabledAt(HTML_TAB_INDEX, 
false);
 
  652             msgbodyTabbedPane.setEnabledAt(RTF_TAB_INDEX, 
false);
 
  653             msgbodyTabbedPane.setEnabledAt(HDR_TAB_INDEX, 
false);
 
  654             msgbodyTabbedPane.setEnabledAt(HDR_TAB_INDEX, 
false);
 
  655             configureTextArea(TSK_TEXT, TEXT_TAB_INDEX);
 
  656             configureAttachments();
 
  657         } 
catch (TskCoreException ex) {
 
  658             LOGGER.log(Level.WARNING, 
"Failed to get attributes for message.", ex); 
 
  662     private static String 
getAttributeValueSafe(BlackboardArtifact artifact, BlackboardAttribute.ATTRIBUTE_TYPE type) throws TskCoreException {
 
  663         return Optional.ofNullable(artifact.getAttribute(
new BlackboardAttribute.Type(type)))
 
  664                 .map(BlackboardAttribute::getDisplayString)
 
  677         Document doc = Jsoup.parse(htmlInString);
 
  680         doc.select(
"img[src]").forEach(img -> img.attr(
"src", 
""));
 
  690             this.attachments = attachments;
 
  701             setKeys(attachments);
 
  719             Sheet sheet = 
new Sheet();
 
  720             Sheet.Set sheetSet = sheet.get(Sheet.PROPERTIES);
 
  721             if (sheetSet == null) {
 
  722                 sheetSet = Sheet.createPropertiesSet();
 
  725             AbstractFile file = getContent();
 
  726             sheetSet.put(
new NodeProperty<>(
"Name", 
"Name", 
"Name", file.getName()));
 
  727             sheetSet.put(
new NodeProperty<>(
"Size", 
"Size", 
"Size", file.getSize()));
 
  728             sheetSet.put(
new NodeProperty<>(
"Mime Type", 
"Mime Type", 
"Mime Type", StringUtils.defaultString(file.getMIMEType())));
 
  729             sheetSet.put(
new NodeProperty<>(
"Known", 
"Known", 
"Known", file.getKnown().getName()));
 
  731             addTagProperty(sheetSet);
 
javax.swing.JScrollPane textbodyScrollPane
 
final Set< AbstractFile > attachments
 
javax.swing.JPanel attachmentsPanel
 
static void configureTextPaneAsRtf(JTextPane pane)
 
final DataResultPanel drp
 
static String cleanseHTML(String htmlInString)
 
javax.swing.JScrollPane rtfbodyScrollPane
 
int isPreferred(Node node)
 
javax.swing.JLabel toLabel
 
javax.swing.JLabel ccText
 
static String getAttributeValueSafe(BlackboardArtifact artifact, BlackboardAttribute.ATTRIBUTE_TYPE type)
 
boolean isSupported(Node node)
 
static String wrapInHtmlBody(String htmlText)
 
javax.swing.JPanel envelopePanel
 
javax.swing.JLabel fromLabel
 
void configureTextArea(BlackboardAttribute.ATTRIBUTE_TYPE type, int index)
 
static boolean isMessageArtifact(BlackboardArtifact nodeArtifact)
 
ExplorerManager getExplorerManager()
 
javax.swing.JScrollPane htmlScrollPane
 
javax.swing.JTabbedPane msgbodyTabbedPane
 
javax.swing.JScrollPane headersScrollPane
 
javax.swing.JLabel fromText
 
void setNode(Node rootNode)
 
javax.swing.JLabel datetimeText
 
javax.swing.JLabel ccLabel
 
javax.swing.JLabel toText
 
static DataResultPanel createInstanceUninitialized(String title, String description, Node currentRootNode, int childNodeCount, DataContent customContentView)
 
ExplorerManager drpExplorerManager
 
static Optional< BlackboardArtifact > getAssociatedArtifact(final BlackboardArtifact artifact)
 
void showImagesToggleButtonActionPerformed(java.awt.event.ActionEvent evt)
 
javax.swing.JTextPane rtfbodyTextPane
 
javax.swing.JTextPane htmlbodyTextPane
 
javax.swing.JScrollPane attachmentsScrollPane
 
static void configureTextPaneAsHtml(JTextPane pane)
 
javax.swing.JPanel htmlPane
 
final List< JTextComponent > textAreas
 
BlackboardArtifact artifact
 
javax.swing.JLabel subjectLabel
 
javax.swing.JButton viewInNewWindowButton
 
Node[] createNodes(AbstractFile t)
 
javax.swing.JLabel directionText
 
void enableCommonFields()
 
synchronized static Logger getLogger(String name)
 
void viewInNewWindowButtonActionPerformed(java.awt.event.ActionEvent evt)
 
javax.swing.JTextArea textbodyTextArea
 
void configureAttachments()
 
javax.swing.JLabel subjectText
 
DataContentViewer createInstance()
 
javax.swing.JToggleButton showImagesToggleButton
 
final void resetComponent()
 
javax.swing.JTextArea headersTextArea