19 package org.sleuthkit.autopsy.contentviewers.artifactviewers;
 
   21 import java.awt.Component;
 
   22 import java.awt.Dimension;
 
   23 import java.awt.GridBagConstraints;
 
   24 import java.awt.GridBagLayout;
 
   25 import java.awt.Insets;
 
   26 import java.awt.Toolkit;
 
   27 import java.awt.datatransfer.StringSelection;
 
   28 import java.awt.event.ActionEvent;
 
   29 import java.awt.event.ActionListener;
 
   30 import java.util.ArrayList;
 
   31 import java.util.Arrays;
 
   32 import java.util.HashMap;
 
   33 import java.util.List;
 
   35 import java.util.Optional;
 
   36 import java.util.logging.Level;
 
   37 import javax.swing.JLabel;
 
   38 import javax.swing.JMenuItem;
 
   39 import javax.swing.JPopupMenu;
 
   40 import javax.swing.JTextPane;
 
   41 import javax.swing.SwingUtilities;
 
   42 import javax.swing.border.EmptyBorder;
 
   43 import org.apache.commons.lang.StringUtils;
 
   44 import org.openide.util.NbBundle;
 
   45 import org.openide.util.lookup.ServiceProvider;
 
   61 @ServiceProvider(service = ArtifactContentViewer.class)
 
   64     private static final long serialVersionUID = 1L;
 
   67     private final static int MAX_COLS = 4;
 
   68     private final static Insets ZERO_INSETS = 
new java.awt.Insets(0, 0, 0, 0);
 
   70     private final static Insets FIRST_HEADER_INSETS = ZERO_INSETS;
 
   75     private final static double GLUE_WEIGHT_X = 1.0;
 
   76     private final static double TEXT_WEIGHT_X = 0.0;
 
   77     private final static int LABEL_COLUMN = 0;
 
   78     private final static int VALUE_COLUMN = 1;
 
   79     private final static int VALUE_WIDTH = 2;
 
   80     private final static int LABEL_WIDTH = 1;
 
   90     private final GridBagLayout gridBagLayout = 
new GridBagLayout();
 
   91     private final GridBagConstraints gridBagConstraints = 
new GridBagConstraints();
 
   92     private final Map<Integer, Integer[]> orderingMap = 
new HashMap<>();
 
   93     private final javax.swing.JPanel detailsPanel = 
