All Downloads are FREE. Search and download functionalities are using the official Maven repository.

cdc.util.prefs.FilePreferences Maven / Gradle / Ivy

There is a newer version: 0.9.0
Show newest version
package cdc.util.prefs;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.TreeMap;
import java.util.prefs.AbstractPreferences;
import java.util.prefs.BackingStoreException;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

/**
 * Preferences implementation that stores data to a user defined file.
 * 

* This is an adaptation of public domain code developed by David C., that * can be found here. */ public class FilePreferences extends AbstractPreferences { private static final Logger LOGGER = LogManager.getLogger(FilePreferences.class); private final Map root = new TreeMap<>(); private final Map children = new TreeMap<>(); private boolean isRemoved = false; public FilePreferences(AbstractPreferences parent, String name) { super(parent, name); LOGGER.trace("({}, {})", parent == null ? "null" : parent.absolutePath(), name); try { sync(); } catch (final BackingStoreException e) { LOGGER.error("Unable to sync on creation of node " + name, e); } } private void buildPath(StringBuilder builder) { final FilePreferences parent = (FilePreferences) parent(); if (parent != null) { parent.buildPath(builder); builder.append(name()).append('.'); } } private String getPath() { final StringBuilder builder = new StringBuilder(); buildPath(builder); return builder.toString(); } @Override protected void putSpi(String key, String value) { LOGGER.trace("putSpi({}, {})", key, value); root.put(key, value); try { flush(); } catch (final BackingStoreException e) { LOGGER.error("Unable to flush after putting " + key, e); } } @Override protected String getSpi(String key) { LOGGER.trace("getSpi({})", key); return root.get(key); } @Override protected void removeSpi(String key) { LOGGER.trace("removeSpi({})", key); root.remove(key); try { flush(); } catch (final BackingStoreException e) { LOGGER.error("Unable to flush after removing " + key, e); } } @Override protected void removeNodeSpi() throws BackingStoreException { LOGGER.trace("removeNodeSpi()"); isRemoved = true; flush(); } @Override protected String[] keysSpi() { return root.keySet().toArray(new String[root.keySet().size()]); } @Override protected String[] childrenNamesSpi() { return children.keySet().toArray(new String[children.keySet().size()]); } @Override protected FilePreferences childSpi(String name) { LOGGER.trace("childSpi({})", name); FilePreferences child = children.get(name); if (child == null || child.isRemoved()) { child = new FilePreferences(this, name); children.put(name, child); } return child; } @Override protected void syncSpi() throws BackingStoreException { LOGGER.trace("syncSpi()"); if (isRemoved()) { return; } final File file = FilePreferencesFactory.getPreferencesFile(); if (!file.exists()) { return; } synchronized (file) { LOGGER.trace("load({})", file); final Properties properties = new Properties(); try (final FileInputStream fis = new FileInputStream(file)) { properties.load(fis); final String path = getPath(); for (final String key : properties.stringPropertyNames()) { if (key.startsWith(path)) { final String subKey = key.substring(path.length()); // Only load immediate descendants if (subKey.indexOf('.') == -1) { root.put(subKey, properties.getProperty(key)); } } } } catch (final IOException e) { LOGGER.catching(e); throw new BackingStoreException(e); } } } @Override protected void flushSpi() throws BackingStoreException { LOGGER.trace("flushSpi()"); final File file = FilePreferencesFactory.getPreferencesFile(); synchronized (file) { final Properties properties = new Properties(); try { final String path = getPath(); if (file.exists()) { try (final FileInputStream fis = new FileInputStream(file)) { properties.load(fis); } final List toRemove = new ArrayList<>(); // Make a list of all direct children of this node to be // removed for (final String key : properties.stringPropertyNames()) { if (key.startsWith(path)) { final String subKey = key.substring(path.length()); // Only do immediate descendants if (subKey.indexOf('.') == -1) { toRemove.add(key); } } } // Remove them now that the enumeration is done with for (final String key : toRemove) { properties.remove(key); } } // If this node hasn't been removed, add back in any values if (!isRemoved) { for (final Map.Entry entry : root.entrySet()) { properties.setProperty(path + entry.getKey(), entry.getValue()); } } LOGGER.trace("save({})", file); try (final FileOutputStream fos = new FileOutputStream(file)) { properties.store(fos, "FilePreferences"); } } catch (final IOException e) { LOGGER.catching(e); throw new BackingStoreException(e); } } } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy