19package org.sleuthkit.autopsy.contentviewers.artifactviewers;
21import java.awt.Component;
22import java.awt.Cursor;
23import java.awt.Toolkit;
24import java.awt.event.ActionEvent;
25import java.awt.event.ActionListener;
26import java.awt.datatransfer.StringSelection;
27import java.text.SimpleDateFormat;
28import java.util.ArrayList;
29import java.util.Enumeration;
31import java.util.logging.Level;
32import javax.swing.JMenuItem;
33import javax.swing.JTextArea;
34import javax.swing.event.ChangeEvent;
35import javax.swing.event.ListSelectionEvent;
36import javax.swing.event.TableColumnModelEvent;
37import javax.swing.table.DefaultTableModel;
38import javax.swing.table.TableColumn;
39import javax.swing.event.TableColumnModelListener;
40import javax.swing.text.View;
41import org.apache.commons.lang.StringUtils;
42import org.openide.util.NbBundle;
43import org.sleuthkit.autopsy.coreutils.Logger;
44import org.sleuthkit.datamodel.BlackboardArtifact;
45import org.sleuthkit.datamodel.BlackboardAttribute;
46import org.sleuthkit.datamodel.Content;
47import org.sleuthkit.datamodel.TskCoreException;
48import org.netbeans.swing.etable.ETable;
49import com.google.gson.JsonElement;
50import com.google.gson.JsonObject;
51import com.google.gson.JsonParser;
52import com.google.gson.JsonArray;
53import java.util.Locale;
55import javax.swing.SwingUtilities;
56import org.sleuthkit.autopsy.coreutils.TimeZoneUtils;
57import org.sleuthkit.autopsy.discovery.ui.AbstractArtifactDetailsPanel;
63@SuppressWarnings(
"PMD.SingularField")
67 "DefaultTableArtifactContentViewer.attrsTableHeader.type=Type",
68 "DefaultTableArtifactContentViewer.attrsTableHeader.value=Value",
69 "DefaultTableArtifactContentViewer.attrsTableHeader.sources=Source(s)",
70 "DataContentViewerArtifact.failedToGetSourcePath.message=Failed to get source file path from case database",
71 "DataContentViewerArtifact.failedToGetAttributes.message=Failed to get some or all attributes from case database"
79 Bundle.DefaultTableArtifactContentViewer_attrsTableHeader_type(),
80 Bundle.DefaultTableArtifactContentViewer_attrsTableHeader_value(),
81 Bundle.DefaultTableArtifactContentViewer_attrsTableHeader_sources()};
97 resultsTable.setModel(
new javax.swing.table.DefaultTableModel() {
98 private static final long serialVersionUID = 1L;
101 public boolean isCellEditable(int rowIndex, int columnIndex) {
105 resultsTable.setCellSelectionEnabled(
true);
106 resultsTable.getTableHeader().setReorderingAllowed(
false);
107 resultsTable.setColumnHidingAllowed(
false);
108 resultsTable.getColumnModel().getSelectionModel().setSelectionMode(javax.swing.ListSelectionModel.SINGLE_INTERVAL_SELECTION);
109 resultsTable.getColumnModel().addColumnModelListener(
new TableColumnModelListener() {
112 public void columnAdded(TableColumnModelEvent e) {
117 public void columnRemoved(TableColumnModelEvent e) {
122 public void columnMoved(TableColumnModelEvent e) {
127 public void columnMarginChanged(ChangeEvent e) {
132 public void columnSelectionChanged(ListSelectionEvent e) {
136 resultsTable.setAutoResizeMode(javax.swing.JTable.AUTO_RESIZE_NEXT_COLUMN);
144 int valueColIndex = -1;
145 for (
int col = 0; col <
resultsTable.getColumnCount(); col++) {
150 if (valueColIndex != -1) {
151 for (
int row = 0; row <
resultsTable.getRowCount(); row++) {
153 resultsTable.getCellRenderer(row, valueColIndex), row, valueColIndex);
155 if (comp instanceof JTextArea) {
156 final JTextArea tc = (JTextArea) comp;
157 final View rootView = tc.getUI().getRootView(tc);
158 java.awt.Insets i = tc.getInsets();
159 rootView.setSize(
resultsTable.getColumnModel().getColumn(valueColIndex)
162 rowHeight = (int) rootView.getPreferredSpan(View.Y_AXIS);
164 rowHeight = comp.getPreferredSize().height;
177 Enumeration<TableColumn> columns =
resultsTable.getColumnModel().getColumns();
178 while (columns.hasMoreElements()) {
179 TableColumn col = columns.nextElement();
195 @SuppressWarnings(
"unchecked")
210 setPreferredSize(
new java.awt.Dimension(0, 0));
212 resultsTableScrollPane.setHorizontalScrollBarPolicy(javax.swing.ScrollPaneConstants.HORIZONTAL_SCROLLBAR_ALWAYS);
213 resultsTableScrollPane.setVerticalScrollBarPolicy(javax.swing.ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);
217 javax.swing.GroupLayout
layout =
new javax.swing.GroupLayout(
this);
219 layout.setHorizontalGroup(
220 layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
224 layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
225 .addComponent(
resultsTableScrollPane, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, 58, Short.MAX_VALUE)
239 ActionListener actList =
new ActionListener() {
241 public void actionPerformed(ActionEvent e) {
242 JMenuItem jmi = (JMenuItem) e.getSource();
244 StringBuilder selectedText =
new StringBuilder(512);
247 selectedText.append((String)
resultsTable.getValueAt(row, col));
248 selectedText.append(
'\t');
252 selectedText.append(System.lineSeparator());
255 Toolkit.getDefaultToolkit().getSystemClipboard().setContents(
new StringSelection(selectedText.toString()),
null);
271 ((DefaultTableModel)
resultsTable.getModel()).setRowCount(0);
284 SwingUtilities.invokeLater(
new Runnable() {
291 }
catch (TskCoreException ex) {
292 logger.log(Level.SEVERE, String.format(
"Error getting parent content for artifact (artifact_id=%d, obj_id=%d)", artifact.getArtifactID(), artifact.getObjectID()), ex);
307 private class ResultsTableArtifact {
309 private final SimpleDateFormat
dateFormatter =
new SimpleDateFormat(
"yyyy-MM-dd HH:mm:ss", Locale.US);
314 ResultsTableArtifact(BlackboardArtifact artifact, Content
content) {
321 artifactDisplayName = errorMsg;
322 rowData =
new String[1][3];
323 rowData[0] =
new String[]{
"", errorMsg,
""};
331 private void addRows(BlackboardArtifact artifact) {
332 List<String[]> rowsToAdd =
new ArrayList<>();
337 for (BlackboardAttribute attr : artifact.getAttributes()) {
342 switch (attr.getAttributeType().getValueType()) {
350 String jsonVal = attr.getValueString();
351 JsonElement jsonEl = JsonParser.parseString(jsonVal);
361 value = attr.getDisplayString();
367 String sources = StringUtils.join(attr.getSources(),
", ");
368 rowsToAdd.add(
new String[]{attr.getAttributeType().getDisplayName(), value, sources});
376 path =
content.getUniquePath();
378 }
catch (TskCoreException ex) {
379 logger.log(Level.SEVERE, String.format(
"Error getting source content path for artifact (artifact_id=%d, obj_id=%d)", artifact.getArtifactID(), artifact.getObjectID()), ex);
380 path = Bundle.DataContentViewerArtifact_failedToGetSourcePath_message();
382 rowsToAdd.add(
new String[]{
"Source File Path", path,
""});
386 rowsToAdd.add(
new String[]{
"Artifact ID", Long.toString(artifact.getArtifactID()),
""});
387 }
catch (TskCoreException ex) {
388 rowsToAdd.add(
new String[]{
"", Bundle.DataContentViewerArtifact_failedToGetAttributes_message(),
""});
390 rowData = rowsToAdd.toArray(
new String[0][0]);
396 String getArtifactDisplayName() {
397 return artifactDisplayName;
413 if (element ==
null || element.isJsonNull()) {
415 }
else if (element.isJsonPrimitive()) {
416 return element.getAsString();
417 }
else if (element.isJsonObject()) {
418 StringBuilder sb =
new StringBuilder(
"");
419 JsonObject obj = element.getAsJsonObject();
421 for (Map.Entry<String, JsonElement> entry : obj.entrySet()) {
425 String returnString = sb.toString();
426 if (startIndent.length() == 0 && returnString.startsWith(
NEW_LINE)) {
427 returnString = returnString.substring(
NEW_LINE.length());
430 }
else if (element.isJsonArray()) {
431 StringBuilder sb =
new StringBuilder(
"");
432 JsonArray jsonArray = element.getAsJsonArray();
433 if (jsonArray.size() > 0) {
435 for (JsonElement arrayMember : jsonArray) {
436 sb.append(
NEW_LINE).append(String.format(
"%s%d", startIndent, count));
442 String returnString = sb.toString();
443 if (startIndent.length() == 0 && returnString.startsWith(
NEW_LINE)) {
444 returnString = returnString.substring(
NEW_LINE.length());
462 if (jsonElement.isJsonArray()) {
463 JsonArray jsonArray = jsonElement.getAsJsonArray();
464 if (jsonArray.size() > 0) {
466 sb.append(
NEW_LINE).append(String.format(
"%s%s", startIndent, jsonKey));
467 for (JsonElement arrayMember : jsonArray) {
473 }
else if (jsonElement.isJsonObject()) {
475 }
else if (jsonElement.isJsonPrimitive()) {
476 String attributeName = jsonKey;
477 String attributeValue;
478 if (attributeName.toUpperCase().contains(
"DATETIME")) {
481 attributeValue = jsonElement.getAsString();
483 sb.append(
NEW_LINE).append(String.format(
"%s%s = %s", startIndent, attributeName, attributeValue));
484 }
else if (jsonElement.isJsonNull()) {
485 sb.append(
NEW_LINE).append(String.format(
"%s%s = null", startIndent, jsonKey));
498 this.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
499 DefaultTableModel tModel = ((DefaultTableModel)
resultsTable.getModel());
500 String[][] rows = resultsTableArtifact ==
null ?
new String[0][0] : resultsTableArtifact.
getRows();
505 this.setCursor(
null);
515 javax.swing.JTextArea jtex =
new javax.swing.JTextArea();
516 if (value instanceof String) {
517 jtex.setText((String) value);
518 jtex.setLineWrap(
true);
519 jtex.setWrapStyleWord(
false);
523 jtex.setBackground(javax.swing.UIManager.getColor(
"Table.selectionBackground"));
525 jtex.setBackground(javax.swing.UIManager.getColor(
"Table.background"));
javax.swing.JScrollPane resultsTableScrollPane
void updateView(ResultsTableArtifact resultsTableArtifact)
void customizeComponents()
static final int CELL_BOTTOM_MARGIN
DefaultTableArtifactContentViewer()
boolean isSupported(BlackboardArtifact artifact)
static final int CELL_RIGHT_MARGIN
javax.swing.JMenuItem selectAllMenuItem
javax.swing.JPopupMenu rightClickMenu
static final String[] COLUMN_HEADERS
static final int[] COLUMN_WIDTHS
static final long serialVersionUID
javax.swing.JMenuItem copyMenuItem
void setArtifact(BlackboardArtifact artifact)
static final Logger logger
final String artifactDisplayName
void appendJsonElementToString(String jsonKey, JsonElement jsonElement, String startIndent, StringBuilder sb)
final SimpleDateFormat dateFormatter
static final String NEW_LINE
static final String INDENT_RIGHT
void addRows(BlackboardArtifact artifact)
String toJsonDisplayString(JsonElement element, String startIndent)
Component getTableCellRendererComponent(javax.swing.JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column)
synchronized static Logger getLogger(String name)
static String getFormattedTime(long epochTime)