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
77 return readWithDependencies(resource, dependencyAggregator);
78 }
79
80 public YamlConversionResult readWithDependencies(final Resource resource, YamlConfigurationDependencyAggregator dependencyAggregator) throws IOException {
81 final Object result = doReadWithDependencies(resource, dependencyAggregator);
82
83 return new YamlConversionResult(result, dependencyAggregator.getDependencies());
84 }
85
86 protected Object doReadWithDependencies(final Resource res, YamlConfigurationDependencyAggregator dependencyAggregator) throws IOException {
87 final Yaml yaml = newSnakeYaml(res, dependencyAggregator);
88 try (final Reader reader = res.openReader()) {
89 return yaml.load(new WhiteSpaceNormalisingReader(reader));
90 } catch (YAMLException ye) {
91 throw new YamlReaderException(ye, res);
92 }
93 }
94
95 public Map<String, Object> readToMap(final Resource resource) throws IOException {
96
97 return (Map<String, Object>) read(resource);
98 }
99
100 protected Object readNoCast(final Resource res) throws IOException {
101 return doReadWithDependencies(res, new YamlConfigurationDependencyAggregator());
102 }
103
104 protected Yaml newSnakeYaml(Resource yamlResource, YamlConfigurationDependencyAggregator dependencyAggregator) {
105 final MgnlYamlConstructornstructor.html#MgnlYamlConstructor">MgnlYamlConstructor constructor = new MgnlYamlConstructor(this, yamlResource, dependencyAggregator);
106 customConstructs.forEach(constructor::registerConstruct);
107 customMultiConstructs.forEach(constructor::registerMultiConstruct);
108
109 return new Yaml(constructor);
110 }
111
112
113
114
115
116
117 public static class YamlConversionResult {
118
119 public static YamlConversionResult empty() {
120 return new YamlConversionResult(new HashMap<>(), Collections.emptySet());
121 }
122
123 private final Object result;
124 private final Set<YamlConfigurationDependency> dependencies;
125
126 public YamlConversionResult(Object result, Set<YamlConfigurationDependency> dependencies) {
127 this.result = result;
128 this.dependencies = dependencies;
129 }
130
131 public Set<YamlConfigurationDependency> getDependencies() {
132 return dependencies;
133 }
134
135 public Object getResult() {
136 return result;
137 }
138 }
139
140 }