Autopsy  4.19.3
Graphical digital forensics platform for The Sleuth Kit and other tools.
MessageArtifactViewer.java
Go to the documentation of this file.
1 /*
2  * Autopsy Forensic Browser
3  *
4  * Copyright 2017-2020 Basis Technology Corp.
5  * Contact: carrier <at> sleuthkit <dot> org
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  * http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  */
19 package org.sleuthkit.autopsy.contentviewers.artifactviewers;
20 
22 import java.awt.Color;
23 import java.awt.Component;
24 import java.awt.ComponentOrientation;
25 import java.awt.Cursor;
26 import java.util.Arrays;
27 import java.util.List;
28 import java.util.Set;
29 import java.util.concurrent.ExecutionException;
30 import java.util.logging.Level;
31 import javax.swing.JScrollPane;
32 import javax.swing.text.JTextComponent;
33 import org.apache.commons.lang3.StringUtils;
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.util.NbBundle;
39 import org.openide.util.lookup.ServiceProvider;
51 import org.sleuthkit.datamodel.BlackboardArtifact;
52 import static org.sleuthkit.datamodel.BlackboardArtifact.ARTIFACT_TYPE.TSK_EMAIL_MSG;
53 import static org.sleuthkit.datamodel.BlackboardArtifact.ARTIFACT_TYPE.TSK_KEYWORD_HIT;
54 import static org.sleuthkit.datamodel.BlackboardArtifact.ARTIFACT_TYPE.TSK_MESSAGE;
55 import org.sleuthkit.datamodel.BlackboardAttribute;
56 import static org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_ASSOCIATED_ARTIFACT;
57 import static org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME;
58 import static org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME_RCVD;
59 import static org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DIRECTION;
60 import static org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_EMAIL_CC;
61 import static org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_EMAIL_CONTENT_HTML;
62 import static org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_EMAIL_CONTENT_PLAIN;
63 import static org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_EMAIL_CONTENT_RTF;
64 import static org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_EMAIL_FROM;
65 import static org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_EMAIL_TO;
66 import static org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_HEADERS;
67 import static org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PHONE_NUMBER_FROM;
68 import static org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PHONE_NUMBER_TO;
69 import static org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_SUBJECT;
70 import static org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_TEXT;
71 import org.sleuthkit.datamodel.TskCoreException;
72 import org.sleuthkit.datamodel.blackboardutils.attributes.MessageAttachments.Attachment;
73 
77 @ServiceProvider(service = ArtifactContentViewer.class)
78 @SuppressWarnings("PMD.SingularField") // UI widgets cause lots of false positives
79 public class MessageArtifactViewer extends javax.swing.JPanel implements ArtifactContentViewer {
80 
85  class TextComponent implements TranslatablePanel.ContentComponent {
86 
87  private final Component rootComponent;
88  private final AutoWrappingJTextPane childTextComponent;
89 
90  TextComponent() {
91  childTextComponent = new AutoWrappingJTextPane();
92  childTextComponent.setEditable(false);
93 
94  JScrollPane parentComponent = new JScrollPane();
95  parentComponent.setHorizontalScrollBarPolicy(javax.swing.ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
96  parentComponent.setVerticalScrollBarPolicy(javax.swing.ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED);
97  parentComponent.setViewportView(childTextComponent);
98  rootComponent = parentComponent;
99  }
100 
101  @Override
102  public Component getRootComponent() {
103  return rootComponent;
104  }
105 
106  @Override
107  public void setContent(String content, ComponentOrientation orientation) throws TranslatablePanelException {
108  childTextComponent.setText(content == null ? "" : content);
109  childTextComponent.setComponentOrientation(orientation);
110  childTextComponent.setCaretPosition(0);
111  }
112  }
113 
114  private static final long serialVersionUID = 1L;
115  private static final Logger LOGGER = Logger.getLogger(MessageArtifactViewer.class.getName());
116  private static final BlackboardAttribute.Type TSK_ASSOCIATED_TYPE = new BlackboardAttribute.Type(TSK_ASSOCIATED_ARTIFACT);
117 
118  private static final int HDR_TAB_INDEX = 0;
119  private static final int TEXT_TAB_INDEX = 1;
120  private static final int HTML_TAB_INDEX = 2;
121  private static final int RTF_TAB_INDEX = 3;
122  private static final int ATTM_TAB_INDEX = 4;
123  private static final int ACCT_TAB_INDEX = 5;
124 
125  private final List<JTextComponent> textAreas;
127  private final TranslatablePanel textPanel = new TranslatablePanel(new TextComponent());
131  private BlackboardArtifact artifact;
132  private final DataResultPanel drp;
133  private ExplorerManager drpExplorerManager;
134 
135  private MessageAccountPanel accountsPanel;
136 
137  private MessageArtifactWorker worker;
138 
139  public MessageArtifactViewer(List<JTextComponent> textAreas, DataResultPanel drp) {
140  this.textAreas = textAreas;
141  this.drp = drp;
142  }
143 
147  @NbBundle.Messages("MessageArtifactViewer.AttachmentPanel.title=Attachments")
149  initComponents();
150  accountsPanel = new MessageAccountPanel();
151 
152  htmlPane.add(htmlPanel);
153  envelopePanel.setBackground(new Color(0, 0, 0, 38));
154  drp = DataResultPanel.createInstanceUninitialized(Bundle.MessageArtifactViewer_AttachmentPanel_title(), "", new TableFilterNode(Node.EMPTY, false), 0, null);
155  attachmentsScrollPane.setViewportView(drp);
156 
157  msgbodyTabbedPane.insertTab(NbBundle.getMessage(MessageArtifactViewer.class, "MessageArtifactViewer.textbodyScrollPane.TabConstraints.tabTitle"),
158  null,
159  textPanel,
160  null,
161  TEXT_TAB_INDEX);
162 
163  msgbodyTabbedPane.setEnabledAt(ATTM_TAB_INDEX, true);
164 
165  accountScrollPane.setViewportView(accountsPanel);
166  msgbodyTabbedPane.setEnabledAt(ACCT_TAB_INDEX, CentralRepository.isEnabled());
167 
168  /*
169  * HTML tab uses the HtmlPanel instead of an internal text pane, so we
170  * use 'null' for that index.
171  */
172  textAreas = Arrays.asList(headersTextArea, null, null, rtfbodyTextPane);
173 
174  Utilities.configureTextPaneAsRtf(rtfbodyTextPane);
175  resetComponent();
176 
177  }
178 
179  @Override
180  public void addNotify() {
181  super.addNotify(); //To change body of generated methods, choose Tools | Templates.
182 
183  drp.open();
184  drpExplorerManager = drp.getExplorerManager();
185  drpExplorerManager.addPropertyChangeListener(evt
186  -> viewInNewWindowButton.setEnabled(drpExplorerManager.getSelectedNodes().length == 1));
187  }
188 
194  @SuppressWarnings("unchecked")
195  // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
196  private void initComponents() {
197 
198  envelopePanel = new javax.swing.JPanel();
199  fromLabel = new javax.swing.JLabel();
200  datetimeText = new javax.swing.JLabel();
201  fromText = new javax.swing.JLabel();
202  toLabel = new javax.swing.JLabel();
203  toText = new javax.swing.JLabel();
204  ccLabel = new javax.swing.JLabel();
205  ccText = new javax.swing.JLabel();
206  subjectLabel = new javax.swing.JLabel();
207  subjectText = new javax.swing.JLabel();
208  directionText = new javax.swing.JLabel();
209  msgbodyTabbedPane = new javax.swing.JTabbedPane();
210  headersScrollPane = new javax.swing.JScrollPane();
211  headersTextArea = new javax.swing.JTextArea();
212  htmlPane = new javax.swing.JPanel();
213  rtfbodyScrollPane = new javax.swing.JScrollPane();
214  rtfbodyTextPane = new javax.swing.JTextPane();
215  attachmentsPanel = new javax.swing.JPanel();
216  viewInNewWindowButton = new javax.swing.JButton();
217  attachmentsScrollPane = new javax.swing.JScrollPane();
218  accountsTab = new javax.swing.JPanel();
219  accountScrollPane = new javax.swing.JScrollPane();
220 
221  envelopePanel.setBackground(new java.awt.Color(204, 204, 204));
222 
223  org.openide.awt.Mnemonics.setLocalizedText(fromLabel, org.openide.util.NbBundle.getMessage(MessageArtifactViewer.class, "MessageArtifactViewer.fromLabel.text")); // NOI18N
224 
225  datetimeText.setHorizontalAlignment(javax.swing.SwingConstants.RIGHT);
226  org.openide.awt.Mnemonics.setLocalizedText(datetimeText, org.openide.util.NbBundle.getMessage(MessageArtifactViewer.class, "MessageArtifactViewer.datetimeText.text")); // NOI18N
227 
228  org.openide.awt.Mnemonics.setLocalizedText(fromText, org.openide.util.NbBundle.getMessage(MessageArtifactViewer.class, "MessageArtifactViewer.fromText.text")); // NOI18N
229 
230  org.openide.awt.Mnemonics.setLocalizedText(toLabel, org.openide.util.NbBundle.getMessage(MessageArtifactViewer.class, "MessageArtifactViewer.toLabel.text")); // NOI18N
231 
232  org.openide.awt.Mnemonics.setLocalizedText(toText, org.openide.util.NbBundle.getMessage(MessageArtifactViewer.class, "MessageArtifactViewer.toText.text")); // NOI18N
233  toText.setAutoscrolls(true);
234  toText.setMinimumSize(new java.awt.Dimension(27, 14));
235 
236  org.openide.awt.Mnemonics.setLocalizedText(ccLabel, org.openide.util.NbBundle.getMessage(MessageArtifactViewer.class, "MessageArtifactViewer.ccLabel.text")); // NOI18N
237 
238  org.openide.awt.Mnemonics.setLocalizedText(ccText, org.openide.util.NbBundle.getMessage(MessageArtifactViewer.class, "MessageArtifactViewer.ccText.text")); // NOI18N
239  ccText.setMinimumSize(new java.awt.Dimension(27, 14));
240 
241  org.openide.awt.Mnemonics.setLocalizedText(subjectLabel, org.openide.util.NbBundle.getMessage(MessageArtifactViewer.class, "MessageArtifactViewer.subjectLabel.text")); // NOI18N
242 
243  org.openide.awt.Mnemonics.setLocalizedText(subjectText, org.openide.util.NbBundle.getMessage(MessageArtifactViewer.class, "MessageArtifactViewer.subjectText.text")); // NOI18N
244  subjectText.setMinimumSize(new java.awt.Dimension(26, 14));
245 
246  directionText.setHorizontalAlignment(javax.swing.SwingConstants.RIGHT);
247  org.openide.awt.Mnemonics.setLocalizedText(directionText, org.openide.util.NbBundle.getMessage(MessageArtifactViewer.class, "MessageArtifactViewer.directionText.text")); // NOI18N
248 
249  javax.swing.GroupLayout envelopePanelLayout = new javax.swing.GroupLayout(envelopePanel);
250  envelopePanel.setLayout(envelopePanelLayout);
251  envelopePanelLayout.setHorizontalGroup(
252  envelopePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
253  .addGroup(envelopePanelLayout.createSequentialGroup()
254  .addGap(5, 5, 5)
255  .addGroup(envelopePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
256  .addGroup(envelopePanelLayout.createSequentialGroup()
257  .addGroup(envelopePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
258  .addComponent(fromLabel)
259  .addComponent(toLabel))
260  .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
261  .addGroup(envelopePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
262  .addGroup(envelopePanelLayout.createSequentialGroup()
263  .addComponent(toText, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
264  .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
265  .addComponent(directionText, javax.swing.GroupLayout.PREFERRED_SIZE, 66, javax.swing.GroupLayout.PREFERRED_SIZE))
266  .addGroup(envelopePanelLayout.createSequentialGroup()
267  .addComponent(fromText, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
268  .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
269  .addComponent(datetimeText, javax.swing.GroupLayout.PREFERRED_SIZE, 140, javax.swing.GroupLayout.PREFERRED_SIZE))))
270  .addGroup(envelopePanelLayout.createSequentialGroup()
271  .addComponent(ccLabel)
272  .addGap(26, 26, 26)
273  .addComponent(ccText, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
274  .addGroup(envelopePanelLayout.createSequentialGroup()
275  .addComponent(subjectLabel)
276  .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
277  .addComponent(subjectText, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)))
278  .addGap(5, 5, 5))
279  );
280  envelopePanelLayout.setVerticalGroup(
281  envelopePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
282  .addGroup(envelopePanelLayout.createSequentialGroup()
283  .addGap(5, 5, 5)
284  .addGroup(envelopePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
285  .addComponent(fromLabel)
286  .addComponent(datetimeText)
287  .addComponent(fromText))
288  .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
289  .addGroup(envelopePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
290  .addComponent(toLabel)
291  .addComponent(toText, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
292  .addComponent(directionText))
293  .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
294  .addGroup(envelopePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
295  .addComponent(ccLabel)
296  .addComponent(ccText, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
297  .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
298  .addGroup(envelopePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
299  .addComponent(subjectLabel)
300  .addComponent(subjectText, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
301  .addGap(5, 5, 5))
302  );
303 
304  headersScrollPane.setHorizontalScrollBarPolicy(javax.swing.ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
305  headersScrollPane.setVerticalScrollBarPolicy(javax.swing.ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);
306 
307  headersTextArea.setEditable(false);
308  headersTextArea.setColumns(20);
309  headersTextArea.setLineWrap(true);
310  headersTextArea.setRows(5);
311  headersTextArea.setWrapStyleWord(true);
312  headersScrollPane.setViewportView(headersTextArea);
313 
314  msgbodyTabbedPane.addTab(org.openide.util.NbBundle.getMessage(MessageArtifactViewer.class, "MessageArtifactViewer.headersScrollPane.TabConstraints.tabTitle"), headersScrollPane); // NOI18N
315 
316  htmlPane.setLayout(new java.awt.BorderLayout());
317  msgbodyTabbedPane.addTab(org.openide.util.NbBundle.getMessage(MessageArtifactViewer.class, "MessageArtifactViewer.htmlPane.TabConstraints.tabTitle"), htmlPane); // NOI18N
318 
319  rtfbodyScrollPane.setVerticalScrollBarPolicy(javax.swing.ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);
320 
321  rtfbodyTextPane.setEditable(false);
322  rtfbodyScrollPane.setViewportView(rtfbodyTextPane);
323 
324  msgbodyTabbedPane.addTab(org.openide.util.NbBundle.getMessage(MessageArtifactViewer.class, "MessageArtifactViewer.rtfbodyScrollPane.TabConstraints.tabTitle"), rtfbodyScrollPane); // NOI18N
325 
326  org.openide.awt.Mnemonics.setLocalizedText(viewInNewWindowButton, org.openide.util.NbBundle.getMessage(MessageArtifactViewer.class, "MessageArtifactViewer.viewInNewWindowButton.text")); // NOI18N
327  viewInNewWindowButton.addActionListener(new java.awt.event.ActionListener() {
328  public void actionPerformed(java.awt.event.ActionEvent evt) {
329  viewInNewWindowButtonActionPerformed(evt);
330  }
331  });
332 
333  javax.swing.GroupLayout attachmentsPanelLayout = new javax.swing.GroupLayout(attachmentsPanel);
334  attachmentsPanel.setLayout(attachmentsPanelLayout);
335  attachmentsPanelLayout.setHorizontalGroup(
336  attachmentsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
337  .addGroup(attachmentsPanelLayout.createSequentialGroup()
338  .addGap(0, 0, 0)
339  .addGroup(attachmentsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
340  .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, attachmentsPanelLayout.createSequentialGroup()
341  .addComponent(viewInNewWindowButton)
342  .addGap(3, 3, 3))
343  .addComponent(attachmentsScrollPane, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, 647, Short.MAX_VALUE)))
344  );
345  attachmentsPanelLayout.setVerticalGroup(
346  attachmentsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
347  .addGroup(attachmentsPanelLayout.createSequentialGroup()
348  .addGap(0, 0, 0)
349  .addComponent(viewInNewWindowButton)
350  .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
351  .addComponent(attachmentsScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, 333, Short.MAX_VALUE)
352  .addGap(0, 0, 0))
353  );
354 
355  msgbodyTabbedPane.addTab(org.openide.util.NbBundle.getMessage(MessageArtifactViewer.class, "MessageArtifactViewer.attachmentsPanel.TabConstraints.tabTitle"), attachmentsPanel); // NOI18N
356 
357  accountsTab.setLayout(new java.awt.BorderLayout());
358  accountsTab.add(accountScrollPane, java.awt.BorderLayout.CENTER);
359 
360  msgbodyTabbedPane.addTab(org.openide.util.NbBundle.getMessage(MessageArtifactViewer.class, "MessageArtifactViewer.accountsTab.TabConstraints.tabTitle"), accountsTab); // NOI18N
361 
362  javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
363  this.setLayout(layout);
364  layout.setHorizontalGroup(
365  layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
366  .addGroup(layout.createSequentialGroup()
367  .addGap(5, 5, 5)
368  .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
369  .addComponent(msgbodyTabbedPane)
370  .addComponent(envelopePanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
371  .addGap(5, 5, 5))
372  );
373  layout.setVerticalGroup(
374  layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
375  .addGroup(layout.createSequentialGroup()
376  .addGap(5, 5, 5)
377  .addComponent(envelopePanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
378  .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
379  .addComponent(msgbodyTabbedPane)
380  .addGap(5, 5, 5))
381  );
382  }// </editor-fold>//GEN-END:initComponents
383 
384  private void viewInNewWindowButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_viewInNewWindowButtonActionPerformed
385  new NewWindowViewAction("View in new window", drpExplorerManager.getSelectedNodes()[0]).actionPerformed(evt);
386  }//GEN-LAST:event_viewInNewWindowButtonActionPerformed
387 
388 
389  // Variables declaration - do not modify//GEN-BEGIN:variables
390  private javax.swing.JScrollPane accountScrollPane;
391  private javax.swing.JPanel accountsTab;
392  private javax.swing.JPanel attachmentsPanel;
393  private javax.swing.JScrollPane attachmentsScrollPane;
394  private javax.swing.JLabel ccLabel;
395  private javax.swing.JLabel ccText;
396  private javax.swing.JLabel datetimeText;
397  private javax.swing.JLabel directionText;
398  private javax.swing.JPanel envelopePanel;
399  private javax.swing.JLabel fromLabel;
400  private javax.swing.JLabel fromText;
401  private javax.swing.JScrollPane headersScrollPane;
402  private javax.swing.JTextArea headersTextArea;
403  private javax.swing.JPanel htmlPane;
404  private javax.swing.JTabbedPane msgbodyTabbedPane;
405  private javax.swing.JScrollPane rtfbodyScrollPane;
406  private javax.swing.JTextPane rtfbodyTextPane;
407  private javax.swing.JLabel subjectLabel;
408  private javax.swing.JLabel subjectText;
409  private javax.swing.JLabel toLabel;
410  private javax.swing.JLabel toText;
411  private javax.swing.JButton viewInNewWindowButton;
412  // End of variables declaration//GEN-END:variables
413 
414  @Override
415  public void setArtifact(BlackboardArtifact artifact) {
416  resetComponent();
417 
418  if (worker != null) {
419  worker.cancel(true);
420  worker = null;
421  }
422 
423  if (artifact == null) {
424  return;
425  }
426 
427  worker = new MessageArtifactWorker(artifact) {
428  @Override
429  public void done() {
430  if (isCancelled()) {
431  return;
432  }
433 
434  try {
435  MesssageArtifactData data = get();
436  MessageArtifactViewer.this.artifact = data.getArtifact();
437  if (data.getArtifact().getArtifactTypeID() == TSK_MESSAGE.getTypeID()) {
438  displayMsg(data);
439  } else if (data.getArtifact().getArtifactTypeID() == TSK_EMAIL_MSG.getTypeID()) {
440  displayEmailMsg(data);
441  } else {
442  resetComponent();
443  }
444 
445  msgbodyTabbedPane.setEnabledAt(ACCT_TAB_INDEX, true);
446  accountsPanel.setArtifact(data.getArtifact());
447  setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
448 
449  } catch (InterruptedException | ExecutionException ex) {
450  LOGGER.log(Level.SEVERE, String.format("Failed to update message viewer for artifact (%d)", artifact.getId(), ex));
451  }
452  }
453  };
454 
455  setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
456  worker.execute();
457  }
458 
459  @Override
460  public Component getComponent() {
461  return this;
462  }
463 
464  public void resetComponent() {
465  // reset all fields
466  fromText.setText("");
467  fromLabel.setEnabled(false);
468  toText.setText("");
469  toLabel.setEnabled(false);
470  ccText.setText("");
471  ccLabel.setEnabled(false);
472  subjectText.setText("");
473  subjectLabel.setEnabled(false);
474  datetimeText.setText("");
475  datetimeText.setEnabled(false);
476  directionText.setText("");
477  directionText.setEnabled(false);
478 
479  headersTextArea.setText("");
480  rtfbodyTextPane.setText("");
481  htmlPanel.reset();
482  textPanel.reset();
483  msgbodyTabbedPane.setEnabled(false);
484  drp.setNode(null);
485  }
486 
487  @Override
488  public boolean isSupported(BlackboardArtifact artifact) {
489  if (artifact == null) {
490  return false;
491  }
492  //if the artifact is a keyword hit, check if its associated artifact is a message or email.
493  if (artifact.getArtifactTypeID() == TSK_KEYWORD_HIT.getTypeID()) {
494  try {
495  if (MessageArtifactWorker.getAssociatedArtifact(artifact).map(MessageArtifactViewer::isMessageArtifact).orElse(false)) {
496  return true;
497  }
498  } catch (TskCoreException ex) {
499  LOGGER.log(Level.SEVERE, "error getting associated artifact", ex);
500  }
501  }
502  return isMessageArtifact(artifact);
503  }
504 
514  public static boolean isMessageArtifact(BlackboardArtifact nodeArtifact) {
515  final int artifactTypeID = nodeArtifact.getArtifactTypeID();
516  return artifactTypeID == TSK_EMAIL_MSG.getTypeID()
517  || artifactTypeID == TSK_MESSAGE.getTypeID();
518  }
519 
529  private void configureTextArea(String text, int index) {
530  if (index == HTML_TAB_INDEX && StringUtils.isNotBlank(text)) {
531  htmlPanel.setHtmlText(text);
532  } else if (index == TEXT_TAB_INDEX && StringUtils.isNotBlank(text)) {
533  textPanel.setContent(text, artifact.toString());
534  } else {
535  JTextComponent textComponent = textAreas.get(index);
536  if (textComponent != null) {
537  textComponent.setText(text);
538  textComponent.setCaretPosition(0); //make sure we start at the top
539  }
540  }
541 
542  final boolean hasText = text.length() > 0;
543 
544  msgbodyTabbedPane.setEnabledAt(index, hasText);
545  if (hasText) {
546  msgbodyTabbedPane.setSelectedIndex(index);
547  }
548  }
549 
550  private void enableCommonFields() {
551  msgbodyTabbedPane.setEnabled(true);
552  fromLabel.setEnabled(true);
553  toLabel.setEnabled(true);
554  subjectLabel.setEnabled(true);
555  datetimeText.setEnabled(true);
556  }
557 
558  private void configureAttachments(Set<Attachment> attachments) {
559  int numberOfAttachments = attachments.size();
560 
561  msgbodyTabbedPane.setEnabledAt(ATTM_TAB_INDEX, numberOfAttachments > 0);
562  msgbodyTabbedPane.setTitleAt(ATTM_TAB_INDEX, "Attachments (" + numberOfAttachments + ")");
563  drp.setNode(new TableFilterNode(new DataResultFilterNode(new AbstractNode(
564  new AttachmentsChildren(attachments))), true));
565  }
566 
567  private void displayEmailMsg(MesssageArtifactData artifactData) {
568  enableCommonFields();
569 
570  directionText.setEnabled(false);
571  ccLabel.setEnabled(true);
572 
573  this.fromText.setText(artifactData.getAttributeDisplayString( TSK_EMAIL_FROM));
574  this.fromText.setToolTipText(artifactData.getAttributeDisplayString(TSK_EMAIL_FROM));
575  this.toText.setText(artifactData.getAttributeDisplayString(TSK_EMAIL_TO));
576  this.toText.setToolTipText(artifactData.getAttributeDisplayString(TSK_EMAIL_TO));
577  this.directionText.setText("");
578  this.ccText.setText(artifactData.getAttributeDisplayString(TSK_EMAIL_CC));
579  this.ccText.setToolTipText(artifactData.getAttributeDisplayString(TSK_EMAIL_CC));
580  this.subjectText.setText(artifactData.getAttributeDisplayString(TSK_SUBJECT));
581  this.datetimeText.setText(artifactData.getAttributeDisplayString(TSK_DATETIME_RCVD));
582 
583  configureTextArea(artifactData.getAttributeDisplayString(TSK_HEADERS), HDR_TAB_INDEX);
584  configureTextArea(artifactData.getAttributeDisplayString(TSK_EMAIL_CONTENT_PLAIN), TEXT_TAB_INDEX);
585  configureTextArea(artifactData.getAttributeDisplayString(TSK_EMAIL_CONTENT_HTML), HTML_TAB_INDEX);
586  configureTextArea(artifactData.getAttributeDisplayString(TSK_EMAIL_CONTENT_RTF), RTF_TAB_INDEX);
587  configureAttachments(artifactData.getAttachements());
588  }
589 
590  private void displayMsg(MesssageArtifactData artifactData) {
591  enableCommonFields();
592 
593  directionText.setEnabled(true);
594  ccLabel.setEnabled(false);
595 
596  this.fromText.setText(artifactData.getAttributeDisplayString(TSK_PHONE_NUMBER_FROM));
597  this.toText.setText(artifactData.getAttributeDisplayString(TSK_PHONE_NUMBER_TO));
598  this.directionText.setText(artifactData.getAttributeDisplayString(TSK_DIRECTION));
599  this.ccText.setText("");
600  this.subjectText.setText(artifactData.getAttributeDisplayString(TSK_SUBJECT));
601  this.datetimeText.setText(artifactData.getAttributeDisplayString(TSK_DATETIME));
602 
603  msgbodyTabbedPane.setEnabledAt(HTML_TAB_INDEX, false);
604  msgbodyTabbedPane.setEnabledAt(RTF_TAB_INDEX, false);
605  msgbodyTabbedPane.setEnabledAt(HDR_TAB_INDEX, false);
606  msgbodyTabbedPane.setEnabledAt(HDR_TAB_INDEX, false);
607  configureTextArea(artifactData.getAttributeDisplayString(TSK_TEXT), TEXT_TAB_INDEX);
608  configureAttachments(artifactData.getAttachements());
609  }
610 
614  private static class AttachmentsChildren extends Children.Keys<Attachment> {
615 
616  private final Set<Attachment> attachments;
617 
618  AttachmentsChildren(Set<Attachment> attachments) {
619  this.attachments = attachments;
620  }
621 
622  @Override
623  protected Node[] createNodes(Attachment t) {
624  return new Node[]{new AttachmentNode(t)};
625  }
626 
627  @Override
628  protected void addNotify() {
629  super.addNotify();
630  setKeys(attachments);
631  }
632  }
633 }
static void configureTextPaneAsRtf(JTextPane pane)
Definition: Utilities.java:52
void setContent(String content, String contentDescriptor)
MessageArtifactViewer(List< JTextComponent > textAreas, DataResultPanel drp)
static DataResultPanel createInstanceUninitialized(String title, String description, Node currentRootNode, int childNodeCount, DataContent customContentView)
synchronized static Logger getLogger(String name)
Definition: Logger.java:124

Copyright © 2012-2022 Basis Technology. Generated on: Tue Jun 27 2023
This work is licensed under a Creative Commons Attribution-Share Alike 3.0 United States License.