Merge pull request #5250 from eugene7646/progress_panel_5555

Progress panel (5555)
This commit is contained in:
Richard Cordovano 2019-09-24 11:26:00 -04:00 committed by GitHub
commit ac86abf7a4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 132 additions and 64 deletions

View File

@ -19,12 +19,12 @@
package org.sleuthkit.autopsy.report;
/**
* This interface is necessary in order to not break backwards compatibility
* of GeneralReportModule interface. See JIRA-5354.
* This interface is necessary in order to not break backwards compatibility of
* GeneralReportModule interface. See JIRA-5354.
*/
public interface ReportProgressPanel {
/**
/**
* Used by a report generation module to communicate report generation
* status to this panel and its listeners.
*/
@ -74,7 +74,7 @@ public interface ReportProgressPanel {
* indeterminate.
*
* @param indeterminate True if the progress bar should be set to
* indeterminate.
* indeterminate.
*/
public void setIndeterminate(boolean indeterminate);
@ -95,6 +95,15 @@ public interface ReportProgressPanel {
*/
public void complete(ReportStatus reportStatus);
/**
* Makes the components of this panel indicate the final status of
* generation of the report.
*
* @param reportStatus The final status, must be COMPLETE or ERROR.
* @param statusMessage String to use as label or error text.
*/
public void complete(ReportStatus reportStatus, String statusMessage);
/**
* Makes the components of this panel indicate the generation of the report
* is completed.

View File

@ -214,6 +214,29 @@ class ReportProgressDialog extends javax.swing.JPanel implements ReportProgressP
*/
@Override
public void complete(ReportStatus reportStatus) {
switch (reportStatus) {
case COMPLETE:
complete(reportStatus, NbBundle.getMessage(this.getClass(), "ReportProgressDialog.complete.processLbl.text"));
break;
case ERROR:
complete(reportStatus, NbBundle.getMessage(this.getClass(), "ReportProgressDialog.complete.processLb2.text"));
break;
default:
complete(reportStatus, "");
break;
}
}
/**
* Makes the components of this panel indicate the final status of
* generation of the report.
*
* @param reportStatus The final status, must be COMPLETE or ERROR.
* @param statusMessage String to use as label or error text.
*/
@Override
public void complete(ReportStatus reportStatus, String statusMessage) {
EventQueue.invokeLater(() -> {
reportProgressBar.setIndeterminate(false);
if (status != ReportStatus.CANCELED) {
@ -222,7 +245,7 @@ class ReportProgressDialog extends javax.swing.JPanel implements ReportProgressP
ReportStatus oldValue = status;
status = ReportStatus.COMPLETE;
statusMessageLabel.setForeground(Color.BLACK);
statusMessageLabel.setText(NbBundle.getMessage(this.getClass(), "ReportProgressDialog.complete.processLbl.text"));
statusMessageLabel.setText(statusMessage);
reportProgressBar.setValue(reportProgressBar.getMaximum());
reportProgressBar.setStringPainted(true);
reportProgressBar.setForeground(GREEN);
@ -234,7 +257,7 @@ class ReportProgressDialog extends javax.swing.JPanel implements ReportProgressP
ReportStatus oldValue = status;
status = ReportStatus.ERROR;
statusMessageLabel.setForeground(RED);
statusMessageLabel.setText(NbBundle.getMessage(this.getClass(), "ReportProgressDialog.complete.processLb2.text"));
statusMessageLabel.setText(statusMessage);
reportProgressBar.setValue(reportProgressBar.getMaximum());
reportProgressBar.setStringPainted(true);
reportProgressBar.setForeground(RED);

View File

@ -104,9 +104,13 @@ public class ReportProgressLogger implements ReportProgressPanel {
* Logs the final status of the report generation.
*
* @param reportStatus The final status, must be COMPLETE or ERROR.
* @param statusMessage String to use as label or error text.
*/
@Override
public void complete(ReportStatus reportStatus) {
public void complete(ReportStatus reportStatus, String statusMessage) {
if (!statusMessage.isEmpty()) {
logger.log(Level.INFO, statusMessage);
}
if (status != ReportStatus.CANCELED) {
switch (reportStatus) {
case COMPLETE: {
@ -126,6 +130,16 @@ public class ReportProgressLogger implements ReportProgressPanel {
}
}
/**
* Logs the final status of the report generation.
*
* @param reportStatus The final status, must be COMPLETE or ERROR.
*/
@Override
public void complete(ReportStatus reportStatus) {
complete(reportStatus, "");
}
/**
* Logs that the generation of the report was cancelled.
*/

View File

@ -79,13 +79,16 @@ public final class CaseUcoFormatExporter {
* @param progressPanel ReportProgressPanel to update progress
*/
@NbBundle.Messages({
"ReportCaseUco.noCaseOpen=Unable to open currect case",
"ReportCaseUco.unableToCreateDirectories=Unable to create directory for CASE-UCO report",
"ReportCaseUco.initializing=Creating directories...",
"ReportCaseUco.querying=Querying files...",
"ReportCaseUco.ingestWarning=Warning, this report will be created before ingest services completed",
"ReportCaseUco.datasourceMsg=Generating CASE-UCO Report for %s",
"ReportCaseUco.srcModuleName.text=CASE-UCO Report"
"ReportCaseUco.srcModuleName.text=CASE-UCO Report",
"ReportCaseUco.databaseError=Failed to get list of files from case database",
"ReportCaseUco.jsonError=Failed to create JSON output for the CASE-UCO report",
"ReportCaseUco.resultSetError=Unable to read result set",
"ReportCaseUco.noOpenCase=No current case open"
})
@SuppressWarnings("deprecation")
public static void generateReport(String reportOutputPath, ReportProgressPanel progressPanel) {
@ -102,8 +105,7 @@ public final class CaseUcoFormatExporter {
Files.createDirectories(Paths.get(reportFile.getParent()));
} catch (IOException ex) {
logger.log(Level.SEVERE, "Unable to create directory for CASE-UCO report", ex); //NON-NLS
progressPanel.updateStatusLabel(Bundle.ReportCaseUco_unableToCreateDirectories());
progressPanel.complete(ReportProgressPanel.ReportStatus.ERROR);
progressPanel.complete(ReportProgressPanel.ReportStatus.ERROR, Bundle.ReportCaseUco_unableToCreateDirectories());
return;
}
@ -178,17 +180,17 @@ public final class CaseUcoFormatExporter {
progressPanel.complete(ReportProgressPanel.ReportStatus.COMPLETE);
} catch (TskCoreException ex) {
logger.log(Level.SEVERE, "Failed to get list of files from case database", ex); //NON-NLS
progressPanel.complete(ReportProgressPanel.ReportStatus.ERROR);
logger.log(Level.SEVERE, Bundle.ReportCaseUco_databaseError(), ex); //NON-NLS
progressPanel.complete(ReportProgressPanel.ReportStatus.ERROR, Bundle.ReportCaseUco_databaseError());
} catch (IOException ex) {
logger.log(Level.SEVERE, "Failed to create JSON output for the CASE-UCO report", ex); //NON-NLS
progressPanel.complete(ReportProgressPanel.ReportStatus.ERROR);
logger.log(Level.SEVERE, Bundle.ReportCaseUco_jsonError(), ex); //NON-NLS
progressPanel.complete(ReportProgressPanel.ReportStatus.ERROR, Bundle.ReportCaseUco_jsonError());
} catch (SQLException ex) {
logger.log(Level.WARNING, "Unable to read result set", ex); //NON-NLS
progressPanel.complete(ReportProgressPanel.ReportStatus.ERROR);
logger.log(Level.WARNING, Bundle.ReportCaseUco_resultSetError(), ex); //NON-NLS
progressPanel.complete(ReportProgressPanel.ReportStatus.ERROR, Bundle.ReportCaseUco_resultSetError());
} catch (NoCurrentCaseException ex) {
logger.log(Level.SEVERE, "No current case open", ex); //NON-NLS
progressPanel.complete(ReportProgressPanel.ReportStatus.ERROR);
logger.log(Level.SEVERE, Bundle.ReportCaseUco_noOpenCase(), ex); //NON-NLS
progressPanel.complete(ReportProgressPanel.ReportStatus.ERROR, Bundle.ReportCaseUco_noOpenCase());
} finally {
if (jsonGenerator != null) {
try {

View File

@ -101,6 +101,24 @@ class KMLReport implements GeneralReportModule {
* @param baseReportDir path to save the report
* @param progressPanel panel to update the report's progress
*/
@NbBundle.Messages({
"KMLReport.unableToExtractPhotos=Could not extract photo information.",
"KMLReport.exifPhotoError=Could not extract photos with EXIF metadata.",
"KMLReport.bookmarkError=Could not extract Bookmark information.",
"KMLReport.gpsBookmarkError=Could not get GPS Bookmarks from database.",
"KMLReport.locationError=Could not extract Last Known Location information.",
"KMLReport.locationDatabaseError=Could not get GPS Last Known Location from database.",
"KMLReport.gpsRouteError=Could not extract GPS Route information.",
"KMLReport.gpsRouteDatabaseError=Could not get GPS Routes from database.",
"KMLReport.gpsSearchDatabaseError=Could not get GPS Searches from database.",
"KMLReport.trackpointError=Could not extract Trackpoint information.",
"KMLReport.trackpointDatabaseError=Could not get GPS Trackpoints from database.",
"KMLReport.stylesheetError=Error placing KML stylesheet. The .KML file will not function properly.",
"KMLReport.kmlFileWriteError=Could not write the KML file.",
"# {0} - filePath",
"KMLReport.errorGeneratingReport=Error adding {0} to case as a report.",
"KMLReport.unableToOpenCase=Exception while getting open case."
})
@Override
public void generateReport(String baseReportDir, ReportProgressPanel progressPanel) {
try {
@ -114,6 +132,7 @@ class KMLReport implements GeneralReportModule {
progressPanel.start();
progressPanel.updateStatusLabel(NbBundle.getMessage(this.getClass(), "ReportKML.progress.querying"));
String kmlFileFullPath = baseReportDir + REPORT_KML; //NON-NLS
String errorMessage = "";
skCase = currentCase.getSleuthkitCase();
@ -235,12 +254,14 @@ class KMLReport implements GeneralReportModule {
} catch (ReadContentInputStreamException ex) {
logger.log(Level.WARNING, String.format("Error reading file '%s' (id=%d).", fileName, fileId), ex);
} catch (Exception ex) {
logger.log(Level.SEVERE, "Could not extract photo information.", ex); //NON-NLS
errorMessage = Bundle.KMLReport_unableToExtractPhotos();
logger.log(Level.SEVERE, errorMessage, ex); //NON-NLS
result = ReportProgressPanel.ReportStatus.ERROR;
}
}
} catch (TskCoreException ex) {
logger.log(Level.SEVERE, "Could not extract photos with EXIF metadata.", ex); //NON-NLS
errorMessage = Bundle.KMLReport_exifPhotoError();
logger.log(Level.SEVERE, errorMessage, ex); //NON-NLS
result = ReportProgressPanel.ReportStatus.ERROR;
}
@ -256,12 +277,14 @@ class KMLReport implements GeneralReportModule {
String formattedCoordinates = String.format("%.2f, %.2f", lat, lon);
gpsBookmarksFolder.addContent(makePlacemark(bookmarkName, FeatureColor.BLUE, desc, timestamp, point, formattedCoordinates));
} catch (Exception ex) {
logger.log(Level.SEVERE, "Could not extract Bookmark information.", ex); //NON-NLS
errorMessage = Bundle.KMLReport_bookmarkError();
logger.log(Level.SEVERE, errorMessage, ex); //NON-NLS
result = ReportProgressPanel.ReportStatus.ERROR;
}
}
} catch (TskCoreException ex) {
logger.log(Level.SEVERE, "Could not get GPS Bookmarks from database.", ex); //NON-NLS
errorMessage = Bundle.KMLReport_gpsBookmarkError();
logger.log(Level.SEVERE, errorMessage, ex); //NON-NLS
result = ReportProgressPanel.ReportStatus.ERROR;
}
@ -277,12 +300,14 @@ class KMLReport implements GeneralReportModule {
String formattedCoordinates = String.format("%.2f, %.2f", lat, lon);
gpsLastKnownLocationFolder.addContent(makePlacemark("Last Known Location", FeatureColor.PURPLE, desc, timestamp, point, formattedCoordinates)); //NON-NLS
} catch (Exception ex) {
logger.log(Level.SEVERE, "Could not extract Last Known Location information.", ex); //NON-NLS
errorMessage = Bundle.KMLReport_locationError();
logger.log(Level.SEVERE, errorMessage, ex); //NON-NLS
result = ReportProgressPanel.ReportStatus.ERROR;
}
}
} catch (TskCoreException ex) {
logger.log(Level.SEVERE, "Could not get GPS Last Known Location from database.", ex); //NON-NLS
errorMessage = Bundle.KMLReport_locationDatabaseError();
logger.log(Level.SEVERE, errorMessage, ex); //NON-NLS
result = ReportProgressPanel.ReportStatus.ERROR;
}
@ -310,12 +335,14 @@ class KMLReport implements GeneralReportModule {
formattedCoordinates = String.format("%.2f, %.2f", latitudeEnd, longitudeEnd);
gpsRouteFolder.addContent(makePlacemark("End", FeatureColor.GREEN, desc, timestamp, endingPoint, formattedCoordinates)); //NON-NLS
} catch (Exception ex) {
logger.log(Level.SEVERE, "Could not extract GPS Route information.", ex); //NON-NLS
errorMessage = Bundle.KMLReport_gpsRouteError();
logger.log(Level.SEVERE, errorMessage, ex); //NON-NLS
result = ReportProgressPanel.ReportStatus.ERROR;
}
}
} catch (TskCoreException ex) {
logger.log(Level.SEVERE, "Could not get GPS Routes from database.", ex); //NON-NLS
errorMessage = Bundle.KMLReport_gpsRouteDatabaseError();
logger.log(Level.SEVERE, errorMessage, ex); //NON-NLS
result = ReportProgressPanel.ReportStatus.ERROR;
}
@ -338,7 +365,8 @@ class KMLReport implements GeneralReportModule {
gpsSearchesFolder.addContent(makePlacemark(searchName, FeatureColor.WHITE, desc, timestamp, point, formattedCoordinates)); //NON-NLS
}
} catch (TskCoreException ex) {
logger.log(Level.SEVERE, "Could not get GPS Searches from database.", ex); //NON-NLS
errorMessage = Bundle.KMLReport_gpsSearchDatabaseError();
logger.log(Level.SEVERE, errorMessage, ex); //NON-NLS
result = ReportProgressPanel.ReportStatus.ERROR;
}
@ -364,12 +392,14 @@ class KMLReport implements GeneralReportModule {
}
gpsTrackpointsFolder.addContent(makePlacemark(trackName, FeatureColor.YELLOW, desc, timestamp, point, formattedCoordinates));
} catch (Exception ex) {
logger.log(Level.SEVERE, "Could not extract Trackpoint information.", ex); //NON-NLS
errorMessage = Bundle.KMLReport_trackpointError();
logger.log(Level.SEVERE, errorMessage, ex); //NON-NLS
result = ReportProgressPanel.ReportStatus.ERROR;
}
}
} catch (TskCoreException ex) {
logger.log(Level.SEVERE, "Could not get GPS Trackpoints from database.", ex); //NON-NLS
errorMessage = Bundle.KMLReport_trackpointDatabaseError();
logger.log(Level.SEVERE, errorMessage, ex); //NON-NLS
result = ReportProgressPanel.ReportStatus.ERROR;
}
@ -379,7 +409,8 @@ class KMLReport implements GeneralReportModule {
OutputStream output = new FileOutputStream(baseReportDir + KML_STYLE_FILE); // Preserve slash direction
FileUtil.copy(input, output);
} catch (IOException ex) {
logger.log(Level.SEVERE, "Error placing KML stylesheet. The .KML file will not function properly.", ex); //NON-NLS
errorMessage = Bundle.KMLReport_stylesheetError();
logger.log(Level.SEVERE, errorMessage, ex); //NON-NLS
result = ReportProgressPanel.ReportStatus.ERROR;
}
@ -394,18 +425,20 @@ class KMLReport implements GeneralReportModule {
NbBundle.getMessage(this.getClass(), "ReportKML.genReport.srcModuleName.text"),
prependedStatus + NbBundle.getMessage(this.getClass(), "ReportKML.genReport.reportName"));
} catch (IOException ex) {
logger.log(Level.SEVERE, "Could not write the KML file.", ex); //NON-NLS
progressPanel.complete(ReportProgressPanel.ReportStatus.ERROR);
errorMessage = Bundle.KMLReport_kmlFileWriteError();
logger.log(Level.SEVERE, errorMessage, ex); //NON-NLS
progressPanel.complete(ReportProgressPanel.ReportStatus.ERROR, errorMessage);
} catch (TskCoreException ex) {
String errorMessage = String.format("Error adding %s to case as a report", kmlFileFullPath); //NON-NLS
errorMessage = Bundle.KMLReport_errorGeneratingReport(kmlFileFullPath);
logger.log(Level.SEVERE, errorMessage, ex);
result = ReportProgressPanel.ReportStatus.ERROR;
} catch (NoCurrentCaseException ex) {
logger.log(Level.SEVERE, "Exception while getting open case.", ex);
errorMessage = Bundle.KMLReport_unableToOpenCase();
logger.log(Level.SEVERE, errorMessage, ex);
result = ReportProgressPanel.ReportStatus.ERROR;
}
progressPanel.complete(result);
progressPanel.complete(result, errorMessage);
}
/**

View File

@ -160,9 +160,8 @@ public class PortableCaseReportModule implements ReportModule {
} else {
logger.log(Level.SEVERE, logWarning, ex);
}
progressPanel.updateStatusLabel(dialogWarning);
progressPanel.setIndeterminate(false);
progressPanel.complete(ReportProgressPanel.ReportStatus.ERROR);
progressPanel.complete(ReportProgressPanel.ReportStatus.ERROR, dialogWarning);
cleanup();
}

View File

@ -115,17 +115,13 @@ public class STIXReportModule implements GeneralReportModule {
if (stixFileName == null) {
logger.log(Level.SEVERE, "STIXReportModuleConfigPanel.stixFile not initialized "); //NON-NLS
progressPanel.complete(ReportStatus.ERROR);
progressPanel.updateStatusLabel(
NbBundle.getMessage(this.getClass(), "STIXReportModule.progress.noFildDirProvided"));
progressPanel.complete(ReportStatus.ERROR, NbBundle.getMessage(this.getClass(), "STIXReportModule.progress.noFildDirProvided"));
new File(baseReportDir).delete();
return;
}
if (stixFileName.isEmpty()) {
logger.log(Level.SEVERE, "No STIX file/directory provided "); //NON-NLS
progressPanel.complete(ReportStatus.ERROR);
progressPanel.updateStatusLabel(
NbBundle.getMessage(this.getClass(), "STIXReportModule.progress.noFildDirProvided"));
progressPanel.complete(ReportStatus.ERROR, NbBundle.getMessage(this.getClass(), "STIXReportModule.progress.noFildDirProvided"));
new File(baseReportDir).delete();
return;
}
@ -133,9 +129,7 @@ public class STIXReportModule implements GeneralReportModule {
if (!stixFile.exists()) {
logger.log(Level.SEVERE, String.format("Unable to open STIX file/directory %s", stixFileName)); //NON-NLS
progressPanel.complete(ReportStatus.ERROR);
progressPanel.updateStatusLabel(
NbBundle.getMessage(this.getClass(), "STIXReportModule.progress.couldNotOpenFileDir", stixFileName));
progressPanel.complete(ReportStatus.ERROR, NbBundle.getMessage(this.getClass(), "STIXReportModule.progress.couldNotOpenFileDir", stixFileName));
new File(baseReportDir).delete();
return;
}
@ -177,17 +171,13 @@ public class STIXReportModule implements GeneralReportModule {
// the "complete" message to indicate this.
Case.getCurrentCaseThrows().addReport(reportPath, Bundle.STIXReportModule_srcModuleName_text(), "");
if (hadErrors) {
progressPanel.complete(ReportStatus.ERROR);
progressPanel.updateStatusLabel(
NbBundle.getMessage(this.getClass(), "STIXReportModule.progress.completedWithErrors"));
progressPanel.complete(ReportStatus.ERROR, NbBundle.getMessage(this.getClass(), "STIXReportModule.progress.completedWithErrors"));
} else {
progressPanel.complete(ReportStatus.COMPLETE);
}
} catch (IOException ex) {
logger.log(Level.SEVERE, "Unable to complete STIX report.", ex); //NON-NLS
progressPanel.complete(ReportStatus.ERROR);
progressPanel.updateStatusLabel(
NbBundle.getMessage(this.getClass(), "STIXReportModule.progress.completedWithErrors"));
progressPanel.complete(ReportStatus.ERROR, NbBundle.getMessage(this.getClass(), "STIXReportModule.progress.completedWithErrors"));
} catch (TskCoreException | NoCurrentCaseException ex) {
logger.log(Level.SEVERE, "Unable to add report to database.", ex);
}

View File

@ -111,6 +111,7 @@ public class SaveTaggedHashesToHashDb implements GeneralReportModule {
@Messages({
"AddTaggedHashesToHashDb.error.noHashSetsSelected=No hash set selected for export.",
"AddTaggedHashesToHashDb.error.unableToOpenCase=Exception while getting open case.",
"AddTaggedHashesToHashDb.error.noTagsSelected=No tags selected for export."
})
@Override
@ -120,8 +121,7 @@ public class SaveTaggedHashesToHashDb implements GeneralReportModule {
openCase = Case.getCurrentCaseThrows();
} catch (NoCurrentCaseException ex) {
Logger.getLogger(SaveTaggedHashesToHashDb.class.getName()).log(Level.SEVERE, "Exception while getting open case.", ex);
progressPanel.updateStatusLabel("Exception while getting open case.");
progressPanel.complete(ReportProgressPanel.ReportStatus.ERROR);
progressPanel.complete(ReportProgressPanel.ReportStatus.ERROR, Bundle.AddTaggedHashesToHashDb_error_unableToOpenCase());
return;
}
progressPanel.setIndeterminate(true);
@ -131,9 +131,8 @@ public class SaveTaggedHashesToHashDb implements GeneralReportModule {
HashDb hashSet = configPanel.getSelectedHashDatabase();
if (hashSet == null) {
logger.log(Level.WARNING, "No hash set selected for export."); //NON-NLS
progressPanel.updateStatusLabel(Bundle.AddTaggedHashesToHashDb_error_noHashSetsSelected());
progressPanel.setIndeterminate(false);
progressPanel.complete(ReportProgressPanel.ReportStatus.ERROR);
progressPanel.complete(ReportProgressPanel.ReportStatus.ERROR, Bundle.AddTaggedHashesToHashDb_error_noHashSetsSelected());
return;
}
@ -143,9 +142,8 @@ public class SaveTaggedHashesToHashDb implements GeneralReportModule {
List<TagName> tagNames = configPanel.getSelectedTagNames();
if (tagNames.isEmpty()) {
logger.log(Level.WARNING, "No tags selected for export."); //NON-NLS
progressPanel.updateStatusLabel(Bundle.AddTaggedHashesToHashDb_error_noTagsSelected());
progressPanel.setIndeterminate(false);
progressPanel.complete(ReportProgressPanel.ReportStatus.ERROR);
progressPanel.complete(ReportProgressPanel.ReportStatus.ERROR, Bundle.AddTaggedHashesToHashDb_error_noTagsSelected());
return;
}