Unverified Commit 81f7c46e authored by Romain Reuillon's avatar Romain Reuillon
Browse files

[Core] fix: base configuration on apache commons config.

parent 6a76519a
......@@ -287,8 +287,9 @@ object OSGi extends Defaults {
version := asmVersion)
lazy val config = OsgiProject("com.typesafe.config") settings (
libraryDependencies += "com.typesafe" % "config" % "1.3.0",
version := "1.3.0")
lazy val config = OsgiProject("org.apache.commons.configuration2", privatePackages = Seq("!scala.*", "*")) settings (
libraryDependencies += "org.apache.commons" % "commons-configuration2" % "2.0",
libraryDependencies += "commons-beanutils" % "commons-beanutils" % "1.9.2",
version := "2.0")
}
......@@ -19,8 +19,11 @@ package org.openmole.core.workspace
import java.io.File
import org.openmole.core.exception.{ UserBadDataError, InternalProcessingError }
import org.openmole.core.exception.{ InternalProcessingError, UserBadDataError }
import org.openmole.tool.file._
import org.apache.commons.configuration2._
import org.apache.commons.configuration2.builder._
import org.apache.commons.configuration2.builder.fluent._
import scala.concurrent.duration._
......@@ -40,121 +43,24 @@ class ConfigurationLocation[T](val group: String, val name: String, _default:
class ConfigurationFile(val file: File) {
var lastModificationTime: Long = _
var values: Map[String, Map[String, (Int, String)]] = _
var commentedValues: Map[String, Map[String, (Int, String)]] = _
val config = new Configurations().properties(file)
load()
val reloading = new ReloadingFileBasedConfigurationBuilder(classOf[PropertiesConfiguration])
.configure(new Parameters().fileBased().setFile(file))
def value(group: String, name: String): Option[String] = synchronized {
checkModified
val g = values.get(group)
val v = g.flatMap(_.get(name).map(_._2))
v
}
def commentedValue(group: String, name: String): Option[String] = synchronized {
checkModified
commentedValues.get(group).flatMap(_.get(name).map(_._2))
}
reloading.setAutoSave(true)
def setValue(group: String, name: String, value: String) = synchronized {
checkModified
values.get(group).flatMap(_.get(name)) match {
case Some((i, l)) replace(i, Value(group, name, value).toString)
case None file.append(s"\n${Value(group, name, value)}")
}
load()
}
def value(group: String, name: String): Option[String] =
Option(config.getString(s"$group.$name"))
def addCommentedValue(group: String, name: String, value: String) = synchronized {
checkModified
file.append(s"\n# ${Value(group, name, value)}")
load()
}
def setValue(group: String, name: String, value: String) =
config.setProperty(s"$group.$name", value)
def removeValue(group: String, name: String) = synchronized {
val lineNumbers = values(activeLines).map(_._1).toSet
val content =
for {
(l, i) file.lines.zipWithIndex
if !lineNumbers.contains(i)
} yield l
file.content = content.mkString("\n")
load()
}
def setCommentedValue(group: String, name: String, value: String) =
config.setProperty(s"# $group.$name", value)
def clear() = synchronized {
def clear() = {
file.content = ""
load()
}
private def replace(line: Int, content: String) = {
val lines = file.lines
val newLines = lines.take(line) ++ Seq(content) ++ lines.drop(line + 1)
file.content = newLines.mkString("\n")
}
private def checkModified =
if (file.lastModified() > lastModificationTime) load()
private def load() = {
lastModificationTime = file.lastModified()
values = readValues
commentedValues = readCommentedValues
}
private case class Value(group: String, name: String, value: String) {
override def toString = s"${group}.${name} = ${value}"
}
private def readValues: Map[String, Map[String, (Int, String)]] = linesToMap(activeLines)
private def readCommentedValues: Map[String, Map[String, (Int, String)]] = linesToMap(commentedLines)
private def commentedLines =
file.lines.zipWithIndex.map(_.swap).
filter { case (_, l) isCommentedLine(l) }.
map { case (i, l) i l.trim.drop(1) }
private def activeLines =
file.lines.zipWithIndex.map(_.swap).
filter { case (_, l) !isCommentedLine(l) }
private def parseValue(s: String) = {
def split(s: String) = {
val equalIndex = s.indexOf('=')
if (equalIndex == -1) None
else {
val kp = s.take(equalIndex)
val v = s.takeRight(s.length - equalIndex - 1)
val Array(g, k) = kp.split('.')
if (k.isEmpty) None
else Some(Value(g.trim, k.trim, v.trim))
}
}
split(s.trim)
}
private def isCommentedLine(s: String) =
s.trim.headOption.map(_ == '#').getOrElse(false)
private def linesToMap(lines: Seq[(Int, String)]) = toMap(values(lines))
private def values(lines: Seq[(Int, String)]) = lines.flatMap { case (i, l) parseValue(l).map(i _) }
private def toMap(vs: Seq[(Int, Value)]) = {
def content =
for {
(g, values) vs.groupBy(_._2.group).toSeq
} yield {
def content = for {
(n, inGroup) values.groupBy(_._2.name).toSeq
} yield n (inGroup.last._1 inGroup.last._2.value)
g content.toMap
}
content.toMap
}
}
......
......@@ -165,17 +165,13 @@ class Workspace(val location: File) {
}
def setDefault[T](location: ConfigurationLocation[T])(implicit configurationString: ConfigurationString[T]) = synchronized {
if (!preferenceIsSet(location) && !commentedPreferenceSet(location)) {
if (!preferenceIsSet(location)) {
def defaultOrException = location.default.getOrElse(throw new UserBadDataError(s"No default value set for location ${this}."))
def prop = if (location.cyphered) encrypt(configurationString.toString(defaultOrException)) else configurationString.toString(defaultOrException)
configurationFile.addCommentedValue(location.group, location.name, prop)
configurationFile.setCommentedValue(location.group, location.name, prop)
}
}
def removePreference[T](location: ConfigurationLocation[T]) = synchronized {
configurationFile.removeValue(location.group, location.name)
}
def file(name: String): File = new File(location, name)
def withTmpFile[T](prefix: String, postfix: String)(f: File T): T = {
......@@ -229,7 +225,6 @@ class Workspace(val location: File) {
}
}
def commentedPreferenceSet[T](configurationLocation: ConfigurationLocation[T]) = configurationFile.commentedValue(configurationLocation.group, configurationLocation.name).isDefined
def preferenceIsSet[T](configurationLocation: ConfigurationLocation[T]) = configurationFile.value(configurationLocation.group, configurationLocation.name).isDefined
def passwordChosen = configurationFile.value(passwordTest.group, passwordTest.name).isDefined
def passwordHasBeenSet = _password.map(passwordIsCorrect).getOrElse(false)
......
......@@ -181,6 +181,7 @@ object EGIAuthentication extends Logger {
def testDIRACAccess(a: EGIAuthentication, voName: String)(implicit decrypt: Decrypt) =
Try(DIRACEnvironment(voName).jobService.jobService.token).map(_ true)
def DIRACVos = fr.iscpif.gridscale.egi.DIRACJobService.supportedVOs()
}
sealed trait EGIAuthentication
......
......@@ -104,7 +104,8 @@ object Bin extends Defaults(Core, Plugin, REST, Gui, Libraries, ThirdParties, ro
Libraries.slf4j,
Libraries.scalaz,
Libraries.asm,
Libraries.collections
Libraries.collections,
Libraries.configuration
) ++ webServerDependencies
lazy val guiCoreDependencies = Seq(
......
......@@ -45,7 +45,7 @@ object Core extends Defaults {
libraryDependencies ++= Seq(slick, xstream))
val workspace = OsgiProject("workspace", imports = Seq("*")) settings
(libraryDependencies ++= Seq(jasypt, xstream, math)) dependsOn
(libraryDependencies ++= Seq(jasypt, xstream, math, Libraries.configuration)) dependsOn
(exception, event, tools, replication, openmoleCrypto)
val macros = OsgiProject("macros", imports = Seq("*")) settings (libraryDependencies += scalaLang % "provided" /*, provided(scalaCompiler)*/ )
......
......@@ -175,4 +175,6 @@ object Libraries extends Defaults {
lazy val asm = "org.openmole" %% "org-objectweb-asm" % "5.1"
lazy val configuration = "org.openmole" %% "org-apache-commons-configuration2" % "2.0"
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment