19 package org.sleuthkit.autopsy.casemodule;
22 import com.google.common.annotations.Beta;
23 import com.google.common.eventbus.Subscribe;
24 import com.google.common.util.concurrent.ThreadFactoryBuilder;
25 import java.awt.Cursor;
27 import java.awt.Frame;
28 import java.awt.event.ActionEvent;
29 import java.awt.event.ActionListener;
30 import java.beans.PropertyChangeListener;
31 import java.beans.PropertyChangeSupport;
33 import java.lang.reflect.InvocationTargetException;
34 import java.nio.file.InvalidPathException;
35 import java.nio.file.Path;
36 import java.nio.file.Paths;
37 import java.sql.Connection;
38 import java.sql.DriverManager;
39 import java.sql.ResultSet;
40 import java.sql.SQLException;
41 import java.sql.Statement;
42 import java.text.SimpleDateFormat;
43 import java.util.Collection;
44 import java.util.Date;
45 import java.util.HashMap;
46 import java.util.HashSet;
47 import java.util.List;
50 import java.util.TimeZone;
51 import java.util.UUID;
52 import java.util.concurrent.CancellationException;
53 import java.util.concurrent.ExecutionException;
54 import java.util.concurrent.ExecutorService;
55 import java.util.concurrent.Executors;
56 import java.util.concurrent.Future;
57 import java.util.concurrent.ThreadFactory;
58 import java.util.concurrent.TimeUnit;
59 import java.util.logging.Level;
60 import java.util.stream.Collectors;
61 import java.util.stream.Stream;
62 import javax.annotation.concurrent.GuardedBy;
63 import javax.annotation.concurrent.ThreadSafe;
64 import javax.swing.JOptionPane;
65 import javax.swing.SwingUtilities;
66 import org.apache.commons.lang3.StringUtils;
67 import org.openide.util.Lookup;
68 import org.openide.util.NbBundle;
69 import org.openide.util.NbBundle.Messages;
70 import org.openide.util.actions.CallableSystemAction;
71 import org.openide.windows.WindowManager;
158 import org.
sleuthkit.datamodel.TskUnsupportedSchemaVersionException;
185 = Executors.newSingleThreadExecutor(
new ThreadFactoryBuilder().setNameFormat(
"case-open-file-systems-%d").build());
205 WindowManager.getDefault().invokeWhenUIReady(() -> {
206 mainFrame = WindowManager.getDefault().getMainWindow();
228 if (typeName != null) {
230 if (typeName.equalsIgnoreCase(c.toString())) {
254 "Case_caseType_singleUser=Single-user case",
255 "Case_caseType_multiUser=Multi-user case"
258 if (fromString(typeName) == SINGLE_USER_CASE) {
259 return Bundle.Case_caseType_singleUser();
261 return Bundle.Case_caseType_multiUser();
271 this.typeName = typeName;
286 return (otherTypeName == null) ?
false : typeName.equals(otherTypeName);
541 }
catch (TskCoreException ex) {
542 logger.log(Level.SEVERE,
"Unable to retrieve the hasData status from the db", ex);
585 }
catch (TskCoreException ex) {
586 logger.log(Level.SEVERE,
"Unable to retrieve the hasData status from the db", ex);
669 .map(Events::toString)
670 .collect(Collectors.toSet()), listener);
681 .map(Events::toString)
682 .collect(Collectors.toSet()), listener);
705 eventTypes.forEach((
Events event) -> {
750 eventTypes.forEach((
Events event) -> {
764 return !(caseName.contains(
"\\") || caseName.contains(
"/") || caseName.contains(
":")
765 || caseName.contains(
"*") || caseName.contains(
"?") || caseName.contains(
"\"")
766 || caseName.contains(
"<") || caseName.contains(
">") || caseName.contains(
"|"));
818 "Case.exceptionMessage.emptyCaseName=Must specify a case name.",
819 "Case.exceptionMessage.emptyCaseDir=Must specify a case directory path."
823 throw new CaseActionException(Bundle.Case_exceptionMessage_emptyCaseName());
825 if (caseDir.isEmpty()) {
826 throw new CaseActionException(Bundle.Case_exceptionMessage_emptyCaseDir());
845 "# {0} - exception message",
"Case.exceptionMessage.failedToReadMetadata=Failed to read case metadata:\n{0}.",
846 "Case.exceptionMessage.cannotOpenMultiUserCaseNoSettings=Multi-user settings are missing (see Tools, Options, Multi-user tab), cannot open a multi-user case."
851 metadata =
new CaseMetadata(Paths.get(caseMetadataFilePath));
853 throw new CaseActionException(Bundle.Case_exceptionMessage_failedToReadMetadata(ex.getLocalizedMessage()), ex);
856 throw new CaseActionException(Bundle.Case_exceptionMessage_cannotOpenMultiUserCaseNoSettings());
867 return currentCase != null;
884 throw new IllegalStateException(NbBundle.getMessage(
Case.class,
"Case.getCurCase.exception.noneOpen"), ex);
908 if (openCase == null) {
909 throw new NoCurrentCaseException(NbBundle.getMessage(
Case.class,
"Case.getCurCase.exception.noneOpen"));
924 "# {0} - exception message",
"Case.closeException.couldNotCloseCase=Error closing case: {0}",
925 "Case.progressIndicatorTitle.closingCase=Closing Case"
929 if (null == currentCase) {
935 logger.log(Level.INFO,
"Closing current case {0} ({1}) in {2}",
new Object[]{closedCase.getDisplayName(), closedCase.getName(), closedCase.getCaseDirectory()});
937 logger.log(Level.INFO,
"Closed current case {0} ({1}) in {2}",
new Object[]{closedCase.getDisplayName(), closedCase.getName(), closedCase.getCaseDirectory()});
938 }
catch (CaseActionException ex) {
960 if (null == currentCase) {
980 "Case.progressIndicatorTitle.deletingDataSource=Removing Data Source"
982 static void deleteDataSourceFromCurrentCase(Long dataSourceObjectID)
throws CaseActionException {
984 if (null == currentCase) {
991 CaseMetadata caseMetadata = currentCase.
getMetadata();
999 Case theCase =
new Case(caseMetadata);
1000 theCase.doOpenCaseAction(Bundle.Case_progressIndicatorTitle_deletingDataSource(), theCase::deleteDataSource, CaseLockType.EXCLUSIVE,
false, dataSourceObjectID);
1021 "Case.progressIndicatorTitle.deletingCase=Deleting Case",
1022 "Case.exceptionMessage.cannotDeleteCurrentCase=Cannot delete current case, it must be closed first.",
1023 "# {0} - case display name",
"Case.exceptionMessage.deletionInterrupted=Deletion of the case {0} was cancelled."
1027 if (null != currentCase) {
1028 throw new CaseActionException(Bundle.Case_exceptionMessage_cannotDeleteCurrentCase());
1038 progressIndicator.
start(Bundle.Case_progressMessage_preparing());
1045 }
catch (InterruptedException ex) {
1051 throw new CaseActionException(Bundle.Case_exceptionMessage_deletionInterrupted(metadata.
getCaseDisplayName()), ex);
1055 progressIndicator.
finish();
1070 "Case.progressIndicatorTitle.creatingCase=Creating Case",
1071 "Case.progressIndicatorTitle.openingCase=Opening Case",
1072 "Case.exceptionMessage.cannotLocateMainWindow=Cannot locate main application window"
1076 if (null != currentCase) {
1079 }
catch (CaseActionException ex) {
1088 logger.log(Level.INFO,
"Opening {0} ({1}) in {2} as the current case",
new Object[]{newCurrentCase.getDisplayName(), newCurrentCase.getName(), newCurrentCase.getCaseDirectory()});
1089 String progressIndicatorTitle;
1092 progressIndicatorTitle = Bundle.Case_progressIndicatorTitle_creatingCase();
1093 openCaseAction = newCurrentCase::create;
1095 progressIndicatorTitle = Bundle.Case_progressIndicatorTitle_openingCase();
1096 openCaseAction = newCurrentCase::open;
1099 currentCase = newCurrentCase;
1100 logger.log(Level.INFO,
"Opened {0} ({1}) in {2} as the current case",
new Object[]{newCurrentCase.getDisplayName(), newCurrentCase.getName(), newCurrentCase.getCaseDirectory()});
1106 logger.log(Level.INFO, String.format(
"Cancelled opening %s (%s) in %s as the current case", newCurrentCase.
getDisplayName(), newCurrentCase.
getName(), newCurrentCase.
getCaseDirectory()));
1108 }
catch (CaseActionException ex) {
1109 logger.log(Level.SEVERE, String.format(
"Error opening %s (%s) in %s as the current case", newCurrentCase.
getDisplayName(), newCurrentCase.
getName(), newCurrentCase.
getCaseDirectory()), ex);
1127 String uniqueCaseName = caseDisplayName.replaceAll(
"[^\\p{ASCII}]",
"_");
1132 uniqueCaseName = uniqueCaseName.replaceAll(
"[\\p{Cntrl}]",
"_");
1137 uniqueCaseName = uniqueCaseName.replaceAll(
"[ /?:'\"\\\\]",
"_");
1142 uniqueCaseName = uniqueCaseName.toLowerCase();
1147 SimpleDateFormat dateFormat =
new SimpleDateFormat(
"yyyyMMdd_HHmmss");
1148 Date date =
new Date();
1149 uniqueCaseName = uniqueCaseName +
"_" + dateFormat.format(date);
1151 return uniqueCaseName;
1168 File caseDir =
new File(caseDirPath);
1169 if (caseDir.exists()) {
1170 if (caseDir.isFile()) {
1171 throw new CaseActionException(NbBundle.getMessage(
Case.class,
"Case.createCaseDir.exception.existNotDir", caseDirPath));
1172 }
else if (!caseDir.canRead() || !caseDir.canWrite()) {
1173 throw new CaseActionException(NbBundle.getMessage(
Case.class,
"Case.createCaseDir.exception.existCantRW", caseDirPath));
1180 if (!caseDir.mkdirs()) {
1181 throw new CaseActionException(NbBundle.getMessage(
Case.class,
"Case.createCaseDir.exception.cantCreate", caseDirPath));
1189 String hostPathComponent =
"";
1194 Path exportDir = Paths.get(caseDirPath, hostPathComponent, EXPORT_FOLDER);
1195 if (!exportDir.toFile().mkdirs()) {
1196 throw new CaseActionException(NbBundle.getMessage(
Case.class,
"Case.createCaseDir.exception.cantCreateCaseDir", exportDir));
1199 Path logsDir = Paths.get(caseDirPath, hostPathComponent, LOG_FOLDER);
1200 if (!logsDir.toFile().mkdirs()) {
1201 throw new CaseActionException(NbBundle.getMessage(
Case.class,
"Case.createCaseDir.exception.cantCreateCaseDir", logsDir));
1204 Path cacheDir = Paths.get(caseDirPath, hostPathComponent, CACHE_FOLDER);
1205 if (!cacheDir.toFile().mkdirs()) {
1206 throw new CaseActionException(NbBundle.getMessage(
Case.class,
"Case.createCaseDir.exception.cantCreateCaseDir", cacheDir));
1209 Path moduleOutputDir = Paths.get(caseDirPath, hostPathComponent, MODULE_FOLDER);
1210 if (!moduleOutputDir.toFile().mkdirs()) {
1211 throw new CaseActionException(NbBundle.getMessage(
Case.class,
"Case.createCaseDir.exception.cantCreateModDir", moduleOutputDir));
1214 Path reportsDir = Paths.get(caseDirPath, hostPathComponent, REPORTS_FOLDER);
1215 if (!reportsDir.toFile().mkdirs()) {
1216 throw new CaseActionException(NbBundle.getMessage(
Case.class,
"Case.createCaseDir.exception.cantCreateReportsDir", reportsDir));
1227 static Map<Long, String> getImagePaths(SleuthkitCase db) {
1228 Map<Long, String> imgPaths =
new HashMap<>();
1230 Map<Long, List<String>> imgPathsList = db.getImagePaths();
1231 for (Map.Entry<Long, List<String>> entry : imgPathsList.entrySet()) {
1232 if (entry.getValue().size() > 0) {
1233 imgPaths.put(entry.getKey(), entry.getValue().get(0));
1236 }
catch (TskCoreException ex) {
1237 logger.log(Level.SEVERE,
"Error getting image paths", ex);
1253 "Case.creationException.couldNotAcquireResourcesLock=Failed to get lock on case resources"
1257 Path caseDirPath = Paths.get(caseDir);
1261 }
catch (InterruptedException ex) {
1264 throw new CaseActionException(Bundle.Case_creationException_couldNotAcquireResourcesLock(), ex);
1287 String backupDbPath = caseDb.getBackupDatabasePath();
1288 if (null != backupDbPath) {
1289 JOptionPane.showMessageDialog(
1291 NbBundle.getMessage(
Case.class,
"Case.open.msgDlg.updated.msg", backupDbPath),
1292 NbBundle.getMessage(
Case.class,
"Case.open.msgDlg.updated.title"),
1293 JOptionPane.INFORMATION_MESSAGE);
1300 Map<Long, String> imgPaths = getImagePaths(caseDb);
1301 for (Map.Entry<Long, String> entry : imgPaths.entrySet()) {
1302 long obj_id = entry.getKey();
1303 String path = entry.getValue();
1311 SwingUtilities.invokeAndWait(
new Runnable() {
1314 int response = JOptionPane.showConfirmDialog(
1316 NbBundle.getMessage(
Case.class,
"Case.checkImgExist.confDlg.doesntExist.msg", path),
1317 NbBundle.getMessage(
Case.class,
"Case.checkImgExist.confDlg.doesntExist.title"),
1318 JOptionPane.YES_NO_OPTION);
1319 if (response == JOptionPane.YES_OPTION) {
1320 MissingImageDialog.makeDialog(obj_id, caseDb);
1322 logger.log(Level.SEVERE,
"User proceeding with missing image files");
1328 }
catch (InterruptedException | InvocationTargetException ex) {
1329 logger.log(Level.SEVERE,
"Failed to show missing image confirmation dialog", ex);
1340 CallableSystemAction.get(CaseDetailsAction.class).setEnabled(
true);
1355 final boolean hasData = newCurrentCase.
hasData();
1357 SwingUtilities.invokeLater(() -> {
1366 mainFrame.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
1373 mainFrame.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
1389 SwingUtilities.invokeLater(() -> {
1399 CallableSystemAction.get(
AddImageAction.class).setEnabled(
false);
1402 CallableSystemAction.get(CaseDetailsAction.class).setEnabled(
false);
1404 CallableSystemAction.get(CaseDeleteAction.class).setEnabled(
false);
1548 hostPath = Paths.get(caseDirectory);
1550 if (!hostPath.toFile().exists()) {
1551 hostPath.toFile().mkdirs();
1553 return hostPath.toString();
1560 return Paths.get(System.getProperty(
"java.io.tmpdir"),
APP_NAME,
getName());
1572 Path basePath = null;
1577 basePath = (StringUtils.isBlank(customDirectory))
1579 : Paths.get(customDirectory, APP_NAME,
getName());
1597 : Paths.get(TEMP_FOLDER);
1599 File caseTempDir = basePath
1600 .resolve(caseRelPath)
1604 if (!caseTempDir.exists()) {
1605 caseTempDir.mkdirs();
1608 return caseTempDir.getAbsolutePath();
1681 return path.subpath(path.getNameCount() - 2, path.getNameCount()).toString();
1683 return path.subpath(path.getNameCount() - 1, path.getNameCount()).toString();
1697 return caseDb.getRootObjects();
1706 Set<TimeZone> timezones =
new HashSet<>();
1707 String query =
"SELECT time_zone FROM data_source_info";
1708 try (SleuthkitCase.CaseDbQuery dbQuery = caseDb.executeQuery(query)) {
1709 ResultSet timeZoneSet = dbQuery.getResultSet();
1710 while (timeZoneSet.next()) {
1711 String timeZone = timeZoneSet.getString(
"time_zone");
1712 if (timeZone != null && !timeZone.isEmpty()) {
1713 timezones.add(TimeZone.getTimeZone(timeZone));
1716 }
catch (TskCoreException | SQLException ex) {
1717 logger.log(Level.SEVERE,
"Error getting data source time zones", ex);
1761 hasDataSource =
true;
1869 logger.log(Level.WARNING,
"Unable to send notifcation regarding comment change due to no current case being open", ex);
1919 public void addReport(String localPath, String srcModuleName, String reportName)
throws TskCoreException {
1920 addReport(localPath, srcModuleName, reportName, null);
1937 public Report
addReport(String localPath, String srcModuleName, String reportName, Content parent)
throws TskCoreException {
1938 String normalizedLocalPath;
1940 if (localPath.toLowerCase().contains(
"http:")) {
1941 normalizedLocalPath = localPath;
1943 normalizedLocalPath = Paths.get(localPath).normalize().toString();
1945 }
catch (InvalidPathException ex) {
1946 String errorMsg =
"Invalid local path provided: " + localPath;
1947 throw new TskCoreException(errorMsg, ex);
1951 Report report = this.caseDb.addReport(normalizedLocalPath, srcModuleName, reportName, parent);
1965 return this.caseDb.getAllReports();
1976 public void deleteReports(Collection<? extends Report> reports)
throws TskCoreException {
1977 for (Report report : reports) {
1978 this.caseDb.deleteReport(report);
1983 }
catch (TskCoreException ex) {
1984 logger.log(Level.SEVERE,
"Unable to retrieve the hasData status from the db", ex);
1987 for (Report report : reports) {
2009 "Case.exceptionMessage.metadataUpdateError=Failed to update case metadata"
2011 void updateCaseDetails(CaseDetails caseDetails)
throws CaseActionException {
2014 metadata.setCaseDetails(caseDetails);
2015 }
catch (CaseMetadataException ex) {
2016 throw new CaseActionException(Bundle.Case_exceptionMessage_metadataUpdateError(), ex);
2020 CaseNodeData nodeData = CaseNodeData.readCaseNodeData(metadata.
getCaseDirectory());
2022 CaseNodeData.writeCaseNodeData(nodeData);
2023 }
catch (CaseNodeDataException | InterruptedException ex) {
2024 throw new CaseActionException(Bundle.Case_exceptionMessage_couldNotUpdateCaseNodeData(ex.getLocalizedMessage()), ex);
2027 if (!oldCaseDetails.getCaseNumber().equals(caseDetails.
getCaseNumber())) {
2028 eventPublisher.
publish(
new AutopsyEvent(Events.NUMBER.toString(), oldCaseDetails.getCaseNumber(), caseDetails.
getCaseNumber()));
2030 if (!oldCaseDetails.getExaminerName().equals(caseDetails.
getExaminerName())) {
2031 eventPublisher.
publish(
new AutopsyEvent(Events.NUMBER.toString(), oldCaseDetails.getExaminerName(), caseDetails.
getExaminerName()));
2034 eventPublisher.
publish(
new AutopsyEvent(Events.NAME.toString(), oldCaseDetails.getCaseDisplayName(), caseDetails.
getCaseDisplayName()));
2036 eventPublisher.
publish(
new AutopsyEvent(Events.CASE_DETAILS.toString(), oldCaseDetails, caseDetails));
2037 if (RuntimeProperties.runningWithGUI()) {
2038 SwingUtilities.invokeLater(() -> {
2042 }
catch (Exception ex) {
2043 logger.log(Level.SEVERE,
"Error updating case name in UI", ex);
2071 metadata = caseMetaData;
2105 "Case.progressIndicatorCancelButton.label=Cancel",
2106 "Case.progressMessage.preparing=Preparing...",
2107 "Case.progressMessage.cancelling=Cancelling...",
2108 "Case.exceptionMessage.cancelled=Cancelled.",
2109 "# {0} - exception message",
"Case.exceptionMessage.execExceptionWrapperMessage={0}"
2119 if (allowCancellation) {
2123 progressIndicatorTitle,
2124 new String[]{Bundle.Case_progressIndicatorCancelButton_label()},
2125 Bundle.Case_progressIndicatorCancelButton_label(),
2126 cancelButtonListener);
2130 progressIndicatorTitle);
2135 progressIndicator.
start(Bundle.Case_progressMessage_preparing());
2144 caseActionExecutor = Executors.newSingleThreadExecutor(threadFactory);
2145 Future<Void> future = caseActionExecutor.submit(() -> {
2147 caseAction.
execute(progressIndicator, additionalParams);
2151 if (null == resourcesLock) {
2152 throw new CaseActionException(Bundle.Case_creationException_couldNotAcquireResourcesLock());
2154 caseAction.
execute(progressIndicator, additionalParams);
2155 }
catch (CaseActionException ex) {
2162 if (null != cancelButtonListener) {
2171 }
catch (InterruptedException discarded) {
2175 if (null != cancelButtonListener) {
2178 future.cancel(
true);
2181 }
catch (CancellationException discarded) {
2187 }
catch (ExecutionException ex) {
2192 throw new CaseActionException(Bundle.Case_exceptionMessage_execExceptionWrapperMessage(ex.getCause().getLocalizedMessage()), ex);
2194 progressIndicator.
finish();
2214 assert (additionalParams == null);
2235 }
catch (CaseActionException ex) {
2244 }
catch (InterruptedException discarded) {
2246 close(progressIndicator);
2266 assert (additionalParams == null);
2286 }
catch (CaseActionException ex) {
2295 }
catch (InterruptedException discarded) {
2297 close(progressIndicator);
2312 "# {0} - case",
"Case.openFileSystems.retrievingImages=Retrieving images for case: {0}...",
2313 "# {0} - image",
"Case.openFileSystems.openingImage=Opening all filesystems for image: {0}..."
2316 if (backgroundOpenFileSystemsFuture != null && !backgroundOpenFileSystemsFuture.isDone()) {
2317 backgroundOpenFileSystemsFuture.cancel(
true);
2346 caseName = (this.tskCase != null) ? this.tskCase.getDatabaseName() :
"";
2357 if (Thread.interrupted()) {
2358 throw new InterruptedException();
2368 progressIndicator.
progress(Bundle.Case_openFileSystems_retrievingImages(caseName));
2370 return this.tskCase.getImages();
2371 }
catch (TskCoreException ex) {
2374 String.format(
"Could not obtain images while opening case: %s.", caseName),
2390 private void openFileSystems(List<Image> images)
throws TskCoreException, InterruptedException {
2391 byte[] tempBuff =
new byte[512];
2393 for (Image image : images) {
2394 String imageStr = image.getName();
2396 progressIndicator.
progress(Bundle.Case_openFileSystems_openingImage(imageStr));
2398 Collection<FileSystem> fileSystems = this.tskCase.getImageFileSystems(image);
2400 for (FileSystem fileSystem : fileSystems) {
2401 fileSystem.read(tempBuff, 0, 512);
2413 if (images == null) {
2421 String.format(
"Skipping background load of file systems due to large number of images in case (%d)", images.size()));
2427 }
catch (InterruptedException ex) {
2430 String.format(
"Background operation opening all file systems in %s has been cancelled.", caseName));
2431 }
catch (Exception ex) {
2433 logger.log(Level.WARNING,
"Error while opening file systems in background", ex);
2454 "Case.progressMessage.deletingDataSource=Removing the data source from the case...",
2455 "Case.exceptionMessage.dataSourceNotFound=The data source was not found.",
2456 "Case.exceptionMessage.errorDeletingDataSourceFromCaseDb=An error occurred while removing the data source from the case database.",
2457 "Case.exceptionMessage.errorDeletingDataSourceFromTextIndex=An error occurred while removing the data source from the text index.",})
2458 Void deleteDataSource(ProgressIndicator progressIndicator, Object additionalParams)
throws CaseActionException {
2459 assert (additionalParams instanceof Long);
2460 open(progressIndicator, null);
2462 progressIndicator.progress(Bundle.Case_progressMessage_deletingDataSource());
2463 Long dataSourceObjectID = (Long) additionalParams;
2465 DataSource dataSource = this.caseDb.getDataSource(dataSourceObjectID);
2466 if (dataSource == null) {
2467 throw new CaseActionException(Bundle.Case_exceptionMessage_dataSourceNotFound());
2469 SleuthkitCaseAdminUtil.deleteDataSource(this.caseDb, dataSourceObjectID);
2470 }
catch (TskDataException | TskCoreException ex) {
2471 throw new CaseActionException(Bundle.Case_exceptionMessage_errorDeletingDataSourceFromCaseDb(), ex);
2475 }
catch (KeywordSearchServiceException ex) {
2476 throw new CaseActionException(Bundle.Case_exceptionMessage_errorDeletingDataSourceFromTextIndex(), ex);
2478 eventPublisher.
publish(
new DataSourceDeletedEvent(dataSourceObjectID));
2481 close(progressIndicator);
2496 public SleuthkitCase
createPortableCase(String caseName, File portableCaseFolder)
throws TskCoreException {
2498 if (portableCaseFolder.exists()) {
2499 throw new TskCoreException(
"Portable case folder " + portableCaseFolder.toString() +
" already exists");
2501 if (!portableCaseFolder.mkdirs()) {
2502 throw new TskCoreException(
"Error creating portable case folder " + portableCaseFolder.toString());
2510 portableCaseMetadata.setCaseDatabaseName(SINGLE_USER_CASE_DB_NAME);
2512 throw new TskCoreException(
"Error creating case metadata", ex);
2516 SleuthkitCase portableSleuthkitCase;
2518 portableSleuthkitCase = SleuthkitCase.newCase(dbFilePath);
2520 return portableSleuthkitCase;
2533 if (Thread.currentThread().isInterrupted()) {
2534 throw new CaseActionCancelledException(Bundle.Case_exceptionMessage_cancelled());
2549 "Case.progressMessage.creatingCaseDirectory=Creating case directory..."
2556 progressIndicator.
progress(Bundle.Case_progressMessage_creatingCaseDirectory());
2558 progressIndicator.
progress(Bundle.Case_progressMessage_creatingCaseDirectory());
2570 "Case.progressMessage.switchingLogDirectory=Switching log directory..."
2573 progressIndicator.
progress(Bundle.Case_progressMessage_switchingLogDirectory());
2589 "Case.progressMessage.savingCaseMetadata=Saving case metadata to file...",
2590 "# {0} - exception message",
"Case.exceptionMessage.couldNotSaveCaseMetadata=Failed to save case metadata:\n{0}."
2593 progressIndicator.
progress(Bundle.Case_progressMessage_savingCaseMetadata());
2595 this.metadata.writeToFile();
2597 throw new CaseActionException(Bundle.Case_exceptionMessage_couldNotSaveCaseMetadata(ex.getLocalizedMessage()), ex);
2613 "Case.progressMessage.creatingCaseNodeData=Creating coordination service node data...",
2614 "# {0} - exception message",
"Case.exceptionMessage.couldNotCreateCaseNodeData=Failed to create coordination service node data:\n{0}."
2618 progressIndicator.
progress(Bundle.Case_progressMessage_creatingCaseNodeData());
2622 throw new CaseActionException(Bundle.Case_exceptionMessage_couldNotCreateCaseNodeData(ex.getLocalizedMessage()), ex);
2639 "Case.progressMessage.updatingCaseNodeData=Updating coordination service node data...",
2640 "# {0} - exception message",
"Case.exceptionMessage.couldNotUpdateCaseNodeData=Failed to update coordination service node data:\n{0}."
2644 progressIndicator.
progress(Bundle.Case_progressMessage_updatingCaseNodeData());
2650 throw new CaseActionException(Bundle.Case_exceptionMessage_couldNotUpdateCaseNodeData(ex.getLocalizedMessage()), ex);
2661 "Case.progressMessage.clearingTempDirectory=Clearing case temp directory..."
2667 progressIndicator.
progress(Bundle.Case_progressMessage_clearingTempDirectory());
2683 "Case.progressMessage.creatingCaseDatabase=Creating case database...",
2684 "# {0} - exception message",
"Case.exceptionMessage.couldNotGetDbServerConnectionInfo=Failed to get case database server conneciton info:\n{0}.",
2685 "# {0} - exception message",
"Case.exceptionMessage.couldNotCreateCaseDatabase=Failed to create case database:\n{0}.",
2686 "# {0} - exception message",
"Case.exceptionMessage.couldNotSaveDbNameToMetadataFile=Failed to save case database name to case metadata file:\n{0}."
2689 progressIndicator.
progress(Bundle.Case_progressMessage_creatingCaseDatabase());
2698 metadata.setCaseDatabaseName(SINGLE_USER_CASE_DB_NAME);
2706 metadata.setCaseDatabaseName(caseDb.getDatabaseName());
2708 }
catch (TskCoreException ex) {
2709 throw new CaseActionException(Bundle.Case_exceptionMessage_couldNotCreateCaseDatabase(ex.getLocalizedMessage()), ex);
2711 throw new CaseActionException(Bundle.Case_exceptionMessage_couldNotGetDbServerConnectionInfo(ex.getLocalizedMessage()), ex);
2713 throw new CaseActionException(Bundle.Case_exceptionMessage_couldNotSaveDbNameToMetadataFile(ex.getLocalizedMessage()), ex);
2729 "Case.progressMessage.openingCaseDatabase=Opening case database...",
2730 "# {0} - exception message",
"Case.exceptionMessage.couldNotOpenCaseDatabase=Failed to open case database:\n{0}.",
2731 "# {0} - exception message",
"Case.exceptionMessage.unsupportedSchemaVersionMessage=Unsupported case database schema version:\n{0}.",
2732 "Case.open.exception.multiUserCaseNotEnabled=Cannot open a multi-user case if multi-user cases are not enabled. See Tools, Options, Multi-User."
2735 progressIndicator.
progress(Bundle.Case_progressMessage_openingCaseDatabase());
2743 String fullDatabasePath = (
new File(databaseName).isAbsolute())
2747 caseDb = SleuthkitCase.openCase(fullDatabasePath, contentProvider);
2751 throw new CaseActionException(Bundle.Case_open_exception_multiUserCaseNotEnabled());
2754 }
catch (TskUnsupportedSchemaVersionException ex) {
2755 throw new CaseActionException(Bundle.Case_exceptionMessage_unsupportedSchemaVersionMessage(ex.getLocalizedMessage()), ex);
2757 throw new CaseActionException(Bundle.Case_exceptionMessage_couldNotGetDbServerConnectionInfo(ex.getLocalizedMessage()), ex);
2758 }
catch (TskCoreException ex) {
2759 throw new CaseActionException(Bundle.Case_exceptionMessage_couldNotOpenCaseDatabase(ex.getLocalizedMessage()), ex);
2774 Collection<? extends AutopsyContentProvider> customContentProviders = Lookup.getDefault().lookupAll(
AutopsyContentProvider.class);
2775 if (customContentProviders != null) {
2778 if (customProvider == null || !StringUtils.equalsIgnoreCase(providerName, customProvider.getName())) {
2782 ContentStreamProvider contentProvider = customProvider.load();
2783 if (contentProvider != null) {
2784 return contentProvider;
2800 "Case.progressMessage.openingCaseLevelServices=Opening case-level services...",})
2802 progressIndicator.
progress(Bundle.Case_progressMessage_openingCaseLevelServices());
2803 this.caseServices =
new Services(caseDb);
2809 caseDb.registerForEvents(sleuthkitEventListener);
2824 @NbBundle.Messages({
2825 "Case.progressMessage.openingApplicationServiceResources=Opening application service case resources...",
2826 "# {0} - service name",
"Case.serviceOpenCaseResourcesProgressIndicator.title={0} Opening Case Resources",
2827 "# {0} - service name",
"Case.serviceOpenCaseResourcesProgressIndicator.cancellingMessage=Cancelling opening case resources by {0}...",
2828 "# {0} - service name",
"Case.servicesException.notificationTitle={0} Error"
2839 progressIndicator.
progress(Bundle.Case_progressMessage_openingApplicationServiceResources());
2851 cancelButtonListener =
new CancelButtonListener(Bundle.Case_serviceOpenCaseResourcesProgressIndicator_cancellingMessage(service.getServiceName()));
2854 Bundle.Case_serviceOpenCaseResourcesProgressIndicator_title(service.getServiceName()),
2855 new String[]{Bundle.Case_progressIndicatorCancelButton_label()},
2856 Bundle.Case_progressIndicatorCancelButton_label(),
2857 cancelButtonListener);
2861 appServiceProgressIndicator.
start(Bundle.Case_progressMessage_preparing());
2863 String threadNameSuffix = service.getServiceName().replaceAll(
"[ ]",
"-");
2864 threadNameSuffix = threadNameSuffix.toLowerCase();
2866 ExecutorService executor = Executors.newSingleThreadExecutor(threadFactory);
2867 Future<Void> future = executor.submit(() -> {
2868 service.openCaseResources(context);
2871 if (null != cancelButtonListener) {
2883 }
catch (InterruptedException discarded) {
2888 future.cancel(
true);
2889 }
catch (CancellationException discarded) {
2897 }
catch (ExecutionException ex) {
2904 Case.
logger.log(Level.SEVERE, String.format(
"%s failed to open case resources for %s", service.getServiceName(), this.
getDisplayName()), ex);
2906 SwingUtilities.invokeLater(() -> {
2918 appServiceProgressIndicator.
finish();
2936 "Case.progressMessage.settingUpNetworkCommunications=Setting up network communications...",
2937 "# {0} - exception message",
"Case.exceptionMessage.couldNotOpenRemoteEventChannel=Failed to open remote events channel:\n{0}.",
2938 "# {0} - exception message",
"Case.exceptionMessage.couldNotCreatCollaborationMonitor=Failed to create collaboration monitor:\n{0}."
2942 progressIndicator.
progress(Bundle.Case_progressMessage_settingUpNetworkCommunications());
2946 collaborationMonitor =
new CollaborationMonitor(metadata.
getCaseName());
2948 throw new CaseActionException(Bundle.Case_exceptionMessage_couldNotOpenRemoteEventChannel(ex.getLocalizedMessage()), ex);
2949 }
catch (CollaborationMonitor.CollaborationMonitorException ex) {
2950 throw new CaseActionException(Bundle.Case_exceptionMessage_couldNotCreatCollaborationMonitor(ex.getLocalizedMessage()), ex);
2978 Bundle.Case_progressIndicatorTitle_closingCase());
2982 progressIndicator.
start(Bundle.Case_progressMessage_preparing());
2991 Future<Void> future = caseActionExecutor.submit(() -> {
2993 close(progressIndicator);
3000 progressIndicator.
progress(Bundle.Case_progressMessage_preparing());
3002 if (null == resourcesLock) {
3003 throw new CaseActionException(Bundle.Case_creationException_couldNotAcquireResourcesLock());
3005 close(progressIndicator);
3019 }
catch (InterruptedException | CancellationException unused) {
3026 }
catch (ExecutionException ex) {
3027 throw new CaseActionException(Bundle.Case_exceptionMessage_execExceptionWrapperMessage(ex.getCause().getMessage()), ex);
3030 progressIndicator.
finish();
3040 "Case.progressMessage.shuttingDownNetworkCommunications=Shutting down network communications...",
3041 "Case.progressMessage.closingApplicationServiceResources=Closing case-specific application service resources...",
3042 "Case.progressMessage.closingCaseDatabase=Closing case database..."
3052 progressIndicator.
progress(Bundle.Case_progressMessage_shuttingDownNetworkCommunications());
3053 if (null != collaborationMonitor) {
3054 collaborationMonitor.shutdown();
3063 progressIndicator.
progress(Bundle.Case_progressMessage_closingApplicationServiceResources());
3069 if (null != caseDb) {
3070 progressIndicator.
progress(Bundle.Case_progressMessage_closingCaseDatabase());
3071 caseDb.unregisterForEvents(sleuthkitEventListener);
3083 progressIndicator.
progress(Bundle.Case_progressMessage_switchingLogDirectory());
3092 "# {0} - serviceName",
"Case.serviceCloseResourcesProgressIndicator.title={0} Closing Case Resources",
3093 "# {0} - service name",
"# {1} - exception message",
"Case.servicesException.serviceResourcesCloseError=Could not close case resources for {0} service: {1}"
3106 Bundle.Case_serviceCloseResourcesProgressIndicator_title(service.getServiceName()));
3110 progressIndicator.
start(Bundle.Case_progressMessage_preparing());
3112 String threadNameSuffix = service.getServiceName().replaceAll(
"[ ]",
"-");
3113 threadNameSuffix = threadNameSuffix.toLowerCase();
3115 ExecutorService executor = Executors.newSingleThreadExecutor(threadFactory);
3116 Future<Void> future = executor.submit(() -> {
3117 service.closeCaseResources(context);
3122 }
catch (InterruptedException ex) {
3123 Case.
logger.log(Level.SEVERE, String.format(
"Unexpected interrupt while waiting on %s service to close case resources", service.getServiceName()), ex);
3124 }
catch (CancellationException ex) {
3125 Case.
logger.log(Level.SEVERE, String.format(
"Unexpected cancellation while waiting on %s service to close case resources", service.getServiceName()), ex);
3126 }
catch (ExecutionException ex) {
3127 Case.
logger.log(Level.SEVERE, String.format(
"%s service failed to open case resources", service.getServiceName()), ex);
3130 Bundle.Case_servicesException_notificationTitle(service.getServiceName()),
3131 Bundle.Case_servicesException_serviceResourcesCloseError(service.getServiceName(), ex.getLocalizedMessage())));
3135 progressIndicator.
finish();
3146 "Case.lockingException.couldNotAcquireSharedLock=Failed to get a shared lock on the case.",
3147 "Case.lockingException.couldNotAcquireExclusiveLock=Failed to get an exclusive lock on the case."
3158 throw new CaseActionException(Bundle.Case_lockingException_couldNotAcquireSharedLock());
3160 throw new CaseActionException(Bundle.Case_lockingException_couldNotAcquireExclusiveLock());
3165 throw new CaseActionException(Bundle.Case_lockingException_couldNotAcquireSharedLock(), ex);
3167 throw new CaseActionException(Bundle.Case_lockingException_couldNotAcquireExclusiveLock(), ex);
3181 logger.log(Level.SEVERE, String.format(
"Failed to release shared case directory lock for %s",
getMetadata().
getCaseDirectory()), ex);
3194 if (!subDirectory.exists()) {
3195 subDirectory.mkdirs();
3197 return subDirectory.toString();
3213 "Case.exceptionMessage.errorsDeletingCase=Errors occured while deleting the case. See the application log for details."
3216 boolean errorsOccurred =
false;
3220 errorsOccurred =
true;
3226 }
catch (CaseActionException ex) {
3227 errorsOccurred =
true;
3233 if (errorsOccurred) {
3234 throw new CaseActionException(Bundle.Case_exceptionMessage_errorsDeletingCase());
3258 "Case.progressMessage.connectingToCoordSvc=Connecting to coordination service...",
3259 "# {0} - exception message",
"Case.exceptionMessage.failedToConnectToCoordSvc=Failed to connect to coordination service:\n{0}.",
3260 "Case.exceptionMessage.cannotGetLockToDeleteCase=Cannot delete case because it is open for another user or host.",
3261 "# {0} - exception message",
"Case.exceptionMessage.failedToLockCaseForDeletion=Failed to exclusively lock case for deletion:\n{0}.",
3262 "Case.progressMessage.fetchingCoordSvcNodeData=Fetching coordination service node data for the case...",
3263 "# {0} - exception message",
"Case.exceptionMessage.failedToFetchCoordSvcNodeData=Failed to fetch coordination service node data:\n{0}.",
3264 "Case.progressMessage.deletingResourcesCoordSvcNode=Deleting case resources coordination service node...",
3265 "Case.progressMessage.deletingCaseDirCoordSvcNode=Deleting case directory coordination service node..."
3268 progressIndicator.
progress(Bundle.Case_progressMessage_connectingToCoordSvc());
3274 throw new CaseActionException(Bundle.Case_exceptionMessage_failedToConnectToCoordSvc(ex.getLocalizedMessage()));
3278 boolean errorsOccurred =
false;
3280 if (dirLock == null) {
3282 throw new CaseActionException(Bundle.Case_exceptionMessage_cannotGetLockToDeleteCase());
3285 progressIndicator.
progress(Bundle.Case_progressMessage_fetchingCoordSvcNodeData());
3290 throw new CaseActionException(Bundle.Case_exceptionMessage_failedToFetchCoordSvcNodeData(ex.getLocalizedMessage()));
3295 progressIndicator.
progress(Bundle.Case_progressMessage_deletingResourcesCoordSvcNode());
3301 errorsOccurred =
true;
3302 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);
3304 }
catch (InterruptedException ex) {
3305 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);
3310 throw new CaseActionException(Bundle.Case_exceptionMessage_failedToLockCaseForDeletion(ex.getLocalizedMessage()));
3313 if (!errorsOccurred) {
3314 progressIndicator.
progress(Bundle.Case_progressMessage_deletingCaseDirCoordSvcNode());
3320 errorsOccurred =
true;
3324 if (errorsOccurred) {
3325 throw new CaseActionException(Bundle.Case_exceptionMessage_errorsDeletingCase());
3355 boolean errorsOccurred =
false;
3362 errorsOccurred =
true;
3365 errorsOccurred =
true;
3367 }
catch (CaseActionException ex) {
3368 errorsOccurred =
true;
3371 return errorsOccurred;
3395 "Case.progressMessage.deletingCaseDatabase=Deleting case database..."
3399 progressIndicator.
progress(Bundle.Case_progressMessage_deletingCaseDatabase());
3400 logger.log(Level.INFO, String.format(
"Deleting case database for %s (%s) in %s", caseNodeData.
getDisplayName(), caseNodeData.
getName(), caseNodeData.
getDirectory()));
3402 String url =
"jdbc:postgresql://" + info.getHost() +
":" + info.getPort() +
"/postgres";
3403 Class.forName(
"org.postgresql.Driver");
3404 try (Connection connection = DriverManager.getConnection(url, info.getUserName(), info.getPassword()); Statement statement = connection.createStatement()) {
3405 String dbExistsQuery =
"SELECT 1 from pg_database WHERE datname = '" + metadata.
getCaseDatabaseName() +
"'";
3406 try (ResultSet queryResult = statement.executeQuery(dbExistsQuery)) {
3407 if (queryResult.next()) {
3409 statement.execute(deleteCommand);
3450 "Case.progressMessage.deletingTextIndex=Deleting text index..."
3453 progressIndicator.
progress(Bundle.Case_progressMessage_deletingTextIndex());
3457 searchService.deleteTextIndex(metadata);
3493 "Case.progressMessage.deletingCaseDirectory=Deleting case directory..."
3496 progressIndicator.
progress(Bundle.Case_progressMessage_deletingCaseDirectory());
3498 throw new CaseActionException(String.format(
"Failed to delete %s", metadata.
getCaseDirectory()));
3510 "Case.progressMessage.removingCaseFromRecentCases=Removing case from Recent Cases menu..."
3514 progressIndicator.
progress(Bundle.Case_progressMessage_removingCaseFromRecentCases());
3515 SwingUtilities.invokeLater(() -> {
3531 boolean isNodeNodeEx =
false;
3532 Throwable cause = ex.getCause();
3533 if (cause != null) {
3534 String causeMessage = cause.getMessage();
3535 isNodeNodeEx = causeMessage.contains(NO_NODE_ERROR_MSG_FRAGMENT);
3537 return isNodeNodeEx;
3556 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);
3575 if (!hasDataSource) {
3590 String query =
"SELECT count(*) AS count FROM (SELECT * FROM data_source_info LIMIT 1)t";
3591 try (SleuthkitCase.CaseDbQuery dbQuery = caseDb.executeQuery(query)) {
3592 ResultSet resultSet = dbQuery.getResultSet();
3593 if (resultSet.next()) {
3594 return resultSet.getLong(
"count") > 0;
3597 }
catch (SQLException ex) {
3598 logger.log(Level.SEVERE,
"Error accessing case database", ex);
3599 throw new TskCoreException(
"Error accessing case databse", ex);
3614 String query =
"SELECT SUM(cnt) total FROM "
3615 +
"(SELECT COUNT(*) AS cnt FROM "
3616 +
"(SELECT * FROM tsk_objects LIMIT 1)t "
3618 +
"SELECT COUNT(*) AS cnt FROM "
3619 +
"(SELECT * FROM tsk_hosts LIMIT 1)r) s";
3620 try (SleuthkitCase.CaseDbQuery dbQuery = caseDb.executeQuery(query)) {
3621 ResultSet resultSet = dbQuery.getResultSet();
3622 if (resultSet.next()) {
3623 return resultSet.getLong(
"total") > 0;
3627 }
catch (SQLException ex) {
3628 logger.log(Level.SEVERE,
"Error accessing case database", ex);
3629 throw new TskCoreException(
"Error accessing case databse", ex);
3653 R
execute(T progressIndicator, V additionalParams)
throws CaseActionException;
3751 ((ModalDialogProgressIndicator) progressIndicator).
setCancelling(cancellationMessage);
3780 return new Thread(task, threadName);
3817 public static void create(String caseDir, String caseDisplayName, String caseNumber, String examiner)
throws CaseActionException {
3842 public static void create(String caseDir, String caseDisplayName, String caseNumber, String examiner,
CaseType caseType)
throws CaseActionException {
3858 public static void open(String caseMetadataFilePath)
throws CaseActionException {
3915 return new File(filePath).isFile();
3954 return "ModuleOutput";
3967 public static PropertyChangeSupport
3969 return new PropertyChangeSupport(
Case.class
4001 public Image
addImage(String imgPath,
long imgId, String timeZone)
throws CaseActionException {
4003 Image newDataSource = caseDb.getImageById(imgId);
4005 return newDataSource;
4006 }
catch (TskCoreException ex) {
4007 throw new CaseActionException(NbBundle.getMessage(
this.getClass(),
"Case.addImg.exception.msg"), ex);
4034 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)
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()
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
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)
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)
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)
void publisHostsRemovedFromPersonEvent(TskEvent.HostsRemovedFromPersonTskEvent event)
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)
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)
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)
String getCacheDirectory()
static void addPropertyChangeListener(PropertyChangeListener listener)
void publishHostsUpdatedEvent(TskEvent.HostsUpdatedTskEvent event)
void removeSubscriber(Set< String > eventNames, PropertyChangeListener subscriber)
String getModuleDirectory()
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)
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 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()
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)
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()
static void addEventSubscriber(Set< String > eventNames, PropertyChangeListener subscriber)
void updateCaseNodeData(ProgressIndicator progressIndicator)
static void error(String message)
void publicTagSetsAdded(TskEvent.TagSetsAddedTskEvent event)
final SleuthkitCase tskCase
String getExaminerEmail()