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();
 
  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)) {
 
  350                     logger.log(Level.SEVERE, 
"Couldn't get count of DataArtifacts for content", ex); 
 
  362         if (artifact == null) {
 
  363             return LESS_PREFERRED;
 
  369             artifactType = artifact.
getType();
 
  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;
 
  381             return LESS_PREFERRED;
 
  384         switch (artifactType.getCategory()) {
 
  387                 return MORE_PREFERRED;
 
  390                 return LESS_PREFERRED;
 
  396             if (viewer.isSupported(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) {
 
  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) && 
 
  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();
 
  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<>();
 
  566                 artifactContents.add(artifact);
 
  573             if (artifact != null) {
 
  574                 index = artifacts.indexOf(artifact);
 
  582                                 long assocArtifactId = attr.getValueLong();
 
  583                                 int assocArtifactIndex = -1;
 
  585                                     if (assocArtifactId == art.getArtifactID()) {
 
  586                                         assocArtifactIndex = artifacts.indexOf(art);
 
  590                                 if (assocArtifactIndex >= 0) {
 
  591                                     index = assocArtifactIndex;
 
  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)
static final Type TSK_WEB_DOWNLOAD
Blackboard getBlackboard()
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
BlackboardArtifact.Type getType()
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)
static final Type TSK_WEB_CACHE
SleuthkitCase getSleuthkitCase()
void setArtifactContents(List< DataArtifact > artifactList)
synchronized void startNewTask(SwingWorker< ViewUpdate, Void > task)
List< BlackboardAttribute > getAttributes()
javax.swing.JPanel artifactContentPanel
javax.swing.JButton nextPageButton
ViewUpdate doInBackground()
boolean hasDataArtifacts(long sourceObjId)
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()