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