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;
39 import java.util.Collections;
40 import java.util.HashSet;
57 @ServiceProvider(service = DataContentViewer.class, position = 6)
58 @SuppressWarnings(
"PMD.SingularField")
61 private static final long serialVersionUID = 1L;
64 "DataArtifactContentViewer.failedToGetSourcePath.message=Failed to get source file path from case database",
65 "DataArtifactContentViewer.failedToGetAttributes.message=Failed to get some or all attributes from case database"
69 private final static String ERROR_TEXT = NbBundle.getMessage(
DataArtifactContentViewer.class,
"DataArtifactContentViewer.errorText");
77 private int currentPage = 1;
78 private final Object lock =
new Object();
82 private final Collection<ArtifactContentViewer> knowArtifactViewers =
new HashSet<>(Lookup.getDefault().lookupAll(
ArtifactContentViewer.class));
96 @SuppressWarnings(
"unchecked")
98 private
void initComponents() {
99 java.awt.GridBagConstraints gridBagConstraints;
101 scrollPane =
new javax.swing.JScrollPane();
102 menuBar =
new javax.swing.JPanel();
103 totalPageLabel =
new javax.swing.JLabel();
104 ofLabel =
new javax.swing.JLabel();
105 currentPageLabel =
new javax.swing.JLabel();
106 pageLabel =
new javax.swing.JLabel();
107 nextPageButton =
new javax.swing.JButton();
108 pageLabel2 =
new javax.swing.JLabel();
109 prevPageButton =
new javax.swing.JButton();
110 artifactLabel =
new javax.swing.JLabel();
111 filler1 =
new javax.swing.Box.Filler(
new java.awt.Dimension(0, 0),
new java.awt.Dimension(0, 0),
new java.awt.Dimension(32767, 0));
112 artifactContentPanel =
new javax.swing.JPanel();
114 setMinimumSize(
new java.awt.Dimension(300, 60));
115 setPreferredSize(
new java.awt.Dimension(300, 60));
117 scrollPane.setHorizontalScrollBarPolicy(javax.swing.ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
118 scrollPane.setVerticalScrollBarPolicy(javax.swing.ScrollPaneConstants.VERTICAL_SCROLLBAR_NEVER);
119 scrollPane.setPreferredSize(
new java.awt.Dimension(6, 60));
121 menuBar.setMaximumSize(null);
122 menuBar.setMinimumSize(null);
123 menuBar.setPreferredSize(null);
124 menuBar.setLayout(
new java.awt.GridBagLayout());
126 totalPageLabel.setText(
org.openide.util.NbBundle.getMessage(
DataArtifactContentViewer.class,
"DataArtifactContentViewer.totalPageLabel.text"));
127 totalPageLabel.setMaximumSize(null);
128 totalPageLabel.setPreferredSize(null);
129 gridBagConstraints =
new java.awt.GridBagConstraints();
130 gridBagConstraints.gridx = 3;
131 gridBagConstraints.gridy = 0;
132 gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
133 gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
134 gridBagConstraints.insets =
new java.awt.Insets(3, 12, 0, 0);
135 menuBar.add(totalPageLabel, gridBagConstraints);
138 gridBagConstraints =
new java.awt.GridBagConstraints();
139 gridBagConstraints.gridx = 2;
140 gridBagConstraints.gridy = 0;
141 gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
142 gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
143 gridBagConstraints.insets =
new java.awt.Insets(3, 12, 0, 0);
144 menuBar.add(ofLabel, gridBagConstraints);
146 currentPageLabel.setText(
org.openide.util.NbBundle.getMessage(
DataArtifactContentViewer.class,
"DataArtifactContentViewer.currentPageLabel.text"));
147 currentPageLabel.setMaximumSize(null);
148 currentPageLabel.setPreferredSize(null);
149 gridBagConstraints =
new java.awt.GridBagConstraints();
150 gridBagConstraints.gridx = 1;
151 gridBagConstraints.gridy = 0;
152 gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
153 gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
154 gridBagConstraints.insets =
new java.awt.Insets(3, 7, 0, 0);
155 menuBar.add(currentPageLabel, gridBagConstraints);
158 gridBagConstraints =
new java.awt.GridBagConstraints();
159 gridBagConstraints.gridx = 0;
160 gridBagConstraints.gridy = 0;
161 gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
162 gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
163 gridBagConstraints.insets =
new java.awt.Insets(3, 12, 0, 0);
164 menuBar.add(pageLabel, gridBagConstraints);
166 nextPageButton.setIcon(
new javax.swing.ImageIcon(getClass().getResource(
"/org/sleuthkit/autopsy/corecomponents/btn_step_forward.png")));
167 nextPageButton.setText(
org.openide.util.NbBundle.getMessage(
DataArtifactContentViewer.class,
"DataArtifactContentViewer.nextPageButton.text"));
168 nextPageButton.setBorderPainted(
false);
169 nextPageButton.setContentAreaFilled(
false);
170 nextPageButton.setDisabledIcon(
new javax.swing.ImageIcon(getClass().getResource(
"/org/sleuthkit/autopsy/corecomponents/btn_step_forward_disabled.png")));
171 nextPageButton.setMargin(
new java.awt.Insets(2, 0, 2, 0));
172 nextPageButton.setPreferredSize(
new java.awt.Dimension(23, 23));
173 nextPageButton.setRolloverIcon(
new javax.swing.ImageIcon(getClass().getResource(
"/org/sleuthkit/autopsy/corecomponents/btn_step_forward_hover.png")));
174 nextPageButton.addActionListener(
new java.awt.event.ActionListener() {
175 public void actionPerformed(java.awt.event.ActionEvent evt) {
176 nextPageButtonActionPerformed(evt);
179 gridBagConstraints =
new java.awt.GridBagConstraints();
180 gridBagConstraints.gridx = 6;
181 gridBagConstraints.gridy = 0;
182 gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
183 gridBagConstraints.insets =
new java.awt.Insets(0, 0, 35, 0);
184 menuBar.add(nextPageButton, gridBagConstraints);
187 pageLabel2.setMaximumSize(
new java.awt.Dimension(29, 14));
188 pageLabel2.setMinimumSize(
new java.awt.Dimension(29, 14));
189 gridBagConstraints =
new java.awt.GridBagConstraints();
190 gridBagConstraints.gridx = 4;
191 gridBagConstraints.gridy = 0;
192 gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
193 gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
194 gridBagConstraints.insets =
new java.awt.Insets(3, 30, 0, 0);
195 menuBar.add(pageLabel2, gridBagConstraints);
197 prevPageButton.setIcon(
new javax.swing.ImageIcon(getClass().getResource(
"/org/sleuthkit/autopsy/corecomponents/btn_step_back.png")));
198 prevPageButton.setText(
org.openide.util.NbBundle.getMessage(
DataArtifactContentViewer.class,
"DataArtifactContentViewer.prevPageButton.text"));
199 prevPageButton.setBorderPainted(
false);
200 prevPageButton.setContentAreaFilled(
false);
201 prevPageButton.setDisabledIcon(
new javax.swing.ImageIcon(getClass().getResource(
"/org/sleuthkit/autopsy/corecomponents/btn_step_back_disabled.png")));
202 prevPageButton.setMargin(
new java.awt.Insets(2, 0, 2, 0));
203 prevPageButton.setPreferredSize(
new java.awt.Dimension(23, 23));
204 prevPageButton.setRolloverIcon(
new javax.swing.ImageIcon(getClass().getResource(
"/org/sleuthkit/autopsy/corecomponents/btn_step_back_hover.png")));
205 prevPageButton.addActionListener(
new java.awt.event.ActionListener() {
206 public void actionPerformed(java.awt.event.ActionEvent evt) {
207 prevPageButtonActionPerformed(evt);
210 gridBagConstraints =
new java.awt.GridBagConstraints();
211 gridBagConstraints.gridx = 5;
212 gridBagConstraints.gridy = 0;
213 gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
214 gridBagConstraints.insets =
new java.awt.Insets(0, 5, 35, 0);
215 menuBar.add(prevPageButton, gridBagConstraints);
216 gridBagConstraints =
new java.awt.GridBagConstraints();
217 gridBagConstraints.gridx = 8;
218 gridBagConstraints.gridy = 0;
219 gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
220 gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHEAST;
221 gridBagConstraints.insets =
new java.awt.Insets(3, 0, 0, 8);
222 menuBar.add(artifactLabel, gridBagConstraints);
223 gridBagConstraints =
new java.awt.GridBagConstraints();
224 gridBagConstraints.gridx = 7;
225 gridBagConstraints.gridy = 0;
226 gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
227 gridBagConstraints.weightx = 0.1;
228 menuBar.add(filler1, gridBagConstraints);
230 scrollPane.setViewportView(menuBar);
232 artifactContentPanel.setLayout(
new javax.swing.OverlayLayout(artifactContentPanel));
234 javax.swing.GroupLayout layout =
new javax.swing.GroupLayout(
this);
235 this.setLayout(layout);
236 layout.setHorizontalGroup(
237 layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
238 .addComponent(scrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, 300, Short.MAX_VALUE)
239 .addComponent(artifactContentPanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
241 layout.setVerticalGroup(
242 layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
243 .addGroup(layout.createSequentialGroup()
244 .addComponent(scrollPane, javax.swing.GroupLayout.PREFERRED_SIZE, 24, javax.swing.GroupLayout.PREFERRED_SIZE)
245 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
246 .addComponent(artifactContentPanel, javax.swing.GroupLayout.DEFAULT_SIZE, 30, Short.MAX_VALUE))
252 currentPageLabel.setText(Integer.toString(currentPage));
253 artifactLabel.setText(artifactTableContents.get(currentPage - 1).getDisplayName());
259 currentPageLabel.setText(Integer.toString(currentPage));
260 artifactLabel.setText(artifactTableContents.get(currentPage - 1).getDisplayName());
284 currentPageLabel.setText(
"");
285 artifactLabel.setText(
"");
286 totalPageLabel.setText(
"");
288 prevPageButton.setEnabled(
false);
289 nextPageButton.setEnabled(
false);
292 artifactContentPanel.removeAll();
300 if (selectedNode == null) {
305 Lookup lookup = selectedNode.getLookup();
306 Content content = lookup.lookup(Content.class);
307 if (content == null) {
316 return NbBundle.getMessage(this.getClass(),
"DataArtifactContentViewer.title");
321 return NbBundle.getMessage(this.getClass(),
"DataArtifactContentViewer.toolTip");
345 for (Content content : node.getLookup().lookupAll(Content.class)) {
346 if ((content != null) && (!(content instanceof DataArtifact)) && (!(content instanceof AnalysisResult))) {
350 logger.log(Level.SEVERE,
"Couldn't get count of DataArtifacts for content", ex);
361 DataArtifact artifact = node.getLookup().lookup(DataArtifact.class);
362 if (artifact == null) {
363 return LESS_PREFERRED;
367 BlackboardArtifact.Type artifactType;
369 artifactType = artifact.getType();
370 }
catch (TskCoreException ex) {
371 logger.log(Level.SEVERE,
372 String.format(
"There was an error getting the artifact type for artifact with id: %d", artifact.getId()),
374 return LESS_PREFERRED;
378 if (artifactType.getTypeID() == BlackboardArtifact.Type.TSK_WEB_DOWNLOAD.getTypeID()
379 || artifactType.getTypeID() == BlackboardArtifact.Type.TSK_WEB_CACHE.getTypeID()) {
381 return LESS_PREFERRED;
384 switch (artifactType.getCategory()) {
387 return MORE_PREFERRED;
390 return LESS_PREFERRED;
396 if (viewer.isSupported(artifact)) {
411 DataArtifact artifact;
414 ViewUpdate(
int numberOfPages,
int currentPage, DataArtifact artifact) {
415 this.currentPage = currentPage;
416 this.numberOfPages = numberOfPages;
417 this.artifact = artifact;
418 this.errorMsg = null;
421 ViewUpdate(
int numberOfPages,
int currentPage, String errorMsg) {
422 this.currentPage = currentPage;
423 this.numberOfPages = numberOfPages;
424 this.errorMsg = errorMsg;
425 this.artifact = null;
437 this.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
439 nextPageButton.setEnabled(viewUpdate.currentPage < viewUpdate.numberOfPages);
440 prevPageButton.setEnabled(viewUpdate.currentPage > 1);
441 currentPage = viewUpdate.currentPage;
442 totalPageLabel.setText(Integer.toString(viewUpdate.numberOfPages));
443 currentPageLabel.setText(Integer.toString(currentPage));
445 artifactContentPanel.removeAll();
447 if (viewUpdate.artifact != null) {
448 artifactLabel.setText(viewUpdate.artifact.getDisplayName());
450 DataArtifact artifact = viewUpdate.artifact;
456 artifactLabel.setText(viewUpdate.errorMsg);
459 artifactContentPanel.repaint();
460 artifactContentPanel.revalidate();
461 this.setCursor(null);
472 private synchronized void startNewTask(SwingWorker<ViewUpdate, Void> task) {
475 if (currentTask != null) {
478 currentTask.cancel(
false);
483 currentTask.execute();
493 synchronized (lock) {
494 this.artifactTableContents = artifactList;
504 synchronized (lock) {
505 return Collections.unmodifiableList(artifactTableContents);
515 return (content != null) &&
516 (!(content instanceof DataArtifact)) &&
517 (!(content instanceof AnalysisResult));
530 this.selectedNode = selectedNode;
537 Lookup lookup = selectedNode.getLookup();
540 List<DataArtifact> artifacts = Collections.emptyList();
541 Collection<? extends Content> contents = lookup.lookupAll(Content.class);
542 if (contents.isEmpty()) {
543 return new ViewUpdate(getArtifactContents().size(), currentPage, ERROR_TEXT);
545 for (Content content : contents) {
546 if (isSourceContent(content)) {
550 artifacts = content.getAllDataArtifacts();
552 }
catch (TskException ex) {
553 logger.log(Level.SEVERE,
"Couldn't get artifacts", ex);
554 return new ViewUpdate(getArtifactContents().size(), currentPage, ERROR_TEXT);
564 ArrayList<DataArtifact> artifactContents =
new ArrayList<>();
565 for (DataArtifact artifact : artifacts) {
566 artifactContents.add(artifact);
572 DataArtifact artifact = lookup.lookup(DataArtifact.class);
573 if (artifact != null) {
574 index = artifacts.indexOf(artifact);
580 for (BlackboardAttribute attr : artifact.getAttributes()) {
581 if (attr.getAttributeType().getTypeID() == BlackboardAttribute.ATTRIBUTE_TYPE.TSK_ASSOCIATED_ARTIFACT.getTypeID()) {
582 long assocArtifactId = attr.getValueLong();
583 int assocArtifactIndex = -1;
584 for (DataArtifact art : artifacts) {
585 if (assocArtifactId == art.getArtifactID()) {
586 assocArtifactIndex = artifacts.indexOf(art);
590 if (assocArtifactIndex >= 0) {
591 index = assocArtifactIndex;
596 }
catch (TskCoreException ex) {
597 logger.log(Level.WARNING,
"Couldn't get associated artifact to display in Content Viewer.", ex);
608 ViewUpdate viewUpdate =
new ViewUpdate(artifactContents.size(), index + 1, artifactContents.get(index));
616 setArtifactContents(artifactContents);
623 if (!isCancelled()) {
626 if (viewUpdate != null) {
627 currentNode = selectedNode;
628 updateView(viewUpdate);
630 }
catch (InterruptedException | ExecutionException ex) {
631 logger.log(Level.WARNING,
"Artifact display task unexpectedly interrupted or failed", ex);
647 this.pageIndex = pageIndex;
654 List<DataArtifact> artifactContents = getArtifactContents();
661 DataArtifact artifactContent = artifactContents.get(pageIndex - 1);
662 return new ViewUpdate(artifactContents.size(), pageIndex, artifactContent);
667 if (!isCancelled()) {
670 if (viewUpdate != null) {
671 updateView(viewUpdate);
673 }
catch (InterruptedException | ExecutionException ex) {
674 logger.log(Level.WARNING,
"Artifact display task unexpectedly interrupted or failed", ex);
ViewUpdate doInBackground()
int isPreferred(Node node)
DataArtifactContentViewer()
DataContentViewer createInstance()
List< DataArtifact > artifactTableContents
javax.swing.Box.Filler filler1
javax.swing.JLabel artifactLabel
void nextPageButtonActionPerformed(java.awt.event.ActionEvent evt)
javax.swing.JLabel pageLabel2
javax.swing.JLabel currentPageLabel
javax.swing.JPanel menuBar
javax.swing.JLabel ofLabel
void updateView(ViewUpdate viewUpdate)
javax.swing.JScrollPane scrollPane
javax.swing.JButton prevPageButton
void setNode(Node selectedNode)
SleuthkitCase getSleuthkitCase()
void setArtifactContents(List< DataArtifact > artifactList)
synchronized void startNewTask(SwingWorker< ViewUpdate, Void > task)
javax.swing.JPanel artifactContentPanel
javax.swing.JButton nextPageButton
ViewUpdate doInBackground()
ArtifactContentViewer getSupportingViewer(DataArtifact artifact)
boolean isSupported(Node node)
synchronized static Logger getLogger(String name)
javax.swing.JLabel totalPageLabel
static Case getCurrentCaseThrows()
void prevPageButtonActionPerformed(java.awt.event.ActionEvent evt)
javax.swing.JLabel pageLabel
static boolean isSourceContent(Content content)
SwingWorker< ViewUpdate, Void > currentTask
void setArtifact(BlackboardArtifact artifact)
List< DataArtifact > getArtifactContents()