From 74a3b3bfd5b723337a52008340f0066b29bb2a85 Mon Sep 17 00:00:00 2001 From: Richard Cordovano Date: Tue, 30 Jul 2013 07:15:34 -0400 Subject: [PATCH 1/4] Rectified incorrect copyrigth notice update --- Core/src/org/sleuthkit/autopsy/report/ReportWizardAction.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Core/src/org/sleuthkit/autopsy/report/ReportWizardAction.java b/Core/src/org/sleuthkit/autopsy/report/ReportWizardAction.java index 780e14351d..dbe63a4b64 100644 --- a/Core/src/org/sleuthkit/autopsy/report/ReportWizardAction.java +++ b/Core/src/org/sleuthkit/autopsy/report/ReportWizardAction.java @@ -4,7 +4,7 @@ * * Copyright 2013 Basis Technology Corp. * - * Copyright 2013 42six Solutions. + * Copyright 2012 42six Solutions. * Contact: aebadirad 42six com * Project Contact/Architect: carrier sleuthkit org * From 5882f5341a15bc7704287e6a185f5fe3f304ea1f Mon Sep 17 00:00:00 2001 From: Richard Cordovano Date: Wed, 31 Jul 2013 20:36:57 -0400 Subject: [PATCH 2/4] Added column auto-sizing to spreadsheet table report module (ReportExcel class) --- .../sleuthkit/autopsy/report/ReportExcel.java | 80 ++++++++++++------- 1 file changed, 50 insertions(+), 30 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/report/ReportExcel.java b/Core/src/org/sleuthkit/autopsy/report/ReportExcel.java index 82448ebcbe..d7844aa1cc 100644 --- a/Core/src/org/sleuthkit/autopsy/report/ReportExcel.java +++ b/Core/src/org/sleuthkit/autopsy/report/ReportExcel.java @@ -1,7 +1,7 @@ /* * Autopsy Forensic Browser * - * Copyright 2012 Basis Technology Corp. + * Copyright 2013 Basis Technology Corp. * Contact: carrier sleuthkit org * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -22,8 +22,6 @@ import java.io.FileOutputStream; import java.io.IOException; import java.text.SimpleDateFormat; import java.util.List; -import java.util.Map; -import java.util.TreeMap; import java.util.logging.Level; import org.apache.poi.hssf.util.HSSFColor; import org.apache.poi.ss.usermodel.*; @@ -34,7 +32,6 @@ import org.sleuthkit.autopsy.coreutils.Logger; public class ReportExcel implements TableReportModule { private static final Logger logger = Logger.getLogger(ReportExcel.class.getName()); private static ReportExcel instance; - private Case currentCase; private Workbook wb; private Sheet sheet; @@ -42,8 +39,7 @@ public class ReportExcel implements TableReportModule { private CellStyle setStyle; private CellStyle elementStyle; private int rowCount = 2; - - private Map dataTypes; + private int sheetColCount = 0; private String currentDataType; private String reportPath; @@ -65,33 +61,41 @@ public class ReportExcel implements TableReportModule { * @param path path to save the report */ @Override - public void startReport(String path) { - currentCase = Case.getCurrentCase(); - + public void startReport(String path) { wb = new XSSFWorkbook(); + // TODO: The commented out cell style settings below do not work as desired when + // the output file is loaded by MS Excel or OfficeLibre. The font height and weight + // settings only work as expected when the output file is loaded by OfficeLibre. + // The alignment and text wrap settings appear to have no effect. titleStyle = wb.createCellStyle(); - titleStyle.setBorderBottom((short) 1); +// titleStyle.setBorderBottom((short) 1); Font titleFont = wb.createFont(); titleFont.setFontHeightInPoints((short) 12); titleStyle.setFont(titleFont); + titleStyle.setAlignment(CellStyle.ALIGN_LEFT); + titleStyle.setWrapText(true); setStyle = wb.createCellStyle(); Font setFont = wb.createFont(); setFont.setFontHeightInPoints((short) 14); setFont.setBoldweight((short) 10); setStyle.setFont(setFont); + setStyle.setAlignment(CellStyle.ALIGN_LEFT); + setStyle.setWrapText(true); elementStyle = wb.createCellStyle(); - elementStyle.setFillBackgroundColor(HSSFColor.LIGHT_YELLOW.index); +// elementStyle.setF illBackgroundColor(HSSFColor.LIGHT_YELLOW.index); Font elementFont = wb.createFont(); elementFont.setFontHeightInPoints((short) 14); elementStyle.setFont(elementFont); + elementStyle.setAlignment(CellStyle.ALIGN_LEFT); + elementStyle.setWrapText(true); - dataTypes = new TreeMap(); this.reportPath = path + getFilePath(); // Write the summary + Case currentCase = Case.getCurrentCase(); sheet = wb.createSheet("Summary"); sheet.createRow(0).createCell(0).setCellValue("Case Name:"); sheet.getRow(0).createCell(1).setCellValue(currentCase.getName()); @@ -101,6 +105,8 @@ public class ReportExcel implements TableReportModule { sheet.getRow(2).createCell(1).setCellValue(currentCase.getExaminer()); sheet.createRow(3).createCell(0).setCellValue("# of Images:"); sheet.getRow(3).createCell(1).setCellValue(currentCase.getImageIDs().length); + sheet.autoSizeColumn(0); + sheet.autoSizeColumn(1); } /** @@ -135,6 +141,8 @@ public class ReportExcel implements TableReportModule { sheet = wb.createSheet(title); sheet.setAutobreaks(true); currentDataType = title; + rowCount = 2; + sheetColCount = 0; } /** @@ -142,12 +150,14 @@ public class ReportExcel implements TableReportModule { */ @Override public void endDataType() { - Row temp = sheet.createRow(0); - temp.createCell(0).setCellValue("Number of " + currentDataType + " artifacts:"); - temp.createCell(1).setCellValue(rowCount); - - dataTypes.put(currentDataType, rowCount); - rowCount = 2; + Row row = sheet.createRow(0); + row.createCell(0).setCellValue("Number of " + currentDataType + " artifacts:"); + row.createCell(1).setCellValue(rowCount); + + // Now that the sheet is complete, size the columns to the content. + for (int i = 0; i < sheetColCount; ++i) { + sheet.autoSizeColumn(i); + } } /** @@ -157,9 +167,9 @@ public class ReportExcel implements TableReportModule { @Override public void startSet(String setName) { setName = escapeForExcel(setName); - Row temp = sheet.createRow(rowCount); - temp.setRowStyle(setStyle); - temp.createCell(0).setCellValue(setName); + Row row = sheet.createRow(rowCount); + row.setRowStyle(setStyle); + row.createCell(0).setCellValue(setName); rowCount++; } @@ -168,12 +178,14 @@ public class ReportExcel implements TableReportModule { */ @Override public void endSet() { - rowCount++; // Put a space between the sets + // Add an empty row as a separator. + sheet.createRow(rowCount); + rowCount++; } - // Ignored in Excel Report @Override public void addSetIndex(List sets) { + // Ignored in Excel Report } /** @@ -183,9 +195,9 @@ public class ReportExcel implements TableReportModule { @Override public void addSetElement(String elementName) { elementName = escapeForExcel(elementName); - Row temp = sheet.createRow(rowCount); - temp.setRowStyle(elementStyle); - temp.createCell(0).setCellValue(elementName); + Row row = sheet.createRow(rowCount); + row.setRowStyle(elementStyle); + row.createCell(0).setCellValue(elementName); rowCount++; } @@ -195,17 +207,25 @@ public class ReportExcel implements TableReportModule { */ @Override public void startTable(List titles) { - Row temp = sheet.createRow(rowCount); - temp.setRowStyle(titleStyle); + int tableColCount = 0; + Row row = sheet.createRow(rowCount); + row.setRowStyle(titleStyle); for (int i=0; i sheetColCount) { + sheetColCount = tableColCount; + } } - // Do nothing on end table @Override public void endTable() { + // Add an empty row as a separator. + sheet.createRow(rowCount); + rowCount++; } /** From 0bb6b8f453c3bafa642705ad3d7c04d1b0dc4a7d Mon Sep 17 00:00:00 2001 From: Richard Cordovano Date: Thu, 1 Aug 2013 17:24:08 -0400 Subject: [PATCH 3/4] Added tags filter comment output to ReportHTML and ReportExcel classes --- .../sleuthkit/autopsy/report/ReportExcel.java | 178 +++++++++++++----- .../autopsy/report/ReportGenerator.java | 126 ++++++++----- .../sleuthkit/autopsy/report/ReportHTML.java | 36 ++++ 3 files changed, 252 insertions(+), 88 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/report/ReportExcel.java b/Core/src/org/sleuthkit/autopsy/report/ReportExcel.java index d7844aa1cc..c9024b26cd 100644 --- a/Core/src/org/sleuthkit/autopsy/report/ReportExcel.java +++ b/Core/src/org/sleuthkit/autopsy/report/ReportExcel.java @@ -38,9 +38,9 @@ public class ReportExcel implements TableReportModule { private CellStyle titleStyle; private CellStyle setStyle; private CellStyle elementStyle; - private int rowCount = 2; + private int rowIndex = 0; private int sheetColCount = 0; - private String currentDataType; + private int artifactsCount = 0; private String reportPath; // Get the default instance of this report @@ -62,8 +62,13 @@ public class ReportExcel implements TableReportModule { */ @Override public void startReport(String path) { + // Set the path and save it for when the report is written to disk. + this.reportPath = path + getFilePath(); + + // Make a workbook. wb = new XSSFWorkbook(); + // Create some cell styles. // TODO: The commented out cell style settings below do not work as desired when // the output file is loaded by MS Excel or OfficeLibre. The font height and weight // settings only work as expected when the output file is loaded by OfficeLibre. @@ -91,22 +96,8 @@ public class ReportExcel implements TableReportModule { elementStyle.setFont(elementFont); elementStyle.setAlignment(CellStyle.ALIGN_LEFT); elementStyle.setWrapText(true); - - this.reportPath = path + getFilePath(); - - // Write the summary - Case currentCase = Case.getCurrentCase(); - sheet = wb.createSheet("Summary"); - sheet.createRow(0).createCell(0).setCellValue("Case Name:"); - sheet.getRow(0).createCell(1).setCellValue(currentCase.getName()); - sheet.createRow(1).createCell(0).setCellValue("Case Number:"); - sheet.getRow(1).createCell(1).setCellValue(currentCase.getNumber()); - sheet.createRow(2).createCell(0).setCellValue("Examiner:"); - sheet.getRow(2).createCell(1).setCellValue(currentCase.getExaminer()); - sheet.createRow(3).createCell(0).setCellValue("# of Images:"); - sheet.getRow(3).createCell(1).setCellValue(currentCase.getImageIDs().length); - sheet.autoSizeColumn(0); - sheet.autoSizeColumn(1); + + writeSummaryWorksheet(); } /** @@ -132,27 +123,90 @@ public class ReportExcel implements TableReportModule { /** - * Start a new sheet for the given data type. - * @param title data type name + * Start a new worksheet for the given data type. + * @param name data type name */ @Override - public void startDataType(String title) { - title = escapeForExcel(title); - sheet = wb.createSheet(title); + public void startDataType(String name) { + // Create a worksheet for the data type (assumed to be an artifact type). + name = escapeForExcel(name); + sheet = wb.createSheet(name); sheet.setAutobreaks(true); - currentDataType = title; - rowCount = 2; - sheetColCount = 0; + artifactsCount = 0; + + // Add a title row to the worksheet. + rowIndex = 0; + Row row = sheet.createRow(rowIndex); + row.setRowStyle(setStyle); + row.createCell(0).setCellValue(name); + ++rowIndex; + + // Add an artifacts count row. The actual count will be filled in later. + row = sheet.createRow(rowIndex); + row.setRowStyle(setStyle); + row.createCell(0).setCellValue("Number of artifacts:"); + ++rowIndex; + + // Add an empty row as a separator. + sheet.createRow(rowIndex); + ++rowIndex; + + // There will be at least two columns, one each for the artifacts count and its label. + sheetColCount = 2; } + /** + * Start a new worksheet for the given data type. + * Note: This method is a temporary workaround to avoid modifying the TableReportModule interface. + * + * @param name Name of the data type + * @param comment Comment on the data type, may be the empty string + */ + public void startDataType(String name, String comment) { + // Create a worksheet for the data type (assumed to be an artifact type). + name = escapeForExcel(name); + sheet = wb.createSheet(name); + sheet.setAutobreaks(true); + artifactsCount = 0; + + // Add a title row to the worksheet. + rowIndex = 0; + Row row = sheet.createRow(rowIndex); + row.setRowStyle(setStyle); + row.createCell(0).setCellValue(name); + ++rowIndex; + + // Add an artifacts count row. The actual count will be filled in later. + row = sheet.createRow(rowIndex); + row.setRowStyle(setStyle); + row.createCell(0).setCellValue("Number of artifacts:"); + ++rowIndex; + + // Add a comment row, if a comment was supplied. + if (!comment.isEmpty()) { + row = sheet.createRow(rowIndex); + row.setRowStyle(setStyle); + row.createCell(0).setCellValue(comment); + ++rowIndex; + } + + // Add an empty row as a separator. + sheet.createRow(rowIndex); + ++rowIndex; + + // There will be at least two columns, one each for the artifacts count and its label. + sheetColCount = 2; + } + /** * End the current data type and sheet. */ @Override public void endDataType() { - Row row = sheet.createRow(0); - row.createCell(0).setCellValue("Number of " + currentDataType + " artifacts:"); - row.createCell(1).setCellValue(rowCount); + // Fill in the artifact count cell in row 0. + Row row = sheet.getRow(1); + row.setRowStyle(setStyle); + row.createCell(1).setCellValue(artifactsCount); // Now that the sheet is complete, size the columns to the content. for (int i = 0; i < sheetColCount; ++i) { @@ -167,10 +221,10 @@ public class ReportExcel implements TableReportModule { @Override public void startSet(String setName) { setName = escapeForExcel(setName); - Row row = sheet.createRow(rowCount); + Row row = sheet.createRow(rowIndex); row.setRowStyle(setStyle); row.createCell(0).setCellValue(setName); - rowCount++; + rowIndex++; } /** @@ -179,8 +233,8 @@ public class ReportExcel implements TableReportModule { @Override public void endSet() { // Add an empty row as a separator. - sheet.createRow(rowCount); - rowCount++; + sheet.createRow(rowIndex); + rowIndex++; } @Override @@ -195,10 +249,10 @@ public class ReportExcel implements TableReportModule { @Override public void addSetElement(String elementName) { elementName = escapeForExcel(elementName); - Row row = sheet.createRow(rowCount); + Row row = sheet.createRow(rowIndex); row.setRowStyle(elementStyle); row.createCell(0).setCellValue(elementName); - rowCount++; + rowIndex++; } /** @@ -208,13 +262,13 @@ public class ReportExcel implements TableReportModule { @Override public void startTable(List titles) { int tableColCount = 0; - Row row = sheet.createRow(rowCount); + Row row = sheet.createRow(rowIndex); row.setRowStyle(titleStyle); for (int i=0; i sheetColCount) { sheetColCount = tableColCount; @@ -224,8 +278,8 @@ public class ReportExcel implements TableReportModule { @Override public void endTable() { // Add an empty row as a separator. - sheet.createRow(rowCount); - rowCount++; + sheet.createRow(rowIndex); + ++rowIndex; } /** @@ -234,11 +288,12 @@ public class ReportExcel implements TableReportModule { */ @Override public void addRow(List row) { - Row temp = sheet.createRow(rowCount); - for (int i=0; i { - List tableModules; - List artifactTypes; - HashSet tagNamesFilter; + private List tableModules = new ArrayList<>(); + private List artifactTypes = new ArrayList<>(); + private HashSet tagNamesFilter = new HashSet<>(); // Create an ArtifactWorker with the enabled/disabled state of all Artifacts ArtifactsReportsWorker(Map artifactTypeSelections, Map tagSelections) { - tableModules = new ArrayList<>(); + // Get the report modules selected by the user. for (Entry entry : tableProgress.entrySet()) { tableModules.add(entry.getKey()); } - artifactTypes = new ArrayList<>(); + // Get the artifact types selected by the user. for (Entry entry : artifactTypeSelections.entrySet()) { if (entry.getValue()) { artifactTypes.add(entry.getKey()); } } + // Get the tags selected by the user. if (tagSelections != null) { - tagNamesFilter = new HashSet<>(); for (Entry entry : tagSelections.entrySet()) { if (entry.getValue() == true) { tagNamesFilter.add(entry.getKey()); @@ -238,6 +237,13 @@ public class ReportGenerator { } } + // Make a comment on the tags filter. + StringBuilder comment = new StringBuilder(); + if (!tagNamesFilter.isEmpty()) { + comment.append("This report only includes files and artifacts tagged with: "); + comment.append(makeCommaSeparatedList(tagNamesFilter)); + } + // For every enabled artifact type for (ARTIFACT_TYPE type : artifactTypes) { // Check to see if all the TableReportModules have been canceled @@ -254,16 +260,16 @@ public class ReportGenerator { // If the type is keyword hit or hashset hit, use the helper if (type.equals(ARTIFACT_TYPE.TSK_KEYWORD_HIT)) { - writeKeywordHits(tableModules, tagNamesFilter); + writeKeywordHits(tableModules, comment.toString(), tagNamesFilter); continue; } else if (type.equals(ARTIFACT_TYPE.TSK_HASHSET_HIT)) { - writeHashsetHits(tableModules, tagNamesFilter); + writeHashsetHits(tableModules, comment.toString(), tagNamesFilter); continue; } // Otherwise setup the unsorted list of artifacts, to later be sorted ArtifactComparator c = new ArtifactComparator(); - List>> unsortedArtifacts = new ArrayList>>(); + List>> unsortedArtifacts = new ArrayList<>(); try { // For every artifact of the current type, add it and it's attributes to a list for (BlackboardArtifact artifact : skCase.getBlackboardArtifacts(type)) { @@ -289,14 +295,20 @@ public class ReportGenerator { // For every module start a new data type and table for the current artifact type. for (TableReportModule module : tableModules) { tableProgress.get(module).updateStatusLabel("Now processing " + type.getDisplayName() + "..."); - - module.startDataType(type.getDisplayName()); - + + // This is a temporary workaround to avoid modifying the TableReportModule interface. if (module instanceof ReportHTML) { ReportHTML htmlReportModule = (ReportHTML)module; + htmlReportModule.startDataType(type.getDisplayName(), comment.toString()); htmlReportModule.startTable(columnHeaders, type); } + else if (module instanceof ReportExcel) { + ReportExcel excelReportModule = (ReportExcel)module; + excelReportModule.startDataType(type.getDisplayName(), comment.toString()); + excelReportModule.startTable(columnHeaders); + } else { + module.startDataType(type.getDisplayName()); module.startTable(columnHeaders); } } @@ -323,6 +335,7 @@ public class ReportGenerator { rowData.add(tagsList); } + // This is a temporary workaround to avoid modifying the TableReportModule interface. if (module instanceof ReportHTML) { ReportHTML htmlReportModule = (ReportHTML)module; htmlReportModule.addRow(rowData, artifactEntry.getKey()); @@ -353,7 +366,7 @@ public class ReportGenerator { private Boolean failsTagFilter(HashSet tags, HashSet tagsFilter) { - if (tagsFilter == null) { + if (tagsFilter == null || tagsFilter.isEmpty()) { return false; } @@ -367,7 +380,7 @@ public class ReportGenerator { * @param tableModules modules to report on */ @SuppressWarnings("deprecation") - private void writeKeywordHits(List tableModules, HashSet tagNamesFilter) { + private void writeKeywordHits(List tableModules, String comment, HashSet tagNamesFilter) { ResultSet listsRs = null; try { // Query for keyword lists @@ -377,7 +390,7 @@ public class ReportGenerator { "AND art.artifact_type_id = " + ARTIFACT_TYPE.TSK_KEYWORD_HIT.getTypeID() + " " + "AND att.artifact_id = art.artifact_id " + "GROUP BY list"); - List lists = new ArrayList(); + List lists = new ArrayList<>(); while(listsRs.next()) { String list = listsRs.getString("list"); if(list.isEmpty()) { @@ -388,7 +401,18 @@ public class ReportGenerator { // Make keyword data type and give them set index for (TableReportModule module : tableModules) { - module.startDataType(ARTIFACT_TYPE.TSK_KEYWORD_HIT.getDisplayName()); + // This is a temporary workaround to avoid modifying the TableReportModule interface. + if (module instanceof ReportHTML) { + ReportHTML htmlReportModule = (ReportHTML)module; + htmlReportModule.startDataType(ARTIFACT_TYPE.TSK_KEYWORD_HIT.getDisplayName(), comment); + } + else if (module instanceof ReportExcel) { + ReportExcel excelReportModule = (ReportExcel)module; + excelReportModule.startDataType(ARTIFACT_TYPE.TSK_KEYWORD_HIT.getDisplayName(), comment); + } + else { + module.startDataType(ARTIFACT_TYPE.TSK_KEYWORD_HIT.getDisplayName()); + } module.addSetIndex(lists); tableProgress.get(module).updateStatusLabel("Now processing " + ARTIFACT_TYPE.TSK_KEYWORD_HIT.getDisplayName() + "..."); @@ -507,11 +531,11 @@ public class ReportGenerator { } /** - * Write the hashset hits to the provided TableReportModules. + * Write the hash set hits to the provided TableReportModules. * @param tableModules modules to report on */ @SuppressWarnings("deprecation") - private void writeHashsetHits(List tableModules, HashSet tagNamesFilter) { + private void writeHashsetHits(List tableModules, String comment, HashSet tagNamesFilter) { ResultSet listsRs = null; try { // Query for hashsets @@ -521,14 +545,24 @@ public class ReportGenerator { "AND art.artifact_type_id = " + ARTIFACT_TYPE.TSK_HASHSET_HIT.getTypeID() + " " + "AND att.artifact_id = art.artifact_id " + "GROUP BY list"); - List lists = new ArrayList(); + List lists = new ArrayList<>(); while(listsRs.next()) { lists.add(listsRs.getString("list")); } - // Make hashset data type and give them set index for (TableReportModule module : tableModules) { - module.startDataType(ARTIFACT_TYPE.TSK_HASHSET_HIT.getDisplayName()); + // This is a temporary workaround to avoid modifying the TableReportModule interface. + if (module instanceof ReportHTML) { + ReportHTML htmlReportModule = (ReportHTML)module; + htmlReportModule.startDataType(ARTIFACT_TYPE.TSK_HASHSET_HIT.getDisplayName(), comment); + } + else if (module instanceof ReportExcel) { + ReportExcel excelReportModule = (ReportExcel)module; + excelReportModule.startDataType(ARTIFACT_TYPE.TSK_HASHSET_HIT.getDisplayName(), comment); + } + else { + module.startDataType(ARTIFACT_TYPE.TSK_HASHSET_HIT.getDisplayName()); + } module.addSetIndex(lists); tableProgress.get(module).updateStatusLabel("Now processing " + ARTIFACT_TYPE.TSK_HASHSET_HIT.getDisplayName() + "..."); @@ -640,55 +674,55 @@ public class ReportGenerator { switch (type) { case TSK_WEB_BOOKMARK: - columnHeaders = new ArrayList(Arrays.asList(new String[] {"URL", "Title", "Date Accessed", "Program", "Source File"})); + columnHeaders = new ArrayList<>(Arrays.asList(new String[] {"URL", "Title", "Date Accessed", "Program", "Source File"})); break; case TSK_WEB_COOKIE: - columnHeaders = new ArrayList(Arrays.asList(new String[] {"URL", "Date/Time", "Name", "Value", "Program", "Source File"})); + columnHeaders = new ArrayList<>(Arrays.asList(new String[] {"URL", "Date/Time", "Name", "Value", "Program", "Source File"})); break; case TSK_WEB_HISTORY: - columnHeaders = new ArrayList(Arrays.asList(new String[] {"URL", "Date Accessed", "Referrer", "Name", "Program", "Source File"})); + columnHeaders = new ArrayList<>(Arrays.asList(new String[] {"URL", "Date Accessed", "Referrer", "Name", "Program", "Source File"})); break; case TSK_WEB_DOWNLOAD: - columnHeaders = new ArrayList(Arrays.asList(new String[] {"Destination", "Source URL", "Date Accessed", "Program", "Source File"})); + columnHeaders = new ArrayList<>(Arrays.asList(new String[] {"Destination", "Source URL", "Date Accessed", "Program", "Source File"})); break; case TSK_RECENT_OBJECT: - columnHeaders = new ArrayList(Arrays.asList(new String[] {"Path", "Source File"})); + columnHeaders = new ArrayList<>(Arrays.asList(new String[] {"Path", "Source File"})); break; case TSK_INSTALLED_PROG: - columnHeaders = new ArrayList(Arrays.asList(new String[] {"Program Name", "Install Date/Time", "Source File"})); + columnHeaders = new ArrayList<>(Arrays.asList(new String[] {"Program Name", "Install Date/Time", "Source File"})); break; case TSK_KEYWORD_HIT: - columnHeaders = new ArrayList(Arrays.asList(new String[] {"Preview", "Source File"})); + columnHeaders = new ArrayList<>(Arrays.asList(new String[] {"Preview", "Source File"})); break; case TSK_HASHSET_HIT: - columnHeaders = new ArrayList(Arrays.asList(new String[] {"File", "Size"})); + columnHeaders = new ArrayList<>(Arrays.asList(new String[] {"File", "Size"})); break; case TSK_DEVICE_ATTACHED: - columnHeaders = new ArrayList(Arrays.asList(new String[] {"Name", "Device ID", "Date/Time", "Source File"})); + columnHeaders = new ArrayList<>(Arrays.asList(new String[] {"Name", "Device ID", "Date/Time", "Source File"})); break; case TSK_WEB_SEARCH_QUERY: - columnHeaders = new ArrayList(Arrays.asList(new String[] {"Text", "Domain", "Date Accessed", "Program Name", "Source File"})); + columnHeaders = new ArrayList<>(Arrays.asList(new String[] {"Text", "Domain", "Date Accessed", "Program Name", "Source File"})); break; case TSK_METADATA_EXIF: - columnHeaders = new ArrayList(Arrays.asList(new String[] {"Date Taken", "Device Manufacturer", "Device Model", "Latitude", "Longitude", "Source File"})); + columnHeaders = new ArrayList<>(Arrays.asList(new String[] {"Date Taken", "Device Manufacturer", "Device Model", "Latitude", "Longitude", "Source File"})); break; case TSK_TAG_FILE: - columnHeaders = new ArrayList(Arrays.asList(new String[] {"File", "Tag", "Comment"})); + columnHeaders = new ArrayList<>(Arrays.asList(new String[] {"File", "Tag", "Comment"})); break; case TSK_TAG_ARTIFACT: - columnHeaders = new ArrayList(Arrays.asList(new String[] {"Result Type", "Tag", "Comment", "Source File"})); + columnHeaders = new ArrayList<>(Arrays.asList(new String[] {"Result Type", "Tag", "Comment", "Source File"})); break; case TSK_CONTACT: - columnHeaders = new ArrayList(Arrays.asList(new String[] {"Person Name", "Phone Number", "Phone Number (Home)", "Phone Number (Office)", "Phone Number (Mobile)", "Email", "Source File" })); + columnHeaders = new ArrayList<>(Arrays.asList(new String[] {"Person Name", "Phone Number", "Phone Number (Home)", "Phone Number (Office)", "Phone Number (Mobile)", "Email", "Source File" })); break; case TSK_MESSAGE: - columnHeaders = new ArrayList(Arrays.asList(new String[] {"Message Type", "Direction", "Date/Time", "From Phone Number", "From Email", "To Phone Number", "To Email", "Subject", "Text", "Source File" })); + columnHeaders = new ArrayList<>(Arrays.asList(new String[] {"Message Type", "Direction", "Date/Time", "From Phone Number", "From Email", "To Phone Number", "To Email", "Subject", "Text", "Source File" })); break; case TSK_CALLLOG: - columnHeaders = new ArrayList(Arrays.asList(new String[] {"Person Name", "Phone Number", "Date/Time", "Direction", "Source File" })); + columnHeaders = new ArrayList<>(Arrays.asList(new String[] {"Person Name", "Phone Number", "Date/Time", "Direction", "Source File" })); break; case TSK_CALENDAR_ENTRY: - columnHeaders = new ArrayList(Arrays.asList(new String[] {"Calendar Entry Type", "Description", "Start Date/Time", "End Date/Time", "Location", "Source File" })); + columnHeaders = new ArrayList<>(Arrays.asList(new String[] {"Calendar Entry Type", "Description", "Start Date/Time", "End Date/Time", "Location", "Source File" })); break; default: return null; @@ -711,7 +745,7 @@ public class ReportGenerator { * @return Map of the BlackboardAttributes mapped to their attribute type ID */ public Map getMappedAttributes(List attList, TableReportModule... module) { - Map attributes = new HashMap(); + Map attributes = new HashMap<>(); int size = ATTRIBUTE_TYPE.values().length; for (int n = 0; n <= size; n++) { attributes.put(n, ""); @@ -759,11 +793,11 @@ public class ReportGenerator { private String makeCommaSeparatedList(Collection items) { String list = ""; for (Iterator iterator = items.iterator(); iterator.hasNext(); ) { - list += iterator.next() + (iterator.hasNext() ? "," : ""); + list += iterator.next() + (iterator.hasNext() ? ", " : ""); } return list; } - + /** * Get a list of Strings with all the row values for a given BlackboardArtifact and * list of BlackboardAttributes Entry, basing the date/time field on the given TableReportModule. @@ -882,7 +916,7 @@ public class ReportGenerator { } return taggedArtifactRow; case TSK_CONTACT: - List contact = new ArrayList(); + List contact = new ArrayList<>(); contact.add(attributes.get(ATTRIBUTE_TYPE.TSK_NAME_PERSON.getTypeID())); contact.add(attributes.get(ATTRIBUTE_TYPE.TSK_PHONE_NUMBER.getTypeID())); contact.add(attributes.get(ATTRIBUTE_TYPE.TSK_PHONE_NUMBER_HOME.getTypeID())); @@ -892,7 +926,7 @@ public class ReportGenerator { contact.add(getFileUniquePath(entry.getKey().getObjectID())); return contact; case TSK_MESSAGE: - List message = new ArrayList(); + List message = new ArrayList<>(); message.add(attributes.get(ATTRIBUTE_TYPE.TSK_MESSAGE_TYPE.getTypeID())); message.add(attributes.get(ATTRIBUTE_TYPE.TSK_DIRECTION.getTypeID())); message.add(attributes.get(ATTRIBUTE_TYPE.TSK_DATETIME.getTypeID())); @@ -905,7 +939,7 @@ public class ReportGenerator { message.add(getFileUniquePath(entry.getKey().getObjectID())); return message; case TSK_CALLLOG: - List call_log = new ArrayList(); + List call_log = new ArrayList<>(); call_log.add(attributes.get(ATTRIBUTE_TYPE.TSK_NAME_PERSON.getTypeID())); call_log.add(attributes.get(ATTRIBUTE_TYPE.TSK_PHONE_NUMBER.getTypeID())); call_log.add(attributes.get(ATTRIBUTE_TYPE.TSK_DATETIME.getTypeID())); @@ -913,7 +947,7 @@ public class ReportGenerator { call_log.add(getFileUniquePath(entry.getKey().getObjectID())); return call_log; case TSK_CALENDAR_ENTRY: - List calEntry = new ArrayList(); + List calEntry = new ArrayList<>(); calEntry.add(attributes.get(ATTRIBUTE_TYPE.TSK_CALENDAR_ENTRY_TYPE.getTypeID())); calEntry.add(attributes.get(ATTRIBUTE_TYPE.TSK_DESCRIPTION.getTypeID())); calEntry.add(attributes.get(ATTRIBUTE_TYPE.TSK_DATETIME_START.getTypeID())); diff --git a/Core/src/org/sleuthkit/autopsy/report/ReportHTML.java b/Core/src/org/sleuthkit/autopsy/report/ReportHTML.java index 3c660cade9..7cb5602c56 100644 --- a/Core/src/org/sleuthkit/autopsy/report/ReportHTML.java +++ b/Core/src/org/sleuthkit/autopsy/report/ReportHTML.java @@ -177,6 +177,41 @@ public class ReportHTML implements TableReportModule { } } + /** + * Start a new HTML page for the given data type. Update the output stream to this page, + * and setup the web page header. + * Note: This method is a temporary workaround to avoid modifying the TableReportModule interface. + * + * @param name Name of the data type + * @param comment Comment on the data type, may be the empty string + */ + public void startDataType(String name, String comment) { + String title = org.sleuthkit.autopsy.coreutils.FileUtil.escapeFileName(name); + try { + out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(path + title + getExtension()), "UTF-8")); + } catch (FileNotFoundException ex) { + logger.log(Level.SEVERE, "File not found: {0}", ex); + } catch (UnsupportedEncodingException ex) { + logger.log(Level.SEVERE, "Unrecognized encoding"); + } + + try { + StringBuilder page = new StringBuilder(); + page.append("\n\n\t").append(name).append("\n\t\n\n\n\n"); + page.append("
").append(name).append("
\n
\n"); + if (!comment.isEmpty()) { + page.append("

"); + page.append(comment); + page.append("

\n"); + } + out.write(page.toString()); + currentDataType = name; + rowCount = 0; + } catch (IOException ex) { + logger.log(Level.SEVERE, "Failed to write page head: {0}", ex); + } + } + /** * End the current data type. Write the end of the web page and close the * output stream. @@ -284,6 +319,7 @@ public class ReportHTML implements TableReportModule { /** * Start a new table with the given column headers. + * Note: This method is a temporary workaround to avoid modifying the TableReportModule interface. * * @param columnHeaders column headers * @param sourceArtifact source blackboard artifact for the table data From c03cbf146e4840be7f7d4bed945e1ce709c1cc85 Mon Sep 17 00:00:00 2001 From: Richard Cordovano Date: Thu, 1 Aug 2013 17:25:33 -0400 Subject: [PATCH 4/4] Tidied up implemtation of adding tags filter comment output to ReportHTML and ReportExcel classes --- .../sleuthkit/autopsy/report/ReportExcel.java | 28 +++++++++++-------- .../autopsy/report/ReportGenerator.java | 2 +- .../sleuthkit/autopsy/report/ReportHTML.java | 2 +- 3 files changed, 18 insertions(+), 14 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/report/ReportExcel.java b/Core/src/org/sleuthkit/autopsy/report/ReportExcel.java index c9024b26cd..a491c0a3c6 100644 --- a/Core/src/org/sleuthkit/autopsy/report/ReportExcel.java +++ b/Core/src/org/sleuthkit/autopsy/report/ReportExcel.java @@ -132,10 +132,10 @@ public class ReportExcel implements TableReportModule { name = escapeForExcel(name); sheet = wb.createSheet(name); sheet.setAutobreaks(true); + rowIndex = 0; artifactsCount = 0; // Add a title row to the worksheet. - rowIndex = 0; Row row = sheet.createRow(rowIndex); row.setRowStyle(setStyle); row.createCell(0).setCellValue(name); @@ -167,10 +167,10 @@ public class ReportExcel implements TableReportModule { name = escapeForExcel(name); sheet = wb.createSheet(name); sheet.setAutobreaks(true); + rowIndex = 0; artifactsCount = 0; // Add a title row to the worksheet. - rowIndex = 0; Row row = sheet.createRow(rowIndex); row.setRowStyle(setStyle); row.createCell(0).setCellValue(name); @@ -224,7 +224,7 @@ public class ReportExcel implements TableReportModule { Row row = sheet.createRow(rowIndex); row.setRowStyle(setStyle); row.createCell(0).setCellValue(setName); - rowIndex++; + ++rowIndex; } /** @@ -234,7 +234,7 @@ public class ReportExcel implements TableReportModule { public void endSet() { // Add an empty row as a separator. sheet.createRow(rowIndex); - rowIndex++; + ++rowIndex; } @Override @@ -252,7 +252,7 @@ public class ReportExcel implements TableReportModule { Row row = sheet.createRow(rowIndex); row.setRowStyle(elementStyle); row.createCell(0).setCellValue(elementName); - rowIndex++; + ++rowIndex; } /** @@ -268,8 +268,9 @@ public class ReportExcel implements TableReportModule { row.createCell(i).setCellValue(titles.get(i)); ++tableColCount; } - rowIndex++; + ++rowIndex; + // Keep track of the number of columns with data in them for later column auto-sizing. if (tableColCount > sheetColCount) { sheetColCount = tableColCount; } @@ -287,13 +288,13 @@ public class ReportExcel implements TableReportModule { * @param row cells to add */ @Override - public void addRow(List row) { - Row temp = sheet.createRow(rowIndex); - for (int i = 0; i < row.size(); ++i) { - temp.createCell(i).setCellValue(row.get(i)); + public void addRow(List rowData) { + Row row = sheet.createRow(rowIndex); + for (int i = 0; i < rowData.size(); ++i) { + row.createCell(i).setCellValue(rowData.get(i)); } - ++artifactsCount; ++rowIndex; + ++artifactsCount; } /** @@ -339,13 +340,16 @@ public class ReportExcel implements TableReportModule { private void writeSummaryWorksheet() { sheet = wb.createSheet("Summary"); - rowIndex = 0; + Row row = sheet.createRow(rowIndex); row.setRowStyle(setStyle); row.createCell(0).setCellValue("Summary"); ++rowIndex; + sheet.createRow(rowIndex); + ++rowIndex; + Case currentCase = Case.getCurrentCase(); row = sheet.createRow(rowIndex); diff --git a/Core/src/org/sleuthkit/autopsy/report/ReportGenerator.java b/Core/src/org/sleuthkit/autopsy/report/ReportGenerator.java index b31de40737..ea177fc38b 100644 --- a/Core/src/org/sleuthkit/autopsy/report/ReportGenerator.java +++ b/Core/src/org/sleuthkit/autopsy/report/ReportGenerator.java @@ -366,7 +366,7 @@ public class ReportGenerator { private Boolean failsTagFilter(HashSet tags, HashSet tagsFilter) { - if (tagsFilter == null || tagsFilter.isEmpty()) { + if (null == tagsFilter || tagsFilter.isEmpty()) { return false; } diff --git a/Core/src/org/sleuthkit/autopsy/report/ReportHTML.java b/Core/src/org/sleuthkit/autopsy/report/ReportHTML.java index 7cb5602c56..86506f0777 100644 --- a/Core/src/org/sleuthkit/autopsy/report/ReportHTML.java +++ b/Core/src/org/sleuthkit/autopsy/report/ReportHTML.java @@ -852,7 +852,7 @@ public class ReportHTML implements TableReportModule { summary.append("Case:").append(caseName).append("\n"); summary.append("Case Number:").append(!caseNumber.isEmpty() ? caseNumber : "No case number").append("\n"); summary.append("Examiner:").append(!examiner.isEmpty() ? examiner : "No examiner").append("\n"); - summary.append("# of Images:").append(imagecount).append("\n"); + summary.append("Number of Images:").append(imagecount).append("\n"); summary.append("\n"); summary.append("
\n"); summary.append("
\n");