Commit dc333641725bac9b6f72b250163a1a7b4b57eb1a
1 parent
05a7d42b
ResourceBundle inserido
Showing
10 changed files
with
1397 additions
and
0 deletions
Show diff stats
core/src/main/java/org/demoiselle/jee/core/annotation/Ignore.java
0 → 100644
@@ -0,0 +1,56 @@ | @@ -0,0 +1,56 @@ | ||
1 | +/* | ||
2 | + * Demoiselle Framework | ||
3 | + * Copyright (C) 2010 SERPRO | ||
4 | + * ---------------------------------------------------------------------------- | ||
5 | + * This file is part of Demoiselle Framework. | ||
6 | + * | ||
7 | + * Demoiselle Framework is free software; you can redistribute it and/or | ||
8 | + * modify it under the terms of the GNU Lesser General Public License version 3 | ||
9 | + * as published by the Free Software Foundation. | ||
10 | + * | ||
11 | + * This program is distributed in the hope that it will be useful, | ||
12 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | + * GNU General Public License for more details. | ||
15 | + * | ||
16 | + * You should have received a copy of the GNU Lesser General Public License version 3 | ||
17 | + * along with this program; if not, see <http://www.gnu.org/licenses/> | ||
18 | + * or write to the Free Software Foundation, Inc., 51 Franklin Street, | ||
19 | + * Fifth Floor, Boston, MA 02110-1301, USA. | ||
20 | + * ---------------------------------------------------------------------------- | ||
21 | + * Este arquivo é parte do Framework Demoiselle. | ||
22 | + * | ||
23 | + * O Framework Demoiselle é um software livre; você pode redistribuí-lo e/ou | ||
24 | + * modificá-lo dentro dos termos da GNU LGPL versão 3 como publicada pela Fundação | ||
25 | + * do Software Livre (FSF). | ||
26 | + * | ||
27 | + * Este programa é distribuído na esperança que possa ser útil, mas SEM NENHUMA | ||
28 | + * GARANTIA; sem uma garantia implícita de ADEQUAÇÃO a qualquer MERCADO ou | ||
29 | + * APLICAÇÃO EM PARTICULAR. Veja a Licença Pública Geral GNU/LGPL em português | ||
30 | + * para maiores detalhes. | ||
31 | + * | ||
32 | + * Você deve ter recebido uma cópia da GNU LGPL versão 3, sob o título | ||
33 | + * "LICENCA.txt", junto com esse programa. Se não, acesse <http://www.gnu.org/licenses/> | ||
34 | + * ou escreva para a Fundação do Software Livre (FSF) Inc., | ||
35 | + * 51 Franklin St, Fifth Floor, Boston, MA 02111-1301, USA. | ||
36 | + */ | ||
37 | +package org.demoiselle.jee.core.annotation; | ||
38 | + | ||
39 | +import static java.lang.annotation.ElementType.FIELD; | ||
40 | +import static java.lang.annotation.RetentionPolicy.RUNTIME; | ||
41 | + | ||
42 | +import java.lang.annotation.Retention; | ||
43 | +import java.lang.annotation.Target; | ||
44 | + | ||
45 | +/** | ||
46 | + * <p>Used in fields of classes annotated with {@link org.demoiselle.configuration.Configuration} | ||
47 | + * to indicate that the system should ignore this field when population the new configuration | ||
48 | + * instance with values extracted from the source file.</p> | ||
49 | + * | ||
50 | + * @see org.demoiselle.configuration.Configuration | ||
51 | + * @author SERPRO | ||
52 | + */ | ||
53 | +@Target(FIELD) | ||
54 | +@Retention(RUNTIME) | ||
55 | +public @interface Ignore { | ||
56 | +} |
core/src/main/java/org/demoiselle/jee/core/annotation/Name.java
0 → 100644
@@ -0,0 +1,98 @@ | @@ -0,0 +1,98 @@ | ||
1 | +/* | ||
2 | + * Demoiselle Framework | ||
3 | + * Copyright (C) 2010 SERPRO | ||
4 | + * ---------------------------------------------------------------------------- | ||
5 | + * This file is part of Demoiselle Framework. | ||
6 | + * | ||
7 | + * Demoiselle Framework is free software; you can redistribute it and/or | ||
8 | + * modify it under the terms of the GNU Lesser General Public License version 3 | ||
9 | + * as published by the Free Software Foundation. | ||
10 | + * | ||
11 | + * This program is distributed in the hope that it will be useful, | ||
12 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | + * GNU General Public License for more details. | ||
15 | + * | ||
16 | + * You should have received a copy of the GNU Lesser General Public License version 3 | ||
17 | + * along with this program; if not, see <http://www.gnu.org/licenses/> | ||
18 | + * or write to the Free Software Foundation, Inc., 51 Franklin Street, | ||
19 | + * Fifth Floor, Boston, MA 02110-1301, USA. | ||
20 | + * ---------------------------------------------------------------------------- | ||
21 | + * Este arquivo é parte do Framework Demoiselle. | ||
22 | + * | ||
23 | + * O Framework Demoiselle é um software livre; você pode redistribuí-lo e/ou | ||
24 | + * modificá-lo dentro dos termos da GNU LGPL versão 3 como publicada pela Fundação | ||
25 | + * do Software Livre (FSF). | ||
26 | + * | ||
27 | + * Este programa é distribuído na esperança que possa ser útil, mas SEM NENHUMA | ||
28 | + * GARANTIA; sem uma garantia implícita de ADEQUAÇÃO a qualquer MERCADO ou | ||
29 | + * APLICAÇÃO EM PARTICULAR. Veja a Licença Pública Geral GNU/LGPL em português | ||
30 | + * para maiores detalhes. | ||
31 | + * | ||
32 | + * Você deve ter recebido uma cópia da GNU LGPL versão 3, sob o título | ||
33 | + * "LICENCA.txt", junto com esse programa. Se não, acesse <http://www.gnu.org/licenses/> | ||
34 | + * ou escreva para a Fundação do Software Livre (FSF) Inc., | ||
35 | + * 51 Franklin St, Fifth Floor, Boston, MA 02111-1301, USA. | ||
36 | + */ | ||
37 | +package org.demoiselle.jee.core.annotation; | ||
38 | + | ||
39 | +import javax.enterprise.inject.spi.InjectionPoint; | ||
40 | +import javax.enterprise.util.Nonbinding; | ||
41 | +import javax.inject.Named; | ||
42 | +import javax.inject.Qualifier; | ||
43 | +import java.lang.annotation.Inherited; | ||
44 | +import java.lang.annotation.Retention; | ||
45 | +import java.lang.annotation.Target; | ||
46 | + | ||
47 | +import static java.lang.annotation.ElementType.*; | ||
48 | +import static java.lang.annotation.RetentionPolicy.RUNTIME; | ||
49 | + | ||
50 | +/** | ||
51 | + * <p> | ||
52 | + * String based non-binding qualifier. | ||
53 | + * </p> | ||
54 | + * | ||
55 | + * <p> | ||
56 | + * This annotation is used to qualify beans using an user defined String. {@link javax.enterprise.inject.Produces} | ||
57 | + * methods can then read this string and use it to customize the bean creation process. | ||
58 | + * </p> | ||
59 | + * | ||
60 | + * <p> | ||
61 | + * The {@link #value()} attribute is non-binding (contrary to {@link Named#value()}, meaning multiple classes | ||
62 | + * qualified with this annotation, even with different values, will be considered the same candidate for | ||
63 | + * injection points. To avoid ambiguous resolutions and select which candidate to choose usually you'll need a | ||
64 | + * producer method to read the string and select the best fitted candidate. | ||
65 | + * </p> | ||
66 | + * | ||
67 | + * <p> | ||
68 | + * The framework classes qualified with this annotation already have such producers and the accepted values for | ||
69 | + * this annotation will be detailed in their respective documentations. | ||
70 | + * </p> | ||
71 | + * | ||
72 | + * | ||
73 | + * @author SERPRO | ||
74 | + * | ||
75 | + * @see org.demoiselle.util.ResourceBundle | ||
76 | + * @see org.demoiselle.internal.producer.ResourceBundleProducer#create(InjectionPoint) | ||
77 | + * @see org.demoiselle.internal.producer.LoggerProducer#createNamed(InjectionPoint) | ||
78 | + */ | ||
79 | +@Qualifier | ||
80 | +@Inherited | ||
81 | +@Retention(RUNTIME) | ||
82 | +@Target({ TYPE, FIELD, METHOD, PARAMETER }) | ||
83 | +public @interface Name { | ||
84 | + | ||
85 | + /** | ||
86 | + * <p> | ||
87 | + * Specifies a name to access a custom configuration that will change how the annotated bean works. | ||
88 | + * </p> | ||
89 | + * <p> | ||
90 | + * This attribute is nonbinding so you can use the {@link Name} annotation to create {@linkplain javax.enterprise.inject.Produces} | ||
91 | + * methods or fields and have only one producer that works with all injection points no matter the value of this attribute. | ||
92 | + * </p> | ||
93 | + * @return Name of custom settings to personalize how the annotated bean works. | ||
94 | + */ | ||
95 | + @Nonbinding | ||
96 | + String value() default ""; | ||
97 | + | ||
98 | +} |
core/src/main/java/org/demoiselle/jee/core/annotation/Priority.java
0 → 100644
@@ -0,0 +1,96 @@ | @@ -0,0 +1,96 @@ | ||
1 | +/* | ||
2 | + * Demoiselle Framework | ||
3 | + * Copyright (C) 2010 SERPRO | ||
4 | + * ---------------------------------------------------------------------------- | ||
5 | + * This file is part of Demoiselle Framework. | ||
6 | + * | ||
7 | + * Demoiselle Framework is free software; you can redistribute it and/or | ||
8 | + * modify it under the terms of the GNU Lesser General Public License version 3 | ||
9 | + * as published by the Free Software Foundation. | ||
10 | + * | ||
11 | + * This program is distributed in the hope that it will be useful, | ||
12 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | + * GNU General Public License for more details. | ||
15 | + * | ||
16 | + * You should have received a copy of the GNU Lesser General Public License version 3 | ||
17 | + * along with this program; if not, see <http://www.gnu.org/licenses/> | ||
18 | + * or write to the Free Software Foundation, Inc., 51 Franklin Street, | ||
19 | + * Fifth Floor, Boston, MA 02110-1301, USA. | ||
20 | + * ---------------------------------------------------------------------------- | ||
21 | + * Este arquivo é parte do Framework Demoiselle. | ||
22 | + * | ||
23 | + * O Framework Demoiselle é um software livre; você pode redistribuí-lo e/ou | ||
24 | + * modificá-lo dentro dos termos da GNU LGPL versão 3 como publicada pela Fundação | ||
25 | + * do Software Livre (FSF). | ||
26 | + * | ||
27 | + * Este programa é distribuído na esperança que possa ser útil, mas SEM NENHUMA | ||
28 | + * GARANTIA; sem uma garantia implícita de ADEQUAÇÃO a qualquer MERCADO ou | ||
29 | + * APLICAÇÃO EM PARTICULAR. Veja a Licença Pública Geral GNU/LGPL em português | ||
30 | + * para maiores detalhes. | ||
31 | + * | ||
32 | + * Você deve ter recebido uma cópia da GNU LGPL versão 3, sob o título | ||
33 | + * "LICENCA.txt", junto com esse programa. Se não, acesse <http://www.gnu.org/licenses/> | ||
34 | + * ou escreva para a Fundação do Software Livre (FSF) Inc., | ||
35 | + * 51 Franklin St, Fifth Floor, Boston, MA 02111-1301, USA. | ||
36 | + */ | ||
37 | +package org.demoiselle.jee.core.annotation; | ||
38 | + | ||
39 | +import java.lang.annotation.Retention; | ||
40 | +import java.lang.annotation.Target; | ||
41 | + | ||
42 | +import static java.lang.annotation.ElementType.METHOD; | ||
43 | +import static java.lang.annotation.ElementType.TYPE; | ||
44 | +import static java.lang.annotation.RetentionPolicy.RUNTIME; | ||
45 | + | ||
46 | +/** | ||
47 | + * <p> | ||
48 | + * Used to prioritize some execution flow, as methods annotated with @startup or @shutdown, | ||
49 | + * or some interface implementation. | ||
50 | + * </p> | ||
51 | + * | ||
52 | + * @author SERPRO | ||
53 | + */ | ||
54 | +@Target({ TYPE, METHOD }) | ||
55 | +@Retention(RUNTIME) | ||
56 | +public @interface Priority { | ||
57 | + | ||
58 | + /** | ||
59 | + * Most important priority value. | ||
60 | + */ | ||
61 | + static int MAX_PRIORITY = Integer.MIN_VALUE; | ||
62 | + | ||
63 | + /** | ||
64 | + * Less important priority value. | ||
65 | + */ | ||
66 | + static int MIN_PRIORITY = Integer.MAX_VALUE; | ||
67 | + | ||
68 | + /** | ||
69 | + * Less important priority value. | ||
70 | + */ | ||
71 | + static int L1_PRIORITY = MIN_PRIORITY; | ||
72 | + | ||
73 | + /** | ||
74 | + * Higher priority than L1_PRIORITY | ||
75 | + */ | ||
76 | + static int L2_PRIORITY = L1_PRIORITY - 100; | ||
77 | + | ||
78 | + /** | ||
79 | + * Higher priority than L2_PRIORITY | ||
80 | + */ | ||
81 | + static int L3_PRIORITY = L2_PRIORITY - 100; | ||
82 | + | ||
83 | + /** | ||
84 | + * Higher priority than L3_PRIORITY | ||
85 | + */ | ||
86 | + static int L4_PRIORITY = L3_PRIORITY - 100; | ||
87 | + | ||
88 | + /** | ||
89 | + * <p> | ||
90 | + * An integer value defines the priority order. The lower the value, the greater priority. | ||
91 | + * <p> | ||
92 | + * | ||
93 | + * @return Priority value, lower values have higher priority. | ||
94 | + */ | ||
95 | + int value(); | ||
96 | +} |
core/src/main/java/org/demoiselle/jee/core/annotation/Strategy.java
0 → 100644
@@ -0,0 +1,83 @@ | @@ -0,0 +1,83 @@ | ||
1 | +/* | ||
2 | + * Demoiselle Framework | ||
3 | + * Copyright (C) 2010 SERPRO | ||
4 | + * ---------------------------------------------------------------------------- | ||
5 | + * This file is part of Demoiselle Framework. | ||
6 | + * | ||
7 | + * Demoiselle Framework is free software; you can redistribute it and/or | ||
8 | + * modify it under the terms of the GNU Lesser General Public License version 3 | ||
9 | + * as published by the Free Software Foundation. | ||
10 | + * | ||
11 | + * This program is distributed in the hope that it will be useful, | ||
12 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | + * GNU General Public License for more details. | ||
15 | + * | ||
16 | + * You should have received a copy of the GNU Lesser General Public License version 3 | ||
17 | + * along with this program; if not, see <http://www.gnu.org/licenses/> | ||
18 | + * or write to the Free Software Foundation, Inc., 51 Franklin Street, | ||
19 | + * Fifth Floor, Boston, MA 02110-1301, USA. | ||
20 | + * ---------------------------------------------------------------------------- | ||
21 | + * Este arquivo é parte do Framework Demoiselle. | ||
22 | + * | ||
23 | + * O Framework Demoiselle é um software livre; você pode redistribuí-lo e/ou | ||
24 | + * modificá-lo dentro dos termos da GNU LGPL versão 3 como publicada pela Fundação | ||
25 | + * do Software Livre (FSF). | ||
26 | + * | ||
27 | + * Este programa é distribuído na esperança que possa ser útil, mas SEM NENHUMA | ||
28 | + * GARANTIA; sem uma garantia implícita de ADEQUAÇÃO a qualquer MERCADO ou | ||
29 | + * APLICAÇÃO EM PARTICULAR. Veja a Licença Pública Geral GNU/LGPL em português | ||
30 | + * para maiores detalhes. | ||
31 | + * | ||
32 | + * Você deve ter recebido uma cópia da GNU LGPL versão 3, sob o título | ||
33 | + * "LICENCA.txt", junto com esse programa. Se não, acesse <http://www.gnu.org/licenses/> | ||
34 | + * ou escreva para a Fundação do Software Livre (FSF) Inc., | ||
35 | + * 51 Franklin St, Fifth Floor, Boston, MA 02111-1301, USA. | ||
36 | + */ | ||
37 | +package org.demoiselle.jee.core.annotation; | ||
38 | +import static java.lang.annotation.ElementType.FIELD; | ||
39 | +import static java.lang.annotation.ElementType.METHOD; | ||
40 | +import static java.lang.annotation.ElementType.PARAMETER; | ||
41 | +import static java.lang.annotation.ElementType.TYPE; | ||
42 | +import static java.lang.annotation.RetentionPolicy.RUNTIME; | ||
43 | + | ||
44 | +import java.lang.annotation.Inherited; | ||
45 | +import java.lang.annotation.Retention; | ||
46 | +import java.lang.annotation.Target; | ||
47 | + | ||
48 | +import javax.inject.Qualifier; | ||
49 | + | ||
50 | +/** | ||
51 | + * | ||
52 | + * <p> | ||
53 | + * This literal marks a bean to be selected at runtime based on a priority system. | ||
54 | + * The user qualifies the injection point with this literal and then at runtime | ||
55 | + * the CDI engine will circle through all candidate subtypes to be injected | ||
56 | + * that are annotated with {@link Priority}. If there is only one subtype with the | ||
57 | + * highest priority then this one will be selected to be injected. | ||
58 | + * </p> | ||
59 | + * | ||
60 | + * <p> | ||
61 | + * This allows users to plug in libraries with new candidates and have them be selected | ||
62 | + * if their priority values are higher than the default values already present. One example | ||
63 | + * is the {@link org.demoiselle.security.Authorizer} type, the framework has a {@link org.demoiselle.internal.implementation.DefaultAuthorizer} | ||
64 | + * with {@link Priority#L1_PRIORITY the lowest priority} but the user can add libraries with new | ||
65 | + * implementations of {@link org.demoiselle.security.Authorizer} annotated with higher priorities, the code will | ||
66 | + * then automatically select these new implementations with no extra configuration. | ||
67 | + * </p> | ||
68 | + * | ||
69 | + * <p> | ||
70 | + * This annotation must be used with supported types. Usually this involves creating {@link javax.enterprise.inject.Produces} CDI | ||
71 | + * producer methods that will select the correct strategy. To create your own producer | ||
72 | + * methods that support strategy selection, use the utility {@linkplain org.demoiselle.internal.producer.StrategySelector}. | ||
73 | + * </p> | ||
74 | + * | ||
75 | + * @author SERPRO | ||
76 | + */ | ||
77 | +@Qualifier | ||
78 | +@Inherited | ||
79 | +@Retention(RUNTIME) | ||
80 | +@Target({ TYPE, FIELD, METHOD, PARAMETER }) | ||
81 | +public @interface Strategy { | ||
82 | + | ||
83 | +} |
core/src/main/java/org/demoiselle/jee/core/internal/producer/ResourceBundleProducer.java
0 → 100644
@@ -0,0 +1,72 @@ | @@ -0,0 +1,72 @@ | ||
1 | +/* | ||
2 | + * To change this license header, choose License Headers in Project Properties. | ||
3 | + * To change this template file, choose Tools | Templates | ||
4 | + * and open the template in the editor. | ||
5 | + */ | ||
6 | +package org.demoiselle.jee.core.internal.producer; | ||
7 | + | ||
8 | +import java.io.Serializable; | ||
9 | +import java.util.Locale; | ||
10 | +import org.demoiselle.jee.core.util.ResourceBundle; | ||
11 | +import javax.enterprise.context.Dependent; | ||
12 | +import javax.enterprise.inject.Default; | ||
13 | +import javax.enterprise.inject.Produces; | ||
14 | +import javax.enterprise.inject.spi.CDI; | ||
15 | +import javax.enterprise.inject.spi.InjectionPoint; | ||
16 | +import org.demoiselle.jee.core.annotation.Name; | ||
17 | +import org.demoiselle.util.CDIUtils; | ||
18 | + | ||
19 | +/** | ||
20 | + * | ||
21 | + * @author 70744416353 | ||
22 | + */ | ||
23 | +@Dependent | ||
24 | +public class ResourceBundleProducer implements Serializable { | ||
25 | + | ||
26 | + private static final long serialVersionUID = 1L; | ||
27 | + | ||
28 | + @Default | ||
29 | + @Produces | ||
30 | + public ResourceBundle createDefault() { | ||
31 | + return create((String) null); | ||
32 | + } | ||
33 | + | ||
34 | + /* | ||
35 | + * Produces a {@link java.util.ResourceBundle} instance loading the properties file whose name | ||
36 | + * is defined by the {@link Name} literal. If no value is specified | ||
37 | + * then the default "messages.properties" file is loaded. | ||
38 | + */ | ||
39 | + @Name | ||
40 | + @Produces | ||
41 | + public ResourceBundle create(InjectionPoint ip) { | ||
42 | + String baseName = null; | ||
43 | + if (ip != null && ip.getQualifiers() != null) { | ||
44 | + Name nameQualifier = CDIUtils.getQualifier(Name.class, ip); | ||
45 | + if (nameQualifier != null) { | ||
46 | + baseName = nameQualifier.value(); | ||
47 | + if ("".equals(baseName)) { | ||
48 | + baseName = null; | ||
49 | + } | ||
50 | + } | ||
51 | + } | ||
52 | + | ||
53 | + return create(baseName); | ||
54 | + } | ||
55 | + | ||
56 | + public static ResourceBundle create(String baseName) { | ||
57 | + ResourceBundle bundle; | ||
58 | + | ||
59 | + try { | ||
60 | + bundle = baseName != null | ||
61 | + ? new ResourceBundle(baseName, CDI.current().select(Locale.class).get()) { | ||
62 | + } | ||
63 | + : new ResourceBundle("messages", CDI.current().select(Locale.class).get()); | ||
64 | + } catch (RuntimeException e) { | ||
65 | + bundle = baseName != null | ||
66 | + ? new ResourceBundle(baseName, Locale.getDefault()) | ||
67 | + : new ResourceBundle("messages", Locale.getDefault()); | ||
68 | + } | ||
69 | + | ||
70 | + return bundle; | ||
71 | + } | ||
72 | +} |
core/src/main/java/org/demoiselle/jee/core/util/CDIUtils.java
0 → 100644
@@ -0,0 +1,121 @@ | @@ -0,0 +1,121 @@ | ||
1 | +package org.demoiselle.util; | ||
2 | + | ||
3 | +import javax.enterprise.inject.spi.InjectionPoint; | ||
4 | +import java.lang.annotation.Annotation; | ||
5 | +import java.util.Arrays; | ||
6 | +import java.util.Collection; | ||
7 | + | ||
8 | +/** | ||
9 | + * Utility class to peform useful operations on CDI discovered beans. | ||
10 | + * | ||
11 | + * @author SERPRO | ||
12 | + */ | ||
13 | +public final class CDIUtils { | ||
14 | + | ||
15 | + private static final Annotation[] annotationArrayType = new Annotation[0]; | ||
16 | + | ||
17 | + /** | ||
18 | + * Returns <code>true</code> if one annotation of the provided type is present | ||
19 | + * on a list of annotations. | ||
20 | + * | ||
21 | + * @param annotationType Annotation type being looked for. | ||
22 | + * @param allAnnotations List of all annotations where to look for. | ||
23 | + * @return <code>true</code> if the annotation is present on the list | ||
24 | + */ | ||
25 | + @SuppressWarnings("WeakerAccess") | ||
26 | + public static boolean hasAnnotation(Class<? extends Annotation> annotationType, Annotation... allAnnotations) { | ||
27 | + for (Annotation currentAnnotation : allAnnotations) { | ||
28 | + if (currentAnnotation.annotationType().isAssignableFrom(annotationType)) { | ||
29 | + return true; | ||
30 | + } | ||
31 | + } | ||
32 | + | ||
33 | + return false; | ||
34 | + } | ||
35 | + | ||
36 | + /** | ||
37 | + * @param annotationType Type of the annotation being checked | ||
38 | + * @param allAnnotations List of annotations to check for the specific one | ||
39 | + * @see #hasAnnotation(Class, Annotation...) | ||
40 | + * @return <code>true</code> if the annotation is present on the list | ||
41 | + */ | ||
42 | + @SuppressWarnings("WeakerAccess") | ||
43 | + public static boolean hasAnnotation(Class<? extends Annotation> annotationType, | ||
44 | + Collection<Annotation> allAnnotations) { | ||
45 | + return hasAnnotation(annotationType, allAnnotations.toArray(annotationArrayType)); | ||
46 | + } | ||
47 | + | ||
48 | + /** | ||
49 | + * Returns <code>true</code> if a base class is annotated with the provided annotation. | ||
50 | + * | ||
51 | + * @param annotationType Annotation type to look for | ||
52 | + * @param baseType Class to check for the informed annotation | ||
53 | + * @see #hasAnnotation(Class, Annotation...) | ||
54 | + * @return <code>true</code> if the annotation is present on the list | ||
55 | + */ | ||
56 | + @SuppressWarnings("WeakerAccess") | ||
57 | + public static boolean hasAnnotation(Class<? extends Annotation> annotationType, Class<?> baseType) { | ||
58 | + return hasAnnotation(annotationType, baseType.getAnnotations()); | ||
59 | + } | ||
60 | + | ||
61 | + /** | ||
62 | + * Returns the annotation instance that matches the annotation type provided, | ||
63 | + * or <code>null</code> if no annotation of that type is present. | ||
64 | + * | ||
65 | + * @param annotationType Annotation type being looked for. | ||
66 | + * @param allAnnotations List of all annotations where to look for. | ||
67 | + * @param <T> Type of the specific annotation returned | ||
68 | + * @return The annotation instance found, or <code>null</code> if there is no such annotation present. | ||
69 | + */ | ||
70 | + @SuppressWarnings({ "WeakerAccess", "unchecked" }) | ||
71 | + public static <T extends Annotation> T getAnnotation(Class<T> annotationType, Annotation... allAnnotations) { | ||
72 | + for (Annotation currentAnnotation : allAnnotations) { | ||
73 | + if (currentAnnotation.annotationType().isAssignableFrom(annotationType)) { | ||
74 | + return (T) currentAnnotation; | ||
75 | + } | ||
76 | + } | ||
77 | + | ||
78 | + return null; | ||
79 | + } | ||
80 | + | ||
81 | + /** | ||
82 | + * @param annotationType Annotation type being looked for. | ||
83 | + * @param allAnnotations List of all annotations where to look for. | ||
84 | + * @param <T> Type of the specific annotation returned | ||
85 | + * @see #getAnnotation(Class, Annotation...) | ||
86 | + * @return The annotation instance found, or <code>null</code> if there is no such annotation present. | ||
87 | + */ | ||
88 | + @SuppressWarnings({ "WeakerAccess" }) | ||
89 | + public static <T extends Annotation> T getAnnotation(Class<T> annotationType, | ||
90 | + Collection<Annotation> allAnnotations) { | ||
91 | + return getAnnotation(annotationType, allAnnotations.toArray(annotationArrayType)); | ||
92 | + } | ||
93 | + | ||
94 | + /** | ||
95 | + * Returns <code>true</code> if one qualifier of the provided type is present | ||
96 | + * on an injection point. | ||
97 | + * | ||
98 | + * @param qualifierAnnotationType Annotation type being looked for. | ||
99 | + * @param ip Injection point of a bean type. | ||
100 | + * @return <code>true</code> if the annotation is present on the list | ||
101 | + */ | ||
102 | + @SuppressWarnings("WeakerAccess") | ||
103 | + public static boolean hasQualifier(Class<? extends Annotation> qualifierAnnotationType, InjectionPoint ip) { | ||
104 | + return hasAnnotation(qualifierAnnotationType, ip.getQualifiers()); | ||
105 | + } | ||
106 | + | ||
107 | + /** | ||
108 | + * Returns the annotation instance that matches the annotation type provided, | ||
109 | + * or <code>null</code> if no annotation of that type is present. | ||
110 | + * | ||
111 | + * @param qualifierAnnotationType Annotation type being looked for. | ||
112 | + * @param ip Injection point of a bean type. | ||
113 | + * @param <T> Type of the specific annotation returned | ||
114 | + * @return The annotation instance found, or <code>null</code> if there is no such annotation present. | ||
115 | + */ | ||
116 | + @SuppressWarnings("WeakerAccess") | ||
117 | + public static <T extends Annotation> T getQualifier(Class<T> qualifierAnnotationType, InjectionPoint ip) { | ||
118 | + return getAnnotation(qualifierAnnotationType, ip.getQualifiers()); | ||
119 | + } | ||
120 | + | ||
121 | +} |
core/src/main/java/org/demoiselle/jee/core/util/Exceptions.java
0 → 100644
@@ -0,0 +1,67 @@ | @@ -0,0 +1,67 @@ | ||
1 | +/* | ||
2 | + * Demoiselle Framework | ||
3 | + * Copyright (C) 2010 SERPRO | ||
4 | + * ---------------------------------------------------------------------------- | ||
5 | + * This file is part of Demoiselle Framework. | ||
6 | + * | ||
7 | + * Demoiselle Framework is free software; you can redistribute it and/or | ||
8 | + * modify it under the terms of the GNU Lesser General Public License version 3 | ||
9 | + * as published by the Free Software Foundation. | ||
10 | + * | ||
11 | + * This program is distributed in the hope that it will be useful, | ||
12 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | + * GNU General Public License for more details. | ||
15 | + * | ||
16 | + * You should have received a copy of the GNU Lesser General Public License version 3 | ||
17 | + * along with this program; if not, see <http://www.gnu.org/licenses/> | ||
18 | + * or write to the Free Software Foundation, Inc., 51 Franklin Street, | ||
19 | + * Fifth Floor, Boston, MA 02110-1301, USA. | ||
20 | + * ---------------------------------------------------------------------------- | ||
21 | + * Este arquivo é parte do Framework Demoiselle. | ||
22 | + * | ||
23 | + * O Framework Demoiselle é um software livre; você pode redistribuí-lo e/ou | ||
24 | + * modificá-lo dentro dos termos da GNU LGPL versão 3 como publicada pela Fundação | ||
25 | + * do Software Livre (FSF). | ||
26 | + * | ||
27 | + * Este programa é distribuído na esperança que possa ser útil, mas SEM NENHUMA | ||
28 | + * GARANTIA; sem uma garantia implícita de ADEQUAÇÃO a qualquer MERCADO ou | ||
29 | + * APLICAÇÃO EM PARTICULAR. Veja a Licença Pública Geral GNU/LGPL em português | ||
30 | + * para maiores detalhes. | ||
31 | + * | ||
32 | + * Você deve ter recebido uma cópia da GNU LGPL versão 3, sob o título | ||
33 | + * "LICENCA.txt", junto com esse programa. Se não, acesse <http://www.gnu.org/licenses/> | ||
34 | + * ou escreva para a Fundação do Software Livre (FSF) Inc., | ||
35 | + * 51 Franklin St, Fifth Floor, Boston, MA 02111-1301, USA. | ||
36 | + */ | ||
37 | +package org.demoiselle.util; | ||
38 | + | ||
39 | +/** | ||
40 | + *Class that offer tow methods that can help with manipulation of throwable exceptions. | ||
41 | + * | ||
42 | + * @author SERPRO | ||
43 | + */ | ||
44 | +public final class Exceptions { | ||
45 | + | ||
46 | + /** | ||
47 | + * Constructor without parameters. | ||
48 | + */ | ||
49 | + private Exceptions() { | ||
50 | + } | ||
51 | + | ||
52 | + /** | ||
53 | + * Receives as parameter any kind of Throwable objects, and throws a RuntimeException instead. | ||
54 | + * | ||
55 | + * @param throwable | ||
56 | + * a throwable object. | ||
57 | + * | ||
58 | + * @throws RuntimeException throws this kind of exception every time that is called. | ||
59 | + */ | ||
60 | + public static void handleToRuntimeException(final Throwable throwable) throws RuntimeException { | ||
61 | + if (throwable instanceof RuntimeException) { | ||
62 | + throw (RuntimeException) throwable; | ||
63 | + } else { | ||
64 | + throw new RuntimeException(throwable); | ||
65 | + } | ||
66 | + } | ||
67 | +} |
core/src/main/java/org/demoiselle/jee/core/util/Reflections.java
0 → 100644
@@ -0,0 +1,367 @@ | @@ -0,0 +1,367 @@ | ||
1 | +/* | ||
2 | + * Demoiselle Framework | ||
3 | + * Copyright (C) 2010 SERPRO | ||
4 | + * ---------------------------------------------------------------------------- | ||
5 | + * This file is part of Demoiselle Framework. | ||
6 | + * | ||
7 | + * Demoiselle Framework is free software; you can redistribute it and/or | ||
8 | + * modify it under the terms of the GNU Lesser General Public License version 3 | ||
9 | + * as published by the Free Software Foundation. | ||
10 | + * | ||
11 | + * This program is distributed in the hope that it will be useful, | ||
12 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | + * GNU General Public License for more details. | ||
15 | + * | ||
16 | + * You should have received a copy of the GNU Lesser General Public License version 3 | ||
17 | + * along with this program; if not, see <http://www.gnu.org/licenses/> | ||
18 | + * or write to the Free Software Foundation, Inc., 51 Franklin Street, | ||
19 | + * Fifth Floor, Boston, MA 02110-1301, USA. | ||
20 | + * ---------------------------------------------------------------------------- | ||
21 | + * Este arquivo é parte do Framework Demoiselle. | ||
22 | + * | ||
23 | + * O Framework Demoiselle é um software livre; você pode redistribuí-lo e/ou | ||
24 | + * modificá-lo dentro dos termos da GNU LGPL versão 3 como publicada pela Fundação | ||
25 | + * do Software Livre (FSF). | ||
26 | + * | ||
27 | + * Este programa é distribuído na esperança que possa ser útil, mas SEM NENHUMA | ||
28 | + * GARANTIA; sem uma garantia implícita de ADEQUAÇÃO a qualquer MERCADO ou | ||
29 | + * APLICAÇÃO EM PARTICULAR. Veja a Licença Pública Geral GNU/LGPL em português | ||
30 | + * para maiores detalhes. | ||
31 | + * | ||
32 | + * Você deve ter recebido uma cópia da GNU LGPL versão 3, sob o título | ||
33 | + * "LICENCA.txt", junto com esse programa. Se não, acesse <http://www.gnu.org/licenses/> | ||
34 | + * ou escreva para a Fundação do Software Livre (FSF) Inc., | ||
35 | + * 51 Franklin St, Fifth Floor, Boston, MA 02111-1301, USA. | ||
36 | + */ | ||
37 | +package org.demoiselle.util; | ||
38 | + | ||
39 | +import java.io.InputStream; | ||
40 | +import java.lang.reflect.*; | ||
41 | +import java.net.URL; | ||
42 | +import java.util.ArrayList; | ||
43 | +import java.util.Arrays; | ||
44 | +import java.util.List; | ||
45 | + | ||
46 | +/** | ||
47 | + * Provides some features to do some operations relating to java reflection. | ||
48 | + * | ||
49 | + * @author SERPRO | ||
50 | + */ | ||
51 | +public class Reflections { | ||
52 | + | ||
53 | + protected Reflections() { | ||
54 | + // Impede instanciar subclasses desse tipo. | ||
55 | + throw new UnsupportedOperationException(); | ||
56 | + } | ||
57 | + | ||
58 | + /** | ||
59 | + * Return the parametized type used with a concrete implementation of a class that accepts generics. Ex: If you | ||
60 | + * declare | ||
61 | + * <pre> | ||
62 | + * public class SpecializedCollection implements Collection<SpecializedType> { | ||
63 | + * // ... | ||
64 | + * } | ||
65 | + * </pre> | ||
66 | + * then the code <code>getGenericTypeArgument(SpecializedCollection.class , 0);</code> will return the type | ||
67 | + * <code>SpecializedType</code>. | ||
68 | + * | ||
69 | + * @param type Base type to check for generic arguments | ||
70 | + * @param idx zero based index of the generic argument to get | ||
71 | + * @param <T> Type of the generic argument | ||
72 | + * @return The class representing the type of the generic argument | ||
73 | + */ | ||
74 | + @SuppressWarnings("unchecked") | ||
75 | + public static <T> Class<T> getGenericTypeArgument(final Type type, final int idx) { | ||
76 | + ParameterizedType paramType; | ||
77 | + try { | ||
78 | + paramType = (ParameterizedType) type; | ||
79 | + } catch (ClassCastException cause) { | ||
80 | + return getGenericTypeArgument((Class<T>) type, idx); | ||
81 | + } | ||
82 | + | ||
83 | + return (Class<T>) paramType.getActualTypeArguments()[idx]; | ||
84 | + } | ||
85 | + | ||
86 | + /** | ||
87 | + * Return the parametized type used with a concrete implementation of a class that accepts generics. Ex: If you | ||
88 | + * declare | ||
89 | + * <pre> | ||
90 | + * <code> | ||
91 | + * public class SpecializedCollection implements Collection<SpecializedType> { | ||
92 | + * // ... | ||
93 | + * } | ||
94 | + * </code> | ||
95 | + * </pre> | ||
96 | + * then the code <code>getGenericTypeArgument(SpecializedCollection.class , 0);</code> will return the type | ||
97 | + * <code>SpecializedType</code>. | ||
98 | + * | ||
99 | + * @param clazz Base type to check for generic arguments | ||
100 | + * @param idx zero based index of the generic argument to get | ||
101 | + * @param <T> Type of the generic argument | ||
102 | + * @return The class representing the type of the generic argument | ||
103 | + */ | ||
104 | + @SuppressWarnings("unchecked") | ||
105 | + public static <T> Class<T> getGenericTypeArgument(final Class<?> clazz, final int idx) { | ||
106 | + final Type type = clazz.getGenericSuperclass(); | ||
107 | + | ||
108 | + ParameterizedType paramType; | ||
109 | + try { | ||
110 | + paramType = (ParameterizedType) type; | ||
111 | + } catch (ClassCastException cause) { | ||
112 | + return getGenericTypeArgument((Class<T>) type, idx); | ||
113 | + } | ||
114 | + | ||
115 | + return (Class<T>) paramType.getActualTypeArguments()[idx]; | ||
116 | + } | ||
117 | + | ||
118 | + /** | ||
119 | + * <p> | ||
120 | + * Return the parametized type passed to field types that accepts Generics. | ||
121 | + * </p> | ||
122 | + * Ex: If you declare | ||
123 | + * <pre> | ||
124 | + * <code> | ||
125 | + * public class MyClass{ | ||
126 | + * private Collection<String> myStringCollection; | ||
127 | + * } | ||
128 | + * </code> | ||
129 | + * </pre> | ||
130 | + * then the code <code>getGenericTypeArgument( MyClass.class.getDeclaredField("myStringCollection") , 0);</code> | ||
131 | + * will return the type <code>String</code>. | ||
132 | + * | ||
133 | + * @param field Field which type is generified | ||
134 | + * @param idx zero based index of the generic argument to get | ||
135 | + * @param <T> Type of the generic argument | ||
136 | + * @return The class representing the type of the generic argument | ||
137 | + */ | ||
138 | + @SuppressWarnings("unchecked") | ||
139 | + public static <T> Class<T> getGenericTypeArgument(final Field field, final int idx) { | ||
140 | + final Type type = field.getGenericType(); | ||
141 | + final ParameterizedType paramType = (ParameterizedType) type; | ||
142 | + | ||
143 | + return (Class<T>) paramType.getActualTypeArguments()[idx]; | ||
144 | + } | ||
145 | + | ||
146 | + /** | ||
147 | + * <p> | ||
148 | + * Return the parametized type passed to members (fields or methods) that accepts Generics. | ||
149 | + * </p> | ||
150 | + * | ||
151 | + * @param member Member which type is generified | ||
152 | + * @param idx zero based index of the generic argument to get | ||
153 | + * @param <T> Type of the generic argument | ||
154 | + * @return The class representing the type of the generic argument | ||
155 | + * @see #getGenericTypeArgument(Field field, int idx) | ||
156 | + */ | ||
157 | + public static <T> Class<T> getGenericTypeArgument(final Member member, final int idx) { | ||
158 | + Class<T> result = null; | ||
159 | + | ||
160 | + if (member instanceof Field) { | ||
161 | + result = getGenericTypeArgument((Field) member, idx); | ||
162 | + } else if (member instanceof Method) { | ||
163 | + result = getGenericTypeArgument((Method) member, idx); | ||
164 | + } | ||
165 | + | ||
166 | + return result; | ||
167 | + } | ||
168 | + | ||
169 | + /** | ||
170 | + * <p> | ||
171 | + * Return the parametized type passed to methods that accepts Generics. | ||
172 | + * </p> | ||
173 | + * | ||
174 | + * @param method Generified method reference | ||
175 | + * @param idx zero based index of the generic argument to get | ||
176 | + * @param <T> Type of the generic argument | ||
177 | + * @return The class representing the type of the generic argument | ||
178 | + * @see #getGenericTypeArgument(Field field, int idx) | ||
179 | + */ | ||
180 | + @SuppressWarnings("unchecked") | ||
181 | + public static <T> Class<T> getGenericTypeArgument(final Method method, final int idx) { | ||
182 | + return (Class<T>) method.getGenericParameterTypes()[idx]; | ||
183 | + } | ||
184 | + | ||
185 | + /** | ||
186 | + * Returns the value contained in the given field. | ||
187 | + * | ||
188 | + * @param field field to be extracted the value. | ||
189 | + * @param object object that contains the field. | ||
190 | + * @param <T> Type of the generic argument | ||
191 | + * @return value of the field. | ||
192 | + */ | ||
193 | + @SuppressWarnings("unchecked") | ||
194 | + public static <T> T getFieldValue(Field field, Object object) { | ||
195 | + T result = null; | ||
196 | + | ||
197 | + try { | ||
198 | + boolean acessible = field.isAccessible(); | ||
199 | + field.setAccessible(true); | ||
200 | + result = (T) field.get(object); | ||
201 | + field.setAccessible(acessible); | ||
202 | + | ||
203 | + } catch (Exception e) { | ||
204 | + Exceptions.handleToRuntimeException(e); | ||
205 | + } | ||
206 | + | ||
207 | + return result; | ||
208 | + } | ||
209 | + | ||
210 | + /** | ||
211 | + * Sets a value in a field. | ||
212 | + * | ||
213 | + * @param field field to be setted. | ||
214 | + * @param object object that contains the field. | ||
215 | + * @param value value to be setted in the field. | ||
216 | + */ | ||
217 | + public static void setFieldValue(Field field, Object object, Object value) { | ||
218 | + try { | ||
219 | + boolean acessible = field.isAccessible(); | ||
220 | + field.setAccessible(true); | ||
221 | + field.set(object, value); | ||
222 | + field.setAccessible(acessible); | ||
223 | + | ||
224 | + } catch (Exception e) { | ||
225 | + Exceptions.handleToRuntimeException(e); | ||
226 | + } | ||
227 | + } | ||
228 | + | ||
229 | + /** | ||
230 | + * @param type Base type to look for fields | ||
231 | + * @return All non static fields from a certain type. Inherited fields are not returned, so if you need to get | ||
232 | + * inherited fields you must iterate over this type's hierarchy. | ||
233 | + */ | ||
234 | + public static Field[] getNonStaticDeclaredFields(Class<?> type) { | ||
235 | + List<Field> fields = new ArrayList<Field>(); | ||
236 | + | ||
237 | + if (type != null) { | ||
238 | + for (Field field : type.getDeclaredFields()) { | ||
239 | + if (!Modifier.isStatic(field.getModifiers()) && !field.getType().equals(type.getDeclaringClass())) { | ||
240 | + fields.add(field); | ||
241 | + } | ||
242 | + } | ||
243 | + } | ||
244 | + | ||
245 | + return fields.toArray(new Field[0]); | ||
246 | + } | ||
247 | + | ||
248 | + /** | ||
249 | + * @param type Base type to look for fields | ||
250 | + * @return All non static fields from a certain type, including fields declared in superclasses of this type. | ||
251 | + */ | ||
252 | + public static List<Field> getNonStaticFields(Class<?> type) { | ||
253 | + List<Field> fields = new ArrayList<Field>(); | ||
254 | + | ||
255 | + if (type != null) { | ||
256 | + Class<?> currentType = type; | ||
257 | + while (currentType != null && !"java.lang.Object".equals(currentType.getCanonicalName())) { | ||
258 | + fields.addAll(Arrays.asList(getNonStaticDeclaredFields(currentType))); | ||
259 | + currentType = currentType.getSuperclass(); | ||
260 | + } | ||
261 | + } | ||
262 | + | ||
263 | + return fields; | ||
264 | + } | ||
265 | + | ||
266 | + /** | ||
267 | + * Instantiate an object of the given type. The default constructor with no parameters is used. | ||
268 | + * | ||
269 | + * @param clazz Base type of object to instantiate | ||
270 | + * @param <T> Final type of instantiated object | ||
271 | + * @return New instance of provided type | ||
272 | + */ | ||
273 | + public static <T> T instantiate(Class<T> clazz) { | ||
274 | + T object = null; | ||
275 | + try { | ||
276 | + object = clazz.newInstance(); | ||
277 | + } catch (InstantiationException | IllegalAccessException e) { | ||
278 | + Exceptions.handleToRuntimeException(e); | ||
279 | + } | ||
280 | + return object; | ||
281 | + } | ||
282 | + | ||
283 | + /** | ||
284 | + * Verifies if a given class could be converted to a given type. | ||
285 | + * | ||
286 | + * @param clazz class to be checked. | ||
287 | + * @param type type to be checked. | ||
288 | + * @return {@link Boolean} true if the given class can be converted to a given type, and false otherwise. | ||
289 | + */ | ||
290 | + public static boolean isOfType(Class<?> clazz, Class<?> type) { | ||
291 | + return type.isAssignableFrom(clazz) && clazz != type; | ||
292 | + } | ||
293 | + | ||
294 | + /** | ||
295 | + * Obtains the {@link ClassLoader} for the given class, from his canonical name. | ||
296 | + * | ||
297 | + * @param canonicalName canonical name of the the given class. | ||
298 | + * @return {@link ClassLoader} ClassLoader for the given class. | ||
299 | + */ | ||
300 | + public static ClassLoader getClassLoaderForClass(final String canonicalName) { | ||
301 | + return Reflections.getClassLoaderForResource(canonicalName.replaceAll("\\.", "/") + ".class"); | ||
302 | + } | ||
303 | + | ||
304 | + /** | ||
305 | + * Obtains the {@link ClassLoader} for the given resource. | ||
306 | + * | ||
307 | + * @param resource String representation of the fully qualified path to the resource on the classpath | ||
308 | + * @return {@link ClassLoader} ClassLoader for the given resource. | ||
309 | + */ | ||
310 | + public static ClassLoader getClassLoaderForResource(final String resource) { | ||
311 | + final String stripped = resource.charAt(0) == '/' ? resource.substring(1) : resource; | ||
312 | + | ||
313 | + URL url = null; | ||
314 | + ClassLoader result = Thread.currentThread().getContextClassLoader(); | ||
315 | + | ||
316 | + if (result != null) { | ||
317 | + url = result.getResource(stripped); | ||
318 | + } | ||
319 | + | ||
320 | + if (url == null) { | ||
321 | + result = Reflections.class.getClassLoader(); | ||
322 | + url = Reflections.class.getClassLoader().getResource(stripped); | ||
323 | + } | ||
324 | + | ||
325 | + if (url == null) { | ||
326 | + result = null; | ||
327 | + } | ||
328 | + | ||
329 | + return result; | ||
330 | + } | ||
331 | + | ||
332 | + /** | ||
333 | + * Return an URL to access a resource available to the active classloader for the calling thread. | ||
334 | + * | ||
335 | + * @param resource String representation of the location of the resource on the classpath | ||
336 | + * @return The {@link URL} for the resource | ||
337 | + */ | ||
338 | + public static URL getResourceAsURL(final String resource) { | ||
339 | + ClassLoader classLoader = getClassLoaderForResource(resource); | ||
340 | + return classLoader != null ? classLoader.getResource(resource) : null; | ||
341 | + } | ||
342 | + | ||
343 | + /** | ||
344 | + * Return an InputStream to access a resource available to the active classloader for the calling thread. | ||
345 | + * | ||
346 | + * @param resource String representation of the location of the resource on the classpath | ||
347 | + * @return An {@link InputStream} that reads data from the resource | ||
348 | + */ | ||
349 | + public static InputStream getResourceAsStream(final String resource) { | ||
350 | + ClassLoader classLoader = getClassLoaderForResource(resource); | ||
351 | + return classLoader != null ? classLoader.getResourceAsStream(resource) : null; | ||
352 | + } | ||
353 | + | ||
354 | + /** | ||
355 | + * Loads a class with the given name using the active classloader for the current thread. | ||
356 | + * | ||
357 | + * @param className String with fully qualified class name of the desired class | ||
358 | + * @param <T> Final type of the loaded class | ||
359 | + * @return Class representing the loaded type | ||
360 | + * @throws ClassNotFoundException If no class with this name exists | ||
361 | + */ | ||
362 | + @SuppressWarnings("unchecked") | ||
363 | + public static <T> Class<T> forName(final String className) throws ClassNotFoundException { | ||
364 | + ClassLoader classLoader = getClassLoaderForClass(className); | ||
365 | + return (Class<T>) Class.forName(className, true, classLoader); | ||
366 | + } | ||
367 | +} |
core/src/main/java/org/demoiselle/jee/core/util/ResourceBundle.java
0 → 100644
@@ -0,0 +1,136 @@ | @@ -0,0 +1,136 @@ | ||
1 | +/* | ||
2 | + * Demoiselle Framework | ||
3 | + * Copyright (C) 2010 SERPRO | ||
4 | + * ---------------------------------------------------------------------------- | ||
5 | + * This file is part of Demoiselle Framework. | ||
6 | + * | ||
7 | + * Demoiselle Framework is free software; you can redistribute it and/or | ||
8 | + * modify it under the terms of the GNU Lesser General Public License version 3 | ||
9 | + * as published by the Free Software Foundation. | ||
10 | + * | ||
11 | + * This program is distributed in the hope that it will be useful, | ||
12 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | + * GNU General Public License for more details. | ||
15 | + * | ||
16 | + * You should have received a copy of the GNU Lesser General Public License version 3 | ||
17 | + * along with this program; if not, see <http://www.gnu.org/licenses/> | ||
18 | + * or write to the Free Software Foundation, Inc., 51 Franklin Street, | ||
19 | + * Fifth Floor, Boston, MA 02110-1301, USA. | ||
20 | + * ---------------------------------------------------------------------------- | ||
21 | + * Este arquivo é parte do Framework Demoiselle. | ||
22 | + * | ||
23 | + * O Framework Demoiselle é um software livre; você pode redistribuí-lo e/ou | ||
24 | + * modificá-lo dentro dos termos da GNU LGPL versão 3 como publicada pela Fundação | ||
25 | + * do Software Livre (FSF). | ||
26 | + * | ||
27 | + * Este programa é distribuído na esperança que possa ser útil, mas SEM NENHUMA | ||
28 | + * GARANTIA; sem uma garantia implícita de ADEQUAÇÃO a qualquer MERCADO ou | ||
29 | + * APLICAÇÃO EM PARTICULAR. Veja a Licença Pública Geral GNU/LGPL em português | ||
30 | + * para maiores detalhes. | ||
31 | + * | ||
32 | + * Você deve ter recebido uma cópia da GNU LGPL versão 3, sob o título | ||
33 | + * "LICENCA.txt", junto com esse programa. Se não, acesse <http://www.gnu.org/licenses/> | ||
34 | + * ou escreva para a Fundação do Software Livre (FSF) Inc., | ||
35 | + * 51 Franklin St, Fifth Floor, Boston, MA 02111-1301, USA. | ||
36 | + */ | ||
37 | +package org.demoiselle.jee.core.util; | ||
38 | + | ||
39 | +import java.io.Serializable; | ||
40 | +import java.lang.reflect.Method; | ||
41 | +import java.util.Enumeration; | ||
42 | +import java.util.Locale; | ||
43 | +import java.util.MissingResourceException; | ||
44 | +import java.util.Set; | ||
45 | + | ||
46 | +/** | ||
47 | + * <p>The Demoiselle's ResourceBundle extends the abstraction {@link java.util.ResourceBundle}, | ||
48 | + * and provide the locale and the base name for the bundle.</p> | ||
49 | + * | ||
50 | + * <p>To select which resource properties file to load when injecting beans of this class, qualify | ||
51 | + * the injection point with {@link org.demoiselle.annotation.Name}, using the resource name (without | ||
52 | + * the '.properties' extension) as the value. If the injection point isn't qualified the default | ||
53 | + * file <code>messages.properties</code> will be loaded from the root of the classpath.</p> | ||
54 | + * | ||
55 | + * @author SERPRO | ||
56 | + */ | ||
57 | +public class ResourceBundle extends java.util.ResourceBundle implements Serializable { | ||
58 | + | ||
59 | + private static final long serialVersionUID = 1L; | ||
60 | + | ||
61 | + private String baseName; | ||
62 | + | ||
63 | + private transient java.util.ResourceBundle delegate; | ||
64 | + | ||
65 | + private final Locale locale; | ||
66 | + | ||
67 | + private java.util.ResourceBundle getDelegate() { | ||
68 | + if (delegate == null) { | ||
69 | + try { | ||
70 | + ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); | ||
71 | + delegate = ResourceBundle.getBundle(baseName, locale, classLoader); | ||
72 | + | ||
73 | + } catch (MissingResourceException mre) { | ||
74 | + delegate = ResourceBundle.getBundle(baseName, locale); | ||
75 | + } | ||
76 | + } | ||
77 | + | ||
78 | + return delegate; | ||
79 | + } | ||
80 | + | ||
81 | + /** | ||
82 | + * Constructor that set values of baseName and locale. | ||
83 | + * | ||
84 | + * @param baseName | ||
85 | + * the base name to construct the complete bundle name. | ||
86 | + * | ||
87 | + * @param locale | ||
88 | + * locale to define the choosen bundle. | ||
89 | + */ | ||
90 | + public ResourceBundle(String baseName, Locale locale) { | ||
91 | + this.baseName = baseName; | ||
92 | + this.locale = locale; | ||
93 | + } | ||
94 | + | ||
95 | + @Override | ||
96 | + public boolean containsKey(String key) { | ||
97 | + return getDelegate().containsKey(key); | ||
98 | + } | ||
99 | + | ||
100 | + @Override | ||
101 | + public Enumeration<String> getKeys() { | ||
102 | + return getDelegate().getKeys(); | ||
103 | + } | ||
104 | + | ||
105 | + @Override | ||
106 | + public Locale getLocale() { | ||
107 | + return getDelegate().getLocale(); | ||
108 | + } | ||
109 | + | ||
110 | + @Override | ||
111 | + public Set<String> keySet() { | ||
112 | + return getDelegate().keySet(); | ||
113 | + } | ||
114 | + | ||
115 | + public String getString(String key, Object... params) { | ||
116 | + return Strings.getString(getString(key), params); | ||
117 | + } | ||
118 | + | ||
119 | + @Override | ||
120 | + protected Object handleGetObject(String key) { | ||
121 | + Object result; | ||
122 | + | ||
123 | + try { | ||
124 | + Method method = getDelegate().getClass().getMethod("handleGetObject", String.class); | ||
125 | + | ||
126 | + method.setAccessible(true); | ||
127 | + result = method.invoke(delegate, key); | ||
128 | + method.setAccessible(false); | ||
129 | + | ||
130 | + } catch (Exception cause) { | ||
131 | + throw new RuntimeException(cause); | ||
132 | + } | ||
133 | + | ||
134 | + return result; | ||
135 | + } | ||
136 | +} |
core/src/main/java/org/demoiselle/jee/core/util/Strings.java
0 → 100644
@@ -0,0 +1,301 @@ | @@ -0,0 +1,301 @@ | ||
1 | +/* | ||
2 | + * Demoiselle Framework | ||
3 | + * Copyright (C) 2010 SERPRO | ||
4 | + * ---------------------------------------------------------------------------- | ||
5 | + * This file is part of Demoiselle Framework. | ||
6 | + * | ||
7 | + * Demoiselle Framework is free software; you can redistribute it and/or | ||
8 | + * modify it under the terms of the GNU Lesser General Public License version 3 | ||
9 | + * as published by the Free Software Foundation. | ||
10 | + * | ||
11 | + * This program is distributed in the hope that it will be useful, | ||
12 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | + * GNU General Public License for more details. | ||
15 | + * | ||
16 | + * You should have received a copy of the GNU Lesser General Public License version 3 | ||
17 | + * along with this program; if not, see <http://www.gnu.org/licenses/> | ||
18 | + * or write to the Free Software Foundation, Inc., 51 Franklin Street, | ||
19 | + * Fifth Floor, Boston, MA 02110-1301, USA. | ||
20 | + * ---------------------------------------------------------------------------- | ||
21 | + * Este arquivo é parte do Framework Demoiselle. | ||
22 | + * | ||
23 | + * O Framework Demoiselle é um software livre; você pode redistribuí-lo e/ou | ||
24 | + * modificá-lo dentro dos termos da GNU LGPL versão 3 como publicada pela Fundação | ||
25 | + * do Software Livre (FSF). | ||
26 | + * | ||
27 | + * Este programa é distribuído na esperança que possa ser útil, mas SEM NENHUMA | ||
28 | + * GARANTIA; sem uma garantia implícita de ADEQUAÇÃO a qualquer MERCADO ou | ||
29 | + * APLICAÇÃO EM PARTICULAR. Veja a Licença Pública Geral GNU/LGPL em português | ||
30 | + * para maiores detalhes. | ||
31 | + * | ||
32 | + * Você deve ter recebido uma cópia da GNU LGPL versão 3, sob o título | ||
33 | + * "LICENCA.txt", junto com esse programa. Se não, acesse <http://www.gnu.org/licenses/> | ||
34 | + * ou escreva para a Fundação do Software Livre (FSF) Inc., | ||
35 | + * 51 Franklin St, Fifth Floor, Boston, MA 02111-1301, USA. | ||
36 | + */ | ||
37 | +package org.demoiselle.jee.core.util; | ||
38 | + | ||
39 | +import org.demoiselle.jee.core.annotation.Ignore; | ||
40 | + | ||
41 | +import java.io.BufferedReader; | ||
42 | +import java.io.IOException; | ||
43 | +import java.io.InputStream; | ||
44 | +import java.io.InputStreamReader; | ||
45 | +import java.lang.reflect.Field; | ||
46 | +import java.util.Arrays; | ||
47 | +import java.util.regex.Matcher; | ||
48 | +import java.util.regex.Pattern; | ||
49 | +import org.demoiselle.util.Reflections; | ||
50 | + | ||
51 | +/** | ||
52 | + * Contain a set of methods that implements a set of functionalities that | ||
53 | + * envolves manipulation of strings. | ||
54 | + * | ||
55 | + * @author SERPRO | ||
56 | + */ | ||
57 | +public final class Strings { | ||
58 | + | ||
59 | + private Strings() { | ||
60 | + } | ||
61 | + | ||
62 | + /** | ||
63 | + * Returns if some string matches with the format of a ResourceBundle key or | ||
64 | + * not. | ||
65 | + * | ||
66 | + * @param key string to check if matches with key format of ResourceBundle. | ||
67 | + * @return boolean true if matches and false otherwise. | ||
68 | + */ | ||
69 | + public static boolean isResourceBundleKeyFormat(final String key) { | ||
70 | + return Pattern.matches("^\\{(.+)\\}$", key == null ? "" : key); | ||
71 | + } | ||
72 | + | ||
73 | + /** | ||
74 | + * Removes specific characteres from a given string. | ||
75 | + * | ||
76 | + * @param string string to be changed, by the removing of some characters. | ||
77 | + * @param chars characters to be removed from string. | ||
78 | + * @return String returns the given string without the given characters. | ||
79 | + */ | ||
80 | + public static String removeChars(String string, char... chars) { | ||
81 | + String result = string; | ||
82 | + | ||
83 | + if (result != null) { | ||
84 | + for (char ch : chars) { | ||
85 | + result = result.replace(String.valueOf(ch), ""); | ||
86 | + } | ||
87 | + } | ||
88 | + return result; | ||
89 | + } | ||
90 | + | ||
91 | + public static String join(String separator, String... strings) { | ||
92 | + StringBuffer result = new StringBuffer(); | ||
93 | + | ||
94 | + if (strings != null) { | ||
95 | + for (int i = 0; i < strings.length; i++) { | ||
96 | + if (i != 0 && separator != null) { | ||
97 | + result.append(separator); | ||
98 | + } | ||
99 | + | ||
100 | + if (strings[i] != null) { | ||
101 | + result.append(strings[i]); | ||
102 | + } | ||
103 | + } | ||
104 | + } | ||
105 | + | ||
106 | + return result.length() > 0 ? result.toString() : null; | ||
107 | + } | ||
108 | + | ||
109 | + /** | ||
110 | + * Inserts the character "0" in the begin of a given string. The quantity of | ||
111 | + * zeros that will be placed depends on the difference between the length of | ||
112 | + * the given string and the value of howMuchZeros. | ||
113 | + * | ||
114 | + * @param string string to insert zeros characthers. | ||
115 | + * @param howMuchZeros its controls how much zeros will be insert. | ||
116 | + * @return String Retuns the string, added with appropriate number of zeros. | ||
117 | + * For exemplo, if string = "yes" and howMuchZeros = 5, the returned string | ||
118 | + * will be "00yes". | ||
119 | + */ | ||
120 | + public static String insertZeros(String string, int howMuchZeros) { | ||
121 | + StringBuffer result = new StringBuffer((string == null ? "" : string).trim()); | ||
122 | + int difference = howMuchZeros - result.toString().length(); | ||
123 | + | ||
124 | + for (int j = 0; j < difference; j++) { | ||
125 | + result.insert(0, '0'); | ||
126 | + } | ||
127 | + | ||
128 | + return result.toString(); | ||
129 | + } | ||
130 | + | ||
131 | + /** | ||
132 | + * * Replaces the numbers between braces in the given string with the given | ||
133 | + * parameters. The process will replace a number between braces for the | ||
134 | + * parameter for which its order in the set of parameters matches with the | ||
135 | + * number of the given string. For exemple, if is received the following | ||
136 | + * string "Treats an {0} exception" and the set of parameters | ||
137 | + * {"DemoiselleException"}, the return will be the following string: "Treats | ||
138 | + * an DemoiselleException exception". | ||
139 | + * | ||
140 | + * @param string with the numbers with braces to be replaced with the | ||
141 | + * parameters. | ||
142 | + * @param params parameters that will replace the number with braces in the | ||
143 | + * given string. | ||
144 | + * @return String string with numbers replaced with the matching parameter. | ||
145 | + */ | ||
146 | + public static String getString(final String string, final Object... params) { | ||
147 | + String result = null; | ||
148 | + | ||
149 | + if (string != null) { | ||
150 | + result = new String(string); | ||
151 | + } | ||
152 | + | ||
153 | + if (params != null && string != null) { | ||
154 | + for (int i = 0; i < params.length; i++) { | ||
155 | + if (params[i] != null) { | ||
156 | + result = result.replaceAll("\\{" + i + "\\}", Matcher.quoteReplacement(params[i].toString())); | ||
157 | + } | ||
158 | + } | ||
159 | + } | ||
160 | + | ||
161 | + return result; | ||
162 | + } | ||
163 | + | ||
164 | + /** | ||
165 | + * Verifies if a given string is empty or null. | ||
166 | + * | ||
167 | + * @param string string to be verified. | ||
168 | + * @return boolean returns true if the given string is empty or null and | ||
169 | + * returns false otherwise. | ||
170 | + */ | ||
171 | + public static boolean isEmpty(String string) { | ||
172 | + return string == null || string.trim().isEmpty(); | ||
173 | + } | ||
174 | + | ||
175 | + /** | ||
176 | + * Converts any object to string. | ||
177 | + * | ||
178 | + * @param object object to be converted. | ||
179 | + * @return String the given object converted to string. | ||
180 | + */ | ||
181 | + public static String toString(Object object) { | ||
182 | + StringBuffer result = new StringBuffer(); | ||
183 | + Object fieldValue; | ||
184 | + | ||
185 | + if (object != null) { | ||
186 | + result.append(object.getClass().getSimpleName()); | ||
187 | + result.append(" ["); | ||
188 | + | ||
189 | + boolean first = true; | ||
190 | + for (Field field : Reflections.getNonStaticDeclaredFields(object.getClass())) { | ||
191 | + if (!field.isAnnotationPresent(Ignore.class)) { | ||
192 | + if (first) { | ||
193 | + first = false; | ||
194 | + } else { | ||
195 | + result.append(", "); | ||
196 | + } | ||
197 | + | ||
198 | + result.append(field.getName()); | ||
199 | + result.append('='); | ||
200 | + fieldValue = Reflections.getFieldValue(field, object); | ||
201 | + result.append(fieldValue != null && fieldValue.getClass().isArray() | ||
202 | + ? Arrays.toString((Object[]) fieldValue) | ||
203 | + : fieldValue); | ||
204 | + } | ||
205 | + } | ||
206 | + | ||
207 | + result.append(']'); | ||
208 | + } | ||
209 | + | ||
210 | + return result.toString(); | ||
211 | + } | ||
212 | + | ||
213 | + /** | ||
214 | + * Replace the camel case string for a lowercase string separated for a | ||
215 | + * given symbol. | ||
216 | + * | ||
217 | + * @param string string that separeted with camel case. | ||
218 | + * @param symbol simbol to be the new separator for the given string. | ||
219 | + * @return String the given string separated with the given symbol. | ||
220 | + */ | ||
221 | + public static String camelCaseToSymbolSeparated(String string, String symbol) { | ||
222 | + if (symbol == null) { | ||
223 | + symbol = ""; | ||
224 | + } | ||
225 | + | ||
226 | + return string == null ? null : string.replaceAll("\\B([A-Z])", symbol + "$1").toLowerCase(); | ||
227 | + } | ||
228 | + | ||
229 | + /** | ||
230 | + * Sets the first character of a given string to upper case. | ||
231 | + * | ||
232 | + * @param string Full string to convert | ||
233 | + * @return String the given string with the first character setted to upper | ||
234 | + * case. | ||
235 | + */ | ||
236 | + public static String firstToUpper(String string) { | ||
237 | + String result = string; | ||
238 | + | ||
239 | + if (!Strings.isEmpty(string)) { | ||
240 | + result = string.toUpperCase().charAt(0) + (string.length() > 1 ? string.substring(1) : ""); | ||
241 | + } | ||
242 | + | ||
243 | + return result; | ||
244 | + } | ||
245 | + | ||
246 | + /** | ||
247 | + * Removes braces from a given string. | ||
248 | + * | ||
249 | + * @param string Message to remove braces from | ||
250 | + * @return String the given string without braces. | ||
251 | + */ | ||
252 | + public static String removeBraces(String string) { | ||
253 | + String result = string; | ||
254 | + | ||
255 | + if (isResourceBundleKeyFormat(string)) { | ||
256 | + result = string.substring(1, string.length() - 1); | ||
257 | + } | ||
258 | + | ||
259 | + return result; | ||
260 | + } | ||
261 | + | ||
262 | + /** | ||
263 | + * Inserts braces in a given string. | ||
264 | + * | ||
265 | + * @param string Original string to insert braces on. | ||
266 | + * @return String the given string with braces. | ||
267 | + */ | ||
268 | + public static String insertBraces(String string) { | ||
269 | + String result = string; | ||
270 | + | ||
271 | + if (!isEmpty(string)) { | ||
272 | + result = "{" + string + "}"; | ||
273 | + } | ||
274 | + | ||
275 | + return result; | ||
276 | + } | ||
277 | + | ||
278 | + public static String parse(InputStream inputStream) throws IOException { | ||
279 | + StringBuilder result = new StringBuilder(); | ||
280 | + | ||
281 | + if (inputStream != null) { | ||
282 | + BufferedReader reader = null; | ||
283 | + | ||
284 | + try { | ||
285 | + reader = new BufferedReader(new InputStreamReader(inputStream)); | ||
286 | + String line; | ||
287 | + | ||
288 | + while ((line = reader.readLine()) != null) { | ||
289 | + result.append(line); | ||
290 | + } | ||
291 | + | ||
292 | + } finally { | ||
293 | + if (reader != null) { | ||
294 | + reader.close(); | ||
295 | + } | ||
296 | + } | ||
297 | + } | ||
298 | + | ||
299 | + return result.length() > 0 ? result.toString() : null; | ||
300 | + } | ||
301 | +} |