1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package de.smartics.properties.spi.core.context;
17
18 import static de.smartics.properties.api.core.domain.ConfigMessageBean.systemId;
19
20 import java.io.BufferedInputStream;
21 import java.io.IOException;
22 import java.io.InputStream;
23 import java.net.URL;
24 import java.util.List;
25 import java.util.Locale;
26
27 import org.apache.commons.io.IOUtils;
28 import org.apache.commons.lang.StringUtils;
29 import org.jdom.Document;
30 import org.jdom.Element;
31 import org.jdom.JDOMException;
32 import org.jdom.Namespace;
33 import org.jdom.input.SAXBuilder;
34
35 import de.smartics.properties.api.core.domain.ConfigCode;
36 import de.smartics.properties.api.core.domain.ConfigException;
37 import de.smartics.properties.api.core.domain.PropertiesContext;
38 import de.smartics.properties.api.core.domain.PropertiesContext.Builder;
39 import de.smartics.properties.spi.core.util.ClassLoaderUtils;
40 import de.smartics.util.lang.classpath.ClassPathContext;
41
42
43
44
45 public final class DeclarationConfigParser
46 {
47
48
49
50
51
52
53
54 private static final Namespace NS = Namespace
55 .getNamespace("http://smartics.de/properties/declaration/1");
56
57
58
59
60
61
62
63 private final LocaleFinder localeFinder = new LocaleFinder();
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82 public DeclarationConfigParser()
83 {
84 }
85
86
87
88
89
90
91
92
93
94
95
96
97
98 public PropertiesContext parse(final Class<?> type) throws ConfigException
99 {
100 final String archivePath = ClassLoaderUtils.calcArchivePath(type);
101 final ClassPathContext context =
102 new ClassPathContext(type.getClassLoader(), archivePath);
103 return parse(context);
104 }
105
106
107
108
109
110
111
112
113
114 public PropertiesContext parse(final ClassPathContext context)
115 throws ConfigException
116 {
117 final URL url = context.getResource(PropertiesContext.DECLARATION_FILE);
118 if (url != null)
119 {
120 final String systemId = url.toExternalForm();
121 final List<Locale> locales = localeFinder.find(systemId, context);
122
123 InputStream in = null;
124 try
125 {
126 try
127 {
128 in = new BufferedInputStream(url.openStream());
129 }
130 catch (final IOException e)
131 {
132 throw new ConfigException(systemId(
133 ConfigCode.CONFIG_FILE_CANNOT_BE_READ, e,
134 PropertiesContext.DECLARATION_FILE));
135 }
136 return parse(systemId, locales, in);
137 }
138 finally
139 {
140 IOUtils.closeQuietly(in);
141 }
142 }
143 throw new ConfigException(systemId(ConfigCode.CONFIG_FILE_NOT_FOUND,
144 PropertiesContext.DECLARATION_FILE));
145 }
146
147 private PropertiesContext parse(final String systemId,
148 final List<Locale> locales, final InputStream input)
149 throws ConfigException
150 {
151 try
152 {
153 final SAXBuilder parser = new SAXBuilder();
154 final Document document = parser.build(input, systemId);
155
156 final PropertiesContext.Builder builder = new PropertiesContext.Builder();
157 builder.withLocales(locales);
158
159 final Element rootNode = document.getRootElement();
160 final String homePageUrl = rootNode.getChildText("homepage-url", NS);
161 final String propertiesReportUrl =
162 rootNode.getChildText("properties-report-url", NS);
163 if (StringUtils.isNotBlank(propertiesReportUrl))
164 {
165 builder.withHomePageUrl(homePageUrl).withPropertiesReportUrl(
166 propertiesReportUrl);
167 }
168
169 handleAliases(rootNode, builder);
170
171 return builder.build();
172 }
173 catch (final JDOMException e)
174 {
175 throw new ConfigException(systemId(ConfigCode.CONFIG_FILE_CANNOT_BE_READ,
176 e, systemId));
177 }
178 catch (final IOException e)
179 {
180 throw new ConfigException(systemId(ConfigCode.CONFIG_FILE_CANNOT_BE_READ,
181 e, systemId));
182 }
183 }
184
185 @SuppressWarnings("unchecked")
186 private void handleAliases(final Element rootNode, final Builder builder)
187 {
188 final Element aliases = rootNode.getChild("aliases", NS);
189 if (aliases != null)
190 {
191 final List<Element> aliasElements = aliases.getChildren("alias", NS);
192 for (final Element aliasElement : aliasElements)
193 {
194 final String alias = aliasElement.getTextNormalize();
195 final String physical = aliasElement.getAttributeValue("for", NS);
196 builder.withAlias(alias, physical);
197 }
198 }
199 }
200 }