Commit a7fec2fe722ac668f4c1a06633423eb46e3c3e84

Authored by Emerson Oliveira
1 parent 8ff80912
Exists in master

Início da refatoração do ConfigurationLoader

impl/core/src/main/java/br/gov/frameworkdemoiselle/internal/configuration/ConfigurationLoader.java
@@ -37,37 +37,26 @@ @@ -37,37 +37,26 @@
37 */ 37 */
38 package br.gov.frameworkdemoiselle.internal.configuration; 38 package br.gov.frameworkdemoiselle.internal.configuration;
39 39
  40 +import static br.gov.frameworkdemoiselle.configuration.ConfigType.SYSTEM;
  41 +
40 import java.io.FileNotFoundException; 42 import java.io.FileNotFoundException;
41 import java.io.Serializable; 43 import java.io.Serializable;
42 import java.lang.reflect.Field; 44 import java.lang.reflect.Field;
  45 +import java.lang.reflect.InvocationTargetException;
43 import java.lang.reflect.Method; 46 import java.lang.reflect.Method;
44 -import java.lang.reflect.ParameterizedType;  
45 -import java.lang.reflect.Type;  
46 -import java.net.URL;  
47 -import java.util.HashMap;  
48 -import java.util.Iterator;  
49 -import java.util.Map;  
50 -import java.util.Properties;  
51 -import java.util.regex.Matcher;  
52 -import java.util.regex.Pattern;  
53 -  
54 -import javax.validation.constraints.NotNull;  
55 -  
56 -import org.apache.commons.configuration.DataConfiguration; 47 +
  48 +import org.apache.commons.configuration.AbstractConfiguration;
  49 +import org.apache.commons.configuration.FileConfiguration;
