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 56 String value = configuration.getString(prefix + key);
57 57  
58 58 if (value!=null){
59   - Object enums[] = field.getDeclaringClass().getEnumConstants();
  59 + Object enums[] = field.getType().getEnumConstants();
60 60  
61 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 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 37 package br.gov.frameworkdemoiselle.internal.bootstrap;
2 38  
3 39 import java.lang.annotation.Annotation;
4 40 import java.lang.reflect.Type;
5   -import java.net.URL;
  41 +import java.util.Collections;
  42 +import java.util.HashSet;
6 43 import java.util.Locale;
7 44 import java.util.Set;
8 45  
... ... @@ -10,18 +47,20 @@ import javax.enterprise.context.ApplicationScoped;
10 47 import javax.enterprise.context.ConversationScoped;
11 48 import javax.enterprise.context.RequestScoped;
12 49 import javax.enterprise.context.SessionScoped;
  50 +import javax.enterprise.event.Observes;
13 51 import javax.enterprise.inject.spi.AnnotatedConstructor;
14 52 import javax.enterprise.inject.spi.AnnotatedField;
15 53 import javax.enterprise.inject.spi.AnnotatedMethod;
16 54 import javax.enterprise.inject.spi.AnnotatedType;
17   -import javax.enterprise.inject.spi.BeanManager;
18 55 import javax.enterprise.inject.spi.Extension;
19 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 60 import org.apache.commons.configuration.PropertiesConfiguration;
23 61 import org.slf4j.Logger;
24 62  
  63 +import br.gov.frameworkdemoiselle.DemoiselleException;
25 64 import br.gov.frameworkdemoiselle.annotation.Name;
26 65 import br.gov.frameworkdemoiselle.annotation.ViewScoped;
27 66 import br.gov.frameworkdemoiselle.configuration.Configuration;
... ... @@ -37,151 +76,158 @@ public class EntityManagerBootstrap implements Extension {
37 76  
38 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 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 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 104 case NOSCOPE:
83   - returnedAnnotation = delegate.getAnnotation(annotationType);
  105 + expectedScopedAnnotationType = null;
  106 + scopedLiteral = null;
  107 + break;
84 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 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 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 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 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 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 233 private Logger getLogger() {
... ... @@ -194,9 +240,15 @@ public class EntityManagerBootstrap implements Extension {
194 240  
195 241 private ResourceBundle getBundle() {
196 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 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 50 /**
51 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 54 public class EntityManagerConfig implements Serializable {
55 55  
56 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 44  
45 45 import javax.annotation.PostConstruct;
46 46 import javax.annotation.PreDestroy;
47   -import javax.enterprise.context.RequestScoped;
48 47 import javax.enterprise.inject.Default;
49 48 import javax.enterprise.inject.Produces;
50 49 import javax.enterprise.inject.spi.InjectionPoint;
... ... @@ -67,8 +66,7 @@ import br.gov.frameworkdemoiselle.util.ResourceBundle;
67 66 * persistence.xml, demoiselle.properties or @PersistenceUnit annotation.
68 67 * </p>
69 68 */
70   -@RequestScoped
71   -public class EntityManagerProducer implements Serializable {
  69 +public class EntityManagerProducer implements Serializable{
72 70  
73 71 private static final long serialVersionUID = 1L;
74 72  
... ... @@ -83,7 +81,7 @@ public class EntityManagerProducer implements Serializable {
83 81  
84 82 @Inject
85 83 private EntityManagerFactoryProducer factory;
86   -
  84 +
87 85 /**
88 86 * <p>
89 87 * Default EntityManager factory. Tries two strategies to produces EntityManager instances.
... ... @@ -98,7 +96,7 @@ public class EntityManagerProducer implements Serializable {
98 96 */
99 97 @Default
100 98 @Produces
101   - public EntityManager createDefault(InjectionPoint ip, EntityManagerConfig config) {
  99 + protected EntityManager createDefault(InjectionPoint ip, EntityManagerConfig config) {
102 100 String persistenceUnit = getFromProperties(config);
103 101  
104 102 if (persistenceUnit == null) {
... ... @@ -108,9 +106,21 @@ public class EntityManagerProducer implements Serializable {
108 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 121 @Name("")
112 122 @Produces
113   - public EntityManager createNamed(InjectionPoint ip, EntityManagerConfig config) {
  123 + protected EntityManager createNamed(InjectionPoint ip, EntityManagerConfig config) {
114 124 String persistenceUnit = ip.getAnnotated().getAnnotation(Name.class).value();
115 125 return new EntityManagerProxy(persistenceUnit);
116 126 }
... ... @@ -166,16 +176,16 @@ public class EntityManagerProducer implements Serializable {
166 176 return persistenceUnits.iterator().next();
167 177 }
168 178 }
169   -
  179 +
170 180 @PostConstruct
171   - public void init() {
  181 + protected void init() {
172 182 for (String persistenceUnit : factory.getCache().keySet()) {
173 183 getEntityManager(persistenceUnit);
174 184 }
175 185 }
176 186  
177 187 @PreDestroy
178   - public void close() {
  188 + protected void close() {
179 189 for (EntityManager entityManager : cache.values()) {
180 190 entityManager.close();
181 191 }
... ...
impl/extension/jpa/src/main/java/br/gov/frameworkdemoiselle/internal/producer/RequestScopedProducer.java
... ... @@ -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 51 import javax.persistence.criteria.CriteriaQuery;
52 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 59 import br.gov.frameworkdemoiselle.internal.producer.EntityManagerProducer;
55 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 65 * Delegates all operation invocations to the cached EntityManager.
... ... @@ -62,7 +69,7 @@ import br.gov.frameworkdemoiselle.util.Beans;
62 69 public class EntityManagerProxy implements EntityManager, Serializable {
63 70  
64 71 private static final long serialVersionUID = 1L;
65   -
  72 +
66 73 /**
67 74 * Persistence unit of the delegated EntityManager.
68 75 */
... ... @@ -95,6 +102,7 @@ public class EntityManagerProxy implements EntityManager, Serializable {
95 102 @Override
96 103 public void persist(Object entity) {
97 104 joinTransactionIfNecessary();
  105 + checkEntityManagerScopePassivable(entity);
98 106 getEntityManagerDelegate().persist(entity);
99 107 }
100 108  
... ... @@ -105,6 +113,7 @@ public class EntityManagerProxy implements EntityManager, Serializable {
105 113 @Override
106 114 public <T> T merge(T entity) {
107 115 joinTransactionIfNecessary();
  116 + checkEntityManagerScopePassivable(entity);
108 117 return getEntityManagerDelegate().merge(entity);
109 118 }
110 119  
... ... @@ -115,6 +124,7 @@ public class EntityManagerProxy implements EntityManager, Serializable {
115 124 @Override
116 125 public void remove(Object entity) {
117 126 joinTransactionIfNecessary();
  127 + checkEntityManagerScopePassivable(entity);
118 128 getEntityManagerDelegate().remove(entity);
119 129 }
120 130  
... ... @@ -510,4 +520,30 @@ public class EntityManagerProxy implements EntityManager, Serializable {
510 520 public String toString() {
511 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 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 43 persistence-unit-name-found=Unidade de persist\u00EAncia "{0}" encontrada.
44 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 46 malformed-jpql=Consulta JPQL mal formada para pagina\u00E7\u00E3o de dados.
47 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 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 7 import javax.persistence.EntityManager;
8 8  
9 9 import org.jboss.arquillian.container.test.api.Deployment;
  10 +import org.jboss.arquillian.container.test.api.OperateOnDeployment;
10 11 import org.jboss.arquillian.junit.Arquillian;
11 12 import org.jboss.shrinkwrap.api.spec.WebArchive;
  13 +import org.junit.After;
  14 +import org.junit.Before;
12 15 import org.junit.Test;
13 16 import org.junit.runner.RunWith;
14 17  
15 18 import test.Tests;
  19 +import br.gov.frameworkdemoiselle.context.RequestContext;
16 20 import br.gov.frameworkdemoiselle.internal.proxy.EntityManagerProxy;
17 21 import br.gov.frameworkdemoiselle.util.Beans;
18 22 import br.gov.frameworkdemoiselle.util.NameQualifier;
... ... @@ -22,16 +26,38 @@ public class ProducerTest {
22 26  
23 27 private static final String PATH = "src/test/resources/producer";
24 28  
25   - @Deployment
  29 + @Deployment(name="request_scoped_producer")
26 30 public static WebArchive createDeployment() {
27 31 WebArchive deployment = Tests.createDeployment(ProducerTest.class);
28 32 deployment.addAsResource(Tests.createFileAsset(PATH + "/persistence.xml"), "META-INF/persistence.xml");
29 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 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 59 @Test
  60 + @OperateOnDeployment("request_scoped_producer")
35 61 public void produceEntityManager() {
36 62 EntityManager manager = Beans.getReference(EntityManager.class);
37 63  
... ... @@ -40,6 +66,7 @@ public class ProducerTest {
40 66 }
41 67  
42 68 @Test
  69 + @OperateOnDeployment("request_scoped_producer")
43 70 public void produceMultipleEntityManagers() {
44 71 EntityManager m1 = Beans.getReference(EntityManager.class, new NameQualifier("pu"));
45 72  
... ... @@ -53,6 +80,7 @@ public class ProducerTest {
53 80 }
54 81  
55 82 @Test
  83 + @OperateOnDeployment("request_scoped_producer")
56 84 public void produceOneEntityManagerPerRequest() {
57 85 EntityManager m1 = Beans.getReference(EntityManager.class, new NameQualifier("pu"));
58 86  
... ... @@ -71,6 +99,29 @@ public class ProducerTest {
71 99  
72 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 126 private String createId(String id) {
76 127 return this.getClass().getName() + "_" + id;
... ...
impl/extension/jpa/src/test/resources/producer/demoiselle.properties
1   -frameworkdemoiselle.persistence.default.unit.name=pu
2 1 \ No newline at end of file
  2 +frameworkdemoiselle.persistence.default.unit.name=pu
  3 +frameworkdemoiselle.persistence.entitymanager.scope=request
3 4 \ No newline at end of file
... ...
impl/extension/jpa/src/test/resources/producer/demoiselle_noscoped.properties 0 → 100644
... ... @@ -0,0 +1,2 @@
  1 +frameworkdemoiselle.persistence.default.unit.name=pu
  2 +frameworkdemoiselle.persistence.entitymanager.scope=noscope
0 3 \ No newline at end of file
... ...