diff --git a/src/main/java/com/sothr/imagetools/App.java b/src/main/java/com/sothr/imagetools/App.java index 703540e..239a4d6 100644 --- a/src/main/java/com/sothr/imagetools/App.java +++ b/src/main/java/com/sothr/imagetools/App.java @@ -38,6 +38,7 @@ public class App extends Application @Override public void init() throws Exception{ AppConfig.configLogging(); + AppConfig.loadProperties(); logger = LoggerFactory.getLogger(this.getClass()); logger.info("Initializing Image Tools"); List parameters = this.getParameters().getRaw(); @@ -75,6 +76,7 @@ public class App extends Application @Override public void stop() throws Exception { logger.info("Image-Tools is shutting down"); + AppConfig.saveProperties(); super.stop(); } } diff --git a/src/main/java/com/sothr/imagetools/AppConfig.java b/src/main/java/com/sothr/imagetools/AppConfig.java index 5611ead..4315508 100644 --- a/src/main/java/com/sothr/imagetools/AppConfig.java +++ b/src/main/java/com/sothr/imagetools/AppConfig.java @@ -1,5 +1,6 @@ package com.sothr.imagetools; +import com.sothr.imagetools.util.PropertiesService; import org.apache.log4j.PropertyConfigurator; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -11,15 +12,22 @@ class AppConfig { private static Logger logger; + //Logging defaults private static final String LOGSETTINGSFILE = "./log4j.properties"; + private static Boolean configuredLogging = false; - public static void configLogging() { + //Properties defaults + private static final String DEFAULTPROPERTIESFILE = "default.properties"; + private static final String USERPROPERTIESFILE = "./config.xml"; + private static Boolean loadedProperties = false; + + public static void configLogging(String location) { //Logging Config - File file = new File(LOGSETTINGSFILE); + File file = new File(location); Boolean fromFile = false; if (file.exists()) { fromFile = true; - PropertyConfigurator.configure(LOGSETTINGSFILE); + PropertyConfigurator.configure(location); } else { //Simple error logging configuration Properties defaultProps = new Properties(); @@ -38,4 +46,28 @@ class AppConfig { logger.info(String.format("Configured Logger %s", message)); } + //Only configure logging from the default file once + public static void configLogging() { + if (!configuredLogging) { + configLogging(LOGSETTINGSFILE); + configuredLogging = true; + } + } + + public static void loadProperties() { + if (!loadedProperties) { + File file = new File(USERPROPERTIESFILE); + if (file.exists()) { + PropertiesService.loadProperties(DEFAULTPROPERTIESFILE, USERPROPERTIESFILE); + } else { + PropertiesService.loadProperties(DEFAULTPROPERTIESFILE, null); + } + loadedProperties = true; + } + } + + public static void saveProperties() { + PropertiesService.saveXMLProperties(USERPROPERTIESFILE); + } + } diff --git a/src/main/resources/default.properties b/src/main/resources/default.properties index 5c8ae3c..c681289 100644 --- a/src/main/resources/default.properties +++ b/src/main/resources/default.properties @@ -6,16 +6,16 @@ version=${project.version} #images must be 90% similar image.differenceThreshold=0.90 #control generation of hashes for new images. -image.ahash=true -image.ahashWeight=0.70 -image.dhash=true -image.dhashWeight=0.85 +image.ahash.use=true +image.ahash.weight=0.70 +image.dhash.use=true +image.dhash.weight=0.85 #set to false if hashing images is taking too long -image.phash=true -image.phashWeight=1.0 +image.phash.use=true +image.phash.weight=1.0 #Default Thumbnail Settings #Directory where to store thumbnails -thumbnail.directory=/cache/thumbnails/ +thumbnail.directory=./cache/thumbnails/ #Size of the thumbnail to generate and store thumbnail.size=128 diff --git a/src/main/scala/com/sothr/imagetools/util/PropertiesService.scala b/src/main/scala/com/sothr/imagetools/util/PropertiesService.scala index 07ff0c0..149ea78 100644 --- a/src/main/scala/com/sothr/imagetools/util/PropertiesService.scala +++ b/src/main/scala/com/sothr/imagetools/util/PropertiesService.scala @@ -2,32 +2,69 @@ package com.sothr.imagetools.util import java.util.Properties import grizzled.slf4j.Logging +import java.io.{FileInputStream, FileOutputStream, OutputStream} +import scala.collection.JavaConversions._ /* * Service for loading and interacting with the properties file */ object PropertiesService extends Logging { - val properties:Properties = new Properties() + private val properties:Properties = new Properties() + private var version:Version = null + private val propertiesToClean:Array[String] = Array("version") /* * Load the properties file from the specified location */ - def loadProperties(location:String) = { - info(s"Attempting to load properties from: $location") - val inputStream = ResourceLoader.get.getResourceStream(location) - val splitLocation = location.split("""\.""") - if (splitLocation(splitLocation.length) equals "xml") { - properties.loadFromXML(inputStream) - } else if (splitLocation(splitLocation.length) equals "properties") { - properties.load(inputStream); + def loadProperties(defaultLocation:String, userLocation:String = null) = { + info(s"Attempting to load properties from: $defaultLocation") + val defaultInputStream = ResourceLoader.get.getResourceStream(defaultLocation) + properties.load(defaultInputStream) + if (userLocation != null) { + val userInputStream = new FileInputStream(userLocation) + val userProperties = new Properties(); + userProperties.loadFromXML(userInputStream) + + for (propertyName:String <- userProperties.stringPropertyNames()) { + properties.setProperty(propertyName, userProperties.getProperty(propertyName)); + } } else { - error("Unable to load the properties file because it is not in the .properties or .xml format") + info("No user properties file exists to load from") + } + version = new Version(properties.getProperty("version")); + info(s"Detected Version: $version") + } + + /** + * Gets a properties object that is cleaned of things that are expected to change. i.e. version + */ + private def getCleanProperties():Properties = { + val cleanProperties:Properties = properties.clone().asInstanceOf[Properties] + //Remove properties to be cleaned + for (key <- propertiesToClean) { + cleanProperties.remove(key) } + return cleanProperties + } + + def saveXMLProperties(location:String) = { + info(s"Saving user properties to $location") + val out:OutputStream = new FileOutputStream(location, false) + val cleanProperties = getCleanProperties + //insert special keys here + cleanProperties.setProperty("version.previous", version.toString()) + cleanProperties.storeToXML(out, "User Properties") + out.flush() + out.close() + } + + def get(key:String):String = { + return properties.getProperty(key) } - def saveProperties(location:String) = { - + def set(key:String, value:String) = { + properties.setProperty(key, value) } -} +} \ No newline at end of file diff --git a/src/main/scala/com/sothr/imagetools/util/Version.scala b/src/main/scala/com/sothr/imagetools/util/Version.scala new file mode 100644 index 0000000..ad7b4b5 --- /dev/null +++ b/src/main/scala/com/sothr/imagetools/util/Version.scala @@ -0,0 +1,17 @@ +package com.sothr.imagetools.util + +/** + * Created by drew on 1/6/14. + */ +class Version(val versionString:String) { + //parse version into parts + val (major,minor,revision,buildType) = { + val splitVersion = versionString.split("""\.""") + val splitType = splitVersion(splitVersion.length-1).split("""-""") + (splitVersion(0),splitVersion(1),splitType(0),splitType(1)) + } + + override def toString():String = { + return s"$major.$minor.$revision-$buildType" + } +}