Ni JSON ni YAML ne peuvent inclure des fichiers. Quoi que vous fassiez sera une étape de pré-traitement où vous mettrez le base.yaml
et votre fichier réel ensemble.
Une façon grossière de le faire serait:
#include base.yaml
appName: my-awesome-app
Que ce soit votre fichier. Au chargement, vous lisez d'abord la première ligne, et si elle commence par #include
, vous le remplacez par le contenu du fichier inclus. Vous devez le faire de manière récursive. C'est essentiellement ce que fait le préprocesseur C avec les fichiers C et inclut.
sont Désavantages:
- même si les deux fichiers sont valides YAML, le résultat ne peut pas.
- Si l'un des fichiers contient une fin de directive ou un marqueur de fin de document (
---
ou ...
), vous obtiendrez deux documents distincts dans un fichier.
- Vous ne pouvez pas remplacer les valeurs de
base.yaml
dans votre fichier.
Donc, une alternative serait d'opérer réellement sur la structure YAML. Pour cela, vous avez besoin de l'API de l'analyseur YAML (SnakeYAML dans votre cas) et analyser votre fichier avec cela. Vous devez utiliser l'API Compose:
private Node preprocess(final Reader myInput) {
final Yaml yaml = new Yaml();
final Node node = yaml.compose(myInput);
processIncludes(node);
return node;
}
private void processIncludes(final Node node) {
if (node instanceof MappingNode) {
final List<NodeTuple> values = ((MappingNode) node).getValue();
for (final NodeTuple tuple: values) {
if ("!include".equals(tuple.getKeyNode().getTag().getValue())) {
final String includedFilePath =
((ScalarNode) tuple.getValueNode()).getValue();
final Node content = preprocess(new FileReader(includedFilePath));
// now merge the content in your preferred way into the values list.
// that will change the content of the node.
}
}
}
}
public String executePreprocessor(final Reader source) {
final Node node = preprocess(source);
final StringWriter writer = new StringWriter();
final DumperOptions dOptions = new DumperOptions()
Serializer ser = new Serializer(new Emitter(writer, dOptions),
new Resolver(), dOptions, null);
ser.open();
ser.serialize(node);
ser.close();
return writer.toString();
}
Ce code parser comprend comme ceci:
!include : base.yaml
appName: my-awesome-app
J'utilisé la balise privée !include
de sorte qu'il n'y aura pas des conflits de noms avec une touche de cartographie normale. Attention à l'espace derrière !include
. Je n'ai pas donné de code pour fusionner le fichier inclus car je ne savais pas comment gérer les clés de mappage en double. Il ne devrait pas être difficile à mettre en œuvre cependant. Attention aux bugs, je n'ai pas testé ce code.
La chaîne résultante peut être l'entrée de Jackson.
[HOCON] (https://github.com/typesafehub/config#features-of-hocon) a la syntaxe 'include' –