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

Copyright © 2012-2016 Basis Technology. Generated on: Tue Oct 25 2016
This work is licensed under a Creative Commons Attribution-Share Alike 3.0 United States License.