Autopsy  4.12.0
Graphical digital forensics platform for The Sleuth Kit and other tools.
TableReportGenerator.java
Go to the documentation of this file.
1 /*
2  * Autopsy Forensic Browser
3  *
4  * Copyright 2013-2019 Basis Technology Corp.
5  * Contact: carrier <at> sleuthkit <dot> org
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  * http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  */
19 package org.sleuthkit.autopsy.report;
20 
21 import com.google.common.collect.ListMultimap;
22 import com.google.common.collect.Lists;
23 import com.google.common.collect.Multimaps;
24 import java.sql.ResultSet;
25 import java.sql.SQLException;
26 import java.util.ArrayList;
27 import java.util.Arrays;
28 import java.util.Collection;
29 import java.util.Collections;
30 import java.util.Comparator;
31 import java.util.HashMap;
32 import java.util.HashSet;
33 import java.util.Iterator;
34 import java.util.List;
35 import java.util.Map;
36 import java.util.Objects;
37 import java.util.Set;
38 import java.util.TreeSet;
39 import java.util.logging.Level;
40 import org.openide.util.NbBundle;
41 import org.openide.util.NbBundle.Messages;
49 import org.sleuthkit.datamodel.AbstractFile;
50 import org.sleuthkit.datamodel.Account;
51 import org.sleuthkit.datamodel.BlackboardArtifact;
52 import org.sleuthkit.datamodel.BlackboardArtifactTag;
53 import org.sleuthkit.datamodel.BlackboardAttribute;
54 import org.sleuthkit.datamodel.BlackboardAttribute.Type;
55 import org.sleuthkit.datamodel.Content;
56 import org.sleuthkit.datamodel.ContentTag;
57 import org.sleuthkit.datamodel.SleuthkitCase;
58 import org.sleuthkit.datamodel.TagName;
59 import org.sleuthkit.datamodel.TskCoreException;
60 import org.sleuthkit.datamodel.TskData;
61 
62 class TableReportGenerator {
63 
64  private final List<BlackboardArtifact.Type> artifactTypes = new ArrayList<>();
65  private final HashSet<String> tagNamesFilter = new HashSet<>();
66 
67  private final Set<Content> images = new HashSet<>();
68  private final ReportProgressPanel progressPanel;
69  private final TableReportModule tableReport;
70  private final Map<Integer, List<Column>> columnHeaderMap;
71  private static final Logger logger = Logger.getLogger(TableReportGenerator.class.getName());
72 
73  private final List<String> errorList;
74 
75  TableReportGenerator(Map<BlackboardArtifact.Type, Boolean> artifactTypeSelections, Map<String, Boolean> tagNameSelections, ReportProgressPanel progressPanel, TableReportModule tableReport) {
76 
77  this.progressPanel = progressPanel;
78  this.tableReport = tableReport;
79  this.columnHeaderMap = new HashMap<>();
80  errorList = new ArrayList<>();
81  // Get the artifact types selected by the user.
82  for (Map.Entry<BlackboardArtifact.Type, Boolean> entry : artifactTypeSelections.entrySet()) {
83  if (entry.getValue()) {
84  artifactTypes.add(entry.getKey());
85  }
86  }
87 
88  // Get the tag names selected by the user and make a tag names filter.
89  if (null != tagNameSelections) {
90  for (Map.Entry<String, Boolean> entry : tagNameSelections.entrySet()) {
91  if (entry.getValue() == true) {
92  tagNamesFilter.add(entry.getKey());
93  }
94  }
95  }
96  }
97 
98  protected void execute() {
99  // Start the progress indicators for each active TableReportModule.
100 
101  progressPanel.start();
102  progressPanel.setIndeterminate(false);
103  progressPanel.setMaximumProgress(this.artifactTypes.size() + 2); // +2 for content and blackboard artifact tags
104  // report on the blackboard results
105  if (progressPanel.getStatus() != ReportProgressPanel.ReportStatus.CANCELED) {
106  makeBlackboardArtifactTables();
107  }
108 
109  // report on the tagged files and artifacts
110  if (progressPanel.getStatus() != ReportProgressPanel.ReportStatus.CANCELED) {
111  makeContentTagsTables();
112  }
113 
114  if (progressPanel.getStatus() != ReportProgressPanel.ReportStatus.CANCELED) {
115  makeBlackboardArtifactTagsTables();
116  }
117 
118  if (progressPanel.getStatus() != ReportProgressPanel.ReportStatus.CANCELED) {
119  // report on the tagged images
120  makeThumbnailTable();
121  }
122  }
123 
127  private void makeBlackboardArtifactTables() {
128  // Make a comment string describing the tag names filter in effect.
129  String comment = "";
130  if (!tagNamesFilter.isEmpty()) {
131  comment += NbBundle.getMessage(this.getClass(), "ReportGenerator.artifactTable.taggedResults.text");
132  comment += makeCommaSeparatedList(tagNamesFilter);
133  }
134 
135  // Add a table to the report for every enabled blackboard artifact type.
136  for (BlackboardArtifact.Type type : artifactTypes) {
137  // Check for cancellaton.
138 
139  if (progressPanel.getStatus() == ReportProgressPanel.ReportStatus.CANCELED) {
140  return;
141  }
142 
143  progressPanel.updateStatusLabel(
144  NbBundle.getMessage(this.getClass(), "ReportGenerator.progress.processing",
145  type.getDisplayName()));
146 
147  // Keyword hits and hashset hit artifacts get special handling.
148  if (type.getTypeID() == BlackboardArtifact.ARTIFACT_TYPE.TSK_KEYWORD_HIT.getTypeID()) {
149  writeKeywordHits(tableReport, comment, tagNamesFilter);
150  continue;
151  } else if (type.getTypeID() == BlackboardArtifact.ARTIFACT_TYPE.TSK_HASHSET_HIT.getTypeID()) {
152  writeHashsetHits(tableReport, comment, tagNamesFilter);
153  continue;
154  }
155 
156  List<ArtifactData> artifactList = getFilteredArtifacts(type, tagNamesFilter);
157 
158  if (artifactList.isEmpty()) {
159  continue;
160  }
161 
162  /*
163  * TSK_ACCOUNT artifacts get grouped by their TSK_ACCOUNT_TYPE
164  * attribute, and then handed off to the standard method for writing
165  * tables.
166  */
167  if (type.getTypeID() == BlackboardArtifact.ARTIFACT_TYPE.TSK_ACCOUNT.getTypeID()) {
168  //Group account artifacts by their account type
169  ListMultimap<String, ArtifactData> groupedArtifacts = Multimaps.index(artifactList,
170  artifactData -> {
171  try {
172  return artifactData.getArtifact().getAttribute(new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_ACCOUNT_TYPE)).getValueString();
173  } catch (TskCoreException ex) {
174  logger.log(Level.SEVERE, "Unable to get value of TSK_ACCOUNT_TYPE attribute. Defaulting to \"unknown\"", ex);
175  return "unknown";
176  }
177  });
178  for (String accountTypeStr : groupedArtifacts.keySet()) {
179  /*
180  * If the report is a ReportHTML, the data type name
181  * eventualy makes it to useDataTypeIcon which expects but
182  * does not require a artifact name, so we make a synthetic
183  * compund name by appending a ":" and the account type.
184  */
185  String accountDisplayname = accountTypeStr;
186  if (accountTypeStr != null) {
187  try {
188  Account.Type acctType = Case.getCurrentCaseThrows().getSleuthkitCase().getCommunicationsManager().getAccountType(accountTypeStr);
189  if (acctType != null) {
190  accountDisplayname = acctType.getDisplayName();
191  }
192  } catch (TskCoreException | NoCurrentCaseException ex) {
193  logger.log(Level.SEVERE, "Unable to get display name for account type " + accountTypeStr, ex);
194  }
195  }
196 
197  final String compundDataTypeName = BlackboardArtifact.ARTIFACT_TYPE.TSK_ACCOUNT.getDisplayName() + ": " + accountDisplayname;
198  writeTableForDataType(new ArrayList<>(groupedArtifacts.get(accountTypeStr)), type, compundDataTypeName, comment);
199  }
200  } else {
201  //all other artifact types are sent to writeTableForDataType directly
202  writeTableForDataType(artifactList, type, type.getDisplayName(), comment);
203  }
204  }
205  }
206 
217  private void writeTableForDataType(List<ArtifactData> artifactList, BlackboardArtifact.Type type, String tableName, String comment) {
218  /*
219  * Make a sorted set of all of the attribute types that are on any of
220  * the given artifacts.
221  */
222  Set<BlackboardAttribute.Type> attrTypeSet = new TreeSet<>(Comparator.comparing(BlackboardAttribute.Type::getDisplayName));
223  for (ArtifactData data : artifactList) {
224  List<BlackboardAttribute> attributes = data.getAttributes();
225  for (BlackboardAttribute attribute : attributes) {
226  attrTypeSet.add(attribute.getAttributeType());
227  }
228  }
229  /*
230  * Get the columns appropriate for the artifact type. This is used to
231  * get the data that will be in the cells below based on type, and
232  * display the column headers.
233  */
234  List<Column> columns = getArtifactTableColumns(type.getTypeID(), attrTypeSet);
235  if (columns.isEmpty()) {
236  return;
237  }
238  columnHeaderMap.put(type.getTypeID(), columns);
239 
240  /*
241  * The artifact list is sorted now, as getting the row data is dependent
242  * on having the columns, which is necessary for sorting.
243  */
244  Collections.sort(artifactList);
245 
246  tableReport.startDataType(tableName, comment);
247  tableReport.startTable(Lists.transform(columns, Column::getColumnHeader));
248 
249  for (ArtifactData artifactData : artifactList) {
250  // Get the row data for this artifact, and has the
251  // module add it.
252  List<String> rowData = artifactData.getRow();
253  if (rowData.isEmpty()) {
254  return;
255  }
256 
257  tableReport.addRow(rowData);
258  }
259  // Finish up this data type
260  progressPanel.increment();
261  tableReport.endTable();
262  tableReport.endDataType();
263  }
264 
268  @Messages({"ReportGenerator.tagTable.header.userName=User Name"})
269  @SuppressWarnings("deprecation")
270  private void makeContentTagsTables() {
271 
272  // Get the content tags.
273  List<ContentTag> tags;
274  try {
275  tags = Case.getCurrentCaseThrows().getServices().getTagsManager().getAllContentTags();
276  } catch (TskCoreException | NoCurrentCaseException ex) {
277  errorList.add(NbBundle.getMessage(this.getClass(), "ReportGenerator.errList.failedGetContentTags"));
278  logger.log(Level.SEVERE, "failed to get content tags", ex); //NON-NLS
279  return;
280  }
281 
282  // Tell the modules reporting on content tags is beginning.
283  // @@@ This casting is a tricky little workaround to allow the HTML report module to slip in a content hyperlink.
284  // @@@ Alos Using the obsolete ARTIFACT_TYPE.TSK_TAG_FILE is also an expedient hack.
285  progressPanel.updateStatusLabel(
286  NbBundle.getMessage(this.getClass(), "ReportGenerator.progress.processing",
287  BlackboardArtifact.ARTIFACT_TYPE.TSK_TAG_FILE.getDisplayName()));
288  ArrayList<String> columnHeaders = new ArrayList<>(Arrays.asList(
289  NbBundle.getMessage(this.getClass(), "ReportGenerator.htmlOutput.header.tag"),
290  NbBundle.getMessage(this.getClass(), "ReportGenerator.htmlOutput.header.file"),
291  NbBundle.getMessage(this.getClass(), "ReportGenerator.htmlOutput.header.comment"),
292  NbBundle.getMessage(this.getClass(), "ReportGenerator.tagTable.header.userName"),
293  NbBundle.getMessage(this.getClass(), "ReportGenerator.htmlOutput.header.timeModified"),
294  NbBundle.getMessage(this.getClass(), "ReportGenerator.htmlOutput.header.timeChanged"),
295  NbBundle.getMessage(this.getClass(), "ReportGenerator.htmlOutput.header.timeAccessed"),
296  NbBundle.getMessage(this.getClass(), "ReportGenerator.htmlOutput.header.timeCreated"),
297  NbBundle.getMessage(this.getClass(), "ReportGenerator.htmlOutput.header.size"),
298  NbBundle.getMessage(this.getClass(), "ReportGenerator.htmlOutput.header.hash")));
299 
300  StringBuilder comment = new StringBuilder();
301  if (!tagNamesFilter.isEmpty()) {
302  comment.append(
303  NbBundle.getMessage(this.getClass(), "ReportGenerator.makeContTagTab.taggedFiles.msg"));
304  comment.append(makeCommaSeparatedList(tagNamesFilter));
305  }
306  if (tableReport instanceof ReportHTML) {
307  ReportHTML htmlReportModule = (ReportHTML) tableReport;
308  htmlReportModule.startDataType(BlackboardArtifact.ARTIFACT_TYPE.TSK_TAG_FILE.getDisplayName(), comment.toString());
309  htmlReportModule.startContentTagsTable(columnHeaders);
310  } else {
311  tableReport.startDataType(BlackboardArtifact.ARTIFACT_TYPE.TSK_TAG_FILE.getDisplayName(), comment.toString());
312  tableReport.startTable(columnHeaders);
313  }
314 
315  // Give the modules the rows for the content tags.
316  for (ContentTag tag : tags) {
317  // skip tags that we are not reporting on
318  String notableString = tag.getName().getKnownStatus() == TskData.FileKnown.BAD ? TagsManager.getNotableTagLabel() : "";
319  if (passesTagNamesFilter(tag.getName().getDisplayName() + notableString) == false) {
320  continue;
321  }
322 
323  String fileName;
324  try {
325  fileName = tag.getContent().getUniquePath();
326  } catch (TskCoreException ex) {
327  fileName = tag.getContent().getName();
328  }
329 
330  ArrayList<String> rowData = new ArrayList<>(Arrays.asList(tag.getName().getDisplayName() + notableString, fileName, tag.getComment(), tag.getUserName()));
331  Content content = tag.getContent();
332  if (content instanceof AbstractFile) {
333  AbstractFile file = (AbstractFile) content;
334 
335  // Add metadata about the file to HTML output
336  rowData.add(file.getMtimeAsDate());
337  rowData.add(file.getCtimeAsDate());
338  rowData.add(file.getAtimeAsDate());
339  rowData.add(file.getCrtimeAsDate());
340  rowData.add(Long.toString(file.getSize()));
341  rowData.add(file.getMd5Hash());
342  }
343  // @@@ This casting is a tricky little workaround to allow the HTML report module to slip in a content hyperlink.
344  if (tableReport instanceof ReportHTML) {
345  ReportHTML htmlReportModule = (ReportHTML) tableReport;
346  htmlReportModule.addRowWithTaggedContentHyperlink(rowData, tag);
347  } else {
348  tableReport.addRow(rowData);
349  }
350 
351  // see if it is for an image so that we later report on it
352  checkIfTagHasImage(tag);
353  }
354 
355  // The the modules content tags reporting is ended.
356  progressPanel.increment();
357  tableReport.endTable();
358  tableReport.endDataType();
359  }
360 
364  @SuppressWarnings("deprecation")
365  private void makeBlackboardArtifactTagsTables() {
366 
367  List<BlackboardArtifactTag> tags;
368  try {
369  tags = Case.getCurrentCaseThrows().getServices().getTagsManager().getAllBlackboardArtifactTags();
370  } catch (TskCoreException | NoCurrentCaseException ex) {
371  errorList.add(NbBundle.getMessage(this.getClass(), "ReportGenerator.errList.failedGetBBArtifactTags"));
372  logger.log(Level.SEVERE, "failed to get blackboard artifact tags", ex); //NON-NLS
373  return;
374  }
375 
376  // Tell the modules reporting on blackboard artifact tags data type is beginning.
377  // @@@ Using the obsolete ARTIFACT_TYPE.TSK_TAG_ARTIFACT is an expedient hack.
378  progressPanel.updateStatusLabel(
379  NbBundle.getMessage(this.getClass(), "ReportGenerator.progress.processing",
380  BlackboardArtifact.ARTIFACT_TYPE.TSK_TAG_ARTIFACT.getDisplayName()));
381  StringBuilder comment = new StringBuilder();
382  if (!tagNamesFilter.isEmpty()) {
383  comment.append(
384  NbBundle.getMessage(this.getClass(), "ReportGenerator.makeBbArtTagTab.taggedRes.msg"));
385  comment.append(makeCommaSeparatedList(tagNamesFilter));
386  }
387  tableReport.startDataType(BlackboardArtifact.ARTIFACT_TYPE.TSK_TAG_ARTIFACT.getDisplayName(), comment.toString());
388  tableReport.startTable(new ArrayList<>(Arrays.asList(
389  NbBundle.getMessage(this.getClass(), "ReportGenerator.tagTable.header.resultType"),
390  NbBundle.getMessage(this.getClass(), "ReportGenerator.tagTable.header.tag"),
391  NbBundle.getMessage(this.getClass(), "ReportGenerator.tagTable.header.comment"),
392  NbBundle.getMessage(this.getClass(), "ReportGenerator.tagTable.header.srcFile"),
393  NbBundle.getMessage(this.getClass(), "ReportGenerator.tagTable.header.userName"))));
394 
395  // Give the modules the rows for the content tags.
396  for (BlackboardArtifactTag tag : tags) {
397  String notableString = tag.getName().getKnownStatus() == TskData.FileKnown.BAD ? TagsManager.getNotableTagLabel() : "";
398  if (passesTagNamesFilter(tag.getName().getDisplayName() + notableString) == false) {
399  continue;
400  }
401 
402  List<String> row;
403  row = new ArrayList<>(Arrays.asList(tag.getArtifact().getArtifactTypeName(), tag.getName().getDisplayName() + notableString,
404  tag.getComment(), tag.getContent().getName(), tag.getUserName()));
405  tableReport.addRow(row);
406 
407  // check if the tag is an image that we should later make a thumbnail for
408  checkIfTagHasImage(tag);
409  }
410 
411  // The the modules blackboard artifact tags reporting is ended.
412  progressPanel.increment();
413  tableReport.endTable();
414  tableReport.endDataType();
415  }
416 
424  private boolean passesTagNamesFilter(String tagName) {
425  return tagNamesFilter.isEmpty() || tagNamesFilter.contains(tagName);
426  }
427 
431  private void makeThumbnailTable() {
432  progressPanel.updateStatusLabel(
433  NbBundle.getMessage(this.getClass(), "ReportGenerator.progress.createdThumb.text"));
434 
435  if (tableReport instanceof ReportHTML) {
436  ReportHTML htmlModule = (ReportHTML) tableReport;
437  htmlModule.startDataType(
438  NbBundle.getMessage(this.getClass(), "ReportGenerator.thumbnailTable.name"),
439  NbBundle.getMessage(this.getClass(), "ReportGenerator.thumbnailTable.desc"));
440  List<String> emptyHeaders = new ArrayList<>();
441  for (int i = 0; i < ReportHTML.THUMBNAIL_COLUMNS; i++) {
442  emptyHeaders.add("");
443  }
444  htmlModule.startTable(emptyHeaders);
445 
446  htmlModule.addThumbnailRows(images);
447 
448  htmlModule.endTable();
449  htmlModule.endDataType();
450  }
451 
452  }
453 
460  private void checkIfTagHasImage(BlackboardArtifactTag artifactTag) {
461  AbstractFile file;
462  try {
463  file = Case.getCurrentCaseThrows().getSleuthkitCase().getAbstractFileById(artifactTag.getArtifact().getObjectID());
464  } catch (TskCoreException | NoCurrentCaseException ex) {
465  errorList.add(
466  NbBundle.getMessage(this.getClass(), "ReportGenerator.errList.errGetContentFromBBArtifact"));
467  logger.log(Level.WARNING, "Error while getting content from a blackboard artifact to report on.", ex); //NON-NLS
468  return;
469  }
470 
471  if (file != null) {
472  checkIfFileIsImage(file);
473  }
474  }
475 
483  private void checkIfTagHasImage(ContentTag contentTag) {
484  Content c = contentTag.getContent();
485  if (c instanceof AbstractFile == false) {
486  return;
487  }
488  checkIfFileIsImage((AbstractFile) c);
489  }
490 
496  private void checkIfFileIsImage(AbstractFile file) {
497 
498  if (file.isDir()
499  || file.getType() == TskData.TSK_DB_FILES_TYPE_ENUM.UNALLOC_BLOCKS
500  || file.getType() == TskData.TSK_DB_FILES_TYPE_ENUM.UNUSED_BLOCKS) {
501  return;
502  }
503 
504  if (ImageUtils.thumbnailSupported(file)) {
505  images.add(file);
506  }
507  }
508 
517  private String makeCommaSeparatedList(Collection<String> items) {
518  String list = "";
519  for (Iterator<String> iterator = items.iterator(); iterator.hasNext();) {
520  list += iterator.next() + (iterator.hasNext() ? ", " : "");
521  }
522  return list;
523  }
524 
530  @SuppressWarnings("deprecation")
531  @NbBundle.Messages({"ReportGenerator.errList.noOpenCase=No open case available."})
532  private void writeKeywordHits(TableReportModule tableModule, String comment, HashSet<String> tagNamesFilter) {
533 
534  // Query for keyword lists-only so that we can tell modules what lists
535  // will exist for their index.
536  // @@@ There is a bug in here. We should use the tags in the below code
537  // so that we only report the lists that we will later provide with real
538  // hits. If no keyord hits are tagged, then we make the page for nothing.
539  String orderByClause;
540  Case openCase;
541  try {
542  openCase = Case.getCurrentCaseThrows();
543  } catch (NoCurrentCaseException ex) {
544  errorList.add(Bundle.ReportGenerator_errList_noOpenCase());
545  logger.log(Level.SEVERE, "Exception while getting open case: ", ex); //NON-NLS
546  return;
547  }
548 
549  // Get a list of all selected tag IDs
550  String tagIDList = "";
551  if (!tagNamesFilter.isEmpty()) {
552  try {
553  Map<String, TagName> tagNamesMap = Case.getCurrentCaseThrows().getServices().getTagsManager().getDisplayNamesToTagNamesMap();
554  for (String tagDisplayName : tagNamesFilter) {
555  if (tagNamesMap.containsKey(tagDisplayName)) {
556  if (!tagIDList.isEmpty()) {
557  tagIDList += ",";
558  }
559  tagIDList += tagNamesMap.get(tagDisplayName).getId();
560  } else {
561  // If the tag name ends with "(Notable)", try stripping that off
562  if (tagDisplayName.endsWith(getNotableTagLabel())) {
563  String editedDisplayName = tagDisplayName.substring(0, tagDisplayName.length() - getNotableTagLabel().length());
564  if (tagNamesMap.containsKey(editedDisplayName)) {
565  if (!tagIDList.isEmpty()) {
566  tagIDList += ",";
567  }
568  tagIDList += tagNamesMap.get(editedDisplayName).getId();
569  }
570  }
571  }
572  }
573  } catch (NoCurrentCaseException | TskCoreException ex) {
574  logger.log(Level.SEVERE, "Exception while getting tag info - proceeding without tag filter: ", ex); //NON-NLS
575  tagIDList = "";
576  }
577  }
578 
579  // Check if there are any ad-hoc results
580  String adHocCountQuery = "SELECT COUNT(*) FROM "
581  + //NON-NLS
582  "(SELECT art.artifact_id FROM blackboard_artifacts AS art, blackboard_attributes AS att1 ";//NON-NLS
583  if (!tagIDList.isEmpty()) {
584  adHocCountQuery += ", blackboard_artifact_tags as tag "; //NON-NLS
585  }
586  adHocCountQuery += "WHERE (att1.artifact_id = art.artifact_id) AND (art.artifact_type_id = " + BlackboardArtifact.ARTIFACT_TYPE.TSK_KEYWORD_HIT.getTypeID() + ") "; // NON-NLS
587  if (!tagIDList.isEmpty()) {
588  adHocCountQuery += " AND (art.artifact_id = tag.artifact_id) AND (tag.tag_name_id IN (" + tagIDList + ")) "; //NON-NLS
589  }
590  adHocCountQuery += "EXCEPT "
591  + // NON-NLS
592  "SELECT art.artifact_id FROM blackboard_artifacts AS art, blackboard_attributes AS att1 WHERE (att1.artifact_id = art.artifact_id) AND (art.artifact_type_id = " + BlackboardArtifact.ARTIFACT_TYPE.TSK_KEYWORD_HIT.getTypeID() + ") AND (att1.attribute_type_id = " + BlackboardAttribute.ATTRIBUTE_TYPE.TSK_SET_NAME.getTypeID() + ")) AS adHocHits"; //NON-NLS
593 
594  int adHocCount = 0;
595  try (SleuthkitCase.CaseDbQuery dbQuery = openCase.getSleuthkitCase().executeQuery(adHocCountQuery)) {
596  ResultSet adHocCountResultSet = dbQuery.getResultSet();
597  if (adHocCountResultSet.next()) {
598  adHocCount = adHocCountResultSet.getInt(1); //NON-NLS
599  } else {
600  throw new TskCoreException("Error counting ad hoc keywords");
601  }
602  } catch (TskCoreException | SQLException ex) {
603  errorList.add(NbBundle.getMessage(this.getClass(), "ReportGenerator.errList.failedQueryKWLists"));
604  logger.log(Level.SEVERE, "Failed to count ad hoc searches with query " + adHocCountQuery, ex); //NON-NLS
605  return;
606  }
607 
608  // Create the query to get the keyword list names
609  if (openCase.getCaseType() == Case.CaseType.MULTI_USER_CASE) {
610  orderByClause = "ORDER BY convert_to(list, 'SQL_ASCII') ASC NULLS FIRST"; //NON-NLS
611  } else {
612  orderByClause = "ORDER BY list ASC"; //NON-NLS
613  }
614  String keywordListQuery
615  = "SELECT att.value_text AS list "
616  + //NON-NLS
617  "FROM blackboard_attributes AS att, blackboard_artifacts AS art "; // NON-NLS
618  if (!tagIDList.isEmpty()) {
619  keywordListQuery += ", blackboard_artifact_tags as tag "; //NON-NLS
620  }
621  keywordListQuery += "WHERE att.attribute_type_id = " + BlackboardAttribute.ATTRIBUTE_TYPE.TSK_SET_NAME.getTypeID() + " "
622  + //NON-NLS
623  "AND art.artifact_type_id = " + BlackboardArtifact.ARTIFACT_TYPE.TSK_KEYWORD_HIT.getTypeID() + " "
624  + //NON-NLS
625  "AND att.artifact_id = art.artifact_id ";
626  if (!tagIDList.isEmpty()) {
627  keywordListQuery += "AND (art.artifact_id = tag.artifact_id) "
628  + //NON-NLS
629  "AND (tag.tag_name_id IN (" + tagIDList + ")) "; //NON-NLS
630  }
631  if (adHocCount > 0) {
632  keywordListQuery += " UNION SELECT \'\' AS list ";
633  }
634  keywordListQuery = "SELECT * FROM ( " + keywordListQuery + " ) kwListNames ";
635  keywordListQuery += "GROUP BY list " + orderByClause; //NON-NLS
636 
637  // Make the table of contents links for each list type
638  try (SleuthkitCase.CaseDbQuery dbQuery = openCase.getSleuthkitCase().executeQuery(keywordListQuery)) {
639  ResultSet listsRs = dbQuery.getResultSet();
640  List<String> lists = new ArrayList<>();
641  while (listsRs.next()) {
642  String list = listsRs.getString("list"); //NON-NLS
643  if (list.isEmpty()) {
644  list = NbBundle.getMessage(this.getClass(), "ReportGenerator.writeKwHits.userSrchs");
645  }
646  lists.add(list);
647  }
648 
649  // Make keyword data type and give them set index
650  tableModule.startDataType(BlackboardArtifact.ARTIFACT_TYPE.TSK_KEYWORD_HIT.getDisplayName(), comment);
651  tableModule.addSetIndex(lists);
652  progressPanel.updateStatusLabel(
653  NbBundle.getMessage(this.getClass(), "ReportGenerator.progress.processing",
654  BlackboardArtifact.ARTIFACT_TYPE.TSK_KEYWORD_HIT.getDisplayName()));
655  } catch (TskCoreException | SQLException ex) {
656  errorList.add(NbBundle.getMessage(this.getClass(), "ReportGenerator.errList.failedQueryKWLists"));
657  logger.log(Level.SEVERE, "Failed to query keyword lists with query " + keywordListQuery, ex); //NON-NLS
658  return;
659  }
660 
661  // Query for keywords, grouped by list
662  if (openCase.getCaseType() == Case.CaseType.MULTI_USER_CASE) {
663  orderByClause = "ORDER BY convert_to(list, 'SQL_ASCII') ASC NULLS FIRST, " //NON-NLS
664  + "convert_to(keyword, 'SQL_ASCII') ASC NULLS FIRST, " //NON-NLS
665  + "convert_to(parent_path, 'SQL_ASCII') ASC NULLS FIRST, " //NON-NLS
666  + "convert_to(name, 'SQL_ASCII') ASC NULLS FIRST, " //NON-NLS
667  + "convert_to(preview, 'SQL_ASCII') ASC NULLS FIRST"; //NON-NLS
668  } else {
669  orderByClause = "ORDER BY list ASC, keyword ASC, parent_path ASC, name ASC, preview ASC"; //NON-NLS
670  }
671 
672  // Query for keywords that are part of a list
673  String keywordListsQuery
674  = "SELECT art.artifact_id AS artifact_id, art.obj_id AS obj_id, att1.value_text AS keyword, att2.value_text AS preview, att3.value_text AS list, f.name AS name, f.parent_path AS parent_path "
675  + //NON-NLS
676  "FROM blackboard_artifacts AS art, blackboard_attributes AS att1, blackboard_attributes AS att2, blackboard_attributes AS att3, tsk_files AS f "
677  + //NON-NLS
678  "WHERE (att1.artifact_id = art.artifact_id) "
679  + //NON-NLS
680  "AND (att2.artifact_id = art.artifact_id) "
681  + //NON-NLS
682  "AND (att3.artifact_id = art.artifact_id) "
683  + //NON-NLS
684  "AND (f.obj_id = art.obj_id) "
685  + //NON-NLS
686  "AND (att1.attribute_type_id = " + BlackboardAttribute.ATTRIBUTE_TYPE.TSK_KEYWORD.getTypeID() + ") "
687  + //NON-NLS
688  "AND (att2.attribute_type_id = " + BlackboardAttribute.ATTRIBUTE_TYPE.TSK_KEYWORD_PREVIEW.getTypeID() + ") "
689  + //NON-NLS
690  "AND (att3.attribute_type_id = " + BlackboardAttribute.ATTRIBUTE_TYPE.TSK_SET_NAME.getTypeID() + ") "
691  + //NON-NLS
692  "AND (art.artifact_type_id = " + BlackboardArtifact.ARTIFACT_TYPE.TSK_KEYWORD_HIT.getTypeID() + ") ";
693 
694  // Query for keywords that are not part of a list
695  String keywordAdHocQuery
696  = "SELECT art.artifact_id AS artifact_id, art.obj_id AS obj_id, att1.value_text AS keyword, att2.value_text AS preview, \'\' AS list, f.name AS name, f.parent_path AS parent_path "
697  + // NON-NLS
698  "FROM blackboard_artifacts AS art, blackboard_attributes AS att1, blackboard_attributes AS att2, tsk_files AS f "
699  + // NON-NLS
700  "WHERE "
701  + // NON-NLS
702  " (art.artifact_id IN (SELECT art.artifact_id FROM blackboard_artifacts AS art, blackboard_attributes AS att1 WHERE (att1.artifact_id = art.artifact_id) AND (art.artifact_type_id = " + BlackboardArtifact.ARTIFACT_TYPE.TSK_KEYWORD_HIT.getTypeID() + ") "
703  + // NON-NLS
704  "EXCEPT "
705  + // NON-NLS
706  "SELECT art.artifact_id FROM blackboard_artifacts AS art, blackboard_attributes AS att1 WHERE (att1.artifact_id = art.artifact_id) AND (art.artifact_type_id = " + BlackboardArtifact.ARTIFACT_TYPE.TSK_KEYWORD_HIT.getTypeID() + ") AND (att1.attribute_type_id = " + BlackboardAttribute.ATTRIBUTE_TYPE.TSK_SET_NAME.getTypeID() + "))) "
707  + //NON-NLS
708  "AND (att1.artifact_id = art.artifact_id) "
709  + //NON-NLS
710  "AND (att2.artifact_id = art.artifact_id) "
711  + //NON-NLS
712  "AND (f.obj_id = art.obj_id) "
713  + //NON-NLS
714  "AND (att1.attribute_type_id = " + BlackboardAttribute.ATTRIBUTE_TYPE.TSK_KEYWORD.getTypeID() + ") "
715  + // NON-NLS
716  "AND (att2.attribute_type_id = " + BlackboardAttribute.ATTRIBUTE_TYPE.TSK_KEYWORD_PREVIEW.getTypeID() + ") "
717  + // NON-NLS
718  "AND (art.artifact_type_id = " + BlackboardArtifact.ARTIFACT_TYPE.TSK_KEYWORD_HIT.getTypeID() + ") "; // NON-NLS
719 
720  String keywordsQuery = "SELECT * FROM ( " + keywordListsQuery + " UNION " + keywordAdHocQuery + " ) kwHits " + orderByClause;
721 
722  try (SleuthkitCase.CaseDbQuery dbQuery = openCase.getSleuthkitCase().executeQuery(keywordsQuery)) {
723  ResultSet resultSet = dbQuery.getResultSet();
724 
725  String currentKeyword = "";
726  String currentList = "";
727  while (resultSet.next()) {
728  // Check to see if all the TableReportModules have been canceled
729  if (progressPanel.getStatus() == ReportProgressPanel.ReportStatus.CANCELED) {
730  break;
731  }
732 
733  // Get any tags that associated with this artifact and apply the tag filter.
734  HashSet<String> uniqueTagNames = getUniqueTagNames(resultSet.getLong("artifact_id")); //NON-NLS
735  if (failsTagFilter(uniqueTagNames, tagNamesFilter)) {
736  continue;
737  }
738  String tagsList = makeCommaSeparatedList(uniqueTagNames);
739 
740  Long objId = resultSet.getLong("obj_id"); //NON-NLS
741  String keyword = resultSet.getString("keyword"); //NON-NLS
742  String preview = resultSet.getString("preview"); //NON-NLS
743  String list = resultSet.getString("list"); //NON-NLS
744  String uniquePath = "";
745 
746  try {
747  AbstractFile f = openCase.getSleuthkitCase().getAbstractFileById(objId);
748  if (f != null) {
749  uniquePath = openCase.getSleuthkitCase().getAbstractFileById(objId).getUniquePath();
750  }
751  } catch (TskCoreException ex) {
752  errorList.add(
753  NbBundle.getMessage(this.getClass(), "ReportGenerator.errList.failedGetAbstractFileByID"));
754  logger.log(Level.WARNING, "Failed to get Abstract File by ID.", ex); //NON-NLS
755  }
756 
757  // If the lists aren't the same, we've started a new list
758  if ((!list.equals(currentList) && !list.isEmpty()) || (list.isEmpty() && !currentList.equals(
759  NbBundle.getMessage(this.getClass(), "ReportGenerator.writeKwHits.userSrchs")))) {
760  if (!currentList.isEmpty()) {
761  tableModule.endTable();
762  tableModule.endSet();
763  }
764  currentList = list.isEmpty() ? NbBundle
765  .getMessage(this.getClass(), "ReportGenerator.writeKwHits.userSrchs") : list;
766  currentKeyword = ""; // reset the current keyword because it's a new list
767  tableModule.startSet(currentList);
768  progressPanel.updateStatusLabel(
769  NbBundle.getMessage(this.getClass(), "ReportGenerator.progress.processingList",
770  BlackboardArtifact.ARTIFACT_TYPE.TSK_KEYWORD_HIT.getDisplayName(), currentList));
771  }
772  if (!keyword.equals(currentKeyword)) {
773  // End the previous table if one exists.
774  if (!currentKeyword.equals("")) {
775  tableModule.endTable();
776  }
777 
778  // Prepare for a new table.
779  currentKeyword = keyword;
780  tableModule.addSetElement(currentKeyword);
781  List<String> columnHeaderNames = new ArrayList<>();
782  columnHeaderNames.add(NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.preview"));
783  columnHeaderNames.add(NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.srcFile"));
784  columnHeaderNames.add(NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.tags"));
785  tableModule.startTable(columnHeaderNames);
786  }
787 
788  tableModule.addRow(Arrays.asList(new String[]{preview, uniquePath, tagsList}));
789  }
790 
791  // End the previous table if one exists.
792  if (!currentKeyword.isEmpty()) {
793  tableModule.endTable();
794  }
795 
796  // Finish the current data type
797  progressPanel.increment();
798  tableModule.endDataType();
799  } catch (TskCoreException | SQLException ex) {
800  errorList.add(NbBundle.getMessage(this.getClass(), "ReportGenerator.errList.failedQueryKWs"));
801  logger.log(Level.SEVERE, "Failed to query keywords with query " + keywordsQuery, ex); //NON-NLS
802  }
803  }
804 
810  @SuppressWarnings("deprecation")
811  private void writeHashsetHits(TableReportModule tableModule, String comment, HashSet<String> tagNamesFilter) {
812  String orderByClause;
813  Case openCase;
814  try {
815  openCase = Case.getCurrentCaseThrows();
816  } catch (NoCurrentCaseException ex) {
817  errorList.add(Bundle.ReportGenerator_errList_noOpenCase());
818  logger.log(Level.SEVERE, "Exception while getting open case: ", ex); //NON-NLS
819  return;
820  }
821  if (openCase.getCaseType() == Case.CaseType.MULTI_USER_CASE) {
822  orderByClause = "ORDER BY convert_to(att.value_text, 'SQL_ASCII') ASC NULLS FIRST"; //NON-NLS
823  } else {
824  orderByClause = "ORDER BY att.value_text ASC"; //NON-NLS
825  }
826  String hashsetsQuery
827  = "SELECT att.value_text AS list "
828  + //NON-NLS
829  "FROM blackboard_attributes AS att, blackboard_artifacts AS art "
830  + //NON-NLS
831  "WHERE att.attribute_type_id = " + BlackboardAttribute.ATTRIBUTE_TYPE.TSK_SET_NAME.getTypeID() + " "
832  + //NON-NLS
833  "AND art.artifact_type_id = " + BlackboardArtifact.ARTIFACT_TYPE.TSK_HASHSET_HIT.getTypeID() + " "
834  + //NON-NLS
835  "AND att.artifact_id = art.artifact_id "
836  + //NON-NLS
837  "GROUP BY list " + orderByClause; //NON-NLS
838 
839  try (SleuthkitCase.CaseDbQuery dbQuery = openCase.getSleuthkitCase().executeQuery(hashsetsQuery)) {
840  // Query for hashsets
841  ResultSet listsRs = dbQuery.getResultSet();
842  List<String> lists = new ArrayList<>();
843  while (listsRs.next()) {
844  lists.add(listsRs.getString("list")); //NON-NLS
845  }
846 
847  tableModule.startDataType(BlackboardArtifact.ARTIFACT_TYPE.TSK_HASHSET_HIT.getDisplayName(), comment);
848  tableModule.addSetIndex(lists);
849  progressPanel.updateStatusLabel(
850  NbBundle.getMessage(this.getClass(), "ReportGenerator.progress.processing",
851  BlackboardArtifact.ARTIFACT_TYPE.TSK_HASHSET_HIT.getDisplayName()));
852  } catch (TskCoreException | SQLException ex) {
853  errorList.add(NbBundle.getMessage(this.getClass(), "ReportGenerator.errList.failedQueryHashsetLists"));
854  logger.log(Level.SEVERE, "Failed to query hashset lists: ", ex); //NON-NLS
855  return;
856  }
857 
858  if (openCase.getCaseType() == Case.CaseType.MULTI_USER_CASE) {
859  orderByClause = "ORDER BY convert_to(att.value_text, 'SQL_ASCII') ASC NULLS FIRST, " //NON-NLS
860  + "convert_to(f.parent_path, 'SQL_ASCII') ASC NULLS FIRST, " //NON-NLS
861  + "convert_to(f.name, 'SQL_ASCII') ASC NULLS FIRST, " //NON-NLS
862  + "size ASC NULLS FIRST"; //NON-NLS
863  } else {
864  orderByClause = "ORDER BY att.value_text ASC, f.parent_path ASC, f.name ASC, size ASC"; //NON-NLS
865  }
866  String hashsetHitsQuery
867  = "SELECT art.artifact_id, art.obj_id, att.value_text AS setname, f.name AS name, f.size AS size, f.parent_path AS parent_path "
868  + //NON-NLS
869  "FROM blackboard_artifacts AS art, blackboard_attributes AS att, tsk_files AS f "
870  + //NON-NLS
871  "WHERE (att.artifact_id = art.artifact_id) "
872  + //NON-NLS
873  "AND (f.obj_id = art.obj_id) "
874  + //NON-NLS
875  "AND (att.attribute_type_id = " + BlackboardAttribute.ATTRIBUTE_TYPE.TSK_SET_NAME.getTypeID() + ") "
876  + //NON-NLS
877  "AND (art.artifact_type_id = " + BlackboardArtifact.ARTIFACT_TYPE.TSK_HASHSET_HIT.getTypeID() + ") "
878  + //NON-NLS
879  orderByClause; //NON-NLS
880 
881  try (SleuthkitCase.CaseDbQuery dbQuery = openCase.getSleuthkitCase().executeQuery(hashsetHitsQuery)) {
882  // Query for hashset hits
883  ResultSet resultSet = dbQuery.getResultSet();
884  String currentSet = "";
885  while (resultSet.next()) {
886  // Check to see if all the TableReportModules have been canceled
887  if (progressPanel.getStatus() == ReportProgressPanel.ReportStatus.CANCELED) {
888  break;
889  }
890 
891  // Get any tags that associated with this artifact and apply the tag filter.
892  HashSet<String> uniqueTagNames = getUniqueTagNames(resultSet.getLong("artifact_id")); //NON-NLS
893  if (failsTagFilter(uniqueTagNames, tagNamesFilter)) {
894  continue;
895  }
896  String tagsList = makeCommaSeparatedList(uniqueTagNames);
897 
898  Long objId = resultSet.getLong("obj_id"); //NON-NLS
899  String set = resultSet.getString("setname"); //NON-NLS
900  String size = resultSet.getString("size"); //NON-NLS
901  String uniquePath = "";
902 
903  try {
904  AbstractFile f = openCase.getSleuthkitCase().getAbstractFileById(objId);
905  if (f != null) {
906  uniquePath = openCase.getSleuthkitCase().getAbstractFileById(objId).getUniquePath();
907  }
908  } catch (TskCoreException ex) {
909  errorList.add(
910  NbBundle.getMessage(this.getClass(), "ReportGenerator.errList.failedGetAbstractFileFromID"));
911  logger.log(Level.WARNING, "Failed to get Abstract File from ID.", ex); //NON-NLS
912  return;
913  }
914 
915  // If the sets aren't the same, we've started a new set
916  if (!set.equals(currentSet)) {
917  if (!currentSet.isEmpty()) {
918  tableModule.endTable();
919  tableModule.endSet();
920  }
921  currentSet = set;
922  tableModule.startSet(currentSet);
923  List<String> columnHeaderNames = new ArrayList<>();
924  columnHeaderNames.add(NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.file"));
925  columnHeaderNames.add(NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.size"));
926  columnHeaderNames.add(NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.tags"));
927  tableModule.startTable(columnHeaderNames);
928  progressPanel.updateStatusLabel(
929  NbBundle.getMessage(this.getClass(), "ReportGenerator.progress.processingList",
930  BlackboardArtifact.ARTIFACT_TYPE.TSK_HASHSET_HIT.getDisplayName(), currentSet));
931  }
932 
933  // Add a row for this hit to every module
934  tableModule.addRow(Arrays.asList(new String[]{uniquePath, size, tagsList}));
935  }
936 
937  // Finish the current data type
938  progressPanel.increment();
939  tableModule.endDataType();
940  } catch (TskCoreException | SQLException ex) {
941  errorList.add(NbBundle.getMessage(this.getClass(), "ReportGenerator.errList.failedQueryHashsetHits"));
942  logger.log(Level.SEVERE, "Failed to query hashsets hits: ", ex); //NON-NLS
943  }
944  }
945 
949  List<String> getErrorList() {
950  return errorList;
951  }
952 
957  private class ArtifactData implements Comparable<ArtifactData> {
958 
959  private BlackboardArtifact artifact;
960  private List<BlackboardAttribute> attributes;
961  private HashSet<String> tags;
962  private List<String> rowData = null;
963  private Content content;
964 
965  ArtifactData(BlackboardArtifact artifact, List<BlackboardAttribute> attrs, HashSet<String> tags) {
966  this.artifact = artifact;
967  this.attributes = attrs;
968  this.tags = tags;
969  try {
970  this.content = Case.getCurrentCaseThrows().getSleuthkitCase().getContentById(artifact.getObjectID());
971  } catch (TskCoreException | NoCurrentCaseException ex) {
972  logger.log(Level.SEVERE, "Could not get content from database", ex);
973  }
974  }
975 
976  public BlackboardArtifact getArtifact() {
977  return artifact;
978  }
979 
980  public List<BlackboardAttribute> getAttributes() {
981  return attributes;
982  }
983 
984  public HashSet<String> getTags() {
985  return tags;
986  }
987 
988  public long getArtifactID() {
989  return artifact.getArtifactID();
990  }
991 
992  public long getObjectID() {
993  return artifact.getObjectID();
994  }
995 
999  public Content getContent() {
1000  return content;
1001  }
1002 
1012  @Override
1013  public int compareTo(ArtifactData otherArtifactData) {
1014  List<String> thisRow = getRow();
1015  List<String> otherRow = otherArtifactData.getRow();
1016  for (int i = 0; i < thisRow.size(); i++) {
1017  int compare = thisRow.get(i).compareTo(otherRow.get(i));
1018  if (compare != 0) {
1019  return compare;
1020  }
1021  }
1022  return ((Long) this.getArtifactID()).compareTo(otherArtifactData.getArtifactID());
1023  }
1024 
1032  public List<String> getRow() {
1033  if (rowData == null) {
1034  try {
1035  rowData = getOrderedRowDataAsStrings();
1036  // If else is done so that row data is not set before
1037  // columns are added to the hash map.
1038  if (rowData.size() > 0) {
1039  // replace null values if attribute was not defined
1040  for (int i = 0; i < rowData.size(); i++) {
1041  if (rowData.get(i) == null) {
1042  rowData.set(i, "");
1043  }
1044  }
1045  } else {
1046  rowData = null;
1047  return new ArrayList<>();
1048  }
1049  } catch (TskCoreException ex) {
1050  errorList.add(
1051  NbBundle.getMessage(this.getClass(), "ReportGenerator.errList.coreExceptionWhileGenRptRow"));
1052  logger.log(Level.WARNING, "Core exception while generating row data for artifact report.", ex); //NON-NLS
1053  rowData = Collections.<String>emptyList();
1054  }
1055  }
1056  return rowData;
1057  }
1058 
1068  private List<String> getOrderedRowDataAsStrings() throws TskCoreException {
1069 
1070  List<String> orderedRowData = new ArrayList<>();
1071  if (BlackboardArtifact.ARTIFACT_TYPE.TSK_EXT_MISMATCH_DETECTED.getTypeID() == getArtifact().getArtifactTypeID()) {
1072  if (content != null && content instanceof AbstractFile) {
1073  AbstractFile file = (AbstractFile) content;
1074  orderedRowData.add(file.getName());
1075  orderedRowData.add(file.getNameExtension());
1076  String mimeType = file.getMIMEType();
1077  if (mimeType == null) {
1078  orderedRowData.add("");
1079  } else {
1080  orderedRowData.add(mimeType);
1081  }
1082  orderedRowData.add(file.getUniquePath());
1083  } else {
1084  // Make empty rows to make sure the formatting is correct
1085  orderedRowData.add(null);
1086  orderedRowData.add(null);
1087  orderedRowData.add(null);
1088  orderedRowData.add(null);
1089  }
1090  orderedRowData.add(makeCommaSeparatedList(getTags()));
1091 
1092  } else if (BlackboardArtifact.ARTIFACT_TYPE.TSK_INTERESTING_FILE_HIT.getTypeID() == getArtifact().getArtifactTypeID()) {
1093  String[] attributeDataArray = new String[5];
1094  // Array is used so that order of the attributes is maintained.
1095  for (BlackboardAttribute attr : attributes) {
1096  if (attr.getAttributeType().equals(new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_SET_NAME))) {
1097  attributeDataArray[0] = attr.getDisplayString();
1098  } else if (attr.getAttributeType().equals(new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_CATEGORY))) {
1099  attributeDataArray[1] = attr.getDisplayString();
1100  } else if (attr.getAttributeType().equals(new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_COMMENT))) {
1101  attributeDataArray[3] = attr.getDisplayString();
1102  } else if (attr.getAttributeType().equals(new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DESCRIPTION))) {
1103  attributeDataArray[4] = attr.getDisplayString();
1104  }
1105  }
1106 
1107  attributeDataArray[2] = content.getUniquePath();
1108  orderedRowData.addAll(Arrays.asList(attributeDataArray));
1109 
1110  HashSet<String> allTags = getTags();
1111  try {
1112  List<ContentTag> contentTags = Case.getCurrentCaseThrows().getServices().getTagsManager().getContentTagsByContent(content);
1113  for (ContentTag ct : contentTags) {
1114  String notableString = ct.getName().getKnownStatus() == TskData.FileKnown.BAD ? TagsManager.getNotableTagLabel() : "";
1115  allTags.add(ct.getName().getDisplayName() + notableString);
1116  }
1117  } catch (TskCoreException | NoCurrentCaseException ex) {
1118  errorList.add(NbBundle.getMessage(this.getClass(), "ReportGenerator.errList.failedGetContentTags"));
1119  logger.log(Level.SEVERE, "Failed to get content tags", ex); //NON-NLS
1120  }
1121  orderedRowData.add(makeCommaSeparatedList(allTags));
1122 
1123  } else if (columnHeaderMap.containsKey(this.artifact.getArtifactTypeID())) {
1124 
1125  for (Column currColumn : columnHeaderMap.get(this.artifact.getArtifactTypeID())) {
1126  String cellData = currColumn.getCellData(this);
1127  orderedRowData.add(cellData);
1128  }
1129  }
1130 
1131  return orderedRowData;
1132  }
1133 
1134  }
1135 
1145  private List<ArtifactData> getFilteredArtifacts(BlackboardArtifact.Type type, HashSet<String> tagNamesFilter) {
1146  List<ArtifactData> artifacts = new ArrayList<>();
1147  try {
1148  for (BlackboardArtifact artifact : Case.getCurrentCaseThrows().getSleuthkitCase().getBlackboardArtifacts(type.getTypeID())) {
1149  List<BlackboardArtifactTag> tags = Case.getCurrentCaseThrows().getServices().getTagsManager().getBlackboardArtifactTagsByArtifact(artifact);
1150  HashSet<String> uniqueTagNames = new HashSet<>();
1151  for (BlackboardArtifactTag tag : tags) {
1152  String notableString = tag.getName().getKnownStatus() == TskData.FileKnown.BAD ? TagsManager.getNotableTagLabel() : "";
1153  uniqueTagNames.add(tag.getName().getDisplayName() + notableString);
1154  }
1155  if (failsTagFilter(uniqueTagNames, tagNamesFilter)) {
1156  continue;
1157  }
1158  try {
1159  artifacts.add(new ArtifactData(artifact, Case.getCurrentCaseThrows().getSleuthkitCase().getBlackboardAttributes(artifact), uniqueTagNames));
1160  } catch (TskCoreException ex) {
1161  errorList.add(NbBundle.getMessage(this.getClass(), "ReportGenerator.errList.failedGetBBAttribs"));
1162  logger.log(Level.SEVERE, "Failed to get Blackboard Attributes when generating report.", ex); //NON-NLS
1163  }
1164  }
1165  } catch (TskCoreException | NoCurrentCaseException ex) {
1166  errorList.add(NbBundle.getMessage(this.getClass(), "ReportGenerator.errList.failedGetBBArtifacts"));
1167  logger.log(Level.SEVERE, "Failed to get Blackboard Artifacts when generating report.", ex); //NON-NLS
1168  }
1169  return artifacts;
1170  }
1171 
1172  private Boolean failsTagFilter(HashSet<String> tagNames, HashSet<String> tagsNamesFilter) {
1173  if (null == tagsNamesFilter || tagsNamesFilter.isEmpty()) {
1174  return false;
1175  }
1176 
1177  HashSet<String> filteredTagNames = new HashSet<>(tagNames);
1178  filteredTagNames.retainAll(tagsNamesFilter);
1179  return filteredTagNames.isEmpty();
1180  }
1181 
1192  @Messages({"ReportGenerator.artTableColHdr.comment=Comment"})
1193  private List<Column> getArtifactTableColumns(int artifactTypeId, Set<BlackboardAttribute.Type> attributeTypeSet) {
1194  ArrayList<Column> columns = new ArrayList<>();
1195 
1196  // Long switch statement to retain ordering of attribute types that are
1197  // attached to pre-defined artifact types.
1198  if (BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_BOOKMARK.getTypeID() == artifactTypeId) {
1199  columns.add(new AttributeColumn(NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.url"),
1200  new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_URL)));
1201 
1202  columns.add(new AttributeColumn(NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.title"),
1203  new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_TITLE)));
1204 
1205  columns.add(new AttributeColumn(NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.dateCreated"),
1206  new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME_CREATED)));
1207 
1208  columns.add(new AttributeColumn(NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.program"),
1209  new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PROG_NAME)));
1210 
1211  } else if (BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_COOKIE.getTypeID() == artifactTypeId) {
1212  columns.add(new AttributeColumn(NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.url"),
1213  new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_URL)));
1214 
1215  columns.add(new AttributeColumn(NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.dateTime"),
1216  new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME)));
1217 
1218  columns.add(new AttributeColumn(NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.name"),
1219  new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_NAME)));
1220 
1221  columns.add(new AttributeColumn(NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.value"),
1222  new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_VALUE)));
1223 
1224  columns.add(new AttributeColumn(NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.program"),
1225  new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PROG_NAME)));
1226 
1227  } else if (BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_HISTORY.getTypeID() == artifactTypeId) {
1228  columns.add(new AttributeColumn(NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.url"),
1229  new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_URL)));
1230 
1231  columns.add(new AttributeColumn(NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.dateAccessed"),
1232  new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME_ACCESSED)));
1233 
1234  columns.add(new AttributeColumn(NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.referrer"),
1235  new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_REFERRER)));
1236 
1237  columns.add(new AttributeColumn(NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.title"),
1238  new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_TITLE)));
1239 
1240  columns.add(new AttributeColumn(NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.program"),
1241  new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PROG_NAME)));
1242 
1243  columns.add(new AttributeColumn(NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.urlDomainDecoded"),
1244  new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_URL_DECODED)));
1245 
1246  } else if (BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_DOWNLOAD.getTypeID() == artifactTypeId) {
1247  columns.add(new AttributeColumn(NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.dest"),
1248  new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PATH)));
1249 
1250  columns.add(new AttributeColumn(NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.sourceUrl"),
1251  new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_URL)));
1252 
1253  columns.add(new AttributeColumn(NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.dateAccessed"),
1254  new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME_ACCESSED)));
1255 
1256  columns.add(new AttributeColumn(NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.program"),
1257  new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PROG_NAME)));
1258 
1259  attributeTypeSet.remove(new Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PATH_ID));
1260  } else if (BlackboardArtifact.ARTIFACT_TYPE.TSK_RECENT_OBJECT.getTypeID() == artifactTypeId) {
1261  columns.add(new AttributeColumn(NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.path"),
1262  new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PATH)));
1263 
1264  columns.add(new AttributeColumn(NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.dateTime"),
1265  new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME)));
1266 
1267  attributeTypeSet.remove(new Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PATH_ID));
1268  } else if (BlackboardArtifact.ARTIFACT_TYPE.TSK_INSTALLED_PROG.getTypeID() == artifactTypeId) {
1269  columns.add(new AttributeColumn(NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.progName"),
1270  new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PROG_NAME)));
1271 
1272  columns.add(new AttributeColumn(NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.instDateTime"),
1273  new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME)));
1274 
1275  } else if (BlackboardArtifact.ARTIFACT_TYPE.TSK_KEYWORD_HIT.getTypeID() == artifactTypeId) {
1276  columns.add(new HeaderOnlyColumn(NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.preview")));
1277 
1278  } else if (BlackboardArtifact.ARTIFACT_TYPE.TSK_HASHSET_HIT.getTypeID() == artifactTypeId) {
1279  columns.add(new SourceFileColumn(NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.file")));
1280 
1281  columns.add(new HeaderOnlyColumn(NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.size")));
1282 
1283  } else if (BlackboardArtifact.ARTIFACT_TYPE.TSK_DEVICE_ATTACHED.getTypeID() == artifactTypeId) {
1284  columns.add(new AttributeColumn(NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.devMake"),
1285  new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DEVICE_MAKE)));
1286 
1287  columns.add(new AttributeColumn(NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.devModel"),
1288  new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DEVICE_MODEL)));
1289 
1290  columns.add(new AttributeColumn(NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.deviceId"),
1291  new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DEVICE_ID)));
1292 
1293  columns.add(new AttributeColumn(NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.dateTime"),
1294  new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME)));
1295 
1296  } else if (BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_SEARCH_QUERY.getTypeID() == artifactTypeId) {
1297  columns.add(new AttributeColumn(NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.text"),
1298  new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_TEXT)));
1299 
1300  columns.add(new AttributeColumn(NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.domain"),
1301  new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DOMAIN)));
1302 
1303  columns.add(new AttributeColumn(NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.dateAccessed"),
1304  new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME_ACCESSED)));
1305 
1306  columns.add(new AttributeColumn(NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.progName"),
1307  new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PROG_NAME)));
1308 
1309  } else if (BlackboardArtifact.ARTIFACT_TYPE.TSK_METADATA_EXIF.getTypeID() == artifactTypeId) {
1310  columns.add(new AttributeColumn(NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.dateTaken"),
1311  new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME_CREATED)));
1312 
1313  columns.add(new AttributeColumn(NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.devManufacturer"),
1314  new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DEVICE_MAKE)));
1315 
1316  columns.add(new AttributeColumn(NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.devModel"),
1317  new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DEVICE_MODEL)));
1318 
1319  columns.add(new AttributeColumn(NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.latitude"),
1320  new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_GEO_LATITUDE)));
1321 
1322  columns.add(new AttributeColumn(NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.longitude"),
1323  new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_GEO_LONGITUDE)));
1324 
1325  columns.add(new AttributeColumn(NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.altitude"),
1326  new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_GEO_ALTITUDE)));
1327 
1328  } else if (BlackboardArtifact.ARTIFACT_TYPE.TSK_CONTACT.getTypeID() == artifactTypeId) {
1329  columns.add(new AttributeColumn(NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.personName"),
1330  new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_NAME)));
1331 
1332  columns.add(new AttributeColumn(NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.phoneNumber"),
1333  new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PHONE_NUMBER)));
1334 
1335  columns.add(new AttributeColumn(NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.phoneNumHome"),
1336  new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PHONE_NUMBER_HOME)));
1337 
1338  columns.add(new AttributeColumn(NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.phoneNumOffice"),
1339  new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PHONE_NUMBER_OFFICE)));
1340 
1341  columns.add(new AttributeColumn(NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.phoneNumMobile"),
1342  new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PHONE_NUMBER_MOBILE)));
1343 
1344  columns.add(new AttributeColumn(NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.email"),
1345  new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_EMAIL)));
1346 
1347  } else if (BlackboardArtifact.ARTIFACT_TYPE.TSK_MESSAGE.getTypeID() == artifactTypeId) {
1348  columns.add(new AttributeColumn(NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.msgType"),
1349  new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_MESSAGE_TYPE)));
1350 
1351  columns.add(new AttributeColumn(NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.direction"),
1352  new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DIRECTION)));
1353 
1354  columns.add(new AttributeColumn(NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.readStatus"),
1355  new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_READ_STATUS)));
1356 
1357  columns.add(new AttributeColumn(NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.dateTime"),
1358  new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME)));
1359 
1360  columns.add(new AttributeColumn(NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.fromPhoneNum"),
1361  new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PHONE_NUMBER_FROM)));
1362 
1363  columns.add(new AttributeColumn(NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.fromEmail"),
1364  new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_EMAIL_FROM)));
1365 
1366  columns.add(new AttributeColumn(NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.toPhoneNum"),
1367  new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PHONE_NUMBER_TO)));
1368 
1369  columns.add(new AttributeColumn(NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.toEmail"),
1370  new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_EMAIL_TO)));
1371 
1372  columns.add(new AttributeColumn(NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.subject"),
1373  new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_SUBJECT)));
1374 
1375  columns.add(new AttributeColumn(NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.text"),
1376  new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_TEXT)));
1377 
1378  } else if (BlackboardArtifact.ARTIFACT_TYPE.TSK_CALLLOG.getTypeID() == artifactTypeId) {
1379  columns.add(new AttributeColumn(NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.personName"),
1380  new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_NAME)));
1381 
1382  columns.add(new AttributeColumn(NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.fromPhoneNum"),
1383  new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PHONE_NUMBER_FROM)));
1384 
1385  columns.add(new AttributeColumn(NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.toPhoneNum"),
1386  new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PHONE_NUMBER_TO)));
1387 
1388  columns.add(new AttributeColumn(NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.dateTime"),
1389  new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME_START)));
1390 
1391  columns.add(new AttributeColumn(NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.direction"),
1392  new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DIRECTION)));
1393 
1394  } else if (BlackboardArtifact.ARTIFACT_TYPE.TSK_CALENDAR_ENTRY.getTypeID() == artifactTypeId) {
1395  columns.add(new AttributeColumn(NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.calendarEntryType"),
1396  new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_CALENDAR_ENTRY_TYPE)));
1397 
1398  columns.add(new AttributeColumn(NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.description"),
1399  new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DESCRIPTION)));
1400 
1401  columns.add(new AttributeColumn(NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.startDateTime"),
1402  new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME_START)));
1403 
1404  columns.add(new AttributeColumn(NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.endDateTime"),
1405  new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME_END)));
1406 
1407  columns.add(new AttributeColumn(NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.location"),
1408  new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_LOCATION)));
1409 
1410  } else if (BlackboardArtifact.ARTIFACT_TYPE.TSK_SPEED_DIAL_ENTRY.getTypeID() == artifactTypeId) {
1411  columns.add(new AttributeColumn(NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.shortCut"),
1412  new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_SHORTCUT)));
1413 
1414  columns.add(new AttributeColumn(NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.personName"),
1415  new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_NAME_PERSON)));
1416 
1417  columns.add(new AttributeColumn(NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.phoneNumber"),
1418  new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PHONE_NUMBER)));
1419 
1420  } else if (BlackboardArtifact.ARTIFACT_TYPE.TSK_BLUETOOTH_PAIRING.getTypeID() == artifactTypeId) {
1421  columns.add(new AttributeColumn(NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.deviceName"),
1422  new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DEVICE_NAME)));
1423 
1424  columns.add(new AttributeColumn(NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.deviceAddress"),
1425  new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DEVICE_ID)));
1426 
1427  columns.add(new AttributeColumn(NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.dateTime"),
1428  new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME)));
1429 
1430  } else if (BlackboardArtifact.ARTIFACT_TYPE.TSK_GPS_TRACKPOINT.getTypeID() == artifactTypeId) {
1431  columns.add(new AttributeColumn(NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.latitude"),
1432  new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_GEO_LATITUDE)));
1433 
1434  columns.add(new AttributeColumn(NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.longitude"),
1435  new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_GEO_LONGITUDE)));
1436 
1437  columns.add(new AttributeColumn(NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.dateTime"),
1438  new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME)));
1439 
1440  } else if (BlackboardArtifact.ARTIFACT_TYPE.TSK_GPS_BOOKMARK.getTypeID() == artifactTypeId) {
1441  columns.add(new AttributeColumn(NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.latitude"),
1442  new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_GEO_LATITUDE)));
1443 
1444  columns.add(new AttributeColumn(NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.longitude"),
1445  new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_GEO_LONGITUDE)));
1446 
1447  columns.add(new AttributeColumn(NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.altitude"),
1448  new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_GEO_ALTITUDE)));
1449 
1450  columns.add(new AttributeColumn(NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.name"),
1451  new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_NAME)));
1452 
1453  columns.add(new AttributeColumn(NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.locationAddress"),
1454  new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_LOCATION)));
1455 
1456  columns.add(new AttributeColumn(NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.dateTime"),
1457  new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME)));
1458 
1459  } else if (BlackboardArtifact.ARTIFACT_TYPE.TSK_GPS_LAST_KNOWN_LOCATION.getTypeID() == artifactTypeId) {
1460  columns.add(new AttributeColumn(NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.latitude"),
1461  new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_GEO_LATITUDE)));
1462 
1463  columns.add(new AttributeColumn(NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.longitude"),
1464  new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_GEO_LONGITUDE)));
1465 
1466  columns.add(new AttributeColumn(NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.altitude"),
1467  new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_GEO_ALTITUDE)));
1468 
1469  columns.add(new AttributeColumn(NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.name"),
1470  new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_NAME)));
1471 
1472  columns.add(new AttributeColumn(NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.locationAddress"),
1473  new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_LOCATION)));
1474 
1475  columns.add(new AttributeColumn(NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.dateTime"),
1476  new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME)));
1477 
1478  } else if (BlackboardArtifact.ARTIFACT_TYPE.TSK_GPS_SEARCH.getTypeID() == artifactTypeId) {
1479  columns.add(new AttributeColumn(NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.latitude"),
1480  new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_GEO_LATITUDE)));
1481 
1482  columns.add(new AttributeColumn(NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.longitude"),
1483  new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_GEO_LONGITUDE)));
1484 
1485  columns.add(new AttributeColumn(NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.altitude"),
1486  new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_GEO_ALTITUDE)));
1487 
1488  columns.add(new AttributeColumn(NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.name"),
1489  new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_NAME)));
1490 
1491  columns.add(new AttributeColumn(NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.locationAddress"),
1492  new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_LOCATION)));
1493 
1494  columns.add(new AttributeColumn(NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.dateTime"),
1495  new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME)));
1496 
1497  } else if (BlackboardArtifact.ARTIFACT_TYPE.TSK_SERVICE_ACCOUNT.getTypeID() == artifactTypeId) {
1498  columns.add(new AttributeColumn(NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.category"),
1499  new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_CATEGORY)));
1500 
1501  columns.add(new AttributeColumn(NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.userId"),
1502  new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_USER_ID)));
1503 
1504  columns.add(new AttributeColumn(NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.password"),
1505  new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PASSWORD)));
1506 
1507  columns.add(new AttributeColumn(NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.personName"),
1508  new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_NAME)));
1509 
1510  columns.add(new AttributeColumn(NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.appName"),
1511  new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PROG_NAME)));
1512 
1513  columns.add(new AttributeColumn(NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.url"),
1514  new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_URL)));
1515 
1516  columns.add(new AttributeColumn(NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.appPath"),
1517  new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PATH)));
1518 
1519  columns.add(new AttributeColumn(NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.description"),
1520  new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DESCRIPTION)));
1521 
1522  columns.add(new AttributeColumn(NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.replytoAddress"),
1523  new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_EMAIL_REPLYTO)));
1524 
1525  columns.add(new AttributeColumn(NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.mailServer"),
1526  new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_SERVER_NAME)));
1527 
1528  } else if (BlackboardArtifact.ARTIFACT_TYPE.TSK_ENCRYPTION_DETECTED.getTypeID() == artifactTypeId
1529  || BlackboardArtifact.ARTIFACT_TYPE.TSK_ENCRYPTION_SUSPECTED.getTypeID() == artifactTypeId) {
1530  columns.add(new AttributeColumn(NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.name"),
1531  new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_NAME)));
1532 
1533  } else if (BlackboardArtifact.ARTIFACT_TYPE.TSK_EXT_MISMATCH_DETECTED.getTypeID() == artifactTypeId) {
1534  columns.add(new HeaderOnlyColumn(NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.file")));
1535 
1536  columns.add(new HeaderOnlyColumn(NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.extension.text")));
1537 
1538  columns.add(new HeaderOnlyColumn(NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.mimeType.text")));
1539 
1540  columns.add(new HeaderOnlyColumn(NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.path")));
1541 
1542  } else if (BlackboardArtifact.ARTIFACT_TYPE.TSK_OS_INFO.getTypeID() == artifactTypeId) {
1543  columns.add(new AttributeColumn(NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.processorArchitecture.text"),
1544  new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PROCESSOR_ARCHITECTURE)));
1545 
1546  columns.add(new AttributeColumn(NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.osName.text"),
1547  new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PROG_NAME)));
1548 
1549  columns.add(new AttributeColumn(NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.osInstallDate.text"),
1550  new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME)));
1551 
1552  } else if (BlackboardArtifact.ARTIFACT_TYPE.TSK_EMAIL_MSG.getTypeID() == artifactTypeId) {
1553  columns.add(new AttributeColumn(NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.tskEmailTo"),
1554  new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_EMAIL_TO)));
1555 
1556  columns.add(new AttributeColumn(NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.tskEmailFrom"),
1557  new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_EMAIL_FROM)));
1558 
1559  columns.add(new AttributeColumn(NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.tskSubject"),
1560  new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_SUBJECT)));
1561 
1562  columns.add(new AttributeColumn(NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.tskDateTimeSent"),
1563  new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME_SENT)));
1564 
1565  columns.add(new AttributeColumn(NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.tskDateTimeRcvd"),
1566  new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME_RCVD)));
1567 
1568  columns.add(new AttributeColumn(NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.tskPath"),
1569  new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PATH)));
1570 
1571  columns.add(new AttributeColumn(NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.tskEmailCc"),
1572  new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_EMAIL_CC)));
1573 
1574  columns.add(new AttributeColumn(NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.tskEmailBcc"),
1575  new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_EMAIL_BCC)));
1576 
1577  columns.add(new AttributeColumn(NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.tskMsgId"),
1578  new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_MSG_ID)));
1579 
1580  } else if (BlackboardArtifact.ARTIFACT_TYPE.TSK_INTERESTING_FILE_HIT.getTypeID() == artifactTypeId) {
1581  columns.add(new AttributeColumn(NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.tskSetName"),
1582  new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_SET_NAME)));
1583 
1584  columns.add(new AttributeColumn(NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.tskInterestingFilesCategory"),
1585  new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_CATEGORY)));
1586 
1587  columns.add(new AttributeColumn(NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.tskPath"),
1588  new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PATH)));
1589 
1590  columns.add(new AttributeColumn(NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.comment"),
1591  new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_COMMENT)));
1592 
1593  columns.add(new AttributeColumn(NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.description"),
1594  new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DESCRIPTION)));
1595 
1596  } else if (BlackboardArtifact.ARTIFACT_TYPE.TSK_GPS_ROUTE.getTypeID() == artifactTypeId) {
1597  columns.add(new AttributeColumn(NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.tskGpsRouteCategory"),
1598  new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_CATEGORY)));
1599 
1600  columns.add(new AttributeColumn(NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.dateTime"),
1601  new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME)));
1602 
1603  columns.add(new AttributeColumn(NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.latitudeEnd"),
1604  new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_GEO_LATITUDE_END)));
1605 
1606  columns.add(new AttributeColumn(NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.longitudeEnd"),
1607  new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_GEO_LONGITUDE_END)));
1608 
1609  columns.add(new AttributeColumn(NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.latitudeStart"),
1610  new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_GEO_LATITUDE_START)));
1611 
1612  columns.add(new AttributeColumn(NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.longitudeStart"),
1613  new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_GEO_LONGITUDE_START)));
1614 
1615  columns.add(new AttributeColumn(NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.name"),
1616  new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_NAME)));
1617 
1618  columns.add(new AttributeColumn(NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.location"),
1619  new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_LOCATION)));
1620 
1621  columns.add(new AttributeColumn(NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.program"),
1622  new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PROG_NAME)));
1623 
1624  } else if (BlackboardArtifact.ARTIFACT_TYPE.TSK_INTERESTING_ARTIFACT_HIT.getTypeID() == artifactTypeId) {
1625  columns.add(new AttributeColumn(NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.tskSetName"),
1626  new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_SET_NAME)));
1627 
1628  columns.add(new AttributeColumn(NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.associatedArtifact"),
1629  new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_ASSOCIATED_ARTIFACT)));
1630 
1631  columns.add(new AttributeColumn(NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.program"),
1632  new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PROG_NAME)));
1633 
1634  } else if (BlackboardArtifact.ARTIFACT_TYPE.TSK_PROG_RUN.getTypeID() == artifactTypeId) {
1635  columns.add(new AttributeColumn(NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.program"),
1636  new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PROG_NAME)));
1637 
1638  columns.add(new AttributeColumn(NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.associatedArtifact"),
1639  new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_ASSOCIATED_ARTIFACT)));
1640 
1641  columns.add(new AttributeColumn(NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.dateTime"),
1642  new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME)));
1643 
1644  columns.add(new AttributeColumn(NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.count"),
1645  new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_COUNT)));
1646 
1647  } else if (BlackboardArtifact.ARTIFACT_TYPE.TSK_OS_ACCOUNT.getTypeID() == artifactTypeId) {
1648  columns.add(new AttributeColumn(NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.userName"),
1649  new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_USER_NAME)));
1650 
1651  columns.add(new AttributeColumn(NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.userId"),
1652  new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_USER_ID)));
1653 
1654  } else if (BlackboardArtifact.ARTIFACT_TYPE.TSK_REMOTE_DRIVE.getTypeID() == artifactTypeId) {
1655  columns.add(new AttributeColumn(NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.localPath"),
1656  new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_LOCAL_PATH)));
1657 
1658  columns.add(new AttributeColumn(NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.remotePath"),
1659  new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_REMOTE_PATH)));
1660  } else if (artifactTypeId == BlackboardArtifact.ARTIFACT_TYPE.TSK_ACCOUNT.getTypeID()) {
1661  columns.add(new StatusColumn());
1662  attributeTypeSet.remove(new Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_ACCOUNT_TYPE));
1663  attributeTypeSet.remove(new Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_ASSOCIATED_ARTIFACT));
1664  attributeTypeSet.remove(new Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_SET_NAME));
1665  attributeTypeSet.remove(new Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_KEYWORD_SEARCH_DOCUMENT_ID));
1666  } else if (artifactTypeId == BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_CACHE.getTypeID()) {
1667  attributeTypeSet.remove(new Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PATH_ID));
1668  } else {
1669  // This is the case that it is a custom type. The reason an else is
1670  // necessary is to make sure that the source file column is added
1671  for (BlackboardAttribute.Type type : attributeTypeSet) {
1672  columns.add(new AttributeColumn(type.getDisplayName(), type));
1673  }
1674  columns.add(new SourceFileColumn(NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.srcFile")));
1675  columns.add(new TaggedResultsColumn(NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.tags")));
1676 
1677  // Short circuits to guarantee that the attribute types aren't added
1678  // twice.
1679  return columns;
1680  }
1681  // If it is an attribute column, it removes the attribute type of that
1682  // column from the set, so types are not reported more than once.
1683  for (Column column : columns) {
1684  attributeTypeSet = column.removeTypeFromSet(attributeTypeSet);
1685  }
1686  // Now uses the remaining types in the set to construct columns
1687  for (BlackboardAttribute.Type type : attributeTypeSet) {
1688  columns.add(new AttributeColumn(type.getDisplayName(), type));
1689  }
1690  // Source file column is added here for ordering purposes.
1691  if (artifactTypeId == BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_BOOKMARK.getTypeID()
1692  || artifactTypeId == BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_COOKIE.getTypeID()
1693  || artifactTypeId == BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_HISTORY.getTypeID()
1694  || artifactTypeId == BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_DOWNLOAD.getTypeID()
1695  || artifactTypeId == BlackboardArtifact.ARTIFACT_TYPE.TSK_RECENT_OBJECT.getTypeID()
1696  || artifactTypeId == BlackboardArtifact.ARTIFACT_TYPE.TSK_INSTALLED_PROG.getTypeID()
1697  || artifactTypeId == BlackboardArtifact.ARTIFACT_TYPE.TSK_DEVICE_ATTACHED.getTypeID()
1698  || artifactTypeId == BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_SEARCH_QUERY.getTypeID()
1699  || artifactTypeId == BlackboardArtifact.ARTIFACT_TYPE.TSK_METADATA_EXIF.getTypeID()
1700  || artifactTypeId == BlackboardArtifact.ARTIFACT_TYPE.TSK_CONTACT.getTypeID()
1701  || artifactTypeId == BlackboardArtifact.ARTIFACT_TYPE.TSK_MESSAGE.getTypeID()
1702  || artifactTypeId == BlackboardArtifact.ARTIFACT_TYPE.TSK_CALLLOG.getTypeID()
1703  || artifactTypeId == BlackboardArtifact.ARTIFACT_TYPE.TSK_CALENDAR_ENTRY.getTypeID()
1704  || artifactTypeId == BlackboardArtifact.ARTIFACT_TYPE.TSK_SPEED_DIAL_ENTRY.getTypeID()
1705  || artifactTypeId == BlackboardArtifact.ARTIFACT_TYPE.TSK_BLUETOOTH_PAIRING.getTypeID()
1706  || artifactTypeId == BlackboardArtifact.ARTIFACT_TYPE.TSK_GPS_TRACKPOINT.getTypeID()
1707  || artifactTypeId == BlackboardArtifact.ARTIFACT_TYPE.TSK_GPS_BOOKMARK.getTypeID()
1708  || artifactTypeId == BlackboardArtifact.ARTIFACT_TYPE.TSK_GPS_LAST_KNOWN_LOCATION.getTypeID()
1709  || artifactTypeId == BlackboardArtifact.ARTIFACT_TYPE.TSK_GPS_SEARCH.getTypeID()
1710  || artifactTypeId == BlackboardArtifact.ARTIFACT_TYPE.TSK_SERVICE_ACCOUNT.getTypeID()
1711  || artifactTypeId == BlackboardArtifact.ARTIFACT_TYPE.TSK_ENCRYPTION_DETECTED.getTypeID()
1712  || artifactTypeId == BlackboardArtifact.ARTIFACT_TYPE.TSK_ENCRYPTION_SUSPECTED.getTypeID()
1713  || artifactTypeId == BlackboardArtifact.ARTIFACT_TYPE.TSK_OS_INFO.getTypeID()) {
1714  columns.add(new SourceFileColumn(NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.srcFile")));
1715  }
1716  columns.add(new TaggedResultsColumn(NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.tags")));
1717 
1718  return columns;
1719  }
1720 
1728  private String getFileUniquePath(Content content) {
1729  try {
1730  if (content != null) {
1731  return content.getUniquePath();
1732  } else {
1733  return "";
1734  }
1735  } catch (TskCoreException ex) {
1736  errorList.add(NbBundle.getMessage(this.getClass(), "ReportGenerator.errList.failedGetAbstractFileByID"));
1737  logger.log(Level.WARNING, "Failed to get Abstract File by ID.", ex); //NON-NLS
1738  }
1739  return "";
1740 
1741  }
1742 
1752  @SuppressWarnings("deprecation")
1753  private HashSet<String> getUniqueTagNames(long artifactId) throws TskCoreException {
1754  HashSet<String> uniqueTagNames = new HashSet<>();
1755 
1756  String query = "SELECT display_name, artifact_id, knownStatus FROM tag_names AS tn, blackboard_artifact_tags AS bat "
1757  + //NON-NLS
1758  "WHERE tn.tag_name_id = bat.tag_name_id AND bat.artifact_id = " + artifactId; //NON-NLS
1759 
1760  try (SleuthkitCase.CaseDbQuery dbQuery = Case.getCurrentCaseThrows().getSleuthkitCase().executeQuery(query)) {
1761  ResultSet tagNameRows = dbQuery.getResultSet();
1762  while (tagNameRows.next()) {
1763  String notableString = tagNameRows.getInt("knownStatus") == TskData.FileKnown.BAD.ordinal() ? getNotableTagLabel() : "";
1764  uniqueTagNames.add(tagNameRows.getString("display_name") + notableString); //NON-NLS
1765  }
1766  } catch (TskCoreException | SQLException | NoCurrentCaseException ex) {
1767  throw new TskCoreException("Error getting tag names for artifact: ", ex);
1768  }
1769 
1770  return uniqueTagNames;
1771 
1772  }
1773 
1774  private interface Column {
1775 
1776  String getColumnHeader();
1777 
1778  String getCellData(ArtifactData artData);
1779 
1780  Set<BlackboardAttribute.Type> removeTypeFromSet(Set<BlackboardAttribute.Type> types);
1781  }
1782 
1783  private class StatusColumn implements Column {
1784 
1785  @NbBundle.Messages("TableReportGenerator.StatusColumn.Header=Review Status")
1786  @Override
1787  public String getColumnHeader() {
1788  return Bundle.TableReportGenerator_StatusColumn_Header();
1789  }
1790 
1791  @Override
1792  public String getCellData(ArtifactData artData) {
1793  return artData.getArtifact().getReviewStatus().getDisplayName();
1794  }
1795 
1796  @Override
1797  public Set<BlackboardAttribute.Type> removeTypeFromSet(Set<BlackboardAttribute.Type> types) {
1798  // This column doesn't have a type, so nothing to remove
1799  return types;
1800  }
1801 
1802  }
1803 
1804  private class AttributeColumn implements Column {
1805 
1806  private final String columnHeader;
1807  private final BlackboardAttribute.Type attributeType;
1808 
1815  AttributeColumn(String columnHeader, BlackboardAttribute.Type attributeType) {
1816  this.columnHeader = Objects.requireNonNull(columnHeader);
1818  }
1819 
1820  @Override
1821  public String getColumnHeader() {
1822  return this.columnHeader;
1823  }
1824 
1825  @Override
1826  public String getCellData(ArtifactData artData) {
1827  List<BlackboardAttribute> attributes = artData.getAttributes();
1828  for (BlackboardAttribute attribute : attributes) {
1829  if (attribute.getAttributeType().equals(this.attributeType)) {
1830  if (attribute.getAttributeType().getValueType() != BlackboardAttribute.TSK_BLACKBOARD_ATTRIBUTE_VALUE_TYPE.DATETIME) {
1831  return attribute.getDisplayString();
1832  } else {
1833  return ContentUtils.getStringTime(attribute.getValueLong(), artData.getContent());
1834  }
1835  }
1836  }
1837  return "";
1838  }
1839 
1840  @Override
1841  public Set<BlackboardAttribute.Type> removeTypeFromSet(Set<BlackboardAttribute.Type> types) {
1842  types.remove(this.attributeType);
1843  return types;
1844  }
1845  }
1846 
1847  private class SourceFileColumn implements Column {
1848 
1849  private final String columnHeader;
1850 
1851  SourceFileColumn(String columnHeader) {
1852  this.columnHeader = columnHeader;
1853  }
1854 
1855  @Override
1856  public String getColumnHeader() {
1857  return this.columnHeader;
1858  }
1859 
1860  @Override
1861  public String getCellData(ArtifactData artData) {
1862  return getFileUniquePath(artData.getContent());
1863  }
1864 
1865  @Override
1866  public Set<BlackboardAttribute.Type> removeTypeFromSet(Set<BlackboardAttribute.Type> types) {
1867  // This column doesn't have a type, so nothing to remove
1868  return types;
1869  }
1870  }
1871 
1872  private class TaggedResultsColumn implements Column {
1873 
1874  private final String columnHeader;
1875 
1876  TaggedResultsColumn(String columnHeader) {
1877  this.columnHeader = columnHeader;
1878  }
1879 
1880  @Override
1881  public String getColumnHeader() {
1882  return this.columnHeader;
1883  }
1884 
1885  @Override
1886  public String getCellData(ArtifactData artData) {
1887  return makeCommaSeparatedList(artData.getTags());
1888  }
1889 
1890  @Override
1891  public Set<BlackboardAttribute.Type> removeTypeFromSet(Set<BlackboardAttribute.Type> types) {
1892  // This column doesn't have a type, so nothing to remove
1893  return types;
1894  }
1895  }
1896 
1897  private class HeaderOnlyColumn implements Column {
1898 
1899  private final String columnHeader;
1900 
1901  HeaderOnlyColumn(String columnHeader) {
1902  this.columnHeader = columnHeader;
1903  }
1904 
1905  @Override
1906  public String getColumnHeader() {
1907  return columnHeader;
1908  }
1909 
1910  @Override
1911  public String getCellData(ArtifactData artData) {
1912  throw new UnsupportedOperationException("Cannot get cell data of unspecified column");
1913  }
1914 
1915  @Override
1916  public Set<BlackboardAttribute.Type> removeTypeFromSet(Set<BlackboardAttribute.Type> types) {
1917  // This column doesn't have a type, so nothing to remove
1918  return types;
1919  }
1920  }
1921 }
Set< BlackboardAttribute.Type > removeTypeFromSet(Set< BlackboardAttribute.Type > types)
static String getStringTime(long epochSeconds, TimeZone tzone)
List< ContentTag > getContentTagsByContent(Content content)
Set< BlackboardAttribute.Type > removeTypeFromSet(Set< BlackboardAttribute.Type > types)
Set< BlackboardAttribute.Type > removeTypeFromSet(Set< BlackboardAttribute.Type > types)
Set< BlackboardAttribute.Type > removeTypeFromSet(Set< BlackboardAttribute.Type > types)
Set< BlackboardAttribute.Type > removeTypeFromSet(Set< BlackboardAttribute.Type > types)
List< BlackboardArtifactTag > getBlackboardArtifactTagsByArtifact(BlackboardArtifact artifact)
Set< BlackboardAttribute.Type > removeTypeFromSet(Set< BlackboardAttribute.Type > types)

Copyright © 2012-2018 Basis Technology. Generated on: Wed Sep 18 2019
This work is licensed under a Creative Commons Attribution-Share Alike 3.0 United States License.