19 package org.sleuthkit.autopsy.timeline;
 
   21 import java.io.IOException;
 
   22 import java.io.InputStream;
 
   23 import java.io.OutputStream;
 
   24 import java.nio.file.Files;
 
   25 import java.nio.file.Path;
 
   26 import java.nio.file.Paths;
 
   27 import java.util.Objects;
 
   28 import java.util.Properties;
 
   29 import org.apache.commons.lang3.StringUtils;
 
   35 class PerCaseTimelineProperties {
 
   37     private static final String STALE_KEY = 
"stale"; 
 
   38     private static final String WAS_INGEST_RUNNING_KEY = 
"was_ingest_running"; 
 
   40     private final Case autoCase;
 
   41     private final Path propertiesPath;
 
   43     PerCaseTimelineProperties(Case c) {
 
   44         Objects.requireNonNull(c, 
"Case must not be null");
 
   46         propertiesPath = Paths.get(autoCase.getModuleDirectory(), 
"Timeline", 
"timeline.properties"); 
 
   57     public synchronized boolean isDBStale() throws IOException {
 
   59         String stale = getProperty(STALE_KEY);
 
   60         return StringUtils.isBlank(stale) ? 
true : Boolean.valueOf(stale);
 
   72     public synchronized void setDbStale(Boolean stale) 
throws IOException {
 
   73         setProperty(STALE_KEY, stale.toString());
 
   83     public synchronized boolean wasIngestRunning() throws IOException {
 
   84         String stale = getProperty(WAS_INGEST_RUNNING_KEY);
 
   85         return StringUtils.isBlank(stale) ? 
true : Boolean.valueOf(stale);
 
   96     public synchronized void setIngestRunning(Boolean ingestRunning) 
throws IOException {
 
   97         setProperty(WAS_INGEST_RUNNING_KEY, ingestRunning.toString());
 
  108     private synchronized Path getPropertiesPath() throws IOException {
 
  110         if (!Files.exists(propertiesPath)) {
 
  111             Path parent = propertiesPath.getParent();
 
  112             Files.createDirectories(parent);
 
  113             Files.createFile(propertiesPath);
 
  115         return propertiesPath;
 
  127     private synchronized String getProperty(String propertyKey) 
throws IOException {
 
  128         return getProperties().getProperty(propertyKey);
 
  139     private synchronized void setProperty(String propertyKey, String propertyValue) 
throws IOException {
 
  140         Path propertiesFile = getPropertiesPath();
 
  141         Properties props = getProperties(propertiesFile);
 
  142         props.setProperty(propertyKey, propertyValue);
 
  144         try (OutputStream fos = Files.newOutputStream(propertiesFile)) {
 
  145             props.store(fos, 
""); 
 
  156     private synchronized Properties getProperties() throws IOException {
 
  157         return getProperties(getPropertiesPath());
 
  170     private synchronized Properties getProperties(
final Path propertiesFile) 
throws IOException {
 
  171         try (InputStream inputStream = Files.newInputStream(propertiesFile)) {
 
  172             Properties props = 
new Properties();
 
  173             props.load(inputStream);