1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package de.smartics.properties.spi.config.transfer;
17
18 import java.io.BufferedInputStream;
19 import java.io.IOException;
20 import java.io.InputStream;
21 import java.net.MalformedURLException;
22 import java.net.URL;
23 import java.net.URLClassLoader;
24 import java.util.ArrayList;
25 import java.util.Collection;
26 import java.util.Collections;
27 import java.util.Iterator;
28 import java.util.List;
29 import java.util.Properties;
30 import java.util.Set;
31 import java.util.logging.Logger;
32
33 import org.apache.commons.io.IOUtils;
34
35 import de.smartics.exceptions.runtime.ExceptionContextManager;
36 import de.smartics.properties.api.config.domain.PropertyLocation;
37 import de.smartics.properties.api.config.domain.PropertyProvider;
38 import de.smartics.properties.api.config.domain.key.ConfigurationKey;
39 import de.smartics.properties.api.core.domain.PropertiesContext;
40 import de.smartics.properties.resource.domain.ArtifactRef;
41 import de.smartics.properties.resource.domain.ClassPathEnvironment;
42 import de.smartics.properties.spi.config.definition.DefinitionConfigParser;
43 import de.smartics.properties.spi.config.definition.PropertiesDefinitionContext;
44 import de.smartics.properties.spi.config.support.PropertiesHelper;
45 import de.smartics.properties.spi.config.support.PropertiesPropertyProvider;
46 import de.smartics.properties.spi.core.classpath.PropertiesFilesLoader;
47 import de.smartics.util.lang.Arg;
48
49
50
51
52
53 public final class PropertyProviderList implements Iterable<PropertyProvider>
54 {
55
56
57
58
59
60
61
62
63
64 private final Logger log = Logger.getLogger(ExceptionContextManager.class
65 .getName());
66
67
68
69
70 private final List<PropertyProvider> propertyProviders =
71 new ArrayList<PropertyProvider>(64);
72
73
74
75
76
77
78
79
80 public PropertyProviderList()
81 {
82 }
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100 public void addPropertyProvider(final PropertyProvider provider)
101 throws NullPointerException
102 {
103 Arg.checkNotNull("provider", provider);
104 propertyProviders.add(provider);
105 }
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122 public void addPropertyDefinitions(
123 final DefinitionConfigParser<?> definitionConfigParser,
124 final ClassPathEnvironment env) throws NullPointerException,
125 TransferException
126 {
127 Arg.checkNotNull("env", env);
128
129 final List<ArtifactRef> artifactRefs = env.getArtifactRefs();
130 if (artifactRefs.isEmpty())
131 {
132 return;
133 }
134
135 final PropertiesFilesLoader loader = new PropertiesFilesLoader();
136 for (final ArtifactRef artifactRef : artifactRefs)
137 {
138 final PropertiesDefinitionContext context =
139 readDefinition(definitionConfigParser, artifactRef);
140 if (context == null)
141 {
142 continue;
143 }
144
145 final URL rootUrl = artifactRef.getUrl();
146 final Collection<URL> rootUrls = Collections.singleton(rootUrl);
147 final Set<String> propertiesFiles = loader.getPropertiesFiles(rootUrls);
148
149 final ClassLoader classLoader =
150 new URLClassLoader(rootUrls.toArray(new URL[rootUrls.size()]), Thread
151 .currentThread().getContextClassLoader());
152 for (final String propertiesFile : propertiesFiles)
153 {
154 if (propertiesFile.contains("META-INF"))
155 {
156 continue;
157 }
158
159 final ConfigurationKey<?> key = getKey(context, propertiesFile);
160 final PropertiesHelper helper = new PropertiesHelper(key);
161
162
163
164
165 final Properties properties =
166 helper.readProperties(classLoader, propertiesFile);
167 final PropertyLocation sourceId = new PropertyLocation(propertiesFile);
168 final PropertyProvider provider =
169 new PropertiesPropertyProvider(key, sourceId, properties);
170 propertyProviders.add(provider);
171 }
172 }
173 }
174
175 private ConfigurationKey<?> getKey(final PropertiesDefinitionContext context,
176 final String propertiesFile) throws TransferException
177 {
178 final ConfigurationKey<?> key = context.getKey(propertiesFile);
179 if (key == null)
180 {
181 throw new TransferException(
182 new NoConfigurationKeyForPropertiesMessageBean(propertiesFile));
183 }
184 return key;
185 }
186
187 private PropertiesDefinitionContext readDefinition(
188 final DefinitionConfigParser<?> definitionConfigParser,
189 final ArtifactRef artifactRef) throws IllegalArgumentException
190 {
191 InputStream input = null;
192 try
193 {
194 final URL url = calcDefinitionXmlUrl(artifactRef);
195 final String systemId =
196 artifactRef.getId().toString() + ':' + url.toExternalForm();
197
198 input = new BufferedInputStream(url.openStream());
199 final PropertiesDefinitionContext context =
200 definitionConfigParser.parse(systemId, input);
201 return context;
202 }
203 catch (final MalformedURLException e)
204 {
205 final TransferMessageBean message =
206 DefinitionXmlMessageBean.malformedUrl(e, artifactRef);
207 log.fine(message.toString());
208 throw new TransferException(message);
209 }
210 catch (final IOException e)
211 {
212 final TransferMessageBean message =
213 DefinitionXmlMessageBean.missingDefinition(e, artifactRef);
214 log.fine(message.toString());
215 throw new TransferException(message);
216 }
217 finally
218 {
219 IOUtils.closeQuietly(input);
220 }
221 }
222
223 private static URL calcDefinitionXmlUrl(final ArtifactRef artifactRef)
224 throws MalformedURLException
225 {
226 final URL url;
227 if (artifactRef.getUrl().toExternalForm().endsWith(".jar"))
228 {
229 url = calcDefinitionXmlUrlFromJar(artifactRef);
230 }
231 else
232 {
233 url = calcDefinitionXmlUrlForDir(artifactRef);
234 }
235 return url;
236 }
237
238 private static URL calcDefinitionXmlUrlFromJar(final ArtifactRef artifactRef)
239 throws MalformedURLException
240 {
241 final String jarUrl = artifactRef.getUrl().toExternalForm();
242 final URL definitionXmlUrl =
243 new URL("jar:" + jarUrl + "!/" + PropertiesContext.DEFINITION_FILE);
244 return definitionXmlUrl;
245 }
246
247 private static URL calcDefinitionXmlUrlForDir(final ArtifactRef artifactRef)
248 throws MalformedURLException
249 {
250 final String jarUrl = artifactRef.getUrl().toExternalForm();
251 final URL definitionXmlUrl =
252 new URL(jarUrl + PropertiesContext.DEFINITION_FILE);
253 return definitionXmlUrl;
254 }
255
256 @Override
257 public Iterator<PropertyProvider> iterator()
258 {
259 return propertyProviders.iterator();
260 }
261
262
263
264 }