19 package org.sleuthkit.autopsy.core;
 
   22 import java.io.FileInputStream;
 
   23 import java.io.FileOutputStream;
 
   24 import java.io.IOException;
 
   25 import java.io.InputStream;
 
   26 import java.util.Map.Entry;
 
   27 import java.util.Properties;
 
   28 import java.util.logging.Level;
 
   29 import java.util.prefs.AbstractPreferences;
 
   30 import java.util.prefs.BackingStoreException;
 
   36 class ConfigProperties 
extends AbstractPreferences {
 
   40     private static java.util.logging.Logger logger = null;
 
   49     private static java.util.logging.Logger getLogger() {
 
   56     private final Properties inMemoryProperties = 
new Properties();
 
   57     private final String configPath;
 
   65     public ConfigProperties(String configPath) {
 
   67         this.configPath = configPath;
 
   75     public synchronized void load() throws IOException {
 
   76         Properties loaded = loadSavedProperties(this.configPath);
 
   77         this.inMemoryProperties.clear();
 
   78         mergeProperties(loaded, this.inMemoryProperties, 
true);
 
   82     protected void putSpi(String key, String value) {
 
   83         inMemoryProperties.put(key, value);
 
   88     protected String getSpi(String key) {
 
   89         Object val = inMemoryProperties.get(key);
 
   96     protected void removeSpi(String key) {
 
   97         inMemoryProperties.remove(key);
 
  102     protected void removeNodeSpi() throws BackingStoreException {
 
  103         inMemoryProperties.clear();
 
  108     protected String[] keysSpi() throws BackingStoreException {
 
  109         return inMemoryProperties.keySet().toArray(
new String[inMemoryProperties.size()]);
 
  113     protected String[] childrenNamesSpi() throws BackingStoreException {
 
  114         return new String[0];
 
  118     protected AbstractPreferences childSpi(String name) {
 
  119         throw new IllegalArgumentException(
"Cannot create new child nodes");
 
  123     protected void syncSpi() throws BackingStoreException {
 
  125             Properties onDiskProps = loadSavedProperties(this.configPath);
 
  126             mergeProperties(onDiskProps, this.inMemoryProperties, 
false);
 
  128         } 
catch (IOException ex) {
 
  129             throw new BackingStoreException(
new IOException(
"An error occurred while saving to: " + this.configPath, ex));
 
  136     private void tryFlush() {
 
  139         } 
catch (BackingStoreException ex) {
 
  140             getLogger().log(Level.SEVERE, 
"An error occurred when writing to disk at: " + 
this.configPath, ex);
 
  145     protected void flushSpi() throws BackingStoreException {
 
  146         try (FileOutputStream fos = 
new FileOutputStream(this.configPath)) {
 
  147             this.inMemoryProperties.store(fos, 
"Set settings (batch)");
 
  148         } 
catch (IOException ex) {
 
  149             throw new BackingStoreException(
new IOException(
"An error occurred while saving to: " + this.configPath, ex));
 
  164     private static Properties loadSavedProperties(String path) 
throws IOException {
 
  165         Properties props = 
new Properties();
 
  167         File propFile = 
new File(path);
 
  168         if (propFile.exists()) {
 
  169             try (InputStream inputStream = 
new FileInputStream(propFile)) {
 
  170                 props.load(inputStream);
 
  185     private static void mergeProperties(Properties src, Properties dest, 
boolean overwrite) {
 
  189             for (Entry<Object, Object> entry : dest.entrySet()) {
 
  190                 dest.putIfAbsent(entry.getKey(), entry.getValue());
 
synchronized static Logger getLogger(String name)