Autopsy 4.22.1
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 */
19package org.sleuthkit.autopsy.contentviewers.artifactviewers;
20
21import org.sleuthkit.autopsy.datamodel.AttachmentNode;
22import java.awt.Color;
23import java.awt.Component;
24import java.awt.ComponentOrientation;
25import java.awt.Cursor;
26import java.util.Arrays;
27import java.util.List;
28import java.util.Set;
29import java.util.concurrent.ExecutionException;
30import java.util.logging.Level;
31import javax.swing.JScrollPane;
32import javax.swing.text.JTextComponent;
33import org.apache.commons.lang3.StringUtils;
34import org.openide.explorer.ExplorerManager;
35import org.openide.nodes.AbstractNode;
36import org.openide.nodes.Children;
37import org.openide.nodes.Node;
38import org.openide.util.NbBundle;
39import org.openide.util.lookup.ServiceProvider;
40import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepository;
41import org.sleuthkit.autopsy.contentviewers.TranslatablePanel;
42import org.sleuthkit.autopsy.contentviewers.TranslatablePanel.TranslatablePanelException;
43import org.sleuthkit.autopsy.contentviewers.Utilities;
44import org.sleuthkit.autopsy.contentviewers.artifactviewers.MessageArtifactWorker.MesssageArtifactData;
45import org.sleuthkit.autopsy.corecomponents.AutoWrappingJTextPane;
46import org.sleuthkit.autopsy.corecomponents.DataResultPanel;
47import org.sleuthkit.autopsy.corecomponents.TableFilterNode;
48import org.sleuthkit.autopsy.coreutils.Logger;
49import org.sleuthkit.autopsy.directorytree.DataResultFilterNode;
50import org.sleuthkit.autopsy.directorytree.NewWindowViewAction;
51import org.sleuthkit.datamodel.BlackboardArtifact;
52import static org.sleuthkit.datamodel.BlackboardArtifact.ARTIFACT_TYPE.TSK_EMAIL_MSG;
53import static org.sleuthkit.datamodel.BlackboardArtifact.ARTIFACT_TYPE.TSK_KEYWORD_HIT;
54import static org.sleuthkit.datamodel.BlackboardArtifact.ARTIFACT_TYPE.TSK_MESSAGE;
55import org.sleuthkit.datamodel.BlackboardAttribute;
56import static org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_ASSOCIATED_ARTIFACT;
57import static org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME;
58import static org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME_RCVD;
59import static org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DIRECTION;
60import static org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_EMAIL_CC;
61import static org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_EMAIL_CONTENT_HTML;
62import static org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_EMAIL_CONTENT_PLAIN;
63import static org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_EMAIL_CONTENT_RTF;
64import static org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_EMAIL_FROM;
65import static org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_EMAIL_TO;
66import static org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_HEADERS;
67import static org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PHONE_NUMBER_FROM;
68import static org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PHONE_NUMBER_TO;
69import static org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_SUBJECT;
70import static org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_TEXT;
71import org.sleuthkit.datamodel.TskCoreException;
72import org.sleuthkit.datamodel.blackboardutils.attributes.MessageAttachments.Attachment;
73
77@ServiceProvider(service = ArtifactContentViewer.class)
78@SuppressWarnings("PMD.SingularField") // UI widgets cause lots of false positives
79public 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;
126 private final org.sleuthkit.autopsy.contentviewers.HtmlPanel htmlPanel = new org.sleuthkit.autopsy.contentviewers.HtmlPanel();
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")
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,
162
163 msgbodyTabbedPane.setEnabledAt(ATTM_TAB_INDEX, true);
164
165 accountScrollPane.setViewportView(accountsPanel);
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
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) {
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 {
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 }
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) {
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) {
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)
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-2024 Sleuth Kit Labs. Generated on:
This work is licensed under a Creative Commons Attribution-Share Alike 3.0 United States License.