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.registry.DefinitionMetadataBuilder;
37 import info.magnolia.config.registry.Registry;
38 import info.magnolia.config.source.ConfigurationSource;
39 import info.magnolia.config.source.ConfigurationSourceType;
40 import info.magnolia.config.source.ConfigurationSourceTypes;
41 import info.magnolia.resourceloader.Resource;
42 import info.magnolia.resourceloader.ResourceOrigin;
43 import info.magnolia.resourceloader.ResourceVisitor;
44 import info.magnolia.resourceloader.util.Functions;
45 import info.magnolia.resourceloader.util.PredicatedResourceVisitor;
46 import info.magnolia.resourceloader.util.VoidFunction;
47
48 import java.io.IOException;
49 import java.util.regex.Matcher;
50 import java.util.regex.Pattern;
51
52 import org.slf4j.Logger;
53 import org.slf4j.LoggerFactory;
54
55
56
57
58
59
60 public abstract class AbstractFileResourceConfigurationSource<T> implements ConfigurationSource {
61
62 private static final Logger log = LoggerFactory.getLogger(AbstractFileResourceConfigurationSource.class);
63
64 private final ResourceOrigin origin;
65 private final Pattern pathPattern;
66 private final Registry<T> registry;
67 private final PathToMetadataInferrer pathToMetadataInferrer;
68
69
70
71
72 public AbstractFileResourceConfigurationSource(ResourceOrigin origin, Registry<T> registry, Pattern pathPattern) throws IOException {
73 this.origin = origin;
74 this.registry = registry;
75 this.pathPattern = pathPattern;
76 this.pathToMetadataInferrer = new RegexBasedPathToMetadataInferrer(this.pathPattern);
77 }
78
79 @Override
80 public ConfigurationSourceType type() {
81 return ConfigurationSourceTypes.file;
82 }
83
84 @Override
85 public void start() throws IOException {
86 log.info("Setting up {} to load {} definitions from resources", getClass().getSimpleName(), getRootType().getSimpleName());
87 final LoadAndRegisterFunction loadAndRegisterFunction = new LoadAndRegisterFunction();
88 final ResourceVisitor visitor = PredicatedResourceVisitor.onAllMatchingFiles(Functions.pathMatches(pathPattern), loadAndRegisterFunction);
89 origin.traverseWith(visitor);
90 origin.watchForChanges(visitor);
91 }
92
93
94 public abstract void loadAndRegister(Resource resource);
95
96 protected Registry<T> getRegistry() {
97 return registry;
98 }
99
100 protected final Class<T> getRootType() {
101 return registry.type().baseClass();
102 }
103
104 protected DefinitionMetadataBuilder createMetadata(Resource resource) {
105 final DefinitionMetadataBuilder metadataBuilder = registry.newMetadataBuilder()
106 .type(getRegistry().type())
107
108 .location(resource.getPath());
109
110 return pathToMetadataInferrer.populateFrom(metadataBuilder, resource);
111 }
112
113 private class LoadAndRegisterFunction extends VoidFunction<Resource> {
114 @Override
115 public void doWith(Resource resource) {
116
117
118
119
120 if (resource.isDirectory()) {
121 log.debug("Ignoring event on directory {}", resource);
122 return;
123 }
124
125 final Matcher matcher = pathPattern.matcher(resource.getPath());
126 if (!matcher.matches()) {
127 log.debug("Ignoring event on {} (no match for {})", resource, pathPattern);
128 return;
129 }
130
131 log.debug("Loading {} ({})", resource, resource.getPath());
132 loadAndRegister(resource);
133 }
134 }
135 }