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.Collections;
45 import java.util.Date;
46 import java.util.HashMap;
47 import java.util.HashSet;
48 import java.util.List;
51 import java.util.TimeZone;
52 import java.util.UUID;
53 import java.util.concurrent.CancellationException;
54 import java.util.concurrent.ExecutionException;
55 import java.util.concurrent.ExecutorService;
56 import java.util.concurrent.Executors;
57 import java.util.concurrent.Future;
58 import java.util.concurrent.ThreadFactory;
59 import java.util.concurrent.TimeUnit;
60 import java.util.logging.Level;
61 import java.util.stream.Collectors;
62 import java.util.stream.Stream;
63 import javax.annotation.concurrent.GuardedBy;
64 import javax.annotation.concurrent.ThreadSafe;
65 import javax.swing.JOptionPane;
66 import javax.swing.SwingUtilities;
67 import org.apache.commons.lang3.StringUtils;
68 import org.openide.util.Lookup;
69 import org.openide.util.NbBundle;
70 import org.openide.util.NbBundle.Messages;
71 import org.openide.util.actions.CallableSystemAction;
72 import org.openide.windows.WindowManager;
165 import org.
sleuthkit.datamodel.TskUnsupportedSchemaVersionException;
192 = Executors.newSingleThreadExecutor(
new ThreadFactoryBuilder().setNameFormat(
"case-open-file-systems-%d").build());
212 WindowManager.getDefault().invokeWhenUIReady(() -> {
213 mainFrame = WindowManager.getDefault().getMainWindow();
235 if (typeName != null) {
237 if (typeName.equalsIgnoreCase(c.toString())) {
261 "Case_caseType_singleUser=Single-user case",
262 "Case_caseType_multiUser=Multi-user case"
265 if (fromString(typeName) == SINGLE_USER_CASE) {
266 return Bundle.Case_caseType_singleUser();
268 return Bundle.Case_caseType_multiUser();
278 this.typeName = typeName;
293 return (otherTypeName == null) ?
false : typeName.equals(otherTypeName);
548 }
catch (TskCoreException ex) {
549 logger.log(Level.SEVERE,
"Unable to retrieve the hasData status from the db", ex);
592 }
catch (TskCoreException ex) {
593 logger.log(Level.SEVERE,
"Unable to retrieve the hasData status from the db", ex);
676 .map(Events::toString)
677 .collect(Collectors.toSet()), listener);
688 .map(Events::toString)
689 .collect(Collectors.toSet()), listener);
712 eventTypes.forEach((
Events event) -> {
757 eventTypes.forEach((
Events event) -> {
771 return !(caseName.contains(
"\\") || caseName.contains(
"/") || caseName.contains(
":")
772 || caseName.contains(
"*") || caseName.contains(
"?") || caseName.contains(
"\"")
773 || caseName.contains(
"<") || caseName.contains(
">") || caseName.contains(
"|"));
825 "Case.exceptionMessage.emptyCaseName=Must specify a case name.",
826 "Case.exceptionMessage.emptyCaseDir=Must specify a case directory path."
830 throw new CaseActionException(Bundle.Case_exceptionMessage_emptyCaseName());
832 if (caseDir.isEmpty()) {
833 throw new CaseActionException(Bundle.Case_exceptionMessage_emptyCaseDir());
852 "# {0} - exception message",
"Case.exceptionMessage.failedToReadMetadata=Failed to read case metadata:\n{0}.",
853 "Case.exceptionMessage.cannotOpenMultiUserCaseNoSettings=Multi-user settings are missing (see Tools, Options, Multi-user tab), cannot open a multi-user case."
858 metadata =
new CaseMetadata(Paths.get(caseMetadataFilePath));
860 throw new CaseActionException(Bundle.Case_exceptionMessage_failedToReadMetadata(ex.getLocalizedMessage()), ex);
863 throw new CaseActionException(Bundle.Case_exceptionMessage_cannotOpenMultiUserCaseNoSettings());
874 return currentCase != null;
891 throw new IllegalStateException(NbBundle.getMessage(
Case.class,
"Case.getCurCase.exception.noneOpen"), ex);
915 if (openCase == null) {
916 throw new NoCurrentCaseException(NbBundle.getMessage(
Case.class,
"Case.getCurCase.exception.noneOpen"));
931 "# {0} - exception message",
"Case.closeException.couldNotCloseCase=Error closing case: {0}",
932 "Case.progressIndicatorTitle.closingCase=Closing Case"
936 if (null == currentCase) {
942 logger.log(Level.INFO,
"Closing current case {0} ({1}) in {2}",
new Object[]{closedCase.getDisplayName(), closedCase.getName(), closedCase.getCaseDirectory()});
944 logger.log(Level.INFO,
"Closed current case {0} ({1}) in {2}",
new Object[]{closedCase.getDisplayName(), closedCase.getName(), closedCase.getCaseDirectory()});
945 }
catch (CaseActionException ex) {
967 if (null == currentCase) {
987 "Case.progressIndicatorTitle.deletingDataSource=Removing Data Source"
989 static void deleteDataSourceFromCurrentCase(Long dataSourceObjectID)
throws CaseActionException {
991 if (null == currentCase) {
998 CaseMetadata caseMetadata = currentCase.
getMetadata();
1006 Case theCase =
new Case(caseMetadata);
1007 theCase.doOpenCaseAction(Bundle.Case_progressIndicatorTitle_deletingDataSource(), theCase::deleteDataSource, CaseLockType.EXCLUSIVE,
false, dataSourceObjectID);
1028 "Case.progressIndicatorTitle.deletingCase=Deleting Case",
1029 "Case.exceptionMessage.cannotDeleteCurrentCase=Cannot delete current case, it must be closed first.",
1030 "# {0} - case display name",
"Case.exceptionMessage.deletionInterrupted=Deletion of the case {0} was cancelled."
1034 if (null != currentCase) {
1035 throw new CaseActionException(Bundle.Case_exceptionMessage_cannotDeleteCurrentCase());
1045 progressIndicator.
start(Bundle.Case_progressMessage_preparing());
1052 }
catch (InterruptedException ex) {
1058 throw new CaseActionException(Bundle.Case_exceptionMessage_deletionInterrupted(metadata.
getCaseDisplayName()), ex);
1062 progressIndicator.
finish();
1077 "Case.progressIndicatorTitle.creatingCase=Creating Case",
1078 "Case.progressIndicatorTitle.openingCase=Opening Case",
1079 "Case.exceptionMessage.cannotLocateMainWindow=Cannot locate main application window"
1083 if (null != currentCase) {
1086 }
catch (CaseActionException ex) {
1095 logger.log(Level.INFO,
"Opening {0} ({1}) in {2} as the current case",
new Object[]{newCurrentCase.getDisplayName(), newCurrentCase.getName(), newCurrentCase.getCaseDirectory()});
1096 String progressIndicatorTitle;
1099 progressIndicatorTitle = Bundle.Case_progressIndicatorTitle_creatingCase();
1100 openCaseAction = newCurrentCase::create;
1102 progressIndicatorTitle = Bundle.Case_progressIndicatorTitle_openingCase();
1103 openCaseAction = newCurrentCase::open;
1106 currentCase = newCurrentCase;
1107 logger.log(Level.INFO,
"Opened {0} ({1}) in {2} as the current case",
new Object[]{newCurrentCase.getDisplayName(), newCurrentCase.getName(), newCurrentCase.getCaseDirectory()});
1113 logger.log(Level.INFO, String.format(
"Cancelled opening %s (%s) in %s as the current case", newCurrentCase.
getDisplayName(), newCurrentCase.
getName(), newCurrentCase.
getCaseDirectory()));
1115 }
catch (CaseActionException ex) {
1116 logger.log(Level.SEVERE, String.format(
"Error opening %s (%s) in %s as the current case", newCurrentCase.
getDisplayName(), newCurrentCase.
getName(), newCurrentCase.
getCaseDirectory()), ex);
1134 String uniqueCaseName = caseDisplayName.replaceAll(
"[^\\p{ASCII}]",
"_");
1139 uniqueCaseName = uniqueCaseName.replaceAll(
"[\\p{Cntrl}]",
"_");
1144 uniqueCaseName = uniqueCaseName.replaceAll(
"[ /?:'\"\\\\]",
"_");
1149 uniqueCaseName = uniqueCaseName.toLowerCase();
1154 SimpleDateFormat dateFormat =
new SimpleDateFormat(
"yyyyMMdd_HHmmss");
1155 Date date =
new Date();
1156 uniqueCaseName = uniqueCaseName +
"_" + dateFormat.format(date);
1158 return uniqueCaseName;
1175 File caseDir =
new File(caseDirPath);
1176 if (caseDir.exists()) {
1177 if (caseDir.isFile()) {
1178 throw new CaseActionException(NbBundle.getMessage(
Case.class,
"Case.createCaseDir.exception.existNotDir", caseDirPath));
1179 }
else if (!caseDir.canRead() || !caseDir.canWrite()) {
1180 throw new CaseActionException(NbBundle.getMessage(
Case.class,
"Case.createCaseDir.exception.existCantRW", caseDirPath));
1187 if (!caseDir.mkdirs()) {
1188 throw new CaseActionException(NbBundle.getMessage(
Case.class,
"Case.createCaseDir.exception.cantCreate", caseDirPath));
1196 String hostPathComponent =
"";
1201 Path exportDir = Paths.get(caseDirPath, hostPathComponent, EXPORT_FOLDER);
1202 if (!exportDir.toFile().mkdirs()) {
1203 throw new CaseActionException(NbBundle.getMessage(
Case.class,
"Case.createCaseDir.exception.cantCreateCaseDir", exportDir));
1206 Path logsDir = Paths.get(caseDirPath, hostPathComponent, LOG_FOLDER);
1207 if (!logsDir.toFile().mkdirs()) {
1208 throw new CaseActionException(NbBundle.getMessage(
Case.class,
"Case.createCaseDir.exception.cantCreateCaseDir", logsDir));
1211 Path cacheDir = Paths.get(caseDirPath, hostPathComponent, CACHE_FOLDER);
1212 if (!cacheDir.toFile().mkdirs()) {
1213 throw new CaseActionException(NbBundle.getMessage(
Case.class,
"Case.createCaseDir.exception.cantCreateCaseDir", cacheDir));
1216 Path moduleOutputDir = Paths.get(caseDirPath, hostPathComponent, MODULE_FOLDER);
1217 if (!moduleOutputDir.toFile().mkdirs()) {
1218 throw new CaseActionException(NbBundle.getMessage(
Case.class,
"Case.createCaseDir.exception.cantCreateModDir", moduleOutputDir));
1221 Path reportsDir = Paths.get(caseDirPath, hostPathComponent, REPORTS_FOLDER);
1222 if (!reportsDir.toFile().mkdirs()) {
1223 throw new CaseActionException(NbBundle.getMessage(
Case.class,
"Case.createCaseDir.exception.cantCreateReportsDir", reportsDir));
1234 static Map<Long, String> getImagePaths(SleuthkitCase db) {
1235 Map<Long, String> imgPaths =
new HashMap<>();
1237 Map<Long, List<String>> imgPathsList = db.getImagePaths();
1238 for (Map.Entry<Long, List<String>> entry : imgPathsList.entrySet()) {
1239 if (entry.getValue().size() > 0) {
1240 imgPaths.put(entry.getKey(), entry.getValue().get(0));
1243 }
catch (TskCoreException ex) {
1244 logger.log(Level.SEVERE,
"Error getting image paths", ex);
1260 "Case.creationException.couldNotAcquireResourcesLock=Failed to get lock on case resources"
1264 Path caseDirPath = Paths.get(caseDir);
1268 }
catch (InterruptedException ex) {
1271 throw new CaseActionException(Bundle.Case_creationException_couldNotAcquireResourcesLock(), ex);
1294 String backupDbPath = caseDb.getBackupDatabasePath();
1295 if (null != backupDbPath) {
1296 JOptionPane.showMessageDialog(
1298 NbBundle.getMessage(
Case.class,
"Case.open.msgDlg.updated.msg", backupDbPath),
1299 NbBundle.getMessage(
Case.class,
"Case.open.msgDlg.updated.title"),
1300 JOptionPane.INFORMATION_MESSAGE);
1307 Map<Long, String> imgPaths = getImagePaths(caseDb);
1308 for (Map.Entry<Long, String> entry : imgPaths.entrySet()) {
1309 long obj_id = entry.getKey();
1310 String path = entry.getValue();
1318 SwingUtilities.invokeAndWait(
new Runnable() {
1321 int response = JOptionPane.showConfirmDialog(
1323 NbBundle.getMessage(
Case.class,
"Case.checkImgExist.confDlg.doesntExist.msg", path),
1324 NbBundle.getMessage(
Case.class,
"Case.checkImgExist.confDlg.doesntExist.title"),
1325 JOptionPane.YES_NO_OPTION);
1326 if (response == JOptionPane.YES_OPTION) {
1327 MissingImageDialog.makeDialog(obj_id, caseDb);
1329 logger.log(Level.SEVERE,
"User proceeding with missing image files");
1335 }
catch (InterruptedException | InvocationTargetException ex) {
1336 logger.log(Level.SEVERE,
"Failed to show missing image confirmation dialog", ex);
1347 CallableSystemAction.get(CaseDetailsAction.class).setEnabled(
true);
1362 final boolean hasData = newCurrentCase.
hasData();
1364 SwingUtilities.invokeLater(() -> {
1373 mainFrame.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
1380 mainFrame.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
1396 SwingUtilities.invokeLater(() -> {
1406 CallableSystemAction.get(
AddImageAction.class).setEnabled(
false);
1409 CallableSystemAction.get(CaseDetailsAction.class).setEnabled(
false);
1411 CallableSystemAction.get(CaseDeleteAction.class).setEnabled(
false);
1555 hostPath = Paths.get(caseDirectory);
1557 if (!hostPath.toFile().exists()) {
1558 hostPath.toFile().mkdirs();
1560 return hostPath.toString();
1567 return Paths.get(System.getProperty(
"java.io.tmpdir"),
APP_NAME,
getName());
1579 Path basePath = null;
1584 basePath = (StringUtils.isBlank(customDirectory))
1586 : Paths.get(customDirectory, APP_NAME,
getName());
1604 : Paths.get(TEMP_FOLDER);
1606 File caseTempDir = basePath
1607 .resolve(caseRelPath)
1611 if (!caseTempDir.exists()) {
1612 caseTempDir.mkdirs();
1615 return caseTempDir.getAbsolutePath();
1688 return path.subpath(path.getNameCount() - 2, path.getNameCount()).toString();
1690 return path.subpath(path.getNameCount() - 1, path.getNameCount()).toString();
1704 return caseDb.getRootObjects();
1713 Set<TimeZone> timezones =
new HashSet<>();
1714 String query =
"SELECT time_zone FROM data_source_info";
1715 try (SleuthkitCase.CaseDbQuery dbQuery = caseDb.executeQuery(query)) {
1716 ResultSet timeZoneSet = dbQuery.getResultSet();
1717 while (timeZoneSet.next()) {
1718 String timeZone = timeZoneSet.getString(
"time_zone");
1719 if (timeZone != null && !timeZone.isEmpty()) {
1720 timezones.add(TimeZone.getTimeZone(timeZone));
1723 }
catch (TskCoreException | SQLException ex) {
1724 logger.log(Level.SEVERE,
"Error getting data source time zones", ex);
1768 hasDataSource =
true;
1876 logger.log(Level.WARNING,
"Unable to send notifcation regarding comment change due to no current case being open", ex);
1926 public void addReport(String localPath, String srcModuleName, String reportName)
throws TskCoreException {
1927 addReport(localPath, srcModuleName, reportName, null);
1944 public Report
addReport(String localPath, String srcModuleName, String reportName, Content parent)
throws TskCoreException {
1945 String normalizedLocalPath;
1947 if (localPath.toLowerCase().contains(
"http:")) {
1948 normalizedLocalPath = localPath;
1950 normalizedLocalPath = Paths.get(localPath).normalize().toString();
1952 }
catch (InvalidPathException ex) {
1953 String errorMsg =
"Invalid local path provided: " + localPath;
1954 throw new TskCoreException(errorMsg, ex);
1958 Report report = this.caseDb.addReport(normalizedLocalPath, srcModuleName, reportName, parent);
1972 return this.caseDb.getAllReports();
1983 public void deleteReports(Collection<? extends Report> reports)
throws TskCoreException {
1984 for (Report report : reports) {
1985 this.caseDb.deleteReport(report);
1990 }
catch (TskCoreException ex) {
1991 logger.log(Level.SEVERE,
"Unable to retrieve the hasData status from the db", ex);
1994 for (Report report : reports) {
2016 "Case.exceptionMessage.metadataUpdateError=Failed to update case metadata"
2018 void updateCaseDetails(CaseDetails caseDetails)
throws CaseActionException {
2021 metadata.setCaseDetails(caseDetails);
2022 }
catch (CaseMetadataException ex) {
2023 throw new CaseActionException(Bundle.Case_exceptionMessage_metadataUpdateError(), ex);
2027 CaseNodeData nodeData = CaseNodeData.readCaseNodeData(metadata.
getCaseDirectory());
2029 CaseNodeData.writeCaseNodeData(nodeData);
2030 }
catch (CaseNodeDataException | InterruptedException ex) {
2031 throw new CaseActionException(Bundle.Case_exceptionMessage_couldNotUpdateCaseNodeData(ex.getLocalizedMessage()), ex);
2034 if (!oldCaseDetails.getCaseNumber().equals(caseDetails.
getCaseNumber())) {
2035 eventPublisher.
publish(
new AutopsyEvent(Events.NUMBER.toString(), oldCaseDetails.getCaseNumber(), caseDetails.
getCaseNumber()));
2037 if (!oldCaseDetails.getExaminerName().equals(caseDetails.
getExaminerName())) {
2038 eventPublisher.
publish(
new AutopsyEvent(Events.NUMBER.toString(), oldCaseDetails.getExaminerName(), caseDetails.
getExaminerName()));
2041 eventPublisher.
publish(
new AutopsyEvent(Events.NAME.toString(), oldCaseDetails.getCaseDisplayName(), caseDetails.
getCaseDisplayName()));
2043 eventPublisher.
publish(
new AutopsyEvent(Events.CASE_DETAILS.toString(), oldCaseDetails, caseDetails));
2044 if (RuntimeProperties.runningWithGUI()) {
2045 SwingUtilities.invokeLater(() -> {
2049 }
catch (Exception ex) {
2050 logger.log(Level.SEVERE,
"Error updating case name in UI", ex);
2078 metadata = caseMetaData;
2112 "Case.progressIndicatorCancelButton.label=Cancel",
2113 "Case.progressMessage.preparing=Preparing...",
2114 "Case.progressMessage.cancelling=Cancelling...",
2115 "Case.exceptionMessage.cancelled=Cancelled.",
2116 "# {0} - exception message",
"Case.exceptionMessage.execExceptionWrapperMessage={0}"
2126 if (allowCancellation) {
2130 progressIndicatorTitle,
2131 new String[]{Bundle.Case_progressIndicatorCancelButton_label()},
2132 Bundle.Case_progressIndicatorCancelButton_label(),
2133 cancelButtonListener);
2137 progressIndicatorTitle);
2142 progressIndicator.
start(Bundle.Case_progressMessage_preparing());
2151 caseActionExecutor = Executors.newSingleThreadExecutor(threadFactory);
2152 Future<Void> future = caseActionExecutor.submit(() -> {
2154 caseAction.
execute(progressIndicator, additionalParams);
2158 if (null == resourcesLock) {
2159 throw new CaseActionException(Bundle.Case_creationException_couldNotAcquireResourcesLock());
2161 caseAction.
execute(progressIndicator, additionalParams);
2162 }
catch (CaseActionException ex) {
2169 if (null != cancelButtonListener) {
2178 }
catch (InterruptedException discarded) {
2182 if (null != cancelButtonListener) {
2185 future.cancel(
true);
2188 }
catch (CancellationException discarded) {
2194 }
catch (ExecutionException ex) {
2199 throw new CaseActionException(Bundle.Case_exceptionMessage_execExceptionWrapperMessage(ex.getCause().getLocalizedMessage()), ex);
2201 progressIndicator.
finish();
2221 assert (additionalParams == null);
2242 }
catch (CaseActionException ex) {
2251 }
catch (InterruptedException discarded) {
2253 close(progressIndicator);
2273 assert (additionalParams == null);
2293 }
catch (CaseActionException ex) {
2302 }
catch (InterruptedException discarded) {
2304 close(progressIndicator);
2319 "# {0} - case",
"Case.openFileSystems.retrievingImages=Retrieving images for case: {0}...",
2320 "# {0} - image",
"Case.openFileSystems.openingImage=Opening all filesystems for image: {0}..."
2323 if (backgroundOpenFileSystemsFuture != null && !backgroundOpenFileSystemsFuture.isDone()) {
2324 backgroundOpenFileSystemsFuture.cancel(
true);
2353 caseName = (this.tskCase != null) ? this.tskCase.getDatabaseName() :
"";
2364 if (Thread.interrupted()) {
2365 throw new InterruptedException();
2375 progressIndicator.
progress(Bundle.Case_openFileSystems_retrievingImages(caseName));
2377 return this.tskCase.getImages();
2378 }
catch (TskCoreException ex) {
2381 String.format(
"Could not obtain images while opening case: %s.", caseName),
2397 private void openFileSystems(List<Image> images)
throws TskCoreException, InterruptedException {
2398 byte[] tempBuff =
new byte[512];
2400 for (Image image : images) {
2401 String imageStr = image.getName();
2403 progressIndicator.
progress(Bundle.Case_openFileSystems_openingImage(imageStr));
2405 Collection<FileSystem> fileSystems = this.tskCase.getImageFileSystems(image);
2407 for (FileSystem fileSystem : fileSystems) {
2408 fileSystem.read(tempBuff, 0, 512);
2420 if (images == null) {
2428 String.format(
"Skipping background load of file systems due to large number of images in case (%d)", images.size()));
2434 }
catch (InterruptedException ex) {
2437 String.format(
"Background operation opening all file systems in %s has been cancelled.", caseName));
2438 }
catch (Exception ex) {
2440 logger.log(Level.WARNING,
"Error while opening file systems in background", ex);
2461 "Case.progressMessage.deletingDataSource=Removing the data source from the case...",
2462 "Case.exceptionMessage.dataSourceNotFound=The data source was not found.",
2463 "Case.exceptionMessage.errorDeletingDataSourceFromCaseDb=An error occurred while removing the data source from the case database.",
2464 "Case.exceptionMessage.errorDeletingDataSourceFromTextIndex=An error occurred while removing the data source from the text index.",})
2465 Void deleteDataSource(ProgressIndicator progressIndicator, Object additionalParams)
throws CaseActionException {
2466 assert (additionalParams instanceof Long);
2467 open(progressIndicator, null);
2469 progressIndicator.progress(Bundle.Case_progressMessage_deletingDataSource());
2470 Long dataSourceObjectID = (Long) additionalParams;
2472 DataSource dataSource = this.caseDb.getDataSource(dataSourceObjectID);
2473 if (dataSource == null) {
2474 throw new CaseActionException(Bundle.Case_exceptionMessage_dataSourceNotFound());
2476 SleuthkitCaseAdminUtil.deleteDataSource(this.caseDb, dataSourceObjectID);
2477 }
catch (TskDataException | TskCoreException ex) {
2478 throw new CaseActionException(Bundle.Case_exceptionMessage_errorDeletingDataSourceFromCaseDb(), ex);
2482 }
catch (KeywordSearchServiceException ex) {
2483 throw new CaseActionException(Bundle.Case_exceptionMessage_errorDeletingDataSourceFromTextIndex(), ex);
2485 eventPublisher.
publish(
new DataSourceDeletedEvent(dataSourceObjectID));
2488 close(progressIndicator);
2503 public SleuthkitCase
createPortableCase(String caseName, File portableCaseFolder)
throws TskCoreException {
2505 if (portableCaseFolder.exists()) {
2506 throw new TskCoreException(
"Portable case folder " + portableCaseFolder.toString() +
" already exists");
2508 if (!portableCaseFolder.mkdirs()) {
2509 throw new TskCoreException(
"Error creating portable case folder " + portableCaseFolder.toString());
2517 portableCaseMetadata.setCaseDatabaseName(SINGLE_USER_CASE_DB_NAME);
2519 throw new TskCoreException(
"Error creating case metadata", ex);
2523 SleuthkitCase portableSleuthkitCase;
2525 portableSleuthkitCase = SleuthkitCase.newCase(dbFilePath);
2527 return portableSleuthkitCase;
2540 if (Thread.currentThread().isInterrupted()) {
2541 throw new CaseActionCancelledException(Bundle.Case_exceptionMessage_cancelled());
2556 "Case.progressMessage.creatingCaseDirectory=Creating case directory..."
2563 progressIndicator.
progress(Bundle.Case_progressMessage_creatingCaseDirectory());
2565 progressIndicator.
progress(Bundle.Case_progressMessage_creatingCaseDirectory());
2577 "Case.progressMessage.switchingLogDirectory=Switching log directory..."
2580 progressIndicator.
progress(Bundle.Case_progressMessage_switchingLogDirectory());
2596 "Case.progressMessage.savingCaseMetadata=Saving case metadata to file...",
2597 "# {0} - exception message",
"Case.exceptionMessage.couldNotSaveCaseMetadata=Failed to save case metadata:\n{0}."
2600 progressIndicator.
progress(Bundle.Case_progressMessage_savingCaseMetadata());
2602 this.metadata.writeToFile();
2604 throw new CaseActionException(Bundle.Case_exceptionMessage_couldNotSaveCaseMetadata(ex.getLocalizedMessage()), ex);
2620 "Case.progressMessage.creatingCaseNodeData=Creating coordination service node data...",
2621 "# {0} - exception message",
"Case.exceptionMessage.couldNotCreateCaseNodeData=Failed to create coordination service node data:\n{0}."
2625 progressIndicator.
progress(Bundle.Case_progressMessage_creatingCaseNodeData());
2629 throw new CaseActionException(Bundle.Case_exceptionMessage_couldNotCreateCaseNodeData(ex.getLocalizedMessage()), ex);
2646 "Case.progressMessage.updatingCaseNodeData=Updating coordination service node data...",
2647 "# {0} - exception message",
"Case.exceptionMessage.couldNotUpdateCaseNodeData=Failed to update coordination service node data:\n{0}."
2651 progressIndicator.
progress(Bundle.Case_progressMessage_updatingCaseNodeData());
2657 throw new CaseActionException(Bundle.Case_exceptionMessage_couldNotUpdateCaseNodeData(ex.getLocalizedMessage()), ex);
2668 "Case.progressMessage.clearingTempDirectory=Clearing case temp directory..."
2674 progressIndicator.
progress(Bundle.Case_progressMessage_clearingTempDirectory());
2690 "Case.progressMessage.creatingCaseDatabase=Creating case database...",
2691 "# {0} - exception message",
"Case.exceptionMessage.couldNotGetDbServerConnectionInfo=Failed to get case database server conneciton info:\n{0}.",
2692 "# {0} - exception message",
"Case.exceptionMessage.couldNotCreateCaseDatabase=Failed to create case database:\n{0}.",
2693 "# {0} - exception message",
"Case.exceptionMessage.couldNotSaveDbNameToMetadataFile=Failed to save case database name to case metadata file:\n{0}."
2696 progressIndicator.
progress(Bundle.Case_progressMessage_creatingCaseDatabase());
2705 metadata.setCaseDatabaseName(SINGLE_USER_CASE_DB_NAME);
2713 metadata.setCaseDatabaseName(caseDb.getDatabaseName());
2715 }
catch (TskCoreException ex) {
2716 throw new CaseActionException(Bundle.Case_exceptionMessage_couldNotCreateCaseDatabase(ex.getLocalizedMessage()), ex);
2718 throw new CaseActionException(Bundle.Case_exceptionMessage_couldNotGetDbServerConnectionInfo(ex.getLocalizedMessage()), ex);
2720 throw new CaseActionException(Bundle.Case_exceptionMessage_couldNotSaveDbNameToMetadataFile(ex.getLocalizedMessage()), ex);
2736 "Case.progressMessage.openingCaseDatabase=Opening case database...",
2737 "# {0} - exception message",
"Case.exceptionMessage.couldNotOpenCaseDatabase=Failed to open case database:\n{0}.",
2738 "# {0} - exception message",
"Case.exceptionMessage.unsupportedSchemaVersionMessage=Unsupported case database schema version:\n{0}.",
2739 "Case.open.exception.multiUserCaseNotEnabled=Cannot open a multi-user case if multi-user cases are not enabled. See Tools, Options, Multi-User."
2742 progressIndicator.
progress(Bundle.Case_progressMessage_openingCaseDatabase());
2746 caseDb = SleuthkitCase.openCase(Paths.get(metadata.
getCaseDirectory(), databaseName).toString());
2750 throw new CaseActionException(Bundle.Case_open_exception_multiUserCaseNotEnabled());
2753 }
catch (TskUnsupportedSchemaVersionException ex) {
2754 throw new CaseActionException(Bundle.Case_exceptionMessage_unsupportedSchemaVersionMessage(ex.getLocalizedMessage()), ex);
2756 throw new CaseActionException(Bundle.Case_exceptionMessage_couldNotGetDbServerConnectionInfo(ex.getLocalizedMessage()), ex);
2757 }
catch (TskCoreException ex) {
2758 throw new CaseActionException(Bundle.Case_exceptionMessage_couldNotOpenCaseDatabase(ex.getLocalizedMessage()), ex);
2769 "Case.progressMessage.openingCaseLevelServices=Opening case-level services...",})
2771 progressIndicator.
progress(Bundle.Case_progressMessage_openingCaseLevelServices());
2772 this.caseServices =
new Services(caseDb);
2778 caseDb.registerForEvents(sleuthkitEventListener);
2793 @NbBundle.Messages({
2794 "Case.progressMessage.openingApplicationServiceResources=Opening application service case resources...",
2795 "# {0} - service name",
"Case.serviceOpenCaseResourcesProgressIndicator.title={0} Opening Case Resources",
2796 "# {0} - service name",
"Case.serviceOpenCaseResourcesProgressIndicator.cancellingMessage=Cancelling opening case resources by {0}...",
2797 "# {0} - service name",
"Case.servicesException.notificationTitle={0} Error"
2808 progressIndicator.
progress(Bundle.Case_progressMessage_openingApplicationServiceResources());
2820 cancelButtonListener =
new CancelButtonListener(Bundle.Case_serviceOpenCaseResourcesProgressIndicator_cancellingMessage(service.getServiceName()));
2823 Bundle.Case_serviceOpenCaseResourcesProgressIndicator_title(service.getServiceName()),
2824 new String[]{Bundle.Case_progressIndicatorCancelButton_label()},
2825 Bundle.Case_progressIndicatorCancelButton_label(),
2826 cancelButtonListener);
2830 appServiceProgressIndicator.
start(Bundle.Case_progressMessage_preparing());
2832 String threadNameSuffix = service.getServiceName().replaceAll(
"[ ]",
"-");
2833 threadNameSuffix = threadNameSuffix.toLowerCase();
2835 ExecutorService executor = Executors.newSingleThreadExecutor(threadFactory);
2836 Future<Void> future = executor.submit(() -> {
2837 service.openCaseResources(context);
2840 if (null != cancelButtonListener) {
2852 }
catch (InterruptedException discarded) {
2857 future.cancel(
true);
2858 }
catch (CancellationException discarded) {
2866 }
catch (ExecutionException ex) {
2873 Case.
logger.log(Level.SEVERE, String.format(
"%s failed to open case resources for %s", service.getServiceName(), this.
getDisplayName()), ex);
2875 SwingUtilities.invokeLater(() -> {
2887 appServiceProgressIndicator.
finish();
2905 "Case.progressMessage.settingUpNetworkCommunications=Setting up network communications...",
2906 "# {0} - exception message",
"Case.exceptionMessage.couldNotOpenRemoteEventChannel=Failed to open remote events channel:\n{0}.",
2907 "# {0} - exception message",
"Case.exceptionMessage.couldNotCreatCollaborationMonitor=Failed to create collaboration monitor:\n{0}."
2911 progressIndicator.
progress(Bundle.Case_progressMessage_settingUpNetworkCommunications());
2915 collaborationMonitor =
new CollaborationMonitor(metadata.
getCaseName());
2917 throw new CaseActionException(Bundle.Case_exceptionMessage_couldNotOpenRemoteEventChannel(ex.getLocalizedMessage()), ex);
2918 }
catch (CollaborationMonitor.CollaborationMonitorException ex) {
2919 throw new CaseActionException(Bundle.Case_exceptionMessage_couldNotCreatCollaborationMonitor(ex.getLocalizedMessage()), ex);
2947 Bundle.Case_progressIndicatorTitle_closingCase());
2951 progressIndicator.
start(Bundle.Case_progressMessage_preparing());
2960 Future<Void> future = caseActionExecutor.submit(() -> {
2962 close(progressIndicator);
2969 progressIndicator.
progress(Bundle.Case_progressMessage_preparing());
2971 if (null == resourcesLock) {
2972 throw new CaseActionException(Bundle.Case_creationException_couldNotAcquireResourcesLock());
2974 close(progressIndicator);
2988 }
catch (InterruptedException | CancellationException unused) {
2995 }
catch (ExecutionException ex) {
2996 throw new CaseActionException(Bundle.Case_exceptionMessage_execExceptionWrapperMessage(ex.getCause().getMessage()), ex);
2999 progressIndicator.
finish();
3009 "Case.progressMessage.shuttingDownNetworkCommunications=Shutting down network communications...",
3010 "Case.progressMessage.closingApplicationServiceResources=Closing case-specific application service resources...",
3011 "Case.progressMessage.closingCaseDatabase=Closing case database..."
3021 progressIndicator.
progress(Bundle.Case_progressMessage_shuttingDownNetworkCommunications());
3022 if (null != collaborationMonitor) {
3023 collaborationMonitor.shutdown();
3032 progressIndicator.
progress(Bundle.Case_progressMessage_closingApplicationServiceResources());
3038 if (null != caseDb) {
3039 progressIndicator.
progress(Bundle.Case_progressMessage_closingCaseDatabase());
3040 caseDb.unregisterForEvents(sleuthkitEventListener);
3052 progressIndicator.
progress(Bundle.Case_progressMessage_switchingLogDirectory());
3061 "# {0} - serviceName",
"Case.serviceCloseResourcesProgressIndicator.title={0} Closing Case Resources",
3062 "# {0} - service name",
"# {1} - exception message",
"Case.servicesException.serviceResourcesCloseError=Could not close case resources for {0} service: {1}"
3075 Bundle.Case_serviceCloseResourcesProgressIndicator_title(service.getServiceName()));
3079 progressIndicator.
start(Bundle.Case_progressMessage_preparing());
3081 String threadNameSuffix = service.getServiceName().replaceAll(
"[ ]",
"-");
3082 threadNameSuffix = threadNameSuffix.toLowerCase();
3084 ExecutorService executor = Executors.newSingleThreadExecutor(threadFactory);
3085 Future<Void> future = executor.submit(() -> {
3086 service.closeCaseResources(context);
3091 }
catch (InterruptedException ex) {
3092 Case.
logger.log(Level.SEVERE, String.format(
"Unexpected interrupt while waiting on %s service to close case resources", service.getServiceName()), ex);
3093 }
catch (CancellationException ex) {
3094 Case.
logger.log(Level.SEVERE, String.format(
"Unexpected cancellation while waiting on %s service to close case resources", service.getServiceName()), ex);
3095 }
catch (ExecutionException ex) {
3096 Case.
logger.log(Level.SEVERE, String.format(
"%s service failed to open case resources", service.getServiceName()), ex);
3099 Bundle.Case_servicesException_notificationTitle(service.getServiceName()),
3100 Bundle.Case_servicesException_serviceResourcesCloseError(service.getServiceName(), ex.getLocalizedMessage())));
3104 progressIndicator.
finish();
3115 "Case.lockingException.couldNotAcquireSharedLock=Failed to get a shared lock on the case.",
3116 "Case.lockingException.couldNotAcquireExclusiveLock=Failed to get an exclusive lock on the case."
3127 throw new CaseActionException(Bundle.Case_lockingException_couldNotAcquireSharedLock());
3129 throw new CaseActionException(Bundle.Case_lockingException_couldNotAcquireExclusiveLock());
3134 throw new CaseActionException(Bundle.Case_lockingException_couldNotAcquireSharedLock(), ex);
3136 throw new CaseActionException(Bundle.Case_lockingException_couldNotAcquireExclusiveLock(), ex);
3150 logger.log(Level.SEVERE, String.format(
"Failed to release shared case directory lock for %s",
getMetadata().
getCaseDirectory()), ex);
3163 if (!subDirectory.exists()) {
3164 subDirectory.mkdirs();
3166 return subDirectory.toString();
3182 "Case.exceptionMessage.errorsDeletingCase=Errors occured while deleting the case. See the application log for details."
3185 boolean errorsOccurred =
false;
3189 errorsOccurred =
true;
3195 }
catch (CaseActionException ex) {
3196 errorsOccurred =
true;
3202 if (errorsOccurred) {
3203 throw new CaseActionException(Bundle.Case_exceptionMessage_errorsDeletingCase());
3227 "Case.progressMessage.connectingToCoordSvc=Connecting to coordination service...",
3228 "# {0} - exception message",
"Case.exceptionMessage.failedToConnectToCoordSvc=Failed to connect to coordination service:\n{0}.",
3229 "Case.exceptionMessage.cannotGetLockToDeleteCase=Cannot delete case because it is open for another user or host.",
3230 "# {0} - exception message",
"Case.exceptionMessage.failedToLockCaseForDeletion=Failed to exclusively lock case for deletion:\n{0}.",
3231 "Case.progressMessage.fetchingCoordSvcNodeData=Fetching coordination service node data for the case...",
3232 "# {0} - exception message",
"Case.exceptionMessage.failedToFetchCoordSvcNodeData=Failed to fetch coordination service node data:\n{0}.",
3233 "Case.progressMessage.deletingResourcesCoordSvcNode=Deleting case resources coordination service node...",
3234 "Case.progressMessage.deletingCaseDirCoordSvcNode=Deleting case directory coordination service node..."
3237 progressIndicator.
progress(Bundle.Case_progressMessage_connectingToCoordSvc());
3243 throw new CaseActionException(Bundle.Case_exceptionMessage_failedToConnectToCoordSvc(ex.getLocalizedMessage()));
3247 boolean errorsOccurred =
false;
3249 if (dirLock == null) {
3251 throw new CaseActionException(Bundle.Case_exceptionMessage_cannotGetLockToDeleteCase());
3254 progressIndicator.
progress(Bundle.Case_progressMessage_fetchingCoordSvcNodeData());
3259 throw new CaseActionException(Bundle.Case_exceptionMessage_failedToFetchCoordSvcNodeData(ex.getLocalizedMessage()));
3264 progressIndicator.
progress(Bundle.Case_progressMessage_deletingResourcesCoordSvcNode());
3270 errorsOccurred =
true;
3271 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);
3273 }
catch (InterruptedException ex) {
3274 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);
3279 throw new CaseActionException(Bundle.Case_exceptionMessage_failedToLockCaseForDeletion(ex.getLocalizedMessage()));
3282 if (!errorsOccurred) {
3283 progressIndicator.
progress(Bundle.Case_progressMessage_deletingCaseDirCoordSvcNode());
3289 errorsOccurred =
true;
3293 if (errorsOccurred) {
3294 throw new CaseActionException(Bundle.Case_exceptionMessage_errorsDeletingCase());
3324 boolean errorsOccurred =
false;
3331 errorsOccurred =
true;
3334 errorsOccurred =
true;
3336 }
catch (CaseActionException ex) {
3337 errorsOccurred =
true;
3340 return errorsOccurred;
3364 "Case.progressMessage.deletingCaseDatabase=Deleting case database..."
3368 progressIndicator.
progress(Bundle.Case_progressMessage_deletingCaseDatabase());
3369 logger.log(Level.INFO, String.format(
"Deleting case database for %s (%s) in %s", caseNodeData.
getDisplayName(), caseNodeData.
getName(), caseNodeData.
getDirectory()));
3371 String url =
"jdbc:postgresql://" + info.getHost() +
":" + info.getPort() +
"/postgres";
3372 Class.forName(
"org.postgresql.Driver");
3373 try (Connection connection = DriverManager.getConnection(url, info.getUserName(), info.getPassword()); Statement statement = connection.createStatement()) {
3374 String dbExistsQuery =
"SELECT 1 from pg_database WHERE datname = '" + metadata.
getCaseDatabaseName() +
"'";
3375 try (ResultSet queryResult = statement.executeQuery(dbExistsQuery)) {
3376 if (queryResult.next()) {
3378 statement.execute(deleteCommand);
3419 "Case.progressMessage.deletingTextIndex=Deleting text index..."
3422 progressIndicator.
progress(Bundle.Case_progressMessage_deletingTextIndex());
3426 searchService.deleteTextIndex(metadata);
3462 "Case.progressMessage.deletingCaseDirectory=Deleting case directory..."
3465 progressIndicator.
progress(Bundle.Case_progressMessage_deletingCaseDirectory());
3467 throw new CaseActionException(String.format(
"Failed to delete %s", metadata.
getCaseDirectory()));
3479 "Case.progressMessage.removingCaseFromRecentCases=Removing case from Recent Cases menu..."
3483 progressIndicator.
progress(Bundle.Case_progressMessage_removingCaseFromRecentCases());
3484 SwingUtilities.invokeLater(() -> {
3500 boolean isNodeNodeEx =
false;
3501 Throwable cause = ex.getCause();
3502 if (cause != null) {
3503 String causeMessage = cause.getMessage();
3504 isNodeNodeEx = causeMessage.contains(NO_NODE_ERROR_MSG_FRAGMENT);
3506 return isNodeNodeEx;
3525 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);
3544 if (!hasDataSource) {
3559 String query =
"SELECT count(*) AS count FROM (SELECT * FROM data_source_info LIMIT 1)t";
3560 try (SleuthkitCase.CaseDbQuery dbQuery = caseDb.executeQuery(query)) {
3561 ResultSet resultSet = dbQuery.getResultSet();
3562 if (resultSet.next()) {
3563 return resultSet.getLong(
"count") > 0;
3566 }
catch (SQLException ex) {
3567 logger.log(Level.SEVERE,
"Error accessing case database", ex);
3568 throw new TskCoreException(
"Error accessing case databse", ex);
3583 String query =
"SELECT SUM(cnt) total FROM "
3584 +
"(SELECT COUNT(*) AS cnt FROM "
3585 +
"(SELECT * FROM tsk_objects LIMIT 1)t "
3587 +
"SELECT COUNT(*) AS cnt FROM "
3588 +
"(SELECT * FROM tsk_hosts LIMIT 1)r) s";
3589 try (SleuthkitCase.CaseDbQuery dbQuery = caseDb.executeQuery(query)) {
3590 ResultSet resultSet = dbQuery.getResultSet();
3591 if (resultSet.next()) {
3592 return resultSet.getLong(
"total") > 0;
3596 }
catch (SQLException ex) {
3597 logger.log(Level.SEVERE,
"Error accessing case database", ex);
3598 throw new TskCoreException(
"Error accessing case databse", ex);
3622 R
execute(T progressIndicator, V additionalParams)
throws CaseActionException;
3720 ((ModalDialogProgressIndicator) progressIndicator).
setCancelling(cancellationMessage);
3749 return new Thread(task, threadName);
3786 public static void create(String caseDir, String caseDisplayName, String caseNumber, String examiner)
throws CaseActionException {
3811 public static void create(String caseDir, String caseDisplayName, String caseNumber, String examiner,
CaseType caseType)
throws CaseActionException {
3827 public static void open(String caseMetadataFilePath)
throws CaseActionException {
3884 return new File(filePath).isFile();
3923 return "ModuleOutput";
3936 public static PropertyChangeSupport
3938 return new PropertyChangeSupport(
Case.class
3970 public Image
addImage(String imgPath,
long imgId, String timeZone)
throws CaseActionException {
3972 Image newDataSource = caseDb.getImageById(imgId);
3974 return newDataSource;
3975 }
catch (TskCoreException ex) {
3976 throw new CaseActionException(NbBundle.getMessage(
this.getClass(),
"Case.addImg.exception.msg"), ex);
4003 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)
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()