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