new javax.swing.JPanel();
 
  102         gridBagConstraints.anchor = GridBagConstraints.FIRST_LINE_START;
 
  103         detailsPanel.setLayout(gridBagLayout);
 
  150     @NbBundle.Messages({
"GeneralPurposeArtifactViewer.unknown.text=Unknown"})
 
  154         if (artifact != null) {
 
  155             String dataSourceName = Bundle.GeneralPurposeArtifactViewer_unknown_text();
 
  156             String hostName = Bundle.GeneralPurposeArtifactViewer_unknown_text();
 
  157             String sourceFileName = Bundle.GeneralPurposeArtifactViewer_unknown_text();
 
  158             Map<Integer, List<BlackboardAttribute>> attributeMap = 
new HashMap<>();
 
  162                     List<BlackboardAttribute> attrList = attributeMap.get(bba.getAttributeType().getTypeID());
 
  163                     if (attrList == null) {
 
  164                         attrList = 
new ArrayList<>();
 
  167                     attributeMap.put(bba.getAttributeType().getTypeID(), attrList);
 
  172                         .map(h -> h.getName())
 
  177                 logger.log(Level.WARNING, 
"Unable to get attributes for artifact " + artifact.
getArtifactID(), ex);
 
  179             updateView(artifact, attributeMap, dataSourceName, hostName, sourceFileName);
 
  181         detailsScrollPane.setViewportView(detailsPanel);
 
  182         detailsScrollPane.revalidate();
 
  190     private 
void resetComponent() {
 
  192         detailsPanel.removeAll();
 
  193         detailsPanel.setLayout(gridBagLayout);
 
  194         detailsPanel.revalidate();
 
  195         gridBagConstraints.gridy = 0;
 
  196         gridBagConstraints.gridx = LABEL_COLUMN;
 
  197         gridBagConstraints.weighty = 0.0;
 
  198         gridBagConstraints.weightx = TEXT_WEIGHT_X;    
 
  199         gridBagConstraints.fill = GridBagConstraints.NONE;
 
  200         gridBagConstraints.insets = ZERO_INSETS;
 
  206         return (artifact != null)
 
  218     @NbBundle.Messages({
"GeneralPurposeArtifactViewer.details.attrHeader=Details",
 
  219         "GeneralPurposeArtifactViewer.details.sourceHeader=Source",
 
  220         "GeneralPurposeArtifactViewer.details.dataSource=Data Source",
 
  221         "GeneralPurposeArtifactViewer_details_host=Host",
 
  222         "GeneralPurposeArtifactViewer.details.file=File",
 
  223         "GeneralPurposeArtifactViewer.details.datesHeader=Dates"})
 
  229     @SuppressWarnings(
"unchecked")
 
  233         detailsScrollPane = 
new javax.swing.JScrollPane();
 
  235         detailsScrollPane.setPreferredSize(
new java.awt.Dimension(300, 0));
 
  237         javax.swing.GroupLayout layout = 
new javax.swing.GroupLayout(
this);
 
  238         this.setLayout(layout);
 
  239         layout.setHorizontalGroup(
 
  240             layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
 
  241             .addComponent(detailsScrollPane, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
 
  243         layout.setVerticalGroup(
 
  244             layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
 
  245             .addGroup(layout.createSequentialGroup()
 
  246                 .addComponent(detailsScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
 
  262     @NbBundle.Messages({
"GeneralPurposeArtifactViewer.dates.created=Created",
 
  263         "GeneralPurposeArtifactViewer.dates.start=Start",
 
  264         "GeneralPurposeArtifactViewer.dates.end=End",
 
  265         "GeneralPurposeArtifactViewer.dates.time=Time",
 
  266         "GeneralPurposeArtifactViewer.term.label=Term",
 
  267         "GeneralPurposeArtifactViewer.details.otherHeader=Other",
 
  268         "GeneralPurposeArtifactViewer.noFile.text= (no longer exists)"})
 
  270     private void updateView(
BlackboardArtifact artifact, Map<Integer, List<BlackboardAttribute>> attributeMap, String dataSourceName, String hostName, String sourceFilePath) {
 
  272         if (!(artifactTypeId < 1 || artifactTypeId >= Integer.MAX_VALUE)) {
 
  273             JTextPane firstTextPane = addDetailsHeader(artifactTypeId);
 
  274             Integer[] orderingArray = orderingMap.get(artifactTypeId);
 
  275             if (orderingArray == null) {
 
  276                 orderingArray = DEFAULT_ORDERING;
 
  278             for (Integer attrId : orderingArray) {
 
  279                 List<BlackboardAttribute> attrList = attributeMap.remove(attrId);
 
  280                 if (attrList != null) {
 
  282                         if (bba.getAttributeType().getTypeName().startsWith(
"TSK_DATETIME")) {
 
  289                             addNameValueRow(Bundle.GeneralPurposeArtifactViewer_term_label(), bba.getDisplayString());
 
  291                             String displayString = bba.getDisplayString();
 
  293                                 displayString += Bundle.GeneralPurposeArtifactViewer_noFile_text();
 
  295                             addNameValueRow(bba.getAttributeType().getDisplayName(), displayString);
 
  297                             addNameValueRow(bba.getAttributeType().getDisplayName(), bba.getDisplayString());
 
  303                 boolean headerAdded = 
false;
 
  309             if (!attributeMap.keySet().isEmpty()) {
 
  310                 addHeader(Bundle.GeneralPurposeArtifactViewer_details_otherHeader());
 
  311                 for (
int key : attributeMap.keySet()) {
 
  313                         if (bba.getAttributeType().getTypeName().startsWith(
"TSK_DATETIME")) {
 
  316                             addNameValueRow(bba.getAttributeType().getDisplayName(), bba.getDisplayString());
 
  321             addHeader(Bundle.GeneralPurposeArtifactViewer_details_sourceHeader());
 
  322             addNameValueRow(Bundle.GeneralPurposeArtifactViewer_details_host(), StringUtils.defaultString(hostName));
 
  323             addNameValueRow(Bundle.GeneralPurposeArtifactViewer_details_dataSource(), dataSourceName);
 
  324             addNameValueRow(Bundle.GeneralPurposeArtifactViewer_details_file(), sourceFilePath);
 
  327             if (firstTextPane != null) {
 
  328                 firstTextPane.setCaretPosition(0);
 
  331         detailsPanel.revalidate();
 
  344     private boolean addDates(String label, List<BlackboardAttribute> attrList, 
boolean headerExists) {
 
  345         boolean headerAdded = headerExists;
 
  346         if (attrList != null) {
 
  348                 addHeader(Bundle.GeneralPurposeArtifactViewer_details_datesHeader());
 
  351             String labelToUse = label;
 
  353                 if (StringUtils.isBlank(label)) {
 
  354                     labelToUse = bba.getAttributeType().getDisplayName();
 
  356                 addNameValueRow(labelToUse, bba.getDisplayString());
 
  367     @NbBundle.Messages({
"GeneralPurposeArtifactViewer.details.bookmarkHeader=Bookmark Details",
 
  368         "GeneralPurposeArtifactViewer.details.historyHeader=Visit Details",
 
  369         "GeneralPurposeArtifactViewer.details.downloadHeader=Downloaded File",
 
  370         "GeneralPurposeArtifactViewer.details.searchHeader=Web Search",
 
  371         "GeneralPurposeArtifactViewer.details.cachedHeader=Cached File",
 
  372         "GeneralPurposeArtifactViewer.details.cookieHeader=Cookie Details",})
 
  376             header = Bundle.GeneralPurposeArtifactViewer_details_historyHeader();
 
  378             header = Bundle.GeneralPurposeArtifactViewer_details_bookmarkHeader();
 
  380             header = Bundle.GeneralPurposeArtifactViewer_details_cachedHeader();
 
  382             header = Bundle.GeneralPurposeArtifactViewer_details_cookieHeader();
 
  384             header = Bundle.GeneralPurposeArtifactViewer_details_downloadHeader();
 
  386             header = Bundle.GeneralPurposeArtifactViewer_details_searchHeader();
 
  388             header = Bundle.GeneralPurposeArtifactViewer_details_attrHeader();
 
  390         return addHeader(header);
 
  401     private JTextPane addHeader(String headerString) {
 
  403         javax.swing.JTextPane headingLabel = 
new javax.swing.JTextPane();
 
  404         headingLabel.setOpaque(
false);
 
  405         headingLabel.setFocusable(
false);
 
  406         headingLabel.setEditable(
false);
 
  409         gridBagConstraints.insets = (gridBagConstraints.gridy == 0)
 
  410                 ? FIRST_HEADER_INSETS
 
  413         gridBagConstraints.gridy++;
 
  414         gridBagConstraints.gridx = LABEL_COLUMN;;
 
  416         gridBagConstraints.gridwidth = MAX_COLS;
 
  418         headingLabel.setText(headerString);
 
  421         headingLabel.setMargin(ZERO_INSETS);
 
  423         addToPanel(headingLabel);
 
  425         gridBagConstraints.gridwidth = LABEL_WIDTH;
 
  428         gridBagConstraints.insets = ZERO_INSETS;
 
  440         addKeyAtCol(keyString);
 
  441         return addValueAtCol(valueString);
 
  450         gridBagConstraints.gridx = MAX_COLS;
 
  451         gridBagConstraints.weightx = GLUE_WEIGHT_X; 
 
  452         gridBagConstraints.fill = GridBagConstraints.BOTH;
 
  453         javax.swing.Box.Filler horizontalFiller = 
new javax.swing.Box.Filler(
new Dimension(0, 0), 
new Dimension(0, 0), 
new Dimension(32767, 0));
 
  455         addToPanel(horizontalFiller);
 
  457         gridBagConstraints.fill = GridBagConstraints.NONE;
 
  458         gridBagConstraints.weightx = TEXT_WEIGHT_X;
 
  466         gridBagConstraints.weighty = 1.0; 
 
  467         gridBagConstraints.fill = GridBagConstraints.VERTICAL;
 
  468         javax.swing.Box.Filler vertFiller = 
new javax.swing.Box.Filler(
new Dimension(0, 0), 
new Dimension(0, 0), 
new Dimension(0, 32767));
 
  470         addToPanel(vertFiller);
 
  482         javax.swing.JLabel keyLabel = 
new javax.swing.JLabel();
 
  483         keyLabel.setFocusable(
false);
 
  484         gridBagConstraints.gridy++;
 
  485         gridBagConstraints.insets = KEY_COLUMN_INSETS;
 
  486         gridBagConstraints.gridx = LABEL_COLUMN;
 
  487         gridBagConstraints.gridwidth = LABEL_WIDTH;
 
  489         keyLabel.setText(keyString + 
": ");
 
  491         addToPanel(keyLabel);
 
  496         detailsPanel.add(comp, gridBagConstraints);
 
  497         detailsPanel.revalidate();
 
  509         JTextPane valueField = 
new JTextPane();
 
  510         valueField.setFocusable(
false);
 
  511         valueField.setEditable(
false);
 
  512         valueField.setOpaque(
false);
 
  513         valueField.setMargin(ZERO_INSETS);
 
  514         gridBagConstraints.gridx = VALUE_COLUMN;
 
  515         gridBagConstraints.insets = VALUE_COLUMN_INSETS;
 
  516         GridBagConstraints cloneConstraints = (GridBagConstraints) gridBagConstraints.clone();
 
  518         cloneConstraints.gridwidth = VALUE_WIDTH;
 
  519         cloneConstraints.fill = GridBagConstraints.BOTH;
 
  521         valueField.setText(valueString);
 
  523         valueField.addMouseListener(
new java.awt.event.MouseAdapter() {
 
  525             public void mouseClicked(java.awt.event.MouseEvent evt) {
 
  526                 valueLabelMouseClicked(evt, valueField);
 
  530         detailsPanel.add(valueField, cloneConstraints);
 
  545         "GeneralPurposeArtifactViewer_menuitem_copy=Copy" 
  548         if (SwingUtilities.isRightMouseButton(evt)) {
 
  549             JPopupMenu popup = 
new JPopupMenu();
 
  550             JMenuItem copyMenu = 
new JMenuItem(Bundle.CommunicationArtifactViewerHelper_menuitem_copy()); 
 
  551             copyMenu.addActionListener(
new ActionListener() {
 
  553                 public void actionPerformed(ActionEvent e) {
 
  554                     Toolkit.getDefaultToolkit().getSystemClipboard().setContents(
new StringSelection(valueLabel.getText()), null);
 
  558             popup.show(valueLabel, evt.getX(), evt.getY());
 
void setArtifact(BlackboardArtifact artifact)
Host getHostByDataSource(DataSource dataSource)
void updateView(BlackboardArtifact artifact, Map< Integer, List< BlackboardAttribute >> attributeMap, String dataSourceName, String hostName, String sourceFilePath)
static Integer getLineSpacing()
JTextPane addNameValueRow(String keyString, String valueString)
static String getFormattedTime(long epochTime)
void addToPanel(Component comp)
static Insets getPanelInsets()
void valueLabelMouseClicked(java.awt.event.MouseEvent evt, JTextPane valueLabel)
static Integer getSectionIndent()
boolean addDates(String label, List< BlackboardAttribute > attrList, boolean headerExists)
JTextPane addValueAtCol(String valueString)
boolean isSupported(BlackboardArtifact artifact)
static Font getHeaderFont()
HostManager getHostManager()
javax.swing.JScrollPane detailsScrollPane
SleuthkitCase getSleuthkitCase()
JTextPane addDetailsHeader(int artifactTypeId)
List< BlackboardAttribute > getAttributes()
static int getColumnSpacing()
static Integer getSectionSpacing()
synchronized static Logger getLogger(String name)
JLabel addKeyAtCol(String keyString)
static Case getCurrentCaseThrows()