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