19 package org.sleuthkit.autopsy.casemodule;
 
   22 import com.google.common.annotations.Beta;
 
   23 import com.google.common.eventbus.Subscribe;
 
   25 import java.awt.Frame;
 
   26 import java.awt.event.ActionEvent;
 
   27 import java.awt.event.ActionListener;
 
   28 import java.beans.PropertyChangeListener;
 
   29 import java.beans.PropertyChangeSupport;
 
   31 import java.nio.file.InvalidPathException;
 
   32 import java.nio.file.Path;
 
   33 import java.nio.file.Paths;
 
   34 import java.sql.Connection;
 
   35 import java.sql.DriverManager;
 
   36 import java.sql.ResultSet;
 
   37 import java.sql.SQLException;
 
   38 import java.sql.Statement;
 
   39 import java.text.SimpleDateFormat;
 
   40 import java.util.Collection;
 
   41 import java.util.Date;
 
   42 import java.util.HashMap;
 
   43 import java.util.HashSet;
 
   44 import java.util.List;
 
   47 import java.util.TimeZone;
 
   48 import java.util.UUID;
 
   49 import java.util.concurrent.CancellationException;
 
   50 import java.util.concurrent.ExecutionException;
 
   51 import java.util.concurrent.ExecutorService;
 
   52 import java.util.concurrent.Executors;
 
   53 import java.util.concurrent.Future;
 
   54 import java.util.concurrent.ThreadFactory;
 
   55 import java.util.concurrent.TimeUnit;
 
   56 import java.util.logging.Level;
 
   57 import java.util.stream.Collectors;
 
   58 import java.util.stream.Stream;
 
   59 import javax.annotation.concurrent.GuardedBy;
 
   60 import javax.annotation.concurrent.ThreadSafe;
 
   61 import javax.swing.JOptionPane;
 
   62 import javax.swing.SwingUtilities;
 
   63 import org.openide.util.Lookup;
 
   64 import org.openide.util.NbBundle;
 
   65 import org.openide.util.NbBundle.Messages;
 
   66 import org.openide.util.actions.CallableSystemAction;
 
   67 import org.openide.windows.WindowManager;
 
  135 import org.
