Merge pull request #1294 from karlmortensen/warn_user_nicely

Warn user nicely
This commit is contained in:
Richard Cordovano 2015-06-04 11:46:45 -04:00
commit c80f81f073
3 changed files with 110 additions and 12 deletions

View File

@ -152,6 +152,9 @@ CaseOpenAction.msgDlg.fileNotExist.title=Error
CaseOpenAction.msgDlg.cantOpenCase.msg=Error\: could not open the case in folder {0}\: {1}
CaseOpenAction.msgDlg.cantOpenCase.title=Error
CaseCreateAction.msgDlg.cantCreateCase.msg=Cannot create case
IntervalErrorReport.NewIssues=new issue(s)
IntervalErrorReport.TotalIssues=total issue(s)
IntervalErrorReport.ErrorText=Database Connection Error
CasePropertiesAction.window.title=Case Properties
CasePropertiesForm.updateCaseName.msgDlg.empty.msg=The caseName cannot be empty.
CasePropertiesForm.updateCaseName.msgDlg.empty.title=Error

View File

@ -75,6 +75,7 @@ public class Case {
private static final String autopsyVer = Version.getVersion(); // current version of autopsy. Change it when the version is changed
private static final String EVENT_CHANNEL_NAME = "%s-Case-Events";
private static String appName = null;
private static IntervalErrorReportData tskErrorReporter = null;
/**
* Name for the property that determines whether to show the dialog at
@ -218,13 +219,6 @@ public class Case {
this.services = new Services(db);
}
/**
* Does initialization that would leak a reference to this if done in the
* constructor.
*/
private void init() {
}
/**
* Gets the currently opened case, if there is one.
*
@ -257,6 +251,8 @@ public class Case {
*
*/
private static void changeCase(Case newCase) {
// force static initialization of error reporter
tskErrorReporter = IntervalErrorReportData.getInstance();
// close the existing case
Case oldCase = Case.currentCase;
Case.currentCase = null;
@ -373,8 +369,6 @@ public class Case {
* constructor.
*/
Case newCase = new Case(caseName, caseNumber, examiner, configFilePath, xmlcm, db, caseType);
newCase.init();
changeCase(newCase);
}
@ -433,8 +427,6 @@ public class Case {
* constructor.
*/
Case openedCase = new Case(caseName, caseNumber, examiner, configFilePath, xmlcm, db, caseType);
openedCase.init();
changeCase(openedCase);
} catch (Exception ex) {

View File

@ -0,0 +1,103 @@
/*
* Autopsy Forensic Browser
*
* Copyright 2011-2015 Basis Technology Corp.
* Contact: carrier <at> sleuthkit <dot> org
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.sleuthkit.autopsy.casemodule;
import org.openide.util.NbBundle;
import org.sleuthkit.autopsy.coreutils.MessageNotifyUtil;
import org.sleuthkit.datamodel.SleuthkitCase;
/**
* This class enables capturing errors and batching them for reporting on a
* no-more-than-x number of seconds basis. When created, you specify what type
* of error it will be batching, and the minimum time between user
* notifications. When the time between notifications has expired, the next
* error encountered will cause a report to be shown to the user.
*/
class IntervalErrorReportData implements SleuthkitCase.ErrorObserver {
private static volatile IntervalErrorReportData instance;
private long newProblems;
private long totalProblems;
private long lastReportedDate;
private final int milliSecondsBetweenReports;
private final String message;
/**
* Create a new IntervalErrorReprotData instance.
*
* @param secondsBetweenReports Minimum number of seconds between reports.
* It will not warn more frequently than this.
* @param message The message that will be shown when warning the user
*/
private IntervalErrorReportData(int secondsBetweenReports, String message) {
this.newProblems = 0;
this.totalProblems = 0;
this.lastReportedDate = 0; // arm the first warning by choosing zero
this.milliSecondsBetweenReports = secondsBetweenReports * 1000; // convert to milliseconds
this.message = message;
SleuthkitCase.addErrorObserver(this);
}
/**
* Returns the singleton instance of this object
*
* @return the singleton instance of this object
*/
public static IntervalErrorReportData getInstance() {
if (instance == null) {
synchronized (IntervalErrorReportData.class) {
if (instance == null) {
instance = new IntervalErrorReportData(60, // No less than 60 seconds between warnings for errors
NbBundle.getMessage(Case.class, "IntervalErrorReport.ErrorText"));
}
}
}
return instance;
}
/**
* Call this to add problems to the class. When the time threshold is met
* (or if this is the first problem encountered), a warning will be shown to
* the user.
*
* @param newProblems the newProblems to set
* @param ex the exception for this error
*/
private void addProblems(long newProblems, Exception ex) {
this.newProblems += newProblems;
this.totalProblems += newProblems;
long currentTimeStamp = System.currentTimeMillis();
if ((currentTimeStamp - lastReportedDate) > milliSecondsBetweenReports) {
this.lastReportedDate = currentTimeStamp;
MessageNotifyUtil.Notify.error(message, ex.getMessage() + " "
+ this.newProblems + " "
+ NbBundle.getMessage(IntervalErrorReportData.class, "IntervalErrorReport.NewIssues")
+ " " + this.totalProblems + " "
+ NbBundle.getMessage(IntervalErrorReportData.class, "IntervalErrorReport.TotalIssues")
+ ".");
this.newProblems = 0;
}
}
@Override
public void receiveError(Exception ex) {
addProblems(1, ex);
}
}