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())) {
369 if (viewer.isSupported(artifact)) {
384 BlackboardArtifact artifact;
387 ViewUpdate(
int numberOfPages,
int currentPage, BlackboardArtifact artifact) {
388 this.currentPage = currentPage;
389 this.numberOfPages = numberOfPages;
390 this.artifact = artifact;
391 this.errorMsg = null;
394 ViewUpdate(
int numberOfPages,
int currentPage, String errorMsg) {
395 this.currentPage = currentPage;
396 this.numberOfPages = numberOfPages;
397 this.errorMsg = errorMsg;
398 this.artifact = null;
410 this.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
412 nextPageButton.setEnabled(viewUpdate.currentPage < viewUpdate.numberOfPages);
413 prevPageButton.setEnabled(viewUpdate.currentPage > 1);
414 currentPage = viewUpdate.currentPage;
415 totalPageLabel.setText(Integer.toString(viewUpdate.numberOfPages));
416 currentPageLabel.setText(Integer.toString(currentPage));
418 artifactContentPanel.removeAll();
420 if (viewUpdate.artifact != null) {
421 artifactLabel.setText(viewUpdate.artifact.getDisplayName());
423 BlackboardArtifact artifact = viewUpdate.artifact;
429 artifactLabel.setText(viewUpdate.errorMsg);
432 artifactContentPanel.repaint();
433 artifactContentPanel.revalidate();
434 this.setCursor(null);
445 private synchronized void startNewTask(SwingWorker<ViewUpdate, Void> task) {
448 if (currentTask != null) {
451 currentTask.cancel(
false);
456 currentTask.execute();
466 synchronized (lock) {
467 this.artifactTableContents = artifactList;
477 synchronized (lock) {
478 return Collections.unmodifiableList(artifactTableContents);
492 this.selectedNode = selectedNode;
499 Lookup lookup = selectedNode.getLookup();
502 ArrayList<BlackboardArtifact> artifacts =
new ArrayList<>();
503 Collection<? extends Content> contents = lookup.lookupAll(Content.class);
504 if (contents.isEmpty()) {
505 return new ViewUpdate(getArtifactContents().size(), currentPage, ERROR_TEXT);
507 Content underlyingContent = null;
508 for (Content content : contents) {
509 if ((content != null) && (!(content instanceof BlackboardArtifact))) {
513 artifacts = content.getAllArtifacts();
514 underlyingContent = content;
516 }
catch (TskException ex) {
517 logger.log(Level.SEVERE,
"Couldn't get artifacts", ex);
518 return new ViewUpdate(getArtifactContents().size(), currentPage, ERROR_TEXT);
528 ArrayList<BlackboardArtifact> artifactContents =
new ArrayList<>();
529 for (BlackboardArtifact artifact : artifacts) {
530 artifactContents.add(artifact);
536 BlackboardArtifact artifact = lookup.lookup(BlackboardArtifact.class);
537 if (artifact != null) {
538 index = artifacts.indexOf(artifact);
544 for (BlackboardAttribute attr : artifact.getAttributes()) {
545 if (attr.getAttributeType().getTypeID() == BlackboardAttribute.ATTRIBUTE_TYPE.TSK_ASSOCIATED_ARTIFACT.getTypeID()) {
546 long assocArtifactId = attr.getValueLong();
547 int assocArtifactIndex = -1;
548 for (BlackboardArtifact art : artifacts) {
549 if (assocArtifactId == art.getArtifactID()) {
550 assocArtifactIndex = artifacts.indexOf(art);
554 if (assocArtifactIndex >= 0) {
555 index = assocArtifactIndex;
560 }
catch (TskCoreException ex) {
561 logger.log(Level.WARNING,
"Couldn't get associated artifact to display in Content Viewer.", ex);
572 ViewUpdate viewUpdate =
new ViewUpdate(artifactContents.size(), index + 1, artifactContents.get(index));
580 setArtifactContents(artifactContents);
587 if (!isCancelled()) {
590 if (viewUpdate != null) {
591 updateView(viewUpdate);
593 }
catch (InterruptedException | ExecutionException ex) {
594 logger.log(Level.WARNING,
"Artifact display task unexpectedly interrupted or failed", ex);
610 this.pageIndex = pageIndex;
617 List<BlackboardArtifact> artifactContents = getArtifactContents();
624 BlackboardArtifact artifactContent = artifactContents.get(pageIndex - 1);
625 return new ViewUpdate(artifactContents.size(), pageIndex, artifactContent);
630 if (!isCancelled()) {
633 if (viewUpdate != null) {
634 updateView(viewUpdate);
636 }
catch (InterruptedException | ExecutionException ex) {
637 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