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

Copyright © 2012-2021 Basis Technology. Generated on: Thu Sep 30 2021
This work is licensed under a Creative Commons Attribution-Share Alike 3.0 United States License.