Autopsy  3.1
Graphical digital forensics platform for The Sleuth Kit and other tools.
ReportGenerator.java
Go to the documentation of this file.
1 /*
2  * Autopsy Forensic Browser
3  *
4  * Copyright 2013 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 java.awt.Dimension;
22 import java.awt.Toolkit;
23 import java.awt.event.ActionEvent;
24 import java.awt.event.ActionListener;
25 import java.awt.event.WindowAdapter;
26 import java.awt.event.WindowEvent;
27 import java.io.File;
28 import java.io.IOException;
29 import java.sql.ResultSet;
30 import java.sql.SQLException;
31 import java.text.DateFormat;
32 import java.text.SimpleDateFormat;
33 import java.util.ArrayList;
34 import java.util.Arrays;
35 import java.util.Collection;
36 import java.util.Collections;
37 import java.util.Date;
38 import java.util.HashMap;
39 import java.util.HashSet;
40 import java.util.Iterator;
41 import java.util.List;
42 import java.util.Map;
43 import java.util.Map.Entry;
44 import java.util.concurrent.ExecutionException;
45 import java.util.logging.Level;
46 import javax.swing.JDialog;
47 import javax.swing.JFrame;
48 import javax.swing.SwingWorker;
49 import org.openide.filesystems.FileUtil;
50 import org.openide.util.NbBundle;
69 
76  class ReportGenerator {
77  private static final Logger logger = Logger.getLogger(ReportGenerator.class.getName());
78 
79  private Case currentCase = Case.getCurrentCase();
80  private SleuthkitCase skCase = currentCase.getSleuthkitCase();
81 
82  private Map<TableReportModule, ReportProgressPanel> tableProgress;
83  private Map<GeneralReportModule, ReportProgressPanel> generalProgress;
84  private Map<FileReportModule, ReportProgressPanel> fileProgress;
85 
86  private String reportPath;
87  private ReportGenerationPanel panel = new ReportGenerationPanel();
88 
89  static final String REPORTS_DIR = "Reports"; //NON-NLS
90 
91  private List<String> errorList;
97  private void displayReportErrors(){
98  if(!errorList.isEmpty()){
99  String errorString = "";
100  for(String error : errorList)
101  errorString += error + "\n";
102  MessageNotifyUtil.Notify.error(
103  NbBundle.getMessage(this.getClass(), "ReportGenerator.notifyErr.errsDuringRptGen"), errorString);
104  return;
105  }
106  }
107 
108  ReportGenerator(Map<TableReportModule, Boolean> tableModuleStates, Map<GeneralReportModule, Boolean> generalModuleStates, Map<FileReportModule, Boolean> fileListModuleStates) {
109  // Create the root reports directory path of the form: <CASE DIRECTORY>/Reports/<Case fileName> <Timestamp>/
110  DateFormat dateFormat = new SimpleDateFormat("MM-dd-yyyy-HH-mm-ss");
111  Date date = new Date();
112  String dateNoTime = dateFormat.format(date);
113  this.reportPath = currentCase.getCaseDirectory() + File.separator + REPORTS_DIR + File.separator + currentCase.getName() + " " + dateNoTime + File.separator;
114 
115  this.errorList = new ArrayList<String>();
116 
117  // Create the root reports directory.
118  try {
119  FileUtil.createFolder(new File(this.reportPath));
120  } catch (IOException ex) {
121  errorList.add(NbBundle.getMessage(this.getClass(), "ReportGenerator.errList.failedMakeRptFolder"));
122  logger.log(Level.SEVERE, "Failed to make report folder, may be unable to generate reports.", ex); //NON-NLS
123  return;
124  }
125 
126  // Initialize the progress panels
127  generalProgress = new HashMap<>();
128  tableProgress = new HashMap<>();
129  fileProgress = new HashMap<>();
130  setupProgressPanels(tableModuleStates, generalModuleStates, fileListModuleStates);
131  }
132 
140  private void setupProgressPanels(Map<TableReportModule, Boolean> tableModuleStates, Map<GeneralReportModule, Boolean> generalModuleStates, Map<FileReportModule, Boolean> fileListModuleStates) {
141  if (null != tableModuleStates) {
142  for (Entry<TableReportModule, Boolean> entry : tableModuleStates.entrySet()) {
143  if (entry.getValue()) {
144  TableReportModule module = entry.getKey();
145  String reportFilePath = module.getRelativeFilePath();
146  if (reportFilePath != null) {
147  tableProgress.put(module, panel.addReport(module.getName(), reportPath + reportFilePath));
148  }
149  else {
150  tableProgress.put(module, panel.addReport(module.getName(), null));
151  }
152  }
153  }
154  }
155 
156  if (null != generalModuleStates) {
157  for (Entry<GeneralReportModule, Boolean> entry : generalModuleStates.entrySet()) {
158  if (entry.getValue()) {
159  GeneralReportModule module = entry.getKey();
160  String reportFilePath = module.getRelativeFilePath();
161  if (reportFilePath != null) {
162  generalProgress.put(module, panel.addReport(module.getName(), reportPath + reportFilePath));
163  }
164  else {
165  generalProgress.put(module, panel.addReport(module.getName(), null));
166  }
167  }
168  }
169  }
170 
171  if (null != fileListModuleStates) {
172  for(Entry<FileReportModule, Boolean> entry : fileListModuleStates.entrySet()) {
173  if (entry.getValue()) {
174  FileReportModule module = entry.getKey();
175  String reportFilePath = module.getRelativeFilePath();
176  if (reportFilePath != null) {
177  fileProgress.put(module, panel.addReport(module.getName(), reportPath + reportFilePath));
178  }
179  else {
180  fileProgress.put(module, panel.addReport(module.getName(), null));
181  }
182  }
183  }
184  }
185  }
186 
190  public void displayProgressPanels() {
191  final JDialog dialog = new JDialog(new JFrame(), true);
192  dialog.setDefaultCloseOperation(JDialog.DO_NOTHING_ON_CLOSE);
193  dialog.setTitle(NbBundle.getMessage(this.getClass(), "ReportGenerator.displayProgress.title.text"));
194  dialog.add(this.panel);
195  dialog.pack();
196 
197  panel.addCloseAction(new ActionListener() {
198  @Override
199  public void actionPerformed(ActionEvent e) {
200  dialog.dispose();
201  }
202  });
203 
204  dialog.addWindowListener(new WindowAdapter() {
205  @Override
206  public void windowClosing(WindowEvent e) {
207  panel.close();
208  }
209  });
210 
211  Dimension screenDimension = Toolkit.getDefaultToolkit().getScreenSize();
212  int w = dialog.getSize().width;
213  int h = dialog.getSize().height;
214 
215  // set the location of the popUp Window on the center of the screen
216  dialog.setLocation((screenDimension.width - w) / 2, (screenDimension.height - h) / 2);
217  dialog.setVisible(true);
218  }
219 
223  public void generateGeneralReports() {
224  GeneralReportsWorker worker = new GeneralReportsWorker();
225  worker.execute();
226  }
227 
234  public void generateTableReports(Map<ARTIFACT_TYPE, Boolean> artifactTypeSelections, Map<String, Boolean> tagNameSelections) {
235  if (!tableProgress.isEmpty() && null != artifactTypeSelections) {
236  TableReportsWorker worker = new TableReportsWorker(artifactTypeSelections, tagNameSelections);
237  worker.execute();
238  }
239  }
240 
247  public void generateFileListReports(Map<FileReportDataTypes, Boolean> enabledInfo) {
248  if (!fileProgress.isEmpty() && null != enabledInfo) {
249  List<FileReportDataTypes> enabled = new ArrayList<>();
250  for (Entry<FileReportDataTypes, Boolean> e : enabledInfo.entrySet()) {
251  if(e.getValue()) {
252  enabled.add(e.getKey());
253  }
254  }
255  FileReportsWorker worker = new FileReportsWorker(enabled);
256  worker.execute();
257  }
258  }
259 
263  private class GeneralReportsWorker extends SwingWorker<Integer, Integer> {
264 
265  @Override
266  protected Integer doInBackground() throws Exception {
267  for (Entry<GeneralReportModule, ReportProgressPanel> entry : generalProgress.entrySet()) {
268  GeneralReportModule module = entry.getKey();
269  if (generalProgress.get(module).getStatus() != ReportStatus.CANCELED) {
270  module.generateReport(reportPath, generalProgress.get(module));
271  }
272  }
273  return 0;
274  }
275 
276  @Override
277  protected void done() {
278  try {
279  get();
280  } catch (InterruptedException | ExecutionException ex) {
282  NbBundle.getMessage(this.getClass(), "ReportGenerator.errors.reportErrorTitle"),
283  NbBundle.getMessage(this.getClass(), "ReportGenerator.errors.reportErrorText") + ex.getLocalizedMessage(),
285  logger.log(Level.SEVERE, "failed to generate reports", ex); //NON-NLS
286  }
287  // catch and ignore if we were cancelled
288  catch (java.util.concurrent.CancellationException ex ) { }
289  finally{
290  displayReportErrors();
291  errorList.clear();
292  }
293  }
294 
295  }
296 
300  private class FileReportsWorker extends SwingWorker<Integer, Integer> {
301  private List<FileReportDataTypes> enabledInfo = Arrays.asList(FileReportDataTypes.values());
302  private List<FileReportModule> fileModules = new ArrayList<>();
303 
304  FileReportsWorker(List<FileReportDataTypes> enabled) {
305  enabledInfo = enabled;
306  for (Entry<FileReportModule, ReportProgressPanel> entry : fileProgress.entrySet()) {
307  fileModules.add(entry.getKey());
308  }
309  }
310 
311  @Override
312  protected Integer doInBackground() throws Exception {
313  for (FileReportModule module : fileModules) {
314  ReportProgressPanel progress = fileProgress.get(module);
315  if (progress.getStatus() != ReportStatus.CANCELED) {
316  progress.start();
317  progress.updateStatusLabel(
318  NbBundle.getMessage(this.getClass(), "ReportGenerator.progress.queryingDb.text"));
319  }
320  }
321 
322  List<AbstractFile> files = getFiles();
323  int numFiles = files.size();
324  for (FileReportModule module : fileModules) {
325  module.startReport(reportPath);
326  module.startTable(enabledInfo);
327  fileProgress.get(module).setIndeterminate(false);
328  fileProgress.get(module).setMaximumProgress(numFiles);
329  }
330 
331  int i = 0;
332  // Add files to report.
333  for (AbstractFile file : files) {
334  // Check to see if any reports have been cancelled.
335  if (fileModules.isEmpty()) {
336  break;
337  }
338  // Remove cancelled reports, add files to report otherwise.
339  Iterator<FileReportModule> iter = fileModules.iterator();
340  while (iter.hasNext()) {
341  FileReportModule module = iter.next();
342  ReportProgressPanel progress = fileProgress.get(module);
343  if (progress.getStatus() == ReportStatus.CANCELED) {
344  iter.remove();
345  } else {
346  module.addRow(file, enabledInfo);
347  progress.increment();
348  }
349 
350  if ((i % 100) == 0) {
351  progress.updateStatusLabel(
352  NbBundle.getMessage(this.getClass(), "ReportGenerator.progress.processingFile.text",
353  file.getName()));
354  }
355  }
356  i++;
357  }
358 
359  for (FileReportModule module : fileModules) {
360  module.endTable();
361  module.endReport();
362  fileProgress.get(module).complete(ReportStatus.COMPLETE);
363  }
364 
365  return 0;
366  }
367 
372  private List<AbstractFile> getFiles() {
373  List<AbstractFile> absFiles;
374  try {
376  absFiles = skCase.findAllFilesWhere("NOT meta_type = " + TskData.TSK_FS_META_TYPE_ENUM.TSK_FS_META_TYPE_DIR.getValue()); //NON-NLS
377  return absFiles;
378  } catch (TskCoreException ex) {
380  NbBundle.getMessage(this.getClass(), "ReportGenerator.errors.reportErrorTitle"),
381  NbBundle.getMessage(this.getClass(), "ReportGenerator.errors.reportErrorText") + ex.getLocalizedMessage(),
383  logger.log(Level.SEVERE, "failed to generate reports. Unable to get all files in the image.", ex); //NON-NLS
384  return Collections.<AbstractFile>emptyList();
385  }
386  }
387 
388  @Override
389  protected void done() {
390  try {
391  get();
392  } catch (InterruptedException | ExecutionException ex) {
394  NbBundle.getMessage(this.getClass(), "ReportGenerator.errors.reportErrorTitle"),
395  NbBundle.getMessage(this.getClass(), "ReportGenerator.errors.reportErrorText") + ex.getLocalizedMessage(),
397  logger.log(Level.SEVERE, "failed to generate reports", ex); //NON-NLS
398  }
399  // catch and ignore if we were cancelled
400  catch (java.util.concurrent.CancellationException ex ) { }
401  finally{
402  displayReportErrors();
403  errorList.clear();
404  }
405  }
406  }
407 
412  private class TableReportsWorker extends SwingWorker<Integer, Integer> {
413  private List<TableReportModule> tableModules = new ArrayList<>();
414  private List<ARTIFACT_TYPE> artifactTypes = new ArrayList<>();
415  private HashSet<String> tagNamesFilter = new HashSet<>();
416 
417  private List<Content> images = new ArrayList<>();
418 
419  TableReportsWorker(Map<ARTIFACT_TYPE, Boolean> artifactTypeSelections, Map<String, Boolean> tagNameSelections) {
420  // Get the report modules selected by the user.
421  for (Entry<TableReportModule, ReportProgressPanel> entry : tableProgress.entrySet()) {
422  tableModules.add(entry.getKey());
423  }
424 
425  // Get the artifact types selected by the user.
426  for (Entry<ARTIFACT_TYPE, Boolean> entry : artifactTypeSelections.entrySet()) {
427  if (entry.getValue()) {
428  artifactTypes.add(entry.getKey());
429  }
430  }
431 
432  // Get the tag names selected by the user and make a tag names filter.
433  if (null != tagNameSelections) {
434  for (Entry<String, Boolean> entry : tagNameSelections.entrySet()) {
435  if (entry.getValue() == true) {
436  tagNamesFilter.add(entry.getKey());
437  }
438  }
439  }
440  }
441 
442  @Override
443  protected Integer doInBackground() throws Exception {
444  // Start the progress indicators for each active TableReportModule.
445  for (TableReportModule module : tableModules) {
446  ReportProgressPanel progress = tableProgress.get(module);
447  if (progress.getStatus() != ReportStatus.CANCELED) {
448  module.startReport(reportPath);
449  progress.start();
450  progress.setIndeterminate(false);
451  progress.setMaximumProgress(ARTIFACT_TYPE.values().length + 2); // +2 for content and blackboard artifact tags
452  }
453  }
454 
455  // report on the blackboard results
457 
458  // report on the tagged files and artifacts
461 
462  // report on the tagged images
464 
465  // finish progress, wrap up
466  for (TableReportModule module : tableModules) {
467  tableProgress.get(module).complete(ReportStatus.COMPLETE);
468  module.endReport();
469  }
470 
471  return 0;
472  }
473 
478  // Make a comment string describing the tag names filter in effect.
479  StringBuilder comment = new StringBuilder();
480  if (!tagNamesFilter.isEmpty()) {
481  comment.append(NbBundle.getMessage(this.getClass(), "ReportGenerator.artifactTable.taggedResults.text"));
482  comment.append(makeCommaSeparatedList(tagNamesFilter));
483  }
484 
485  // Add a table to the report for every enabled blackboard artifact type.
486  for (ARTIFACT_TYPE type : artifactTypes) {
487  // Check for cancellaton.
488  removeCancelledTableReportModules();
489  if (tableModules.isEmpty()) {
490  return;
491  }
492 
493  for (TableReportModule module : tableModules) {
494  tableProgress.get(module).updateStatusLabel(
495  NbBundle.getMessage(this.getClass(), "ReportGenerator.progress.processing",
496  type.getDisplayName()));
497  }
498 
499  // Keyword hits and hashset hit artifacts get special handling.
500  if (type.equals(ARTIFACT_TYPE.TSK_KEYWORD_HIT)) {
501  writeKeywordHits(tableModules, comment.toString(), tagNamesFilter);
502  continue;
503  } else if (type.equals(ARTIFACT_TYPE.TSK_HASHSET_HIT)) {
504  writeHashsetHits(tableModules, comment.toString(), tagNamesFilter);
505  continue;
506  }
507 
508  List<ArtifactData> unsortedArtifacts = getFilteredArtifacts(type, tagNamesFilter);
509 
510  if (unsortedArtifacts.isEmpty()) {
511  continue;
512  }
513 
514  // The most efficient way to sort all the Artifacts is to add them to a List, and then
515  // sort that List based off a Comparator. Adding to a TreeMap/Set/List sorts the list
516  // each time an element is added, which adds unnecessary overhead if we only need it sorted once.
517  Collections.sort(unsortedArtifacts);
518 
519  // Get the column headers appropriate for the artifact type.
520  /* @@@ BC: Seems like a better design here would be to have a method that
521  * takes in the artifact as an argument and returns the attributes. We then use that
522  * to make the headers and to make each row afterwards so that we don't have artifact-specific
523  * logic in both getArtifactTableCoumnHeaders and ArtifactData.getRow()
524  */
525  List<String> columnHeaders = getArtifactTableColumnHeaders(type.getTypeID());
526  if (columnHeaders == null) {
527  // @@@ Hack to prevent system from hanging. Better solution is to merge all attributes into a single column or analyze the artifacts to find out how many are needed.
528  continue;
529  }
530 
531  for (TableReportModule module : tableModules) {
532  module.startDataType(type.getDisplayName(), comment.toString());
533  module.startTable(columnHeaders);
534  }
535 
536  boolean msgSent = false;
537  for(ArtifactData artifactData : unsortedArtifacts) {
538  // Add the row data to all of the reports.
539  for (TableReportModule module : tableModules) {
540 
541  // Get the row data for this type of artifact.
542  List<String> rowData = artifactData.getRow();
543  if (rowData.isEmpty()) {
544  if (msgSent == false) {
545  MessageNotifyUtil.Notify.show(NbBundle.getMessage(this.getClass(),
546  "ReportGenerator.msgShow.skippingArtRow.title",
547  type),
548  NbBundle.getMessage(this.getClass(),
549  "ReportGenerator.msgShow.skippingArtRow.msg"),
551  msgSent = true;
552  }
553  continue;
554  }
555 
556  module.addRow(rowData);
557  }
558  }
559  // Finish up this data type
560  for (TableReportModule module : tableModules) {
561  tableProgress.get(module).increment();
562  module.endTable();
563  module.endDataType();
564  }
565  }
566  }
567 
571  @SuppressWarnings("deprecation")
572  private void makeContentTagsTables() {
573  // Check for cancellaton.
574  removeCancelledTableReportModules();
575  if (tableModules.isEmpty()) {
576  return;
577  }
578 
579  // Get the content tags.
580  List<ContentTag> tags;
581  try {
583  }
584  catch (TskCoreException ex) {
585  errorList.add(NbBundle.getMessage(this.getClass(), "ReportGenerator.errList.failedGetContentTags"));
586  logger.log(Level.SEVERE, "failed to get content tags", ex); //NON-NLS
587  return;
588  }
589 
590  // Tell the modules reporting on content tags is beginning.
591  for (TableReportModule module : tableModules) {
592  // @@@ This casting is a tricky little workaround to allow the HTML report module to slip in a content hyperlink.
593  // @@@ Alos Using the obsolete ARTIFACT_TYPE.TSK_TAG_FILE is also an expedient hack.
594  tableProgress.get(module).updateStatusLabel(
595  NbBundle.getMessage(this.getClass(), "ReportGenerator.progress.processing",
596  ARTIFACT_TYPE.TSK_TAG_FILE.getDisplayName()));
597  ArrayList<String> columnHeaders = new ArrayList<>(Arrays.asList(
598  NbBundle.getMessage(this.getClass(), "ReportGenerator.htmlOutput.header.tag"),
599  NbBundle.getMessage(this.getClass(), "ReportGenerator.htmlOutput.header.file"),
600  NbBundle.getMessage(this.getClass(), "ReportGenerator.htmlOutput.header.comment"),
601  NbBundle.getMessage(this.getClass(), "ReportGenerator.htmlOutput.header.timeModified"),
602  NbBundle.getMessage(this.getClass(), "ReportGenerator.htmlOutput.header.timeChanged"),
603  NbBundle.getMessage(this.getClass(), "ReportGenerator.htmlOutput.header.timeAccessed"),
604  NbBundle.getMessage(this.getClass(), "ReportGenerator.htmlOutput.header.timeCreated"),
605  NbBundle.getMessage(this.getClass(), "ReportGenerator.htmlOutput.header.size"),
606  NbBundle.getMessage(this.getClass(), "ReportGenerator.htmlOutput.header.hash")));
607 
608  StringBuilder comment = new StringBuilder();
609  if (!tagNamesFilter.isEmpty()) {
610  comment.append(
611  NbBundle.getMessage(this.getClass(), "ReportGenerator.makeContTagTab.taggedFiles.msg"));
612  comment.append(makeCommaSeparatedList(tagNamesFilter));
613  }
614  if (module instanceof ReportHTML) {
615  ReportHTML htmlReportModule = (ReportHTML)module;
616  htmlReportModule.startDataType(ARTIFACT_TYPE.TSK_TAG_FILE.getDisplayName(), comment.toString());
617  htmlReportModule.startContentTagsTable(columnHeaders);
618  }
619  else {
620  module.startDataType(ARTIFACT_TYPE.TSK_TAG_FILE.getDisplayName(), comment.toString());
621  module.startTable(columnHeaders);
622  }
623  }
624 
625  // Give the modules the rows for the content tags.
626  for (ContentTag tag : tags) {
627  // skip tags that we are not reporting on
628  if (passesTagNamesFilter(tag.getName().getDisplayName()) == false) {
629  continue;
630  }
631 
632  String fileName;
633  try {
634  fileName = tag.getContent().getUniquePath();
635  } catch (TskCoreException ex) {
636  fileName = tag.getContent().getName();
637  }
638 
639  ArrayList<String> rowData = new ArrayList<>(Arrays.asList(tag.getName().getDisplayName(), fileName, tag.getComment()));
640  for (TableReportModule module : tableModules) {
641  // @@@ This casting is a tricky little workaround to allow the HTML report module to slip in a content hyperlink.
642  if (module instanceof ReportHTML) {
643  ReportHTML htmlReportModule = (ReportHTML)module;
644  htmlReportModule.addRowWithTaggedContentHyperlink(rowData, tag);
645  }
646  else {
647  module.addRow(rowData);
648  }
649  }
650 
651  // see if it is for an image so that we later report on it
652  checkIfTagHasImage(tag);
653  }
654 
655  // The the modules content tags reporting is ended.
656  for (TableReportModule module : tableModules) {
657  tableProgress.get(module).increment();
658  module.endTable();
659  module.endDataType();
660  }
661  }
662 
663  @Override
664  protected void done() {
665  try {
666  get();
667  } catch (InterruptedException | ExecutionException ex) {
669  NbBundle.getMessage(this.getClass(), "ReportGenerator.errors.reportErrorTitle"),
670  NbBundle.getMessage(this.getClass(), "ReportGenerator.errors.reportErrorText") + ex.getLocalizedMessage(),
672  logger.log(Level.SEVERE, "failed to generate reports", ex); //NON-NLS
673  }
674  // catch and ignore if we were cancelled
675  catch (java.util.concurrent.CancellationException ex ) { }
676  finally{
677  displayReportErrors();
678  errorList.clear();
679  }
680  }
681 
685  @SuppressWarnings("deprecation")
687  // Check for cancellaton.
688  removeCancelledTableReportModules();
689  if (tableModules.isEmpty()) {
690  return;
691  }
692 
693  List<BlackboardArtifactTag> tags;
694  try {
696  }
697  catch (TskCoreException ex) {
698  errorList.add(NbBundle.getMessage(this.getClass(), "ReportGenerator.errList.failedGetBBArtifactTags"));
699  logger.log(Level.SEVERE, "failed to get blackboard artifact tags", ex); //NON-NLS
700  return;
701  }
702 
703  // Tell the modules reporting on blackboard artifact tags data type is beginning.
704  // @@@ Using the obsolete ARTIFACT_TYPE.TSK_TAG_ARTIFACT is an expedient hack.
705  for (TableReportModule module : tableModules) {
706  tableProgress.get(module).updateStatusLabel(
707  NbBundle.getMessage(this.getClass(), "ReportGenerator.progress.processing",
708  ARTIFACT_TYPE.TSK_TAG_ARTIFACT.getDisplayName()));
709  StringBuilder comment = new StringBuilder();
710  if (!tagNamesFilter.isEmpty()) {
711  comment.append(
712  NbBundle.getMessage(this.getClass(), "ReportGenerator.makeBbArtTagTab.taggedRes.msg"));
713  comment.append(makeCommaSeparatedList(tagNamesFilter));
714  }
715  module.startDataType(ARTIFACT_TYPE.TSK_TAG_ARTIFACT.getDisplayName(), comment.toString());
716  module.startTable(new ArrayList<>(Arrays.asList(
717  NbBundle.getMessage(this.getClass(), "ReportGenerator.tagTable.header.resultType"),
718  NbBundle.getMessage(this.getClass(), "ReportGenerator.tagTable.header.tag"),
719  NbBundle.getMessage(this.getClass(), "ReportGenerator.tagTable.header.comment"),
720  NbBundle.getMessage(this.getClass(), "ReportGenerator.tagTable.header.srcFile"))));
721  }
722 
723  // Give the modules the rows for the content tags.
724  for (BlackboardArtifactTag tag : tags) {
725  if (passesTagNamesFilter(tag.getName().getDisplayName()) == false) {
726  continue;
727  }
728 
729  List<String> row;
730  for (TableReportModule module : tableModules) {
731  row = new ArrayList<>(Arrays.asList(tag.getArtifact().getArtifactTypeName(), tag.getName().getDisplayName(), tag.getComment(), tag.getContent().getName()));
732  module.addRow(row);
733  }
734 
735  // check if the tag is an image that we should later make a thumbnail for
736  checkIfTagHasImage(tag);
737  }
738 
739  // The the modules blackboard artifact tags reporting is ended.
740  for (TableReportModule module : tableModules) {
741  tableProgress.get(module).increment();
742  module.endTable();
743  module.endDataType();
744  }
745  }
746 
752  private boolean passesTagNamesFilter(String tagName) {
753  return tagNamesFilter.isEmpty() || tagNamesFilter.contains(tagName);
754  }
755 
756  void removeCancelledTableReportModules() {
757  Iterator<TableReportModule> iter = tableModules.iterator();
758  while (iter.hasNext()) {
759  TableReportModule module = iter.next();
760  if (tableProgress.get(module).getStatus() == ReportStatus.CANCELED) {
761  iter.remove();
762  }
763  }
764  }
765 
770  private void makeThumbnailTable() {
771  for (TableReportModule module : tableModules) {
772  tableProgress.get(module).updateStatusLabel(
773  NbBundle.getMessage(this.getClass(), "ReportGenerator.progress.createdThumb.text"));
774 
775  if (module instanceof ReportHTML) {
776  ReportHTML htmlModule = (ReportHTML) module;
777  htmlModule.startDataType(
778  NbBundle.getMessage(this.getClass(), "ReportGenerator.thumbnailTable.name"),
779  NbBundle.getMessage(this.getClass(), "ReportGenerator.thumbnailTable.desc"));
780  List<String> emptyHeaders = new ArrayList<>();
781  for (int i = 0; i < ReportHTML.THUMBNAIL_COLUMNS; i++) {
782  emptyHeaders.add("");
783  }
784  htmlModule.startTable(emptyHeaders);
785 
786  htmlModule.addThumbnailRows(images);
787 
788  htmlModule.endTable();
789  htmlModule.endDataType();
790  }
791  }
792  }
793 
799  private void checkIfTagHasImage(BlackboardArtifactTag artifactTag) {
800  AbstractFile file;
801  try {
803  } catch (TskCoreException ex) {
804  errorList.add(
805  NbBundle.getMessage(this.getClass(), "ReportGenerator.errList.errGetContentFromBBArtifact"));
806  logger.log(Level.WARNING, "Error while getting content from a blackboard artifact to report on.", ex); //NON-NLS
807  return;
808  }
809 
810  if(file != null){
811  checkIfFileIsImage(file);
812  }
813  }
814 
821  private void checkIfTagHasImage(ContentTag contentTag) {
822  Content c = contentTag.getContent();
823  if (c instanceof AbstractFile == false) {
824  return;
825  }
827  }
828 
833  private void checkIfFileIsImage(AbstractFile file) {
834 
835  if (file.isDir() ||
838  return;
839  }
840 
841  if (ImageUtils.thumbnailSupported(file)) {
842  images.add(file);
843  }
844  }
845  }
846 
848  private Boolean failsTagFilter(HashSet<String> tagNames, HashSet<String> tagsNamesFilter)
849  {
850  if (null == tagsNamesFilter || tagsNamesFilter.isEmpty()) {
851  return false;
852  }
853 
854  HashSet<String> filteredTagNames = new HashSet<>(tagNames);
855  filteredTagNames.retainAll(tagsNamesFilter);
856  return filteredTagNames.isEmpty();
857  }
858 
866  private List<ArtifactData> getFilteredArtifacts(ARTIFACT_TYPE type, HashSet<String> tagNamesFilter) {
867  List<ArtifactData> artifacts = new ArrayList<>();
868  try {
869  for (BlackboardArtifact artifact : skCase.getBlackboardArtifacts(type)) {
870  List<BlackboardArtifactTag> tags = Case.getCurrentCase().getServices().getTagsManager().getBlackboardArtifactTagsByArtifact(artifact);
871  HashSet<String> uniqueTagNames = new HashSet<>();
872  for (BlackboardArtifactTag tag : tags) {
873  uniqueTagNames.add(tag.getName().getDisplayName());
874  }
875  if(failsTagFilter(uniqueTagNames, tagNamesFilter)) {
876  continue;
877  }
878  try {
879  artifacts.add(new ArtifactData(artifact, skCase.getBlackboardAttributes(artifact), uniqueTagNames));
880  } catch (TskCoreException ex) {
881  errorList.add(NbBundle.getMessage(this.getClass(), "ReportGenerator.errList.failedGetBBAttribs"));
882  logger.log(Level.SEVERE, "Failed to get Blackboard Attributes when generating report.", ex); //NON-NLS
883  }
884  }
885  }
886  catch (TskCoreException ex) {
887  errorList.add(NbBundle.getMessage(this.getClass(), "ReportGenerator.errList.failedGetBBArtifacts"));
888  logger.log(Level.SEVERE, "Failed to get Blackboard Artifacts when generating report.", ex); //NON-NLS
889  }
890  return artifacts;
891  }
892 
897  @SuppressWarnings("deprecation")
898  private void writeKeywordHits(List<TableReportModule> tableModules, String comment, HashSet<String> tagNamesFilter) {
899 
900  // Query for keyword lists-only so that we can tell modules what lists
901  // will exist for their index.
902  // @@@ There is a bug in here. We should use the tags in the below code
903  // so that we only report the lists that we will later provide with real
904  // hits. If no keyord hits are tagged, then we make the page for nothing.
905  String keywordListQuery =
906  "SELECT att.value_text AS list " + //NON-NLS
907  "FROM blackboard_attributes AS att, blackboard_artifacts AS art " + //NON-NLS
908  "WHERE att.attribute_type_id = " + ATTRIBUTE_TYPE.TSK_SET_NAME.getTypeID() + " " + //NON-NLS
909  "AND art.artifact_type_id = " + ARTIFACT_TYPE.TSK_KEYWORD_HIT.getTypeID() + " " + //NON-NLS
910  "AND att.artifact_id = art.artifact_id " + //NON-NLS
911  "GROUP BY list"; //NON-NLS
912 
913  try (CaseDbQuery dbQuery = skCase.executeQuery(keywordListQuery)) {
914  ResultSet listsRs = dbQuery.getResultSet();
915  List<String> lists = new ArrayList<>();
916  while(listsRs.next()) {
917  String list = listsRs.getString("list"); //NON-NLS
918  if(list.isEmpty()) {
919  list = NbBundle.getMessage(this.getClass(), "ReportGenerator.writeKwHits.userSrchs");
920  }
921  lists.add(list);
922  }
923 
924  // Make keyword data type and give them set index
925  for (TableReportModule module : tableModules) {
926  module.startDataType(ARTIFACT_TYPE.TSK_KEYWORD_HIT.getDisplayName(), comment);
927  module.addSetIndex(lists);
928  tableProgress.get(module).updateStatusLabel(
929  NbBundle.getMessage(this.getClass(), "ReportGenerator.progress.processing",
930  ARTIFACT_TYPE.TSK_KEYWORD_HIT.getDisplayName()));
931  }
932  }
933  catch (TskCoreException | SQLException ex) {
934  errorList.add(NbBundle.getMessage(this.getClass(), "ReportGenerator.errList.failedQueryKWLists"));
935  logger.log(Level.SEVERE, "Failed to query keyword lists: ", ex); //NON-NLS
936  return;
937  }
938 
939  // Query for keywords, grouped by list
940  String keywordsQuery =
941  "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 " + //NON-NLS
942  "FROM blackboard_artifacts AS art, blackboard_attributes AS att1, blackboard_attributes AS att2, blackboard_attributes AS att3, tsk_files AS f " + //NON-NLS
943  "WHERE (att1.artifact_id = art.artifact_id) " + //NON-NLS
944  "AND (att2.artifact_id = art.artifact_id) " + //NON-NLS
945  "AND (att3.artifact_id = art.artifact_id) " + //NON-NLS
946  "AND (f.obj_id = art.obj_id) " + //NON-NLS
947  "AND (att1.attribute_type_id = " + ATTRIBUTE_TYPE.TSK_KEYWORD.getTypeID() + ") " + //NON-NLS
948  "AND (att2.attribute_type_id = " + ATTRIBUTE_TYPE.TSK_KEYWORD_PREVIEW.getTypeID() + ") " + //NON-NLS
949  "AND (att3.attribute_type_id = " + ATTRIBUTE_TYPE.TSK_SET_NAME.getTypeID() + ") " + //NON-NLS
950  "AND (art.artifact_type_id = " + ARTIFACT_TYPE.TSK_KEYWORD_HIT.getTypeID() + ") " + //NON-NLS
951  "ORDER BY list, keyword, parent_path, name"; //NON-NLS
952 
953  try (CaseDbQuery dbQuery = skCase.executeQuery(keywordsQuery)) {
954  ResultSet resultSet = dbQuery.getResultSet();
955 
956  String currentKeyword = "";
957  String currentList = "";
958  while (resultSet.next()) {
959  // Check to see if all the TableReportModules have been canceled
960  if (tableModules.isEmpty()) {
961  break;
962  }
963  Iterator<TableReportModule> iter = tableModules.iterator();
964  while (iter.hasNext()) {
965  TableReportModule module = iter.next();
966  if (tableProgress.get(module).getStatus() == ReportStatus.CANCELED) {
967  iter.remove();
968  }
969  }
970 
971  // Get any tags that associated with this artifact and apply the tag filter.
972  HashSet<String> uniqueTagNames = getUniqueTagNames(resultSet.getLong("artifact_id")); //NON-NLS
973  if(failsTagFilter(uniqueTagNames, tagNamesFilter)) {
974  continue;
975  }
976  String tagsList = makeCommaSeparatedList(uniqueTagNames);
977 
978  Long objId = resultSet.getLong("obj_id"); //NON-NLS
979  String keyword = resultSet.getString("keyword"); //NON-NLS
980  String preview = resultSet.getString("preview"); //NON-NLS
981  String list = resultSet.getString("list"); //NON-NLS
982  String uniquePath = "";
983 
984  try {
985  AbstractFile f = skCase.getAbstractFileById(objId);
986  if(f != null){
987  uniquePath = skCase.getAbstractFileById(objId).getUniquePath();
988  }
989  } catch (TskCoreException ex) {
990  errorList.add(
991  NbBundle.getMessage(this.getClass(), "ReportGenerator.errList.failedGetAbstractFileByID"));
992  logger.log(Level.WARNING, "Failed to get Abstract File by ID.", ex); //NON-NLS
993  }
994 
995  // If the lists aren't the same, we've started a new list
996  if((!list.equals(currentList) && !list.isEmpty()) || (list.isEmpty() && !currentList.equals(
997  NbBundle.getMessage(this.getClass(), "ReportGenerator.writeKwHits.userSrchs")))) {
998  if(!currentList.isEmpty()) {
999  for (TableReportModule module : tableModules) {
1000  module.endTable();
1001  module.endSet();
1002  }
1003  }
1004  currentList = list.isEmpty() ? NbBundle
1005  .getMessage(this.getClass(), "ReportGenerator.writeKwHits.userSrchs") : list;
1006  currentKeyword = ""; // reset the current keyword because it's a new list
1007  for (TableReportModule module : tableModules) {
1008  module.startSet(currentList);
1009  tableProgress.get(module).updateStatusLabel(
1010  NbBundle.getMessage(this.getClass(), "ReportGenerator.progress.processingList",
1011  ARTIFACT_TYPE.TSK_KEYWORD_HIT.getDisplayName(), currentList));
1012  }
1013  }
1014  if (!keyword.equals(currentKeyword)) {
1015  if(!currentKeyword.equals("")) {
1016  for (TableReportModule module : tableModules) {
1017  module.endTable();
1018  }
1019  }
1020  currentKeyword = keyword;
1021  for (TableReportModule module : tableModules) {
1022  module.addSetElement(currentKeyword);
1023  module.startTable(getArtifactTableColumnHeaders(ARTIFACT_TYPE.TSK_KEYWORD_HIT.getTypeID()));
1024  }
1025  }
1026 
1027  String previewreplace = EscapeUtil.escapeHtml(preview);
1028  for (TableReportModule module : tableModules) {
1029  module.addRow(Arrays.asList(new String[] {previewreplace.replaceAll("<!", ""), uniquePath, tagsList}));
1030  }
1031  }
1032 
1033  // Finish the current data type
1034  for (TableReportModule module : tableModules) {
1035  tableProgress.get(module).increment();
1036  module.endDataType();
1037  }
1038  } catch (TskCoreException | SQLException ex) {
1039  errorList.add(NbBundle.getMessage(this.getClass(), "ReportGenerator.errList.failedQueryKWs"));
1040  logger.log(Level.SEVERE, "Failed to query keywords: ", ex); //NON-NLS
1041  }
1042  }
1043 
1048  @SuppressWarnings("deprecation")
1049  private void writeHashsetHits(List<TableReportModule> tableModules, String comment, HashSet<String> tagNamesFilter) {
1050  String hashsetsQuery =
1051  "SELECT att.value_text AS list " + //NON-NLS
1052  "FROM blackboard_attributes AS att, blackboard_artifacts AS art " + //NON-NLS
1053  "WHERE att.attribute_type_id = " + ATTRIBUTE_TYPE.TSK_SET_NAME.getTypeID() + " " + //NON-NLS
1054  "AND art.artifact_type_id = " + ARTIFACT_TYPE.TSK_HASHSET_HIT.getTypeID() + " " + //NON-NLS
1055  "AND att.artifact_id = art.artifact_id " + //NON-NLS
1056  "GROUP BY list"; //NON-NLS
1057 
1058  try (CaseDbQuery dbQuery = skCase.executeQuery(hashsetsQuery)) {
1059  // Query for hashsets
1060  ResultSet listsRs = dbQuery.getResultSet();
1061  List<String> lists = new ArrayList<>();
1062  while(listsRs.next()) {
1063  lists.add(listsRs.getString("list")); //NON-NLS
1064  }
1065 
1066  for (TableReportModule module : tableModules) {
1067  module.startDataType(ARTIFACT_TYPE.TSK_HASHSET_HIT.getDisplayName(), comment);
1068  module.addSetIndex(lists);
1069  tableProgress.get(module).updateStatusLabel(
1070  NbBundle.getMessage(this.getClass(), "ReportGenerator.progress.processing",
1071  ARTIFACT_TYPE.TSK_HASHSET_HIT.getDisplayName()));
1072  }
1073  } catch (TskCoreException | SQLException ex) {
1074  errorList.add(NbBundle.getMessage(this.getClass(), "ReportGenerator.errList.failedQueryHashsetLists"));
1075  logger.log(Level.SEVERE, "Failed to query hashset lists: ", ex); //NON-NLS
1076  return;
1077  }
1078 
1079  String hashsetHitsQuery =
1080  "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 " + //NON-NLS
1081  "FROM blackboard_artifacts AS art, blackboard_attributes AS att, tsk_files AS f " + //NON-NLS
1082  "WHERE (att.artifact_id = art.artifact_id) " + //NON-NLS
1083  "AND (f.obj_id = art.obj_id) " + //NON-NLS
1084  "AND (att.attribute_type_id = " + ATTRIBUTE_TYPE.TSK_SET_NAME.getTypeID() + ") " + //NON-NLS
1085  "AND (art.artifact_type_id = " + ARTIFACT_TYPE.TSK_HASHSET_HIT.getTypeID() + ") " + //NON-NLS
1086  "ORDER BY setname, parent_path, name, size"; //NON-NLS
1087 
1088  try (CaseDbQuery dbQuery = skCase.executeQuery(hashsetHitsQuery)) {
1089  // Query for hashset hits
1090  ResultSet resultSet = dbQuery.getResultSet();
1091  String currentSet = "";
1092  while (resultSet.next()) {
1093  // Check to see if all the TableReportModules have been canceled
1094  if (tableModules.isEmpty()) {
1095  break;
1096  }
1097  Iterator<TableReportModule> iter = tableModules.iterator();
1098  while (iter.hasNext()) {
1099  TableReportModule module = iter.next();
1100  if (tableProgress.get(module).getStatus() == ReportStatus.CANCELED) {
1101  iter.remove();
1102  }
1103  }
1104 
1105  // Get any tags that associated with this artifact and apply the tag filter.
1106  HashSet<String> uniqueTagNames = getUniqueTagNames(resultSet.getLong("artifact_id")); //NON-NLS
1107  if(failsTagFilter(uniqueTagNames, tagNamesFilter)) {
1108  continue;
1109  }
1110  String tagsList = makeCommaSeparatedList(uniqueTagNames);
1111 
1112  Long objId = resultSet.getLong("obj_id"); //NON-NLS
1113  String set = resultSet.getString("setname"); //NON-NLS
1114  String size = resultSet.getString("size"); //NON-NLS
1115  String uniquePath = "";
1116 
1117  try {
1118  AbstractFile f = skCase.getAbstractFileById(objId);
1119  if(f != null){
1120  uniquePath = skCase.getAbstractFileById(objId).getUniquePath();
1121  }
1122  } catch (TskCoreException ex) {
1123  errorList.add(
1124  NbBundle.getMessage(this.getClass(), "ReportGenerator.errList.failedGetAbstractFileFromID"));
1125  logger.log(Level.WARNING, "Failed to get Abstract File from ID.", ex); //NON-NLS
1126  return;
1127  }
1128 
1129  // If the sets aren't the same, we've started a new set
1130  if(!set.equals(currentSet)) {
1131  if(!currentSet.isEmpty()) {
1132  for (TableReportModule module : tableModules) {
1133  module.endTable();
1134  module.endSet();
1135  }
1136  }
1137  currentSet = set;
1138  for (TableReportModule module : tableModules) {
1139  module.startSet(currentSet);
1140  module.startTable(getArtifactTableColumnHeaders(ARTIFACT_TYPE.TSK_HASHSET_HIT.getTypeID()));
1141  tableProgress.get(module).updateStatusLabel(
1142  NbBundle.getMessage(this.getClass(), "ReportGenerator.progress.processingList",
1143  ARTIFACT_TYPE.TSK_HASHSET_HIT.getDisplayName(), currentSet));
1144  }
1145  }
1146 
1147  // Add a row for this hit to every module
1148  for (TableReportModule module : tableModules) {
1149  module.addRow(Arrays.asList(new String[] {uniquePath, size, tagsList}));
1150  }
1151  }
1152 
1153  // Finish the current data type
1154  for (TableReportModule module : tableModules) {
1155  tableProgress.get(module).increment();
1156  module.endDataType();
1157  }
1158  } catch (TskCoreException | SQLException ex) {
1159  errorList.add(NbBundle.getMessage(this.getClass(), "ReportGenerator.errList.failedQueryHashsetHits"));
1160  logger.log(Level.SEVERE, "Failed to query hashsets hits: ", ex); //NON-NLS
1161  }
1162  }
1163 
1170  private List<String> getArtifactTableColumnHeaders(int artifactTypeId) {
1171  ArrayList<String> columnHeaders;
1172 
1173  BlackboardArtifact.ARTIFACT_TYPE type = BlackboardArtifact.ARTIFACT_TYPE.fromID(artifactTypeId);
1174  switch (type) {
1175  case TSK_WEB_BOOKMARK:
1176  columnHeaders = new ArrayList<>(Arrays.asList(new String[] {
1177  NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.url"),
1178  NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.title"),
1179  NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.dateCreated"),
1180  NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.program"),
1181  NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.srcFile")}));
1182  break;
1183  case TSK_WEB_COOKIE:
1184  columnHeaders = new ArrayList<>(Arrays.asList(new String[] {
1185  NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.url"),
1186  NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.dateTime"),
1187  NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.name"),
1188  NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.value"),
1189  NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.program"),
1190  NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.srcFile")}));
1191  break;
1192  case TSK_WEB_HISTORY:
1193  columnHeaders = new ArrayList<>(Arrays.asList(new String[] {
1194  NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.url"),
1195  NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.dateAccessed"),
1196  NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.referrer"),
1197  NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.title"),
1198  NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.program"),
1199  NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.urlDomainDecoded"),
1200  NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.srcFile")}));
1201  break;
1202  case TSK_WEB_DOWNLOAD:
1203  columnHeaders = new ArrayList<>(Arrays.asList(new String[] {
1204  NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.dest"),
1205  NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.sourceUrl"),
1206  NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.dateAccessed"),
1207  NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.program"),
1208  NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.srcFile")}));
1209  break;
1210  case TSK_RECENT_OBJECT:
1211  columnHeaders = new ArrayList<>(Arrays.asList(new String[] {
1212  NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.path"),
1213  NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.dateTime"),
1214  NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.srcFile")}));
1215  break;
1216  case TSK_INSTALLED_PROG:
1217  columnHeaders = new ArrayList<>(Arrays.asList(new String[] {
1218  NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.progName"),
1219  NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.instDateTime"),
1220  NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.srcFile")}));
1221  break;
1222  case TSK_KEYWORD_HIT:
1223  columnHeaders = new ArrayList<>(Arrays.asList(new String[] {
1224  NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.preview"),
1225  NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.srcFile")}));
1226  break;
1227  case TSK_HASHSET_HIT:
1228  columnHeaders = new ArrayList<>(Arrays.asList(new String[] {
1229  NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.file"),
1230  NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.size")}));
1231  break;
1232  case TSK_DEVICE_ATTACHED:
1233  columnHeaders = new ArrayList<>(Arrays.asList(new String[] {
1234  NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.devMake"),
1235  NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.devModel"),
1236  NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.deviceId"),
1237  NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.dateTime"),
1238  NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.srcFile")}));
1239  break;
1240  case TSK_WEB_SEARCH_QUERY:
1241  columnHeaders = new ArrayList<>(Arrays.asList(new String[] {
1242  NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.text"),
1243  NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.domain"),
1244  NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.dateAccessed"),
1245  NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.progName"),
1246  NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.srcFile")}));
1247  break;
1248  case TSK_METADATA_EXIF:
1249  columnHeaders = new ArrayList<>(Arrays.asList(new String[] {
1250  NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.dateTaken"),
1251  NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.devManufacturer"),
1252  NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.devModel"),
1253  NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.latitude"),
1254  NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.longitude"),
1255  NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.altitude"),
1256  NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.srcFile")}));
1257  break;
1258  case TSK_CONTACT:
1259  columnHeaders = new ArrayList<>(Arrays.asList(new String[] {
1260  NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.personName"),
1261  NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.phoneNumber"),
1262  NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.phoneNumHome"),
1263  NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.phoneNumOffice"),
1264  NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.phoneNumMobile"),
1265  NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.email"),
1266  NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.srcFile") }));
1267  break;
1268  case TSK_MESSAGE:
1269  columnHeaders = new ArrayList<>(Arrays.asList(new String[] {
1270  NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.msgType"),
1271  NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.direction"),
1272  NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.readStatus"),
1273  NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.dateTime"),
1274  NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.fromPhoneNum"),
1275  NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.fromEmail"),
1276  NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.toPhoneNum"),
1277  NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.toEmail"),
1278  NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.subject"),
1279  NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.text"),
1280  NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.srcFile") }));
1281  break;
1282  case TSK_CALLLOG:
1283  columnHeaders = new ArrayList<>(Arrays.asList(new String[] {
1284  NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.personName"),
1285  NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.fromPhoneNum"),
1286  NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.toPhoneNum"),
1287  NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.dateTime"),
1288  NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.direction"),
1289  NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.srcFile") }));
1290  break;
1291  case TSK_CALENDAR_ENTRY:
1292  columnHeaders = new ArrayList<>(Arrays.asList(new String[] {
1293  NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.calendarEntryType"),
1294  NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.description"),
1295  NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.startDateTime"),
1296  NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.endDateTime"),
1297  NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.location"),
1298  NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.srcFile") }));
1299  break;
1300  case TSK_SPEED_DIAL_ENTRY:
1301  columnHeaders = new ArrayList<>(Arrays.asList(new String[] {
1302  NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.shortCut"),
1303  NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.personName"),
1304  NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.phoneNumber"),
1305  NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.srcFile") }));
1306  break;
1307  case TSK_BLUETOOTH_PAIRING:
1308  columnHeaders = new ArrayList<>(Arrays.asList(new String[] {
1309  NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.deviceName"),
1310  NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.deviceAddress"),
1311  NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.dateTime"),
1312  NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.srcFile") }));
1313  break;
1314  case TSK_GPS_TRACKPOINT:
1315  columnHeaders = new ArrayList<>(Arrays.asList(new String[] {
1316  NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.latitude"),
1317  NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.longitude"),
1318  NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.dateTime"),
1319  NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.srcFile")}));
1320  break;
1321  case TSK_GPS_BOOKMARK:
1322  columnHeaders = new ArrayList<>(Arrays.asList(new String[] {
1323  NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.latitude"),
1324  NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.longitude"),
1325  NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.altitude"),
1326  NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.name"),
1327  NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.locationAddress"),
1328  NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.dateTime"),
1329  NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.srcFile") }));
1330  break;
1331  case TSK_GPS_LAST_KNOWN_LOCATION:
1332  columnHeaders = new ArrayList<>(Arrays.asList(new String[] {
1333  NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.latitude"),
1334  NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.longitude"),
1335  NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.altitude"),
1336  NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.name"),
1337  NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.locationAddress"),
1338  NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.dateTime"),
1339  NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.srcFile") }));
1340  break;
1341  case TSK_GPS_SEARCH:
1342  columnHeaders = new ArrayList<>(Arrays.asList(new String[] {
1343  NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.latitude"),
1344  NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.longitude"),
1345  NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.altitude"),
1346  NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.name"),
1347  NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.locationAddress"),
1348  NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.dateTime"),
1349  NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.srcFile") }));
1350  break;
1351  case TSK_SERVICE_ACCOUNT:
1352  columnHeaders = new ArrayList<>(Arrays.asList(new String[] {
1353  NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.category"),
1354  NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.userId"),
1355  NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.password"),
1356  NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.personName"),
1357  NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.appName"),
1358  NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.url"),
1359  NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.appPath"),
1360  NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.description"),
1361  NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.replytoAddress"),
1362  NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.mailServer"),
1363  NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.srcFile") }));
1364  break;
1365  case TSK_ENCRYPTION_DETECTED:
1366  columnHeaders = new ArrayList<>(Arrays.asList(new String[] {
1367  NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.name"),
1368  NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.srcFile")}));
1369  break;
1370  case TSK_EXT_MISMATCH_DETECTED:
1371  columnHeaders = new ArrayList<>(Arrays.asList(new String[] {
1372  NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.file"),
1373  NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.extension.text"),
1374  NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.mimeType.text"),
1375  NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.path")}));
1376  break;
1377  case TSK_OS_INFO:
1378  columnHeaders = new ArrayList<>(Arrays.asList(new String[] {
1379  NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.processorArchitecture.text"),
1380  NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.osName.text"),
1381  NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.osInstallDate.text"),
1382  NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.srcFile")}));
1383  break;
1384  case TSK_EMAIL_MSG:
1385  columnHeaders = new ArrayList<>(Arrays.asList(new String[] {
1386  NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.tskEmailTo"), //TSK_EMAIL_TO
1387  NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.tskEmailFrom"), //TSK_EMAIL_FROM
1388  NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.tskSubject"), //TSK_SUBJECT
1389  NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.tskDateTimeSent"), //TSK_DATETIME_SENT
1390  NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.tskDateTimeRcvd"), //TSK_DATETIME_RCVD
1391  NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.tskPath"), //TSK_PATH
1392  NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.tskEmailCc"), //TSK_EMAIL_CC
1393  NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.tskEmailBcc"), //TSK_EMAIL_BCC
1394  NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.tskMsgId")})); //TSK_MSG_ID
1395  break;
1396  case TSK_INTERESTING_FILE_HIT:
1397  columnHeaders = new ArrayList<>(Arrays.asList(new String[]{
1398  NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.tskSetName"), //TSK_SET_NAME
1399  NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.tskInterestingFilesCategory"), //TSK_CATEGORY
1400  NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.tskPath")})); //TSK_PATH
1401  break;
1402  case TSK_GPS_ROUTE:
1403  columnHeaders = new ArrayList<>(Arrays.asList(new String[]{
1404  NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.tskGpsRouteCategory"), //TSK_CATEGORY
1405  NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.dateTime"), //TSK_DATETIME
1406  NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.latitudeEnd"), //TSK_GEO_LATITUDE_END
1407  NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.longitudeEnd"), //TSK_GEO_LONGITUDE_END
1408  NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.latitudeStart"), //TSK_GEO_LATITUDE_START
1409  NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.longitudeStart"), //TSK_GEO_LONGITUDE_START
1410  NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.name"), //TSK_NAME
1411  NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.location"), //TSK_LOCATION
1412  NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.program")}));//TSK_PROG_NAME
1413  break;
1414  case TSK_INTERESTING_ARTIFACT_HIT:
1415  columnHeaders = new ArrayList<>(Arrays.asList(new String[]{
1416  NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.tskSetName"), //TSK_SET_NAME
1417  NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.associatedArtifact"), //TSK_ASSOCIATED_ARTIFACT
1418  NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.program")})); //TSK_PROG_NAME
1419  break;
1420  case TSK_PROG_RUN:
1421  columnHeaders = new ArrayList<>(Arrays.asList(new String[]{
1422  NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.program"), //TSK_PROG_NAME
1423  NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.associatedArtifact"), //TSK_ASSOCIATED_ARTIFACT
1424  NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.dateTime"), //TSK_DATETIME
1425  NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.count")})); //TSK_COUNT
1426  break;
1427 
1428  case TSK_OS_ACCOUNT:
1429  columnHeaders = new ArrayList<>(Arrays.asList(new String[]{
1430  NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.userName"), //TSK_USER_NAME
1431  NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.userId")})); //TSK_USER_ID
1432  break;
1433 
1434  case TSK_REMOTE_DRIVE:
1435  columnHeaders = new ArrayList<>(Arrays.asList(new String[]{
1436  NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.localPath"), //TSK_LOCAL_PATH
1437  NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.remotePath")})); //TSK_REMOTE_PATH
1438  break;
1439  default:
1440  return null;
1441  }
1442  columnHeaders.add(NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.tags"));
1443 
1444  return columnHeaders;
1445  }
1446 
1455  public Map<Integer, String> getMappedAttributes(List<BlackboardAttribute> attList, TableReportModule... module) {
1456  Map<Integer, String> attributes = new HashMap<>();
1457  int size = ATTRIBUTE_TYPE.values().length;
1458  for (int n = 0; n <= size; n++) {
1459  attributes.put(n, "");
1460  }
1461  for (BlackboardAttribute tempatt : attList) {
1462  String value = "";
1463  Integer type = tempatt.getAttributeTypeID();
1464  if (type.equals(ATTRIBUTE_TYPE.TSK_DATETIME.getTypeID()) ||
1465  type.equals(ATTRIBUTE_TYPE.TSK_DATETIME_ACCESSED.getTypeID()) ||
1466  type.equals(ATTRIBUTE_TYPE.TSK_DATETIME_CREATED.getTypeID()) ||
1467  type.equals(ATTRIBUTE_TYPE.TSK_DATETIME_MODIFIED.getTypeID()) ||
1468  type.equals(ATTRIBUTE_TYPE.TSK_DATETIME_SENT.getTypeID()) ||
1469  type.equals(ATTRIBUTE_TYPE.TSK_DATETIME_RCVD.getTypeID()) ||
1470  type.equals(ATTRIBUTE_TYPE.TSK_DATETIME_START.getTypeID()) ||
1471  type.equals(ATTRIBUTE_TYPE.TSK_DATETIME_END.getTypeID())
1472  ) {
1473  if (module.length > 0) {
1474  value = module[0].dateToString(tempatt.getValueLong());
1475  } else {
1476  SimpleDateFormat sdf = new java.text.SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
1477  value = sdf.format(new java.util.Date((tempatt.getValueLong() * 1000)));
1478  }
1479  }
1480  else {
1481  value = tempatt.getDisplayString();
1482  }
1483 
1484  if (value == null) {
1485  value = "";
1486  }
1487  value = EscapeUtil.escapeHtml(value);
1488  attributes.put(type, value);
1489  }
1490  return attributes;
1491  }
1492 
1499  private String makeCommaSeparatedList(Collection<String> items) {
1500  String list = "";
1501  for (Iterator<String> iterator = items.iterator(); iterator.hasNext(); ) {
1502  list += iterator.next() + (iterator.hasNext() ? ", " : "");
1503  }
1504  return list;
1505  }
1506 
1513  private String getFileUniquePath(long objId) {
1514  try {
1515  AbstractFile af = skCase.getAbstractFileById(objId);
1516  if(af!=null) {
1517  return af.getUniquePath();
1518  }
1519  else {
1520  return "";
1521  }
1522  }
1523  catch (TskCoreException ex) {
1524  errorList.add(NbBundle.getMessage(this.getClass(), "ReportGenerator.errList.failedGetAbstractFileByID"));
1525  logger.log(Level.WARNING, "Failed to get Abstract File by ID.", ex); //NON-NLS
1526  }
1527  return "";
1528  }
1529 
1534  private class ArtifactData implements Comparable<ArtifactData> {
1536  private List<BlackboardAttribute> attributes;
1537  private HashSet<String> tags;
1538  private List<String> rowData = null;
1539 
1540  ArtifactData(BlackboardArtifact artifact, List<BlackboardAttribute> attrs, HashSet<String> tags) {
1541  this.artifact = artifact;
1542  this.attributes = attrs;
1543  this.tags = tags;
1544  }
1545 
1547 
1548  public List<BlackboardAttribute> getAttributes() { return attributes; }
1549 
1550  public HashSet<String> getTags() { return tags; }
1551 
1552  public long getArtifactID() { return artifact.getArtifactID(); }
1553 
1554  public long getObjectID() { return artifact.getObjectID(); }
1555 
1556 
1565  @Override
1566  public int compareTo(ArtifactData otherArtifactData) {
1567  List<String> thisRow = getRow();
1568  List<String> otherRow = otherArtifactData.getRow();
1569  for (int i = 0; i < thisRow.size(); i++) {
1570  int compare = thisRow.get(i).compareTo(otherRow.get(i));
1571  if (compare != 0) {
1572  return compare;
1573  }
1574  }
1575  // If all attributes are the same, they're most likely duplicates so sort by artifact ID
1576  return ((Long) this.getArtifactID()).compareTo((Long) otherArtifactData.getArtifactID());
1577  }
1578 
1582  public List<String> getRow() {
1583  if (rowData == null) {
1584  try {
1585  rowData = getOrderedRowDataAsStrings();
1586  // replace null values if attribute was not defined
1587  for (int i = 0; i < rowData.size(); i++) {
1588  if (rowData.get(i) == null)
1589  rowData.set(i, "");
1590  }
1591  } catch (TskCoreException ex) {
1592  errorList.add(
1593  NbBundle.getMessage(this.getClass(), "ReportGenerator.errList.coreExceptionWhileGenRptRow"));
1594  logger.log(Level.WARNING, "Core exception while generating row data for artifact report.", ex); //NON-NLS
1595  rowData = Collections.<String>emptyList();
1596  }
1597  }
1598  return rowData;
1599  }
1600 
1608  private List<String> getOrderedRowDataAsStrings() throws TskCoreException {
1609  Map<Integer, String> mappedAttributes = getMappedAttributes();
1610  List<String> orderedRowData = new ArrayList<>();
1612  switch (type) {
1613  case TSK_WEB_BOOKMARK:
1614  orderedRowData.add(mappedAttributes.get(ATTRIBUTE_TYPE.TSK_URL.getTypeID()));
1615  orderedRowData.add(mappedAttributes.get(ATTRIBUTE_TYPE.TSK_TITLE.getTypeID()));
1616  orderedRowData.add(mappedAttributes.get(ATTRIBUTE_TYPE.TSK_DATETIME_CREATED.getTypeID()));
1617  orderedRowData.add(mappedAttributes.get(ATTRIBUTE_TYPE.TSK_PROG_NAME.getTypeID()));
1618  orderedRowData.add(getFileUniquePath(getObjectID()));
1619  break;
1620  case TSK_WEB_COOKIE:
1621  orderedRowData.add(mappedAttributes.get(ATTRIBUTE_TYPE.TSK_URL.getTypeID()));
1622  orderedRowData.add(mappedAttributes.get(ATTRIBUTE_TYPE.TSK_DATETIME.getTypeID()));
1623  orderedRowData.add(mappedAttributes.get(ATTRIBUTE_TYPE.TSK_NAME.getTypeID()));
1624  orderedRowData.add(mappedAttributes.get(ATTRIBUTE_TYPE.TSK_VALUE.getTypeID()));
1625  orderedRowData.add(mappedAttributes.get(ATTRIBUTE_TYPE.TSK_PROG_NAME.getTypeID()));
1626  orderedRowData.add(getFileUniquePath(getObjectID()));
1627  break;
1628  case TSK_WEB_HISTORY:
1629  orderedRowData.add(mappedAttributes.get(ATTRIBUTE_TYPE.TSK_URL.getTypeID()));
1630  orderedRowData.add(mappedAttributes.get(ATTRIBUTE_TYPE.TSK_DATETIME_ACCESSED.getTypeID()));
1631  orderedRowData.add(mappedAttributes.get(ATTRIBUTE_TYPE.TSK_REFERRER.getTypeID()));
1632  orderedRowData.add(mappedAttributes.get(ATTRIBUTE_TYPE.TSK_TITLE.getTypeID()));
1633  orderedRowData.add(mappedAttributes.get(ATTRIBUTE_TYPE.TSK_URL_DECODED.getTypeID()));
1634  orderedRowData.add(mappedAttributes.get(ATTRIBUTE_TYPE.TSK_PROG_NAME.getTypeID()));
1635  orderedRowData.add(getFileUniquePath(getObjectID()));
1636  break;
1637  case TSK_WEB_DOWNLOAD:
1638  orderedRowData.add(mappedAttributes.get(ATTRIBUTE_TYPE.TSK_PATH.getTypeID()));
1639  orderedRowData.add(mappedAttributes.get(ATTRIBUTE_TYPE.TSK_URL.getTypeID()));
1640  orderedRowData.add(mappedAttributes.get(ATTRIBUTE_TYPE.TSK_DATETIME_ACCESSED.getTypeID()));
1641  orderedRowData.add(mappedAttributes.get(ATTRIBUTE_TYPE.TSK_PROG_NAME.getTypeID()));
1642  orderedRowData.add(getFileUniquePath(getObjectID()));
1643  break;
1644  case TSK_RECENT_OBJECT:
1645  orderedRowData.add(mappedAttributes.get(ATTRIBUTE_TYPE.TSK_PATH.getTypeID()));
1646  orderedRowData.add(mappedAttributes.get(ATTRIBUTE_TYPE.TSK_DATETIME.getTypeID()));
1647  orderedRowData.add(getFileUniquePath(getObjectID()));
1648  break;
1649  case TSK_INSTALLED_PROG:
1650  orderedRowData.add(mappedAttributes.get(ATTRIBUTE_TYPE.TSK_PROG_NAME.getTypeID()));
1651  orderedRowData.add(mappedAttributes.get(ATTRIBUTE_TYPE.TSK_DATETIME.getTypeID()));
1652  orderedRowData.add(getFileUniquePath(getObjectID()));
1653  break;
1654  case TSK_DEVICE_ATTACHED:
1655  orderedRowData.add(mappedAttributes.get(ATTRIBUTE_TYPE.TSK_DEVICE_MAKE.getTypeID()));
1656  orderedRowData.add(mappedAttributes.get(ATTRIBUTE_TYPE.TSK_DEVICE_MODEL.getTypeID()));
1657  orderedRowData.add(mappedAttributes.get(ATTRIBUTE_TYPE.TSK_DEVICE_ID.getTypeID()));
1658  orderedRowData.add(mappedAttributes.get(ATTRIBUTE_TYPE.TSK_DATETIME.getTypeID()));
1659  orderedRowData.add(getFileUniquePath(getObjectID()));
1660  break;
1661  case TSK_WEB_SEARCH_QUERY:
1662  orderedRowData.add(mappedAttributes.get(ATTRIBUTE_TYPE.TSK_TEXT.getTypeID()));
1663  orderedRowData.add(mappedAttributes.get(ATTRIBUTE_TYPE.TSK_DOMAIN.getTypeID()));
1664  orderedRowData.add(mappedAttributes.get(ATTRIBUTE_TYPE.TSK_DATETIME_ACCESSED.getTypeID()));
1665  orderedRowData.add(mappedAttributes.get(ATTRIBUTE_TYPE.TSK_PROG_NAME.getTypeID()));
1666  orderedRowData.add(getFileUniquePath(getObjectID()));
1667  break;
1668  case TSK_METADATA_EXIF:
1669  orderedRowData.add(mappedAttributes.get(ATTRIBUTE_TYPE.TSK_DATETIME_CREATED.getTypeID()));
1670  orderedRowData.add(mappedAttributes.get(ATTRIBUTE_TYPE.TSK_DEVICE_MAKE.getTypeID()));
1671  orderedRowData.add(mappedAttributes.get(ATTRIBUTE_TYPE.TSK_DEVICE_MODEL.getTypeID()));
1672  orderedRowData.add(mappedAttributes.get(ATTRIBUTE_TYPE.TSK_GEO_LATITUDE.getTypeID()));
1673  orderedRowData.add(mappedAttributes.get(ATTRIBUTE_TYPE.TSK_GEO_LONGITUDE.getTypeID()));
1674  orderedRowData.add(mappedAttributes.get(ATTRIBUTE_TYPE.TSK_GEO_ALTITUDE.getTypeID()));
1675  orderedRowData.add(getFileUniquePath(getObjectID()));
1676  break;
1677  case TSK_CONTACT:
1678  orderedRowData.add(mappedAttributes.get(ATTRIBUTE_TYPE.TSK_NAME.getTypeID()));
1679  orderedRowData.add(mappedAttributes.get(ATTRIBUTE_TYPE.TSK_PHONE_NUMBER.getTypeID()));
1680  orderedRowData.add(mappedAttributes.get(ATTRIBUTE_TYPE.TSK_PHONE_NUMBER_HOME.getTypeID()));
1681  orderedRowData.add(mappedAttributes.get(ATTRIBUTE_TYPE.TSK_PHONE_NUMBER_OFFICE.getTypeID()));
1682  orderedRowData.add(mappedAttributes.get(ATTRIBUTE_TYPE.TSK_PHONE_NUMBER_MOBILE.getTypeID()));
1683  orderedRowData.add(mappedAttributes.get(ATTRIBUTE_TYPE.TSK_EMAIL.getTypeID()));
1684  orderedRowData.add(getFileUniquePath(getObjectID()));
1685  break;
1686  case TSK_MESSAGE:
1687  orderedRowData.add(mappedAttributes.get(ATTRIBUTE_TYPE.TSK_MESSAGE_TYPE.getTypeID()));
1688  orderedRowData.add(mappedAttributes.get(ATTRIBUTE_TYPE.TSK_DIRECTION.getTypeID()));
1689  orderedRowData.add(mappedAttributes.get(ATTRIBUTE_TYPE.TSK_READ_STATUS.getTypeID()));
1690  orderedRowData.add(mappedAttributes.get(ATTRIBUTE_TYPE.TSK_DATETIME.getTypeID()));
1691  orderedRowData.add(mappedAttributes.get(ATTRIBUTE_TYPE.TSK_PHONE_NUMBER_FROM.getTypeID()));
1692  orderedRowData.add(mappedAttributes.get(ATTRIBUTE_TYPE.TSK_EMAIL_FROM.getTypeID()));
1693  orderedRowData.add(mappedAttributes.get(ATTRIBUTE_TYPE.TSK_PHONE_NUMBER_TO.getTypeID()));
1694  orderedRowData.add(mappedAttributes.get(ATTRIBUTE_TYPE.TSK_EMAIL_TO.getTypeID()));
1695  orderedRowData.add(mappedAttributes.get(ATTRIBUTE_TYPE.TSK_SUBJECT.getTypeID()));
1696  orderedRowData.add(mappedAttributes.get(ATTRIBUTE_TYPE.TSK_TEXT.getTypeID()));
1697  orderedRowData.add(getFileUniquePath(getObjectID()));
1698  break;
1699  case TSK_CALLLOG:
1700  orderedRowData.add(mappedAttributes.get(ATTRIBUTE_TYPE.TSK_NAME.getTypeID()));
1701  orderedRowData.add(mappedAttributes.get(ATTRIBUTE_TYPE.TSK_PHONE_NUMBER_FROM.getTypeID()));
1702  orderedRowData.add(mappedAttributes.get(ATTRIBUTE_TYPE.TSK_PHONE_NUMBER_TO.getTypeID()));
1703  orderedRowData.add(mappedAttributes.get(ATTRIBUTE_TYPE.TSK_DATETIME_START.getTypeID()));
1704  orderedRowData.add(mappedAttributes.get(ATTRIBUTE_TYPE.TSK_DIRECTION.getTypeID()));
1705  orderedRowData.add(getFileUniquePath(getObjectID()));
1706  break;
1707  case TSK_CALENDAR_ENTRY:
1708  orderedRowData.add(mappedAttributes.get(ATTRIBUTE_TYPE.TSK_CALENDAR_ENTRY_TYPE.getTypeID()));
1709  orderedRowData.add(mappedAttributes.get(ATTRIBUTE_TYPE.TSK_DESCRIPTION.getTypeID()));
1710  orderedRowData.add(mappedAttributes.get(ATTRIBUTE_TYPE.TSK_DATETIME_START.getTypeID()));
1711  orderedRowData.add(mappedAttributes.get(ATTRIBUTE_TYPE.TSK_DATETIME_END.getTypeID()));
1712  orderedRowData.add(mappedAttributes.get(ATTRIBUTE_TYPE.TSK_LOCATION.getTypeID()));
1713  orderedRowData.add(getFileUniquePath(getObjectID()));
1714  break;
1715  case TSK_SPEED_DIAL_ENTRY:
1716  orderedRowData.add(mappedAttributes.get(ATTRIBUTE_TYPE.TSK_SHORTCUT.getTypeID()));
1717  orderedRowData.add(mappedAttributes.get(ATTRIBUTE_TYPE.TSK_NAME_PERSON.getTypeID()));
1718  orderedRowData.add(mappedAttributes.get(ATTRIBUTE_TYPE.TSK_PHONE_NUMBER.getTypeID()));
1719  orderedRowData.add(getFileUniquePath(getObjectID()));
1720  break;
1721  case TSK_BLUETOOTH_PAIRING:
1722  orderedRowData.add(mappedAttributes.get(ATTRIBUTE_TYPE.TSK_DEVICE_NAME.getTypeID()));
1723  orderedRowData.add(mappedAttributes.get(ATTRIBUTE_TYPE.TSK_DEVICE_ID.getTypeID()));
1724  orderedRowData.add(mappedAttributes.get(ATTRIBUTE_TYPE.TSK_DATETIME.getTypeID()));
1725  orderedRowData.add(getFileUniquePath(getObjectID()));
1726  break;
1727  case TSK_GPS_TRACKPOINT:
1728  orderedRowData.add(mappedAttributes.get(ATTRIBUTE_TYPE.TSK_GEO_LATITUDE.getTypeID()));
1729  orderedRowData.add(mappedAttributes.get(ATTRIBUTE_TYPE.TSK_GEO_LONGITUDE.getTypeID()));
1730  orderedRowData.add(mappedAttributes.get(ATTRIBUTE_TYPE.TSK_DATETIME.getTypeID()));
1731  orderedRowData.add(getFileUniquePath(getObjectID()));
1732  break;
1733  case TSK_GPS_BOOKMARK:
1734  orderedRowData.add(mappedAttributes.get(ATTRIBUTE_TYPE.TSK_GEO_LATITUDE.getTypeID()));
1735  orderedRowData.add(mappedAttributes.get(ATTRIBUTE_TYPE.TSK_GEO_LONGITUDE.getTypeID()));
1736  orderedRowData.add(mappedAttributes.get(ATTRIBUTE_TYPE.TSK_GEO_ALTITUDE.getTypeID()));
1737  orderedRowData.add(mappedAttributes.get(ATTRIBUTE_TYPE.TSK_NAME.getTypeID()));
1738  orderedRowData.add(mappedAttributes.get(ATTRIBUTE_TYPE.TSK_LOCATION.getTypeID()));
1739  orderedRowData.add(mappedAttributes.get(ATTRIBUTE_TYPE.TSK_DATETIME.getTypeID()));
1740  orderedRowData.add(getFileUniquePath(getObjectID()));
1741  break;
1742  case TSK_GPS_LAST_KNOWN_LOCATION:
1743  orderedRowData.add(mappedAttributes.get(ATTRIBUTE_TYPE.TSK_GEO_LATITUDE.getTypeID()));
1744  orderedRowData.add(mappedAttributes.get(ATTRIBUTE_TYPE.TSK_GEO_LONGITUDE.getTypeID()));
1745  orderedRowData.add(mappedAttributes.get(ATTRIBUTE_TYPE.TSK_GEO_ALTITUDE.getTypeID()));
1746  orderedRowData.add(mappedAttributes.get(ATTRIBUTE_TYPE.TSK_NAME.getTypeID()));
1747  orderedRowData.add(mappedAttributes.get(ATTRIBUTE_TYPE.TSK_LOCATION.getTypeID()));
1748  orderedRowData.add(mappedAttributes.get(ATTRIBUTE_TYPE.TSK_DATETIME.getTypeID()));
1749  orderedRowData.add(getFileUniquePath(getObjectID()));
1750  break;
1751  case TSK_GPS_SEARCH:
1752  orderedRowData.add(mappedAttributes.get(ATTRIBUTE_TYPE.TSK_GEO_LATITUDE.getTypeID()));
1753  orderedRowData.add(mappedAttributes.get(ATTRIBUTE_TYPE.TSK_GEO_LONGITUDE.getTypeID()));
1754  orderedRowData.add(mappedAttributes.get(ATTRIBUTE_TYPE.TSK_GEO_ALTITUDE.getTypeID()));
1755  orderedRowData.add(mappedAttributes.get(ATTRIBUTE_TYPE.TSK_NAME.getTypeID()));
1756  orderedRowData.add(mappedAttributes.get(ATTRIBUTE_TYPE.TSK_LOCATION.getTypeID()));
1757  orderedRowData.add(mappedAttributes.get(ATTRIBUTE_TYPE.TSK_DATETIME.getTypeID()));
1758  orderedRowData.add(getFileUniquePath(getObjectID()));
1759  break;
1760  case TSK_SERVICE_ACCOUNT:
1761  orderedRowData.add(mappedAttributes.get(ATTRIBUTE_TYPE.TSK_CATEGORY.getTypeID()));
1762  orderedRowData.add(mappedAttributes.get(ATTRIBUTE_TYPE.TSK_USER_ID.getTypeID()));
1763  orderedRowData.add(mappedAttributes.get(ATTRIBUTE_TYPE.TSK_PASSWORD.getTypeID()));
1764  orderedRowData.add(mappedAttributes.get(ATTRIBUTE_TYPE.TSK_NAME.getTypeID()));
1765  orderedRowData.add(mappedAttributes.get(ATTRIBUTE_TYPE.TSK_PROG_NAME.getTypeID()));
1766  orderedRowData.add(mappedAttributes.get(ATTRIBUTE_TYPE.TSK_URL.getTypeID()));
1767  orderedRowData.add(mappedAttributes.get(ATTRIBUTE_TYPE.TSK_PATH.getTypeID()));
1768  orderedRowData.add(mappedAttributes.get(ATTRIBUTE_TYPE.TSK_DESCRIPTION.getTypeID()));
1769  orderedRowData.add(mappedAttributes.get(ATTRIBUTE_TYPE.TSK_EMAIL_REPLYTO.getTypeID()));
1770  orderedRowData.add(mappedAttributes.get(ATTRIBUTE_TYPE.TSK_SERVER_NAME.getTypeID()));
1771  orderedRowData.add(getFileUniquePath(getObjectID()));
1772  break;
1773  case TSK_TOOL_OUTPUT:
1774  orderedRowData.add(mappedAttributes.get(ATTRIBUTE_TYPE.TSK_PROG_NAME.getTypeID()));
1775  orderedRowData.add(mappedAttributes.get(ATTRIBUTE_TYPE.TSK_TEXT.getTypeID()));
1776  orderedRowData.add(getFileUniquePath(getObjectID()));
1777  break;
1778  case TSK_ENCRYPTION_DETECTED:
1779  orderedRowData.add(mappedAttributes.get(ATTRIBUTE_TYPE.TSK_NAME.getTypeID()));
1780  orderedRowData.add(getFileUniquePath(getObjectID()));
1781  break;
1782  case TSK_EXT_MISMATCH_DETECTED:
1783  AbstractFile file = skCase.getAbstractFileById(getObjectID());
1784  if(file != null){
1785  orderedRowData.add(file.getName());
1786  orderedRowData.add(file.getNameExtension());
1787  List<BlackboardAttribute> attrs = file.getGenInfoAttributes(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_FILE_TYPE_SIG);
1788  if (!attrs.isEmpty()) {
1789  orderedRowData.add(attrs.get(0).getValueString());
1790  } else {
1791  orderedRowData.add("");
1792  }
1793  orderedRowData.add(file.getUniquePath());
1794  } else {
1795  // Make empty rows to make sure the formatting is correct
1796  orderedRowData.add(null);
1797  orderedRowData.add(null);
1798  orderedRowData.add(null);
1799  orderedRowData.add(null);
1800  }
1801  break;
1802  case TSK_OS_INFO:
1803  orderedRowData.add(mappedAttributes.get(ATTRIBUTE_TYPE.TSK_PROCESSOR_ARCHITECTURE.getTypeID()));
1804  orderedRowData.add(mappedAttributes.get(ATTRIBUTE_TYPE.TSK_PROG_NAME.getTypeID()));
1805  orderedRowData.add(mappedAttributes.get(ATTRIBUTE_TYPE.TSK_DATETIME.getTypeID()));
1806  orderedRowData.add(getFileUniquePath(getObjectID()));
1807  break;
1808  case TSK_EMAIL_MSG:
1809  orderedRowData.add(mappedAttributes.get(ATTRIBUTE_TYPE.TSK_EMAIL_TO.getTypeID()));
1810  orderedRowData.add(mappedAttributes.get(ATTRIBUTE_TYPE.TSK_EMAIL_FROM.getTypeID()));
1811  orderedRowData.add(mappedAttributes.get(ATTRIBUTE_TYPE.TSK_SUBJECT.getTypeID()));
1812  orderedRowData.add(mappedAttributes.get(ATTRIBUTE_TYPE.TSK_DATETIME_SENT.getTypeID()));
1813  orderedRowData.add(mappedAttributes.get(ATTRIBUTE_TYPE.TSK_DATETIME_RCVD.getTypeID()));
1814  orderedRowData.add(mappedAttributes.get(ATTRIBUTE_TYPE.TSK_PATH.getTypeID()));
1815  orderedRowData.add(mappedAttributes.get(ATTRIBUTE_TYPE.TSK_EMAIL_CC.getTypeID()));
1816  orderedRowData.add(mappedAttributes.get(ATTRIBUTE_TYPE.TSK_EMAIL_BCC.getTypeID()));
1817  orderedRowData.add(mappedAttributes.get(ATTRIBUTE_TYPE.TSK_MSG_ID.getTypeID()));
1818  break;
1819  case TSK_INTERESTING_FILE_HIT:
1820  orderedRowData.add(mappedAttributes.get(ATTRIBUTE_TYPE.TSK_SET_NAME.getTypeID()));
1821  orderedRowData.add(mappedAttributes.get(ATTRIBUTE_TYPE.TSK_CATEGORY.getTypeID()));
1822  String pathToShow=mappedAttributes.get(ATTRIBUTE_TYPE.TSK_PATH.getTypeID());
1823  if (pathToShow.isEmpty())
1824  {
1825  pathToShow=getFileUniquePath(getObjectID());
1826  }
1827  orderedRowData.add(pathToShow);
1828  break;
1829  case TSK_GPS_ROUTE:
1830  orderedRowData.add(mappedAttributes.get(ATTRIBUTE_TYPE.TSK_CATEGORY.getTypeID()));
1831  orderedRowData.add(mappedAttributes.get(ATTRIBUTE_TYPE.TSK_DATETIME.getTypeID()));
1832  orderedRowData.add(mappedAttributes.get(ATTRIBUTE_TYPE.TSK_GEO_LATITUDE_END.getTypeID()));
1833  orderedRowData.add(mappedAttributes.get(ATTRIBUTE_TYPE.TSK_GEO_LONGITUDE_END.getTypeID()));
1834  orderedRowData.add(mappedAttributes.get(ATTRIBUTE_TYPE.TSK_GEO_LATITUDE_START.getTypeID()));
1835  orderedRowData.add(mappedAttributes.get(ATTRIBUTE_TYPE.TSK_GEO_LONGITUDE_START.getTypeID()));
1836  orderedRowData.add(mappedAttributes.get(ATTRIBUTE_TYPE.TSK_NAME.getTypeID()));
1837  orderedRowData.add(mappedAttributes.get(ATTRIBUTE_TYPE.TSK_LOCATION.getTypeID()));
1838  orderedRowData.add(mappedAttributes.get(ATTRIBUTE_TYPE.TSK_PROG_NAME.getTypeID()));
1839  break;
1840  case TSK_INTERESTING_ARTIFACT_HIT:
1841  orderedRowData.add(mappedAttributes.get(ATTRIBUTE_TYPE.TSK_SET_NAME.getTypeID()));
1842  orderedRowData.add(mappedAttributes.get(ATTRIBUTE_TYPE.TSK_ASSOCIATED_ARTIFACT.getTypeID()));
1843  orderedRowData.add(mappedAttributes.get(ATTRIBUTE_TYPE.TSK_PROG_NAME.getTypeID()));
1844  break;
1845  case TSK_PROG_RUN:
1846  orderedRowData.add(mappedAttributes.get(ATTRIBUTE_TYPE.TSK_PROG_NAME.getTypeID()));
1847  orderedRowData.add(mappedAttributes.get(ATTRIBUTE_TYPE.TSK_ASSOCIATED_ARTIFACT.getTypeID()));
1848  orderedRowData.add(mappedAttributes.get(ATTRIBUTE_TYPE.TSK_DATETIME.getTypeID()));
1849  orderedRowData.add(mappedAttributes.get(ATTRIBUTE_TYPE.TSK_COUNT.getTypeID()));
1850  break;
1851  case TSK_OS_ACCOUNT:
1852  orderedRowData.add(mappedAttributes.get(ATTRIBUTE_TYPE.TSK_USER_NAME.getTypeID()));
1853  orderedRowData.add(mappedAttributes.get(ATTRIBUTE_TYPE.TSK_USER_ID.getTypeID()));
1854  break;
1855  case TSK_REMOTE_DRIVE:
1856  orderedRowData.add(mappedAttributes.get(ATTRIBUTE_TYPE.TSK_LOCAL_PATH.getTypeID()));
1857  orderedRowData.add(mappedAttributes.get(ATTRIBUTE_TYPE.TSK_REMOTE_PATH.getTypeID()));
1858  break;
1859  }
1860  orderedRowData.add(makeCommaSeparatedList(getTags()));
1861 
1862  return orderedRowData;
1863  }
1864 
1869  private Map<Integer,String> getMappedAttributes() {
1870  return ReportGenerator.this.getMappedAttributes(attributes);
1871  }
1872  }
1873 
1880  @SuppressWarnings("deprecation")
1881  private HashSet<String> getUniqueTagNames(long artifactId) throws TskCoreException {
1882  HashSet<String> uniqueTagNames = new HashSet<>();
1883 
1884  String query = "SELECT display_name, artifact_id FROM tag_names AS tn, blackboard_artifact_tags AS bat " + //NON-NLS
1885  "WHERE tn.tag_name_id = bat.tag_name_id AND bat.artifact_id = " + artifactId; //NON-NLS
1886 
1887  try (CaseDbQuery dbQuery = skCase.executeQuery(query)) {
1888  ResultSet tagNameRows = dbQuery.getResultSet();
1889  while (tagNameRows.next()) {
1890  uniqueTagNames.add(tagNameRows.getString("display_name")); //NON-NLS
1891  }
1892  }
1893  catch (TskCoreException | SQLException ex) {
1894  throw new TskCoreException("Error getting tag names for artifact: ", ex);
1895  }
1896 
1897  return uniqueTagNames;
1898  }
1899 
1900 }
1901 
static boolean thumbnailSupported(Content content)
Definition: ImageUtils.java:75
void generateReport(String baseReportDir, ReportProgressPanel progressPanel)
TskData.TSK_DB_FILES_TYPE_ENUM getType()
AbstractFile getAbstractFileById(long id)
List< BlackboardArtifactTag > getAllBlackboardArtifactTags()
List< AbstractFile > findAllFilesWhere(String sqlWhereClause)
static void show(String title, String message, MessageType type, ActionListener actionListener)
ArrayList< BlackboardAttribute > getGenInfoAttributes(ATTRIBUTE_TYPE attr_type)

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