Thank you for the clues! I had to run the solution from @DmytroMitin through the debugger to grasp what was happening.
package dynamicProperties
import scala.language.dynamics
class DynamicProps(val props: java.util.Properties, val propName: String = "", val prop: Option[String] = None) extends Dynamic:
def updateDynamic(name: String)(value: String): AnyRef =
val newName = if propName.isEmpty then name else propName + "." + name
props.setProperty(newName, value)
def selectDynamic(name: String): DynamicProps =
val newName = if propName.isEmpty then name else propName + "." + name
val newProp = Option(props.getProperty(newName))
DynamicProps(props, newName, newProp)
def applyDynamicNamed(name: String)(args: (String, String)*): Any =
if name != "add" then throw IllegalArgumentException()
for (k, v) <- args do
props.setProperty(k, v)
override def toString: String = prop.getOrElse("n/a")
This is my test code.
import dynamicProperties.DynamicProps
import org.scalatest.funsuite.AnyFunSuite
class DynamicPropsTest extends AnyFunSuite:
test("Set username") {
val sysProps = DynamicProps(System.getProperties)
sysProps.username = "Fred"
assert(sysProps.username.toString() == "Fred")
sysProps.xxx.yyy = "bbb"
assert(sysProps.xxx.yyy.toString() == "bbb")
}
test("Assign java.home") {
val sysProps = DynamicProps(System.getProperties)
val home = sysProps.java.home.toString()
val javaHome: String = System.getProperty("java.home")
assert(home == javaHome)
}
test("Add key/value pairs") {
val sysProps = DynamicProps(System.getProperties)
sysProps.add(username="Fred", password="Secret")
assert(sysProps.username.toString() == "Fred")
assert(sysProps.password.toString() == "Secret")
}
For setting the properties with multiple periods, I noticed the code jumped to selectDynamic
before going to updateDynamic
.