Autopsy  4.8.0
Graphical digital forensics platform for The Sleuth Kit and other tools.
AnnotationsContentViewer.java
Go to the documentation of this file.
1 /*
2  * Autopsy Forensic Browser
3  *
4  * Copyright 2018 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;
20 
21 import java.awt.Component;
22 import java.util.ArrayList;
23 import java.util.List;
24 import java.util.logging.Level;
25 import org.apache.commons.lang3.StringEscapeUtils;
26 
27 import org.openide.util.NbBundle;
29 import org.openide.nodes.Node;
30 import org.openide.util.lookup.ServiceProvider;
41 import org.sleuthkit.datamodel.AbstractFile;
42 import org.sleuthkit.datamodel.BlackboardArtifact;
43 import org.sleuthkit.datamodel.BlackboardArtifactTag;
44 import org.sleuthkit.datamodel.Content;
45 import org.sleuthkit.datamodel.ContentTag;
46 import org.sleuthkit.datamodel.SleuthkitCase;
47 import org.sleuthkit.datamodel.Tag;
48 import org.sleuthkit.datamodel.TskCoreException;
49 
53 @SuppressWarnings("PMD.SingularField") // UI widgets cause lots of false positives
54 @ServiceProvider(service = DataContentViewer.class, position = 8)
55 @NbBundle.Messages({
56  "AnnotationsContentViewer.title=Annotations",
57  "AnnotationsContentViewer.toolTip=Displays tags and comments associated with the selected content."
58 })
59 public class AnnotationsContentViewer extends javax.swing.JPanel implements DataContentViewer {
60 
61  private static final Logger logger = Logger.getLogger(AnnotationsContentViewer.class.getName());
62 
67  initComponents();
69  }
70 
71  @Override
72  public void setNode(Node node) {
73  if ((node == null) || (!isSupported(node))) {
74  resetComponent();
75  return;
76  }
77 
78  StringBuilder html = new StringBuilder();
79 
80  BlackboardArtifact artifact = node.getLookup().lookup(BlackboardArtifact.class);
81  Content sourceFile = null;
82 
83  try {
84  if (artifact != null) {
85  /*
86  * Get the source content based on the artifact to ensure we
87  * display the correct data instead of whatever was in the node.
88  */
89  sourceFile = artifact.getSleuthkitCase().getAbstractFileById(artifact.getObjectID());
90  } else {
91  /*
92  * No artifact is present, so get the content based on what's
93  * present in the node. In this case, the selected item IS the
94  * source file.
95  */
96  sourceFile = node.getLookup().lookup(AbstractFile.class);
97  }
98  } catch (TskCoreException ex) {
99  logger.log(Level.SEVERE, String.format(
100  "Exception while trying to retrieve a Content instance from the BlackboardArtifact '%s' (id=%d).",
101  artifact.getDisplayName(), artifact.getArtifactID()), ex);
102  }
103 
104  if (artifact != null) {
105  populateTagData(html, artifact, sourceFile);
106  } else {
107  populateTagData(html, sourceFile);
108  }
109 
110  if (sourceFile instanceof AbstractFile) {
111  populateCentralRepositoryData(html, artifact, (AbstractFile) sourceFile);
112  }
113 
114  setText(html.toString());
115  jTextPane1.setCaretPosition(0);
116  }
117 
125  private void populateTagData(StringBuilder html, Content content) {
126  try {
127  SleuthkitCase tskCase = Case.getCurrentCaseThrows().getSleuthkitCase();
128 
129  startSection(html, "Selected Item");
130  List<ContentTag> fileTagsList = tskCase.getContentTagsByContent(content);
131  if (fileTagsList.isEmpty()) {
132  addMessage(html, "There are no tags for the selected content.");
133  } else {
134  for (ContentTag tag : fileTagsList) {
135  addTagEntry(html, tag);
136  }
137  }
138  endSection(html);
139  } catch (NoCurrentCaseException ex) {
140  logger.log(Level.SEVERE, "Exception while getting open case.", ex); // NON-NLS
141  } catch (TskCoreException ex) {
142  logger.log(Level.SEVERE, "Exception while getting tags from the case database.", ex); //NON-NLS
143  }
144  }
145 
154  private void populateTagData(StringBuilder html, BlackboardArtifact artifact, Content sourceFile) {
155  try {
156  SleuthkitCase tskCase = Case.getCurrentCaseThrows().getSleuthkitCase();
157 
158  startSection(html, "Selected Item");
159  List<BlackboardArtifactTag> artifactTagsList = tskCase.getBlackboardArtifactTagsByArtifact(artifact);
160  if (artifactTagsList.isEmpty()) {
161  addMessage(html, "There are no tags for the selected artifact.");
162  } else {
163  for (BlackboardArtifactTag tag : artifactTagsList) {
164  addTagEntry(html, tag);
165  }
166  }
167  endSection(html);
168 
169  if (sourceFile != null) {
170  startSection(html, "Source File");
171  List<ContentTag> fileTagsList = tskCase.getContentTagsByContent(sourceFile);
172  if (fileTagsList.isEmpty()) {
173  addMessage(html, "There are no tags for the source content.");
174  } else {
175  for (ContentTag tag : fileTagsList) {
176  addTagEntry(html, tag);
177  }
178  }
179  endSection(html);
180  }
181  } catch (NoCurrentCaseException ex) {
182  logger.log(Level.SEVERE, "Exception while getting open case.", ex); // NON-NLS
183  } catch (TskCoreException ex) {
184  logger.log(Level.SEVERE, "Exception while getting tags from the case database.", ex); //NON-NLS
185  }
186  }
187 
196  private void populateCentralRepositoryData(StringBuilder html, BlackboardArtifact artifact, AbstractFile sourceFile) {
197  if (EamDb.isEnabled()) {
198  startSection(html, "Central Repository Comments");
199  List<CorrelationAttributeInstance> instancesList = new ArrayList<>();
200  if (artifact != null) {
201  instancesList.addAll(EamArtifactUtil.makeInstancesFromBlackboardArtifact(artifact, false));
202  }
203  try {
205  String md5 = sourceFile.getMd5Hash();
206  if (md5 != null && !md5.isEmpty() && null != artifactTypes && !artifactTypes.isEmpty()) {
207  for (CorrelationAttributeInstance.Type attributeType : artifactTypes) {
208  if (attributeType.getId() == CorrelationAttributeInstance.FILES_TYPE_ID) {
210  instancesList.add(new CorrelationAttributeInstance(
211  md5,
212  attributeType,
213  correlationCase,
214  CorrelationDataSource.fromTSKDataSource(correlationCase, sourceFile.getDataSource()),
215  sourceFile.getParentPath() + sourceFile.getName(),
216  "",
217  sourceFile.getKnown()));
218  break;
219  }
220  }
221  }
222 
223  boolean commentDataFound = false;
224 
225  for (CorrelationAttributeInstance instance : instancesList) {
226  List<CorrelationAttributeInstance> correlatedInstancesList =
227  EamDb.getInstance().getArtifactInstancesByTypeValue(instance.getCorrelationType(), instance.getCorrelationValue());
228  for (CorrelationAttributeInstance correlatedInstance : correlatedInstancesList) {
229  if (correlatedInstance.getComment() != null && correlatedInstance.getComment().isEmpty() == false) {
230  commentDataFound = true;
231  addCentralRepositoryEntry(html, correlatedInstance);
232  }
233  }
234  }
235 
236  if (commentDataFound == false) {
237  addMessage(html, "There is no comment data for the selected content in the Central Repository.");
238  }
239  } catch (EamDbException | TskCoreException ex) {
240  logger.log(Level.SEVERE, "Error connecting to the Central Repository database.", ex); // NON-NLS
242  logger.log(Level.SEVERE, "Error normalizing instance from Central Repository database.", ex); // NON-NLS
243  }
244  endSection(html);
245  }
246  }
247 
253  private void setText(String text) {
254  jTextPane1.setText("<html><body>" + text + "</body></html>"); //NON-NLS
255  }
256 
263  private void startSection(StringBuilder html, String sectionName) {
264  html.append("<p style=\"font-size:14px;font-weight:bold;\">")
265  .append(sectionName)
266  .append("</p><br>"); //NON-NLS
267  }
268 
275  private void addMessage(StringBuilder html, String message) {
276  html.append("<p style=\"font-size:11px;font-style:italic;\">")
277  .append(message)
278  .append("</p><br>"); //NON-NLS
279  }
280 
287  @NbBundle.Messages({
288  "AnnotationsContentViewer.tagEntryDataLabel.tag=Tag:",
289  "AnnotationsContentViewer.tagEntryDataLabel.tagUser=Tag User:",
290  "AnnotationsContentViewer.tagEntryDataLabel.comment=Comment:"
291  })
292  private void addTagEntry(StringBuilder html, Tag tag) {
293  startTable(html);
294  addRow(html, Bundle.AnnotationsContentViewer_tagEntryDataLabel_tag(), tag.getName().getDisplayName());
295  addRow(html, Bundle.AnnotationsContentViewer_tagEntryDataLabel_tagUser(), tag.getUserName());
296  addRow(html, Bundle.AnnotationsContentViewer_tagEntryDataLabel_comment(), formatHtmlString(tag.getComment()));
297  endTable(html);
298  }
299 
308  @NbBundle.Messages({
309  "AnnotationsContentViewer.centralRepositoryEntryDataLabel.case=Case:",
310  "AnnotationsContentViewer.centralRepositoryEntryDataLabel.type=Type:",
311  "AnnotationsContentViewer.centralRepositoryEntryDataLabel.comment=Comment:",
312  "AnnotationsContentViewer.centralRepositoryEntryDataLabel.path=Path:"
313  })
314  private void addCentralRepositoryEntry(StringBuilder html, CorrelationAttributeInstance attributeInstance) {
315  startTable(html);
316  addRow(html, Bundle.AnnotationsContentViewer_centralRepositoryEntryDataLabel_case(), attributeInstance.getCorrelationCase().getDisplayName());
317  addRow(html, Bundle.AnnotationsContentViewer_centralRepositoryEntryDataLabel_type(), attributeInstance.getCorrelationType().getDisplayName());
318  addRow(html, Bundle.AnnotationsContentViewer_centralRepositoryEntryDataLabel_comment(), formatHtmlString(attributeInstance.getComment()));
319  addRow(html, Bundle.AnnotationsContentViewer_centralRepositoryEntryDataLabel_path(), attributeInstance.getFilePath());
320  endTable(html);
321  }
322 
328  private void startTable(StringBuilder html) {
329  html.append("<table>"); //NON-NLS
330  }
331 
339  private void addRow(StringBuilder html, String key, String value) {
340  html.append("<tr><td valign=\"top\">"); //NON-NLS
341  html.append(key);
342  html.append("</td><td>"); //NON-NLS
343  html.append(value);
344  html.append("</td></tr>"); //NON-NLS
345  }
346 
352  private void endTable(StringBuilder html) {
353  html.append("</table><br><br>"); //NON-NLS
354  }
355 
361  private void endSection(StringBuilder html) {
362  html.append("<br>"); //NON-NLS
363  }
364 
372  private String formatHtmlString(String text) {
373  String formattedString = StringEscapeUtils.escapeHtml4(text);
374  return formattedString.replaceAll("(\r\n|\r|\n|\n\r)", "<br>");
375  }
376 
382  @SuppressWarnings("unchecked")
383  // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
384  private void initComponents() {
385 
386  jScrollPane5 = new javax.swing.JScrollPane();
387  jTextPane1 = new javax.swing.JTextPane();
388 
389  setPreferredSize(new java.awt.Dimension(100, 58));
390 
391  jTextPane1.setEditable(false);
392  jTextPane1.setName(""); // NOI18N
393  jTextPane1.setPreferredSize(new java.awt.Dimension(600, 52));
394  jScrollPane5.setViewportView(jTextPane1);
395 
396  javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
397  this.setLayout(layout);
398  layout.setHorizontalGroup(
399  layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
400  .addComponent(jScrollPane5, javax.swing.GroupLayout.DEFAULT_SIZE, 907, Short.MAX_VALUE)
401  );
402  layout.setVerticalGroup(
403  layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
404  .addComponent(jScrollPane5, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, 435, Short.MAX_VALUE)
405  );
406  }// </editor-fold>//GEN-END:initComponents
407 
408  // Variables declaration - do not modify//GEN-BEGIN:variables
409  private javax.swing.JScrollPane jScrollPane5;
410  private javax.swing.JTextPane jTextPane1;
411  // End of variables declaration//GEN-END:variables
412 
413  @Override
414  public String getTitle() {
415  return Bundle.AnnotationsContentViewer_title();
416  }
417 
418  @Override
419  public String getToolTip() {
420  return Bundle.AnnotationsContentViewer_toolTip();
421  }
422 
423  @Override
425  return new AnnotationsContentViewer();
426  }
427 
428  @Override
429  public boolean isSupported(Node node) {
430  BlackboardArtifact artifact = node.getLookup().lookup(BlackboardArtifact.class);
431 
432  try {
433  if (artifact != null) {
434  if (artifact.getSleuthkitCase().getAbstractFileById(artifact.getObjectID()) != null) {
435  return true;
436  }
437  } else {
438  if (node.getLookup().lookup(AbstractFile.class) != null) {
439  return true;
440  }
441  }
442  } catch (TskCoreException ex) {
443  logger.log(Level.SEVERE, String.format(
444  "Exception while trying to retrieve a Content instance from the BlackboardArtifact '%s' (id=%d).",
445  artifact.getDisplayName(), artifact.getArtifactID()), ex);
446  }
447 
448  return false;
449  }
450 
451  @Override
452  public int isPreferred(Node node) {
453  return 1;
454  }
455 
456  @Override
457  public Component getComponent() {
458  return this;
459  }
460 
461  @Override
462  public void resetComponent() {
463  setText("");
464  }
465 }
static CorrelationDataSource fromTSKDataSource(CorrelationCase correlationCase, Content dataSource)
void addCentralRepositoryEntry(StringBuilder html, CorrelationAttributeInstance attributeInstance)
List< CorrelationAttributeInstance > getArtifactInstancesByTypeValue(CorrelationAttributeInstance.Type aType, String value)
List< CorrelationAttributeInstance.Type > getDefinedCorrelationTypes()
static List< CorrelationAttributeInstance > makeInstancesFromBlackboardArtifact(BlackboardArtifact bbArtifact, boolean checkEnabled)
static void configureTextPaneAsHtml(JTextPane pane)
Definition: Utilities.java:32
void populateCentralRepositoryData(StringBuilder html, BlackboardArtifact artifact, AbstractFile sourceFile)
void addRow(StringBuilder html, String key, String value)
void populateTagData(StringBuilder html, BlackboardArtifact artifact, Content sourceFile)
synchronized static Logger getLogger(String name)
Definition: Logger.java:124

Copyright © 2012-2018 Basis Technology. Generated on: Thu Oct 4 2018
This work is licensed under a Creative Commons Attribution-Share Alike 3.0 United States License.