/*
* Autopsy Forensic Browser
*
* Copyright 2013-15 Basis Technology Corp.
* Contact: carrier <at> sleuthkit <dot> org
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.sleuthkit.autopsy.imagegallery;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
import java.util.logging.Level;
import org.sleuthkit.autopsy.casemodule.Case;
import org.sleuthkit.autopsy.coreutils.Logger;
/**
* Provides access to per-case module properties/settings.
*/
class PerCaseProperties {
public static final String ENABLED = "enabled"; //NON-NLS
public static final String STALE = "stale"; //NON-NLS
private final Case theCase;
PerCaseProperties(Case c) {
this.theCase = c;
}
/**
* Makes a new config file of the specified name. Do not include the
* extension.
*
* @param moduleName - The name of the config file to make
*
* @return True if successfully created, false if already exists or an error
* is thrown.
*/
public synchronized boolean makeConfigFile(String moduleName) {
if (!configExists(moduleName)) {
Path propPath = getPropertyPath(moduleName);
Path parent = propPath.getParent();
Properties props = new Properties();
try {
if (!Files.exists(parent)) {
Files.createDirectories(parent);
}
Files.createFile(propPath);
try (OutputStream fos = Files.newOutputStream(propPath)) {
props.store(fos, "");
}
} catch (IOException e) {
Logger.getLogger(PerCaseProperties.class.getName()).log(Level.WARNING, "Was not able to create a new properties file.", e); //NON-NLS
return false;
}
return true;
}
return false;
}
/**
* Determines if a given properties file exists or not.
*
* @param moduleName - The name of the config file to evaluate
*
* @return true if the config exists, false otherwise.
*/
public synchronized boolean configExists(String moduleName) {
Path get = Paths.get(theCase.getModuleDirectory(), moduleName, theCase.getName() + ".properties"); //NON-NLS
return Files.exists(get);
}
public synchronized boolean settingExists(String moduleName, String settingName) {
if (!configExists(moduleName)) {
return false;
}
try {
Properties props = fetchProperties(moduleName);
return (props.getProperty(settingName) != null);
} catch (IOException e) {
return false;
}
}
/**
* Returns the path of the given properties file.
*
* @param moduleName - The name of the config file to evaluate
*
* @return The path of the given config file. Returns null if the config
* file doesn't exist.
*/
private synchronized Path getPropertyPath(String moduleName) {
return Paths.get(theCase.getModuleDirectory(), moduleName, theCase.getName() + ".properties"); //NON-NLS
}
/**
* Returns the given properties file's setting as specific by settingName.
*
* @param moduleName - The name of the config file to read from.
* @param settingName - The setting name to retrieve.
*
* @return - the value associated with the setting.
*
* @throws IOException
*/
public synchronized String getConfigSetting(String moduleName, String settingName) {
if (!configExists(moduleName)) {
makeConfigFile(moduleName);
Logger.getLogger(PerCaseProperties.class.getName()).log(Level.INFO, "File did not exist. Created file [" + moduleName + ".properties]"); //NON-NLS NON-NLS
}
try {
Properties props = fetchProperties(moduleName);
return props.getProperty(settingName);
} catch (IOException e) {
Logger.getLogger(PerCaseProperties.class.getName()).log(Level.WARNING, "Could not read config file [" + moduleName + "]", e); //NON-NLS
return null;
}
}
/**
* Returns the given properties file's map of settings.
*
* @param moduleName - the name of the config file to read from.
*
* @return - the map of all key:value pairs representing the settings of the
* config.
*
* @throws IOException
*/
public synchronized Map< String, String> getConfigSettings(String moduleName) {
if (!configExists(moduleName)) {
makeConfigFile(moduleName);
Logger.getLogger(PerCaseProperties.class.getName()).log(Level.INFO, "File did not exist. Created file [" + moduleName + ".properties]"); //NON-NLS NON-NLS
}
try {
Properties props = fetchProperties(moduleName);
Set<String> keys = props.stringPropertyNames();
Map<String, String> map = new HashMap<>();
for (String s : keys) {
map.put(s, props.getProperty(s));
}
return map;
} catch (IOException e) {
Logger.getLogger(PerCaseProperties.class.getName()).log(Level.WARNING, "Could not read config file [" + moduleName + "]", e); //NON-NLS
return null;
}
}
/**
* Sets the given properties file to the given setting map.
*
* @param moduleName - The name of the module to be written to.
* @param settings - The mapping of all key:value pairs of settings to add
* to the config.
*/
public synchronized void setConfigSettings(String moduleName, Map<String, String> settings) {
if (!configExists(moduleName)) {
makeConfigFile(moduleName);
Logger.getLogger(PerCaseProperties.class.getName()).log(Level.INFO, "File did not exist. Created file [" + moduleName + ".properties]"); //NON-NLS NON-NLS
}
try {
Properties props = fetchProperties(moduleName);
for (Map.Entry<String, String> kvp : settings.entrySet()) {
props.setProperty(kvp.getKey(), kvp.getValue());
}
try (OutputStream fos = Files.newOutputStream(getPropertyPath(moduleName))) {
props.store(fos, "Changed config settings(batch)"); //NON-NLS
}
} catch (IOException e) {
Logger.getLogger(PerCaseProperties.class.getName()).log(Level.WARNING, "Property file exists for [" + moduleName + "] at [" + getPropertyPath(moduleName) + "] but could not be loaded.", e); //NON-NLS NON-NLS NON-NLS
}
}
/**
* Sets the given properties file to the given settings.
*
* @param moduleName - The name of the module to be written to.
* @param settingName - The name of the setting to be modified.
* @param settingVal - the value to set the setting to.
*/
public synchronized void setConfigSetting(String moduleName, String settingName, String settingVal) {
if (!configExists(moduleName)) {
makeConfigFile(moduleName);
Logger.getLogger(PerCaseProperties.class.getName()).log(Level.INFO, "File did not exist. Created file [" + moduleName + ".properties]"); //NON-NLS NON-NLS
}
try {
Properties props = fetchProperties(moduleName);
props.setProperty(settingName, settingVal);
try (OutputStream fos = Files.newOutputStream(getPropertyPath(moduleName))) {
props.store(fos, "Changed config settings(single)"); //NON-NLS
}
} catch (IOException e) {
Logger.getLogger(PerCaseProperties.class.getName()).log(Level.WARNING, "Property file exists for [" + moduleName + "] at [" + getPropertyPath(moduleName) + "] but could not be loaded.", e); //NON-NLS NON-NLS NON-NLS
}
}
/**
* Removes the given key from the given properties file.
*
* @param moduleName - The name of the properties file to be modified.
* @param key - the name of the key to remove.
*/
public synchronized void removeProperty(String moduleName, String key) {
if (!configExists(moduleName)) {
makeConfigFile(moduleName);
Logger.getLogger(PerCaseProperties.class.getName()).log(Level.INFO, "File did not exist. Created file [" + moduleName + ".properties]"); //NON-NLS NON-NLS
}
try {
if (getConfigSetting(moduleName, key) != null) {
Properties props = fetchProperties(moduleName);
props.remove(key);
try (OutputStream fos = Files.newOutputStream(getPropertyPath(moduleName))) {
props.store(fos, "Removed " + key); //NON-NLS
}
}
} catch (IOException e) {
Logger.getLogger(PerCaseProperties.class.getName()).log(Level.WARNING, "Could not remove property from file, file not found", e); //NON-NLS
}
}
/**
* Returns the properties file as specified by moduleName.
*
* @param moduleName
*
* @return Properties file as specified by moduleName.
*
* @throws IOException
*/
private Properties fetchProperties(String moduleName) throws IOException {
if (!configExists(moduleName)) {
makeConfigFile(moduleName);
Logger.getLogger(PerCaseProperties.class.getName()).log(Level.INFO, "File did not exist. Created file [" + moduleName + ".properties]"); //NON-NLS NON-NLS
}
Properties props;
try (InputStream inputStream = Files.newInputStream(getPropertyPath(moduleName))) {
props = new Properties();
props.load(inputStream);
}
return props;
}
}