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

Copyright © 2012-2021 Basis Technology. Generated on: Tue Feb 22 2022
This work is licensed under a Creative Commons Attribution-Share Alike 3.0 United States License.