19 package org.sleuthkit.autopsy.corecomponents;
21 import java.awt.Component;
22 import java.awt.Cursor;
23 import java.util.ArrayList;
24 import java.util.Collection;
25 import java.util.List;
26 import java.util.concurrent.ExecutionException;
27 import java.util.logging.Level;
28 import javax.swing.SwingWorker;
29 import org.openide.nodes.Node;
30 import org.openide.util.Lookup;
31 import org.openide.util.NbBundle;
32 import org.openide.util.lookup.ServiceProvider;
36 import org.
sleuthkit.datamodel.BlackboardArtifact.ARTIFACT_TYPE;
41 import java.util.Collections;
42 import java.util.HashSet;
53 @ServiceProvider(service = DataContentViewer.class, position = 7)
54 @SuppressWarnings(
"PMD.SingularField")
57 private static final long serialVersionUID = 1L;
60 "DataContentViewerArtifact.failedToGetSourcePath.message=Failed to get source file path from case database",
61 "DataContentViewerArtifact.failedToGetAttributes.message=Failed to get some or all attributes from case database"
65 private final static String ERROR_TEXT = NbBundle.getMessage(
DataContentViewerArtifact.class,
"DataContentViewerArtifact.errorText");
68 private int currentPage = 1;
69 private final Object lock =
new Object();
73 private final Collection<ArtifactContentViewer> knowArtifactViewers =
new HashSet<>(Lookup.getDefault().lookupAll(
ArtifactContentViewer.class));
87 @SuppressWarnings(
"unchecked")
89 private
void initComponents() {
90 java.awt.GridBagConstraints gridBagConstraints;
92 jScrollPane1 =
new javax.swing.JScrollPane();
93 jPanel1 =
new javax.swing.JPanel();
94 totalPageLabel =
new javax.swing.JLabel();
95 ofLabel =
new javax.swing.JLabel();
96 currentPageLabel =
new javax.swing.JLabel();
97 pageLabel =
new javax.swing.JLabel();
98 nextPageButton =
new javax.swing.JButton();
99 pageLabel2 =
new javax.swing.JLabel();
100 prevPageButton =
new javax.swing.JButton();
101 artifactLabel =
new javax.swing.JLabel();
102 filler1 =
new javax.swing.Box.Filler(
new java.awt.Dimension(0, 0),
new java.awt.Dimension(0, 0),
new java.awt.Dimension(32767, 0));
103 artifactContentPanel =
new javax.swing.JPanel();
105 setPreferredSize(
new java.awt.Dimension(100, 58));
107 jScrollPane1.setHorizontalScrollBarPolicy(javax.swing.ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
108 jScrollPane1.setVerticalScrollBarPolicy(javax.swing.ScrollPaneConstants.VERTICAL_SCROLLBAR_NEVER);
110 jPanel1.setPreferredSize(
new java.awt.Dimension(620, 58));
111 jPanel1.setLayout(
new java.awt.GridBagLayout());
113 totalPageLabel.setText(
org.openide.util.NbBundle.getMessage(
DataContentViewerArtifact.class,
"DataContentViewerArtifact.totalPageLabel.text"));
114 totalPageLabel.setMaximumSize(
new java.awt.Dimension(40, 16));
115 totalPageLabel.setPreferredSize(
new java.awt.Dimension(25, 16));
116 gridBagConstraints =
new java.awt.GridBagConstraints();
117 gridBagConstraints.gridx = 3;
118 gridBagConstraints.gridy = 0;
119 gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
120 gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
121 gridBagConstraints.insets =
new java.awt.Insets(3, 12, 0, 0);
122 jPanel1.add(totalPageLabel, gridBagConstraints);
125 gridBagConstraints =
new java.awt.GridBagConstraints();
126 gridBagConstraints.gridx = 2;
127 gridBagConstraints.gridy = 0;
128 gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
129 gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
130 gridBagConstraints.insets =
new java.awt.Insets(3, 12, 0, 0);
131 jPanel1.add(ofLabel, gridBagConstraints);
133 currentPageLabel.setText(
org.openide.util.NbBundle.getMessage(
DataContentViewerArtifact.class,
"DataContentViewerArtifact.currentPageLabel.text"));
134 currentPageLabel.setMaximumSize(
new java.awt.Dimension(38, 14));
135 currentPageLabel.setMinimumSize(
new java.awt.Dimension(18, 14));
136 currentPageLabel.setPreferredSize(
new java.awt.Dimension(20, 14));
137 gridBagConstraints =
new java.awt.GridBagConstraints();
138 gridBagConstraints.gridx = 1;
139 gridBagConstraints.gridy = 0;
140 gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
141 gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
142 gridBagConstraints.insets =
new java.awt.Insets(4, 7, 0, 0);
143 jPanel1.add(currentPageLabel, gridBagConstraints);
146 gridBagConstraints =
new java.awt.GridBagConstraints();
147 gridBagConstraints.gridx = 0;
148 gridBagConstraints.gridy = 0;
149 gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
150 gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
151 gridBagConstraints.insets =
new java.awt.Insets(3, 12, 0, 0);
152 jPanel1.add(pageLabel, gridBagConstraints);
154 nextPageButton.setIcon(
new javax.swing.ImageIcon(getClass().getResource(
"/org/sleuthkit/autopsy/corecomponents/btn_step_forward.png")));
155 nextPageButton.setText(
org.openide.util.NbBundle.getMessage(
DataContentViewerArtifact.class,
"DataContentViewerArtifact.nextPageButton.text"));
156 nextPageButton.setBorderPainted(
false);
157 nextPageButton.setContentAreaFilled(
false);
158 nextPageButton.setDisabledIcon(
new javax.swing.ImageIcon(getClass().getResource(
"/org/sleuthkit/autopsy/corecomponents/btn_step_forward_disabled.png")));
159 nextPageButton.setMargin(
new java.awt.Insets(2, 0, 2, 0));
160 nextPageButton.setPreferredSize(
new java.awt.Dimension(23, 23));
161 nextPageButton.setRolloverIcon(
new javax.swing.ImageIcon(getClass().getResource(
"/org/sleuthkit/autopsy/corecomponents/btn_step_forward_hover.png")));
162 nextPageButton.addActionListener(
new java.awt.event.ActionListener() {
163 public void actionPerformed(java.awt.event.ActionEvent evt) {
164 nextPageButtonActionPerformed(evt);
167 gridBagConstraints =
new java.awt.GridBagConstraints();
168 gridBagConstraints.gridx = 6;
169 gridBagConstraints.gridy = 0;
170 gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
171 gridBagConstraints.insets =
new java.awt.Insets(0, 0, 35, 0);
172 jPanel1.add(nextPageButton, gridBagConstraints);
175 pageLabel2.setMaximumSize(
new java.awt.Dimension(29, 14));
176 pageLabel2.setMinimumSize(
new java.awt.Dimension(29, 14));
177 gridBagConstraints =
new java.awt.GridBagConstraints();
178 gridBagConstraints.gridx = 4;
179 gridBagConstraints.gridy = 0;
180 gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
181 gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
182 gridBagConstraints.insets =
new java.awt.Insets(3, 41, 0, 0);
183 jPanel1.add(pageLabel2, gridBagConstraints);
185 prevPageButton.setIcon(
new javax.swing.ImageIcon(getClass().getResource(
"/org/sleuthkit/autopsy/corecomponents/btn_step_back.png")));
186 prevPageButton.setText(
org.openide.util.NbBundle.getMessage(
DataContentViewerArtifact.class,
"DataContentViewerArtifact.prevPageButton.text"));
187 prevPageButton.setBorderPainted(
false);
188 prevPageButton.setContentAreaFilled(
false);
189 prevPageButton.setDisabledIcon(
new javax.swing.ImageIcon(getClass().getResource(
"/org/sleuthkit/autopsy/corecomponents/btn_step_back_disabled.png")));
190 prevPageButton.setMargin(
new java.awt.Insets(2, 0, 2, 0));
191 prevPageButton.setPreferredSize(
new java.awt.Dimension(23, 23));
192 prevPageButton.setRolloverIcon(
new javax.swing.ImageIcon(getClass().getResource(
"/org/sleuthkit/autopsy/corecomponents/btn_step_back_hover.png")));
193 prevPageButton.addActionListener(
new java.awt.event.ActionListener() {
194 public void actionPerformed(java.awt.event.ActionEvent evt) {
195 prevPageButtonActionPerformed(evt);
198 gridBagConstraints =
new java.awt.GridBagConstraints();
199 gridBagConstraints.gridx = 5;
200 gridBagConstraints.gridy = 0;
201 gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
202 gridBagConstraints.insets =
new java.awt.Insets(0, 5, 35, 0);
203 jPanel1.add(prevPageButton, gridBagConstraints);
204 gridBagConstraints =
new java.awt.GridBagConstraints();
205 gridBagConstraints.gridx = 8;
206 gridBagConstraints.gridy = 0;
207 gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
208 gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHEAST;
209 gridBagConstraints.insets =
new java.awt.Insets(3, 0, 0, 8);
210 jPanel1.add(artifactLabel, gridBagConstraints);
211 gridBagConstraints =
new java.awt.GridBagConstraints();
212 gridBagConstraints.gridx = 7;
213 gridBagConstraints.gridy = 0;
214 gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
215 gridBagConstraints.weightx = 0.1;
216 jPanel1.add(filler1, gridBagConstraints);
218 jScrollPane1.setViewportView(jPanel1);
220 artifactContentPanel.setLayout(
new javax.swing.OverlayLayout(artifactContentPanel));
222 javax.swing.GroupLayout layout =
new javax.swing.GroupLayout(
this);
223 this.setLayout(layout);
224 layout.setHorizontalGroup(
225 layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
226 .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 561, Short.MAX_VALUE)
227 .addComponent(artifactContentPanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
229 layout.setVerticalGroup(
230 layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
231 .addGroup(layout.createSequentialGroup()
232 .addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 24, javax.swing.GroupLayout.PREFERRED_SIZE)
233 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
234 .addComponent(artifactContentPanel, javax.swing.GroupLayout.DEFAULT_SIZE, 397, Short.MAX_VALUE))
240 currentPageLabel.setText(Integer.toString(currentPage));
241 artifactLabel.setText(artifactTableContents.get(currentPage - 1).getDisplayName());
247 currentPageLabel.setText(Integer.toString(currentPage));
248 artifactLabel.setText(artifactTableContents.get(currentPage - 1).getDisplayName());
272 currentPageLabel.setText(
"");
273 artifactLabel.setText(
"");
274 totalPageLabel.setText(
"");
276 prevPageButton.setEnabled(
false);
277 nextPageButton.setEnabled(
false);
280 artifactContentPanel.removeAll();
285 if (currentNode == selectedNode) {
288 currentNode = selectedNode;
291 if (selectedNode == null) {
296 Lookup lookup = selectedNode.getLookup();
297 Content content = lookup.lookup(Content.class);
298 if (content == null) {
307 return NbBundle.getMessage(this.getClass(),
"DataContentViewerArtifact.title");
312 return NbBundle.getMessage(this.getClass(),
"DataContentViewerArtifact.toolTip");
336 for (Content content : node.getLookup().lookupAll(Content.class)) {
337 if ((content != null) && (!(content instanceof BlackboardArtifact))) {
339 return content.getAllArtifactsCount() > 0;
340 }
catch (TskException ex) {
341 logger.log(Level.SEVERE,
"Couldn't get count of BlackboardArtifacts for content", ex);
350 BlackboardArtifact artifact = node.getLookup().lookup(BlackboardArtifact.class);
354 if ((artifact == null)
355 || (artifact.getArtifactTypeID() == ARTIFACT_TYPE.TSK_HASHSET_HIT.getTypeID())
356 || (artifact.getArtifactTypeID() == ARTIFACT_TYPE.TSK_KEYWORD_HIT.getTypeID())
357 || (artifact.getArtifactTypeID() == ARTIFACT_TYPE.TSK_INTERESTING_FILE_HIT.getTypeID())
358 || (artifact.getArtifactTypeID() == ARTIFACT_TYPE.TSK_OBJECT_DETECTED.getTypeID())
359 || (artifact.getArtifactTypeID() == ARTIFACT_TYPE.TSK_METADATA_EXIF.getTypeID())
360 || (artifact.getArtifactTypeID() == ARTIFACT_TYPE.TSK_EXT_MISMATCH_DETECTED.getTypeID())
361 || (artifact.getArtifactTypeID() == ARTIFACT_TYPE.TSK_WEB_DOWNLOAD.getTypeID())
362 || (artifact.getArtifactTypeID() == ARTIFACT_TYPE.TSK_WEB_CACHE.getTypeID())) {
371 if (viewer.isSupported(artifact)) {
386 BlackboardArtifact artifact;
389 ViewUpdate(
int numberOfPages,
int currentPage, BlackboardArtifact artifact) {
390 this.currentPage = currentPage;
391 this.numberOfPages = numberOfPages;
392 this.artifact = artifact;
393 this.errorMsg = null;
396 ViewUpdate(
int numberOfPages,
int currentPage, String errorMsg) {
397 this.currentPage = currentPage;
398 this.numberOfPages = numberOfPages;
399 this.errorMsg = errorMsg;
400 this.artifact = null;
412 this.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
414 nextPageButton.setEnabled(viewUpdate.currentPage < viewUpdate.numberOfPages);
415 prevPageButton.setEnabled(viewUpdate.currentPage > 1);
416 currentPage = viewUpdate.currentPage;
417 totalPageLabel.setText(Integer.toString(viewUpdate.numberOfPages));
418 currentPageLabel.setText(Integer.toString(currentPage));
420 artifactContentPanel.removeAll();
422 if (viewUpdate.artifact != null) {
423 artifactLabel.setText(viewUpdate.artifact.getDisplayName());
425 BlackboardArtifact artifact = viewUpdate.artifact;
431 artifactLabel.setText(viewUpdate.errorMsg);
434 artifactContentPanel.repaint();
435 artifactContentPanel.revalidate();
436 this.setCursor(null);
447 private synchronized void startNewTask(SwingWorker<ViewUpdate, Void> task) {
450 if (currentTask != null) {
453 currentTask.cancel(
false);
458 currentTask.execute();
468 synchronized (lock) {
469 this.artifactTableContents = artifactList;
479 synchronized (lock) {
480 return Collections.unmodifiableList(artifactTableContents);
494 this.selectedNode = selectedNode;
501 Lookup lookup = selectedNode.getLookup();
504 ArrayList<BlackboardArtifact> artifacts =
new ArrayList<>();
505 Collection<? extends Content> contents = lookup.lookupAll(Content.class);
506 if (contents.isEmpty()) {
507 return new ViewUpdate(getArtifactContents().size(), currentPage, ERROR_TEXT);
509 Content underlyingContent = null;
510 for (Content content : contents) {
511 if ((content != null) && (!(content instanceof BlackboardArtifact))) {
515 artifacts = content.getAllArtifacts();
516 underlyingContent = content;
518 }
catch (TskException ex) {
519 logger.log(Level.SEVERE,
"Couldn't get artifacts", ex);
520 return new ViewUpdate(getArtifactContents().size(), currentPage, ERROR_TEXT);
530 ArrayList<BlackboardArtifact> artifactContents =
new ArrayList<>();
531 for (BlackboardArtifact artifact : artifacts) {
532 artifactContents.add(artifact);
538 BlackboardArtifact artifact = lookup.lookup(BlackboardArtifact.class);
539 if (artifact != null) {
540 index = artifacts.indexOf(artifact);
546 for (BlackboardAttribute attr : artifact.getAttributes()) {
547 if (attr.getAttributeType().getTypeID() == BlackboardAttribute.ATTRIBUTE_TYPE.TSK_ASSOCIATED_ARTIFACT.getTypeID()) {
548 long assocArtifactId = attr.getValueLong();
549 int assocArtifactIndex = -1;
550 for (BlackboardArtifact art : artifacts) {
551 if (assocArtifactId == art.getArtifactID()) {
552 assocArtifactIndex = artifacts.indexOf(art);
556 if (assocArtifactIndex >= 0) {
557 index = assocArtifactIndex;
562 }
catch (TskCoreException ex) {
563 logger.log(Level.WARNING,
"Couldn't get associated artifact to display in Content Viewer.", ex);
574 ViewUpdate viewUpdate =
new ViewUpdate(artifactContents.size(), index + 1, artifactContents.get(index));
582 setArtifactContents(artifactContents);
589 if (!isCancelled()) {
592 if (viewUpdate != null) {
593 updateView(viewUpdate);
595 }
catch (InterruptedException | ExecutionException ex) {
596 logger.log(Level.WARNING,
"Artifact display task unexpectedly interrupted or failed", ex);
612 this.pageIndex = pageIndex;
619 List<BlackboardArtifact> artifactContents = getArtifactContents();
626 BlackboardArtifact artifactContent = artifactContents.get(pageIndex - 1);
627 return new ViewUpdate(artifactContents.size(), pageIndex, artifactContent);
632 if (!isCancelled()) {
635 if (viewUpdate != null) {
636 updateView(viewUpdate);
638 }
catch (InterruptedException | ExecutionException ex) {
639 logger.log(Level.WARNING,
"Artifact display task unexpectedly interrupted or failed", ex);
void prevPageButtonActionPerformed(java.awt.event.ActionEvent evt)
javax.swing.JScrollPane jScrollPane1
javax.swing.JPanel artifactContentPanel
javax.swing.JLabel pageLabel
synchronized void startNewTask(SwingWorker< ViewUpdate, Void > task)
javax.swing.JPanel jPanel1
List< BlackboardArtifact > artifactTableContents
javax.swing.JLabel artifactLabel
javax.swing.JButton nextPageButton
void nextPageButtonActionPerformed(java.awt.event.ActionEvent evt)
DataContentViewerArtifact()
ViewUpdate doInBackground()
void updateView(ViewUpdate viewUpdate)
void setNode(Node selectedNode)
javax.swing.Box.Filler filler1
javax.swing.JLabel totalPageLabel
ArtifactContentViewer getSupportingViewer(BlackboardArtifact artifact)
SwingWorker< ViewUpdate, Void > currentTask
javax.swing.JButton prevPageButton
void setArtifactContents(List< BlackboardArtifact > artifactList)
javax.swing.JLabel pageLabel2
javax.swing.JLabel ofLabel
DataContentViewer createInstance()
synchronized static Logger getLogger(String name)
ViewUpdate doInBackground()
List< BlackboardArtifact > getArtifactContents()
boolean isSupported(Node node)
int isPreferred(Node node)
void setArtifact(BlackboardArtifact artifact)
javax.swing.JLabel currentPageLabel