19 package org.sleuthkit.autopsy.contentviewers.annotations;
 
   21 import com.google.common.collect.ImmutableSet;
 
   22 import java.awt.Component;
 
   23 import java.beans.PropertyChangeEvent;
 
   24 import java.beans.PropertyChangeListener;
 
   25 import java.util.EnumSet;
 
   27 import java.util.concurrent.ExecutionException;
 
   28 import java.util.logging.Level;
 
   29 import javax.swing.SwingWorker;
 
   30 import org.apache.commons.lang3.tuple.Pair;
 
   32 import static org.openide.util.NbBundle.Messages;
 
   33 import org.openide.nodes.Node;
 
   34 import org.openide.util.lookup.ServiceProvider;
 
   37 import org.jsoup.nodes.Document;
 
   38 import org.openide.util.WeakListeners;
 
   55 @SuppressWarnings(
"PMD.SingularField") 
 
   58     "AnnotationsContentViewer.title=Annotations",
 
   59     "AnnotationsContentViewer.toolTip=Displays tags and comments associated with the selected content.",
 
   60     "AnnotationsContentViewer.onEmpty=No annotations were found for this particular item." 
   64     private static final long serialVersionUID = 1L;
 
   67     private static final Set<
Case.
Events> CASE_EVENTS_OF_INTEREST = EnumSet.of(
 
   76     private static final Set<BlackboardArtifact.Type> ARTIFACT_TYPES_OF_INTEREST = ImmutableSet.of(
 
   77             BlackboardArtifact.Type.TSK_HASHSET_HIT,
 
   78             BlackboardArtifact.Type.TSK_INTERESTING_FILE_HIT
 
   81     private final PropertyChangeListener ingestEventListener = (evt) -> {
 
   85         if (curArtifactId == null && curContentId == null) {
 
   97                 for (BlackboardArtifact artifact : moduleDataEvent.
getArtifacts()) {
 
   98                     if ((curArtifactId != null && artifact.getArtifactID() == curArtifactId)
 
   99                             || (curContentId != null && artifact.getObjectID() == curContentId)) {
 
  108     private final PropertyChangeListener weakIngestEventListener = WeakListeners.propertyChange(ingestEventListener, null);
 
  110     private final PropertyChangeListener caseEventListener = (evt) -> {
 
  114         if (curArtifactId == null && curContentId == null) {
 
  118         Pair<Long, Long> artifactContentId = getIdsFromEvent(evt);
 
  119         Long artifactId = artifactContentId.getLeft();
 
  120         Long contentId = artifactContentId.getRight();
 
  123         if ((curArtifactId != null && curArtifactId.equals(artifactId)) || (curContentId != null && curContentId.equals(contentId))) {
 
  128     private final PropertyChangeListener weakCaseEventListener = WeakListeners.propertyChange(caseEventListener, null);
 
  130     private final Object updateLock = 
new Object();
 
  156         unregisterListeners();
 
  170         DisplayTskItems displayItems = 
AnnotationUtils.getDisplayContent(node);
 
  171         this.curArtifactId = displayItems.getArtifact() == null ? null : displayItems.getArtifact().getArtifactID();
 
  172         this.curContentId = displayItems.getContent() == null ? null : displayItems.getContent().getId();
 
  173         updateData(this.node, 
true);
 
  188             eventType = 
Case.
Events.valueOf(evt.getPropertyName());
 
  189         } 
catch (IllegalArgumentException ex) {
 
  190             logger.log(Level.SEVERE, 
"Unknown event type: " + evt.getPropertyName(), ex);
 
  191             return Pair.of(null, null);
 
  194         Long artifactId = null;
 
  195         Long contentId = null;
 
  198             case BLACKBOARD_ARTIFACT_TAG_ADDED:
 
  200                     BlackboardArtifact art = ((BlackBoardArtifactTagAddedEvent) evt).getAddedTag().getArtifact();
 
  201                     artifactId = art.getArtifactID();
 
  202                     contentId = art.getObjectID();
 
  205             case BLACKBOARD_ARTIFACT_TAG_DELETED:
 
  207                     artifactId = ((BlackBoardArtifactTagDeletedEvent) evt).getDeletedTagInfo().getArtifactID();
 
  208                     contentId = ((BlackBoardArtifactTagDeletedEvent) evt).getDeletedTagInfo().getContentID();
 
  211             case CONTENT_TAG_ADDED:
 
  213                     contentId = ((ContentTagAddedEvent) evt).getAddedTag().getContent().getId();
 
  216             case CONTENT_TAG_DELETED:
 
  218                     contentId = ((ContentTagDeletedEvent) evt).getDeletedTagInfo().getContentID();
 
  221             case CR_COMMENT_CHANGED:
 
  223                     long commentObjId = ((CommentChangedEvent) evt).getContentID();
 
  224                     artifactId = commentObjId;
 
  225                     contentId = commentObjId;
 
  232         return Pair.of(artifactId, contentId);
 
  239         if (this.isVisible()) {
 
  240             updateData(this.node, 
false);
 
  262         synchronized (updateLock) {
 
  263             if (worker != null) {
 
  282     @SuppressWarnings(
"unchecked")
 
  284     private 
void initComponents() {
 
  286         javax.swing.JScrollPane scrollPane = 
new javax.swing.JScrollPane();
 
  287         textPanel = 
new javax.swing.JTextPane();
 
  289         setPreferredSize(
new java.awt.Dimension(100, 58));
 
  291         textPanel.setEditable(
false);
 
  292         textPanel.setName(
""); 
 
  293         textPanel.setPreferredSize(
new java.awt.Dimension(600, 52));
 
  294         scrollPane.setViewportView(textPanel);
 
  296         javax.swing.GroupLayout layout = 
new javax.swing.GroupLayout(
this);
 
  297         this.setLayout(layout);
 
  298         layout.setHorizontalGroup(
 
  299             layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
 
  300             .addComponent(scrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, 907, Short.MAX_VALUE)
 
  302         layout.setVerticalGroup(
 
  303             layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
 
  304             .addComponent(scrollPane, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, 435, Short.MAX_VALUE)
 
  314         return Bundle.AnnotationsContentViewer_title();
 
  319         return Bundle.AnnotationsContentViewer_toolTip();
 
  344         textPanel.setText(
"");
 
  366             this.resetCaretPosition = resetCaretPosition;
 
  386             if (!isCancelled()) {
 
  390                     textPanel.setText(text);
 
  392                     if (resetCaretPosition) {
 
  393                         textPanel.setCaretPosition(0);
 
  396                 } 
catch (InterruptedException | ExecutionException ex) {
 
  397                     logger.log(Level.SEVERE, 
"Failed to get annotation information for node", ex);
 
  401             synchronized (updateLock) {
 
  402                 if (worker == 
this) {
 
Collection< BlackboardArtifact > getArtifacts()
 
BlackboardArtifact.Type getBlackboardArtifactType()
 
static synchronized IngestManager getInstance()
 
boolean isSupported(Node node)
 
javax.swing.JTextPane textPanel
 
static void setStyles(JTextPane textPane)
 
final boolean resetCaretPosition
 
static boolean isSupported(Node node)
 
static Document buildDocument(Node node)
 
static void setupHtmlJTextPane(JTextPane textPane)
 
static String getMessageClassName()
 
BLACKBOARD_ARTIFACT_TAG_ADDED
 
static Pair< Long, Long > getIdsFromEvent(PropertyChangeEvent evt)
 
void addIngestModuleEventListener(final PropertyChangeListener listener)
 
synchronized static Logger getLogger(String name)
 
static void addEventTypeSubscriber(Set< Events > eventTypes, PropertyChangeListener subscriber)
 
AnnotationsContentViewer()
 
int isPreferred(Node node)
 
void updateData(Node node, boolean forceReset)
 
static void removeEventTypeSubscriber(Set< Events > eventTypes, PropertyChangeListener subscriber)
 
void unregisterListeners()
 
BLACKBOARD_ARTIFACT_TAG_DELETED
 
DataContentViewer createInstance()