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()