19 package org.sleuthkit.autopsy.contentviewers.artifactviewers;
 
   22 import java.awt.Color;
 
   23 import java.awt.Component;
 
   24 import java.awt.ComponentOrientation;
 
   25 import java.util.Arrays;
 
   26 import java.util.Collection;
 
   27 import java.util.HashSet;
 
   28 import java.util.List;
 
   29 import java.util.Optional;
 
   31 import java.util.logging.Level;
 
   32 import javax.swing.JScrollPane;
 
   33 import javax.swing.text.JTextComponent;
 
   34 import org.apache.commons.lang3.StringUtils;
 
   35 import org.jsoup.Jsoup;
 
   36 import org.jsoup.nodes.Document;
 
   37 import org.openide.explorer.ExplorerManager;
 
   38 import org.openide.nodes.AbstractNode;
 
   39 import org.openide.nodes.Children;
 
   40 import org.openide.nodes.Node;
 
   41 import org.openide.util.NbBundle;
 
   42 import org.openide.util.lookup.ServiceProvider;
 
   55 import static org.
sleuthkit.datamodel.BlackboardArtifact.ARTIFACT_TYPE.TSK_EMAIL_MSG;
 
   56 import static org.
sleuthkit.datamodel.BlackboardArtifact.ARTIFACT_TYPE.TSK_KEYWORD_HIT;
 
   57 import static org.
sleuthkit.datamodel.BlackboardArtifact.ARTIFACT_TYPE.TSK_MESSAGE;
 
   59 import static org.
sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_ASSOCIATED_ARTIFACT;
 
   60 import static org.
sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME;
 
   61 import static org.
sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME_RCVD;
 
   62 import static org.
sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DIRECTION;
 
   63 import static org.
sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_EMAIL_CC;
 
   64 import static org.
sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_EMAIL_CONTENT_HTML;
 
   65 import static org.
sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_EMAIL_CONTENT_PLAIN;
 
   66 import static org.
sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_EMAIL_CONTENT_RTF;
 
   67 import static org.
sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_EMAIL_FROM;
 
   68 import static org.
sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_EMAIL_TO;
 
   69 import static org.
sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_HEADERS;
 
   70 import static org.
sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PHONE_NUMBER_FROM;
 
   71 import static org.
sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PHONE_NUMBER_TO;
 
   72 import static org.
sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_SUBJECT;
 
   73 import static org.
sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_TEXT;
 
   76 import org.
sleuthkit.datamodel.blackboardutils.attributes.BlackboardJsonAttrUtil;
 
   77 import org.
sleuthkit.datamodel.blackboardutils.attributes.MessageAttachments;
 
   78 import org.
sleuthkit.datamodel.blackboardutils.attributes.MessageAttachments.FileAttachment;
 
   79 import org.
sleuthkit.datamodel.blackboardutils.attributes.MessageAttachments.Attachment;
 
   80 import org.
sleuthkit.datamodel.blackboardutils.attributes.MessageAttachments.URLAttachment;
 
   85 @ServiceProvider(service = ArtifactContentViewer.class)
 
   86 @SuppressWarnings(
"PMD.SingularField") 
 
   95         private final Component rootComponent;
 
  100             childTextComponent.setEditable(
false);
 
  102             JScrollPane parentComponent = 
new JScrollPane();
 
  103             parentComponent.setHorizontalScrollBarPolicy(javax.swing.ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
 
  104             parentComponent.setVerticalScrollBarPolicy(javax.swing.ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED);
 
  105             parentComponent.setViewportView(childTextComponent);
 
  106             rootComponent = parentComponent;
 
  110         public Component getRootComponent() {
 
  111             return rootComponent;
 
  116             childTextComponent.
setText(content == null ? 
"" : content);
 
  117             childTextComponent.setComponentOrientation(orientation);
 
  118             childTextComponent.setCaretPosition(0);
 
  122     private static final long serialVersionUID = 1L;
 
  124     private static final BlackboardAttribute.Type TSK_ASSOCIATED_TYPE = 
new BlackboardAttribute.Type(TSK_ASSOCIATED_ARTIFACT);
 
  126     private static final int HDR_TAB_INDEX = 0;
 
  127     private static final int TEXT_TAB_INDEX = 1;
 
  128     private static final int HTML_TAB_INDEX = 2;
 
  129     private static final int RTF_TAB_INDEX = 3;
 
  130     private static final int ATTM_TAB_INDEX = 4;
 
  131     private static final int ACCT_TAB_INDEX = 5;
 
  146         this.textAreas = textAreas;
 
  153     @NbBundle.Messages(
"MessageArtifactViewer.AttachmentPanel.title=Attachments")
 
  156         accountsPanel = 
new MessageAccountPanel();
 
  158         htmlPane.add(htmlPanel);
 
  159         envelopePanel.setBackground(
new Color(0, 0, 0, 38));
 
  161         attachmentsScrollPane.setViewportView(drp);
 
  163         msgbodyTabbedPane.insertTab(NbBundle.getMessage(
MessageArtifactViewer.class, 
"MessageArtifactViewer.textbodyScrollPane.TabConstraints.tabTitle"),
 
  169         msgbodyTabbedPane.setEnabledAt(ATTM_TAB_INDEX, 
true);
 
  171         accountScrollPane.setViewportView(accountsPanel);
 
  178         textAreas = Arrays.asList(headersTextArea, null, null, rtfbodyTextPane);
 
  191         drpExplorerManager.addPropertyChangeListener(evt
 
  192                 -> viewInNewWindowButton.setEnabled(drpExplorerManager.getSelectedNodes().length == 1));
 
  200     @SuppressWarnings(
"unchecked")
 
  202     private 
void initComponents() {
 
  204         envelopePanel = 
new javax.swing.JPanel();
 
  205         fromLabel = 
new javax.swing.JLabel();
 
  206         datetimeText = 
new javax.swing.JLabel();
 
  207         fromText = 
new javax.swing.JLabel();
 
  208         toLabel = 
new javax.swing.JLabel();
 
  209         toText = 
new javax.swing.JLabel();
 
  210         ccLabel = 
new javax.swing.JLabel();
 
  211         ccText = 
new javax.swing.JLabel();
 
  212         subjectLabel = 
new javax.swing.JLabel();
 
  213         subjectText = 
new javax.swing.JLabel();
 
  214         directionText = 
new javax.swing.JLabel();
 
  215         msgbodyTabbedPane = 
new javax.swing.JTabbedPane();
 
  216         headersScrollPane = 
new javax.swing.JScrollPane();
 
  217         headersTextArea = 
new javax.swing.JTextArea();
 
  218         htmlPane = 
new javax.swing.JPanel();
 
  219         rtfbodyScrollPane = 
new javax.swing.JScrollPane();
 
  220         rtfbodyTextPane = 
new javax.swing.JTextPane();
 
  221         attachmentsPanel = 
new javax.swing.JPanel();
 
  222         viewInNewWindowButton = 
new javax.swing.JButton();
 
  223         attachmentsScrollPane = 
new javax.swing.JScrollPane();
 
  224         accountsTab = 
new javax.swing.JPanel();
 
  225         accountScrollPane = 
new javax.swing.JScrollPane();
 
  227         envelopePanel.setBackground(
new java.awt.Color(204, 204, 204));
 
  229         org.openide.awt.Mnemonics.setLocalizedText(fromLabel, 
org.openide.util.NbBundle.getMessage(
MessageArtifactViewer.class, 
"MessageArtifactViewer.fromLabel.text")); 
 
  231         datetimeText.setHorizontalAlignment(javax.swing.SwingConstants.RIGHT);
 
  232         org.openide.awt.Mnemonics.setLocalizedText(datetimeText, 
org.openide.util.NbBundle.getMessage(
MessageArtifactViewer.class, 
"MessageArtifactViewer.datetimeText.text")); 
 
  234         org.openide.awt.Mnemonics.setLocalizedText(fromText, 
org.openide.util.NbBundle.getMessage(
MessageArtifactViewer.class, 
"MessageArtifactViewer.fromText.text")); 
 
  236         org.openide.awt.Mnemonics.setLocalizedText(toLabel, 
org.openide.util.NbBundle.getMessage(
MessageArtifactViewer.class, 
"MessageArtifactViewer.toLabel.text")); 
 
  238         org.openide.awt.Mnemonics.setLocalizedText(toText, 
org.openide.util.NbBundle.getMessage(
MessageArtifactViewer.class, 
"MessageArtifactViewer.toText.text")); 
 
  239         toText.setAutoscrolls(
true);
 
  240         toText.setMinimumSize(
new java.awt.Dimension(27, 14));
 
  242         org.openide.awt.Mnemonics.setLocalizedText(ccLabel, 
org.openide.util.NbBundle.getMessage(
MessageArtifactViewer.class, 
"MessageArtifactViewer.ccLabel.text")); 
 
  244         org.openide.awt.Mnemonics.setLocalizedText(ccText, 
org.openide.util.NbBundle.getMessage(
MessageArtifactViewer.class, 
"MessageArtifactViewer.ccText.text")); 
 
  245         ccText.setMinimumSize(
new java.awt.Dimension(27, 14));
 
  247         org.openide.awt.Mnemonics.setLocalizedText(subjectLabel, 
org.openide.util.NbBundle.getMessage(
MessageArtifactViewer.class, 
"MessageArtifactViewer.subjectLabel.text")); 
 
  249         org.openide.awt.Mnemonics.setLocalizedText(subjectText, 
org.openide.util.NbBundle.getMessage(
MessageArtifactViewer.class, 
"MessageArtifactViewer.subjectText.text")); 
 
  250         subjectText.setMinimumSize(
new java.awt.Dimension(26, 14));
 
  252         directionText.setHorizontalAlignment(javax.swing.SwingConstants.RIGHT);
 
  253         org.openide.awt.Mnemonics.setLocalizedText(directionText, 
org.openide.util.NbBundle.getMessage(
MessageArtifactViewer.class, 
"MessageArtifactViewer.directionText.text")); 
 
  255         javax.swing.GroupLayout envelopePanelLayout = 
new javax.swing.GroupLayout(envelopePanel);
 
  256         envelopePanel.setLayout(envelopePanelLayout);
 
  257         envelopePanelLayout.setHorizontalGroup(
 
  258             envelopePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
 
  259             .addGroup(envelopePanelLayout.createSequentialGroup()
 
  261                 .addGroup(envelopePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
 
  262                     .addGroup(envelopePanelLayout.createSequentialGroup()
 
  263                         .addGroup(envelopePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
 
  264                             .addComponent(fromLabel)
 
  265                             .addComponent(toLabel))
 
  266                         .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
 
  267                         .addGroup(envelopePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
 
  268                             .addGroup(envelopePanelLayout.createSequentialGroup()
 
  269                                 .addComponent(toText, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
 
  270                                 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
 
  271                                 .addComponent(directionText, javax.swing.GroupLayout.PREFERRED_SIZE, 66, javax.swing.GroupLayout.PREFERRED_SIZE))
 
  272                             .addGroup(envelopePanelLayout.createSequentialGroup()
 
  273                                 .addComponent(fromText, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
 
  274                                 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
 
  275                                 .addComponent(datetimeText, javax.swing.GroupLayout.PREFERRED_SIZE, 140, javax.swing.GroupLayout.PREFERRED_SIZE))))
 
  276                     .addGroup(envelopePanelLayout.createSequentialGroup()
 
  277                         .addComponent(ccLabel)
 
  279                         .addComponent(ccText, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
 
  280                     .addGroup(envelopePanelLayout.createSequentialGroup()
 
  281                         .addComponent(subjectLabel)
 
  282                         .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
 
  283                         .addComponent(subjectText, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)))
 
  286         envelopePanelLayout.setVerticalGroup(
 
  287             envelopePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
 
  288             .addGroup(envelopePanelLayout.createSequentialGroup()
 
  290                 .addGroup(envelopePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
 
  291                     .addComponent(fromLabel)
 
  292                     .addComponent(datetimeText)
 
  293                     .addComponent(fromText))
 
  294                 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
 
  295                 .addGroup(envelopePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
 
  296                     .addComponent(toLabel)
 
  297                     .addComponent(toText, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
 
  298                     .addComponent(directionText))
 
  299                 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
 
  300                 .addGroup(envelopePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
 
  301                     .addComponent(ccLabel)
 
  302                     .addComponent(ccText, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
 
  303                 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
 
  304                 .addGroup(envelopePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
 
  305                     .addComponent(subjectLabel)
 
  306                     .addComponent(subjectText, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
 
  310         headersScrollPane.setHorizontalScrollBarPolicy(javax.swing.ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
 
  311         headersScrollPane.setVerticalScrollBarPolicy(javax.swing.ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);
 
  313         headersTextArea.setEditable(
false);
 
  314         headersTextArea.setColumns(20);
 
  315         headersTextArea.setLineWrap(
true);
 
  316         headersTextArea.setRows(5);
 
  317         headersTextArea.setWrapStyleWord(
true);
 
  318         headersScrollPane.setViewportView(headersTextArea);
 
  320         msgbodyTabbedPane.addTab(
org.openide.util.NbBundle.getMessage(
MessageArtifactViewer.class, 
"MessageArtifactViewer.headersScrollPane.TabConstraints.tabTitle"), headersScrollPane); 
 
  322         htmlPane.setLayout(
new java.awt.BorderLayout());
 
  323         msgbodyTabbedPane.addTab(
org.openide.util.NbBundle.getMessage(
MessageArtifactViewer.class, 
"MessageArtifactViewer.htmlPane.TabConstraints.tabTitle"), htmlPane); 
 
  325         rtfbodyScrollPane.setVerticalScrollBarPolicy(javax.swing.ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);
 
  327         rtfbodyTextPane.setEditable(
false);
 
  328         rtfbodyScrollPane.setViewportView(rtfbodyTextPane);
 
  330         msgbodyTabbedPane.addTab(
org.openide.util.NbBundle.getMessage(
MessageArtifactViewer.class, 
"MessageArtifactViewer.rtfbodyScrollPane.TabConstraints.tabTitle"), rtfbodyScrollPane); 
 
  332         org.openide.awt.Mnemonics.setLocalizedText(viewInNewWindowButton, 
org.openide.util.NbBundle.getMessage(
MessageArtifactViewer.class, 
"MessageArtifactViewer.viewInNewWindowButton.text")); 
 
  333         viewInNewWindowButton.addActionListener(
new java.awt.event.ActionListener() {
 
  334             public void actionPerformed(java.awt.event.ActionEvent evt) {
 
  335                 viewInNewWindowButtonActionPerformed(evt);
 
  339         javax.swing.GroupLayout attachmentsPanelLayout = 
new javax.swing.GroupLayout(attachmentsPanel);
 
  340         attachmentsPanel.setLayout(attachmentsPanelLayout);
 
  341         attachmentsPanelLayout.setHorizontalGroup(
 
  342             attachmentsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
 
  343             .addGroup(attachmentsPanelLayout.createSequentialGroup()
 
  345                 .addGroup(attachmentsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
 
  346                     .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, attachmentsPanelLayout.createSequentialGroup()
 
  347                         .addComponent(viewInNewWindowButton)
 
  349                     .addComponent(attachmentsScrollPane, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, 647, Short.MAX_VALUE)))
 
  351         attachmentsPanelLayout.setVerticalGroup(
 
  352             attachmentsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
 
  353             .addGroup(attachmentsPanelLayout.createSequentialGroup()
 
  355                 .addComponent(viewInNewWindowButton)
 
  356                 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
 
  357                 .addComponent(attachmentsScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, 333, Short.MAX_VALUE)
 
  361         msgbodyTabbedPane.addTab(
org.openide.util.NbBundle.getMessage(
MessageArtifactViewer.class, 
"MessageArtifactViewer.attachmentsPanel.TabConstraints.tabTitle"), attachmentsPanel); 
 
  363         accountsTab.setLayout(
new java.awt.BorderLayout());
 
  364         accountsTab.add(accountScrollPane, java.awt.BorderLayout.CENTER);
 
  366         msgbodyTabbedPane.addTab(
org.openide.util.NbBundle.getMessage(
MessageArtifactViewer.class, 
"MessageArtifactViewer.accountsTab.TabConstraints.tabTitle"), accountsTab); 
 
  368         javax.swing.GroupLayout layout = 
new javax.swing.GroupLayout(
this);
 
  369         this.setLayout(layout);
 
  370         layout.setHorizontalGroup(
 
  371             layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
 
  372             .addGroup(layout.createSequentialGroup()
 
  374                 .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
 
  375                     .addComponent(msgbodyTabbedPane)
 
  376                     .addComponent(envelopePanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
 
  379         layout.setVerticalGroup(
 
  380             layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
 
  381             .addGroup(layout.createSequentialGroup()
 
  383                 .addComponent(envelopePanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
 
  384                 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
 
  385                 .addComponent(msgbodyTabbedPane)
 
  391         new NewWindowViewAction(
"View in new window", drpExplorerManager.getSelectedNodes()[0]).actionPerformed(evt);
 
  422         this.artifact = artifact;
 
  423         if (artifact == null) {
 
  432         if (artifact.getArtifactTypeID() == TSK_KEYWORD_HIT.getTypeID()) {
 
  434                 getAssociatedArtifact(artifact).ifPresent(associatedArtifact -> {
 
  435                     this.artifact = associatedArtifact;
 
  437             } 
catch (TskCoreException ex) {
 
  438                 LOGGER.log(Level.SEVERE, 
"error getting associated artifact", ex);
 
  442         if (this.artifact.getArtifactTypeID() == TSK_MESSAGE.getTypeID()) {
 
  444         } 
else if (this.artifact.getArtifactTypeID() == TSK_EMAIL_MSG.getTypeID()) {
 
  450         msgbodyTabbedPane.setEnabledAt(ACCT_TAB_INDEX, 
true);
 
  451         accountsPanel.setArtifact(artifact);
 
  464     private static Optional<BlackboardArtifact> 
getAssociatedArtifact(
final BlackboardArtifact artifact) 
throws TskCoreException {
 
  465         BlackboardAttribute attribute = artifact.getAttribute(TSK_ASSOCIATED_TYPE);
 
  466         if (attribute != null) {
 
  467             return Optional.of(artifact.getSleuthkitCase().getArtifactByArtifactId(attribute.getValueLong()));
 
  469         return Optional.empty();
 
  479         fromText.setText(
"");
 
  480         fromLabel.setEnabled(
false);
 
  482         toLabel.setEnabled(
false);
 
  484         ccLabel.setEnabled(
false);
 
  485         subjectText.setText(
"");
 
  486         subjectLabel.setEnabled(
false);
 
  487         datetimeText.setText(
"");
 
  488         datetimeText.setEnabled(
false);
 
  489         directionText.setText(
"");
 
  490         directionText.setEnabled(
false);
 
  492         headersTextArea.setText(
"");
 
  493         rtfbodyTextPane.setText(
"");
 
  496         msgbodyTabbedPane.setEnabled(
false);
 
  502         if (artifact == null) {
 
  506         if (artifact.getArtifactTypeID() == TSK_KEYWORD_HIT.getTypeID()) {
 
  511             } 
catch (TskCoreException ex) {
 
  512                 LOGGER.log(Level.SEVERE, 
"error getting associated artifact", ex);
 
  515         return isMessageArtifact(artifact);
 
  528         final int artifactTypeID = nodeArtifact.getArtifactTypeID();
 
  529         return artifactTypeID == TSK_EMAIL_MSG.getTypeID()
 
  530                 || artifactTypeID == TSK_MESSAGE.getTypeID();
 
  542     private void configureTextArea(BlackboardAttribute.ATTRIBUTE_TYPE type, 
int index) 
throws TskCoreException {
 
  543         String attributeText = getAttributeValueSafe(artifact, type);
 
  545         if (index == HTML_TAB_INDEX && StringUtils.isNotBlank(attributeText)) {
 
  546             htmlPanel.setHtmlText(attributeText);
 
  547         } 
else if (index == TEXT_TAB_INDEX && StringUtils.isNotBlank(attributeText)) {
 
  548             textPanel.
setContent(attributeText, artifact.toString());
 
  550             JTextComponent textComponent = textAreas.get(index);
 
  551             if (textComponent != null) {
 
  552                 textComponent.setText(attributeText);
 
  553                 textComponent.setCaretPosition(0); 
 
  557         final boolean hasText = attributeText.length() > 0;
 
  559         msgbodyTabbedPane.setEnabledAt(index, hasText);
 
  561             msgbodyTabbedPane.setSelectedIndex(index);
 
  566         msgbodyTabbedPane.setEnabled(
true);
 
  567         fromLabel.setEnabled(
true);
 
  568         toLabel.setEnabled(
true);
 
  569         subjectLabel.setEnabled(
true);
 
  570         datetimeText.setEnabled(
true);
 
  575         final Set<Attachment> attachments;
 
  578         BlackboardAttribute attachmentsAttr = artifact.getAttribute(
new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_ATTACHMENTS));
 
  579         if (attachmentsAttr != null) {
 
  581             attachments = 
new HashSet<>();
 
  583                 MessageAttachments msgAttachments = BlackboardJsonAttrUtil.fromAttribute(attachmentsAttr, MessageAttachments.class);
 
  584                 Collection<FileAttachment> fileAttachments = msgAttachments.getFileAttachments();
 
  585                 for (FileAttachment fileAttachment : fileAttachments) {
 
  586                     attachments.add(fileAttachment);
 
  588                 Collection<URLAttachment> urlAttachments = msgAttachments.getUrlAttachments();
 
  589                 for (URLAttachment urlAttachment : urlAttachments) {
 
  590                     attachments.add(urlAttachment);
 
  592             } 
catch (BlackboardJsonAttrUtil.InvalidJsonException ex) {
 
  593                 LOGGER.log(Level.WARNING, String.format(
"Unable to parse json for MessageAttachments object in artifact: %s", artifact.getName()), ex);
 
  596             attachments = 
new HashSet<>();
 
  597             for (Content child : artifact.getChildren()) {
 
  598                 if (child instanceof AbstractFile) {
 
  599                     attachments.add(
new FileAttachment((AbstractFile) child));
 
  604         final int numberOfAttachments = attachments.size();
 
  606         msgbodyTabbedPane.setEnabledAt(ATTM_TAB_INDEX, numberOfAttachments > 0);
 
  607         msgbodyTabbedPane.setTitleAt(ATTM_TAB_INDEX, 
"Attachments (" + numberOfAttachments + 
")");
 
  613         enableCommonFields();
 
  615         directionText.setEnabled(
false);
 
  616         ccLabel.setEnabled(
true);
 
  619             this.fromText.setText(getAttributeValueSafe(artifact, TSK_EMAIL_FROM));
 
  620             this.fromText.setToolTipText(getAttributeValueSafe(artifact, TSK_EMAIL_FROM));
 
  621             this.toText.setText(getAttributeValueSafe(artifact, TSK_EMAIL_TO));
 
  622             this.toText.setToolTipText(getAttributeValueSafe(artifact, TSK_EMAIL_TO));
 
  623             this.directionText.setText(
"");
 
  624             this.ccText.setText(getAttributeValueSafe(artifact, TSK_EMAIL_CC));
 
  625             this.ccText.setToolTipText(getAttributeValueSafe(artifact, TSK_EMAIL_CC));
 
  626             this.subjectText.setText(getAttributeValueSafe(artifact, TSK_SUBJECT));
 
  627             this.datetimeText.setText(getAttributeValueSafe(artifact, TSK_DATETIME_RCVD));
 
  629             configureTextArea(TSK_HEADERS, HDR_TAB_INDEX);
 
  630             configureTextArea(TSK_EMAIL_CONTENT_PLAIN, TEXT_TAB_INDEX);
 
  631             configureTextArea(TSK_EMAIL_CONTENT_HTML, HTML_TAB_INDEX);
 
  632             configureTextArea(TSK_EMAIL_CONTENT_RTF, RTF_TAB_INDEX);
 
  633             configureAttachments();
 
  634         } 
catch (TskCoreException ex) {
 
  635             LOGGER.log(Level.WARNING, 
"Failed to get attributes for email message.", ex); 
 
  640         enableCommonFields();
 
  642         directionText.setEnabled(
true);
 
  643         ccLabel.setEnabled(
false);
 
  646             this.fromText.setText(getAttributeValueSafe(artifact, TSK_PHONE_NUMBER_FROM));
 
  647             this.toText.setText(getAttributeValueSafe(artifact, TSK_PHONE_NUMBER_TO));
 
  648             this.directionText.setText(getAttributeValueSafe(artifact, TSK_DIRECTION));
 
  649             this.ccText.setText(
"");
 
  650             this.subjectText.setText(getAttributeValueSafe(artifact, TSK_SUBJECT));
 
  651             this.datetimeText.setText(getAttributeValueSafe(artifact, TSK_DATETIME));
 
  653             msgbodyTabbedPane.setEnabledAt(HTML_TAB_INDEX, 
false);
 
  654             msgbodyTabbedPane.setEnabledAt(RTF_TAB_INDEX, 
false);
 
  655             msgbodyTabbedPane.setEnabledAt(HDR_TAB_INDEX, 
false);
 
  656             msgbodyTabbedPane.setEnabledAt(HDR_TAB_INDEX, 
false);
 
  657             configureTextArea(TSK_TEXT, TEXT_TAB_INDEX);
 
  658             configureAttachments();
 
  659         } 
catch (TskCoreException ex) {
 
  660             LOGGER.log(Level.WARNING, 
"Failed to get attributes for message.", ex); 
 
  664     private static String 
getAttributeValueSafe(BlackboardArtifact artifact, BlackboardAttribute.ATTRIBUTE_TYPE type) throws TskCoreException {
 
  665         return Optional.ofNullable(artifact.getAttribute(
new BlackboardAttribute.Type(type)))
 
  666                 .map(BlackboardAttribute::getDisplayString)
 
  679         Document doc = Jsoup.parse(htmlInString);
 
  682         doc.select(
"img[src]").forEach(img -> img.attr(
"src", 
""));
 
  695             this.attachments = attachments;
 
  706             setKeys(attachments);
 
static void configureTextPaneAsRtf(JTextPane pane)
 
javax.swing.JLabel subjectLabel
 
void enableCommonFields()
 
void configureAttachments()
 
static String getAttributeValueSafe(BlackboardArtifact artifact, BlackboardAttribute.ATTRIBUTE_TYPE type)
 
void configureTextArea(BlackboardAttribute.ATTRIBUTE_TYPE type, int index)
 
javax.swing.JTextPane rtfbodyTextPane
 
void setText(String text)
 
javax.swing.JScrollPane headersScrollPane
 
javax.swing.JLabel ccLabel
 
static String cleanseHTML(String htmlInString)
 
BlackboardArtifact artifact
 
javax.swing.JPanel htmlPane
 
javax.swing.JLabel toText
 
javax.swing.JLabel ccText
 
javax.swing.JLabel datetimeText
 
void setArtifact(BlackboardArtifact artifact)
 
ExplorerManager drpExplorerManager
 
void setContent(String content, String contentDescriptor)
 
ExplorerManager getExplorerManager()
 
void setNode(Node rootNode)
 
javax.swing.JPanel envelopePanel
 
MessageArtifactViewer(List< JTextComponent > textAreas, DataResultPanel drp)
 
static DataResultPanel createInstanceUninitialized(String title, String description, Node currentRootNode, int childNodeCount, DataContent customContentView)
 
boolean isSupported(BlackboardArtifact artifact)
 
javax.swing.JLabel fromText
 
javax.swing.JTabbedPane msgbodyTabbedPane
 
javax.swing.JScrollPane attachmentsScrollPane
 
void viewInNewWindowButtonActionPerformed(java.awt.event.ActionEvent evt)
 
final DataResultPanel drp
 
javax.swing.JPanel accountsTab
 
javax.swing.JTextArea headersTextArea
 
javax.swing.JScrollPane accountScrollPane
 
javax.swing.JLabel directionText
 
MessageAccountPanel accountsPanel
 
static boolean isMessageArtifact(BlackboardArtifact nodeArtifact)
 
javax.swing.JScrollPane rtfbodyScrollPane
 
Node[] createNodes(Attachment t)
 
javax.swing.JLabel fromLabel
 
synchronized static Logger getLogger(String name)
 
javax.swing.JButton viewInNewWindowButton
 
final Set< Attachment > attachments
 
javax.swing.JPanel attachmentsPanel
 
javax.swing.JLabel subjectText
 
final List< JTextComponent > textAreas
 
static Optional< BlackboardArtifact > getAssociatedArtifact(final BlackboardArtifact artifact)
 
javax.swing.JLabel toLabel
 
static boolean isEnabled()