19 package org.sleuthkit.autopsy.contentviewers.artifactviewers;
21 import java.awt.Component;
22 import java.awt.Cursor;
23 import java.awt.Toolkit;
24 import java.awt.event.ActionEvent;
25 import java.awt.event.ActionListener;
26 import java.awt.datatransfer.StringSelection;
27 import java.text.SimpleDateFormat;
28 import java.util.ArrayList;
29 import java.util.Enumeration;
30 import java.util.List;
31 import java.util.logging.Level;
32 import javax.swing.JMenuItem;
33 import javax.swing.JTextArea;
34 import javax.swing.event.ChangeEvent;
35 import javax.swing.event.ListSelectionEvent;
36 import javax.swing.event.TableColumnModelEvent;
37 import javax.swing.table.DefaultTableModel;
38 import javax.swing.table.TableColumn;
39 import javax.swing.event.TableColumnModelListener;
40 import javax.swing.text.View;
41 import org.apache.commons.lang.StringUtils;
42 import org.openide.util.NbBundle;
49 import org.netbeans.swing.etable.ETable;
50 import com.google.gson.JsonElement;
51 import com.google.gson.JsonObject;
52 import com.google.gson.JsonParser;
53 import com.google.gson.JsonArray;
54 import java.util.Locale;
56 import javax.swing.SwingUtilities;
64 @SuppressWarnings(
"PMD.SingularField")
68 "DefaultArtifactContentViewer.attrsTableHeader.type=Type",
69 "DefaultArtifactContentViewer.attrsTableHeader.value=Value",
70 "DefaultArtifactContentViewer.attrsTableHeader.sources=Source(s)",
71 "DataContentViewerArtifact.failedToGetSourcePath.message=Failed to get source file path from case database",
72 "DataContentViewerArtifact.failedToGetAttributes.message=Failed to get some or all attributes from case database"
77 private static final long serialVersionUID = 1L;
79 private static final String[] COLUMN_HEADERS = {
80 Bundle.DefaultArtifactContentViewer_attrsTableHeader_type(),
81 Bundle.DefaultArtifactContentViewer_attrsTableHeader_value(),
82 Bundle.DefaultArtifactContentViewer_attrsTableHeader_sources()};
83 private static final int[] COLUMN_WIDTHS = {100, 800, 100};
84 private static final int CELL_BOTTOM_MARGIN = 5;
85 private static final int CELL_RIGHT_MARGIN = 1;
90 resultsTableScrollPane.setViewportView(resultsTable);
91 customizeComponents();
97 resultsTable =
new ETable();
98 resultsTable.setModel(
new javax.swing.table.DefaultTableModel() {
99 private static final long serialVersionUID = 1L;
102 public boolean isCellEditable(
int rowIndex,
int columnIndex) {
106 resultsTable.setCellSelectionEnabled(
true);
107 resultsTable.getTableHeader().setReorderingAllowed(
false);
108 resultsTable.setColumnHidingAllowed(
false);
109 resultsTable.getColumnModel().getSelectionModel().setSelectionMode(javax.swing.ListSelectionModel.SINGLE_INTERVAL_SELECTION);
110 resultsTable.getColumnModel().addColumnModelListener(
new TableColumnModelListener() {
113 public void columnAdded(TableColumnModelEvent e) {
118 public void columnRemoved(TableColumnModelEvent e) {
123 public void columnMoved(TableColumnModelEvent e) {
128 public void columnMarginChanged(ChangeEvent e) {
133 public void columnSelectionChanged(ListSelectionEvent e) {
137 resultsTable.setAutoResizeMode(javax.swing.JTable.AUTO_RESIZE_NEXT_COLUMN);
145 int valueColIndex = -1;
146 for (
int col = 0; col < resultsTable.getColumnCount(); col++) {
147 if (resultsTable.getColumnName(col).equals(COLUMN_HEADERS[1])) {
151 if (valueColIndex != -1) {
152 for (
int row = 0; row < resultsTable.getRowCount(); row++) {
153 Component comp = resultsTable.prepareRenderer(
154 resultsTable.getCellRenderer(row, valueColIndex), row, valueColIndex);
156 if (comp instanceof JTextArea) {
157 final JTextArea tc = (JTextArea) comp;
158 final View rootView = tc.getUI().getRootView(tc);
159 java.awt.Insets i = tc.getInsets();
160 rootView.setSize(resultsTable.getColumnModel().getColumn(valueColIndex)
161 .getWidth() - (i.left + i.right +CELL_RIGHT_MARGIN),
163 rowHeight = (int) rootView.getPreferredSpan(View.Y_AXIS);
165 rowHeight = comp.getPreferredSize().height;
168 resultsTable.setRowHeight(row, rowHeight + CELL_BOTTOM_MARGIN);
178 Enumeration<TableColumn> columns = resultsTable.getColumnModel().getColumns();
179 while (columns.hasMoreElements()) {
180 TableColumn col = columns.nextElement();
181 if (col.getHeaderValue().equals(COLUMN_HEADERS[0])) {
182 col.setPreferredWidth(COLUMN_WIDTHS[0]);
183 }
else if (col.getHeaderValue().equals(COLUMN_HEADERS[1])) {
184 col.setPreferredWidth(COLUMN_WIDTHS[1]);
185 }
else if (col.getHeaderValue().equals(COLUMN_HEADERS[2])) {
186 col.setPreferredWidth(COLUMN_WIDTHS[2]);
196 @SuppressWarnings(
"unchecked")
198 private
void initComponents() {
200 rightClickMenu =
new javax.swing.JPopupMenu();
201 copyMenuItem =
new javax.swing.JMenuItem();
202 selectAllMenuItem =
new javax.swing.JMenuItem();
203 resultsTableScrollPane =
new javax.swing.JScrollPane();
206 rightClickMenu.add(copyMenuItem);
208 selectAllMenuItem.setText(
org.openide.util.NbBundle.getMessage(
DefaultArtifactContentViewer.class,
"DefaultArtifactContentViewer.selectAllMenuItem.text"));
209 rightClickMenu.add(selectAllMenuItem);
211 setPreferredSize(
new java.awt.Dimension(100, 58));
213 resultsTableScrollPane.setHorizontalScrollBarPolicy(javax.swing.ScrollPaneConstants.HORIZONTAL_SCROLLBAR_ALWAYS);
214 resultsTableScrollPane.setVerticalScrollBarPolicy(javax.swing.ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);
215 resultsTableScrollPane.setPreferredSize(
new java.awt.Dimension(620, 34));
217 javax.swing.GroupLayout layout =
new javax.swing.GroupLayout(
this);
218 this.setLayout(layout);
219 layout.setHorizontalGroup(
220 layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
221 .addComponent(resultsTableScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, 100, Short.MAX_VALUE)
223 layout.setVerticalGroup(
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)
238 resultsTable.setComponentPopupMenu(rightClickMenu);
239 ActionListener actList =
new ActionListener() {
241 public void actionPerformed(ActionEvent e) {
242 JMenuItem jmi = (JMenuItem) e.getSource();
243 if (jmi.equals(copyMenuItem)) {
244 StringBuilder selectedText =
new StringBuilder(512);
245 for (
int row : resultsTable.getSelectedRows()) {
246 for (
int col : resultsTable.getSelectedColumns()) {
247 selectedText.append((String) resultsTable.getValueAt(row, col));
248 selectedText.append(
'\t');
251 if (row != resultsTable.getSelectedRows()[resultsTable.getSelectedRows().length - 1]) {
252 selectedText.append(System.lineSeparator());
255 Toolkit.getDefaultToolkit().getSystemClipboard().setContents(
new StringSelection(selectedText.toString()), null);
256 }
else if (jmi.equals(selectAllMenuItem)) {
257 resultsTable.selectAll();
261 copyMenuItem.addActionListener(actList);
263 selectAllMenuItem.addActionListener(actList);
271 ((DefaultTableModel) resultsTable.getModel()).setRowCount(0);
284 SwingUtilities.invokeLater(
new Runnable() {
287 updateView(resultsTableArtifact);
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);
309 private final SimpleDateFormat dateFormatter =
new SimpleDateFormat(
"yyyy-MM-dd HH:mm:ss", Locale.US);
310 private String[][] rowData = null;
315 artifactDisplayName = artifact.getDisplayName();
316 this.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()) {
346 value = epochTimeToString(attr.getValueLong());
350 String jsonVal = attr.getValueString();
351 JsonParser parser =
new JsonParser();
352 JsonObject json = parser.parse(jsonVal).getAsJsonObject();
354 value = toJsonDisplayString(json,
"");
363 value = attr.getDisplayString();
369 String sources = StringUtils.join(attr.getSources(),
", ");
370 rowsToAdd.add(
new String[]{attr.getAttributeType().getDisplayName(), value, sources});
377 if (null != content) {
378 path = content.getUniquePath();
380 }
catch (TskCoreException ex) {
381 logger.log(Level.SEVERE, String.format(
"Error getting source content path for artifact (artifact_id=%d, obj_id=%d)", artifact.getArtifactID(), artifact.getObjectID()), ex);
382 path = Bundle.DataContentViewerArtifact_failedToGetSourcePath_message();
384 rowsToAdd.add(
new String[]{
"Source File Path", path,
""});
388 rowsToAdd.add(
new String[]{
"Artifact ID", Long.toString(artifact.getArtifactID()),
""});
389 }
catch (TskCoreException ex) {
390 rowsToAdd.add(
new String[]{
"", Bundle.DataContentViewerArtifact_failedToGetAttributes_message(),
""});
392 rowData = rowsToAdd.toArray(
new String[0][0]);
398 String getArtifactDisplayName() {
399 return artifactDisplayName;
402 private static final String INDENT_RIGHT =
" ";
403 private static final String NEW_LINE =
"\n";
416 StringBuilder sb =
new StringBuilder(
"");
417 JsonObject obj = element.getAsJsonObject();
419 for (Map.Entry<String, JsonElement> entry : obj.entrySet()) {
420 appendJsonElementToString(entry.getKey(), entry.getValue(), startIndent, sb );
423 String returnString = sb.toString();
424 if (startIndent.length() == 0 && returnString.startsWith(NEW_LINE)) {
425 returnString = returnString.substring(NEW_LINE.length());
440 if (jsonElement.isJsonArray()) {
441 JsonArray jsonArray = jsonElement.getAsJsonArray();
442 if (jsonArray.size() > 0) {
444 sb.append(NEW_LINE).append(String.format(
"%s%s", startIndent, jsonKey));
445 for (JsonElement arrayMember : jsonArray) {
446 sb.append(NEW_LINE).append(String.format(
"%s%d", startIndent.concat(INDENT_RIGHT), count));
447 sb.append(toJsonDisplayString(arrayMember, startIndent.concat(INDENT_RIGHT).concat(INDENT_RIGHT)));
451 }
else if (jsonElement.isJsonObject()) {
452 sb.append(NEW_LINE).append(String.format(
"%s%s %s", startIndent, jsonKey, toJsonDisplayString(jsonElement.getAsJsonObject(), startIndent + INDENT_RIGHT)));
453 }
else if (jsonElement.isJsonPrimitive()) {
454 String attributeName = jsonKey;
455 String attributeValue;
456 if (attributeName.toUpperCase().contains(
"DATETIME")) {
457 attributeValue = epochTimeToString(Long.parseLong(jsonElement.getAsString()));
459 attributeValue = jsonElement.getAsString();
461 sb.append(NEW_LINE).append(String.format(
"%s%s = %s", startIndent, attributeName, attributeValue));
462 }
else if (jsonElement.isJsonNull()) {
463 sb.append(NEW_LINE).append(String.format(
"%s%s = null", startIndent, jsonKey));
474 String dateTimeString =
"0000-00-00 00:00:00";
475 if (null != content && 0 != epochTime) {
477 dateTimeString = dateFormatter.format(
new java.util.Date(epochTime * 1000));
479 return dateTimeString;
492 this.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
494 DefaultTableModel tModel = ((DefaultTableModel) resultsTable.getModel());
495 tModel.setDataVector(resultsTableArtifact.
getRows(), COLUMN_HEADERS);
498 resultsTable.clearSelection();
500 this.setCursor(null);
510 javax.swing.JTextArea jtex =
new javax.swing.JTextArea();
511 if (value instanceof String) {
512 jtex.setText((String) value);
513 jtex.setLineWrap(
true);
514 jtex.setWrapStyleWord(
false);
518 jtex.setBackground(javax.swing.UIManager.getColor(
"Table.selectionBackground"));
520 jtex.setBackground(javax.swing.UIManager.getColor(
"Table.background"));
javax.swing.JMenuItem selectAllMenuItem
void customizeComponents()
javax.swing.JPopupMenu rightClickMenu
Component getTableCellRendererComponent(javax.swing.JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column)
DefaultArtifactContentViewer()
boolean isSupported(BlackboardArtifact artifact)
final String artifactDisplayName
String epochTimeToString(long epochTime)
static TimeZone getTimeZone(Content content)
javax.swing.JScrollPane resultsTableScrollPane
String toJsonDisplayString(JsonElement element, String startIndent)
javax.swing.JMenuItem copyMenuItem
void updateView(ResultsTableArtifact resultsTableArtifact)
synchronized static Logger getLogger(String name)
void setArtifact(BlackboardArtifact artifact)
void appendJsonElementToString(String jsonKey, JsonElement jsonElement, String startIndent, StringBuilder sb)
void addRows(BlackboardArtifact artifact)