19 package org.sleuthkit.autopsy.casemodule;
 
   23 import com.google.common.annotations.Beta;
 
   24 import com.google.common.eventbus.Subscribe;
 
   25 import com.google.common.util.concurrent.ThreadFactoryBuilder;
 
   26 import java.awt.Cursor;
 
   28 import java.awt.Frame;
 
   29 import java.awt.GraphicsEnvironment;
 
   30 import java.awt.event.ActionEvent;
 
   31 import java.awt.event.ActionListener;
 
   32 import java.beans.PropertyChangeListener;
 
   33 import java.beans.PropertyChangeSupport;
 
   35 import java.lang.reflect.InvocationTargetException;
 
   36 import java.nio.file.InvalidPathException;
 
   37 import java.nio.file.Path;
 
   38 import java.nio.file.Paths;
 
   39 import java.sql.Connection;
 
   40 import java.sql.DriverManager;
 
   41 import java.sql.ResultSet;
 
   42 import java.sql.SQLException;
 
   43 import java.sql.Statement;
 
   44 import java.text.SimpleDateFormat;
 
   45 import java.util.ArrayList;
 
   46 import java.util.Collection;
 
   47 import java.util.Date;
 
   48 import java.util.HashMap;
 
   49 import java.util.HashSet;
 
   50 import java.util.List;
 
   53 import java.util.TimeZone;
 
   54 import java.util.UUID;
 
   55 import java.util.concurrent.CancellationException;
 
   56 import java.util.concurrent.ExecutionException;
 
   57 import java.util.concurrent.ExecutorService;
 
   58 import java.util.concurrent.Executors;
 
   59 import java.util.concurrent.Future;
 
   60 import java.util.concurrent.ThreadFactory;
 
   61 import java.util.concurrent.TimeUnit;
 
   62 import java.util.logging.Level;
 
   63 import java.util.stream.Collectors;
 
   64 import java.util.stream.Stream;
 
   65 import javax.annotation.concurrent.GuardedBy;
 
   66 import javax.annotation.concurrent.ThreadSafe;
 
   67 import javax.swing.JOptionPane;
 
   68 import javax.swing.SwingUtilities;
 
   69 import org.apache.commons.lang3.ArrayUtils;
 
   70 import org.apache.commons.lang3.StringUtils;
 
   71 import org.openide.util.Lookup;
 
   72 import org.openide.util.NbBundle;
 
   73 import org.openide.util.NbBundle.Messages;
 
   74 import org.openide.util.actions.CallableSystemAction;
 
   75 import org.openide.windows.WindowManager;
 
  191             = Executors.newSingleThreadExecutor(
new ThreadFactoryBuilder().setNameFormat(
"case-open-file-systems-%d").build());
 
  211         if (!GraphicsEnvironment.isHeadless()) {
 
  212             WindowManager.getDefault().invokeWhenUIReady(() -> {
 
  213                 mainFrame = WindowManager.getDefault().getMainWindow();
 
  236             if (typeName != null) {
 
  238                     if (typeName.equalsIgnoreCase(c.toString())) {
 
  262             "Case_caseType_singleUser=Single-user case",
 
  263             "Case_caseType_multiUser=Multi-user case" 
  266             if (fromString(typeName) == SINGLE_USER_CASE) {
 
  267                 return Bundle.Case_caseType_singleUser();
 
  269                 return Bundle.Case_caseType_multiUser();
 
  279             this.typeName = typeName;
 
  294             return (otherTypeName == null) ? 
false : typeName.equals(otherTypeName);
 
  550                 logger.log(Level.SEVERE, 
"Unable to retrieve the hasData status from the db", ex);
 
  594                 logger.log(Level.SEVERE, 
"Unable to retrieve the hasData status from the db", ex);
 
  677                 .map(Events::toString)
 
  678                 .collect(Collectors.toSet()), listener);
 
  689                 .map(Events::toString)
 
  690                 .collect(Collectors.toSet()), listener);
 
  713         eventTypes.forEach((
Events event) -> {
 
  758         eventTypes.forEach((
Events event) -> {
 
  772         return !(caseName.contains(
"\\") || caseName.contains(
"/") || caseName.contains(
":")
 
  773                 || caseName.contains(
"*") || caseName.contains(
"?") || caseName.contains(
"\"")
 
  774                 || caseName.contains(
"<") || caseName.contains(
">") || caseName.contains(
"|"));
 
  826         "Case.exceptionMessage.emptyCaseName=Must specify a case name.",
 
  827         "Case.exceptionMessage.emptyCaseDir=Must specify a case directory path." 
  831             throw new CaseActionException(Bundle.Case_exceptionMessage_emptyCaseName());
 
  833         if (caseDir.isEmpty()) {
 
  834             throw new CaseActionException(Bundle.Case_exceptionMessage_emptyCaseDir());
 
  853         "# {0} - exception message", 
"Case.exceptionMessage.failedToReadMetadata=Failed to read case metadata:\n{0}.",
 
  854         "Case.exceptionMessage.cannotOpenMultiUserCaseNoSettings=Multi-user settings are missing (see Tools, Options, Multi-user tab), cannot open a multi-user case." 
  859             metadata = 
new CaseMetadata(Paths.get(caseMetadataFilePath));
 
  861             throw new CaseActionException(Bundle.Case_exceptionMessage_failedToReadMetadata(ex.getLocalizedMessage()), ex);
 
  864             throw new CaseActionException(Bundle.Case_exceptionMessage_cannotOpenMultiUserCaseNoSettings());
 
  875         return currentCase != null;
 
  892             throw new IllegalStateException(NbBundle.getMessage(
Case.class, 
"Case.getCurCase.exception.noneOpen"), ex);
 
  916         if (openCase == null) {
 
  917             throw new NoCurrentCaseException(NbBundle.getMessage(
Case.class, 
"Case.getCurCase.exception.noneOpen"));
 
  932         "# {0} - exception message", 
"Case.closeException.couldNotCloseCase=Error closing case: {0}",
 
  933         "Case.progressIndicatorTitle.closingCase=Closing Case" 
  937             if (null == currentCase) {
 
  943                 logger.log(Level.INFO, 
"Closing current case {0} ({1}) in {2}", 
new Object[]{closedCase.getDisplayName(), closedCase.getName(), closedCase.getCaseDirectory()}); 
 
  945                 logger.log(Level.INFO, 
"Closed current case {0} ({1}) in {2}", 
new Object[]{closedCase.getDisplayName(), closedCase.getName(), closedCase.getCaseDirectory()}); 
 
  946             } 
catch (CaseActionException ex) {
 
  968             if (null == currentCase) {
 
  988         "Case.progressIndicatorTitle.deletingDataSource=Removing Data Source" 
  990     static void deleteDataSourceFromCurrentCase(Long dataSourceObjectID) 
throws CaseActionException {
 
  992             if (null == currentCase) {
 
  999             CaseMetadata caseMetadata = currentCase.
getMetadata();
 
 1007             Case theCase = 
new Case(caseMetadata);
 
 1008             theCase.doOpenCaseAction(Bundle.Case_progressIndicatorTitle_deletingDataSource(), theCase::deleteDataSource, CaseLockType.EXCLUSIVE, 
false, dataSourceObjectID);
 
 1029         "Case.progressIndicatorTitle.deletingCase=Deleting Case",
 
 1030         "Case.exceptionMessage.cannotDeleteCurrentCase=Cannot delete current case, it must be closed first.",
 
 1031         "# {0} - case display name", 
"Case.exceptionMessage.deletionInterrupted=Deletion of the case {0} was cancelled." 
 1035             if (null != currentCase) {
 
 1036                 throw new CaseActionException(Bundle.Case_exceptionMessage_cannotDeleteCurrentCase());
 
 1046         progressIndicator.
start(Bundle.Case_progressMessage_preparing());
 
 1053                 } 
catch (InterruptedException ex) {
 
 1059                     throw new CaseActionException(Bundle.Case_exceptionMessage_deletionInterrupted(metadata.
getCaseDisplayName()), ex);
 
 1063             progressIndicator.
finish();
 
 1078         "Case.progressIndicatorTitle.creatingCase=Creating Case",
 
 1079         "Case.progressIndicatorTitle.openingCase=Opening Case",
 
 1080         "Case.exceptionMessage.cannotLocateMainWindow=Cannot locate main application window" 
 1084             if (null != currentCase) {
 
 1087                 } 
catch (CaseActionException ex) {
 
 1096                 logger.log(Level.INFO, 
"Opening {0} ({1}) in {2} as the current case", 
new Object[]{newCurrentCase.getDisplayName(), newCurrentCase.getName(), newCurrentCase.getCaseDirectory()}); 
 
 1097                 String progressIndicatorTitle;
 
 1100                     progressIndicatorTitle = Bundle.Case_progressIndicatorTitle_creatingCase();
 
 1101                     openCaseAction = newCurrentCase::create;
 
 1103                     progressIndicatorTitle = Bundle.Case_progressIndicatorTitle_openingCase();
 
 1104                     openCaseAction = newCurrentCase::open;
 
 1107                 currentCase = newCurrentCase;
 
 1108                 logger.log(Level.INFO, 
"Opened {0} ({1}) in {2} as the current case", 
new Object[]{newCurrentCase.getDisplayName(), newCurrentCase.getName(), newCurrentCase.getCaseDirectory()}); 
 
 1114                 logger.log(Level.INFO, String.format(
"Cancelled opening %s (%s) in %s as the current case", newCurrentCase.
getDisplayName(), newCurrentCase.
getName(), newCurrentCase.
getCaseDirectory())); 
 
 1116             } 
catch (CaseActionException ex) {
 
 1117                 logger.log(Level.SEVERE, String.format(
"Error opening %s (%s) in %s as the current case", newCurrentCase.
getDisplayName(), newCurrentCase.
getName(), newCurrentCase.
getCaseDirectory()), ex); 
 
 1135         String uniqueCaseName = caseDisplayName.replaceAll(
"[^\\p{ASCII}]", 
"_"); 
 
 1140         uniqueCaseName = uniqueCaseName.replaceAll(
"[\\p{Cntrl}]", 
"_"); 
 
 1145         uniqueCaseName = uniqueCaseName.replaceAll(
"[ /?:'\"\\\\]", 
"_"); 
 
 1150         uniqueCaseName = uniqueCaseName.toLowerCase();
 
 1155         SimpleDateFormat dateFormat = 
new SimpleDateFormat(
"yyyyMMdd_HHmmss");
 
 1156         Date date = 
new Date();
 
 1157         uniqueCaseName = uniqueCaseName + 
"_" + dateFormat.format(date);
 
 1159         return uniqueCaseName;
 
 1176         File caseDir = 
new File(caseDirPath);
 
 1177         if (caseDir.exists()) {
 
 1178             if (caseDir.isFile()) {
 
 1179                 throw new CaseActionException(NbBundle.getMessage(
Case.class, 
"Case.createCaseDir.exception.existNotDir", caseDirPath));
 
 1180             } 
else if (!caseDir.canRead() || !caseDir.canWrite()) {
 
 1181                 throw new CaseActionException(NbBundle.getMessage(
Case.class, 
"Case.createCaseDir.exception.existCantRW", caseDirPath));
 
 1188         if (!caseDir.mkdirs()) {
 
 1189             throw new CaseActionException(NbBundle.getMessage(
Case.class, 
"Case.createCaseDir.exception.cantCreate", caseDirPath));
 
 1197         String hostPathComponent = 
"";
 
 1202         Path exportDir = Paths.get(caseDirPath, hostPathComponent, EXPORT_FOLDER);
 
 1203         if (!exportDir.toFile().mkdirs()) {
 
 1204             throw new CaseActionException(NbBundle.getMessage(
Case.class, 
"Case.createCaseDir.exception.cantCreateCaseDir", exportDir));
 
 1207         Path logsDir = Paths.get(caseDirPath, hostPathComponent, LOG_FOLDER);
 
 1208         if (!logsDir.toFile().mkdirs()) {
 
 1209             throw new CaseActionException(NbBundle.getMessage(
Case.class, 
"Case.createCaseDir.exception.cantCreateCaseDir", logsDir));
 
 1212         Path cacheDir = Paths.get(caseDirPath, hostPathComponent, CACHE_FOLDER);
 
 1213         if (!cacheDir.toFile().mkdirs()) {
 
 1214             throw new CaseActionException(NbBundle.getMessage(
Case.class, 
"Case.createCaseDir.exception.cantCreateCaseDir", cacheDir));
 
 1217         Path moduleOutputDir = Paths.get(caseDirPath, hostPathComponent, MODULE_FOLDER);
 
 1218         if (!moduleOutputDir.toFile().mkdirs()) {
 
 1219             throw new CaseActionException(NbBundle.getMessage(
Case.class, 
"Case.createCaseDir.exception.cantCreateModDir", moduleOutputDir));
 
 1222         Path reportsDir = Paths.get(caseDirPath, hostPathComponent, REPORTS_FOLDER);
 
 1223         if (!reportsDir.toFile().mkdirs()) {
 
 1224             throw new CaseActionException(NbBundle.getMessage(
Case.class, 
"Case.createCaseDir.exception.cantCreateReportsDir", reportsDir));
 
 1236         Map<Long, String> imgPaths = 
new HashMap<>();
 
 1239             for (Map.Entry<Long, List<String>> entry : imgPathsList.entrySet()) {
 
 1240                 if (entry.getValue().size() > 0) {
 
 1241                     imgPaths.put(entry.getKey(), entry.getValue().get(0));
 
 1244         } 
catch (TskCoreException ex) {
 
 1245             logger.log(Level.SEVERE, 
"Error getting image paths", ex); 
 
 1261         "Case.creationException.couldNotAcquireResourcesLock=Failed to get lock on case resources" 
 1265             Path caseDirPath = Paths.get(caseDir);
 
 1269         } 
catch (InterruptedException ex) {
 
 1272             throw new CaseActionException(Bundle.Case_creationException_couldNotAcquireResourcesLock(), ex);
 
 1296         if (null != backupDbPath) {
 
 1297             JOptionPane.showMessageDialog(
 
 1299                     NbBundle.getMessage(
Case.class, 
"Case.open.msgDlg.updated.msg", backupDbPath),
 
 1300                     NbBundle.getMessage(
Case.class, 
"Case.open.msgDlg.updated.title"),
 
 1301                     JOptionPane.INFORMATION_MESSAGE);
 
 1308         Map<Long, String> imgPaths = getImagePaths(caseDb);
 
 1309         for (Map.Entry<Long, String> entry : imgPaths.entrySet()) {
 
 1310             long obj_id = entry.getKey();
 
 1311             String path = entry.getValue();
 
 1321                     SwingUtilities.invokeAndWait(
new Runnable() {
 
 1324                             int response = JOptionPane.showConfirmDialog(
 
 1326                                     NbBundle.getMessage(
Case.class, 
"Case.checkImgExist.confDlg.doesntExist.msg", hostName, path),
 
 1327                                     NbBundle.getMessage(
Case.class, 
"Case.checkImgExist.confDlg.doesntExist.title"),
 
 1328                                     JOptionPane.YES_NO_OPTION);
 
 1329                             if (response == JOptionPane.YES_OPTION) {
 
 1330                                 MissingImageDialog.makeDialog(obj_id, caseDb);
 
 1332                                 logger.log(Level.SEVERE, 
"User proceeding with missing image files"); 
 
 1339                     logger.log(Level.SEVERE, 
"Failed to show missing image confirmation dialog", ex); 
 
 1350         CallableSystemAction.get(CaseDetailsAction.class).setEnabled(
true);
 
 1365         final boolean hasData = newCurrentCase.
hasData();
 
 1367         SwingUtilities.invokeLater(() -> {
 
 1376             mainFrame.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
 
 1383             mainFrame.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
 
 1399             SwingUtilities.invokeLater(() -> {
 
 1409                 CallableSystemAction.get(
AddImageAction.class).setEnabled(
false);
 
 1412                 CallableSystemAction.get(CaseDetailsAction.class).setEnabled(
false);
 
 1414                 CallableSystemAction.get(CaseDeleteAction.class).setEnabled(
false);
 
 1558             hostPath = Paths.get(caseDirectory);
 
 1560         if (!hostPath.toFile().exists()) {
 
 1561             hostPath.toFile().mkdirs();
 
 1563         return hostPath.toString();
 
 1570         return Paths.get(System.getProperty(
"java.io.tmpdir"), 
APP_NAME, 
getName());
 
 1582         Path basePath = null;
 
 1587                 basePath = (StringUtils.isBlank(customDirectory))
 
 1589                         : Paths.get(customDirectory, APP_NAME, 
getName());
 
 1607                 : Paths.get(TEMP_FOLDER);
 
 1609         File caseTempDir = basePath
 
 1610                 .resolve(caseRelPath)
 
 1614         if (!caseTempDir.exists()) {
 
 1615             caseTempDir.mkdirs();
 
 1618         return caseTempDir.getAbsolutePath();
 
 1691             return path.subpath(path.getNameCount() - 2, path.getNameCount()).toString();
 
 1693             return path.subpath(path.getNameCount() - 1, path.getNameCount()).toString();
 
 1716         Set<TimeZone> timezones = 
new HashSet<>();
 
 1717         String query = 
"SELECT time_zone FROM data_source_info";
 
 1719             ResultSet timeZoneSet = dbQuery.getResultSet();
 
 1720             while (timeZoneSet.next()) {
 
 1721                 String timeZone = timeZoneSet.getString(
"time_zone");
 
 1722                 if (timeZone != null && !timeZone.isEmpty()) {
 
 1723                     timezones.add(TimeZone.getTimeZone(timeZone));
 
 1727             logger.log(Level.SEVERE, 
"Error getting data source time zones", ex); 
 
 1771         hasDataSource = 
true;
 
 1879             logger.log(Level.WARNING, 
"Unable to send notifcation regarding comment change due to no current case being open", ex);
 
 1930         addReport(localPath, srcModuleName, reportName, null);
 
 1948         String normalizedLocalPath;
 
 1950             if (localPath.toLowerCase().contains(
"http:")) {
 
 1951                 normalizedLocalPath = localPath;
 
 1953                 normalizedLocalPath = Paths.get(localPath).normalize().toString();
 
 1955         } 
catch (InvalidPathException ex) {
 
 1956             String errorMsg = 
"Invalid local path provided: " + localPath; 
 
 1961         Report report = this.caseDb.
addReport(normalizedLocalPath, srcModuleName, reportName, parent);
 
 1987         for (
Report report : reports) {
 
 1994             logger.log(Level.SEVERE, 
"Unable to retrieve the hasData status from the db", ex);
 
 1997         for (
Report report : reports) {
 
 2019         "Case.exceptionMessage.metadataUpdateError=Failed to update case metadata" 
 2021     void updateCaseDetails(CaseDetails caseDetails) 
throws CaseActionException {
 
 2024             metadata.setCaseDetails(caseDetails);
 
 2025         } 
catch (CaseMetadataException ex) {
 
 2026             throw new CaseActionException(Bundle.Case_exceptionMessage_metadataUpdateError(), ex);
 
 2030                 CaseNodeData nodeData = CaseNodeData.readCaseNodeData(metadata.
getCaseDirectory());
 
 2032                 CaseNodeData.writeCaseNodeData(nodeData);
 
 2033             } 
catch (CaseNodeDataException | InterruptedException ex) {
 
 2034                 throw new CaseActionException(Bundle.Case_exceptionMessage_couldNotUpdateCaseNodeData(ex.getLocalizedMessage()), ex);
 
 2037         if (!oldCaseDetails.getCaseNumber().equals(caseDetails.
getCaseNumber())) {
 
 2038             eventPublisher.
publish(
new AutopsyEvent(Events.NUMBER.toString(), oldCaseDetails.getCaseNumber(), caseDetails.
getCaseNumber()));
 
 2040         if (!oldCaseDetails.getExaminerName().equals(caseDetails.
getExaminerName())) {
 
 2041             eventPublisher.
publish(
new AutopsyEvent(Events.NUMBER.toString(), oldCaseDetails.getExaminerName(), caseDetails.
getExaminerName()));
 
 2044             eventPublisher.
publish(
new AutopsyEvent(Events.NAME.toString(), oldCaseDetails.getCaseDisplayName(), caseDetails.
getCaseDisplayName()));
 
 2046         eventPublisher.
publish(
new AutopsyEvent(Events.CASE_DETAILS.toString(), oldCaseDetails, caseDetails));
 
 2047         if (RuntimeProperties.runningWithGUI()) {
 
 2048             SwingUtilities.invokeLater(() -> {
 
 2052                 } 
catch (Exception ex) {
 
 2053                     logger.log(Level.SEVERE, 
"Error updating case name in UI", ex); 
 
 2081         metadata = caseMetaData;
 
 2115         "Case.progressIndicatorCancelButton.label=Cancel",
 
 2116         "Case.progressMessage.preparing=Preparing...",
 
 2117         "Case.progressMessage.cancelling=Cancelling...",
 
 2118         "Case.exceptionMessage.cancelled=Cancelled.",
 
 2119         "# {0} - exception message", 
"Case.exceptionMessage.execExceptionWrapperMessage={0}" 
 2129             if (allowCancellation) {
 
 2133                         progressIndicatorTitle,
 
 2134                         new String[]{Bundle.Case_progressIndicatorCancelButton_label()},
 
 2135                         Bundle.Case_progressIndicatorCancelButton_label(),
 
 2136                         cancelButtonListener);
 
 2140                         progressIndicatorTitle);
 
 2145         progressIndicator.
start(Bundle.Case_progressMessage_preparing());
 
 2154         caseActionExecutor = Executors.newSingleThreadExecutor(threadFactory);
 
 2155         Future<Void> future = caseActionExecutor.submit(() -> {
 
 2157                 caseAction.
execute(progressIndicator, additionalParams);
 
 2161                     if (null == resourcesLock) {
 
 2162                         throw new CaseActionException(Bundle.Case_creationException_couldNotAcquireResourcesLock());
 
 2164                     caseAction.
execute(progressIndicator, additionalParams);
 
 2165                 } 
catch (CaseActionException ex) {
 
 2172         if (null != cancelButtonListener) {
 
 2181         } 
catch (InterruptedException discarded) {
 
 2185             if (null != cancelButtonListener) {
 
 2188                 future.cancel(
true);
 
 2191         } 
catch (CancellationException discarded) {
 
 2197         } 
catch (ExecutionException ex) {
 
 2202             throw new CaseActionException(Bundle.Case_exceptionMessage_execExceptionWrapperMessage(ex.getCause().getLocalizedMessage()), ex);
 
 2204             progressIndicator.
finish();
 
 2224         assert (additionalParams == null);
 
 2245         } 
catch (CaseActionException ex) {
 
 2254             } 
catch (InterruptedException discarded) {
 
 2256             close(progressIndicator);
 
 2276         assert (additionalParams == null);
 
 2298         } 
catch (CaseActionException ex) {
 
 2307             } 
catch (InterruptedException discarded) {
 
 2309             close(progressIndicator);
 
 2320         "Case_checkImagePaths_noPaths=The following images had no associated paths: {0}",
 
 2321         "Case_checkImagePaths_exceptionOccurred=An exception occurred while checking if image paths are present" 
 2325         if (StringUtils.isNotBlank(
this.metadata.getContentProviderName())) {
 
 2331             List<Image> noPathImages = 
new ArrayList<>();
 
 2332             List<Image> images = this.caseDb.
getImages();
 
 2333             for (
Image img: images) {
 
 2334                 if (ArrayUtils.isEmpty(img.getPaths())) {
 
 2335                     noPathImages.add(img);
 
 2339             if (!noPathImages.isEmpty()) {
 
 2340                 String imageListStr = noPathImages.stream().map(
Image::getName).collect(Collectors.joining(
", "));
 
 2341                 throw new CaseActionException(Bundle.Case_checkImagePaths_noPaths(imageListStr));
 
 2344             throw new CaseActionException(Bundle.Case_checkImagePaths_exceptionOccurred(), ex);
 
 2358         "# {0} - case", 
"Case.openFileSystems.retrievingImages=Retrieving images for case: {0}...",
 
 2359         "# {0} - image", 
"Case.openFileSystems.openingImage=Opening all filesystems for image: {0}..." 
 2362         if (backgroundOpenFileSystemsFuture != null && !backgroundOpenFileSystemsFuture.isDone()) {
 
 2363             backgroundOpenFileSystemsFuture.cancel(
true);
 
 2392             caseName = (this.tskCase != null) ? this.tskCase.
getDatabaseName() : 
"";
 
 2403             if (Thread.interrupted()) {
 
 2404                 throw new InterruptedException();
 
 2414             progressIndicator.
progress(Bundle.Case_openFileSystems_retrievingImages(caseName));
 
 2420                         String.format(
"Could not obtain images while opening case: %s.", caseName),
 
 2437             byte[] tempBuff = 
new byte[512];
 
 2439             for (
Image image : images) {
 
 2440                 String imageStr = image.getName();
 
 2442                 progressIndicator.
progress(Bundle.Case_openFileSystems_openingImage(imageStr));
 
 2447                     fileSystem.read(tempBuff, 0, 512);
 
 2459                 if (images == null) {
 
 2467                             String.format(
"Skipping background load of file systems due to large number of images in case (%d)", images.size()));
 
 2473             } 
catch (InterruptedException ex) {
 
 2476                         String.format(
"Background operation opening all file systems in %s has been cancelled.", caseName));
 
 2477             } 
catch (Exception ex) {
 
 2479                 logger.log(Level.WARNING, 
"Error while opening file systems in background", ex);
 
 2500         "Case.progressMessage.deletingDataSource=Removing the data source from the case...",
 
 2501         "Case.exceptionMessage.dataSourceNotFound=The data source was not found.",
 
 2502         "Case.exceptionMessage.errorDeletingDataSourceFromCaseDb=An error occurred while removing the data source from the case database.",
 
 2503         "Case.exceptionMessage.errorDeletingDataSourceFromTextIndex=An error occurred while removing the data source from the text index.",})
 
 2504     Void deleteDataSource(ProgressIndicator progressIndicator, Object additionalParams) 
throws CaseActionException {
 
 2505         assert (additionalParams instanceof Long);
 
 2506         open(progressIndicator, null);
 
 2508             progressIndicator.progress(Bundle.Case_progressMessage_deletingDataSource());
 
 2509             Long dataSourceObjectID = (Long) additionalParams;
 
 2511                 DataSource dataSource = this.caseDb.
getDataSource(dataSourceObjectID);
 
 2512                 if (dataSource == null) {
 
 2513                     throw new CaseActionException(Bundle.Case_exceptionMessage_dataSourceNotFound());
 
 2515                 SleuthkitCaseAdminUtil.deleteDataSource(this.caseDb, dataSourceObjectID);
 
 2516             } 
catch (TskDataException | TskCoreException ex) {
 
 2517                 throw new CaseActionException(Bundle.Case_exceptionMessage_errorDeletingDataSourceFromCaseDb(), ex);
 
 2521             } 
catch (KeywordSearchServiceException ex) {
 
 2522                 throw new CaseActionException(Bundle.Case_exceptionMessage_errorDeletingDataSourceFromTextIndex(), ex);
 
 2524             eventPublisher.
publish(
new DataSourceDeletedEvent(dataSourceObjectID));
 
 2527             close(progressIndicator);
 
 2544         if (portableCaseFolder.exists()) {
 
 2545             throw new TskCoreException(
"Portable case folder " + portableCaseFolder.toString() + 
" already exists");
 
 2547         if (!portableCaseFolder.mkdirs()) {
 
 2548             throw new TskCoreException(
"Error creating portable case folder " + portableCaseFolder.toString());
 
 2556             portableCaseMetadata.setCaseDatabaseName(SINGLE_USER_CASE_DB_NAME);
 
 2566         return portableSleuthkitCase;
 
 2579         if (Thread.currentThread().isInterrupted()) {
 
 2580             throw new CaseActionCancelledException(Bundle.Case_exceptionMessage_cancelled());
 
 2595         "Case.progressMessage.creatingCaseDirectory=Creating case directory..." 
 2602         progressIndicator.
progress(Bundle.Case_progressMessage_creatingCaseDirectory());
 
 2604             progressIndicator.
progress(Bundle.Case_progressMessage_creatingCaseDirectory());
 
 2616         "Case.progressMessage.switchingLogDirectory=Switching log directory..." 
 2619         progressIndicator.
progress(Bundle.Case_progressMessage_switchingLogDirectory());
 
 2635         "Case.progressMessage.savingCaseMetadata=Saving case metadata to file...",
 
 2636         "# {0} - exception message", 
"Case.exceptionMessage.couldNotSaveCaseMetadata=Failed to save case metadata:\n{0}." 
 2639         progressIndicator.
progress(Bundle.Case_progressMessage_savingCaseMetadata());
 
 2641             this.metadata.writeToFile();
 
 2643             throw new CaseActionException(Bundle.Case_exceptionMessage_couldNotSaveCaseMetadata(ex.getLocalizedMessage()), ex);
 
 2659         "Case.progressMessage.creatingCaseNodeData=Creating coordination service node data...",
 
 2660         "# {0} - exception message", 
"Case.exceptionMessage.couldNotCreateCaseNodeData=Failed to create coordination service node data:\n{0}." 
 2664             progressIndicator.
progress(Bundle.Case_progressMessage_creatingCaseNodeData());
 
 2668                 throw new CaseActionException(Bundle.Case_exceptionMessage_couldNotCreateCaseNodeData(ex.getLocalizedMessage()), ex);
 
 2685         "Case.progressMessage.updatingCaseNodeData=Updating coordination service node data...",
 
 2686         "# {0} - exception message", 
"Case.exceptionMessage.couldNotUpdateCaseNodeData=Failed to update coordination service node data:\n{0}." 
 2690             progressIndicator.
progress(Bundle.Case_progressMessage_updatingCaseNodeData());
 
 2696                 throw new CaseActionException(Bundle.Case_exceptionMessage_couldNotUpdateCaseNodeData(ex.getLocalizedMessage()), ex);
 
 2707         "Case.progressMessage.clearingTempDirectory=Clearing case temp directory..." 
 2713         progressIndicator.
progress(Bundle.Case_progressMessage_clearingTempDirectory());
 
 2729         "Case.progressMessage.creatingCaseDatabase=Creating case database...",
 
 2730         "# {0} - exception message", 
"Case.exceptionMessage.couldNotGetDbServerConnectionInfo=Failed to get case database server conneciton info:\n{0}.",
 
 2731         "# {0} - exception message", 
"Case.exceptionMessage.couldNotCreateCaseDatabase=Failed to create case database:\n{0}.",
 
 2732         "# {0} - exception message", 
"Case.exceptionMessage.couldNotSaveDbNameToMetadataFile=Failed to save case database name to case metadata file:\n{0}." 
 2735         progressIndicator.
progress(Bundle.Case_progressMessage_creatingCaseDatabase());
 
 2744                 metadata.setCaseDatabaseName(SINGLE_USER_CASE_DB_NAME);
 
 2756             throw new CaseActionException(Bundle.Case_exceptionMessage_couldNotCreateCaseDatabase(ex.getLocalizedMessage()), ex);
 
 2758             throw new CaseActionException(Bundle.Case_exceptionMessage_couldNotGetDbServerConnectionInfo(ex.getLocalizedMessage()), ex);
 
 2760             throw new CaseActionException(Bundle.Case_exceptionMessage_couldNotSaveDbNameToMetadataFile(ex.getLocalizedMessage()), ex);
 
 2776         "Case.progressMessage.openingCaseDatabase=Opening case database...",
 
 2777         "# {0} - exception message", 
"Case.exceptionMessage.couldNotOpenCaseDatabase=Failed to open case database:\n{0}.",
 
 2778         "# {0} - exception message", 
"Case.exceptionMessage.unsupportedSchemaVersionMessage=Unsupported case database schema version:\n{0}.",
 
 2779         "Case.exceptionMessage.contentProviderCouldNotBeFound=Content provider was specified for the case but could not be loaded.",
 
 2780         "Case.open.exception.multiUserCaseNotEnabled=Cannot open a multi-user case if multi-user cases are not enabled. See Tools, Options, Multi-User." 
 2783         progressIndicator.
progress(Bundle.Case_progressMessage_openingCaseDatabase());
 
 2789                 if (metadata.
getContentProviderName().trim().toUpperCase().startsWith(CT_PROVIDER_PREFIX.toUpperCase())) {
 
 2792                 throw new CaseActionException(Bundle.Case_exceptionMessage_contentProviderCouldNotBeFound());
 
 2800                 throw new CaseActionException(Bundle.Case_open_exception_multiUserCaseNotEnabled());
 
 2804             throw new CaseActionException(Bundle.Case_exceptionMessage_unsupportedSchemaVersionMessage(ex.getLocalizedMessage()), ex);
 
 2806             throw new CaseActionException(Bundle.Case_exceptionMessage_couldNotGetDbServerConnectionInfo(ex.getLocalizedMessage()), ex);
 
 2809             throw new CaseActionException(Bundle.Case_exceptionMessage_couldNotOpenCaseDatabase(ex.getLocalizedMessage()), ex);    
 
 2820         "# {0} - appplicationName",
 
 2821         "Case_throwIfConcurrentDbAccessException_fileLock_concurrentAccessException=The case is open in {0}. Please close it before attempting to open it in Autopsy.",
 
 2822         "Case_throwIfConcurrentDbAccessException_fileLock_concurrentAccessException_defaultApp=another application" 
 2826         Throwable curEx = ex;
 
 2828         for (
int i = 0; i < 10; i++) {
 
 2829             if (curEx == null) {
 
 2832                 concurrentEx = foundEx;
 
 2835                 curEx = curEx.getCause();    
 
 2839         if (concurrentEx != null) {
 
 2840             throw new CaseActionException(Bundle.Case_throwIfConcurrentDbAccessException_fileLock_concurrentAccessException(
 
 2842                             Bundle.Case_throwIfConcurrentDbAccessException_fileLock_concurrentAccessException_defaultApp())
 
 2858         Collection<? extends AutopsyContentProvider> customContentProviders = Lookup.getDefault().lookupAll(
AutopsyContentProvider.class);
 
 2859         if (customContentProviders != null) {
 
 2862                 if (customProvider == null || !StringUtils.equalsIgnoreCase(providerName, customProvider.getName())) {
 
 2867                 if (contentProvider != null) {
 
 2868                     return contentProvider;
 
 2884         "Case.progressMessage.openingCaseLevelServices=Opening case-level services...",})
 
 2886         progressIndicator.
progress(Bundle.Case_progressMessage_openingCaseLevelServices());
 
 2887         this.caseServices = 
new Services(caseDb);
 
 2908     @NbBundle.Messages({
 
 2909         "Case.progressMessage.openingApplicationServiceResources=Opening application service case resources...",
 
 2910         "# {0} - service name", 
"Case.serviceOpenCaseResourcesProgressIndicator.title={0} Opening Case Resources",
 
 2911         "# {0} - service name", 
"Case.serviceOpenCaseResourcesProgressIndicator.cancellingMessage=Cancelling opening case resources by {0}...",
 
 2912         "# {0} - service name", 
"Case.servicesException.notificationTitle={0} Error" 
 2923         progressIndicator.
progress(Bundle.Case_progressMessage_openingApplicationServiceResources());
 
 2935                 cancelButtonListener = 
new CancelButtonListener(Bundle.Case_serviceOpenCaseResourcesProgressIndicator_cancellingMessage(service.getServiceName()));
 
 2938                         Bundle.Case_serviceOpenCaseResourcesProgressIndicator_title(service.getServiceName()),
 
 2939                         new String[]{Bundle.Case_progressIndicatorCancelButton_label()},
 
 2940                         Bundle.Case_progressIndicatorCancelButton_label(),
 
 2941                         cancelButtonListener);
 
 2945             appServiceProgressIndicator.
start(Bundle.Case_progressMessage_preparing());
 
 2947             String threadNameSuffix = service.getServiceName().replaceAll(
"[ ]", 
"-"); 
 
 2948             threadNameSuffix = threadNameSuffix.toLowerCase();
 
 2950             ExecutorService executor = Executors.newSingleThreadExecutor(threadFactory);
 
 2951             Future<Void> future = executor.submit(() -> {
 
 2952                 service.openCaseResources(context);
 
 2955             if (null != cancelButtonListener) {
 
 2967             } 
catch (InterruptedException discarded) {
 
 2972                 future.cancel(
true);
 
 2973             } 
catch (CancellationException discarded) {
 
 2981             } 
catch (ExecutionException ex) {
 
 2988                 Case.
logger.log(Level.SEVERE, String.format(
"%s failed to open case resources for %s", service.getServiceName(), this.
getDisplayName()), ex);
 
 2990                     SwingUtilities.invokeLater(() -> {
 
 3002                 appServiceProgressIndicator.
finish();
 
 3020         "Case.progressMessage.settingUpNetworkCommunications=Setting up network communications...",
 
 3021         "# {0} - exception message", 
"Case.exceptionMessage.couldNotOpenRemoteEventChannel=Failed to open remote events channel:\n{0}.",
 
 3022         "# {0} - exception message", 
"Case.exceptionMessage.couldNotCreatCollaborationMonitor=Failed to create collaboration monitor:\n{0}." 
 3026             progressIndicator.
progress(Bundle.Case_progressMessage_settingUpNetworkCommunications());
 
 3030                 collaborationMonitor = 
new CollaborationMonitor(metadata.
getCaseName());
 
 3032                 throw new CaseActionException(Bundle.Case_exceptionMessage_couldNotOpenRemoteEventChannel(ex.getLocalizedMessage()), ex);
 
 3033             } 
catch (CollaborationMonitor.CollaborationMonitorException ex) {
 
 3034                 throw new CaseActionException(Bundle.Case_exceptionMessage_couldNotCreatCollaborationMonitor(ex.getLocalizedMessage()), ex);
 
 3062                     Bundle.Case_progressIndicatorTitle_closingCase());
 
 3066         progressIndicator.
start(Bundle.Case_progressMessage_preparing());
 
 3075         Future<Void> future = caseActionExecutor.submit(() -> {
 
 3077                 close(progressIndicator);
 
 3084                 progressIndicator.
progress(Bundle.Case_progressMessage_preparing());
 
 3086                     if (null == resourcesLock) {
 
 3087                         throw new CaseActionException(Bundle.Case_creationException_couldNotAcquireResourcesLock());
 
 3089                     close(progressIndicator);
 
 3103         } 
catch (InterruptedException | CancellationException unused) {
 
 3110         } 
catch (ExecutionException ex) {
 
 3111             throw new CaseActionException(Bundle.Case_exceptionMessage_execExceptionWrapperMessage(ex.getCause().getMessage()), ex);
 
 3114             progressIndicator.
finish();
 
 3124         "Case.progressMessage.shuttingDownNetworkCommunications=Shutting down network communications...",
 
 3125         "Case.progressMessage.closingApplicationServiceResources=Closing case-specific application service resources...",
 
 3126         "Case.progressMessage.closingCaseDatabase=Closing case database..." 
 3136             progressIndicator.
progress(Bundle.Case_progressMessage_shuttingDownNetworkCommunications());
 
 3137             if (null != collaborationMonitor) {
 
 3138                 collaborationMonitor.shutdown();
 
 3147         progressIndicator.
progress(Bundle.Case_progressMessage_closingApplicationServiceResources());
 
 3153         if (null != caseDb) {
 
 3154             progressIndicator.
progress(Bundle.Case_progressMessage_closingCaseDatabase());
 
 3167         progressIndicator.
progress(Bundle.Case_progressMessage_switchingLogDirectory());
 
 3176         "# {0} - serviceName", 
"Case.serviceCloseResourcesProgressIndicator.title={0} Closing Case Resources",
 
 3177         "# {0} - service name", 
"# {1} - exception message", 
"Case.servicesException.serviceResourcesCloseError=Could not close case resources for {0} service: {1}" 
 3190                         Bundle.Case_serviceCloseResourcesProgressIndicator_title(service.getServiceName()));
 
 3194             progressIndicator.
start(Bundle.Case_progressMessage_preparing());
 
 3196             String threadNameSuffix = service.getServiceName().replaceAll(
"[ ]", 
"-"); 
 
 3197             threadNameSuffix = threadNameSuffix.toLowerCase();
 
 3199             ExecutorService executor = Executors.newSingleThreadExecutor(threadFactory);
 
 3200             Future<Void> future = executor.submit(() -> {
 
 3201                 service.closeCaseResources(context);
 
 3206             } 
catch (InterruptedException ex) {
 
 3207                 Case.
logger.log(Level.SEVERE, String.format(
"Unexpected interrupt while waiting on %s service to close case resources", service.getServiceName()), ex);
 
 3208             } 
catch (CancellationException ex) {
 
 3209                 Case.
logger.log(Level.SEVERE, String.format(
"Unexpected cancellation while waiting on %s service to close case resources", service.getServiceName()), ex);
 
 3210             } 
catch (ExecutionException ex) {
 
 3211                 Case.
logger.log(Level.SEVERE, String.format(
"%s service failed to open case resources", service.getServiceName()), ex);
 
 3214                             Bundle.Case_servicesException_notificationTitle(service.getServiceName()),
 
 3215                             Bundle.Case_servicesException_serviceResourcesCloseError(service.getServiceName(), ex.getLocalizedMessage())));
 
 3219                 progressIndicator.
finish();
 
 3230         "Case.lockingException.couldNotAcquireSharedLock=Failed to get a shared lock on the case.",
 
 3231         "Case.lockingException.couldNotAcquireExclusiveLock=Failed to get an exclusive lock on the case." 
 3242                     throw new CaseActionException(Bundle.Case_lockingException_couldNotAcquireSharedLock());
 
 3244                     throw new CaseActionException(Bundle.Case_lockingException_couldNotAcquireExclusiveLock());
 
 3249                 throw new CaseActionException(Bundle.Case_lockingException_couldNotAcquireSharedLock(), ex);
 
 3251                 throw new CaseActionException(Bundle.Case_lockingException_couldNotAcquireExclusiveLock(), ex);
 
 3265                 logger.log(Level.SEVERE, String.format(
"Failed to release shared case directory lock for %s", 
getMetadata().
getCaseDirectory()), ex);
 
 3278         if (!subDirectory.exists()) {
 
 3279             subDirectory.mkdirs();
 
 3281         return subDirectory.toString();
 
 3297         "Case.exceptionMessage.errorsDeletingCase=Errors occured while deleting the case. See the application log for details." 
 3300         boolean errorsOccurred = 
false;
 
 3304             errorsOccurred = 
true;
 
 3310         } 
catch (CaseActionException ex) {
 
 3311             errorsOccurred = 
true;
 
 3317         if (errorsOccurred) {
 
 3318             throw new CaseActionException(Bundle.Case_exceptionMessage_errorsDeletingCase());
 
 3342         "Case.progressMessage.connectingToCoordSvc=Connecting to coordination service...",
 
 3343         "# {0} - exception message", 
"Case.exceptionMessage.failedToConnectToCoordSvc=Failed to connect to coordination service:\n{0}.",
 
 3344         "Case.exceptionMessage.cannotGetLockToDeleteCase=Cannot delete case because it is open for another user or host.",
 
 3345         "# {0} - exception message", 
"Case.exceptionMessage.failedToLockCaseForDeletion=Failed to exclusively lock case for deletion:\n{0}.",
 
 3346         "Case.progressMessage.fetchingCoordSvcNodeData=Fetching coordination service node data for the case...",
 
 3347         "# {0} - exception message", 
"Case.exceptionMessage.failedToFetchCoordSvcNodeData=Failed to fetch coordination service node data:\n{0}.",
 
 3348         "Case.progressMessage.deletingResourcesCoordSvcNode=Deleting case resources coordination service node...",
 
 3349         "Case.progressMessage.deletingCaseDirCoordSvcNode=Deleting case directory coordination service node..." 
 3352         progressIndicator.
progress(Bundle.Case_progressMessage_connectingToCoordSvc());
 
 3358             throw new CaseActionException(Bundle.Case_exceptionMessage_failedToConnectToCoordSvc(ex.getLocalizedMessage()));
 
 3362         boolean errorsOccurred = 
false;
 
 3364             if (dirLock == null) {
 
 3366                 throw new CaseActionException(Bundle.Case_exceptionMessage_cannotGetLockToDeleteCase());
 
 3369             progressIndicator.
progress(Bundle.Case_progressMessage_fetchingCoordSvcNodeData());
 
 3374                 throw new CaseActionException(Bundle.Case_exceptionMessage_failedToFetchCoordSvcNodeData(ex.getLocalizedMessage()));
 
 3379             progressIndicator.
progress(Bundle.Case_progressMessage_deletingResourcesCoordSvcNode());
 
 3385                     errorsOccurred = 
true;
 
 3386                     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); 
 
 3388             } 
catch (InterruptedException ex) {
 
 3389                 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); 
 
 3394             throw new CaseActionException(Bundle.Case_exceptionMessage_failedToLockCaseForDeletion(ex.getLocalizedMessage()));
 
 3397         if (!errorsOccurred) {
 
 3398             progressIndicator.
progress(Bundle.Case_progressMessage_deletingCaseDirCoordSvcNode());
 
 3404                 errorsOccurred = 
true;
 
 3408         if (errorsOccurred) {
 
 3409             throw new CaseActionException(Bundle.Case_exceptionMessage_errorsDeletingCase());
 
 3439         boolean errorsOccurred = 
false;
 
 3446             errorsOccurred = 
true;
 
 3449             errorsOccurred = 
true;
 
 3451         } 
catch (CaseActionException ex) {
 
 3452             errorsOccurred = 
true;
 
 3455         return errorsOccurred;
 
 3479         "Case.progressMessage.deletingCaseDatabase=Deleting case database..." 
 3483             progressIndicator.
progress(Bundle.Case_progressMessage_deletingCaseDatabase());
 
 3484             logger.log(Level.INFO, String.format(
"Deleting case database for %s (%s) in %s", caseNodeData.
getDisplayName(), caseNodeData.
getName(), caseNodeData.
getDirectory())); 
 
 3486             String url = 
"jdbc:postgresql://" + info.
getHost() + 
":" + info.
getPort() + 
"/postgres"; 
 
 3487             Class.forName(
"org.postgresql.Driver"); 
 
 3488             try (Connection connection = DriverManager.getConnection(url, info.
getUserName(), info.
getPassword()); Statement statement = connection.createStatement()) {
 
 3489                 String dbExistsQuery = 
"SELECT 1 from pg_database WHERE datname = '" + metadata.
getCaseDatabaseName() + 
"'"; 
 
 3490                 try (ResultSet queryResult = statement.executeQuery(dbExistsQuery)) {
 
 3491                     if (queryResult.next()) {
 
 3493                         statement.execute(deleteCommand);
 
 3534         "Case.progressMessage.deletingTextIndex=Deleting text index..." 
 3537         progressIndicator.
progress(Bundle.Case_progressMessage_deletingTextIndex());
 
 3541             searchService.deleteTextIndex(metadata);
 
 3577         "Case.progressMessage.deletingCaseDirectory=Deleting case directory..." 
 3580         progressIndicator.
progress(Bundle.Case_progressMessage_deletingCaseDirectory());
 
 3582             throw new CaseActionException(String.format(
"Failed to delete %s", metadata.
getCaseDirectory())); 
 
 3594         "Case.progressMessage.removingCaseFromRecentCases=Removing case from Recent Cases menu..." 
 3598             progressIndicator.
progress(Bundle.Case_progressMessage_removingCaseFromRecentCases());
 
 3599             SwingUtilities.invokeLater(() -> {
 
 3615         boolean isNodeNodeEx = 
false;
 
 3616         Throwable cause = ex.getCause();
 
 3617         if (cause != null) {
 
 3618             String causeMessage = cause.getMessage();
 
 3619             isNodeNodeEx = causeMessage.contains(NO_NODE_ERROR_MSG_FRAGMENT);
 
 3621         return isNodeNodeEx;
 
 3640             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);
 
 3659         if (!hasDataSource) {
 
 3674         String query = 
"SELECT count(*) AS count FROM (SELECT * FROM data_source_info LIMIT 1)t";
 
 3676             ResultSet resultSet = dbQuery.getResultSet();
 
 3677             if (resultSet.next()) {
 
 3678                 return resultSet.getLong(
"count") > 0;
 
 3681         } 
catch (SQLException ex) {
 
 3682             logger.log(Level.SEVERE, 
"Error accessing case database", ex); 
 
 3683             throw new TskCoreException(
"Error accessing case databse", ex);
 
 3698         String query = 
"SELECT SUM(cnt) total FROM " 
 3699                 + 
"(SELECT COUNT(*) AS cnt FROM " 
 3700                 + 
"(SELECT * FROM tsk_objects LIMIT 1)t " 
 3702                 + 
"SELECT COUNT(*) AS cnt FROM " 
 3703                 + 
"(SELECT * FROM tsk_hosts LIMIT 1)r) s";
 
 3705             ResultSet resultSet = dbQuery.getResultSet();
 
 3706             if (resultSet.next()) {
 
 3707                 return resultSet.getLong(
"total") > 0;
 
 3711         } 
catch (SQLException ex) {
 
 3712             logger.log(Level.SEVERE, 
"Error accessing case database", ex); 
 
 3713             throw new TskCoreException(
"Error accessing case databse", ex);
 
 3737         R 
execute(T progressIndicator, V additionalParams) 
throws CaseActionException;
 
 3835                         ((ModalDialogProgressIndicator) progressIndicator).
setCancelling(cancellationMessage);
 
 3864             return new Thread(task, threadName);
 
 3901     public static void create(String caseDir, String caseDisplayName, String caseNumber, String examiner) 
throws CaseActionException {
 
 3926     public static void create(String caseDir, String caseDisplayName, String caseNumber, String examiner, 
CaseType caseType) 
throws CaseActionException {
 
 3942     public static void open(String caseMetadataFilePath) 
throws CaseActionException {
 
 3999         return new File(filePath).isFile();
 
 4038         return "ModuleOutput"; 
 
 4051     public static PropertyChangeSupport
 
 4053         return new PropertyChangeSupport(
Case.class
 
 4085     public Image addImage(String imgPath, 
long imgId, String timeZone) 
throws CaseActionException {
 
 4089             return newDataSource;
 
 4091             throw new CaseActionException(NbBundle.getMessage(
this.getClass(), 
"Case.addImg.exception.msg"), ex);
 
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)
List< Report > getAllReports()
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)
void publishOsAccountsUpdatedEvent(TskEvent.OsAccountsUpdatedTskEvent event)
static synchronized IngestManager getInstance()
void deleteNode(CategoryNode category, String nodePath)
static final ExecutorService openFileSystemsExecutor
static final String NO_NODE_ERROR_MSG_FRAGMENT
void publishPersonsUpdatedEvent(TskEvent.PersonsUpdatedTskEvent event)
static boolean runningWithGUI
static void closeCurrentCase()
void publishHostsDeletedEvent(TskEvent.HostsDeletedTskEvent event)
void setDeletedFlag(DeletedFlags flag)
void acquireCaseLock(CaseLockType lockType)
String getTempDirectory()
synchronized void close()
static boolean existsCurrentCase()
boolean isDeletedFlagSet(DeletedFlags flag)
static void removePropertyChangeListener(PropertyChangeListener listener)
void start(String message, int totalWorkUnits)
static final Logger logger
void notifyBlackBoardArtifactTagAdded(BlackboardArtifactTag newTag, List< BlackboardArtifactTag > removedTagList)
void publish(AutopsyEvent event)
String getLocalizedDisplayName()
static Future<?> backgroundOpenFileSystemsFuture
ADDING_DATA_SOURCE_FAILED
static final String EXPORT_FOLDER
void throwIfConcurrentDbAccessException(Exception ex)
static void createCaseDirectory(String caseDirPath, CaseType caseType)
String getCaseDirectory()
static String getAppName()
void publishOsAccountInstancesAddedEvent(TskEvent.OsAcctInstancesAddedTskEvent event)
void notifyTagDefinitionChanged(String changedTagName)
void openFileSystemsInBackground()
void notifyContentTagAdded(ContentTag newTag, List< ContentTag > deletedTagList)
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 publishHostsAddedToPersonEvent(TskEvent.HostsAddedToPersonTskEvent event)
void publishTimelineEventAddedEvent(TimelineManager.TimelineEventAddedEvent event)
synchronized static void setLogDirectory(String directoryPath)
volatile ExecutorService caseActionExecutor
void notifyCentralRepoCommentChanged(long contentId, String newComment)
static final String APP_NAME
TaskThreadFactory(String threadName)
static final String CACHE_FOLDER
static String getAutopsyVersion()
CaseType(String typeName)
List< Image > getImages()
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)
Map< Long, List< String > > getImagePaths()
void notifyDataSourceNameChanged(Content dataSource, String newName)
static String getCustomTempDirectory()
static CaseDbConnectionInfo getDatabaseConnectionInfo()
String getModulesOutputDirAbsPath()
static void create(String caseDir, String caseDisplayName, String caseNumber, String examiner, CaseType caseType)
void publishPersonsDeletedEvent(TskEvent.PersonsDeletedTskEvent event)
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
final long MAX_IMAGE_THRESHOLD
List< Report > getAllReports()
static boolean canAddDataSources()
static boolean isValidName(String caseName)
void openCaseDataBase(ProgressIndicator progressIndicator)
void createCaseDirectoryIfDoesNotExist(ProgressIndicator progressIndicator)
CollaborationMonitor collaborationMonitor
void openCommunicationChannels(ProgressIndicator progressIndicator)
void deleteReport(Report report)
static void shutDownTaskExecutor(ExecutorService executor)
static void closeCoreWindows()
ProgressIndicator getProgressIndicator()
static String getModulesOutputDirRelPath()
List< Image > getImages()
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)
void publisHostsRemovedFromPersonEvent(TskEvent.HostsRemovedFromPersonTskEvent event)
Image getImageById(long id)
Set< TimeZone > getTimeZone()
static void writeCaseNodeData(CaseNodeData nodeData)
static final String MODULE_FOLDER
static final String CT_PROVIDER_PREFIX
void unregisterForEvents(Object listener)
void openCaseLevelServices(ProgressIndicator progressIndicator)
static void create(String caseDir, String caseDisplayName, String caseNumber, String examiner)
void openFileSystems(List< Image > images)
Path getBaseSystemTempPath()
synchronized void openRemoteEventChannel(String channelName)
String getCaseDisplayName()
void publishPersonsAddedEvent(TskEvent.PersonsAddedTskEvent event)
void createCaseNodeData(ProgressIndicator progressIndicator)
void publicTagNamesAdded(TskEvent.TagNamesAddedTskEvent event)
static void invokeStartupDialog()
void updateDataParameters()
CaseMetadata getMetadata()
static String displayNameToUniqueName(String caseDisplayName)
static void deleteFromRecentCases(CaseMetadata metadata, ProgressIndicator progressIndicator)
String getConflictingApplicationName()
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)
default void setCancelling(String cancellingMessage)
void setLastAccessDate(Date lastAccessDate)
void close(ProgressIndicator progressIndicator)
final ProgressIndicator progressIndicator
SleuthkitCase getSleuthkitCase()
void notifyBlackBoardArtifactTagAdded(BlackboardArtifactTag newTag)
static PropertyChangeSupport getPropertyChangeSupport()
void publishOsAccountDeletedEvent(TskEvent.OsAccountsDeletedTskEvent event)
Report addReport(String localPath, String sourceModuleName, String reportName)
String getCacheDirectory()
static void addPropertyChangeListener(PropertyChangeListener listener)
void publishHostsUpdatedEvent(TskEvent.HostsUpdatedTskEvent event)
void removeSubscriber(Set< String > eventNames, PropertyChangeListener subscriber)
String getModuleDirectory()
List< Content > getRootObjects()
void createCaseDatabase(ProgressIndicator progressIndicator)
Thread newThread(Runnable task)
static void removeEventSubscriber(String eventName, PropertyChangeListener subscriber)
void switchLoggingToCaseLogsDirectory(ProgressIndicator progressIndicator)
void publicTagSetsDeleted(TskEvent.TagSetsDeletedTskEvent event)
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)
static ContentStreamProvider loadContentProvider(String providerName)
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 TempDirChoice getTempDirChoice()
static CoordinationService.Lock acquireCaseResourcesLock(String caseDir)
Collection< FileSystem > getImageFileSystems(Image image)
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)
void publishOsAccountsAddedEvent(TskEvent.OsAccountsAddedTskEvent event)
static SleuthkitCase openCase(String dbPath)
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)
static SleuthkitCase newCase(String dbPath)
String getBackupDatabasePath()
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()
void openAppServiceCaseResources(ProgressIndicator progressIndicator, boolean isNewCase)
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)
DataSource getDataSource(long objectId)
static final String CASE_RESOURCES_THREAD_NAME
static StartupWindowProvider getInstance()
static void deleteCurrentCase()
void publishHostsAddedEvent(TskEvent.HostsAddedTskEvent event)
static boolean deleteDir(File dirPath)
static void createAsCurrentCase(String caseDir, String caseDisplayName, String caseNumber, String examiner, CaseType caseType)
void publicTagNamesUpdated(TskEvent.TagNamesUpdatedTskEvent event)
static void deleteCaseDirectory(CaseMetadata metadata, ProgressIndicator progressIndicator)
static synchronized DirectoryTreeTopComponent findInstance()
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
boolean dbHasDataSource()
static void deleteMultiUserCaseDatabase(CaseNodeData caseNodeData, CaseMetadata metadata, ProgressIndicator progressIndicator, Logger logger)
void publicTagNamesDeleted(TskEvent.TagNamesDeletedTskEvent event)
static boolean isCaseOpen()
String getTextIndexName()
static final String REPORTS_FOLDER
void progress(String message)
HOSTS_REMOVED_FROM_PERSON
static final String TEMP_FOLDER
BLACKBOARD_ARTIFACT_TAG_DELETED
static void checkForCancellation()
static boolean canDeleteCurrentCase()
void registerForEvents(Object listener)
static void addEventSubscriber(Set< String > eventNames, PropertyChangeListener subscriber)
void updateCaseNodeData(ProgressIndicator progressIndicator)
CaseDbQuery executeQuery(String query)
static void error(String message)
void publicTagSetsAdded(TskEvent.TagSetsAddedTskEvent event)
final SleuthkitCase tskCase
String getExaminerEmail()