1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34 package info.magnolia.config.source.yaml;
35
36 import info.magnolia.config.source.yaml.MgnlYamlConstructor.YamlConfigurationDependencyAggregator;
37 import info.magnolia.config.source.yaml.dependency.YamlConfigurationDependency;
38 import info.magnolia.resourceloader.Resource;
39
40 import java.io.IOException;
41 import java.io.Reader;
42 import java.util.Collections;
43 import java.util.HashMap;
44 import java.util.Map;
45 import java.util.Set;
46
47 import javax.inject.Singleton;
48
49 import org.yaml.snakeyaml.Yaml;
50 import org.yaml.snakeyaml.constructor.Construct;
51 import org.yaml.snakeyaml.error.YAMLException;
52
53
54
55
56 @Singleton
57 public class YamlReader {
58
59 private final Map<String, Construct> customConstructs = new HashMap<>();
60 private final Map<String, Construct> customMultiConstructs = new HashMap<>();
61
62 public void registerCustomConstruct(String tag, Construct construct) {
63 this.customConstructs.put(tag, construct);
64 }
65
66 public void registerCustomMultiConstruct(String tagPrefix, Construct construct) {
67 this.customMultiConstructs.put(tagPrefix, construct);
68 }
69
70 public Object read(Resource res) throws IOException {
71 return readNoCast(res);
72 }
73
74 public YamlConversionResult readWithDependencies(final Resource resource) throws IOException {
75 final YamlConfigurationDependencyAggregator dependencyAggregator = new YamlConfigurationDependencyAggregator();
76 final Object result = doReadWithDependencies(resource, dependencyAggregator);
77
78 return new YamlConversionResult(result, dependencyAggregator.getDependencies());
79 }
80
81 protected Object doReadWithDependencies(final Resource res, YamlConfigurationDependencyAggregator dependencyAggregator) throws IOException {
82 final Yaml yaml = newSnakeYaml(res, dependencyAggregator);
83 try (final Reader reader = res.openReader()) {
84 return yaml.load(new WhiteSpaceNormalisingReader(reader));
85 } catch (YAMLException ye) {
86 throw new YamlReaderException(ye, res);
87 }
88 }
89
90 public Map<String, Object> readToMap(final Resource resource) throws IOException {
91
92 return (Map<String, Object>) read(resource);
93 }
94
95 protected Object readNoCast(final Resource res) throws IOException {
96 return doReadWithDependencies(res, new YamlConfigurationDependencyAggregator());
97 }
98
99 protected Yaml newSnakeYaml(Resource yamlResource, YamlConfigurationDependencyAggregator dependencyAggregator) {
100 final MgnlYamlConstructor constructor = new MgnlYamlConstructor(this, yamlResource, dependencyAggregator);
101 customConstructs.forEach(constructor::registerConstruct);
102 customMultiConstructs.forEach(constructor::registerMultiConstruct);
103
104 return new Yaml(constructor);
105 }
106
107
108
109
110
111
112 public static class YamlConversionResult {
113
114 public static YamlConversionResult empty() {
115 return new YamlConversionResult(new HashMap<>(), Collections.emptySet());
116 }
117
118 private final Object result;
119 private final Set<YamlConfigurationDependency> dependencies;
120
121 public YamlConversionResult(Object result, Set<YamlConfigurationDependency> dependencies) {
122 this.result = result;
123 this.dependencies = dependencies;
124 }
125
126 public Set<YamlConfigurationDependency> getDependencies() {
127 return dependencies;
128 }
129
130 public Object getResult() {
131 return result;
132 }
133 }
134
135 }