Avec la bibliothèque Ficus , j'essaie de lire un fichier de configuration qui a l'aspect suivant:
Exception in thread "main" com.typesafe.config.ConfigException$WrongType: myfile.conf @ file:/[XXX]/myfile.conf: 5: security has type OBJECT rather than STRING
Lorsque j'essaie d'obtenir une Map [String, String] , avec:
import net.ceedubs.ficus.Ficus._
import net.ceedubs.ficus.Ficus.toFicusConfig
import net.ceedubs.ficus.readers.ArbitraryTypeReader._
...
myfileConfig.getConfig("macro").as[Map[String, String]](micro)
, J'obtiens l'erreur suivante:
//myfile.conf
macro: {
micro: {
a: "a"
security.something: "b"
}
}
Je n'ai pas trouvé de moyen de contourner cette erreur. Quelle serait une solution de contournement à cette erreur?
------- EDIT -------
Je ne sais pas ce que pourrait être la structure, ni les clés; mais je sais que ce ne sera jamais plus d'un objet de dimension, donc limité aux génériques.
L'idée derrière est donc d'obtenir la configuration quelle que soit la structure interprétée comme (String, String) .
3 Réponses :
Votre as [Map [String, String]] indique que toutes les valeurs sont censées être des chaînes et comme le message d'exception l'indique, la valeur de la clé security n'est pas string (votre configuration est équivalente à
macro: {
micro: {
a: "a"
security: {
something: "b"
}
}
}
). Vous ne voulez donc pas de Map [String, String] .
Mais ce que le correctif devrait être dépend de ce que vous savez sur la structure attendue sous micro : par exemple doit-il toujours y avoir un un et un security.something ? Ou pourrait-il y avoir des clés arbitraires? Etc. etc.
J'ai édité mon article avec un peu de contexte.Pour répondre directement à vos points: je ne connais pas la structure, et il n'y a pas non plus de clés arbitraires.
Votre structure est beaucoup plus complexe que Map [String, String] .
J'utiliserais pureconfig , ce qui rend assez simple la cartographie de la configuration directement dans classes de cas .
Votre exemple serait:
case class Micro(a: String, security: Security) case class Security(soemthing: String) import pureconfig.generic.auto._ pureconfig.loadConfig[Micro]
Merci. Je peux faire ça, oui. Mais cette solution ne concerne pas les clés non arbitraires, ce qui est mon principal problème.
les clés arbitraires ne sont pas le problème - vous avez des types de valeurs arbitraires - vérifiez pureconfig.github.io/ docs / configurable-converters.html
J'ai trouvé quelque chose de ma convenance:
val config = ConfigFactory.load("complex.conf")
val configurationMap = load(complex)
println(configurationMap)
//outputs: Map(b.bc.bca -> bca, a -> a, b.bb -> 4, b.ba -> 4, c -> c)
Avec:
// complex.conf
complex: {
a: "a"
b: {
ba: "4"
bb: 4
bc: {
bca: "bca"
}
}
c: "c"
}
, j'obtiens:
import scala.collection.JavaConversions._
implicit class ConfigurationBouiboui(myConfiguration: Config) {
def load[T](name: String): Map[String, T] = {
myConfiguration // configuration before target
.getConfig(name).entrySet() // configuration as path-value pairs
.map(x => (x.getKey, x.getValue.unwrapped().asInstanceOf[T])) // (dirty) cast value to T
.toMap
}
}