Commit b8e4061f82fb2c3723f8db8f3c04c30da8be2ab4

Authored by Dancovich
1 parent c417ac14
Exists in master

Implementado produtor com escopo selecionável.

impl/core/src/main/java/br/gov/frameworkdemoiselle/internal/implementation/ConfigurationEnumValueExtractor.java
@@ -56,10 +56,10 @@ public class ConfigurationEnumValueExtractor implements ConfigurationValueExtrac @@ -56,10 +56,10 @@ public class ConfigurationEnumValueExtractor implements ConfigurationValueExtrac
56 String value = configuration.getString(prefix + key); 56 String value = configuration.getString(prefix + key);
57 57
58 if (value!=null){ 58 if (value!=null){
59 - Object enums[] = field.getDeclaringClass().getEnumConstants(); 59 + Object enums[] = field.getType().getEnumConstants();
60 60
61 for (int i=0; i<enums.length; i++){ 61 for (int i=0; i<enums.length; i++){
62 - if (enums[i].getClass().getSimpleName().equalsIgnoreCase(value)){ 62 + if ( ((Enum<?>)enums[i]).toString().equalsIgnoreCase(value) ){
63 return enums[i]; 63 return enums[i];
64 } 64 }
65 } 65 }
impl/extension/jpa/src/main/java/br/gov/frameworkdemoiselle/internal/bootstrap/EntityManagerBootstrap.java
  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 + */
1 package br.gov.frameworkdemoiselle.internal.bootstrap; 37 package br.gov.frameworkdemoiselle.internal.bootstrap;
2 38
3 import java.lang.annotation.Annotation; 39 import java.lang.annotation.Annotation;
4 import java.lang.reflect.Type; 40 import java.lang.reflect.Type;
5 -import java.net.URL; 41 +import java.util.Collections;
  42 +import java.util.HashSet;
6 import java.util.Locale; 43 import java.util.Locale;
7 import java.util.Set; 44 import java.util.Set;
8 45
@@ -10,18 +47,20 @@ import javax.enterprise.context.ApplicationScoped; @@ -10,18 +47,20 @@ import javax.enterprise.context.ApplicationScoped;
10 import javax.enterprise.context.ConversationScoped; 47 import javax.enterprise.context.ConversationScoped;
11 import javax.enterprise.context.RequestScoped; 48 import javax.enterprise.context.RequestScoped;
12 import javax.enterprise.context.SessionScoped; 49 import javax.enterprise.context.SessionScoped;
  50 +import javax.enterprise.event.Observes;
13 import javax.enterprise.inject.spi.AnnotatedConstructor; 51 import javax.enterprise.inject.spi.AnnotatedConstructor;
14 import javax.enterprise.inject.spi.AnnotatedField; 52 import javax.enterprise.inject.spi.AnnotatedField;
15 import javax.enterprise.inject.spi.AnnotatedMethod; 53 import javax.enterprise.inject.spi.AnnotatedMethod;
16 import javax.enterprise.inject.spi.AnnotatedType; 54 import javax.enterprise.inject.spi.AnnotatedType;
17 -import javax.enterprise.inject.spi.BeanManager;  
18 import javax.enterprise.inject.spi.Extension; 55 import javax.enterprise.inject.spi.Extension;
19 import javax.enterprise.inject.spi.ProcessAnnotatedType; 56 import javax.enterprise.inject.spi.ProcessAnnotatedType;
20 -import javax.enterprise.inject.spi.ProcessBean; 57 +import javax.enterprise.util.AnnotationLiteral;
21 58
  59 +import org.apache.commons.configuration.ConfigurationException;
22 import org.apache.commons.configuration.PropertiesConfiguration; 60 import org.apache.commons.configuration.PropertiesConfiguration;
23 import org.slf4j.Logger; 61 import org.slf4j.Logger;
24 62
  63 +import br.gov.frameworkdemoiselle.DemoiselleException;
25 import br.gov.frameworkdemoiselle.annotation.Name; 64 import br.gov.frameworkdemoiselle.annotation.Name;
26 import br.gov.frameworkdemoiselle.annotation.ViewScoped; 65 import br.gov.frameworkdemoiselle.annotation.ViewScoped;
27 import br.gov.frameworkdemoiselle.configuration.Configuration; 66 import br.gov.frameworkdemoiselle.configuration.Configuration;
@@ -37,151 +76,158 @@ public class EntityManagerBootstrap implements Extension { @@ -37,151 +76,158 @@ public class EntityManagerBootstrap implements Extension {
37 76
38 private transient ResourceBundle bundle; 77 private transient ResourceBundle bundle;
39 78
40 - private EntityManagerScope selectedScope; 79 + private static final String DEMOISELLE_PROPERTIES_FILE_NAME = "demoiselle.properties";
41 80
42 - public void replaceAnnotatedType(final ProcessAnnotatedType<EntityManagerProducer> event , BeanManager manager){ 81 + public void makeScoped(@Observes ProcessAnnotatedType<EntityManagerProducer> event){
  82 + final AnnotatedType<EntityManagerProducer> type = event.getAnnotatedType();
  83 + final EntityManagerScope scope = getConfiguredEntityManagerScope();
43 84
44 - if (event.getAnnotatedType().getJavaClass().equals(EntityManagerProducer.class)){  
45 - AnnotatedType<EntityManagerProducer> wrapper = new AnnotatedType<EntityManagerProducer>() {  
46 -  
47 - private final AnnotatedType<EntityManagerProducer> delegate = event.getAnnotatedType();  
48 -  
49 - public Class<EntityManagerProducer> getJavaClass() {  
50 - return delegate.getJavaClass();  
51 - }  
52 -  
53 - public Type getBaseType() {  
54 - return delegate.getBaseType();  
55 - }  
56 -  
57 - public Set<AnnotatedConstructor<EntityManagerProducer>> getConstructors() {  
58 - return delegate.getConstructors();  
59 - }  
60 -  
61 - public Set<Type> getTypeClosure() {  
62 - return delegate.getTypeClosure();  
63 - }  
64 -  
65 - public Set<AnnotatedMethod<? super EntityManagerProducer>> getMethods() {  
66 - return delegate.getMethods();  
67 - }  
68 -  
69 - public <T extends Annotation> T getAnnotation(Class<T> annotationType) {  
70 - return delegate.getAnnotation(annotationType);  
71 -  
72 - /*T returnedAnnotation;  
73 - switch(getConfiguredEntityManagerScope()){ 85 + AnnotatedType<EntityManagerProducer> newType = new AnnotatedType<EntityManagerProducer>() {
  86 +
  87 + private AnnotatedType<EntityManagerProducer> delegate = type;
  88 + private AnnotationLiteral<? extends Annotation> scopedLiteral;
  89 + private Class<? extends Annotation> expectedScopedAnnotationType;
  90 + private boolean initialized = false;
  91 + private Set<Annotation> annotations;
  92 +
  93 + private void initialize(){
  94 + if (!initialized){
  95 + switch (scope) {
74 case APPLICATION: 96 case APPLICATION:
75 - returnedAnnotation = (T) (annotationType.equals(ApplicationScoped.class) ? new AnnotationLiteral<ApplicationScoped>() {  
76 - private static final long serialVersionUID = 1L;  
77 - } : delegate.getAnnotation(annotationType)); 97 + expectedScopedAnnotationType = ApplicationScoped.class;
  98 + scopedLiteral = new ApplicationLiteral();
  99 + break;
78 case CONVERSATION: 100 case CONVERSATION:
79 - returnedAnnotation = (T) (annotationType.equals(ConversationScoped.class) ? new AnnotationLiteral<ApplicationScoped>() {  
80 - private static final long serialVersionUID = 1L;  
81 - } : delegate.getAnnotation(annotationType)); 101 + expectedScopedAnnotationType = ConversationScoped.class;
  102 + scopedLiteral = new ConversationLiteral();
  103 + break;
82 case NOSCOPE: 104 case NOSCOPE:
83 - returnedAnnotation = delegate.getAnnotation(annotationType); 105 + expectedScopedAnnotationType = null;
  106 + scopedLiteral = null;
  107 + break;
84 case REQUEST: 108 case REQUEST:
85 - returnedAnnotation = (T) (annotationType.equals(RequestScoped.class) ? new AnnotationLiteral<ApplicationScoped>() {  
86 - private static final long serialVersionUID = 1L;  
87 - } : delegate.getAnnotation(annotationType)); 109 + expectedScopedAnnotationType = RequestScoped.class;
  110 + scopedLiteral = new RequestLiteral();
  111 + break;
88 case SESSION: 112 case SESSION:
89 - returnedAnnotation = (T) (annotationType.equals(SessionScoped.class) ? new AnnotationLiteral<ApplicationScoped>() {  
90 - private static final long serialVersionUID = 1L;  
91 - } : delegate.getAnnotation(annotationType)); 113 + expectedScopedAnnotationType = SessionScoped.class;
  114 + scopedLiteral = new SessionLiteral();
  115 + break;
92 case VIEW: 116 case VIEW:
93 - returnedAnnotation = (T) (annotationType.equals(ViewScoped.class) ? new AnnotationLiteral<ApplicationScoped>() {  
94 - private static final long serialVersionUID = 1L;  
95 - } : delegate.getAnnotation(annotationType)); 117 + expectedScopedAnnotationType = ViewScoped.class;
  118 + scopedLiteral = new ViewLiteral();
  119 + break;
96 default: 120 default:
97 - returnedAnnotation = delegate.getAnnotation(annotationType); 121 + expectedScopedAnnotationType = null;
  122 + scopedLiteral = null;
  123 + break;
98 } 124 }
99 125
100 - return returnedAnnotation;*/ 126 + initialized = true;
101 } 127 }
  128 + }
102 129
103 - public Set<AnnotatedField<? super EntityManagerProducer>> getFields() {  
104 - return delegate.getFields();  
105 - } 130 + public Class<EntityManagerProducer> getJavaClass() {
  131 + return delegate.getJavaClass();
  132 + }
  133 +
  134 + public Type getBaseType() {
  135 + return delegate.getBaseType();
  136 + }
  137 +
  138 + public Set<AnnotatedConstructor<EntityManagerProducer>> getConstructors() {
  139 + return delegate.getConstructors();
  140 + }
106 141
107 - public Set<Annotation> getAnnotations() {  
108 - return delegate.getAnnotations(); 142 + public Set<Type> getTypeClosure() {
  143 + return delegate.getTypeClosure();
  144 + }
  145 +
  146 + public Set<AnnotatedMethod<? super EntityManagerProducer>> getMethods() {
  147 + return delegate.getMethods();
  148 + }
  149 +
  150 + @SuppressWarnings("unchecked")
  151 + public <T extends Annotation> T getAnnotation(Class<T> annotationType) {
  152 + initialize();
  153 +
  154 + if (expectedScopedAnnotationType!=null && expectedScopedAnnotationType.isAssignableFrom(annotationType)){
  155 + return (T) scopedLiteral;
109 } 156 }
  157 + else{
  158 + return delegate.getAnnotation(annotationType);
  159 + }
  160 + }
110 161
111 - public boolean isAnnotationPresent(Class<? extends Annotation> annotationType) {  
112 - switch(getConfiguredEntityManagerScope()){  
113 - case APPLICATION:  
114 - return annotationType.equals(ApplicationScoped.class) ? true : delegate.isAnnotationPresent(annotationType);  
115 - case CONVERSATION:  
116 - return annotationType.equals(ConversationScoped.class) ? true : delegate.isAnnotationPresent(annotationType);  
117 - case NOSCOPE:  
118 - return delegate.isAnnotationPresent(annotationType);  
119 - case REQUEST:  
120 - return annotationType.equals(RequestScoped.class) ? true : delegate.isAnnotationPresent(annotationType);  
121 - case SESSION:  
122 - return annotationType.equals(SessionScoped.class) ? true : delegate.isAnnotationPresent(annotationType);  
123 - case VIEW:  
124 - return annotationType.equals(ViewScoped.class) ? true : delegate.isAnnotationPresent(annotationType);  
125 - default:  
126 - return delegate.isAnnotationPresent(annotationType); 162 + public Set<AnnotatedField<? super EntityManagerProducer>> getFields() {
  163 + return delegate.getFields();
  164 + }
  165 +
  166 + public Set<Annotation> getAnnotations() {
  167 + initialize();
  168 +
  169 + if (annotations==null){
  170 + HashSet<Annotation> myAnnotations = new HashSet<Annotation>();
  171 + myAnnotations.addAll(delegate.getAnnotations());
  172 + if (scopedLiteral!=null && !myAnnotations.contains(scopedLiteral)){
  173 + myAnnotations.add(scopedLiteral);
127 } 174 }
  175 +
  176 + annotations = Collections.unmodifiableSet(myAnnotations);
128 } 177 }
129 - };  
130 -  
131 - event.setAnnotatedType(wrapper);  
132 - }  
133 - }  
134 -  
135 - public void configureBean(ProcessBean<EntityManagerProducer> event , BeanManager manager){  
136 - Class<? extends Annotation> beanScope = event.getBean().getScope();  
137 - System.out.println(beanScope.toString()); 178 +
  179 + return annotations;
  180 + }
  181 +
  182 + public boolean isAnnotationPresent(Class<? extends Annotation> annotationType) {
  183 + if (expectedScopedAnnotationType!=null && expectedScopedAnnotationType.isAssignableFrom(annotationType)){
  184 + return true;
  185 + }
  186 + else{
  187 + return delegate.isAnnotationPresent(annotationType);
  188 + }
  189 + }
  190 + };
  191 +
  192 + event.setAnnotatedType(newType);
138 } 193 }
139 194
140 private EntityManagerScope getConfiguredEntityManagerScope() { 195 private EntityManagerScope getConfiguredEntityManagerScope() {
141 - if (selectedScope==null){  
142 - EntityManagerScope entityManagerScope = null;  
143 - URL configURL = getClass().getResource("demoiselle.properties");  
144 -  
145 - if (configURL != null) {  
146 - try {  
147 - org.apache.commons.configuration.Configuration config = new PropertiesConfiguration(  
148 - configURL);  
149 - Configuration configAnnotation = EntityManagerConfig.class  
150 - .getAnnotation(Configuration.class);  
151 - Name nameAnnotation = EntityManagerConfig.class.getDeclaredField("entityManagerScope")  
152 - .getAnnotation(Name.class);  
153 -  
154 - String prefix = configAnnotation.prefix();  
155 - String sufix = nameAnnotation.value();  
156 -  
157 - String property = prefix.endsWith(".") ? prefix + sufix : prefix + "." + sufix;  
158 -  
159 - String scopeValue = config.getString(property, EntityManagerScope.REQUEST.name())  
160 - .toUpperCase();  
161 -  
162 - for (EntityManagerScope currentScope : EntityManagerScope.values()) {  
163 - if (currentScope.name().equals(scopeValue)) {  
164 - entityManagerScope = currentScope;  
165 - break;  
166 - }  
167 - }  
168 -  
169 - if (entityManagerScope == null) {  
170 - entityManagerScope = EntityManagerScope.REQUEST;  
171 - }  
172 - } catch (Exception e) {  
173 - getLogger().debug(getBundle().getString(""));  
174 - entityManagerScope = EntityManagerScope.REQUEST; 196 + EntityManagerScope entityManagerScope = null;
  197 +
  198 + try {
  199 + org.apache.commons.configuration.Configuration config = new PropertiesConfiguration(DEMOISELLE_PROPERTIES_FILE_NAME);
  200 + Configuration configAnnotation = EntityManagerConfig.class.getAnnotation(Configuration.class);
  201 + Name nameAnnotation = EntityManagerConfig.class.getDeclaredField("entityManagerScope").getAnnotation(
  202 + Name.class);
  203 +
  204 + String prefix = configAnnotation.prefix();
  205 + String sufix = nameAnnotation.value();
  206 +
  207 + String property = prefix.endsWith(".") ? prefix + sufix : prefix + "." + sufix;
  208 +
  209 + String scopeValue = config.getString(property, EntityManagerScope.REQUEST.name()).toUpperCase();
  210 +
  211 + for (EntityManagerScope currentScope : EntityManagerScope.values()) {
  212 + if (currentScope.name().equals(scopeValue)) {
  213 + entityManagerScope = currentScope;
  214 + getLogger().info(getBundle().getString("defining-entity-manager-scope",entityManagerScope.name()));
  215 + break;
175 } 216 }
176 } 217 }
177 - else{ 218 +
  219 + if (entityManagerScope == null) {
  220 + getLogger().info(getBundle().getString("entity-manager-scope-not-defined",EntityManagerScope.REQUEST.name()));
178 entityManagerScope = EntityManagerScope.REQUEST; 221 entityManagerScope = EntityManagerScope.REQUEST;
179 } 222 }
180 -  
181 - this.selectedScope = entityManagerScope; 223 + } catch (ConfigurationException e) {
  224 + getLogger().info(getBundle().getString("entity-manager-scope-not-defined",EntityManagerScope.REQUEST.name()));
  225 + entityManagerScope = EntityManagerScope.REQUEST;
  226 + } catch (Exception e){
  227 + throw new DemoiselleException(e);
182 } 228 }
183 229
184 - return selectedScope; 230 + return entityManagerScope;
185 } 231 }
186 232
187 private Logger getLogger() { 233 private Logger getLogger() {
@@ -194,9 +240,15 @@ public class EntityManagerBootstrap implements Extension { @@ -194,9 +240,15 @@ public class EntityManagerBootstrap implements Extension {
194 240
195 private ResourceBundle getBundle() { 241 private ResourceBundle getBundle() {
196 if (bundle == null) { 242 if (bundle == null) {
197 - bundle = new ResourceBundle("demoiselle-jpa-bundle.properties", Locale.getDefault()); 243 + bundle = new ResourceBundle("demoiselle-jpa-bundle", Locale.getDefault());
198 } 244 }
199 245
200 return bundle; 246 return bundle;
201 } 247 }
  248 +
  249 + class RequestLiteral extends AnnotationLiteral<RequestScoped> implements RequestScoped{private static final long serialVersionUID = 1L;}
  250 + class SessionLiteral extends AnnotationLiteral<SessionScoped> implements SessionScoped{private static final long serialVersionUID = 1L;}
  251 + class ApplicationLiteral extends AnnotationLiteral<ApplicationScoped> implements ApplicationScoped{private static final long serialVersionUID = 1L;}
  252 + class ViewLiteral extends AnnotationLiteral<ViewScoped> implements ViewScoped{private static final long serialVersionUID = 1L;}
  253 + class ConversationLiteral extends AnnotationLiteral<ConversationScoped> implements ConversationScoped{private static final long serialVersionUID = 1L;}
202 } 254 }
impl/extension/jpa/src/main/java/br/gov/frameworkdemoiselle/internal/configuration/EntityManagerConfig.java
@@ -50,7 +50,7 @@ import br.gov.frameworkdemoiselle.util.Strings; @@ -50,7 +50,7 @@ import br.gov.frameworkdemoiselle.util.Strings;
50 /** 50 /**
51 * Configuration class responsible for retrieving specific entity manager parameter values from properties file. 51 * Configuration class responsible for retrieving specific entity manager parameter values from properties file.
52 */ 52 */
53 -@Configuration(prefix = "frameworkdemoiselle.persistence.") 53 +@Configuration(prefix = "frameworkdemoiselle.persistence")
54 public class EntityManagerConfig implements Serializable { 54 public class EntityManagerConfig implements Serializable {
55 55
56 private static final long serialVersionUID = 1L; 56 private static final long serialVersionUID = 1L;
impl/extension/jpa/src/main/java/br/gov/frameworkdemoiselle/internal/producer/EntityManagerProducer.java
@@ -44,7 +44,6 @@ import java.util.Set; @@ -44,7 +44,6 @@ import java.util.Set;
44 44
45 import javax.annotation.PostConstruct; 45 import javax.annotation.PostConstruct;
46 import javax.annotation.PreDestroy; 46 import javax.annotation.PreDestroy;
47 -import javax.enterprise.context.RequestScoped;  
48 import javax.enterprise.inject.Default; 47 import javax.enterprise.inject.Default;
49 import javax.enterprise.inject.Produces; 48 import javax.enterprise.inject.Produces;
50 import javax.enterprise.inject.spi.InjectionPoint; 49 import javax.enterprise.inject.spi.InjectionPoint;
@@ -67,8 +66,7 @@ import br.gov.frameworkdemoiselle.util.ResourceBundle; @@ -67,8 +66,7 @@ import br.gov.frameworkdemoiselle.util.ResourceBundle;
67 * persistence.xml, demoiselle.properties or @PersistenceUnit annotation. 66 * persistence.xml, demoiselle.properties or @PersistenceUnit annotation.
68 * </p> 67 * </p>
69 */ 68 */
70 -@RequestScoped  
71 -public class EntityManagerProducer implements Serializable { 69 +public class EntityManagerProducer implements Serializable{
72 70
73 private static final long serialVersionUID = 1L; 71 private static final long serialVersionUID = 1L;
74 72
@@ -83,7 +81,7 @@ public class EntityManagerProducer implements Serializable { @@ -83,7 +81,7 @@ public class EntityManagerProducer implements Serializable {
83 81
84 @Inject 82 @Inject
85 private EntityManagerFactoryProducer factory; 83 private EntityManagerFactoryProducer factory;
86 - 84 +
87 /** 85 /**
88 * <p> 86 * <p>
89 * Default EntityManager factory. Tries two strategies to produces EntityManager instances. 87 * Default EntityManager factory. Tries two strategies to produces EntityManager instances.
@@ -98,7 +96,7 @@ public class EntityManagerProducer implements Serializable { @@ -98,7 +96,7 @@ public class EntityManagerProducer implements Serializable {
98 */ 96 */
99 @Default 97 @Default
100 @Produces 98 @Produces
101 - public EntityManager createDefault(InjectionPoint ip, EntityManagerConfig config) { 99 + protected EntityManager createDefault(InjectionPoint ip, EntityManagerConfig config) {
102 String persistenceUnit = getFromProperties(config); 100 String persistenceUnit = getFromProperties(config);
103 101
104 if (persistenceUnit == null) { 102 if (persistenceUnit == null) {
@@ -108,9 +106,21 @@ public class EntityManagerProducer implements Serializable { @@ -108,9 +106,21 @@ public class EntityManagerProducer implements Serializable {
108 return new EntityManagerProxy(persistenceUnit); 106 return new EntityManagerProxy(persistenceUnit);
109 } 107 }
110 108
  109 + /**
  110 + *
  111 + * <p>
  112 + * Factory that reads the {@link Name} qualifier and creates an entity manager with
  113 + * a matching persistence unit name.
  114 + * </p>
  115 + *
  116 + *
  117 + * @param config
  118 + * Suplies informations about EntityManager defined in properties file.
  119 + * @return Produced EntityManager.
  120 + */
111 @Name("") 121 @Name("")
112 @Produces 122 @Produces
113 - public EntityManager createNamed(InjectionPoint ip, EntityManagerConfig config) { 123 + protected EntityManager createNamed(InjectionPoint ip, EntityManagerConfig config) {
114 String persistenceUnit = ip.getAnnotated().getAnnotation(Name.class).value(); 124 String persistenceUnit = ip.getAnnotated().getAnnotation(Name.class).value();
115 return new EntityManagerProxy(persistenceUnit); 125 return new EntityManagerProxy(persistenceUnit);
116 } 126 }
@@ -166,16 +176,16 @@ public class EntityManagerProducer implements Serializable { @@ -166,16 +176,16 @@ public class EntityManagerProducer implements Serializable {
166 return persistenceUnits.iterator().next(); 176 return persistenceUnits.iterator().next();
167 } 177 }
168 } 178 }
169 - 179 +
170 @PostConstruct 180 @PostConstruct
171 - public void init() { 181 + protected void init() {
172 for (String persistenceUnit : factory.getCache().keySet()) { 182 for (String persistenceUnit : factory.getCache().keySet()) {
173 getEntityManager(persistenceUnit); 183 getEntityManager(persistenceUnit);
174 } 184 }
175 } 185 }
176 186
177 @PreDestroy 187 @PreDestroy
178 - public void close() { 188 + protected void close() {
179 for (EntityManager entityManager : cache.values()) { 189 for (EntityManager entityManager : cache.values()) {
180 entityManager.close(); 190 entityManager.close();
181 } 191 }
impl/extension/jpa/src/main/java/br/gov/frameworkdemoiselle/internal/producer/RequestScopedProducer.java
@@ -1,20 +0,0 @@ @@ -1,20 +0,0 @@
1 -package br.gov.frameworkdemoiselle.internal.producer;  
2 -  
3 -import static java.lang.annotation.ElementType.TYPE;  
4 -import static java.lang.annotation.RetentionPolicy.RUNTIME;  
5 -  
6 -import java.lang.annotation.Inherited;  
7 -import java.lang.annotation.Retention;  
8 -import java.lang.annotation.Target;  
9 -  
10 -import javax.enterprise.context.RequestScoped;  
11 -import javax.enterprise.inject.Stereotype;  
12 -  
13 -@RequestScoped  
14 -@Stereotype  
15 -@Inherited  
16 -@Retention(RUNTIME)  
17 -@Target({ TYPE })  
18 -public @interface RequestScopedProducer {  
19 -  
20 -}  
impl/extension/jpa/src/main/java/br/gov/frameworkdemoiselle/internal/proxy/EntityManagerProxy.java
@@ -51,8 +51,15 @@ import javax.persistence.criteria.CriteriaBuilder; @@ -51,8 +51,15 @@ import javax.persistence.criteria.CriteriaBuilder;
51 import javax.persistence.criteria.CriteriaQuery; 51 import javax.persistence.criteria.CriteriaQuery;
52 import javax.persistence.metamodel.Metamodel; 52 import javax.persistence.metamodel.Metamodel;
53 53
  54 +import org.slf4j.Logger;
  55 +
  56 +import br.gov.frameworkdemoiselle.DemoiselleException;
  57 +import br.gov.frameworkdemoiselle.internal.configuration.EntityManagerConfig;
  58 +import br.gov.frameworkdemoiselle.internal.configuration.EntityManagerConfig.EntityManagerScope;
54 import br.gov.frameworkdemoiselle.internal.producer.EntityManagerProducer; 59 import br.gov.frameworkdemoiselle.internal.producer.EntityManagerProducer;
55 import br.gov.frameworkdemoiselle.util.Beans; 60 import br.gov.frameworkdemoiselle.util.Beans;
  61 +import br.gov.frameworkdemoiselle.util.NameQualifier;
  62 +import br.gov.frameworkdemoiselle.util.ResourceBundle;
56 63
57 /** 64 /**
58 * Delegates all operation invocations to the cached EntityManager. 65 * Delegates all operation invocations to the cached EntityManager.
@@ -62,7 +69,7 @@ import br.gov.frameworkdemoiselle.util.Beans; @@ -62,7 +69,7 @@ import br.gov.frameworkdemoiselle.util.Beans;
62 public class EntityManagerProxy implements EntityManager, Serializable { 69 public class EntityManagerProxy implements EntityManager, Serializable {
63 70
64 private static final long serialVersionUID = 1L; 71 private static final long serialVersionUID = 1L;
65 - 72 +
66 /** 73 /**
67 * Persistence unit of the delegated EntityManager. 74 * Persistence unit of the delegated EntityManager.
68 */ 75 */
@@ -95,6 +102,7 @@ public class EntityManagerProxy implements EntityManager, Serializable { @@ -95,6 +102,7 @@ public class EntityManagerProxy implements EntityManager, Serializable {
95 @Override 102 @Override
96 public void persist(Object entity) { 103 public void persist(Object entity) {
97 joinTransactionIfNecessary(); 104 joinTransactionIfNecessary();
  105 + checkEntityManagerScopePassivable(entity);
98 getEntityManagerDelegate().persist(entity); 106 getEntityManagerDelegate().persist(entity);
99 } 107 }
100 108
@@ -105,6 +113,7 @@ public class EntityManagerProxy implements EntityManager, Serializable { @@ -105,6 +113,7 @@ public class EntityManagerProxy implements EntityManager, Serializable {
105 @Override 113 @Override
106 public <T> T merge(T entity) { 114 public <T> T merge(T entity) {
107 joinTransactionIfNecessary(); 115 joinTransactionIfNecessary();
  116 + checkEntityManagerScopePassivable(entity);
108 return getEntityManagerDelegate().merge(entity); 117 return getEntityManagerDelegate().merge(entity);
109 } 118 }
110 119
@@ -115,6 +124,7 @@ public class EntityManagerProxy implements EntityManager, Serializable { @@ -115,6 +124,7 @@ public class EntityManagerProxy implements EntityManager, Serializable {
115 @Override 124 @Override
116 public void remove(Object entity) { 125 public void remove(Object entity) {
117 joinTransactionIfNecessary(); 126 joinTransactionIfNecessary();
  127 + checkEntityManagerScopePassivable(entity);
118 getEntityManagerDelegate().remove(entity); 128 getEntityManagerDelegate().remove(entity);
119 } 129 }
120 130
@@ -510,4 +520,30 @@ public class EntityManagerProxy implements EntityManager, Serializable { @@ -510,4 +520,30 @@ public class EntityManagerProxy implements EntityManager, Serializable {
510 public String toString() { 520 public String toString() {
511 return getEntityManagerDelegate().toString(); 521 return getEntityManagerDelegate().toString();
512 } 522 }
  523 +
  524 + public EntityManagerConfig getConfiguration() {
  525 + return Beans.getReference(EntityManagerConfig.class);
  526 + }
  527 +
  528 + public Logger getLogger() {
  529 + return Beans.getReference(Logger.class);
  530 + }
  531 +
  532 + public ResourceBundle getBundle(){
  533 + return Beans.getReference(ResourceBundle.class,new NameQualifier("demoiselle-jpa-bundle"));
  534 + }
  535 +
  536 + private void checkEntityManagerScopePassivable(Object entity) {
  537 + EntityManagerConfig configuration = getConfiguration();
  538 + if (configuration.getEntityManagerScope()==EntityManagerScope.CONVERSATION
  539 + || configuration.getEntityManagerScope()==EntityManagerScope.SESSION
  540 + || configuration.getEntityManagerScope()==EntityManagerScope.VIEW){
  541 + LockModeType lockMode = getEntityManagerDelegate().getLockMode(entity);
  542 + if (lockMode != LockModeType.OPTIMISTIC_FORCE_INCREMENT && lockMode != LockModeType.WRITE){
  543 + String message = getBundle().getString("passivable-scope-with-pessimistic-lock" , configuration.getEntityManagerScope().toString());
  544 + getLogger().error(message);
  545 + throw new DemoiselleException(message);
  546 + }
  547 + }
  548 + }
513 } 549 }
impl/extension/jpa/src/main/resources/demoiselle-jpa-bundle.properties
@@ -42,6 +42,9 @@ can-not-get-persistence-unit-from-persistence=N\u00E3o foi poss\u00EDvel obter a @@ -42,6 +42,9 @@ can-not-get-persistence-unit-from-persistence=N\u00E3o foi poss\u00EDvel obter a
42 more-than-one-persistence-unit-defined=Existe mais de uma unidade de persist\u00EAncia definida. Utilize @{0} no ponto de inje\u00E7\u00E3o ou defina o atributo "frameworkdemoiselle.persistence.unit.name" no arquivo demoiselle.properties. 42 more-than-one-persistence-unit-defined=Existe mais de uma unidade de persist\u00EAncia definida. Utilize @{0} no ponto de inje\u00E7\u00E3o ou defina o atributo "frameworkdemoiselle.persistence.unit.name" no arquivo demoiselle.properties.
43 persistence-unit-name-found=Unidade de persist\u00EAncia "{0}" encontrada. 43 persistence-unit-name-found=Unidade de persist\u00EAncia "{0}" encontrada.
44 entity-manager-closed=O gerenciador de entidades foi fechado. 44 entity-manager-closed=O gerenciador de entidades foi fechado.
45 -no-transaction-active=Nenhuma transa\u00E7\u00E3o est\u00E1 ativa, verifique a configura\u00E7\u00E3o "{0}" no arquivo "{1}" e defina a sua estrat\u00E9gia de transa\u00E7\u00E3o. 45 +no-transaction-active=Nenhuma transa\u00E7\u00E3o est\u00E1 ativa, verifique a configura\u00E7\u00E3o "{0}" no arquivo "{1}" e defina a sua estrat\u00E9gia de transa\u00E7\u00E3o.
46 malformed-jpql=Consulta JPQL mal formada para pagina\u00E7\u00E3o de dados. 46 malformed-jpql=Consulta JPQL mal formada para pagina\u00E7\u00E3o de dados.
47 invalid-scope-for-entity-manager=O escopo especificado para o Entity Manager \u00E9 inv\u00E1lido. Por favor informe um dos escopos v\u00E1lidos para a propriedade frameworkdemoiselle.persistence.entitymanager.scope\: request, session, view, conversation, application 47 invalid-scope-for-entity-manager=O escopo especificado para o Entity Manager \u00E9 inv\u00E1lido. Por favor informe um dos escopos v\u00E1lidos para a propriedade frameworkdemoiselle.persistence.entitymanager.scope\: request, session, view, conversation, application
  48 +entity-manager-scope-not-defined=N\u00E3o foi poss\u00EDvel ler o escopo configurado para o Entity Manager, usando o escopo padr\u00E3o [{0}]
  49 +passivable-scope-with-pessimistic-lock=Entity Manager armazenado no escopo [{0}] requer o uso de trava otimista com vers\u00E3o (veja [LockModeType.OPTIMISTIC_FORCE_INCREMENT])
  50 +defining-entity-manager-scope=Definindo escopo [{0}] para produtor de Entity Manager
48 \ No newline at end of file 51 \ No newline at end of file
impl/extension/jpa/src/test/java/producer/ProducerTest.java
@@ -7,12 +7,16 @@ import static org.junit.Assert.assertTrue; @@ -7,12 +7,16 @@ import static org.junit.Assert.assertTrue;
7 import javax.persistence.EntityManager; 7 import javax.persistence.EntityManager;
8 8
9 import org.jboss.arquillian.container.test.api.Deployment; 9 import org.jboss.arquillian.container.test.api.Deployment;
  10 +import org.jboss.arquillian.container.test.api.OperateOnDeployment;
10 import org.jboss.arquillian.junit.Arquillian; 11 import org.jboss.arquillian.junit.Arquillian;
11 import org.jboss.shrinkwrap.api.spec.WebArchive; 12 import org.jboss.shrinkwrap.api.spec.WebArchive;
  13 +import org.junit.After;
  14 +import org.junit.Before;
12 import org.junit.Test; 15 import org.junit.Test;
13 import org.junit.runner.RunWith; 16 import org.junit.runner.RunWith;
14 17
15 import test.Tests; 18 import test.Tests;
  19 +import br.gov.frameworkdemoiselle.context.RequestContext;
16 import br.gov.frameworkdemoiselle.internal.proxy.EntityManagerProxy; 20 import br.gov.frameworkdemoiselle.internal.proxy.EntityManagerProxy;
17 import br.gov.frameworkdemoiselle.util.Beans; 21 import br.gov.frameworkdemoiselle.util.Beans;
18 import br.gov.frameworkdemoiselle.util.NameQualifier; 22 import br.gov.frameworkdemoiselle.util.NameQualifier;
@@ -22,16 +26,38 @@ public class ProducerTest { @@ -22,16 +26,38 @@ public class ProducerTest {
22 26
23 private static final String PATH = "src/test/resources/producer"; 27 private static final String PATH = "src/test/resources/producer";
24 28
25 - @Deployment 29 + @Deployment(name="request_scoped_producer")
26 public static WebArchive createDeployment() { 30 public static WebArchive createDeployment() {
27 WebArchive deployment = Tests.createDeployment(ProducerTest.class); 31 WebArchive deployment = Tests.createDeployment(ProducerTest.class);
28 deployment.addAsResource(Tests.createFileAsset(PATH + "/persistence.xml"), "META-INF/persistence.xml"); 32 deployment.addAsResource(Tests.createFileAsset(PATH + "/persistence.xml"), "META-INF/persistence.xml");
29 deployment.addAsResource(Tests.createFileAsset(PATH + "/demoiselle.properties"), "demoiselle.properties"); 33 deployment.addAsResource(Tests.createFileAsset(PATH + "/demoiselle.properties"), "demoiselle.properties");
30 - 34 +
  35 + return deployment;
  36 + }
  37 +
  38 + @Deployment(name="no_scoped_producer")
  39 + public static WebArchive createNoScopedDeployment() {
  40 + WebArchive deployment = Tests.createDeployment(ProducerTest.class);
  41 + deployment.addAsResource(Tests.createFileAsset(PATH + "/persistence.xml"), "META-INF/persistence.xml");
  42 + deployment.addAsResource(Tests.createFileAsset(PATH + "/demoiselle_noscoped.properties"), "demoiselle.properties");
  43 +
31 return deployment; 44 return deployment;
32 } 45 }
  46 +
  47 + @Before
  48 + public void before(){
  49 + RequestContext ctx = Beans.getReference(RequestContext.class);
  50 + ctx.activate();
  51 + }
  52 +
  53 + @After
  54 + public void after(){
  55 + RequestContext ctx = Beans.getReference(RequestContext.class);
  56 + ctx.deactivate();
  57 + }
33 58
34 @Test 59 @Test
  60 + @OperateOnDeployment("request_scoped_producer")
35 public void produceEntityManager() { 61 public void produceEntityManager() {
36 EntityManager manager = Beans.getReference(EntityManager.class); 62 EntityManager manager = Beans.getReference(EntityManager.class);
37 63
@@ -40,6 +66,7 @@ public class ProducerTest { @@ -40,6 +66,7 @@ public class ProducerTest {
40 } 66 }
41 67
42 @Test 68 @Test
  69 + @OperateOnDeployment("request_scoped_producer")
43 public void produceMultipleEntityManagers() { 70 public void produceMultipleEntityManagers() {
44 EntityManager m1 = Beans.getReference(EntityManager.class, new NameQualifier("pu")); 71 EntityManager m1 = Beans.getReference(EntityManager.class, new NameQualifier("pu"));
45 72
@@ -53,6 +80,7 @@ public class ProducerTest { @@ -53,6 +80,7 @@ public class ProducerTest {
53 } 80 }
54 81
55 @Test 82 @Test
  83 + @OperateOnDeployment("request_scoped_producer")
56 public void produceOneEntityManagerPerRequest() { 84 public void produceOneEntityManagerPerRequest() {
57 EntityManager m1 = Beans.getReference(EntityManager.class, new NameQualifier("pu")); 85 EntityManager m1 = Beans.getReference(EntityManager.class, new NameQualifier("pu"));
58 86
@@ -71,6 +99,29 @@ public class ProducerTest { @@ -71,6 +99,29 @@ public class ProducerTest {
71 99
72 assertTrue(m2.contains(entity)); 100 assertTrue(m2.contains(entity));
73 } 101 }
  102 +
  103 + @Test
  104 + @OperateOnDeployment("no_scoped_producer")
  105 + public void produceOneEntityManagerPerInjection() {
  106 + //Testa se ao usar o produtor sem escopo, mais de um entity manager é criado a cada injeção.
  107 +
  108 + EntityManager m1 = Beans.getReference(EntityManager.class, new NameQualifier("pu"));
  109 +
  110 + assertNotNull(m1);
  111 + assertEquals(EntityManagerProxy.class, m1.getClass());
  112 +
  113 + EntityManager m2 = Beans.getReference(EntityManager.class, new NameQualifier("pu"));
  114 +
  115 + assertNotNull(m2);
  116 + assertEquals(EntityManagerProxy.class, m2.getClass());
  117 +
  118 + MyEntity entity = new MyEntity();
  119 + entity.setId(createId("testID"));
  120 +
  121 + m1.persist(entity);
  122 +
  123 + assertTrue( ! m2.contains(entity));
  124 + }
74 125
75 private String createId(String id) { 126 private String createId(String id) {
76 return this.getClass().getName() + "_" + id; 127 return this.getClass().getName() + "_" + id;
impl/extension/jpa/src/test/resources/producer/demoiselle.properties
1 -frameworkdemoiselle.persistence.default.unit.name=pu  
2 \ No newline at end of file 1 \ No newline at end of file
  2 +frameworkdemoiselle.persistence.default.unit.name=pu
  3 +frameworkdemoiselle.persistence.entitymanager.scope=request
3 \ No newline at end of file 4 \ No newline at end of file
impl/extension/jpa/src/test/resources/producer/demoiselle_noscoped.properties 0 → 100644
@@ -0,0 +1,2 @@ @@ -0,0 +1,2 @@
  1 +frameworkdemoiselle.persistence.default.unit.name=pu
  2 +frameworkdemoiselle.persistence.entitymanager.scope=noscope
0 \ No newline at end of file 3 \ No newline at end of file