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;
44 import static org.
sleuthkit.datamodel.BlackboardArtifact.ARTIFACT_TYPE.TSK_ASSOCIATED_OBJECT;
54 @ServiceProvider(service = DataContentViewer.class, position = 8)
57 private static final long serialVersionUID = 1L;
59 private static final int ARTIFACT_STR_MAX_LEN = 1024;
60 private static final int ATTRIBUTE_STR_MAX_LEN = 200;
62 private final static Insets FIRST_HEADER_INSETS =
new Insets(0, 0, 0, 0);
67 private static final List<BlackboardArtifact.ARTIFACT_TYPE> CONTEXT_ARTIFACTS =
new ArrayList<>();
68 private final List<ContextSourcePanel> contextSourcePanels =
new ArrayList<>();
69 private final List<ContextUsagePanel> contextUsagePanels =
new ArrayList<>();
72 CONTEXT_ARTIFACTS.add(TSK_ASSOCIATED_OBJECT);
81 jScrollPane.setHorizontalScrollBarPolicy(HORIZONTAL_SCROLLBAR_AS_NEEDED);
89 @SuppressWarnings(
"unchecked")
91 private
void initComponents() {
93 jSourcePanel =
new javax.swing.JPanel();
94 javax.swing.JLabel jSourceLabel =
new javax.swing.JLabel();
95 jUsagePanel =
new javax.swing.JPanel();
96 javax.swing.JLabel jUsageLabel =
new javax.swing.JLabel();
97 jUnknownPanel =
new javax.swing.JPanel();
98 javax.swing.JLabel jUnknownLabel =
new javax.swing.JLabel();
99 jScrollPane =
new javax.swing.JScrollPane();
101 jSourcePanel.setBorder(
new EmptyBorder(FIRST_HEADER_INSETS));
102 jSourcePanel.setLayout(
new javax.swing.BoxLayout(jSourcePanel, javax.swing.BoxLayout.PAGE_AXIS));
105 org.openide.awt.Mnemonics.setLocalizedText(jSourceLabel,
org.openide.util.NbBundle.getMessage(
ContextViewer.class,
"ContextViewer.jSourceLabel.text"));
106 jSourcePanel.add(jSourceLabel);
108 jUsagePanel.setBorder(
new EmptyBorder(HEADER_INSETS));
109 jUsagePanel.setLayout(
new javax.swing.BoxLayout(jUsagePanel, javax.swing.BoxLayout.PAGE_AXIS));
113 org.openide.awt.Mnemonics.setLocalizedText(jUsageLabel,
org.openide.util.NbBundle.getMessage(
ContextViewer.class,
"ContextViewer.jUsageLabel.text"));
114 jUsagePanel.add(jUsageLabel);
116 jUnknownPanel.setLayout(
new javax.swing.BoxLayout(jUnknownPanel, javax.swing.BoxLayout.PAGE_AXIS));
118 org.openide.awt.Mnemonics.setLocalizedText(jUnknownLabel,
org.openide.util.NbBundle.getMessage(
ContextViewer.class,
"ContextViewer.jUnknownLabel.text"));
119 jUnknownLabel.setBorder(
new EmptyBorder(DATA_ROW_INSETS));
120 jUnknownPanel.add(jUnknownLabel);
122 setPreferredSize(
new java.awt.Dimension(0, 0));
124 jScrollPane.setPreferredSize(
new java.awt.Dimension(16, 16));
126 javax.swing.GroupLayout layout =
new javax.swing.GroupLayout(
this);
127 this.setLayout(layout);
128 layout.setHorizontalGroup(
129 layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
130 .addComponent(jScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, 509, Short.MAX_VALUE)
132 layout.setVerticalGroup(
133 layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
134 .addComponent(jScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, 335, Short.MAX_VALUE)
140 if ((selectedNode == null) || (!isSupported(selectedNode))) {
145 AbstractFile file = selectedNode.getLookup().lookup(AbstractFile.class);
147 populatePanels(file);
149 logger.log(Level.SEVERE, String.format(
"Exception displaying context for file %s", file.getName()), ex);
154 "ContextViewer.title=Context",
155 "ContextViewer.toolTip=Displays context for selected file."
160 return Bundle.ContextViewer_title();
165 return Bundle.ContextViewer_toolTip();
180 contextSourcePanels.clear();
181 contextUsagePanels.clear();
188 if (node.getLookup().lookup(AbstractFile.class) != null) {
189 AbstractFile abstractFile = node.getLookup().lookup(AbstractFile.class);
190 for (BlackboardArtifact.ARTIFACT_TYPE artifactType : CONTEXT_ARTIFACTS) {
191 List<BlackboardArtifact> artifactsList;
193 artifactsList = abstractFile.getArtifacts(artifactType);
194 if (!artifactsList.isEmpty()) {
197 }
catch (TskCoreException ex) {
198 logger.log(Level.SEVERE, String.format(
"Exception while looking up context artifacts for file %s", abstractFile), ex);
214 "ContextViewer.unknownSource=Unknown ",
230 boolean foundASource =
false;
231 for (BlackboardArtifact.ARTIFACT_TYPE artifactType : CONTEXT_ARTIFACTS) {
232 List<BlackboardArtifact> artifactsList = tskCase.getBlackboardArtifacts(artifactType, sourceFile.getId());
234 foundASource = !artifactsList.isEmpty();
235 for (BlackboardArtifact contextArtifact : artifactsList) {
236 addAssociatedArtifactToPanel(contextArtifact);
239 javax.swing.JPanel contextContainer =
new javax.swing.JPanel();
240 contextContainer.setLayout(
new BoxLayout(contextContainer, BoxLayout.Y_AXIS));
243 contextContainer.add(jSourcePanel);
245 if (contextSourcePanels.isEmpty()) {
246 contextContainer.add(jUnknownPanel);
248 for (javax.swing.JPanel sourcePanel : contextSourcePanels) {
249 contextContainer.add(sourcePanel);
250 contextContainer.setAlignmentX(0);
253 contextContainer.add(jUsagePanel);
254 if (contextUsagePanels.isEmpty()) {
255 contextContainer.add(jUnknownPanel);
257 for (javax.swing.JPanel usagePanel : contextUsagePanels) {
258 contextContainer.add(usagePanel);
259 contextContainer.setAlignmentX(0);
264 contextContainer.setEnabled(foundASource);
265 contextContainer.setVisible(foundASource);
266 jScrollPane.getViewport().setView(contextContainer);
267 jScrollPane.setEnabled(foundASource);
268 jScrollPane.setVisible(foundASource);
269 jScrollPane.repaint();
270 jScrollPane.revalidate();
285 if (BlackboardArtifact.ARTIFACT_TYPE.TSK_ASSOCIATED_OBJECT.getTypeID() == artifact.getArtifactTypeID()) {
286 BlackboardAttribute associatedArtifactAttribute = artifact.getAttribute(
new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_ASSOCIATED_ARTIFACT));
287 if (associatedArtifactAttribute != null) {
288 long artifactId = associatedArtifactAttribute.getValueLong();
289 BlackboardArtifact associatedArtifact = artifact.getSleuthkitCase().getBlackboardArtifact(artifactId);
291 addArtifactToPanels(associatedArtifact);
304 "ContextViewer.attachmentSource=Attached to: ",
305 "ContextViewer.downloadSource=Downloaded from: ",
306 "ContextViewer.recentDocs=Recent Documents: ",
307 "ContextViewer.programExecution=Program Execution: "
310 Long dateTime = getArtifactDateTime(associatedArtifact);
311 if (BlackboardArtifact.ARTIFACT_TYPE.TSK_MESSAGE.getTypeID() == associatedArtifact.getArtifactTypeID()
312 || BlackboardArtifact.ARTIFACT_TYPE.TSK_EMAIL_MSG.getTypeID() == associatedArtifact.getArtifactTypeID()) {
313 String sourceName = Bundle.ContextViewer_attachmentSource();
314 String sourceText = msgArtifactToAbbreviatedString(associatedArtifact);
316 sourcePanel.setBorder(
new EmptyBorder(DATA_ROW_INSETS));
317 sourcePanel.setAlignmentX(0);
318 contextSourcePanels.add(sourcePanel);
320 }
else if (BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_DOWNLOAD.getTypeID() == associatedArtifact.getArtifactTypeID()
321 || BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_CACHE.getTypeID() == associatedArtifact.getArtifactTypeID()) {
322 String sourceName = Bundle.ContextViewer_downloadSource();
323 String sourceText = webDownloadArtifactToString(associatedArtifact);
325 sourcePanel.setBorder(
new EmptyBorder(DATA_ROW_INSETS));
326 sourcePanel.setAlignmentX(0);
327 contextSourcePanels.add(sourcePanel);
329 }
else if (BlackboardArtifact.ARTIFACT_TYPE.TSK_RECENT_OBJECT.getTypeID() == associatedArtifact.getArtifactTypeID()) {
330 String sourceName = Bundle.ContextViewer_recentDocs();
331 String sourceText = recentDocArtifactToString(associatedArtifact);
333 usagePanel.setBorder(
new EmptyBorder(DATA_ROW_INSETS));
334 usagePanel.setAlignmentX(0);
335 contextUsagePanels.add(usagePanel);
337 }
else if (BlackboardArtifact.ARTIFACT_TYPE.TSK_PROG_RUN.getTypeID() == associatedArtifact.getArtifactTypeID()) {
338 String sourceName = Bundle.ContextViewer_programExecution();
339 String sourceText = programExecArtifactToString(associatedArtifact);
341 usagePanel.setBorder(
new EmptyBorder(DATA_ROW_INSETS));
342 usagePanel.setAlignmentX(0);
343 contextUsagePanels.add(usagePanel);
346 Collections.sort(contextSourcePanels,
new SortByDateTime());
347 Collections.sort(contextUsagePanels,
new SortByDateTime());
361 "ContextViewer.downloadURL=URL",
362 "ContextViewer.downloadedOn=On"
365 StringBuilder sb =
new StringBuilder(ARTIFACT_STR_MAX_LEN);
366 Map<BlackboardAttribute.ATTRIBUTE_TYPE, BlackboardAttribute> attributesMap = getAttributesMap(artifact);
368 if (BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_DOWNLOAD.getTypeID() == artifact.getArtifactTypeID()
369 || BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_CACHE.getTypeID() == artifact.getArtifactTypeID()) {
370 appendAttributeString(sb, BlackboardAttribute.ATTRIBUTE_TYPE.TSK_URL, attributesMap, Bundle.ContextViewer_downloadURL());
371 appendAttributeString(sb, BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME_CREATED, attributesMap, Bundle.ContextViewer_downloadedOn());
373 return sb.toString();
387 "ContextViewer.on=Opened at",
388 "ContextViewer.unknown=Opened at unknown time"
391 StringBuilder sb =
new StringBuilder(ARTIFACT_STR_MAX_LEN);
392 Map<BlackboardAttribute.ATTRIBUTE_TYPE, BlackboardAttribute> attributesMap = getAttributesMap(artifact);
394 BlackboardAttribute attribute = attributesMap.get(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME);
396 if (BlackboardArtifact.ARTIFACT_TYPE.TSK_RECENT_OBJECT.getTypeID() == artifact.getArtifactTypeID()) {
397 if (attribute != null && attribute.getValueLong() > 0) {
398 appendAttributeString(sb, BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME, attributesMap, Bundle.ContextViewer_on());
400 sb.append(Bundle.ContextViewer_unknown());
403 return sb.toString();
417 "ContextViewer.runOn=Program Run On",
418 "ContextViewer.runUnknown= Program Run at unknown time"
421 StringBuilder sb =
new StringBuilder(ARTIFACT_STR_MAX_LEN);
422 Map<BlackboardAttribute.ATTRIBUTE_TYPE, BlackboardAttribute> attributesMap = getAttributesMap(artifact);
424 BlackboardAttribute attribute = attributesMap.get(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME);
426 if (BlackboardArtifact.ARTIFACT_TYPE.TSK_PROG_RUN.getTypeID() == artifact.getArtifactTypeID()) {
427 if (attribute != null && attribute.getValueLong() > 0) {
428 appendAttributeString(sb, BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME, attributesMap, Bundle.ContextViewer_runOn());
430 sb.append(Bundle.ContextViewer_runUnknown());
433 return sb.toString();
446 "ContextViewer.message=Message",
447 "ContextViewer.email=Email",
448 "ContextViewer.messageFrom=From",
449 "ContextViewer.messageTo=To",
450 "ContextViewer.messageOn=On",})
453 StringBuilder sb =
new StringBuilder(ARTIFACT_STR_MAX_LEN);
454 Map<BlackboardAttribute.ATTRIBUTE_TYPE, BlackboardAttribute> attributesMap = getAttributesMap(artifact);
456 if (BlackboardArtifact.ARTIFACT_TYPE.TSK_MESSAGE.getTypeID() == artifact.getArtifactTypeID()) {
457 sb.append(Bundle.ContextViewer_message()).append(
' ');
458 appendAttributeString(sb, BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PHONE_NUMBER_FROM, attributesMap, Bundle.ContextViewer_messageFrom());
459 appendAttributeString(sb, BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PHONE_NUMBER_TO, attributesMap, Bundle.ContextViewer_messageTo());
460 appendAttributeString(sb, BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME, attributesMap, Bundle.ContextViewer_messageOn());
461 }
else if (BlackboardArtifact.ARTIFACT_TYPE.TSK_EMAIL_MSG.getTypeID() == artifact.getArtifactTypeID()) {
462 sb.append(Bundle.ContextViewer_email()).append(
' ');
463 appendAttributeString(sb, BlackboardAttribute.ATTRIBUTE_TYPE.TSK_EMAIL_FROM, attributesMap, Bundle.ContextViewer_messageFrom());
464 appendAttributeString(sb, BlackboardAttribute.ATTRIBUTE_TYPE.TSK_EMAIL_TO, attributesMap, Bundle.ContextViewer_messageTo());
465 appendAttributeString(sb, BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME_SENT, attributesMap, Bundle.ContextViewer_messageOn());
467 return sb.toString();
481 Map<BlackboardAttribute.ATTRIBUTE_TYPE, BlackboardAttribute> attributesMap, String prependStr) {
483 BlackboardAttribute attribute = attributesMap.get(attribType);
484 if (attribute != null) {
485 String attrVal = attribute.getDisplayString();
486 if (!StringUtils.isEmpty(attrVal)) {
487 if (!StringUtils.isEmpty(prependStr)) {
488 sb.append(prependStr).append(
' ');
490 sb.append(StringUtils.abbreviate(attrVal, ATTRIBUTE_STR_MAX_LEN)).append(
' ');
505 private Map<BlackboardAttribute.ATTRIBUTE_TYPE, BlackboardAttribute>
getAttributesMap(BlackboardArtifact artifact)
throws TskCoreException {
506 Map<BlackboardAttribute.ATTRIBUTE_TYPE, BlackboardAttribute> attributeMap =
new HashMap<>();
508 List<BlackboardAttribute> attributeList = artifact.getAttributes();
509 for (BlackboardAttribute attribute : attributeList) {
510 BlackboardAttribute.ATTRIBUTE_TYPE type = BlackboardAttribute.ATTRIBUTE_TYPE.fromID(attribute.getAttributeType().getTypeID());
511 attributeMap.put(type, attribute);
517 interface DateTimePanel {
536 BlackboardAttribute attribute = artifact.getAttribute(
new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME));
538 if (BlackboardArtifact.ARTIFACT_TYPE.TSK_EMAIL_MSG.getTypeID() == artifact.getArtifactTypeID()) {
539 attribute = artifact.getAttribute(
new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME_SENT));
540 }
else if (BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_DOWNLOAD.getTypeID() == artifact.getArtifactTypeID()
541 || BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_CACHE.getTypeID() == artifact.getArtifactTypeID()) {
542 attribute = artifact.getAttribute(
new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME_CREATED));
544 return (attribute != null ? attribute.getValueLong() : null);
550 class SortByDateTime
implements Comparator<DateTimePanel> {
553 public int compare(DateTimePanel panel1, DateTimePanel panel2) {
554 Long dateTime1 = panel1.getDateTime();
555 Long dateTime2 = panel2.getDateTime();
557 if(dateTime1 == null && dateTime2 == null) {
559 }
else if(dateTime1 == null) {
561 }
else if(dateTime2 == null) {
565 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