19 package org.sleuthkit.autopsy.contentviewers;
 
   21 import java.awt.Color;
 
   22 import java.awt.Component;
 
   23 import java.util.Arrays;
 
   24 import java.util.HashSet;
 
   25 import java.util.List;
 
   26 import java.util.Optional;
 
   28 import java.util.logging.Level;
 
   29 import java.util.stream.Collectors;
 
   30 import javax.swing.text.JTextComponent;
 
   31 import org.apache.commons.lang3.StringUtils;
 
   32 import org.jsoup.Jsoup;
 
   33 import org.jsoup.nodes.Document;
 
   34 import org.openide.explorer.ExplorerManager;
 
   35 import org.openide.nodes.AbstractNode;
 
   36 import org.openide.nodes.Children;
 
   37 import org.openide.nodes.Node;
 
   38 import org.openide.nodes.Sheet;
 
   39 import org.openide.util.NbBundle;
 
   40 import org.openide.util.lookup.ServiceProvider;
 
   51 import static org.
sleuthkit.datamodel.BlackboardArtifact.ARTIFACT_TYPE.TSK_EMAIL_MSG;
 
   52 import static org.
sleuthkit.datamodel.BlackboardArtifact.ARTIFACT_TYPE.TSK_KEYWORD_HIT;
 
   53 import static org.
sleuthkit.datamodel.BlackboardArtifact.ARTIFACT_TYPE.TSK_MESSAGE;
 
   55 import static org.
sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_ASSOCIATED_ARTIFACT;
 
   56 import static org.
sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME;
 
   57 import static org.
sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME_RCVD;
 
   58 import static org.
sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DIRECTION;
 
   59 import static org.
sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_EMAIL_CC;
 
   60 import static org.
sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_EMAIL_CONTENT_HTML;
 
   61 import static org.
sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_EMAIL_CONTENT_PLAIN;
 
   62 import static org.
sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_EMAIL_CONTENT_RTF;
 
   63 import static org.
sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_EMAIL_FROM;
 
   64 import static org.
sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_EMAIL_TO;
 
   65 import static org.
sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_HEADERS;
 
   66 import static org.
sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PHONE_NUMBER_FROM;
 
   67 import static org.
sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PHONE_NUMBER_TO;
 
   68 import static org.
sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_SUBJECT;
 
   69 import static org.
sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_TEXT;
 
   75 @ServiceProvider(service = DataContentViewer.class, position = 5)
 
   76 @SuppressWarnings(
"PMD.SingularField") 
 
   79     private static final long serialVersionUID = 1L;
 
   81     private static final BlackboardAttribute.Type TSK_ASSOCIATED_TYPE = 
new BlackboardAttribute.Type(TSK_ASSOCIATED_ARTIFACT);
 
   83     private static final int HDR_TAB_INDEX = 0;
 
   84     private static final int TEXT_TAB_INDEX = 1;
 
   85     private static final int HTML_TAB_INDEX = 2;
 
   86     private static final int RTF_TAB_INDEX = 3;
 
   87     private static final int ATTM_TAB_INDEX = 4;
 
  101     @NbBundle.Messages(
"MessageContentViewer.AtrachmentsPanel.title=Attachments")
 
  104         htmlPane.add(htmlPanel);
 
  105         envelopePanel.setBackground(
new Color(0, 0, 0, 38));
 
  107         attachmentsScrollPane.setViewportView(drp);
 
  108         msgbodyTabbedPane.setEnabledAt(ATTM_TAB_INDEX, 
true);
 
  114         textAreas = Arrays.asList(headersTextArea, textbodyTextArea, null, rtfbodyTextPane);
 
  127         drpExplorerManager.addPropertyChangeListener(evt
 
  128                 -> viewInNewWindowButton.setEnabled(drpExplorerManager.getSelectedNodes().length == 1));
 
  136     @SuppressWarnings(
"unchecked")
 
  138     private 
