19 package org.sleuthkit.autopsy.contentviewers.contextviewer;
21 import java.awt.Component;
22 import java.awt.Insets;
23 import java.util.ArrayList;
24 import java.util.Collections;
25 import java.util.Comparator;
26 import java.util.HashMap;
27 import java.util.List;
29 import java.util.logging.Level;
30 import javax.swing.BoxLayout;
31 import static javax.swing.ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED;
32 import javax.swing.border.EmptyBorder;
33 import org.apache.commons.lang.StringUtils;
34 import org.openide.nodes.Node;
35 import org.openide.util.NbBundle;
36 import org.openide.util.lookup.ServiceProvider;
45 import static org.
sleuthkit.datamodel.BlackboardArtifact.ARTIFACT_TYPE.TSK_ASSOCIATED_OBJECT;
55 @ServiceProvider(service = DataContentViewer.class, position = 8)
58 private static final long serialVersionUID = 1L;
60 private static final int ARTIFACT_STR_MAX_LEN = 1024;
61 private static final int ATTRIBUTE_STR_MAX_LEN = 200;
63 private final static Insets FIRST_HEADER_INSETS =
new Insets(0, 0, 0, 0);
68 private static final List<BlackboardArtifact.ARTIFACT_TYPE> CONTEXT_ARTIFACTS =
new ArrayList<>();
69 private final List<ContextSourcePanel> contextSourcePanels =
new ArrayList<>();
70 private final List<ContextUsagePanel> contextUsagePanels =
new ArrayList<>();
73 CONTEXT_ARTIFACTS.add(TSK_ASSOCIATED_OBJECT);
82 jScrollPane.setHorizontalScrollBarPolicy(HORIZONTAL_SCROLLBAR_AS_NEEDED);
90 @SuppressWarnings(
"unchecked")
92 private
void initComponents() {
94 jSourcePanel =
new javax.swing.JPanel();
95 javax.swing.JLabel jSourceLabel =
new javax.swing.JLabel();
96 jUsagePanel =
new javax.swing.JPanel();
97 javax.swing.JLabel jUsageLabel =
new javax.swing.JLabel();
98 jUnknownPanel =
new javax.swing.JPanel();
99 javax.swing.JLabel jUnknownLabel =
new javax.swing.JLabel();
100 jScrollPane =
new javax.swing.JScrollPane();
102 jSourcePanel.setBorder(
new EmptyBorder(FIRST_HEADER_INSETS));
103 jSourcePanel.setLayout(
new javax.swing.BoxLayout(jSourcePanel, javax.swing.BoxLayout.PAGE_AXIS));
106 org.openide.awt.Mnemonics.setLocalizedText(jSourceLabel,
org.openide.util.NbBundle.getMessage(
ContextViewer.class,
"ContextViewer.jSourceLabel.text"));
107 jSourcePanel.add(jSourceLabel);
109 jUsagePanel.setBorder(
new EmptyBorder(HEADER_INSETS));
110 jUsagePanel.setLayout(
new javax.swing.BoxLayout(jUsagePanel, javax.swing.BoxLayout.PAGE_AXIS));
114 org.openide.awt.Mnemonics.setLocalizedText(jUsageLabel,
org.openide.util.NbBundle.getMessage(
ContextViewer.class,
"ContextViewer.jUsageLabel.text"));
115 jUsagePanel.add(jUsageLabel);
117 jUnknownPanel.setLayout(
new javax.swing.BoxLayout(jUnknownPanel, javax.swing.BoxLayout.PAGE_AXIS));
119 org.openide.awt.Mnemonics.setLocalizedText(jUnknownLabel,
org.openide.util.NbBundle.getMessage(
ContextViewer.class,
"ContextViewer.jUnknownLabel.text"));
120 jUnknownLabel.setBorder(
new EmptyBorder(DATA_ROW_INSETS));
121 jUnknownPanel.add(jUnknownLabel);
123 setPreferredSize(
new java.awt.Dimension(0, 0));
125 jScrollPane.setPreferredSize(
new java.awt.Dimension(16, 16));
127 javax.swing.GroupLayout layout =
new javax.swing.GroupLayout(
this);
128 this.setLayout(layout);
129 layout.setHorizontalGroup(
130 layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
131 .addComponent(jScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, 509, Short.MAX_VALUE)
133 layout.setVerticalGroup(
134 layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
135 .addComponent(jScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, 335, Short.MAX_VALUE)
141 if ((selectedNode == null) || (!isSupported(selectedNode))) {
146 AbstractFile file = selectedNode.getLookup().lookup(AbstractFile.class);
148 populatePanels(file);
150 logger.log(Level.SEVERE, String.format(
"Exception displaying context for file %s", file.getName()), ex);
155 "ContextViewer.title=Context",
156 "ContextViewer.toolTip=Displays context for selected file."
161 return Bundle.ContextViewer_title();
166 return Bundle.ContextViewer_toolTip();
181 contextSourcePanels.clear();
182 contextUsagePanels.clear();
189 if (node.getLookup().lookup(AbstractFile.class) != null) {
190 AbstractFile abstractFile = node.getLookup().lookup(AbstractFile.class);
191 for (BlackboardArtifact.ARTIFACT_TYPE artifactType : CONTEXT_ARTIFACTS) {
192 List<BlackboardArtifact> artifactsList;
194 artifactsList = abstractFile.getArtifacts(artifactType);
195 if (!artifactsList.isEmpty()) {
198 }
catch (TskCoreException ex) {
199 logger.log(Level.SEVERE, String.format(
"Exception while looking up context artifacts for file %s", abstractFile), ex);
215 "ContextViewer.unknownSource=Unknown ",
231 boolean foundASource =
false;
232 for (BlackboardArtifact.ARTIFACT_TYPE artifactType : CONTEXT_ARTIFACTS) {
233 List<BlackboardArtifact> artifactsList = tskCase.getBlackboardArtifacts(artifactType, sourceFile.getId());
235 foundASource = !artifactsList.isEmpty();
236 for (BlackboardArtifact contextArtifact : artifactsList) {
237 addAssociatedArtifactToPanel(contextArtifact);
240 javax.swing.JPanel contextContainer =
new javax.swing.JPanel();
241 contextContainer.setLayout(
new BoxLayout(contextContainer, BoxLayout.Y_AXIS));
244 contextContainer.add(jSourcePanel);
246 if (contextSourcePanels.isEmpty()) {
247 contextContainer.add(jUnknownPanel);
249 for (javax.swing.JPanel sourcePanel : contextSourcePanels) {
250 contextContainer.add(sourcePanel);
251 contextContainer.setAlignmentX(0);
254 contextContainer.add(jUsagePanel);
255 if (contextUsagePanels.isEmpty()) {
256 contextContainer.add(jUnknownPanel);
258 for (javax.swing.JPanel usagePanel : contextUsagePanels) {
259 contextContainer.add(usagePanel);
260 contextContainer.setAlignmentX(0);
265 contextContainer.setEnabled(foundASource);
266 contextContainer.setVisible(foundASource);
267 jScrollPane.getViewport().setView(contextContainer);
268 jScrollPane.setEnabled(foundASource);
269 jScrollPane.setVisible(foundASource);
270 jScrollPane.repaint();
271 jScrollPane.revalidate();
286 if (BlackboardArtifact.ARTIFACT_TYPE.TSK_ASSOCIATED_OBJECT.getTypeID() == artifact.getArtifactTypeID()) {
287 BlackboardAttribute associatedArtifactAttribute = artifact.getAttribute(
new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_ASSOCIATED_ARTIFACT));
288 if (associatedArtifactAttribute != null) {
289 long artifactId = associatedArtifactAttribute.getValueLong();
290 BlackboardArtifact associatedArtifact = artifact.getSleuthkitCase().getBlackboardArtifact(artifactId);
292 addArtifactToPanels(associatedArtifact);
305 "ContextViewer.attachmentSource=Attached to: ",
306 "ContextViewer.downloadSource=Downloaded from: ",
307 "ContextViewer.recentDocs=Recent Documents: ",
308 "ContextViewer.programExecution=Program Execution: "
311 Long dateTime = getArtifactDateTime(associatedArtifact);
312 if (BlackboardArtifact.ARTIFACT_TYPE.TSK_MESSAGE.getTypeID() == associatedArtifact.getArtifactTypeID()
313 || BlackboardArtifact.ARTIFACT_TYPE.TSK_EMAIL_MSG.getTypeID() == associatedArtifact.getArtifactTypeID()) {
314 String sourceName = Bundle.ContextViewer_attachmentSource();
315 String sourceText = msgArtifactToAbbreviatedString(associatedArtifact);
317 sourcePanel.setBorder(
new EmptyBorder(DATA_ROW_INSETS));
318 sourcePanel.setAlignmentX(0);
319 contextSourcePanels.add(sourcePanel);
321 }
else if (BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_DOWNLOAD.getTypeID() == associatedArtifact.getArtifactTypeID()
322 || BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_CACHE.getTypeID() == associatedArtifact.getArtifactTypeID()) {
323 String sourceName = Bundle.ContextViewer_downloadSource();
324 String sourceText = webDownloadArtifactToString(associatedArtifact);
326 sourcePanel.setBorder(
new EmptyBorder(DATA_ROW_INSETS));
327 sourcePanel.setAlignmentX(0);
328 contextSourcePanels.add(sourcePanel);
330 }
else if (BlackboardArtifact.ARTIFACT_TYPE.TSK_RECENT_OBJECT.getTypeID() == associatedArtifact.getArtifactTypeID()) {
331 String sourceName = Bundle.ContextViewer_recentDocs();
332 String sourceText = recentDocArtifactToString(associatedArtifact);
334 usagePanel.setBorder(
new EmptyBorder(DATA_ROW_INSETS));
335 usagePanel.setAlignmentX(0);
336 contextUsagePanels.add(usagePanel);
338 }
else if (BlackboardArtifact.ARTIFACT_TYPE.TSK_PROG_RUN.getTypeID() == associatedArtifact.getArtifactTypeID()) {
339 String sourceName = Bundle.ContextViewer_programExecution();
340 String sourceText = programExecArtifactToString(associatedArtifact);
342 usagePanel.setBorder(
new EmptyBorder(DATA_ROW_INSETS));
343 usagePanel.setAlignmentX(0);
344 contextUsagePanels.add(usagePanel);
347 Collections.sort(contextSourcePanels,
new SortByDateTime());
348 Collections.sort(contextUsagePanels,
new SortByDateTime());
362 "ContextViewer.downloadURL=URL",
363 "ContextViewer.downloadedOn=On"
366 StringBuilder sb =
new StringBuilder(ARTIFACT_STR_MAX_LEN);
367 Map<BlackboardAttribute.ATTRIBUTE_TYPE, BlackboardAttribute> attributesMap = getAttributesMap(artifact);
369 if (BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_DOWNLOAD.getTypeID() == artifact.getArtifactTypeID()
370 || BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_CACHE.getTypeID() == artifact.getArtifactTypeID()) {
371 appendAttributeString(sb, BlackboardAttribute.ATTRIBUTE_TYPE.TSK_URL, attributesMap, Bundle.ContextViewer_downloadURL());
372 appendAttributeString(sb, BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME_CREATED, attributesMap, Bundle.ContextViewer_downloadedOn());
374 return sb.toString();
388 "ContextViewer.on=Opened at",
389 "ContextViewer.unknown=Opened at unknown time"
392 StringBuilder sb =
new StringBuilder(ARTIFACT_STR_MAX_LEN);
393 Map<BlackboardAttribute.ATTRIBUTE_TYPE, BlackboardAttribute> attributesMap = getAttributesMap(artifact);
395 BlackboardAttribute attribute = attributesMap.get(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME);
397 if (BlackboardArtifact.ARTIFACT_TYPE.TSK_RECENT_OBJECT.getTypeID() == artifact.getArtifactTypeID()) {
398 if (attribute != null && attribute.getValueLong() > 0) {
399 appendAttributeString(sb, BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME, attributesMap, Bundle.ContextViewer_on());
401 sb.append(Bundle.ContextViewer_unknown());
404 return sb.toString();
418 "ContextViewer.runOn=Program Run On",
419 "ContextViewer.runUnknown= Program Run at unknown time"
422 StringBuilder sb =
new StringBuilder(ARTIFACT_STR_MAX_LEN);
423 Map<BlackboardAttribute.ATTRIBUTE_TYPE, BlackboardAttribute> attributesMap = getAttributesMap(artifact);
425 BlackboardAttribute attribute = attributesMap.get(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME);
427 if (BlackboardArtifact.ARTIFACT_TYPE.TSK_PROG_RUN.getTypeID() == artifact.getArtifactTypeID()) {
428 if (attribute != null && attribute.getValueLong() > 0) {
429 appendAttributeString(sb, BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME, attributesMap, Bundle.ContextViewer_runOn());
431 sb.append(Bundle.ContextViewer_runUnknown());
434 return sb.toString();
447 "ContextViewer.message=Message",
448 "ContextViewer.email=Email",
449 "ContextViewer.messageFrom=From",
450 "ContextViewer.messageTo=To",
451 "ContextViewer.messageOn=On",})
454 StringBuilder sb =
new StringBuilder(ARTIFACT_STR_MAX_LEN);
455 Map<BlackboardAttribute.ATTRIBUTE_TYPE, BlackboardAttribute> attributesMap = getAttributesMap(artifact);
457 if (BlackboardArtifact.ARTIFACT_TYPE.TSK_MESSAGE.getTypeID() == artifact.getArtifactTypeID()) {
458 sb.append(Bundle.ContextViewer_message()).append(
' ');
459 appendAttributeString(sb, BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PHONE_NUMBER_FROM, attributesMap, Bundle.ContextViewer_messageFrom());
460 appendAttributeString(sb, BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PHONE_NUMBER_TO, attributesMap, Bundle.ContextViewer_messageTo());
461 appendAttributeString(sb, BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME, attributesMap, Bundle.ContextViewer_messageOn());
462 }
else if (BlackboardArtifact.ARTIFACT_TYPE.TSK_EMAIL_MSG.getTypeID() == artifact.getArtifactTypeID()) {
463 sb.append(Bundle.ContextViewer_email()).append(
' ');
464 appendAttributeString(sb, BlackboardAttribute.ATTRIBUTE_TYPE.TSK_EMAIL_FROM, attributesMap, Bundle.ContextViewer_messageFrom());
465 appendAttributeString(sb, BlackboardAttribute.ATTRIBUTE_TYPE.TSK_EMAIL_TO, attributesMap, Bundle.ContextViewer_messageTo());
466 appendAttributeString(sb, BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME_SENT, attributesMap, Bundle.ContextViewer_messageOn());
468 return sb.toString();
482 Map<BlackboardAttribute.ATTRIBUTE_TYPE, BlackboardAttribute> attributesMap, String prependStr) {
484 BlackboardAttribute attribute = attributesMap.get(attribType);
485 if (attribute != null) {
486 String attrVal = attribute.getDisplayString();
487 if (!StringUtils.isEmpty(attrVal)) {
488 if (!StringUtils.isEmpty(prependStr)) {
489 sb.append(prependStr).append(
' ');
491 sb.append(StringUtils.abbreviate(attrVal, ATTRIBUTE_STR_MAX_LEN)).append(
' ');
506 private Map<BlackboardAttribute.ATTRIBUTE_TYPE, BlackboardAttribute>
getAttributesMap(BlackboardArtifact artifact)
throws TskCoreException {
507 Map<BlackboardAttribute.ATTRIBUTE_TYPE, BlackboardAttribute> attributeMap =
new HashMap<>();
509 List<BlackboardAttribute> attributeList = artifact.getAttributes();
510 for (BlackboardAttribute attribute : attributeList) {
511 BlackboardAttribute.ATTRIBUTE_TYPE type = BlackboardAttribute.ATTRIBUTE_TYPE.fromID(attribute.getAttributeType().getTypeID());
512 attributeMap.put(type, attribute);
518 interface DateTimePanel {
537 BlackboardAttribute attribute = artifact.getAttribute(
new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME));
539 if (BlackboardArtifact.ARTIFACT_TYPE.TSK_EMAIL_MSG.getTypeID() == artifact.getArtifactTypeID()) {
540 attribute = artifact.getAttribute(
new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME_SENT));
541 }
else if (BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_DOWNLOAD.getTypeID() == artifact.getArtifactTypeID()
542 || BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_CACHE.getTypeID() == artifact.getArtifactTypeID()) {
543 attribute = artifact.getAttribute(
new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME_CREATED));
545 return (attribute != null ? attribute.getValueLong() : null);
551 class SortByDateTime
implements Comparator<DateTimePanel> {
554 public int compare(DateTimePanel panel1, DateTimePanel panel2) {
555 Long dateTime1 = panel1.getDateTime();
556 Long dateTime2 = panel2.getDateTime();
558 if(dateTime1 == null && dateTime2 == null) {
560 }
else if(dateTime1 == null) {
562 }
else if(dateTime2 == null) {
566 return dateTime1.compareTo(dateTime2);
javax.swing.JPanel jSourcePanel
void addAssociatedArtifactToPanel(BlackboardArtifact artifact)
static Integer getLineSpacing()
static Insets getPanelInsets()
String webDownloadArtifactToString(BlackboardArtifact artifact)
javax.swing.JPanel jUnknownPanel
static Integer getSectionIndent()
String recentDocArtifactToString(BlackboardArtifact artifact)
Map< BlackboardAttribute.ATTRIBUTE_TYPE, BlackboardAttribute > getAttributesMap(BlackboardArtifact artifact)
void appendAttributeString(StringBuilder sb, BlackboardAttribute.ATTRIBUTE_TYPE attribType, Map< BlackboardAttribute.ATTRIBUTE_TYPE, BlackboardAttribute > attributesMap, String prependStr)
static Color getPanelBackground()
void setNode(Node selectedNode)
static Font getHeaderFont()
javax.swing.JPanel jUsagePanel
int isPreferred(Node node)
SleuthkitCase getSleuthkitCase()
String programExecArtifactToString(BlackboardArtifact artifact)
boolean isSupported(Node node)
void populatePanels(AbstractFile sourceFile)
static Integer getSectionSpacing()
void addArtifactToPanels(BlackboardArtifact associatedArtifact)
synchronized static Logger getLogger(String name)
Long getArtifactDateTime(BlackboardArtifact artifact)
static Case getCurrentCaseThrows()
String msgArtifactToAbbreviatedString(BlackboardArtifact artifact)
DataContentViewer createInstance()
javax.swing.JScrollPane jScrollPane