sleuthkit.datamodel.TskUnsupportedSchemaVersionException;
 
  175         WindowManager.getDefault().invokeWhenUIReady(() -> {
 
  176             mainFrame = WindowManager.getDefault().getMainWindow();
 
  198             if (typeName != null) {
 
  200                     if (typeName.equalsIgnoreCase(c.toString())) {
 
  224             "Case_caseType_singleUser=Single-user case",
 
  225             "Case_caseType_multiUser=Multi-user case" 
  228             if (fromString(typeName) == SINGLE_USER_CASE) {
 
  229                 return Bundle.Case_caseType_singleUser();
 
  231                 return Bundle.Case_caseType_multiUser();
 
  241             this.typeName = typeName;
 
  256             return (otherTypeName == null) ? 
false : typeName.equals(otherTypeName);
 
  423         @SuppressWarnings(
"deprecation")
 
  426             for (BlackboardArtifact.Type artifactType : event.getArtifactTypes()) {
 
  436                         event.getModuleName(),
 
  438                         event.getArtifacts(artifactType)));
 
  451                 .map(Events::toString)
 
  452                 .collect(Collectors.toSet()), listener);
 
  463                 .map(Events::toString)
 
  464                 .collect(Collectors.toSet()), listener);
 
  487         eventTypes.forEach((
Events event) -> {
 
  532         eventTypes.forEach((
Events event) -> {
 
  546         return !(caseName.contains(
"\\") || caseName.contains(
"/") || caseName.contains(
":")
 
  547                 || caseName.contains(
"*") || caseName.contains(
"?") || caseName.contains(
"\"")
 
  548                 || caseName.contains(
"<") || caseName.contains(
">") || caseName.contains(
"|"));
 
  600         "Case.exceptionMessage.emptyCaseName=Must specify a case name.",
 
  601         "Case.exceptionMessage.emptyCaseDir=Must specify a case directory path." 
  605             throw new CaseActionException(Bundle.Case_exceptionMessage_emptyCaseName());
 
  607         if (caseDir.isEmpty()) {
 
  608             throw new CaseActionException(Bundle.Case_exceptionMessage_emptyCaseDir());
 
  627         "# {0} - exception message", 
"Case.exceptionMessage.failedToReadMetadata=Failed to read case metadata:\n{0}.",
 
  628         "Case.exceptionMessage.cannotOpenMultiUserCaseNoSettings=Multi-user settings are missing (see Tools, Options, Multi-user tab), cannot open a multi-user case." 
  633             metadata = 
new CaseMetadata(Paths.get(caseMetadataFilePath));
 
  635             throw new CaseActionException(Bundle.Case_exceptionMessage_failedToReadMetadata(ex.getLocalizedMessage()), ex);
 
  638             throw new CaseActionException(Bundle.Case_exceptionMessage_cannotOpenMultiUserCaseNoSettings());
 
  649         return currentCase != null;
 
  666             throw new IllegalStateException(NbBundle.getMessage(
Case.class, 
"Case.getCurCase.exception.noneOpen"), ex);
 
  690         if (openCase == null) {
 
  691             throw new NoCurrentCaseException(NbBundle.getMessage(
Case.class, 
"Case.getCurCase.exception.noneOpen"));
 
  706         "# {0} - exception message", 
"Case.closeException.couldNotCloseCase=Error closing case: {0}",
 
  707         "Case.progressIndicatorTitle.closingCase=Closing Case" 
  711             if (null == currentCase) {
 
  717                 logger.log(Level.INFO, 
"Closing current case {0} ({1}) in {2}", 
new Object[]{closedCase.getDisplayName(), closedCase.getName(), closedCase.getCaseDirectory()}); 
 
  720                 logger.log(Level.INFO, 
"Closed current case {0} ({1}) in {2}", 
new Object[]{closedCase.getDisplayName(), closedCase.getName(), closedCase.getCaseDirectory()}); 
 
  721             } 
catch (CaseActionException ex) {
 
  742             if (null == currentCase) {
 
  762         "Case.progressIndicatorTitle.deletingDataSource=Removing Data Source" 
  764     static void deleteDataSourceFromCurrentCase(Long dataSourceObjectID) 
throws CaseActionException {
 
  766             if (null == currentCase) {
 
  773             CaseMetadata caseMetadata = currentCase.getMetadata();
 
  781             Case theCase = 
new Case(caseMetadata);
 
  782             theCase.doOpenCaseAction(Bundle.Case_progressIndicatorTitle_deletingDataSource(), theCase::deleteDataSource, CaseLockType.EXCLUSIVE, 
false, dataSourceObjectID);
 
  803         "Case.progressIndicatorTitle.deletingCase=Deleting Case",
 
  804         "Case.exceptionMessage.cannotDeleteCurrentCase=Cannot delete current case, it must be closed first.",
 
  805         "# {0} - case display name", 
"Case.exceptionMessage.deletionInterrupted=Deletion of the case {0} was cancelled." 
  809             if (null != currentCase) {
 
  810                 throw new CaseActionException(Bundle.Case_exceptionMessage_cannotDeleteCurrentCase());
 
  820         progressIndicator.
start(Bundle.Case_progressMessage_preparing());
 
  827                 } 
catch (InterruptedException ex) {
 
  833                     throw new CaseActionException(Bundle.Case_exceptionMessage_deletionInterrupted(metadata.
getCaseDisplayName()), ex);
 
  837             progressIndicator.
finish();
 
  852         "Case.progressIndicatorTitle.creatingCase=Creating Case",
 
  853         "Case.progressIndicatorTitle.openingCase=Opening Case",
 
  854         "Case.exceptionMessage.cannotLocateMainWindow=Cannot locate main application window" 
  858             if (null != currentCase) {
 
  861                 } 
catch (CaseActionException ex) {
 
  870                 logger.log(Level.INFO, 
"Opening {0} ({1}) in {2} as the current case", 
new Object[]{newCurrentCase.getDisplayName(), newCurrentCase.getName(), newCurrentCase.getCaseDirectory()}); 
 
  871                 String progressIndicatorTitle;
 
  874                     progressIndicatorTitle = Bundle.Case_progressIndicatorTitle_creatingCase();
 
  875                     openCaseAction = newCurrentCase::create;
 
  877                     progressIndicatorTitle = Bundle.Case_progressIndicatorTitle_openingCase();
 
  878                     openCaseAction = newCurrentCase::open;
 
  881                 currentCase = newCurrentCase;
 
  882                 logger.log(Level.INFO, 
"Opened {0} ({1}) in {2} as the current case", 
new Object[]{newCurrentCase.getDisplayName(), newCurrentCase.getName(), newCurrentCase.getCaseDirectory()}); 
 
  888                 logger.log(Level.INFO, String.format(
"Cancelled opening %s (%s) in %s as the current case", newCurrentCase.
getDisplayName(), newCurrentCase.
getName(), newCurrentCase.
getCaseDirectory())); 
 
  890             } 
catch (CaseActionException ex) {
 
  891                 logger.log(Level.SEVERE, String.format(
"Error opening %s (%s) in %s as the current case", newCurrentCase.
getDisplayName(), newCurrentCase.
getName(), newCurrentCase.
getCaseDirectory()), ex); 
 
  909         String uniqueCaseName = caseDisplayName.replaceAll(
"[^\\p{ASCII}]", 
"_"); 
 
  914         uniqueCaseName = uniqueCaseName.replaceAll(
"[\\p{Cntrl}]", 
"_"); 
 
  919         uniqueCaseName = uniqueCaseName.replaceAll(
"[ /?:'\"\\\\]", 
"_"); 
 
  924         uniqueCaseName = uniqueCaseName.toLowerCase();
 
  929         SimpleDateFormat dateFormat = 
new SimpleDateFormat(
"yyyyMMdd_HHmmss");
 
  930         Date date = 
new Date();
 
  931         uniqueCaseName = uniqueCaseName + 
"_" + dateFormat.format(date);
 
  933         return uniqueCaseName;
 
  950         File caseDir = 
new File(caseDirPath);
 
  951         if (caseDir.exists()) {
 
  952             if (caseDir.isFile()) {
 
  953                 throw new CaseActionException(NbBundle.getMessage(
Case.class, 
"Case.createCaseDir.exception.existNotDir", caseDirPath));
 
  954             } 
else if (!caseDir.canRead() || !caseDir.canWrite()) {
 
  955                 throw new CaseActionException(NbBundle.getMessage(
Case.class, 
"Case.createCaseDir.exception.existCantRW", caseDirPath));
 
  962         if (!caseDir.mkdirs()) {
 
  963             throw new CaseActionException(NbBundle.getMessage(
Case.class, 
"Case.createCaseDir.exception.cantCreate", caseDirPath));
 
  971         String hostPathComponent = 
"";
 
  976         Path exportDir = Paths.get(caseDirPath, hostPathComponent, EXPORT_FOLDER);
 
  977         if (!exportDir.toFile().mkdirs()) {
 
  978             throw new CaseActionException(NbBundle.getMessage(
Case.class, 
"Case.createCaseDir.exception.cantCreateCaseDir", exportDir));
 
  981         Path logsDir = Paths.get(caseDirPath, hostPathComponent, LOG_FOLDER);
 
  982         if (!logsDir.toFile().mkdirs()) {
 
  983             throw new CaseActionException(NbBundle.getMessage(
Case.class, 
"Case.createCaseDir.exception.cantCreateCaseDir", logsDir));
 
  986         Path tempDir = Paths.get(caseDirPath, hostPathComponent, TEMP_FOLDER);
 
  987         if (!tempDir.toFile().mkdirs()) {
 
  988             throw new CaseActionException(NbBundle.getMessage(
Case.class, 
"Case.createCaseDir.exception.cantCreateCaseDir", tempDir));
 
  991         Path cacheDir = Paths.get(caseDirPath, hostPathComponent, CACHE_FOLDER);
 
  992         if (!cacheDir.toFile().mkdirs()) {
 
  993             throw new CaseActionException(NbBundle.getMessage(
Case.class, 
"Case.createCaseDir.exception.cantCreateCaseDir", cacheDir));
 
  996         Path moduleOutputDir = Paths.get(caseDirPath, hostPathComponent, MODULE_FOLDER);
 
  997         if (!moduleOutputDir.toFile().mkdirs()) {
 
  998             throw new CaseActionException(NbBundle.getMessage(
Case.class, 
"Case.createCaseDir.exception.cantCreateModDir", moduleOutputDir));
 
 1001         Path reportsDir = Paths.get(caseDirPath, hostPathComponent, REPORTS_FOLDER);
 
 1002         if (!reportsDir.toFile().mkdirs()) {
 
 1003             throw new CaseActionException(NbBundle.getMessage(
Case.class, 
"Case.createCaseDir.exception.cantCreateReportsDir", reportsDir));
 
 1014     static Map<Long, String> getImagePaths(SleuthkitCase db) {
 
 1015         Map<Long, String> imgPaths = 
new HashMap<>();
 
 1017             Map<Long, List<String>> imgPathsList = db.getImagePaths();
 
 1018             for (Map.Entry<Long, List<String>> entry : imgPathsList.entrySet()) {
 
 1019                 if (entry.getValue().size() > 0) {
 
 1020                     imgPaths.put(entry.getKey(), entry.getValue().get(0));
 
 1023         } 
catch (TskCoreException ex) {
 
 1024             logger.log(Level.SEVERE, 
"Error getting image paths", ex); 
 
 1040         "Case.creationException.couldNotAcquireResourcesLock=Failed to get lock on case resources" 
 1044             Path caseDirPath = Paths.get(caseDir);
 
 1048         } 
catch (InterruptedException ex) {
 
 1051             throw new CaseActionException(Bundle.Case_creationException_couldNotAcquireResourcesLock(), ex);
 
 1070             SwingUtilities.invokeLater(() -> {
 
 1076                 String backupDbPath = caseDb.getBackupDatabasePath();
 
 1077                 if (null != backupDbPath) {
 
 1078                     JOptionPane.showMessageDialog(
 
 1080                             NbBundle.getMessage(
Case.class, 
"Case.open.msgDlg.updated.msg", backupDbPath),
 
 1081                             NbBundle.getMessage(
Case.class, 
"Case.open.msgDlg.updated.title"),
 
 1082                             JOptionPane.INFORMATION_MESSAGE);
 
 1090                 Map<Long, String> imgPaths = getImagePaths(caseDb);
 
 1091                 for (Map.Entry<Long, String> entry : imgPaths.entrySet()) {
 
 1092                     long obj_id = entry.getKey();
 
 1093                     String path = entry.getValue();
 
 1096                         int response = JOptionPane.showConfirmDialog(
 
 1098                                 NbBundle.getMessage(
Case.class, 
"Case.checkImgExist.confDlg.doesntExist.msg", path),
 
 1099                                 NbBundle.getMessage(
Case.class, 
"Case.checkImgExist.confDlg.doesntExist.title"),
 
 1100                                 JOptionPane.YES_NO_OPTION);
 
 1101                         if (response == JOptionPane.YES_OPTION) {
 
 1102                             MissingImageDialog.makeDialog(obj_id, caseDb);
 
 1104                             logger.log(Level.SEVERE, 
"User proceeding with missing image files"); 
 
 1115                 CallableSystemAction.get(CaseDetailsAction.class).setEnabled(
true);
 
 1117                 CallableSystemAction.get(CaseDeleteAction.class).setEnabled(
true);
 
 1129                 RecentCases.getInstance().addRecentCase(newCurrentCase.
getDisplayName(), newCurrentCase.getMetadata().getFilePath().toString());
 
 1139                 if (newCurrentCase.
hasData()) {
 
 1158             SwingUtilities.invokeLater(() -> {
 
 1168                 CallableSystemAction.get(
AddImageAction.class).setEnabled(
false);
 
 1170                 CallableSystemAction.get(CaseDetailsAction.class).setEnabled(
false);
 
 1172                 CallableSystemAction.get(CaseDeleteAction.class).setEnabled(
false);
 
 1198         File tempFolder = 
new File(tempSubDirPath);
 
 1199         if (tempFolder.isDirectory()) {
 
 1200             File[] files = tempFolder.listFiles();
 
 1201             if (files.length > 0) {
 
 1202                 for (File file : files) {
 
 1203                     if (file.isDirectory()) {
 
 1335             hostPath = Paths.get(caseDirectory);
 
 1337         if (!hostPath.toFile().exists()) {
 
 1338             hostPath.toFile().mkdirs();
 
 1340         return hostPath.toString();
 
 1423             return path.subpath(path.getNameCount() - 2, path.getNameCount()).toString();
 
 1425             return path.subpath(path.getNameCount() - 1, path.getNameCount()).toString();
 
 1439         return caseDb.getRootObjects();
 
 1448         Set<TimeZone> timezones = 
new HashSet<>();
 
 1451                 final Content dataSource = c.getDataSource();
 
 1452                 if ((dataSource != null) && (dataSource instanceof Image)) {
 
 1453                     Image image = (Image) dataSource;
 
 1454                     timezones.add(TimeZone.getTimeZone(image.getTimeZone()));
 
 1457         } 
catch (TskCoreException ex) {
 
 1458             logger.log(Level.SEVERE, 
"Error getting data source time zones", ex); 
 
 1480         boolean hasDataSources = 
false;
 
 1483         } 
catch (TskCoreException ex) {
 
 1484             logger.log(Level.SEVERE, 
"Error accessing case database", ex); 
 
 1486         return hasDataSources;
 
 1593             logger.log(Level.WARNING, 
"Unable to send notifcation regarding comment change due to no current case being open", ex);
 
 1630     public void addReport(String localPath, String srcModuleName, String reportName) 
throws TskCoreException {
 
 1631         addReport(localPath, srcModuleName, reportName, null);
 
 1648     public Report 
addReport(String localPath, String srcModuleName, String reportName, Content parent) 
throws TskCoreException {
 
 1649         String normalizedLocalPath;
 
 1651             if (localPath.toLowerCase().contains(
"http:")) {
 
 1652                 normalizedLocalPath = localPath;
 
 1654                 normalizedLocalPath = Paths.get(localPath).normalize().toString();
 
 1656         } 
catch (InvalidPathException ex) {
 
 1657             String errorMsg = 
"Invalid local path provided: " + localPath; 
 
 1658             throw new TskCoreException(errorMsg, ex);
 
 1660         Report report = this.caseDb.addReport(normalizedLocalPath, srcModuleName, reportName, parent);
 
 1674         return this.caseDb.getAllReports();
 
 1685     public void deleteReports(Collection<? extends Report> reports) 
throws TskCoreException {
 
 1686         for (Report report : reports) {
 
 1687             this.caseDb.deleteReport(report);
 
 1709         "Case.exceptionMessage.metadataUpdateError=Failed to update case metadata" 
 1711     void updateCaseDetails(CaseDetails caseDetails) 
throws CaseActionException {
 
 1714             metadata.setCaseDetails(caseDetails);
 
 1715         } 
catch (CaseMetadataException ex) {
 
 1716             throw new CaseActionException(Bundle.Case_exceptionMessage_metadataUpdateError(), ex);
 
 1720                 CaseNodeData nodeData = CaseNodeData.readCaseNodeData(metadata.
getCaseDirectory());
 
 1722                 CaseNodeData.writeCaseNodeData(nodeData);
 
 1723             } 
catch (CaseNodeDataException | InterruptedException ex) {
 
 1724                 throw new CaseActionException(Bundle.Case_exceptionMessage_couldNotUpdateCaseNodeData(ex.getLocalizedMessage()), ex);
 
 1727         if (!oldCaseDetails.getCaseNumber().equals(caseDetails.
getCaseNumber())) {
 
 1728             eventPublisher.
publish(
new AutopsyEvent(Events.NUMBER.toString(), oldCaseDetails.getCaseNumber(), caseDetails.
getCaseNumber()));
 
 1730         if (!oldCaseDetails.getExaminerName().equals(caseDetails.
getExaminerName())) {
 
 1731             eventPublisher.
publish(
new AutopsyEvent(Events.NUMBER.toString(), oldCaseDetails.getExaminerName(), caseDetails.
getExaminerName()));
 
 1734             eventPublisher.
publish(
new AutopsyEvent(Events.NAME.toString(), oldCaseDetails.getCaseDisplayName(), caseDetails.
getCaseDisplayName()));
 
 1736         eventPublisher.
publish(
new AutopsyEvent(Events.CASE_DETAILS.toString(), oldCaseDetails, caseDetails));
 
 1737         if (RuntimeProperties.runningWithGUI()) {
 
 1738             SwingUtilities.invokeLater(() -> {
 
 1741                     RecentCases.getInstance().updateRecentCase(oldCaseDetails.getCaseDisplayName(), metadata.getFilePath().toString(), caseDetails.
getCaseDisplayName(), metadata.getFilePath().toString());
 
 1742                 } 
catch (Exception ex) {
 
 1743                     logger.log(Level.SEVERE, 
"Error updating case name in UI", ex); 
 
 1771         metadata = caseMetaData;
 
 1805         "Case.progressIndicatorCancelButton.label=Cancel",
 
 1806         "Case.progressMessage.preparing=Preparing...",
 
 1807         "Case.progressMessage.cancelling=Cancelling...",
 
 1808         "Case.exceptionMessage.cancelled=Cancelled.",
 
 1809         "# {0} - exception message", 
"Case.exceptionMessage.execExceptionWrapperMessage={0}" 
 1819             if (allowCancellation) {
 
 1823                         progressIndicatorTitle,
 
 1824                         new String[]{Bundle.Case_progressIndicatorCancelButton_label()},
 
 1825                         Bundle.Case_progressIndicatorCancelButton_label(),
 
 1826                         cancelButtonListener);
 
 1830                         progressIndicatorTitle);
 
 1835         progressIndicator.
start(Bundle.Case_progressMessage_preparing());
 
 1844         caseActionExecutor = Executors.newSingleThreadExecutor(threadFactory);
 
 1845         Future<Void> future = caseActionExecutor.submit(() -> {
 
 1847                 caseAction.
execute(progressIndicator, additionalParams);
 
 1851                     if (null == resourcesLock) {
 
 1852                         throw new CaseActionException(Bundle.Case_creationException_couldNotAcquireResourcesLock());
 
 1854                     caseAction.
execute(progressIndicator, additionalParams);
 
 1855                 } 
catch (CaseActionException ex) {
 
 1862         if (null != cancelButtonListener) {
 
 1871         } 
catch (InterruptedException discarded) {
 
 1875             if (null != cancelButtonListener) {
 
 1878                 future.cancel(
true);
 
 1881         } 
catch (CancellationException discarded) {
 
 1887         } 
catch (ExecutionException ex) {
 
 1892             throw new CaseActionException(Bundle.Case_exceptionMessage_execExceptionWrapperMessage(ex.getCause().getLocalizedMessage()), ex);
 
 1894             progressIndicator.
finish();
 
 1914         assert (additionalParams == null);
 
 1935         } 
catch (CaseActionException ex) {
 
 1944             } 
catch (InterruptedException discarded) {
 
 1946             close(progressIndicator);
 
 1966         assert (additionalParams == null);
 
 1984         } 
catch (CaseActionException ex) {
 
 1993             } 
catch (InterruptedException discarded) {
 
 1995             close(progressIndicator);
 
 2015         "Case.progressMessage.deletingDataSource=Removing the data source from the case...",
 
 2016         "Case.exceptionMessage.dataSourceNotFound=The data source was not found.",
 
 2017         "Case.exceptionMessage.errorDeletingDataSourceFromCaseDb=An error occurred while removing the data source from the case database.",
 
 2018         "Case.exceptionMessage.errorDeletingDataSourceFromTextIndex=An error occurred while removing the data source from the text index.",})
 
 2019     Void deleteDataSource(ProgressIndicator progressIndicator, Object additionalParams) 
throws CaseActionException {
 
 2020         assert (additionalParams instanceof Long);
 
 2021         open(progressIndicator, null);
 
 2023             progressIndicator.progress(Bundle.Case_progressMessage_deletingDataSource());
 
 2024             Long dataSourceObjectID = (Long) additionalParams;
 
 2026                 DataSource dataSource = this.caseDb.getDataSource(dataSourceObjectID);
 
 2027                 if (dataSource == null) {
 
 2028                     throw new CaseActionException(Bundle.Case_exceptionMessage_dataSourceNotFound());
 
 2030                 SleuthkitCaseAdminUtil.deleteDataSource(this.caseDb, dataSourceObjectID);
 
 2031             } 
catch (TskDataException | TskCoreException ex) {
 
 2032                 throw new CaseActionException(Bundle.Case_exceptionMessage_errorDeletingDataSourceFromCaseDb(), ex);
 
 2036             } 
catch (KeywordSearchServiceException ex) {
 
 2037                 throw new CaseActionException(Bundle.Case_exceptionMessage_errorDeletingDataSourceFromTextIndex(), ex);
 
 2039             eventPublisher.
publish(
new DataSourceDeletedEvent(dataSourceObjectID));
 
 2042             close(progressIndicator);
 
 2057     public SleuthkitCase 
createPortableCase(String caseName, File portableCaseFolder) 
throws TskCoreException {
 
 2059         if (portableCaseFolder.exists()) {
 
 2060             throw new TskCoreException(
"Portable case folder " + portableCaseFolder.toString() + 
" already exists");
 
 2062         if (!portableCaseFolder.mkdirs()) {
 
 2063             throw new TskCoreException(
"Error creating portable case folder " + portableCaseFolder.toString());
 
 2071             portableCaseMetadata.setCaseDatabaseName(SINGLE_USER_CASE_DB_NAME);
 
 2073             throw new TskCoreException(
"Error creating case metadata", ex);
 
 2077         SleuthkitCase portableSleuthkitCase;
 
 2079         portableSleuthkitCase = SleuthkitCase.newCase(dbFilePath);
 
 2081         return portableSleuthkitCase;
 
 2094         if (Thread.currentThread().isInterrupted()) {
 
 2095             throw new CaseActionCancelledException(Bundle.Case_exceptionMessage_cancelled());
 
 2110         "Case.progressMessage.creatingCaseDirectory=Creating case directory..." 
 2117         progressIndicator.
progress(Bundle.Case_progressMessage_creatingCaseDirectory());
 
 2119             progressIndicator.
progress(Bundle.Case_progressMessage_creatingCaseDirectory());
 
 2131         "Case.progressMessage.switchingLogDirectory=Switching log directory..." 
 2134         progressIndicator.
progress(Bundle.Case_progressMessage_switchingLogDirectory());
 
 2150         "Case.progressMessage.savingCaseMetadata=Saving case metadata to file...",
 
 2151         "# {0} - exception message", 
"Case.exceptionMessage.couldNotSaveCaseMetadata=Failed to save case metadata:\n{0}." 
 2154         progressIndicator.
progress(Bundle.Case_progressMessage_savingCaseMetadata());
 
 2156             this.metadata.writeToFile();
 
 2158             throw new CaseActionException(Bundle.Case_exceptionMessage_couldNotSaveCaseMetadata(ex.getLocalizedMessage()), ex);
 
 2174         "Case.progressMessage.creatingCaseNodeData=Creating coordination service node data...",
 
 2175         "# {0} - exception message", 
"Case.exceptionMessage.couldNotCreateCaseNodeData=Failed to create coordination service node data:\n{0}." 
 2179             progressIndicator.
progress(Bundle.Case_progressMessage_creatingCaseNodeData());
 
 2183                 throw new CaseActionException(Bundle.Case_exceptionMessage_couldNotCreateCaseNodeData(ex.getLocalizedMessage()), ex);
 
 2200         "Case.progressMessage.updatingCaseNodeData=Updating coordination service node data...",
 
 2201         "# {0} - exception message", 
"Case.exceptionMessage.couldNotUpdateCaseNodeData=Failed to update coordination service node data:\n{0}." 
 2205             progressIndicator.
progress(Bundle.Case_progressMessage_updatingCaseNodeData());
 
 2211                 throw new CaseActionException(Bundle.Case_exceptionMessage_couldNotUpdateCaseNodeData(ex.getLocalizedMessage()), ex);
 
 2222         "Case.progressMessage.clearingTempDirectory=Clearing case temp directory..." 
 2228         progressIndicator.
progress(Bundle.Case_progressMessage_clearingTempDirectory());
 
 2244         "Case.progressMessage.creatingCaseDatabase=Creating case database...",
 
 2245         "# {0} - exception message", 
"Case.exceptionMessage.couldNotGetDbServerConnectionInfo=Failed to get case database server conneciton info:\n{0}.",
 
 2246         "# {0} - exception message", 
"Case.exceptionMessage.couldNotCreateCaseDatabase=Failed to create case database:\n{0}.",
 
 2247         "# {0} - exception message", 
"Case.exceptionMessage.couldNotSaveDbNameToMetadataFile=Failed to save case database name to case metadata file:\n{0}." 
 2250         progressIndicator.
progress(Bundle.Case_progressMessage_creatingCaseDatabase());
 
 2259                 metadata.setCaseDatabaseName(SINGLE_USER_CASE_DB_NAME);
 
 2267                 metadata.setCaseDatabaseName(caseDb.getDatabaseName());
 
 2269         } 
catch (TskCoreException ex) {
 
 2270             throw new CaseActionException(Bundle.Case_exceptionMessage_couldNotCreateCaseDatabase(ex.getLocalizedMessage()), ex);
 
 2272             throw new CaseActionException(Bundle.Case_exceptionMessage_couldNotGetDbServerConnectionInfo(ex.getLocalizedMessage()), ex);
 
 2274             throw new CaseActionException(Bundle.Case_exceptionMessage_couldNotSaveDbNameToMetadataFile(ex.getLocalizedMessage()), ex);
 
 2290         "Case.progressMessage.openingCaseDatabase=Opening case database...",
 
 2291         "# {0} - exception message", 
"Case.exceptionMessage.couldNotOpenCaseDatabase=Failed to open case database:\n{0}.",
 
 2292         "# {0} - exception message", 
"Case.exceptionMessage.unsupportedSchemaVersionMessage=Unsupported case database schema version:\n{0}.",
 
 2293         "Case.open.exception.multiUserCaseNotEnabled=Cannot open a multi-user case if multi-user cases are not enabled. See Tools, Options, Multi-User." 
 2296         progressIndicator.
progress(Bundle.Case_progressMessage_openingCaseDatabase());
 
 2300                 caseDb = SleuthkitCase.openCase(Paths.get(metadata.
getCaseDirectory(), databaseName).toString());
 
 2304                 throw new CaseActionException(Bundle.Case_open_exception_multiUserCaseNotEnabled());
 
 2306         } 
catch (TskUnsupportedSchemaVersionException ex) {
 
 2307             throw new CaseActionException(Bundle.Case_exceptionMessage_unsupportedSchemaVersionMessage(ex.getLocalizedMessage()), ex);
 
 2309             throw new CaseActionException(Bundle.Case_exceptionMessage_couldNotGetDbServerConnectionInfo(ex.getLocalizedMessage()), ex);
 
 2310         } 
catch (TskCoreException ex) {
 
 2311             throw new CaseActionException(Bundle.Case_exceptionMessage_couldNotOpenCaseDatabase(ex.getLocalizedMessage()), ex);
 
 2322         "Case.progressMessage.openingCaseLevelServices=Opening case-level services...",})
 
 2324         progressIndicator.
progress(Bundle.Case_progressMessage_openingCaseLevelServices());
 
 2325         this.caseServices = 
new Services(caseDb);
 
 2331         caseDb.registerForEvents(sleuthkitEventListener);
 
 2345     @NbBundle.Messages({
 
 2346         "Case.progressMessage.openingApplicationServiceResources=Opening application service case resources...",
 
 2347         "# {0} - service name", 
"Case.serviceOpenCaseResourcesProgressIndicator.title={0} Opening Case Resources",
 
 2348         "# {0} - service name", 
"Case.serviceOpenCaseResourcesProgressIndicator.cancellingMessage=Cancelling opening case resources by {0}...",
 
 2349         "# {0} - service name", 
"Case.servicesException.notificationTitle={0} Error" 
 2360         progressIndicator.
progress(Bundle.Case_progressMessage_openingApplicationServiceResources());
 
 2372                 cancelButtonListener = 
new CancelButtonListener(Bundle.Case_serviceOpenCaseResourcesProgressIndicator_cancellingMessage(service.getServiceName()));
 
 2375                         Bundle.Case_serviceOpenCaseResourcesProgressIndicator_title(service.getServiceName()),
 
 2376                         new String[]{Bundle.Case_progressIndicatorCancelButton_label()},
 
 2377                         Bundle.Case_progressIndicatorCancelButton_label(),
 
 2378                         cancelButtonListener);
 
 2382             appServiceProgressIndicator.
start(Bundle.Case_progressMessage_preparing());
 
 2384             String threadNameSuffix = service.getServiceName().replaceAll(
"[ ]", 
"-"); 
 
 2385             threadNameSuffix = threadNameSuffix.toLowerCase();
 
 2387             ExecutorService executor = Executors.newSingleThreadExecutor(threadFactory);
 
 2388             Future<Void> future = executor.submit(() -> {
 
 2389                 service.openCaseResources(context);
 
 2392             if (null != cancelButtonListener) {
 
 2404             } 
catch (InterruptedException discarded) {
 
 2409                 future.cancel(
true);
 
 2410             } 
catch (CancellationException discarded) {
 
 2418             } 
catch (ExecutionException ex) {
 
 2425                 Case.
logger.log(Level.SEVERE, String.format(
"%s failed to open case resources for %s", service.getServiceName(), this.
getDisplayName()), ex);
 
 2427                     SwingUtilities.invokeLater(() -> {
 
 2439                 appServiceProgressIndicator.
finish();
 
 2457         "Case.progressMessage.settingUpNetworkCommunications=Setting up network communications...",
 
 2458         "# {0} - exception message", 
"Case.exceptionMessage.couldNotOpenRemoteEventChannel=Failed to open remote events channel:\n{0}.",
 
 2459         "# {0} - exception message", 
"Case.exceptionMessage.couldNotCreatCollaborationMonitor=Failed to create collaboration monitor:\n{0}." 
 2463             progressIndicator.
progress(Bundle.Case_progressMessage_settingUpNetworkCommunications());
 
 2467                 collaborationMonitor = 
new CollaborationMonitor(metadata.
getCaseName());
 
 2469                 throw new CaseActionException(Bundle.Case_exceptionMessage_couldNotOpenRemoteEventChannel(ex.getLocalizedMessage()), ex);
 
 2470             } 
catch (CollaborationMonitor.CollaborationMonitorException ex) {
 
 2471                 throw new CaseActionException(Bundle.Case_exceptionMessage_couldNotCreatCollaborationMonitor(ex.getLocalizedMessage()), ex);
 
 2499                     Bundle.Case_progressIndicatorTitle_closingCase());
 
 2503         progressIndicator.
start(Bundle.Case_progressMessage_preparing());
 
 2512         Future<Void> future = caseActionExecutor.submit(() -> {
 
 2514                 close(progressIndicator);
 
 2521                 progressIndicator.
progress(Bundle.Case_progressMessage_preparing());
 
 2523                     if (null == resourcesLock) {
 
 2524                         throw new CaseActionException(Bundle.Case_creationException_couldNotAcquireResourcesLock());
 
 2526                     close(progressIndicator);
 
 2540         } 
catch (InterruptedException | CancellationException unused) {
 
 2547         } 
catch (ExecutionException ex) {
 
 2548             throw new CaseActionException(Bundle.Case_exceptionMessage_execExceptionWrapperMessage(ex.getCause().getMessage()), ex);
 
 2551             progressIndicator.
finish();
 
 2561         "Case.progressMessage.shuttingDownNetworkCommunications=Shutting down network communications...",
 
 2562         "Case.progressMessage.closingApplicationServiceResources=Closing case-specific application service resources...",
 
 2563         "Case.progressMessage.closingCaseDatabase=Closing case database..." 
 2573             progressIndicator.
progress(Bundle.Case_progressMessage_shuttingDownNetworkCommunications());
 
 2574             if (null != collaborationMonitor) {
 
 2575                 collaborationMonitor.shutdown();
 
 2584         progressIndicator.
progress(Bundle.Case_progressMessage_closingApplicationServiceResources());
 
 2590         if (null != caseDb) {
 
 2591             progressIndicator.
progress(Bundle.Case_progressMessage_closingCaseDatabase());
 
 2592             caseDb.unregisterForEvents(sleuthkitEventListener);
 
 2599         progressIndicator.
progress(Bundle.Case_progressMessage_switchingLogDirectory());
 
 2608         "# {0} - serviceName", 
"Case.serviceCloseResourcesProgressIndicator.title={0} Closing Case Resources",
 
 2609         "# {0} - service name", 
"# {1} - exception message", 
"Case.servicesException.serviceResourcesCloseError=Could not close case resources for {0} service: {1}" 
 2622                         Bundle.Case_serviceCloseResourcesProgressIndicator_title(service.getServiceName()));
 
 2626             progressIndicator.
start(Bundle.Case_progressMessage_preparing());
 
 2628             String threadNameSuffix = service.getServiceName().replaceAll(
"[ ]", 
"-"); 
 
 2629             threadNameSuffix = threadNameSuffix.toLowerCase();
 
 2631             ExecutorService executor = Executors.newSingleThreadExecutor(threadFactory);
 
 2632             Future<Void> future = executor.submit(() -> {
 
 2633                 service.closeCaseResources(context);
 
 2638             } 
catch (InterruptedException ex) {
 
 2639                 Case.
logger.log(Level.SEVERE, String.format(
"Unexpected interrupt while waiting on %s service to close case resources", service.getServiceName()), ex);
 
 2640             } 
catch (CancellationException ex) {
 
 2641                 Case.
logger.log(Level.SEVERE, String.format(
"Unexpected cancellation while waiting on %s service to close case resources", service.getServiceName()), ex);
 
 2642             } 
catch (ExecutionException ex) {
 
 2643                 Case.
logger.log(Level.SEVERE, String.format(
"%s service failed to open case resources", service.getServiceName()), ex);
 
 2646                             Bundle.Case_servicesException_notificationTitle(service.getServiceName()),
 
 2647                             Bundle.Case_servicesException_serviceResourcesCloseError(service.getServiceName(), ex.getLocalizedMessage())));
 
 2651                 progressIndicator.
finish();
 
 2662         "Case.lockingException.couldNotAcquireSharedLock=Failed to get an shared lock on the case.",
 
 2663         "Case.lockingException.couldNotAcquireExclusiveLock=Failed to get a exclusive lock on the case." 
 2674                     throw new CaseActionException(Bundle.Case_lockingException_couldNotAcquireSharedLock());
 
 2676                     throw new CaseActionException(Bundle.Case_lockingException_couldNotAcquireExclusiveLock());
 
 2681                 throw new CaseActionException(Bundle.Case_lockingException_couldNotAcquireSharedLock(), ex);
 
 2683                 throw new CaseActionException(Bundle.Case_lockingException_couldNotAcquireExclusiveLock(), ex);
 
 2697                 logger.log(Level.SEVERE, String.format(
"Failed to release shared case directory lock for %s", getMetadata().
getCaseDirectory()), ex);
 
 2710         if (!subDirectory.exists()) {
 
 2711             subDirectory.mkdirs();
 
 2713         return subDirectory.toString();
 
 2729         "Case.exceptionMessage.errorsDeletingCase=Errors occured while deleting the case. See the application log for details." 
 2732         boolean errorsOccurred = 
false;
 
 2736             errorsOccurred = 
true;
 
 2742         } 
catch (CaseActionException ex) {
 
 2743             errorsOccurred = 
true;
 
 2749         if (errorsOccurred) {
 
 2750             throw new CaseActionException(Bundle.Case_exceptionMessage_errorsDeletingCase());
 
 2774         "Case.progressMessage.connectingToCoordSvc=Connecting to coordination service...",
 
 2775         "# {0} - exception message", 
"Case.exceptionMessage.failedToConnectToCoordSvc=Failed to connect to coordination service:\n{0}.",
 
 2776         "Case.exceptionMessage.cannotGetLockToDeleteCase=Cannot delete case because it is open for another user or host.",
 
 2777         "# {0} - exception message", 
"Case.exceptionMessage.failedToLockCaseForDeletion=Failed to exclusively lock case for deletion:\n{0}.",
 
 2778         "Case.progressMessage.fetchingCoordSvcNodeData=Fetching coordination service node data for the case...",
 
 2779         "# {0} - exception message", 
"Case.exceptionMessage.failedToFetchCoordSvcNodeData=Failed to fetch coordination service node data:\n{0}.",
 
 2780         "Case.progressMessage.deletingResourcesCoordSvcNode=Deleting case resources coordination service node...",
 
 2781         "Case.progressMessage.deletingCaseDirCoordSvcNode=Deleting case directory coordination service node..." 
 2784         progressIndicator.
progress(Bundle.Case_progressMessage_connectingToCoordSvc());
 
 2790             throw new CaseActionException(Bundle.Case_exceptionMessage_failedToConnectToCoordSvc(ex.getLocalizedMessage()));
 
 2794         boolean errorsOccurred = 
false;
 
 2796             if (dirLock == null) {
 
 2798                 throw new CaseActionException(Bundle.Case_exceptionMessage_cannotGetLockToDeleteCase());
 
 2801             progressIndicator.
progress(Bundle.Case_progressMessage_fetchingCoordSvcNodeData());
 
 2806                 throw new CaseActionException(Bundle.Case_exceptionMessage_failedToFetchCoordSvcNodeData(ex.getLocalizedMessage()));
 
 2811             progressIndicator.
progress(Bundle.Case_progressMessage_deletingResourcesCoordSvcNode());
 
 2817                     errorsOccurred = 
true;
 
 2818                     logger.log(Level.WARNING, String.format(
"Error deleting the case resources coordination service node for the case at %s (%s) in %s", metadata.
getCaseDisplayName(), metadata.
getCaseName(), metadata.
getCaseDirectory()), ex); 
 
 2820             } 
catch (InterruptedException ex) {
 
 2821                 logger.log(Level.WARNING, String.format(
"Error deleting the case resources coordination service node for the case at %s (%s) in %s", metadata.
getCaseDisplayName(), metadata.
getCaseName(), metadata.
getCaseDirectory()), ex); 
 
 2826             throw new CaseActionException(Bundle.Case_exceptionMessage_failedToLockCaseForDeletion(ex.getLocalizedMessage()));
 
 2829         if (!errorsOccurred) {
 
 2830             progressIndicator.
progress(Bundle.Case_progressMessage_deletingCaseDirCoordSvcNode());
 
 2836                 errorsOccurred = 
true;
 
 2840         if (errorsOccurred) {
 
 2841             throw new CaseActionException(Bundle.Case_exceptionMessage_errorsDeletingCase());
 
 2871         boolean errorsOccurred = 
false;
 
 2878             errorsOccurred = 
true;
 
 2881             errorsOccurred = 
true;
 
 2883         } 
catch (CaseActionException ex) {
 
 2884             errorsOccurred = 
true;
 
 2887         return errorsOccurred;
 
 2911         "Case.progressMessage.deletingCaseDatabase=Deleting case database..." 
 2915             progressIndicator.
progress(Bundle.Case_progressMessage_deletingCaseDatabase());
 
 2916             logger.log(Level.INFO, String.format(
"Deleting case database for %s (%s) in %s", caseNodeData.
getDisplayName(), caseNodeData.
getName(), caseNodeData.
getDirectory())); 
 
 2918             String url = 
"jdbc:postgresql://" + info.getHost() + 
":" + info.getPort() + 
"/postgres"; 
 
 2919             Class.forName(
"org.postgresql.Driver"); 
 
 2920             try (Connection connection = DriverManager.getConnection(url, info.getUserName(), info.getPassword()); Statement statement = connection.createStatement()) {
 
 2921                 String dbExistsQuery = 
"SELECT 1 from pg_database WHERE datname = '" + metadata.
getCaseDatabaseName() + 
"'"; 
 
 2922                 try (ResultSet queryResult = statement.executeQuery(dbExistsQuery)) {
 
 2923                     if (queryResult.next()) {
 
 2925                         statement.execute(deleteCommand);
 
 2966         "Case.progressMessage.deletingTextIndex=Deleting text index..." 
 2969         progressIndicator.
progress(Bundle.Case_progressMessage_deletingTextIndex());
 
 2973             searchService.deleteTextIndex(metadata);
 
 3009         "Case.progressMessage.deletingCaseDirectory=Deleting case directory..." 
 3012         progressIndicator.
progress(Bundle.Case_progressMessage_deletingCaseDirectory());
 
 3014             throw new CaseActionException(String.format(
"Failed to delete %s", metadata.
getCaseDirectory())); 
 
 3026         "Case.progressMessage.removingCaseFromRecentCases=Removing case from Recent Cases menu..." 
 3030             progressIndicator.
progress(Bundle.Case_progressMessage_removingCaseFromRecentCases());
 
 3031             SwingUtilities.invokeLater(() -> {
 
 3032                 RecentCases.getInstance().removeRecentCase(metadata.
getCaseDisplayName(), metadata.getFilePath().toString());
 
 3047         boolean isNodeNodeEx = 
false;
 
 3048         Throwable cause = ex.getCause();
 
 3049         if (cause != null) {
 
 3050             String causeMessage = cause.getMessage();
 
 3051             isNodeNodeEx = causeMessage.contains(NO_NODE_ERROR_MSG_FRAGMENT);
 
 3053         return isNodeNodeEx;
 
 3072             logger.log(Level.SEVERE, String.format(
"Error updating deleted item flag %s for %s (%s) in %s", flag.name(), caseNodeData.
getDisplayName(), caseNodeData.
getName(), caseNodeData.
getDirectory()), ex);
 
 3097         R 
execute(T progressIndicator, V additionalParams) 
throws CaseActionException;
 
 3195                         ((ModalDialogProgressIndicator) progressIndicator).
setCancelling(cancellationMessage);
 
 3224             return new Thread(task, threadName);
 
 3261     public static void create(String caseDir, String caseDisplayName, String caseNumber, String examiner) 
throws CaseActionException {
 
 3286     public static void create(String caseDir, String caseDisplayName, String caseNumber, String examiner, 
CaseType caseType) 
throws CaseActionException {
 
 3302     public static void open(String caseMetadataFilePath) 
throws CaseActionException {
 
 3359         return new File(filePath).isFile();
 
 3398         return "ModuleOutput"; 
 
 3411     public static PropertyChangeSupport
 
 3413         return new PropertyChangeSupport(
Case.class
 
 3445     public Image 
addImage(String imgPath, 
long imgId, String timeZone) 
throws CaseActionException {
 
 3447             Image newDataSource = caseDb.getImageById(imgId);
 
 3449             return newDataSource;
 
 3450         } 
catch (TskCoreException ex) {
 
 3451             throw new CaseActionException(NbBundle.getMessage(
this.getClass(), 
"Case.addImg.exception.msg"), ex);
 
 3478     public void deleteReports(Collection<? extends Report> reports, 
boolean deleteFromDisk) 
throws TskCoreException {
 
String getLogDirectoryPath()
 
static final AutopsyEventPublisher eventPublisher
 
List< Content > getDataSources()
 
String getModuleOutputDirectoryRelativePath()
 
static CaseNodeData createCaseNodeData(final CaseMetadata metadata)
 
void notifyContentTagDeleted(ContentTag deletedTag)
 
Case(CaseMetadata caseMetaData)
 
static CaseType fromString(String typeName)
 
final SleuthkitEventListener sleuthkitEventListener
 
static final String CASE_ACTION_THREAD_NAME
 
static void setDeletedItemFlag(CaseNodeData caseNodeData, CaseNodeData.DeletedFlags flag)
 
void publishLocally(AutopsyEvent event)
 
static void createAsCurrentCase(CaseType caseType, String caseDir, CaseDetails caseDetails)
 
static String getCaseDirectoryNodePath(Path caseDirectoryPath)
 
void notifyBlackBoardArtifactTagDeleted(BlackboardArtifactTag deletedTag)
 
String getExaminerPhone()
 
Void open(ProgressIndicator progressIndicator, Object additionalParams)
 
Set< TimeZone > getTimeZones()
 
CoordinationService.Lock caseLock
 
static boolean deleteMultiUserCase(CaseNodeData caseNodeData, CaseMetadata metadata, ProgressIndicator progressIndicator, Logger logger)
 
static String getNameForTitle()
 
Image addImage(String imgPath, long imgId, String timeZone)
 
static synchronized IngestManager getInstance()
 
void deleteNode(CategoryNode category, String nodePath)
 
static final String NO_NODE_ERROR_MSG_FRAGMENT
 
static boolean runningWithGUI
 
static void closeCurrentCase()
 
void setDeletedFlag(DeletedFlags flag)
 
void acquireCaseLock(CaseLockType lockType)
 
String getTempDirectory()
 
static boolean existsCurrentCase()
 
boolean isDeletedFlagSet(DeletedFlags flag)
 
static void removePropertyChangeListener(PropertyChangeListener listener)
 
void start(String message, int totalWorkUnits)
 
static final Logger logger
 
void publish(AutopsyEvent event)
 
String getLocalizedDisplayName()
 
ADDING_DATA_SOURCE_FAILED
 
static final String EXPORT_FOLDER
 
static void createCaseDirectory(String caseDirPath, CaseType caseType)
 
String getCaseDirectory()
 
static String getAppName()
 
void notifyTagDefinitionChanged(String changedTagName)
 
void deleteDataSource(Long dataSourceId)
 
static volatile Frame mainFrame
 
static String convertTimeZone(String timeZoneId)
 
static boolean driveExists(String path)
 
static void openCoreWindows()
 
static void deleteSingleUserCase(CaseMetadata metadata, ProgressIndicator progressIndicator)
 
void addSubscriber(Set< String > eventNames, PropertyChangeListener subscriber)
 
void publishTimelineEventAddedEvent(TimelineManager.TimelineEventAddedEvent event)
 
synchronized static void setLogDirectory(String directoryPath)
 
volatile ExecutorService caseActionExecutor
 
void notifyCentralRepoCommentChanged(long contentId, String newComment)
 
TaskThreadFactory(String threadName)
 
static final String CACHE_FOLDER
 
static String getAutopsyVersion()
 
CaseType(String typeName)
 
static void deleteMultiUserCaseDirectory(CaseNodeData caseNodeData, CaseMetadata metadata, ProgressIndicator progressIndicator, Logger logger)
 
Case(CaseType caseType, String caseDir, CaseDetails caseDetails)
 
String getReportDirectory()
 
static String getCaseResourcesNodePath(Path caseDirectoryPath)
 
static CaseNodeData readCaseNodeData(String nodePath)
 
static boolean getIsMultiUserModeEnabled()
 
void addReport(String localPath, String srcModuleName, String reportName)
 
static void updateGUIForCaseOpened(Case newCurrentCase)
 
void notifyDataSourceNameChanged(Content dataSource, String newName)
 
static CaseDbConnectionInfo getDatabaseConnectionInfo()
 
String getModulesOutputDirAbsPath()
 
static void create(String caseDir, String caseDisplayName, String caseNumber, String examiner, CaseType caseType)
 
void closeAppServiceCaseResources()
 
static final int CASE_LOCK_TIMEOUT_MINS
 
static final String SINGLE_USER_CASE_DB_NAME
 
static void deleteCase(CaseMetadata metadata)
 
void deleteReports(Collection<?extends Report > reports, boolean deleteFromDisk)
 
synchronized void closeRemoteEventChannel()
 
KeywordSearchService getKeywordSearchService()
 
static final int CASE_RESOURCES_LOCK_TIMEOUT_HOURS
 
List< Report > getAllReports()
 
static void clearTempSubDir(String tempSubDirPath)
 
static boolean canAddDataSources()
 
static boolean isValidName(String caseName)
 
void openCaseDataBase(ProgressIndicator progressIndicator)
 
void createCaseDirectoryIfDoesNotExist(ProgressIndicator progressIndicator)
 
CollaborationMonitor collaborationMonitor
 
void openCommunicationChannels(ProgressIndicator progressIndicator)
 
static void shutDownTaskExecutor(ExecutorService executor)
 
static void closeCoreWindows()
 
ProgressIndicator getProgressIndicator()
 
static String getModulesOutputDirRelPath()
 
void saveCaseMetadataToFile(ProgressIndicator progressIndicator)
 
static void deleteMultiUserCaseTextIndex(CaseNodeData caseNodeData, CaseMetadata metadata, ProgressIndicator progressIndicator, Logger logger)
 
void doOpenCaseAction(String progressIndicatorTitle, CaseAction< ProgressIndicator, Object, Void > caseAction, CaseLockType caseLockType, boolean allowCancellation, Object additionalParams)
 
Set< TimeZone > getTimeZone()
 
static void writeCaseNodeData(CaseNodeData nodeData)
 
static final String MODULE_FOLDER
 
void openCaseLevelServices(ProgressIndicator progressIndicator)
 
static void create(String caseDir, String caseDisplayName, String caseNumber, String examiner)
 
synchronized void openRemoteEventChannel(String channelName)
 
String getCaseDisplayName()
 
void createCaseNodeData(ProgressIndicator progressIndicator)
 
static void invokeStartupDialog()
 
void publishArtifactsPostedEvent(Blackboard.ArtifactsPostedEvent event)
 
static String displayNameToUniqueName(String caseDisplayName)
 
static void deleteFromRecentCases(CaseMetadata metadata, ProgressIndicator progressIndicator)
 
static void openAsCurrentCase(String caseMetadataFilePath)
 
static void removeEventSubscriber(Set< String > eventNames, PropertyChangeListener subscriber)
 
Lock tryGetExclusiveLock(CategoryNode category, String nodePath, int timeOut, TimeUnit timeUnit)
 
static boolean isNoNodeException(CoordinationServiceException ex)
 
void fireModuleDataEvent(ModuleDataEvent moduleDataEvent)
 
default void setCancelling(String cancellingMessage)
 
void setLastAccessDate(Date lastAccessDate)
 
void close(ProgressIndicator progressIndicator)
 
SleuthkitCase getSleuthkitCase()
 
void notifyBlackBoardArtifactTagAdded(BlackboardArtifactTag newTag)
 
static PropertyChangeSupport getPropertyChangeSupport()
 
String getCacheDirectory()
 
static void addPropertyChangeListener(PropertyChangeListener listener)
 
void removeSubscriber(Set< String > eventNames, PropertyChangeListener subscriber)
 
String getModuleDirectory()
 
void createCaseDatabase(ProgressIndicator progressIndicator)
 
void openAppServiceCaseResources(ProgressIndicator progressIndicator)
 
Thread newThread(Runnable task)
 
static void removeEventSubscriber(String eventName, PropertyChangeListener subscriber)
 
void switchLoggingToCaseLogsDirectory(ProgressIndicator progressIndicator)
 
final CaseMetadata metadata
 
static void deleteTextIndex(CaseMetadata metadata, ProgressIndicator progressIndicator)
 
void deleteTempfilesFromCaseDirectory(ProgressIndicator progressIndicator)
 
void deleteReports(Collection<?extends Report > reports)
 
void notifyDataSourceAdded(Content dataSource, UUID addingDataSourceEventId)
 
Report addReport(String localPath, String srcModuleName, String reportName, Content parent)
 
static boolean pathExists(String filePath)
 
SleuthkitCase createPortableCase(String caseName, File portableCaseFolder)
 
R execute(T progressIndicator, V additionalParams)
 
BLACKBOARD_ARTIFACT_TAG_ADDED
 
static void open(String caseMetadataFilePath)
 
static void openAsCurrentCase(Case newCurrentCase, boolean isNewCase)
 
static CoordinationService.Lock acquireCaseResourcesLock(String caseDir)
 
String getOutputDirectory()
 
static void error(String title, String message)
 
String getOrCreateSubdirectory(String subDirectoryName)
 
boolean equalsName(String otherTypeName)
 
static final String EVENT_CHANNEL_NAME
 
static Case getCurrentCase()
 
static String getLocalHostName()
 
synchronized static Logger getLogger(String name)
 
static Case getCurrentCaseThrows()
 
static void addEventTypeSubscriber(Set< Events > eventTypes, PropertyChangeListener subscriber)
 
static String convertToAlphaNumericFormat(String timeZoneId)
 
static final String LOG_FOLDER
 
Void create(ProgressIndicator progressIndicator, Object additionalParams)
 
Lock tryGetSharedLock(CategoryNode category, String nodePath, int timeOut, TimeUnit timeUnit)
 
String getConfigDirectory()
 
static String getAppName()
 
static synchronized CoordinationService getInstance()
 
static volatile Case currentCase
 
static String getVersion()
 
String getExportDirectory()
 
static void updateGUIForCaseClosed()
 
void notifyAddingDataSource(UUID eventId)
 
static void addEventSubscriber(String eventName, PropertyChangeListener subscriber)
 
void notifyContentTagAdded(ContentTag newTag)
 
void cancelAllIngestJobs(IngestJob.CancellationReason reason)
 
static final String CASE_RESOURCES_THREAD_NAME
 
static StartupWindowProvider getInstance()
 
static void deleteCurrentCase()
 
static boolean deleteDir(File dirPath)
 
static void createAsCurrentCase(String caseDir, String caseDisplayName, String caseNumber, String examiner, CaseType caseType)
 
static void deleteCaseDirectory(CaseMetadata metadata, ProgressIndicator progressIndicator)
 
void notifyFailedAddingDataSource(UUID addingDataSourceEventId)
 
static void deleteMultiUserCase(CaseMetadata metadata, ProgressIndicator progressIndicator)
 
static final String CONFIG_FOLDER
 
static void removeEventTypeSubscriber(Set< Events > eventTypes, PropertyChangeListener subscriber)
 
static final Object caseActionSerializationLock
 
static void deleteMultiUserCaseDatabase(CaseNodeData caseNodeData, CaseMetadata metadata, ProgressIndicator progressIndicator, Logger logger)
 
static boolean isCaseOpen()
 
String getTextIndexName()
 
static final String REPORTS_FOLDER
 
void progress(String message)
 
static final String TEMP_FOLDER
 
BLACKBOARD_ARTIFACT_TAG_DELETED
 
static void checkForCancellation()
 
static void addEventSubscriber(Set< String > eventNames, PropertyChangeListener subscriber)
 
void updateCaseNodeData(ProgressIndicator progressIndicator)
 
static void error(String message)
 
static synchronized IngestServices getInstance()
 
String getExaminerEmail()