void initComponents() {
 
  140         envelopePanel = 
new javax.swing.JPanel();
 
  141         fromLabel = 
new javax.swing.JLabel();
 
  142         datetimeText = 
new javax.swing.JLabel();
 
  143         fromText = 
new javax.swing.JLabel();
 
  144         toLabel = 
new javax.swing.JLabel();
 
  145         toText = 
new javax.swing.JLabel();
 
  146         ccLabel = 
new javax.swing.JLabel();
 
  147         ccText = 
new javax.swing.JLabel();
 
  148         subjectLabel = 
new javax.swing.JLabel();
 
  149         subjectText = 
new javax.swing.JLabel();
 
  150         directionText = 
new javax.swing.JLabel();
 
  151         msgbodyTabbedPane = 
new javax.swing.JTabbedPane();
 
  152         headersScrollPane = 
new javax.swing.JScrollPane();
 
  153         headersTextArea = 
new javax.swing.JTextArea();
 
  154         textbodyScrollPane = 
new javax.swing.JScrollPane();
 
  155         textbodyTextArea = 
new javax.swing.JTextArea();
 
  156         htmlPane = 
new javax.swing.JPanel();
 
  157         rtfbodyScrollPane = 
new javax.swing.JScrollPane();
 
  158         rtfbodyTextPane = 
new javax.swing.JTextPane();
 
  159         attachmentsPanel = 
new javax.swing.JPanel();
 
  160         viewInNewWindowButton = 
new javax.swing.JButton();
 
  161         attachmentsScrollPane = 
new javax.swing.JScrollPane();
 
  163         envelopePanel.setBackground(
new java.awt.Color(204, 204, 204));
 
  165         org.openide.awt.Mnemonics.setLocalizedText(fromLabel, 
org.openide.util.NbBundle.getMessage(
MessageContentViewer.class, 
"MessageContentViewer.fromLabel.text")); 
 
  167         datetimeText.setHorizontalAlignment(javax.swing.SwingConstants.RIGHT);
 
  168         org.openide.awt.Mnemonics.setLocalizedText(datetimeText, 
org.openide.util.NbBundle.getMessage(
MessageContentViewer.class, 
"MessageContentViewer.datetimeText.text")); 
 
  170         org.openide.awt.Mnemonics.setLocalizedText(fromText, 
org.openide.util.NbBundle.getMessage(
MessageContentViewer.class, 
"MessageContentViewer.fromText.text")); 
 
  172         org.openide.awt.Mnemonics.setLocalizedText(toLabel, 
org.openide.util.NbBundle.getMessage(
MessageContentViewer.class, 
"MessageContentViewer.toLabel.text")); 
 
  174         org.openide.awt.Mnemonics.setLocalizedText(toText, 
org.openide.util.NbBundle.getMessage(
MessageContentViewer.class, 
"MessageContentViewer.toText.text")); 
 
  175         toText.setAutoscrolls(
true);
 
  176         toText.setMinimumSize(
new java.awt.Dimension(27, 14));
 
  178         org.openide.awt.Mnemonics.setLocalizedText(ccLabel, 
org.openide.util.NbBundle.getMessage(
MessageContentViewer.class, 
"MessageContentViewer.ccLabel.text")); 
 
  180         org.openide.awt.Mnemonics.setLocalizedText(ccText, 
org.openide.util.NbBundle.getMessage(
MessageContentViewer.class, 
"MessageContentViewer.ccText.text")); 
 
  181         ccText.setMinimumSize(
new java.awt.Dimension(27, 14));
 
  183         org.openide.awt.Mnemonics.setLocalizedText(subjectLabel, 
org.openide.util.NbBundle.getMessage(
MessageContentViewer.class, 
"MessageContentViewer.subjectLabel.text")); 
 
  185         org.openide.awt.Mnemonics.setLocalizedText(subjectText, 
org.openide.util.NbBundle.getMessage(
MessageContentViewer.class, 
"MessageContentViewer.subjectText.text")); 
 
  186         subjectText.setMinimumSize(
new java.awt.Dimension(26, 14));
 
  188         directionText.setHorizontalAlignment(javax.swing.SwingConstants.RIGHT);
 
  189         org.openide.awt.Mnemonics.setLocalizedText(directionText, 
org.openide.util.NbBundle.getMessage(
MessageContentViewer.class, 
"MessageContentViewer.directionText.text")); 
 
  191         javax.swing.GroupLayout envelopePanelLayout = 
new javax.swing.GroupLayout(envelopePanel);
 
  192         envelopePanel.setLayout(envelopePanelLayout);
 
  193         envelopePanelLayout.setHorizontalGroup(
 
  194             envelopePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
 
  195             .addGroup(envelopePanelLayout.createSequentialGroup()
 
  197                 .addGroup(envelopePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
 
  198                     .addGroup(envelopePanelLayout.createSequentialGroup()
 
  199                         .addGroup(envelopePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
 
  200                             .addComponent(fromLabel)
 
  201                             .addComponent(toLabel))
 
  202                         .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
 
  203                         .addGroup(envelopePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
 
  204                             .addGroup(envelopePanelLayout.createSequentialGroup()
 
  205                                 .addComponent(toText, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
 
  206                                 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
 
  207                                 .addComponent(directionText, javax.swing.GroupLayout.PREFERRED_SIZE, 66, javax.swing.GroupLayout.PREFERRED_SIZE))
 
  208                             .addGroup(envelopePanelLayout.createSequentialGroup()
 
  209                                 .addComponent(fromText, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
 
  210                                 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
 
  211                                 .addComponent(datetimeText, javax.swing.GroupLayout.PREFERRED_SIZE, 140, javax.swing.GroupLayout.PREFERRED_SIZE))))
 
  212                     .addGroup(envelopePanelLayout.createSequentialGroup()
 
  213                         .addComponent(ccLabel)
 
  215                         .addComponent(ccText, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
 
  216                     .addGroup(envelopePanelLayout.createSequentialGroup()
 
  217                         .addComponent(subjectLabel)
 
  218                         .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
 
  219                         .addComponent(subjectText, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)))
 
  222         envelopePanelLayout.setVerticalGroup(
 
  223             envelopePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
 
  224             .addGroup(envelopePanelLayout.createSequentialGroup()
 
  226                 .addGroup(envelopePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
 
  227                     .addComponent(fromLabel)
 
  228                     .addComponent(datetimeText)
 
  229                     .addComponent(fromText))
 
  230                 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
 
  231                 .addGroup(envelopePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
 
  232                     .addComponent(toLabel)
 
  233                     .addComponent(toText, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
 
  234                     .addComponent(directionText))
 
  235                 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
 
  236                 .addGroup(envelopePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
 
  237                     .addComponent(ccLabel)
 
  238                     .addComponent(ccText, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
 
  239                 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
 
  240                 .addGroup(envelopePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
 
  241                     .addComponent(subjectLabel)
 
  242                     .addComponent(subjectText, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
 
  246         headersScrollPane.setHorizontalScrollBarPolicy(javax.swing.ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
 
  247         headersScrollPane.setVerticalScrollBarPolicy(javax.swing.ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);
 
  249         headersTextArea.setEditable(
false);
 
  250         headersTextArea.setColumns(20);
 
  251         headersTextArea.setLineWrap(
true);
 
  252         headersTextArea.setRows(5);
 
  253         headersTextArea.setWrapStyleWord(
true);
 
  254         headersScrollPane.setViewportView(headersTextArea);
 
  256         msgbodyTabbedPane.addTab(
org.openide.util.NbBundle.getMessage(
MessageContentViewer.class, 
"MessageContentViewer.headersScrollPane.TabConstraints.tabTitle"), headersScrollPane); 
 
  258         textbodyScrollPane.setHorizontalScrollBarPolicy(javax.swing.ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
 
  259         textbodyScrollPane.setVerticalScrollBarPolicy(javax.swing.ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);
 
  261         textbodyTextArea.setEditable(
false);
 
  262         textbodyTextArea.setLineWrap(
true);
 
  263         textbodyTextArea.setRows(5);
 
  264         textbodyTextArea.setWrapStyleWord(
true);
 
  265         textbodyScrollPane.setViewportView(textbodyTextArea);
 
  267         msgbodyTabbedPane.addTab(
org.openide.util.NbBundle.getMessage(
MessageContentViewer.class, 
"MessageContentViewer.textbodyScrollPane.TabConstraints.tabTitle"), textbodyScrollPane); 
 
  269         htmlPane.setLayout(
new java.awt.BorderLayout());
 
  270         msgbodyTabbedPane.addTab(
org.openide.util.NbBundle.getMessage(
MessageContentViewer.class, 
"MessageContentViewer.htmlPane.TabConstraints.tabTitle"), htmlPane); 
 
  272         rtfbodyScrollPane.setVerticalScrollBarPolicy(javax.swing.ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);
 
  274         rtfbodyTextPane.setEditable(
false);
 
  275         rtfbodyScrollPane.setViewportView(rtfbodyTextPane);
 
  277         msgbodyTabbedPane.addTab(
org.openide.util.NbBundle.getMessage(
MessageContentViewer.class, 
"MessageContentViewer.rtfbodyScrollPane.TabConstraints.tabTitle"), rtfbodyScrollPane); 
 
  279         org.openide.awt.Mnemonics.setLocalizedText(viewInNewWindowButton, 
org.openide.util.NbBundle.getMessage(
MessageContentViewer.class, 
"MessageContentViewer.viewInNewWindowButton.text")); 
 
  280         viewInNewWindowButton.addActionListener(
new java.awt.event.ActionListener() {
 
  281             public void actionPerformed(java.awt.event.ActionEvent evt) {
 
  282                 viewInNewWindowButtonActionPerformed(evt);
 
  286         javax.swing.GroupLayout attachmentsPanelLayout = 
new javax.swing.GroupLayout(attachmentsPanel);
 
  287         attachmentsPanel.setLayout(attachmentsPanelLayout);
 
  288         attachmentsPanelLayout.setHorizontalGroup(
 
  289             attachmentsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
 
  290             .addGroup(attachmentsPanelLayout.createSequentialGroup()
 
  292                 .addGroup(attachmentsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
 
  293                     .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, attachmentsPanelLayout.createSequentialGroup()
 
  294                         .addComponent(viewInNewWindowButton)
 
  296                     .addComponent(attachmentsScrollPane, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, 647, Short.MAX_VALUE)))
 
  298         attachmentsPanelLayout.setVerticalGroup(
 
  299             attachmentsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
 
  300             .addGroup(attachmentsPanelLayout.createSequentialGroup()
 
  302                 .addComponent(viewInNewWindowButton)
 
  303                 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
 
  304                 .addComponent(attachmentsScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, 333, Short.MAX_VALUE)
 
  308         msgbodyTabbedPane.addTab(
org.openide.util.NbBundle.getMessage(
MessageContentViewer.class, 
"MessageContentViewer.attachmentsPanel.TabConstraints.tabTitle"), attachmentsPanel); 
 
  310         javax.swing.GroupLayout layout = 
new javax.swing.GroupLayout(
this);
 
  311         this.setLayout(layout);
 
  312         layout.setHorizontalGroup(
 
  313             layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
 
  314             .addGroup(layout.createSequentialGroup()
 
  316                 .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
 
  317                     .addComponent(msgbodyTabbedPane)
 
  318                     .addComponent(envelopePanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
 
  321         layout.setVerticalGroup(
 
  322             layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
 
  323             .addGroup(layout.createSequentialGroup()
 
  325                 .addComponent(envelopePanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
 
  326                 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
 
  327                 .addComponent(msgbodyTabbedPane)
 
  333         new NewWindowViewAction(
"View in new window", drpExplorerManager.getSelectedNodes()[0]).actionPerformed(evt);
 
  369         artifact = node.getLookup().lookup(BlackboardArtifact.class);
 
  370         if (artifact == null) {
 
  379         if (artifact.getArtifactTypeID() == TSK_KEYWORD_HIT.getTypeID()) {
 
  381                 getAssociatedArtifact(artifact).ifPresent(associatedArtifact -> {
 
  382                     artifact = associatedArtifact;
 
  384             } 
catch (TskCoreException ex) {
 
  385                 LOGGER.log(Level.SEVERE, 
"error getting associated artifact", ex);
 
  389         if (artifact.getArtifactTypeID() == TSK_MESSAGE.getTypeID()) {
 
  391         } 
else if (artifact.getArtifactTypeID() == TSK_EMAIL_MSG.getTypeID()) {
 
  408     private static Optional<BlackboardArtifact> 
getAssociatedArtifact(
final BlackboardArtifact artifact) 
throws TskCoreException {
 
  409         BlackboardAttribute attribute = artifact.getAttribute(TSK_ASSOCIATED_TYPE);
 
  410         if (attribute != null) {
 
  411             return Optional.of(artifact.getSleuthkitCase().getArtifactByArtifactId(attribute.getValueLong()));
 
  413         return Optional.empty();
 
  417     @NbBundle.Messages(
"MessageContentViewer.title=Message")
 
  419         return Bundle.MessageContentViewer_title();
 
  423     @NbBundle.Messages(
"MessageContentViewer.toolTip=Displays messages.")
 
  425         return Bundle.MessageContentViewer_toolTip();
 
  441         fromText.setText(
"");
 
  442         fromLabel.setEnabled(
false);
 
  444         toLabel.setEnabled(
false);
 
  446         ccLabel.setEnabled(
false);
 
  447         subjectText.setText(
"");
 
  448         subjectLabel.setEnabled(
false);
 
  449         datetimeText.setText(
"");
 
  450         datetimeText.setEnabled(
false);
 
  451         directionText.setText(
"");
 
  452         directionText.setEnabled(
false);
 
  454         headersTextArea.setText(
"");
 
  455         rtfbodyTextPane.setText(
"");
 
  457         textbodyTextArea.setText(
"");
 
  458         msgbodyTabbedPane.setEnabled(
false);
 
  464         BlackboardArtifact nodeArtifact = node.getLookup().lookup(BlackboardArtifact.class);
 
  466         if (nodeArtifact == null) {
 
  470         if (nodeArtifact.getArtifactTypeID() == TSK_KEYWORD_HIT.getTypeID()) {
 
  475             } 
catch (TskCoreException ex) {
 
  476                 LOGGER.log(Level.SEVERE, 
"error getting associated artifact", ex);
 
  479         return isMessageArtifact(nodeArtifact);
 
  492         final int artifactTypeID = nodeArtifact.getArtifactTypeID();
 
  493         return artifactTypeID == TSK_EMAIL_MSG.getTypeID()
 
  494                 || artifactTypeID == TSK_MESSAGE.getTypeID();
 
  499         if (isSupported(node)) {
 
  514     private void configureTextArea(BlackboardAttribute.ATTRIBUTE_TYPE type, 
int index) 
throws TskCoreException {
 
  515         String attributeText = getAttributeValueSafe(artifact, type);
 
  517         if (index == HTML_TAB_INDEX && StringUtils.isNotBlank(attributeText)) {
 
  518             htmlPanel.setHtmlText(attributeText);
 
  520             JTextComponent textComponent = textAreas.get(index);
 
  521             if (textComponent != null) {
 
  522                 textComponent.setText(attributeText);
 
  523                 textComponent.setCaretPosition(0); 
 
  527         final boolean hasText = attributeText.length() > 0;
 
  529         msgbodyTabbedPane.setEnabledAt(index, hasText);
 
  531             msgbodyTabbedPane.setSelectedIndex(index);
 
  536         msgbodyTabbedPane.setEnabled(
true);
 
  537         fromLabel.setEnabled(
true);
 
  538         toLabel.setEnabled(
true);
 
  539         subjectLabel.setEnabled(
true);
 
  540         datetimeText.setEnabled(
true);
 
  545         final Set<AbstractFile> attachments = artifact.getChildren().stream()
 
  546                 .filter(AbstractFile.class::isInstance)
 
  547                 .map(AbstractFile.class::cast)
 
  548                 .collect(Collectors.toSet());
 
  549         final int numberOfAttachments = attachments.size();
 
  551         msgbodyTabbedPane.setEnabledAt(ATTM_TAB_INDEX, numberOfAttachments > 0);
 
  552         msgbodyTabbedPane.setTitleAt(ATTM_TAB_INDEX, 
"Attachments (" + numberOfAttachments + 
")");
 
  558         return "<html><body>" + htmlText + 
"</body></html>";
 
  562         enableCommonFields();
 
  564         directionText.setEnabled(
false);
 
  565         ccLabel.setEnabled(
true);
 
  568             this.fromText.setText(getAttributeValueSafe(artifact, TSK_EMAIL_FROM));
 
  569             this.fromText.setToolTipText(getAttributeValueSafe(artifact, TSK_EMAIL_FROM));
 
  570             this.toText.setText(getAttributeValueSafe(artifact, TSK_EMAIL_TO));
 
  571             this.toText.setToolTipText(getAttributeValueSafe(artifact, TSK_EMAIL_TO));
 
  572             this.directionText.setText(
"");
 
  573             this.ccText.setText(getAttributeValueSafe(artifact, TSK_EMAIL_CC));
 
  574             this.ccText.setToolTipText(getAttributeValueSafe(artifact, TSK_EMAIL_CC));
 
  575             this.subjectText.setText(getAttributeValueSafe(artifact, TSK_SUBJECT));
 
  576             this.datetimeText.setText(getAttributeValueSafe(artifact, TSK_DATETIME_RCVD));
 
  578             configureTextArea(TSK_HEADERS, HDR_TAB_INDEX);
 
  579             configureTextArea(TSK_EMAIL_CONTENT_PLAIN, TEXT_TAB_INDEX);
 
  580             configureTextArea(TSK_EMAIL_CONTENT_HTML, HTML_TAB_INDEX);
 
  581             configureTextArea(TSK_EMAIL_CONTENT_RTF, RTF_TAB_INDEX);
 
  582             configureAttachments();
 
  583         } 
catch (TskCoreException ex) {
 
  584             LOGGER.log(Level.WARNING, 
"Failed to get attributes for email message.", ex); 
 
  589         enableCommonFields();
 
  591         directionText.setEnabled(
true);
 
  592         ccLabel.setEnabled(
false);
 
  595             this.fromText.setText(getAttributeValueSafe(artifact, TSK_PHONE_NUMBER_FROM));
 
  596             this.toText.setText(getAttributeValueSafe(artifact, TSK_PHONE_NUMBER_TO));
 
  597             this.directionText.setText(getAttributeValueSafe(artifact, TSK_DIRECTION));
 
  598             this.ccText.setText(
"");
 
  599             this.subjectText.setText(getAttributeValueSafe(artifact, TSK_SUBJECT));
 
  600             this.datetimeText.setText(getAttributeValueSafe(artifact, TSK_DATETIME));
 
  602             msgbodyTabbedPane.setEnabledAt(HTML_TAB_INDEX, 
false);
 
  603             msgbodyTabbedPane.setEnabledAt(RTF_TAB_INDEX, 
false);
 
  604             msgbodyTabbedPane.setEnabledAt(HDR_TAB_INDEX, 
false);
 
  605             msgbodyTabbedPane.setEnabledAt(HDR_TAB_INDEX, 
false);
 
  606             configureTextArea(TSK_TEXT, TEXT_TAB_INDEX);
 
  607             configureAttachments();
 
  608         } 
catch (TskCoreException ex) {
 
  609             LOGGER.log(Level.WARNING, 
"Failed to get attributes for message.", ex); 
 
  613     private static String 
getAttributeValueSafe(BlackboardArtifact artifact, BlackboardAttribute.ATTRIBUTE_TYPE type) throws TskCoreException {
 
  614         return Optional.ofNullable(artifact.getAttribute(
new BlackboardAttribute.Type(type)))
 
  615                 .map(BlackboardAttribute::getDisplayString)
 
  628         Document doc = Jsoup.parse(htmlInString);
 
  631         doc.select(
"img[src]").forEach(img -> img.attr(
"src", 
""));
 
  641             this.attachments = attachments;
 
  652             setKeys(attachments);
 
  670             Sheet sheet = super.createSheet();
 
  671             Set<String> keepProps = 
new HashSet<>(Arrays.asList(
 
  681             Sheet.Set sheetSet = sheet.get(Sheet.PROPERTIES);
 
  682             for (Property<?> p : sheetSet.getProperties()) {
 
  683                 if (!keepProps.contains(p.getName())) {
 
  684                     sheetSet.remove(p.getName());
 
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.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)
 
javax.swing.JTextPane rtfbodyTextPane
 
javax.swing.JScrollPane attachmentsScrollPane
 
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()
 
final void resetComponent()
 
javax.swing.JTextArea headersTextArea