Commit 6a4fb17d1d1a8edeefd39482dd35fa70b7dfb809

Authored by Cleverson Sacramento
1 parent 3242ca5f
Exists in master

Melhorias na implementação do CofigurationLoader

impl/core/src/main/java/br/gov/frameworkdemoiselle/internal/bootstrap/AbstractStrategyBootstrap.java
1 1 package br.gov.frameworkdemoiselle.internal.bootstrap;
2 2  
3   -import java.util.ArrayList;
  3 +import java.util.Collection;
4 4 import java.util.Collections;
5   -import java.util.List;
  5 +import java.util.HashSet;
6 6  
7 7 import javax.enterprise.event.Observes;
8 8 import javax.enterprise.inject.spi.AnnotatedType;
... ... @@ -17,7 +17,7 @@ public abstract class AbstractStrategyBootstrap<I> implements Extension {
17 17  
18 18 private Class<? extends I> strategyClass;
19 19  
20   - private List<Class<? extends I>> cache;
  20 + private Collection<Class<? extends I>> cache;
21 21  
22 22 protected abstract Logger getLogger();
23 23  
... ... @@ -29,9 +29,9 @@ public abstract class AbstractStrategyBootstrap&lt;I&gt; implements Extension {
29 29 return this.strategyClass;
30 30 }
31 31  
32   - public List<Class<? extends I>> getCache() {
  32 + public Collection<Class<? extends I>> getCache() {
33 33 if (this.cache == null) {
34   - this.cache = Collections.synchronizedList(new ArrayList<Class<? extends I>>());
  34 + this.cache = Collections.synchronizedSet(new HashSet<Class<? extends I>>());
35 35 }
36 36  
37 37 return this.cache;
... ...
impl/core/src/main/java/br/gov/frameworkdemoiselle/internal/configuration/ConfigurationLoader.java
... ... @@ -43,9 +43,7 @@ import java.io.Serializable;
43 43 import java.lang.reflect.Field;
44 44 import java.util.Collection;
45 45 import java.util.HashSet;
46   -import java.util.Set;
47 46  
48   -import javax.inject.Inject;
49 47 import javax.validation.constraints.NotNull;
50 48  
51 49 import org.apache.commons.configuration.AbstractConfiguration;
... ... @@ -85,33 +83,32 @@ public class ConfigurationLoader implements Serializable {
85 83  
86 84 private org.apache.commons.configuration.Configuration configuration;
87 85  
88   - private Set<Field> fields;
89   -
90   - private Set<ConfigurationValueExtractor> extractors;
91   -
92   - @Inject
93   - private ConfigurationBootstrap bootstrap;
  86 + private Collection<Field> fields;
94 87  
95 88 public void load(Object object) throws ConfigurationException {
96 89 this.object = object;
97 90  
  91 + loadFields();
98 92 validateFields();
99 93  
100 94 loadType();
101 95 loadResource();
102 96 loadConfiguration();
103   - loadExtractors();
104 97  
105 98 if (this.configuration != null) {
106 99 loadPrefix();
107   - loadFields();
  100 + loadValues();
108 101 }
109 102  
110 103 validateValues();
111 104 }
112 105  
  106 + private void loadFields() {
  107 + this.fields = Reflections.getNonStaticFields(this.object.getClass());
  108 + }
  109 +
113 110 private void validateFields() {
114   - for (Field field : getFields()) {
  111 + for (Field field : this.fields) {
115 112 validateField(field);
116 113 }
117 114 }
... ... @@ -165,14 +162,6 @@ public class ConfigurationLoader implements Serializable {
165 162 this.configuration = conf;
166 163 }
167 164  
168   - private void loadExtractors() {
169   - this.extractors = new HashSet<ConfigurationValueExtractor>();
170   -
171   - for (Class<? extends ConfigurationValueExtractor> extractorClass : this.bootstrap.getCache()) {
172   - this.extractors.add(Beans.getReference(extractorClass));
173   - }
174   - }
175   -
176 165 private void loadPrefix() {
177 166 String prefix = this.object.getClass().getAnnotation(Configuration.class).prefix();
178 167  
... ... @@ -186,21 +175,13 @@ public class ConfigurationLoader implements Serializable {
186 175 this.prefix = prefix;
187 176 }
188 177  
189   - private void loadFields() {
190   - for (Field field : getFields()) {
191   - loadField(field);
192   - }
193   - }
194   -
195   - private Set<Field> getFields() {
196   - if (this.fields == null) {
197   - this.fields = new HashSet<Field>(Reflections.getNonStaticFields(this.object.getClass()));
  178 + private void loadValues() {
  179 + for (Field field : this.fields) {
  180 + loadValue(field);
198 181 }
199   -
200   - return this.fields;
201 182 }
202 183  
203   - private void loadField(Field field) {
  184 + private void loadValue(Field field) {
204 185 if (hasIgnore(field)) {
205 186 return;
206 187 }
... ... @@ -212,9 +193,17 @@ public class ConfigurationLoader implements Serializable {
212 193 }
213 194  
214 195 private Object getValue(Field field, Class<?> type, String key, Object defaultValue) {
  196 + ConfigurationValueExtractor extractor = getValueExtractor(field);
  197 + return extractor.getValue(this.prefix, key, field, this.configuration, defaultValue);
  198 + }
  199 +
  200 + private ConfigurationValueExtractor getValueExtractor(Field field) {
215 201 Collection<ConfigurationValueExtractor> candidates = new HashSet<ConfigurationValueExtractor>();
  202 + ConfigurationBootstrap bootstrap = Beans.getReference(ConfigurationBootstrap.class);
  203 +
  204 + for (Class<? extends ConfigurationValueExtractor> extractorClass : bootstrap.getCache()) {
  205 + ConfigurationValueExtractor extractor = Beans.getReference(extractorClass);
216 206  
217   - for (ConfigurationValueExtractor extractor : this.extractors) {
218 207 if (extractor.isSupported(field)) {
219 208 candidates.add(extractor);
220 209 }
... ... @@ -228,7 +217,7 @@ public class ConfigurationLoader implements Serializable {
228 217 // um extrator personalizado.
229 218 }
230 219  
231   - return elected.getValue(this.prefix, key, field, configuration, defaultValue);
  220 + return elected;
232 221 }
233 222  
234 223 private String getKey(Field field) {
... ... @@ -248,7 +237,7 @@ public class ConfigurationLoader implements Serializable {
248 237 }
249 238  
250 239 private void validateValues() {
251   - for (Field field : getFields()) {
  240 + for (Field field : this.fields) {
252 241 validateValue(field);
253 242 }
254 243 }
... ...
impl/core/src/main/java/br/gov/frameworkdemoiselle/internal/configuration/ConfigurationLoaderBackup.java
... ... @@ -1,470 +0,0 @@
1   -/*
2   -/*
3   - * Demoiselle Framework
4   - * Copyright (C) 2010 SERPRO
5   - * ----------------------------------------------------------------------------
6   - * This file is part of Demoiselle Framework.
7   - *
8   - * Demoiselle Framework is free software; you can redistribute it and/or
9   - * modify it under the terms of the GNU Lesser General Public License version 3
10   - * as published by the Free Software Foundation.
11   - *
12   - * This program is distributed in the hope that it will be useful,
13   - * but WITHOUT ANY WARRANTY; without even the implied warranty of
14   - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15   - * GNU General Public License for more details.
16   - *
17   - * You should have received a copy of the GNU Lesser General Public License version 3
18   - * along with this program; if not, see <http://www.gnu.org/licenses/>
19   - * or write to the Free Software Foundation, Inc., 51 Franklin Street,
20   - * Fifth Floor, Boston, MA 02110-1301, USA.
21   - * ----------------------------------------------------------------------------
22   - * Este arquivo é parte do Framework Demoiselle.
23   - *
24   - * O Framework Demoiselle é um software livre; você pode redistribuí-lo e/ou
25   - * modificá-lo dentro dos termos da GNU LGPL versão 3 como publicada pela Fundação
26   - * do Software Livre (FSF).
27   - *
28   - * Este programa é distribuído na esperança que possa ser útil, mas SEM NENHUMA
29   - * GARANTIA; sem uma garantia implícita de ADEQUAÇÃO a qualquer MERCADO ou
30   - * APLICAÇÃO EM PARTICULAR. Veja a Licença Pública Geral GNU/LGPL em português
31   - * para maiores detalhes.
32   - *
33   - * Você deve ter recebido uma cópia da GNU LGPL versão 3, sob o título
34   - * "LICENCA.txt", junto com esse programa. Se não, acesse <http://www.gnu.org/licenses/>
35   - * ou escreva para a Fundação do Software Livre (FSF) Inc.,
36   - * 51 Franklin St, Fifth Floor, Boston, MA 02111-1301, USA.
37   - */
38   -package br.gov.frameworkdemoiselle.internal.configuration;
39   -
40   -import java.io.FileNotFoundException;
41   -import java.io.Serializable;
42   -import java.lang.reflect.Field;
43   -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;
57   -import org.apache.commons.configuration.PropertiesConfiguration;
58   -import org.apache.commons.configuration.SystemConfiguration;
59   -import org.apache.commons.configuration.XMLConfiguration;
60   -import org.slf4j.Logger;
61   -
62   -import br.gov.frameworkdemoiselle.annotation.Ignore;
63   -import br.gov.frameworkdemoiselle.annotation.Name;
64   -import br.gov.frameworkdemoiselle.configuration.ConfigType;
65   -import br.gov.frameworkdemoiselle.configuration.Configuration;
66   -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;
70   -import br.gov.frameworkdemoiselle.util.ResourceBundle;
71   -import br.gov.frameworkdemoiselle.util.Strings;
72   -
73   -/**
74   - * This component loads a config class annotated with {@link Configuration} by filling its attributes with {@link Param}
75   - * according to a {@link ConfigType}.
76   - *
77   - * @author SERPRO
78   - */
79   -public class ConfigurationLoaderBackup implements Serializable {
80   -
81   - private static final long serialVersionUID = 1L;
82   -
83   - private ResourceBundle bundle;
84   -
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();
96   -
97   - getLogger().debug(getBundle().getString("loading-configuration-class", config.getName()));
98   -
99   - for (Field field : Reflections.getNonStaticFields(config)) {
100   - loadField(field, object, config);
101   - }
102   - }
103   -
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   - }
125   - }
126   -
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   - }
132   - }
133   -
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   -
144   - try {
145   - URL url;
146   -
147   - switch (type) {
148   - 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   -
161   - break;
162   -
163   - 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   -
172   - break;
173   -
174   - default:
175   - throw new ConfigurationException(getBundle().getString("configuration-type-not-implemented-yet",
176   - type.name()));
177   - }
178   -
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);
198   -
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));
237   - }
238   - }
239   -
240   - return value;
241   - }
242   -
243   - private <T> Object getArray(Key key, Field field, org.apache.commons.configuration.Configuration config) {
244   - Object value = null;
245   -
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);
263   - }
264   -
265   - return value;
266   - }
267   -
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   - }
288   -
289   - } catch (Throwable cause) {
290   - throw new ConfigurationException(getBundle().getString("error-converting-to-type", fieldClass.getName()),
291   - cause);
292   - }
293   -
294   - return value;
295   - }
296   -
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;
314   - }
315   -
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   - }
339   - }
340   -
341   - return "";
342   - }
343   -
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;
360   - }
361   -
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();
374   -
375   - if (result != null) {
376   - url = result.getResource(stripped);
377   - }
378   -
379   - if (url == null) {
380   - result = ConfigurationLoader.class.getClassLoader();
381   - url = ConfigurationLoader.class.getClassLoader().getResource(stripped);
382   - }
383   -
384   - if (url == null) {
385   - result = null;
386   - }
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   - }
395   -
396   - private ResourceBundle getBundle() {
397   - if (bundle == null) {
398   - bundle = ResourceBundleProducer.create("demoiselle-core-bundle");
399   - }
400   -
401   - return bundle;
402   - }
403   -
404   - private Logger getLogger() {
405   - if (logger == null) {
406   - logger = LoggerProducer.create(ConfigurationLoader.class);
407   - }
408   -
409   - return logger;
410   - }
411   -
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   - }
469   - }
470   -}