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