57 import org.apache.commons.configuration.PropertiesConfiguration; 50 import org.apache.commons.configuration.PropertiesConfiguration;
58 import org.apache.commons.configuration.SystemConfiguration; 51 import org.apache.commons.configuration.SystemConfiguration;
59 import org.apache.commons.configuration.XMLConfiguration; 52 import org.apache.commons.configuration.XMLConfiguration;
60 -import org.slf4j.Logger;  
61 53
62 import br.gov.frameworkdemoiselle.annotation.Ignore; 54 import br.gov.frameworkdemoiselle.annotation.Ignore;
63 import br.gov.frameworkdemoiselle.annotation.Name; 55 import br.gov.frameworkdemoiselle.annotation.Name;
64 import br.gov.frameworkdemoiselle.configuration.ConfigType; 56 import br.gov.frameworkdemoiselle.configuration.ConfigType;
65 import br.gov.frameworkdemoiselle.configuration.Configuration; 57 import br.gov.frameworkdemoiselle.configuration.Configuration;
66 import br.gov.frameworkdemoiselle.configuration.ConfigurationException; 58 import br.gov.frameworkdemoiselle.configuration.ConfigurationException;
67 -import br.gov.frameworkdemoiselle.internal.producer.LoggerProducer;  
68 -import br.gov.frameworkdemoiselle.internal.producer.ResourceBundleProducer;  
69 import br.gov.frameworkdemoiselle.util.Reflections; 59 import br.gov.frameworkdemoiselle.util.Reflections;
70 -import br.gov.frameworkdemoiselle.util.ResourceBundle;  
71 import br.gov.frameworkdemoiselle.util.Strings; 60 import br.gov.frameworkdemoiselle.util.Strings;
72 61
73 /** 62 /**
@@ -80,391 +69,122 @@ public class ConfigurationLoader implements Serializable { @@ -80,391 +69,122 @@ public class ConfigurationLoader implements Serializable {
80 69
81 private static final long serialVersionUID = 1L; 70 private static final long serialVersionUID = 1L;
82 71
83 - private ResourceBundle bundle; 72 + private ConfigType type;
84 73
85 - private Logger logger;  
86 -  
87 - /**  
88 - * Loads a config class filling it with the corresponding values.  
89 - *  
90 - * @param object  
91 - * config object  
92 - * @throws ConfigurationException  
93 - */  
94 - public void load(Object object) throws ConfigurationException {  
95 - Class<?> config = object.getClass(); 74 + private String resource;
96 75
97 - getLogger().debug(getBundle().getString("loading-configuration-class", config.getName())); 76 + private String prefix;
98 77
99 - for (Field field : Reflections.getNonStaticFields(config)) {  
100 - loadField(field, object, config);  
101 - }  
102 - } 78 + private org.apache.commons.configuration.Configuration configuration;
103 79
104 - private void loadField(Field field, Object object, Class<?> clazz) {  
105 - if (!field.isAnnotationPresent(Ignore.class) && clazz.isAnnotationPresent(Configuration.class)) {  
106 - String resource = clazz.getAnnotation(Configuration.class).resource();  
107 - ConfigType type = clazz.getAnnotation(Configuration.class).type();  
108 - org.apache.commons.configuration.Configuration config = getConfiguration(resource, type);  
109 -  
110 - if (config != null) {  
111 - Key key = new Key(field, clazz, config);  
112 - Object value = getValue(key, field, config);  
113 - validate(field, key, value, resource);  
114 - setValue(field, key, object, value);  
115 - }  
116 - }  
117 - }  
118 -  
119 - private void setValue(Field field, Key key, Object object, Object value) {  
120 - if (value != null) {  
121 - Reflections.setFieldValue(field, object, value);  
122 - getLogger().debug(  
123 - getBundle().getString("configuration-field-loaded", key.toString(), field.getName(), value));  
124 - } 80 + public void load(Object object) throws ConfigurationException {
  81 + loadType(object);
  82 + loadResource(object);
  83 + loadPrefix(object);
  84 + loadConfiguration();
  85 + loadFields(object);
125 } 86 }
126 87
127 - private void validate(Field field, Key key, Object value, String resource) {  
128 - if (field.isAnnotationPresent(NotNull.class) && value == null) {  
129 - throw new ConfigurationException(getBundle().getString("configuration-attribute-is-mandatory",  
130 - key.toString(), resource));  
131 - } 88 + private void loadType(Object object) {
  89 + this.type = object.getClass().getAnnotation(Configuration.class).type();
132 } 90 }
133 91
134 - /**  
135 - * Returns the configuration class according to specified resource name and configuration type.  
136 - *  
137 - * @param resource  
138 - * @param type  
139 - * @return a configuration  
140 - */  
141 - private org.apache.commons.configuration.Configuration getConfiguration(String resource, ConfigType type) {  
142 - org.apache.commons.configuration.Configuration result = null;  
143 - 92 + private void loadConfiguration() {
144 try { 93 try {
145 - URL url; 94 + AbstractConfiguration conf;
146 95
147 - switch (type) { 96 + switch (this.type) {
148 case SYSTEM: 97 case SYSTEM:
149 - result = new SystemConfiguration();  
150 - break;  
151 -  
152 - case PROPERTIES:  
153 - url = getResourceAsURL(resource + ".properties");  
154 -  
155 - if (url != null) {  
156 - result = new DataConfiguration(new PropertiesConfiguration(url));  
157 - } else {  
158 - getLogger().warn(getBundle().getString("resource-not-found", resource + ".properties"));  
159 - }  
160 - 98 + conf = new SystemConfiguration();
161 break; 99 break;
162 100
163 case XML: 101 case XML:
164 - url = getResourceAsURL(resource + ".xml");  
165 -  
166 - if (url != null) {  
167 - result = new DataConfiguration(new XMLConfiguration(url));  
168 - } else {  
169 - getLogger().warn(getBundle().getString("resource-not-found", resource + ".xml"));  
170 - }  
171 - 102 + conf = new XMLConfiguration();
172 break; 103 break;
173 104
174 default: 105 default:
175 - throw new ConfigurationException(getBundle().getString("configuration-type-not-implemented-yet",  
176 - type.name())); 106 + conf = new PropertiesConfiguration();
  107 + break;
177 } 108 }
178 109
179 - } catch (Exception cause) {  
180 - throw new ConfigurationException(getBundle().getString("error-creating-configuration-from-resource",  
181 - resource), cause);  
182 - }  
183 -  
184 - return result;  
185 - }  
186 -  
187 - @SuppressWarnings("unchecked")  
188 - private <T> T getValue(Key key, Field field, org.apache.commons.configuration.Configuration config) {  
189 - Object value;  
190 -  
191 - Class<?> fieldClass = (Class<?>) field.getType();  
192 -  
193 - if (fieldClass.isArray()) {  
194 - value = getArray(key, field, config);  
195 -  
196 - } else if (fieldClass.equals(Map.class)) {  
197 - value = getMap(key, field, config); 110 + conf.setDelimiterParsingDisabled(true);
198 111
199 - } else if (fieldClass.equals(Properties.class)) {  
200 - value = getProperty(key, config);  
201 -  
202 - } else if (fieldClass.equals(Class.class)) {  
203 - value = getClass(key, field, config);  
204 -  
205 - } else {  
206 - value = getBasic(key, field, config);  
207 - }  
208 -  
209 - return (T) value;  
210 - }  
211 -  
212 - @SuppressWarnings("unchecked")  
213 - private <T> Object getMap(Key key, Field field, org.apache.commons.configuration.Configuration config) {  
214 - Map<String, Object> value = null;  
215 -  
216 - String regexp = "^(" + key.getPrefix() + ")((.+)\\.)?(" + key.getName() + ")$";  
217 - Pattern pattern = Pattern.compile(regexp);  
218 - Matcher matcher;  
219 -  
220 - String iterKey;  
221 - String mapKey;  
222 - String confKey;  
223 -  
224 - for (Iterator<String> iter = config.getKeys(); iter.hasNext();) {  
225 - iterKey = iter.next();  
226 - matcher = pattern.matcher(iterKey);  
227 -  
228 - if (matcher.matches()) {  
229 - confKey = matcher.group(1) + (matcher.group(2) == null ? "" : matcher.group(2)) + matcher.group(4);  
230 -  
231 - if (value == null) {  
232 - value = new HashMap<String, Object>();  
233 - }  
234 -  
235 - mapKey = matcher.group(3) == null ? "default" : matcher.group(3);  
236 - value.put(mapKey, config.getProperty(confKey)); 112 + if (conf instanceof FileConfiguration) {
  113 + ((FileConfiguration) conf).setURL(Reflections.getResourceAsURL(this.resource));
  114 + ((FileConfiguration) conf).load();
237 } 115 }
238 - }  
239 -  
240 - return value;  
241 - }  
242 116
243 - private <T> Object getArray(Key key, Field field, org.apache.commons.configuration.Configuration config) {  
244 - Object value = null; 117 + this.configuration = conf;
245 118
246 - Class<?> fieldClass = (Class<?>) field.getType();  
247 -  
248 - try {  
249 - Method method;  
250 - String methodName = "get";  
251 -  
252 - methodName += Strings.firstToUpper(fieldClass.getSimpleName());  
253 - methodName = Strings.removeChars(methodName, '[', ']');  
254 -  
255 - methodName += "Array";  
256 -  
257 - method = config.getClass().getMethod(methodName, String.class);  
258 - value = method.invoke(config, key.toString());  
259 -  
260 - } catch (Throwable cause) {  
261 - throw new ConfigurationException(getBundle().getString("error-converting-to-type", fieldClass.getName()),  
262 - cause); 119 + } catch (FileNotFoundException cause) {
  120 + cause.printStackTrace();
  121 + } catch (org.apache.commons.configuration.ConfigurationException e) {
  122 + e.printStackTrace();
263 } 123 }
264 -  
265 - return value;  
266 } 124 }
267 125
268 - private <T> Object getBasic(Key key, Field field, org.apache.commons.configuration.Configuration config) {  
269 - Object value = null;  
270 -  
271 - Class<?> fieldClass = (Class<?>) field.getType();  
272 -  
273 - try {  
274 - Method method;  
275 - String methodName = "get";  
276 -  
277 - methodName += discoveryGenericType(field);  
278 - methodName += Strings.firstToUpper(fieldClass.getSimpleName());  
279 -  
280 - if (!fieldClass.isPrimitive()) {  
281 - method = config.getClass().getMethod(methodName, String.class, fieldClass);  
282 - value = method.invoke(config, key.toString(), null);  
283 -  
284 - } else if (config.containsKey(key.toString())) {  
285 - method = config.getClass().getMethod(methodName, String.class);  
286 - value = method.invoke(config, key.toString());  
287 - } 126 + private void loadResource(Object object) {
  127 + if (this.type != SYSTEM) {
  128 + String name = object.getClass().getAnnotation(Configuration.class).resource();
  129 + String extension = this.type.toString().toLowerCase();
288 130
289 - } catch (Throwable cause) {  
290 - throw new ConfigurationException(getBundle().getString("error-converting-to-type", fieldClass.getName()),  
291 - cause); 131 + this.resource = name + "." + extension;
292 } 132 }
293 -  
294 - return value;  
295 } 133 }
296 134
297 - private <T> Object getClass(Key key, Field field, org.apache.commons.configuration.Configuration config) {  
298 - Object value = null;  
299 -  
300 - try {  
301 - String canonicalName = config.getString(key.toString());  
302 -  
303 - if (canonicalName != null) {  
304 - ClassLoader classLoader = getClassLoaderForClass(canonicalName);  
305 - value = Class.forName(canonicalName, true, classLoader);  
306 - }  
307 -  
308 - } catch (Exception cause) {  
309 - // TODO Lançar a mensagem correta  
310 - throw new ConfigurationException(null, cause);  
311 - }  
312 -  
313 - return value; 135 + private void loadPrefix(Object object) {
  136 + this.prefix = object.getClass().getAnnotation(Configuration.class).prefix();
314 } 137 }
315 138
316 - /**  
317 - * Discovery the Generic's type. for example: the generic's type of List<Integer> list is an Integer type  
318 - *  
319 - * @param field  
320 - * @return  
321 - */  
322 - private String discoveryGenericType(Field field) {  
323 -  
324 - Type genericFieldType = field.getGenericType();  
325 -  
326 - if (genericFieldType instanceof ParameterizedType) {  
327 - ParameterizedType type = (ParameterizedType) genericFieldType;  
328 - Type[] fieldArgumentTypes = type.getActualTypeArguments();  
329 - for (Type fieldArgumentType : fieldArgumentTypes) {  
330 - @SuppressWarnings("rawtypes")  
331 - Class fieldArgumentClass = (Class) fieldArgumentType;  
332 -  
333 - if ("String".equals(fieldArgumentClass.getSimpleName())) {  
334 - return "";  
335 - }  
336 -  
337 - return fieldArgumentClass.getSimpleName();  
338 - } 139 + private void loadFields(Object object) {
  140 + for (Field field : Reflections.getNonStaticFields(object.getClass())) {
  141 + loadField(field, object);
339 } 142 }
340 -  
341 - return "";  
342 } 143 }
343 144
344 - private Object getProperty(Key key, org.apache.commons.configuration.Configuration config) {  
345 - Object value = null;  
346 -  
347 - @SuppressWarnings("unchecked")  
348 - Iterator<String> iterator = config.getKeys(key.toString());  
349 - if (iterator.hasNext()) {  
350 - Properties props = new Properties();  
351 -  
352 - while (iterator.hasNext()) {  
353 - String fullKey = iterator.next();  
354 - String prefix = key.toString() + ".";  
355 - String unprefixedKey = fullKey.substring(prefix.length());  
356 - props.put(unprefixedKey, config.getString(fullKey));  
357 - }  
358 -  
359 - value = props; 145 + private void loadField(Field field, Object object) {
  146 + if (hasIgnore(field)) {
  147 + return;
360 } 148 }
361 149
362 - return value;  
363 - }  
364 -  
365 - public static ClassLoader getClassLoaderForClass(final String canonicalName) throws FileNotFoundException {  
366 - return getClassLoaderForResource(canonicalName.replaceAll("\\.", "/") + ".class");  
367 - }  
368 -  
369 - public static ClassLoader getClassLoaderForResource(final String resource) throws FileNotFoundException {  
370 - final String stripped = resource.startsWith("/") ? resource.substring(1) : resource;  
371 -  
372 - URL url = null;  
373 - ClassLoader result = Thread.currentThread().getContextClassLoader(); 150 + try {
  151 + String key = getKey(field);
  152 + Class<?> fieldType = field.getType();
  153 + String methodName = "get" + Strings.firstToUpper(fieldType.getSimpleName());
374 154
375 - if (result != null) {  
376 - url = result.getResource(stripped);  
377 - } 155 + Method method = configuration.getClass().getMethod(methodName, String.class, fieldType);
  156 + Object value = method.invoke(configuration, key, Reflections.getFieldValue(field, object));
  157 + // TODO Se não achar no arquivo de configuração vai dar a falsa sensação que o valor padrão foi carregado de
  158 + // lá. Corrigir isso!
378 159
379 - if (url == null) {  
380 - result = ConfigurationLoader.class.getClassLoader();  
381 - url = ConfigurationLoader.class.getClassLoader().getResource(stripped);  
382 - } 160 + Reflections.setFieldValue(field, object, value);
383 161
384 - if (url == null) {  
385 - result = null; 162 + } catch (SecurityException cause) {
  163 + cause.printStackTrace();
  164 + } catch (NoSuchMethodException cause) {
  165 + cause.printStackTrace();
  166 + } catch (IllegalArgumentException cause) {
  167 + cause.printStackTrace();
  168 + } catch (IllegalAccessException cause) {
  169 + cause.printStackTrace();
  170 + } catch (InvocationTargetException cause) {
  171 + cause.printStackTrace();
386 } 172 }
387 -  
388 - return result;  
389 - }  
390 -  
391 - public static URL getResourceAsURL(final String resource) throws FileNotFoundException {  
392 - ClassLoader classLoader = getClassLoaderForResource(resource);  
393 - return classLoader != null ? classLoader.getResource(resource) : null;  
394 } 173 }
395 174
396 - private ResourceBundle getBundle() {  
397 - if (bundle == null) {  
398 - bundle = ResourceBundleProducer.create("demoiselle-core-bundle");  
399 - }  
400 -  
401 - return bundle;  
402 - } 175 + private String getKey(Field field) {
  176 + String key = this.prefix;
403 177
404 - private Logger getLogger() {  
405 - if (logger == null) {  
406 - logger = LoggerProducer.create(ConfigurationLoader.class); 178 + if (field.isAnnotationPresent(Name.class)) {
  179 + key += field.getAnnotation(Name.class).value();
  180 + }else{
  181 + key += field.getName();
407 } 182 }
408 183
409 - return logger; 184 + return key;
410 } 185 }
411 186
412 - private final class Key {  
413 -  
414 - private String prefix;  
415 -  
416 - private String name;  
417 -  
418 - private String key;  
419 -  
420 - private Key(final Field field, final Class<?> type, final org.apache.commons.configuration.Configuration config) {  
421 -  
422 - this.prefix = type.getAnnotation(Configuration.class).prefix();  
423 - if (this.prefix == null) {  
424 - this.prefix = "";  
425 - }  
426 -  
427 - if (field.isAnnotationPresent(Name.class)) {  
428 - this.name = getNameByAnnotation(field);  
429 - } else {  
430 - this.name = getNameByField(field);  
431 - }  
432 -  
433 - this.key = this.prefix + this.name;  
434 -  
435 - if (!config.containsKey(this.key)) {  
436 - getLogger().debug(getBundle().getString("key-not-found", this.key));  
437 - }  
438 - }  
439 -  
440 - private String getNameByAnnotation(Field field) {  
441 - String result;  
442 -  
443 - Name nameAnnotation = field.getAnnotation(Name.class);  
444 - if (Strings.isEmpty(nameAnnotation.value())) {  
445 - throw new ConfigurationException(getBundle().getString("configuration-name-attribute-cant-be-empty"));  
446 - } else {  
447 - result = nameAnnotation.value();  
448 - }  
449 -  
450 - return result;  
451 - }  
452 -  
453 - private String getNameByField(Field field) {  
454 - return field.getName();  
455 - }  
456 -  
457 - public String getPrefix() {  
458 - return prefix;  
459 - }  
460 -  
461 - public String getName() {  
462 - return name;  
463 - }  
464 -  
465 - @Override  
466 - public String toString() {  
467 - return this.key;  
468 - } 187 + private boolean hasIgnore(Field field) {
  188 + return field.isAnnotationPresent(Ignore.class);
469 } 189 }
470 } 190 }
impl/core/src/test/java/br/gov/frameworkdemoiselle/configuration/field/basic/ConfigurationBasicFieldTest.java
@@ -113,7 +113,7 @@ public class ConfigurationBasicFieldTest extends AbstractConfigurationTest { @@ -113,7 +113,7 @@ public class ConfigurationBasicFieldTest extends AbstractConfigurationTest {
113 assertEquals(expected, xmlConfig.getStringWithSpace()); 113 assertEquals(expected, xmlConfig.getStringWithSpace());
114 } 114 }
115 115
116 - // @Test 116 + @Test
117 public void loadStringWithComma() { 117 public void loadStringWithComma() {
118 String expected = "demoiselle,framework"; 118 String expected = "demoiselle,framework";
119 119