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

Copyright © 2012-2020 Basis Technology. Generated on: Wed Apr 8 2020
This work is licensed under a Creative Commons Attribution-Share Alike 3.0 United States License.