1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package de.smartics.properties.impl.config.domain.key.envapp;
17
18 import static de.smartics.properties.api.core.domain.ConfigMessageBean.systemId;
19
20 import static de.smartics.properties.api.core.domain.ConfigMessageBean.duplicate;
21 import java.io.BufferedInputStream;
22 import java.io.InputStream;
23 import java.net.URL;
24 import java.util.ArrayList;
25 import java.util.HashSet;
26 import java.util.List;
27 import java.util.Set;
28
29 import org.apache.commons.io.IOUtils;
30 import org.apache.commons.lang.StringUtils;
31 import org.jdom.Element;
32 import org.jdom.Namespace;
33
34 import de.smartics.properties.api.config.domain.key.ApplicationId;
35 import de.smartics.properties.api.config.domain.key.ConfigurationKey;
36 import de.smartics.properties.api.config.domain.key.EnvironmentId;
37 import de.smartics.properties.api.core.domain.ConfigCode;
38 import de.smartics.properties.api.core.domain.ConfigException;
39 import de.smartics.properties.api.core.domain.DuplicateDefaultKeyException;
40 import de.smartics.properties.api.core.domain.PropertiesContext;
41 import de.smartics.properties.spi.config.definition.DefinitionConfigParser;
42 import de.smartics.properties.spi.config.definition.PropertiesDefinitionContext;
43 import de.smartics.properties.spi.config.domain.key.PathMatcher;
44 import de.smartics.properties.spi.config.domain.key.PropertiesResourceMatcher;
45 import de.smartics.properties.spi.config.domain.key.PropertyResourceMatchers;
46 import de.smartics.properties.spi.core.util.ClassLoaderUtils;
47 import de.smartics.util.lang.classpath.ClassPathContext;
48
49
50
51
52
53
54
55 public abstract class AbstractDefinitionConfigParser<T extends PropertiesDefinitionContext>
56 implements DefinitionConfigParser<T>
57 {
58
59
60
61
62
63
64
65
66
67 protected final Namespace namespace;
68
69
70
71
72
73
74
75
76
77
78 protected AbstractDefinitionConfigParser(final Namespace namespace)
79 {
80 this.namespace = namespace;
81 }
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103 @Override
104 public final T parse(final Class<?> type) throws ConfigException
105 {
106 final ClassLoader loader = type.getClassLoader();
107 final String path = ClassLoaderUtils.calcArchivePath(type);
108 return parse(new ClassPathContext(loader, path));
109 }
110
111
112
113
114
115
116
117
118
119 @Override
120 public final T parse(final ClassPathContext context) throws ConfigException
121 {
122 final URL url = context.getResource(PropertiesContext.DEFINITION_FILE);
123 if (url != null)
124 {
125 final String systemId = url.toExternalForm();
126 InputStream in = null;
127 try
128 {
129 in =
130 new BufferedInputStream(
131 context.getResourceAsStream(PropertiesContext.DEFINITION_FILE));
132 return parse(systemId, in);
133 }
134 finally
135 {
136 IOUtils.closeQuietly(in);
137 }
138 }
139 throw new ConfigException(systemId(ConfigCode.CONFIG_FILE_NOT_FOUND,
140 PropertiesContext.DEFINITION_FILE));
141 }
142
143
144
145
146
147
148
149
150
151 protected final Set<String> readSet(final Element rootNode,
152 final String setGi, final String elementGi)
153 {
154 return readSet(rootNode, setGi, elementGi, new HashSet<String>());
155 }
156
157
158
159
160
161
162
163
164
165
166
167 @SuppressWarnings("unchecked")
168 protected final Set<String> readSet(final Element rootNode,
169 final String setGi, final String elementGi, final Set<String> defaultSet)
170 {
171 final Element set = rootNode.getChild(setGi, namespace);
172 if (set != null)
173 {
174 final Set<String> collection = new HashSet<String>();
175 final List<Element> elements = set.getChildren(elementGi, namespace);
176 for (final Element element : elements)
177 {
178 final String text = element.getTextNormalize();
179 collection.add(text);
180 }
181
182 return collection;
183 }
184
185 return defaultSet;
186 }
187
188
189
190
191
192
193
194
195
196 @SuppressWarnings("unchecked")
197 protected final PropertyResourceMatchers readFiles(final String systemId,
198 final Element rootNode) throws ConfigException
199 {
200 final List<PropertiesResourceMatcher> matchers =
201 new ArrayList<PropertiesResourceMatcher>();
202 ConfigurationKey<?> anyKey = null;
203
204 final Element keySet = rootNode.getChild("key-set", namespace);
205 if (keySet != null)
206 {
207 final List<Element> elements = keySet.getChildren("key", namespace);
208 for (final Element element : elements)
209 {
210 final ConfigurationKey<?> key = readKey(element);
211 final Element files = element.getChild("files", namespace);
212 if (files != null)
213 {
214 final List<Element> fileElements =
215 files.getChildren("file", namespace);
216 final List<PathMatcher.Matcher> pathMatcher =
217 new ArrayList<PathMatcher.Matcher>(fileElements.size());
218 for (final Element file : fileElements)
219 {
220 final String text = file.getTextNormalize();
221 final PathMatcher.Matcher matcher = new PathMatcher.Matcher(text);
222 pathMatcher.add(matcher);
223 }
224 final PropertiesResourceMatcher matcher =
225 PathMatcher.forMatchers(key, pathMatcher);
226 matchers.add(matcher);
227 }
228 else
229 {
230 checkDuplication(systemId, anyKey, key);
231 anyKey = key;
232 }
233 }
234 }
235
236 return new PropertyResourceMatchers(anyKey, matchers);
237 }
238
239 private void checkDuplication(final String systemId,
240 final ConfigurationKey<?> anyKey, final ConfigurationKey<?> key)
241 {
242 if (anyKey != null)
243 {
244 throw new DuplicateDefaultKeyException(duplicate(systemId,
245 anyKey.toString(), key.toString()));
246 }
247 }
248
249
250
251
252
253
254
255
256 protected abstract ConfigurationKey<?> readKey(Element element);
257
258
259
260
261
262
263
264 protected final EnvironmentId readEnvironment(final Element rootNode)
265 {
266 final Element environment = rootNode.getChild("environment", namespace);
267
268 final EnvironmentId environmentId;
269 if (environment != null)
270 {
271 final String name =
272 norm(environment.getChildTextNormalize("name", namespace));
273 final String node =
274 norm(environment.getChildTextNormalize("node", namespace));
275
276 environmentId = new EnvironmentId(name, node);
277 }
278 else
279 {
280 environmentId = EnvironmentId.ANY_ENV;
281 }
282 return environmentId;
283 }
284
285
286
287
288
289
290
291 protected final ApplicationId readApplication(final Element rootNode)
292 {
293 final Element application = rootNode.getChild("application", namespace);
294
295 final ApplicationId applicationId;
296 if (application != null)
297 {
298 final String group =
299 norm(application.getChildTextNormalize("group", namespace));
300 final String artifact =
301 norm(application.getChildTextNormalize("artifact", namespace));
302 final String version =
303 norm(application.getChildTextNormalize("version", namespace));
304 applicationId = new ApplicationId(group, artifact, version);
305 }
306 else
307 {
308 applicationId = ApplicationId.ANY_APP;
309 }
310 return applicationId;
311 }
312
313
314
315
316
317
318
319 protected static final String norm(final String text)
320 {
321 if (StringUtils.isBlank(text))
322 {
323 return null;
324 }
325 return text;
326 }
327
328
329
330 }