Commit 1a85fed145b24aff40e9550a0f930e9ff5642c31

Authored by Cleverson Sacramento
2 parents 2ce9e5ae 00cb3ec0
Exists in master

Merge branch '2.4.0' of git@github.com:demoiselle/framework.git into 2.4.0

Showing 21 changed files with 963 additions and 444 deletions   Show diff stats
impl/core/src/main/java/br/gov/frameworkdemoiselle/annotation/ViewScoped.java
@@ -55,7 +55,7 @@ import javax.enterprise.context.NormalScope; @@ -55,7 +55,7 @@ import javax.enterprise.context.NormalScope;
55 @Inherited 55 @Inherited
56 @Target({ METHOD, TYPE, FIELD }) 56 @Target({ METHOD, TYPE, FIELD })
57 @Retention(RUNTIME) 57 @Retention(RUNTIME)
58 -@NormalScope 58 +@NormalScope(passivating=true)
59 public @interface ViewScoped { 59 public @interface ViewScoped {
60 60
61 } 61 }
impl/core/src/main/java/br/gov/frameworkdemoiselle/util/Beans.java
@@ -40,10 +40,7 @@ import java.lang.annotation.Annotation; @@ -40,10 +40,7 @@ import java.lang.annotation.Annotation;
40 import java.lang.reflect.Member; 40 import java.lang.reflect.Member;
41 import java.lang.reflect.Type; 41 import java.lang.reflect.Type;
42 import java.util.Arrays; 42 import java.util.Arrays;
43 -import java.util.Collections;  
44 -import java.util.HashMap;  
45 import java.util.HashSet; 43 import java.util.HashSet;
46 -import java.util.Map;  
47 import java.util.NoSuchElementException; 44 import java.util.NoSuchElementException;
48 import java.util.Set; 45 import java.util.Set;
49 46
@@ -66,24 +63,19 @@ import br.gov.frameworkdemoiselle.DemoiselleException; @@ -66,24 +63,19 @@ import br.gov.frameworkdemoiselle.DemoiselleException;
66 */ 63 */
67 public final class Beans { 64 public final class Beans {
68 65
69 - private static final Map<ClassLoader, BeanManager> beanManagerCache = Collections  
70 - .synchronizedMap(new HashMap<ClassLoader, BeanManager>());  
71 - 66 + private static BeanManager beanManager = null;
  67 +
72 private Beans() { 68 private Beans() {
73 } 69 }
74 70
75 - public static void setBeanManager(BeanManager beanManager) {  
76 - beanManagerCache.put(getCurrentClassLoader(), beanManager); 71 + public static void setBeanManager(BeanManager manager) {
  72 + beanManager = manager;
77 } 73 }
78 74
79 public static BeanManager getBeanManager() { 75 public static BeanManager getBeanManager() {
80 - return beanManagerCache.get(getCurrentClassLoader());  
81 - }  
82 -  
83 - private static ClassLoader getCurrentClassLoader() {  
84 - return Thread.currentThread().getContextClassLoader(); 76 + return beanManager;
85 } 77 }
86 - 78 +
87 /** 79 /**
88 * Obtains a injectble instance of a bean, which have the given required type and qualifiers, and are available for 80 * Obtains a injectble instance of a bean, which have the given required type and qualifiers, and are available for
89 * injection in the point where this method was call. 81 * injection in the point where this method was call.
impl/extension/jpa/src/main/java/br/gov/frameworkdemoiselle/internal/bootstrap/EntityManagerBootstrap.java
@@ -1,254 +0,0 @@ @@ -1,254 +0,0 @@
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 br.gov.frameworkdemoiselle.internal.bootstrap;  
38 -  
39 -import java.lang.annotation.Annotation;  
40 -import java.lang.reflect.Type;  
41 -import java.util.Collections;  
42 -import java.util.HashSet;  
43 -import java.util.Locale;  
44 -import java.util.Set;  
45 -  
46 -import javax.enterprise.context.ApplicationScoped;  
47 -import javax.enterprise.context.ConversationScoped;  
48 -import javax.enterprise.context.RequestScoped;  
49 -import javax.enterprise.context.SessionScoped;  
50 -import javax.enterprise.event.Observes;  
51 -import javax.enterprise.inject.spi.AnnotatedConstructor;  
52 -import javax.enterprise.inject.spi.AnnotatedField;  
53 -import javax.enterprise.inject.spi.AnnotatedMethod;  
54 -import javax.enterprise.inject.spi.AnnotatedType;  
55 -import javax.enterprise.inject.spi.Extension;  
56 -import javax.enterprise.inject.spi.ProcessAnnotatedType;  
57 -import javax.enterprise.util.AnnotationLiteral;  
58 -  
59 -import org.apache.commons.configuration.ConfigurationException;  
60 -import org.apache.commons.configuration.PropertiesConfiguration;  
61 -import org.slf4j.Logger;  
62 -  
63 -import br.gov.frameworkdemoiselle.DemoiselleException;  
64 -import br.gov.frameworkdemoiselle.annotation.Name;  
65 -import br.gov.frameworkdemoiselle.annotation.ViewScoped;  
66 -import br.gov.frameworkdemoiselle.configuration.Configuration;  
67 -import br.gov.frameworkdemoiselle.internal.configuration.EntityManagerConfig;  
68 -import br.gov.frameworkdemoiselle.internal.configuration.EntityManagerConfig.EntityManagerScope;  
69 -import br.gov.frameworkdemoiselle.internal.producer.EntityManagerProducer;  
70 -import br.gov.frameworkdemoiselle.internal.producer.LoggerProducer;  
71 -import br.gov.frameworkdemoiselle.util.ResourceBundle;  
72 -  
73 -public class EntityManagerBootstrap implements Extension {  
74 -  
75 - private Logger logger;  
76 -  
77 - private transient ResourceBundle bundle;  
78 -  
79 - private static final String DEMOISELLE_PROPERTIES_FILE_NAME = "demoiselle.properties";  
80 -  
81 - public void makeScoped(@Observes ProcessAnnotatedType<EntityManagerProducer> event){  
82 - final AnnotatedType<EntityManagerProducer> type = event.getAnnotatedType();  
83 - final EntityManagerScope scope = getConfiguredEntityManagerScope();  
84 -  
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) {  
96 - case APPLICATION:  
97 - expectedScopedAnnotationType = ApplicationScoped.class;  
98 - scopedLiteral = new ApplicationLiteral();  
99 - break;  
100 - case CONVERSATION:  
101 - expectedScopedAnnotationType = ConversationScoped.class;  
102 - scopedLiteral = new ConversationLiteral();  
103 - break;  
104 - case NOSCOPE:  
105 - expectedScopedAnnotationType = null;  
106 - scopedLiteral = null;  
107 - break;  
108 - case REQUEST:  
109 - expectedScopedAnnotationType = RequestScoped.class;  
110 - scopedLiteral = new RequestLiteral();  
111 - break;  
112 - case SESSION:  
113 - expectedScopedAnnotationType = SessionScoped.class;  
114 - scopedLiteral = new SessionLiteral();  
115 - break;  
116 - case VIEW:  
117 - expectedScopedAnnotationType = ViewScoped.class;  
118 - scopedLiteral = new ViewLiteral();  
119 - break;  
120 - default:  
121 - expectedScopedAnnotationType = null;  
122 - scopedLiteral = null;  
123 - break;  
124 - }  
125 -  
126 - initialized = true;  
127 - }  
128 - }  
129 -  
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 - }  
141 -  
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;  
156 - }  
157 - else{  
158 - return delegate.getAnnotation(annotationType);  
159 - }  
160 - }  
161 -  
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);  
174 - }  
175 -  
176 - annotations = Collections.unmodifiableSet(myAnnotations);  
177 - }  
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);  
193 - }  
194 -  
195 - private EntityManagerScope getConfiguredEntityManagerScope() {  
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;  
216 - }  
217 - }  
218 -  
219 - if (entityManagerScope == null) {  
220 - getLogger().info(getBundle().getString("entity-manager-scope-not-defined",EntityManagerScope.REQUEST.name()));  
221 - entityManagerScope = EntityManagerScope.REQUEST;  
222 - }  
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);  
228 - }  
229 -  
230 - return entityManagerScope;  
231 - }  
232 -  
233 - private Logger getLogger() {  
234 - if (logger == null) {  
235 - logger = LoggerProducer.create(EntityManagerBootstrap.class);  
236 - }  
237 -  
238 - return logger;  
239 - }  
240 -  
241 - private ResourceBundle getBundle() {  
242 - if (bundle == null) {  
243 - bundle = new ResourceBundle("demoiselle-jpa-bundle", Locale.getDefault());  
244 - }  
245 -  
246 - return bundle;  
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;}  
254 -}  
impl/extension/jpa/src/main/java/br/gov/frameworkdemoiselle/internal/producer/AbstractEntityManagerStore.java 0 → 100644
@@ -0,0 +1,153 @@ @@ -0,0 +1,153 @@
  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 br.gov.frameworkdemoiselle.internal.producer;
  38 +
  39 +import java.util.Collections;
  40 +import java.util.HashMap;
  41 +import java.util.Map;
  42 +
  43 +import javax.enterprise.context.RequestScoped;
  44 +import javax.inject.Inject;
  45 +import javax.persistence.EntityManager;
  46 +import javax.persistence.FlushModeType;
  47 +
  48 +import org.slf4j.Logger;
  49 +
  50 +import br.gov.frameworkdemoiselle.annotation.Name;
  51 +import br.gov.frameworkdemoiselle.internal.configuration.EntityManagerConfig;
  52 +import br.gov.frameworkdemoiselle.internal.configuration.EntityManagerConfig.EntityManagerScope;
  53 +import br.gov.frameworkdemoiselle.util.Beans;
  54 +import br.gov.frameworkdemoiselle.util.NameQualifier;
  55 +import br.gov.frameworkdemoiselle.util.ResourceBundle;
  56 +
  57 +/**
  58 + *
  59 + * <p>Stores produced entity managers. When the {@link EntityManagerProducer} try to create an entity manager it will
  60 + * seach this store for a cached instance, only creating a new instance if this cache doesn't contain a suitable one.</p>
  61 + *
  62 + * <p>There are several concrete implementations of this class, each one corresponding to a scoped cache (ex: {@link RequestEntityManagerStore}
  63 + * stores Entity Managers on the request scope). To select witch implementation is used (and with that, what scope is used to store Entity Managers)
  64 + * open the "demoiselle.properties" file and edit the property "frameworkdemoiselle.persistence.entitymanager.scope". The default scope is the
  65 + * {@link RequestScoped}.</p>
  66 + *
  67 + *
  68 + * @author serpro
  69 + *
  70 + */
  71 +public abstract class AbstractEntityManagerStore implements EntityManagerStore {
  72 +
  73 + private static final long serialVersionUID = 1L;
  74 +
  75 + private final Map<String, EntityManager> cache = Collections.synchronizedMap(new HashMap<String, EntityManager>());
  76 +
  77 + @Inject
  78 + private EntityManagerFactoryProducer factory;
  79 +
  80 + @Inject
  81 + private Logger logger;
  82 +
  83 + @Inject
  84 + @Name("demoiselle-jpa-bundle")
  85 + private ResourceBundle bundle;
  86 +
  87 + @Inject
  88 + private EntityManagerConfig configuration;
  89 +
  90 + public EntityManager getEntityManager(String persistenceUnit) {
  91 + EntityManager entityManager = null;
  92 +
  93 + if (cache.containsKey(persistenceUnit)) {
  94 + entityManager = cache.get(persistenceUnit);
  95 +
  96 + } else {
  97 + entityManager = getFactory().create(persistenceUnit).createEntityManager();
  98 + entityManager.setFlushMode(FlushModeType.AUTO);
  99 +
  100 + cache.put(persistenceUnit, entityManager);
  101 + this.getLogger().info(getBundle().getString("entity-manager-was-created", persistenceUnit));
  102 + }
  103 +
  104 + return entityManager;
  105 + }
  106 +
  107 + void init() {
  108 + for (String persistenceUnit : getFactory().getCache().keySet()) {
  109 + getEntityManager(persistenceUnit);
  110 + }
  111 + }
  112 +
  113 + void close() {
  114 + //Se o produtor não possui escopo, então o ciclo de vida
  115 + //de EntityManager produzidos é responsabilidade do desenvolvedor. Não
  116 + //fechamos os EntityManagers aqui.
  117 + if (configuration.getEntityManagerScope() != EntityManagerScope.NOSCOPE){
  118 + for (EntityManager entityManager : cache.values()) {
  119 + entityManager.close();
  120 + }
  121 + }
  122 + cache.clear();
  123 + }
  124 +
  125 + public Map<String, EntityManager> getCache() {
  126 + if (cache==null || cache.isEmpty()){
  127 + init();
  128 + }
  129 +
  130 + return cache;
  131 + }
  132 +
  133 + private EntityManagerFactoryProducer getFactory(){
  134 + if (factory==null){
  135 + factory = Beans.getReference(EntityManagerFactoryProducer.class);
  136 + }
  137 + return factory;
  138 + }
  139 +
  140 + private Logger getLogger(){
  141 + if (logger==null){
  142 + logger = Beans.getReference(Logger.class);
  143 + }
  144 + return logger;
  145 + }
  146 +
  147 + private ResourceBundle getBundle(){
  148 + if (bundle==null){
  149 + bundle = Beans.getReference(ResourceBundle.class , new NameQualifier("demoiselle-jpa-bundle"));
  150 + }
  151 + return bundle;
  152 + }
  153 +}
impl/extension/jpa/src/main/java/br/gov/frameworkdemoiselle/internal/producer/ApplicationEntityManagerStore.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 br.gov.frameworkdemoiselle.internal.producer;
  38 +
  39 +import javax.annotation.PostConstruct;
  40 +import javax.annotation.PreDestroy;
  41 +import javax.enterprise.context.ApplicationScoped;
  42 +
  43 +/**
  44 + *
  45 + * Implementation that stores produced entity managers on the application scope.
  46 + *
  47 + * @author serpro
  48 + *
  49 + */
  50 +@ApplicationScoped
  51 +public class ApplicationEntityManagerStore extends AbstractEntityManagerStore {
  52 +
  53 + private static final long serialVersionUID = 1L;
  54 +
  55 + @Override
  56 + @PostConstruct
  57 + public void initialize() {
  58 + super.init();
  59 + }
  60 +
  61 + @Override
  62 + @PreDestroy
  63 + public void terminate() {
  64 + super.close();
  65 + }
  66 +
  67 +}
impl/extension/jpa/src/main/java/br/gov/frameworkdemoiselle/internal/producer/ConversationEntityManagerStore.java 0 → 100644
@@ -0,0 +1,79 @@ @@ -0,0 +1,79 @@
  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 br.gov.frameworkdemoiselle.internal.producer;
  38 +
  39 +import javax.annotation.PostConstruct;
  40 +import javax.annotation.PreDestroy;
  41 +import javax.enterprise.context.Conversation;
  42 +import javax.enterprise.context.ConversationScoped;
  43 +import javax.inject.Inject;
  44 +
  45 +/**
  46 + *
  47 + * Implementation that stores produced entity managers on the conversation scope.
  48 + * It's the user responsibility to start and end conversations injecting the {@link Conversation} object
  49 + * inside of a conversation scoped bean that need the entity manager.
  50 + *
  51 + * @author serpro
  52 + *
  53 + */
  54 +@ConversationScoped
  55 +public class ConversationEntityManagerStore extends AbstractEntityManagerStore {
  56 +
  57 + private static final long serialVersionUID = 1L;
  58 +
  59 + @Inject
  60 + private Conversation conversation;
  61 +
  62 +
  63 + public Conversation getConversation() {
  64 + return conversation;
  65 + }
  66 +
  67 + @Override
  68 + @PostConstruct
  69 + public void initialize() {
  70 + super.init();
  71 + }
  72 +
  73 + @Override
  74 + @PreDestroy
  75 + public void terminate() {
  76 + super.close();
  77 + }
  78 +
  79 +}
impl/extension/jpa/src/main/java/br/gov/frameworkdemoiselle/internal/producer/DependentEntityManagerStore.java 0 → 100644
@@ -0,0 +1,68 @@ @@ -0,0 +1,68 @@
  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 br.gov.frameworkdemoiselle.internal.producer;
  38 +
  39 +import javax.annotation.PostConstruct;
  40 +import javax.annotation.PreDestroy;
  41 +import javax.enterprise.context.Dependent;
  42 +
  43 +/**
  44 + *
  45 + * Implementation that doesn't store entity managers in any scope, instead
  46 + * produced entity managers are bound to the duration of the bean that injected them.
  47 + *
  48 + * @author serpro
  49 + *
  50 + */
  51 +@Dependent
  52 +public class DependentEntityManagerStore extends AbstractEntityManagerStore {
  53 +
  54 + private static final long serialVersionUID = 1L;
  55 +
  56 + @Override
  57 + @PostConstruct
  58 + public void initialize() {
  59 + super.init();
  60 + }
  61 +
  62 + @Override
  63 + @PreDestroy
  64 + public void terminate() {
  65 + super.close();
  66 + }
  67 +
  68 +}
impl/extension/jpa/src/main/java/br/gov/frameworkdemoiselle/internal/producer/EntityManagerProducer.java
@@ -37,19 +37,16 @@ @@ -37,19 +37,16 @@
37 package br.gov.frameworkdemoiselle.internal.producer; 37 package br.gov.frameworkdemoiselle.internal.producer;
38 38
39 import java.io.Serializable; 39 import java.io.Serializable;
40 -import java.util.Collections;  
41 -import java.util.HashMap;  
42 import java.util.Map; 40 import java.util.Map;
43 import java.util.Set; 41 import java.util.Set;
44 42
45 -import javax.annotation.PostConstruct;  
46 -import javax.annotation.PreDestroy; 43 +import javax.enterprise.context.ApplicationScoped;
47 import javax.enterprise.inject.Default; 44 import javax.enterprise.inject.Default;
  45 +import javax.enterprise.inject.Instance;
48 import javax.enterprise.inject.Produces; 46 import javax.enterprise.inject.Produces;
49 import javax.enterprise.inject.spi.InjectionPoint; 47 import javax.enterprise.inject.spi.InjectionPoint;
50 import javax.inject.Inject; 48 import javax.inject.Inject;
51 import javax.persistence.EntityManager; 49 import javax.persistence.EntityManager;
52 -import javax.persistence.FlushModeType;  
53 50
54 import org.slf4j.Logger; 51 import org.slf4j.Logger;
55 52
@@ -66,6 +63,7 @@ import br.gov.frameworkdemoiselle.util.ResourceBundle; @@ -66,6 +63,7 @@ import br.gov.frameworkdemoiselle.util.ResourceBundle;
66 * persistence.xml, demoiselle.properties or @PersistenceUnit annotation. 63 * persistence.xml, demoiselle.properties or @PersistenceUnit annotation.
67 * </p> 64 * </p>
68 */ 65 */
  66 +@ApplicationScoped
69 public class EntityManagerProducer implements Serializable{ 67 public class EntityManagerProducer implements Serializable{
70 68
71 private static final long serialVersionUID = 1L; 69 private static final long serialVersionUID = 1L;
@@ -76,12 +74,16 @@ public class EntityManagerProducer implements Serializable{ @@ -76,12 +74,16 @@ public class EntityManagerProducer implements Serializable{
76 @Inject 74 @Inject
77 @Name("demoiselle-jpa-bundle") 75 @Name("demoiselle-jpa-bundle")
78 private ResourceBundle bundle; 76 private ResourceBundle bundle;
79 -  
80 - private final Map<String, EntityManager> cache = Collections.synchronizedMap(new HashMap<String, EntityManager>());  
81 - 77 +
82 @Inject 78 @Inject
83 private EntityManagerFactoryProducer factory; 79 private EntityManagerFactoryProducer factory;
84 80
  81 + @Inject
  82 + private Instance<EntityManagerStore> storeInstance;
  83 +
  84 + @Inject
  85 + private EntityManagerConfig configuration;
  86 +
85 /** 87 /**
86 * <p> 88 * <p>
87 * Default EntityManager factory. Tries two strategies to produces EntityManager instances. 89 * Default EntityManager factory. Tries two strategies to produces EntityManager instances.
@@ -125,23 +127,6 @@ public class EntityManagerProducer implements Serializable{ @@ -125,23 +127,6 @@ public class EntityManagerProducer implements Serializable{
125 return new EntityManagerProxy(persistenceUnit); 127 return new EntityManagerProxy(persistenceUnit);
126 } 128 }
127 129
128 - public EntityManager getEntityManager(String persistenceUnit) {  
129 - EntityManager entityManager = null;  
130 -  
131 - if (cache.containsKey(persistenceUnit)) {  
132 - entityManager = cache.get(persistenceUnit);  
133 -  
134 - } else {  
135 - entityManager = factory.create(persistenceUnit).createEntityManager();  
136 - entityManager.setFlushMode(FlushModeType.AUTO);  
137 -  
138 - cache.put(persistenceUnit, entityManager);  
139 - this.logger.info(bundle.getString("entity-manager-was-created", persistenceUnit));  
140 - }  
141 -  
142 - return entityManager;  
143 - }  
144 -  
145 /** 130 /**
146 * Tries to get persistence unit name from demoiselle.properties. 131 * Tries to get persistence unit name from demoiselle.properties.
147 * 132 *
@@ -177,23 +162,31 @@ public class EntityManagerProducer implements Serializable{ @@ -177,23 +162,31 @@ public class EntityManagerProducer implements Serializable{
177 } 162 }
178 } 163 }
179 164
180 - @PostConstruct  
181 - protected void init() {  
182 - for (String persistenceUnit : factory.getCache().keySet()) {  
183 - getEntityManager(persistenceUnit);  
184 - }  
185 - }  
186 -  
187 - @PreDestroy  
188 - protected void close() {  
189 - for (EntityManager entityManager : cache.values()) {  
190 - entityManager.close();  
191 - }  
192 -  
193 - cache.clear(); 165 + public EntityManager getEntityManager(String persistenceUnit) {
  166 + return getStore().getEntityManager(persistenceUnit);
194 } 167 }
195 - 168 +
196 public Map<String, EntityManager> getCache() { 169 public Map<String, EntityManager> getCache() {
197 - return cache; 170 + return getStore().getCache();
198 } 171 }
  172 +
  173 + private EntityManagerStore getStore(){
  174 + switch(configuration.getEntityManagerScope()){
  175 + case REQUEST:
  176 + return storeInstance.select(RequestEntityManagerStore.class).get();
  177 + case APPLICATION:
  178 + return storeInstance.select(ApplicationEntityManagerStore.class).get();
  179 + case CONVERSATION:
  180 + return storeInstance.select(ConversationEntityManagerStore.class).get();
  181 + case NOSCOPE:
  182 + return storeInstance.select(DependentEntityManagerStore.class).get();
  183 + case SESSION:
  184 + return storeInstance.select(SessionEntityManagerStore.class).get();
  185 + case VIEW:
  186 + return storeInstance.select(ViewEntityManagerStore.class).get();
  187 + default:
  188 + return storeInstance.select(RequestEntityManagerStore.class).get();
  189 + }
  190 + }
  191 +
199 } 192 }
impl/extension/jpa/src/main/java/br/gov/frameworkdemoiselle/internal/producer/EntityManagerStore.java 0 → 100644
@@ -0,0 +1,30 @@ @@ -0,0 +1,30 @@
  1 +package br.gov.frameworkdemoiselle.internal.producer;
  2 +
  3 +import java.io.Serializable;
  4 +import java.util.Map;
  5 +
  6 +import javax.annotation.PostConstruct;
  7 +import javax.annotation.PreDestroy;
  8 +import javax.persistence.EntityManager;
  9 +
  10 +
  11 +public interface EntityManagerStore extends Serializable {
  12 +
  13 + /**
  14 + * Run this to initialize all persistence units. It's recomended this method
  15 + * be annotated with {@link PostConstruct}, so it runs as soon as an EntityManager gets injected.
  16 + */
  17 + public abstract void initialize();
  18 +
  19 + /**
  20 + * Run this to close all persistence units. It's recomended this method
  21 + * be annotated with {@link PreDestroy}, so it runs as soon as the scope the EntityManager is
  22 + * attached to ends.
  23 + */
  24 + public abstract void terminate();
  25 +
  26 + Map<String, EntityManager> getCache();
  27 +
  28 + public EntityManager getEntityManager(String persistenceUnit);
  29 +
  30 +}
impl/extension/jpa/src/main/java/br/gov/frameworkdemoiselle/internal/producer/RequestEntityManagerStore.java 0 → 100644
@@ -0,0 +1,66 @@ @@ -0,0 +1,66 @@
  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 br.gov.frameworkdemoiselle.internal.producer;
  38 +
  39 +import javax.annotation.PostConstruct;
  40 +import javax.annotation.PreDestroy;
  41 +import javax.enterprise.context.RequestScoped;
  42 +
  43 +/**
  44 + *
  45 + * Implementation that stores produced entity managers on the request scope.
  46 + *
  47 + * @author serpro
  48 + *
  49 + */
  50 +@RequestScoped
  51 +public class RequestEntityManagerStore extends AbstractEntityManagerStore {
  52 +
  53 + private static final long serialVersionUID = 1L;
  54 +
  55 + @Override
  56 + @PostConstruct
  57 + public void initialize() {
  58 + super.init();
  59 + }
  60 +
  61 + @Override
  62 + @PreDestroy
  63 + public void terminate() {
  64 + super.close();
  65 + }
  66 +}
impl/extension/jpa/src/main/java/br/gov/frameworkdemoiselle/internal/producer/SessionEntityManagerStore.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 br.gov.frameworkdemoiselle.internal.producer;
  38 +
  39 +import javax.annotation.PostConstruct;
  40 +import javax.annotation.PreDestroy;
  41 +import javax.enterprise.context.SessionScoped;
  42 +
  43 +/**
  44 + *
  45 + * Implementation that stores produced entity managers on the session scope.
  46 + *
  47 + * @author serpro
  48 + *
  49 + */
  50 +@SessionScoped
  51 +public class SessionEntityManagerStore extends AbstractEntityManagerStore {
  52 +
  53 + private static final long serialVersionUID = 1L;
  54 +
  55 + @Override
  56 + @PostConstruct
  57 + public void initialize() {
  58 + super.init();
  59 + }
  60 +
  61 + @Override
  62 + @PreDestroy
  63 + public void terminate() {
  64 + super.close();
  65 + }
  66 +
  67 +}
impl/extension/jpa/src/main/java/br/gov/frameworkdemoiselle/internal/producer/ViewEntityManagerStore.java 0 → 100644
@@ -0,0 +1,68 @@ @@ -0,0 +1,68 @@
  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 br.gov.frameworkdemoiselle.internal.producer;
  38 +
  39 +import javax.annotation.PostConstruct;
  40 +import javax.annotation.PreDestroy;
  41 +
  42 +import br.gov.frameworkdemoiselle.annotation.ViewScoped;
  43 +
  44 +/**
  45 + *
  46 + * Implementation that stores produced entity managers on the view scope.
  47 + *
  48 + * @author serpro
  49 + *
  50 + */
  51 +@ViewScoped
  52 +public class ViewEntityManagerStore extends AbstractEntityManagerStore {
  53 +
  54 + private static final long serialVersionUID = 1L;
  55 +
  56 + @Override
  57 + @PostConstruct
  58 + public void initialize() {
  59 + super.init();
  60 + }
  61 +
  62 + @Override
  63 + @PreDestroy
  64 + public void terminate() {
  65 + super.close();
  66 + }
  67 +
  68 +}
impl/extension/jpa/src/main/java/br/gov/frameworkdemoiselle/internal/proxy/EntityManagerProxy.java
@@ -70,10 +70,18 @@ public class EntityManagerProxy implements EntityManager, Serializable { @@ -70,10 +70,18 @@ public class EntityManagerProxy implements EntityManager, Serializable {
70 70
71 private static final long serialVersionUID = 1L; 71 private static final long serialVersionUID = 1L;
72 72
73 - /** 73 + /*
74 * Persistence unit of the delegated EntityManager. 74 * Persistence unit of the delegated EntityManager.
75 */ 75 */
76 private String persistenceUnit; 76 private String persistenceUnit;
  77 +
  78 + /*
  79 + * demoiselle-jpa configuration options
  80 + */
  81 + private EntityManagerConfig configuration;
  82 +
  83 +
  84 + private EntityManager delegateCache;
77 85
78 /** 86 /**
79 * Constructor based on persistence unit name. 87 * Constructor based on persistence unit name.
@@ -91,8 +99,15 @@ public class EntityManagerProxy implements EntityManager, Serializable { @@ -91,8 +99,15 @@ public class EntityManagerProxy implements EntityManager, Serializable {
91 * @return Cached EntityManager 99 * @return Cached EntityManager
92 */ 100 */
93 private EntityManager getEntityManagerDelegate() { 101 private EntityManager getEntityManagerDelegate() {
94 - EntityManagerProducer emp = Beans.getReference(EntityManagerProducer.class);  
95 - return emp.getEntityManager(this.persistenceUnit); 102 + //Se o produtor de EntityManager não estiver em um escopo, precisamos guardar em cache o EntityManager produzido,
  103 + //do contrário, basta solicitar uma instância do produtor (que estará em um escopo) e obter a instância real
  104 + //de EntityManager dele.
  105 + if (getConfiguration().getEntityManagerScope()!=EntityManagerScope.NOSCOPE || delegateCache==null){
  106 + EntityManagerProducer emp = Beans.getReference(EntityManagerProducer.class);
  107 + delegateCache = emp.getEntityManager(this.persistenceUnit);
  108 + }
  109 +
  110 + return delegateCache;
96 } 111 }
97 112
98 /* 113 /*
@@ -113,7 +128,8 @@ public class EntityManagerProxy implements EntityManager, Serializable { @@ -113,7 +128,8 @@ public class EntityManagerProxy implements EntityManager, Serializable {
113 @Override 128 @Override
114 public <T> T merge(T entity) { 129 public <T> T merge(T entity) {
115 joinTransactionIfNecessary(); 130 joinTransactionIfNecessary();
116 - checkEntityManagerScopePassivable(entity); 131 + T managedEntity = getEntityManagerDelegate().merge(entity);
  132 + checkEntityManagerScopePassivable(managedEntity);
117 return getEntityManagerDelegate().merge(entity); 133 return getEntityManagerDelegate().merge(entity);
118 } 134 }
119 135
@@ -155,6 +171,7 @@ public class EntityManagerProxy implements EntityManager, Serializable { @@ -155,6 +171,7 @@ public class EntityManagerProxy implements EntityManager, Serializable {
155 @Override 171 @Override
156 public <T> T find(Class<T> entityClass, Object primaryKey, LockModeType lockMode) { 172 public <T> T find(Class<T> entityClass, Object primaryKey, LockModeType lockMode) {
157 joinTransactionIfNecessary(); 173 joinTransactionIfNecessary();
  174 + checkEntityManagerScopePassivable(lockMode);
158 return getEntityManagerDelegate().find(entityClass, primaryKey, lockMode); 175 return getEntityManagerDelegate().find(entityClass, primaryKey, lockMode);
159 } 176 }
160 177
@@ -166,6 +183,7 @@ public class EntityManagerProxy implements EntityManager, Serializable { @@ -166,6 +183,7 @@ public class EntityManagerProxy implements EntityManager, Serializable {
166 @Override 183 @Override
167 public <T> T find(Class<T> entityClass, Object primaryKey, LockModeType lockMode, Map<String, Object> properties) { 184 public <T> T find(Class<T> entityClass, Object primaryKey, LockModeType lockMode, Map<String, Object> properties) {
168 joinTransactionIfNecessary(); 185 joinTransactionIfNecessary();
  186 + checkEntityManagerScopePassivable(lockMode);
169 return getEntityManagerDelegate().find(entityClass, primaryKey, lockMode, properties); 187 return getEntityManagerDelegate().find(entityClass, primaryKey, lockMode, properties);
170 } 188 }
171 189
@@ -213,6 +231,7 @@ public class EntityManagerProxy implements EntityManager, Serializable { @@ -213,6 +231,7 @@ public class EntityManagerProxy implements EntityManager, Serializable {
213 @Override 231 @Override
214 public void lock(Object entity, LockModeType lockMode) { 232 public void lock(Object entity, LockModeType lockMode) {
215 joinTransactionIfNecessary(); 233 joinTransactionIfNecessary();
  234 + checkEntityManagerScopePassivable(lockMode);
216 getEntityManagerDelegate().lock(entity, lockMode); 235 getEntityManagerDelegate().lock(entity, lockMode);
217 } 236 }
218 237
@@ -223,6 +242,7 @@ public class EntityManagerProxy implements EntityManager, Serializable { @@ -223,6 +242,7 @@ public class EntityManagerProxy implements EntityManager, Serializable {
223 @Override 242 @Override
224 public void lock(Object entity, LockModeType lockMode, Map<String, Object> properties) { 243 public void lock(Object entity, LockModeType lockMode, Map<String, Object> properties) {
225 joinTransactionIfNecessary(); 244 joinTransactionIfNecessary();
  245 + checkEntityManagerScopePassivable(lockMode);
226 getEntityManagerDelegate().lock(entity, lockMode, properties); 246 getEntityManagerDelegate().lock(entity, lockMode, properties);
227 } 247 }
228 248
@@ -363,7 +383,7 @@ public class EntityManagerProxy implements EntityManager, Serializable { @@ -363,7 +383,7 @@ public class EntityManagerProxy implements EntityManager, Serializable {
363 */ 383 */
364 @Override 384 @Override
365 public <T> TypedQuery<T> createNamedQuery(String name, Class<T> resultClass) { 385 public <T> TypedQuery<T> createNamedQuery(String name, Class<T> resultClass) {
366 - return getEntityManagerDelegate().createNamedQuery(name, resultClass); 386 + return new TypedQueryProxy<T>(getEntityManagerDelegate().createNamedQuery(name, resultClass),this);
367 } 387 }
368 388
369 /* 389 /*
@@ -407,7 +427,7 @@ public class EntityManagerProxy implements EntityManager, Serializable { @@ -407,7 +427,7 @@ public class EntityManagerProxy implements EntityManager, Serializable {
407 */ 427 */
408 protected final void joinTransactionIfNecessary() { 428 protected final void joinTransactionIfNecessary() {
409 try { 429 try {
410 - getEntityManagerDelegate().getTransaction(); 430 + /*EntityTransaction transaction = */getEntityManagerDelegate().getTransaction();
411 } catch (IllegalStateException cause) { 431 } catch (IllegalStateException cause) {
412 //IllegalStateException is launched if we are on a JTA entity manager, so 432 //IllegalStateException is launched if we are on a JTA entity manager, so
413 //we assume we need to join transaction instead of creating one. 433 //we assume we need to join transaction instead of creating one.
@@ -521,29 +541,50 @@ public class EntityManagerProxy implements EntityManager, Serializable { @@ -521,29 +541,50 @@ public class EntityManagerProxy implements EntityManager, Serializable {
521 return getEntityManagerDelegate().toString(); 541 return getEntityManagerDelegate().toString();
522 } 542 }
523 543
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")); 544 + private void checkEntityManagerScopePassivable(Object entity) {
  545 + EntityManagerConfig configuration = getConfiguration();
  546 + if (configuration.getEntityManagerScope()==EntityManagerScope.CONVERSATION
  547 + || configuration.getEntityManagerScope()==EntityManagerScope.SESSION
  548 + || configuration.getEntityManagerScope()==EntityManagerScope.VIEW){
  549 +
  550 + LockModeType lockMode = null;
  551 + if (getEntityManagerDelegate().contains(entity)){
  552 + lockMode = getEntityManagerDelegate().getLockMode(entity);
  553 + }
  554 + checkEntityManagerScopePassivable(lockMode);
  555 + }
534 } 556 }
535 557
536 - private void checkEntityManagerScopePassivable(Object entity) { 558 + private void checkEntityManagerScopePassivable(LockModeType lockMode) {
537 EntityManagerConfig configuration = getConfiguration(); 559 EntityManagerConfig configuration = getConfiguration();
538 if (configuration.getEntityManagerScope()==EntityManagerScope.CONVERSATION 560 if (configuration.getEntityManagerScope()==EntityManagerScope.CONVERSATION
539 || configuration.getEntityManagerScope()==EntityManagerScope.SESSION 561 || configuration.getEntityManagerScope()==EntityManagerScope.SESSION
540 || configuration.getEntityManagerScope()==EntityManagerScope.VIEW){ 562 || 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()); 563 +
  564 + if (lockMode!=null
  565 + && lockMode!=LockModeType.NONE
  566 + && lockMode!=LockModeType.OPTIMISTIC_FORCE_INCREMENT){
  567 + String message = getBundle().getString("passivable-scope-without-optimistic-lock" , configuration.getEntityManagerScope().toString());
544 getLogger().error(message); 568 getLogger().error(message);
545 throw new DemoiselleException(message); 569 throw new DemoiselleException(message);
546 } 570 }
547 } 571 }
548 } 572 }
  573 +
  574 + private EntityManagerConfig getConfiguration(){
  575 + if (configuration==null){
  576 + configuration = Beans.getReference(EntityManagerConfig.class);
  577 + }
  578 +
  579 + return configuration;
  580 + }
  581 +
  582 + private Logger getLogger() {
  583 + return Beans.getReference(Logger.class);
  584 + }
  585 +
  586 + private ResourceBundle getBundle(){
  587 + return Beans.getReference(ResourceBundle.class,new NameQualifier("demoiselle-jpa-bundle"));
  588 + }
  589 +
549 } 590 }
impl/extension/jpa/src/main/resources/META-INF/services/javax.enterprise.inject.spi.Extension
@@ -1 +0,0 @@ @@ -1 +0,0 @@
1 -br.gov.frameworkdemoiselle.internal.bootstrap.EntityManagerBootstrap  
2 \ No newline at end of file 0 \ No newline at end of file
impl/extension/jpa/src/main/resources/demoiselle-jpa-bundle.properties
@@ -46,5 +46,5 @@ no-transaction-active=Nenhuma transa\u00E7\u00E3o est\u00E1 ativa, verifique a c @@ -46,5 +46,5 @@ no-transaction-active=Nenhuma transa\u00E7\u00E3o est\u00E1 ativa, verifique a c
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}] 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]) 49 +passivable-scope-without-optimistic-lock=Um Entity Manager armazenado no escopo [{0}] suporta apenas trava otimista com vers\u00E3o. Use o tipo adequado ou remova a trava. (veja [LockModeType.OPTIMISTIC_FORCE_INCREMENT])
50 defining-entity-manager-scope=Definindo escopo [{0}] para produtor de Entity Manager 50 defining-entity-manager-scope=Definindo escopo [{0}] para produtor de Entity Manager
51 \ No newline at end of file 51 \ No newline at end of file
impl/extension/jpa/src/test/java/producer/NoScopedProducerTest.java 0 → 100644
@@ -0,0 +1,59 @@ @@ -0,0 +1,59 @@
  1 +package producer;
  2 +
  3 +import static org.junit.Assert.assertEquals;
  4 +import static org.junit.Assert.assertNotNull;
  5 +import static org.junit.Assert.assertTrue;
  6 +
  7 +import javax.persistence.EntityManager;
  8 +
  9 +import org.jboss.arquillian.container.test.api.Deployment;
  10 +import org.jboss.arquillian.junit.Arquillian;
  11 +import org.jboss.shrinkwrap.api.spec.WebArchive;
  12 +import org.junit.Test;
  13 +import org.junit.runner.RunWith;
  14 +
  15 +import test.Tests;
  16 +import br.gov.frameworkdemoiselle.internal.proxy.EntityManagerProxy;
  17 +import br.gov.frameworkdemoiselle.util.Beans;
  18 +import br.gov.frameworkdemoiselle.util.NameQualifier;
  19 +
  20 +@RunWith(Arquillian.class)
  21 +public class NoScopedProducerTest {
  22 +
  23 + private static final String PATH = "src/test/resources/producer";
  24 +
  25 + @Deployment
  26 + public static WebArchive createDeployment() {
  27 + WebArchive deployment = Tests.createDeployment(NoScopedProducerTest.class);
  28 + deployment.addAsResource(Tests.createFileAsset(PATH + "/persistence.xml"), "META-INF/persistence.xml");
  29 + deployment.addAsResource(Tests.createFileAsset(PATH + "/demoiselle_noscoped.properties"), "demoiselle.properties");
  30 +
  31 + return deployment;
  32 + }
  33 +
  34 + @Test
  35 + public void produceOneEntityManagerPerInjection() {
  36 + EntityManager m1 = Beans.getReference(EntityManager.class, new NameQualifier("pu"));
  37 +
  38 + assertNotNull(m1);
  39 + assertEquals(EntityManagerProxy.class, m1.getClass());
  40 +
  41 + EntityManager m2 = Beans.getReference(EntityManager.class, new NameQualifier("pu"));
  42 +
  43 + assertNotNull(m2);
  44 + assertEquals(EntityManagerProxy.class, m2.getClass());
  45 +
  46 + MyEntity entity = new MyEntity();
  47 + entity.setId(createId("testID"));
  48 +
  49 + m1.persist(entity);
  50 +
  51 + assertTrue( ! m2.contains(entity));
  52 + assertTrue(m1.contains(entity));
  53 + }
  54 +
  55 + private String createId(String id) {
  56 + return this.getClass().getName() + "_" + id;
  57 + }
  58 +
  59 +}
impl/extension/jpa/src/test/java/producer/ProducerTest.java
@@ -1,110 +0,0 @@ @@ -1,110 +0,0 @@
1 -package producer;  
2 -  
3 -import static org.junit.Assert.assertEquals;  
4 -import static org.junit.Assert.assertNotNull;  
5 -import static org.junit.Assert.assertTrue;  
6 -  
7 -import javax.persistence.EntityManager;  
8 -  
9 -import org.jboss.arquillian.container.test.api.Deployment;  
10 -import org.jboss.arquillian.junit.Arquillian;  
11 -import org.jboss.shrinkwrap.api.spec.WebArchive;  
12 -import org.junit.Test;  
13 -import org.junit.runner.RunWith;  
14 -  
15 -import test.Tests;  
16 -import br.gov.frameworkdemoiselle.internal.proxy.EntityManagerProxy;  
17 -import br.gov.frameworkdemoiselle.util.Beans;  
18 -import br.gov.frameworkdemoiselle.util.NameQualifier;  
19 -  
20 -@RunWith(Arquillian.class)  
21 -public class ProducerTest {  
22 -  
23 - private static final String PATH = "src/test/resources/producer";  
24 -  
25 - @Deployment//(name="request_scoped_producer")  
26 - public static WebArchive createDeployment() {  
27 - WebArchive deployment = Tests.createDeployment(ProducerTest.class);  
28 - deployment.addAsResource(Tests.createFileAsset(PATH + "/persistence.xml"), "META-INF/persistence.xml");  
29 - deployment.addAsResource(Tests.createFileAsset(PATH + "/demoiselle.properties"), "demoiselle.properties");  
30 -  
31 - return deployment;  
32 - }  
33 -  
34 - /*@Deployment(name="no_scoped_producer")  
35 - public static WebArchive createNoScopedDeployment() {  
36 - WebArchive deployment = Tests.createDeployment(ProducerTest.class);  
37 - deployment.addAsResource(Tests.createFileAsset(PATH + "/persistence.xml"), "META-INF/persistence.xml");  
38 - deployment.addAsResource(Tests.createFileAsset(PATH + "/demoiselle_noscoped.properties"), "demoiselle.properties");  
39 -  
40 - return deployment;  
41 - }*/  
42 -  
43 - @Test  
44 - public void produceEntityManager() {  
45 - EntityManager manager = Beans.getReference(EntityManager.class);  
46 -  
47 - assertNotNull(manager);  
48 - assertEquals(EntityManagerProxy.class, manager.getClass());  
49 - }  
50 -  
51 - @Test  
52 - public void produceMultipleEntityManagers() {  
53 - EntityManager m1 = Beans.getReference(EntityManager.class, new NameQualifier("pu"));  
54 -  
55 - assertNotNull(m1);  
56 - assertEquals(EntityManagerProxy.class, m1.getClass());  
57 -  
58 - EntityManager m2 = Beans.getReference(EntityManager.class, new NameQualifier("pu2"));  
59 -  
60 - assertNotNull(m2);  
61 - assertEquals(EntityManagerProxy.class, m2.getClass());  
62 - }  
63 -  
64 - @Test  
65 - public void produceOneEntityManagerPerRequest() {  
66 - EntityManager m1 = Beans.getReference(EntityManager.class, new NameQualifier("pu"));  
67 -  
68 - assertNotNull(m1);  
69 - assertEquals(EntityManagerProxy.class, m1.getClass());  
70 -  
71 - EntityManager m2 = Beans.getReference(EntityManager.class, new NameQualifier("pu"));  
72 -  
73 - assertNotNull(m2);  
74 - assertEquals(EntityManagerProxy.class, m2.getClass());  
75 -  
76 - MyEntity entity = new MyEntity();  
77 - entity.setId(createId("testID"));  
78 -  
79 - m1.persist(entity);  
80 -  
81 - assertTrue(m2.contains(entity));  
82 - }  
83 -  
84 - /*@Test  
85 - public void produceOneEntityManagerPerInjection() {  
86 - //Testa se ao usar o produtor sem escopo, mais de um entity manager é criado a cada injeção.  
87 -  
88 - EntityManager m1 = Beans.getReference(EntityManager.class, new NameQualifier("pu"));  
89 -  
90 - assertNotNull(m1);  
91 - assertEquals(EntityManagerProxy.class, m1.getClass());  
92 -  
93 - EntityManager m2 = Beans.getReference(EntityManager.class, new NameQualifier("pu"));  
94 -  
95 - assertNotNull(m2);  
96 - assertEquals(EntityManagerProxy.class, m2.getClass());  
97 -  
98 - MyEntity entity = new MyEntity();  
99 - entity.setId(createId("testID"));  
100 -  
101 - m1.persist(entity);  
102 -  
103 - assertTrue( ! m2.contains(entity));  
104 - }*/  
105 -  
106 - private String createId(String id) {  
107 - return this.getClass().getName() + "_" + id;  
108 - }  
109 -  
110 -}  
impl/extension/jpa/src/test/java/producer/RequestScopedProducerTest.java 0 → 100644
@@ -0,0 +1,118 @@ @@ -0,0 +1,118 @@
  1 +package producer;
  2 +
  3 +import static org.junit.Assert.assertEquals;
  4 +import static org.junit.Assert.assertNotNull;
  5 +import static org.junit.Assert.assertTrue;
  6 +
  7 +import javax.persistence.EntityManager;
  8 +
  9 +import org.jboss.arquillian.container.test.api.Deployment;
  10 +import org.jboss.arquillian.junit.Arquillian;
  11 +import org.jboss.shrinkwrap.api.spec.WebArchive;
  12 +import org.jboss.weld.context.http.HttpRequestContext;
  13 +import org.junit.Test;
  14 +import org.junit.runner.RunWith;
  15 +
  16 +import test.Tests;
  17 +import br.gov.frameworkdemoiselle.internal.proxy.EntityManagerProxy;
  18 +import br.gov.frameworkdemoiselle.util.Beans;
  19 +import br.gov.frameworkdemoiselle.util.NameQualifier;
  20 +
  21 +@RunWith(Arquillian.class)
  22 +public class RequestScopedProducerTest {
  23 +
  24 + private static final String PATH = "src/test/resources/producer";
  25 +
  26 + @Deployment
  27 + public static WebArchive createDeployment() {
  28 + WebArchive deployment = Tests.createDeployment(RequestScopedProducerTest.class);
  29 + deployment.addAsResource(Tests.createFileAsset(PATH + "/persistence.xml"), "META-INF/persistence.xml");
  30 + deployment.addAsResource(Tests.createFileAsset(PATH + "/demoiselle.properties"), "demoiselle.properties");
  31 +
  32 + return deployment;
  33 + }
  34 +
  35 + @Test
  36 + public void produceEntityManager() {
  37 + EntityManager manager = Beans.getReference(EntityManager.class);
  38 +
  39 + assertNotNull(manager);
  40 + assertEquals(EntityManagerProxy.class, manager.getClass());
  41 + }
  42 +
  43 + @Test
  44 + public void produceMultipleEntityManagers() {
  45 + EntityManager m1 = Beans.getReference(EntityManager.class, new NameQualifier("pu"));
  46 +
  47 + assertNotNull(m1);
  48 + assertEquals(EntityManagerProxy.class, m1.getClass());
  49 +
  50 + EntityManager m2 = Beans.getReference(EntityManager.class, new NameQualifier("pu2"));
  51 +
  52 + assertNotNull(m2);
  53 + assertEquals(EntityManagerProxy.class, m2.getClass());
  54 + }
  55 +
  56 + @Test
  57 + public void produceOneEntityManagerPerRequest() {
  58 + EntityManager m1 = Beans.getReference(EntityManager.class, new NameQualifier("pu"));
  59 +
  60 + assertNotNull(m1);
  61 + assertEquals(EntityManagerProxy.class, m1.getClass());
  62 +
  63 + EntityManager m2 = Beans.getReference(EntityManager.class, new NameQualifier("pu"));
  64 +
  65 + assertNotNull(m2);
  66 + assertEquals(EntityManagerProxy.class, m2.getClass());
  67 +
  68 + MyEntity entity = new MyEntity();
  69 + entity.setId(createId("testID"));
  70 +
  71 + m1.persist(entity);
  72 +
  73 + assertTrue(m2.contains(entity));
  74 + }
  75 +
  76 + @Test
  77 + public void produceDifferentEntityManagerPerRequest() {
  78 + HttpRequestContext weldContext = Beans.getReference(HttpRequestContext.class);
  79 +
  80 + boolean wasNotActive = false;
  81 + if (!weldContext.isActive()){
  82 + wasNotActive = true;
  83 + weldContext.activate();
  84 + }
  85 +
  86 + EntityManager m1 = Beans.getReference(EntityManager.class, new NameQualifier("pu"));
  87 + assertNotNull(m1);
  88 + assertEquals(EntityManagerProxy.class, m1.getClass());
  89 +
  90 + MyEntity entity = new MyEntity();
  91 + entity.setId(createId("testID"));
  92 +
  93 + m1.persist(entity);
  94 + assertTrue(m1.contains(entity));
  95 +
  96 + weldContext.invalidate();
  97 + weldContext.deactivate();
  98 +
  99 + if (!weldContext.isActive()){
  100 + weldContext.activate();
  101 + }
  102 +
  103 + EntityManager m2 = Beans.getReference(EntityManager.class, new NameQualifier("pu"));
  104 +
  105 + assertTrue( m2.isOpen() );
  106 + assertTrue( !m2.contains(entity));
  107 +
  108 + if (wasNotActive && weldContext.isActive()){
  109 + weldContext.invalidate();
  110 + weldContext.deactivate();
  111 + }
  112 + }
  113 +
  114 + private String createId(String id) {
  115 + return this.getClass().getName() + "_" + id;
  116 + }
  117 +
  118 +}
impl/extension/jpa/src/test/java/producer/ViewScopedProducerTest.java 0 → 100644
@@ -0,0 +1,83 @@ @@ -0,0 +1,83 @@
  1 +package producer;
  2 +
  3 +import static org.junit.Assert.assertEquals;
  4 +import static org.junit.Assert.assertNotNull;
  5 +import static org.junit.Assert.assertTrue;
  6 +
  7 +import javax.enterprise.context.ContextNotActiveException;
  8 +import javax.persistence.EntityManager;
  9 +
  10 +import org.jboss.arquillian.container.test.api.Deployment;
  11 +import org.jboss.arquillian.junit.Arquillian;
  12 +import org.jboss.shrinkwrap.api.spec.WebArchive;
  13 +import org.junit.Test;
  14 +import org.junit.runner.RunWith;
  15 +
  16 +import test.Tests;
  17 +import br.gov.frameworkdemoiselle.context.ViewContext;
  18 +import br.gov.frameworkdemoiselle.internal.proxy.EntityManagerProxy;
  19 +import br.gov.frameworkdemoiselle.util.Beans;
  20 +import br.gov.frameworkdemoiselle.util.NameQualifier;
  21 +
  22 +@RunWith(Arquillian.class)
  23 +public class ViewScopedProducerTest {
  24 +
  25 + private static final String PATH = "src/test/resources/producer";
  26 +
  27 + @Deployment
  28 + public static WebArchive createDeployment() {
  29 + WebArchive deployment = Tests.createDeployment(ViewScopedProducerTest.class);
  30 + deployment.addAsResource(Tests.createFileAsset(PATH + "/persistence.xml"), "META-INF/persistence.xml");
  31 + deployment.addAsResource(Tests.createFileAsset(PATH + "/demoiselle_viewscoped.properties"), "demoiselle.properties");
  32 +
  33 + return deployment;
  34 + }
  35 +
  36 + @Test
  37 + public void produceOneEntityManagerPerView() {
  38 + ViewContext ctx = Beans.getReference(ViewContext.class);
  39 + ctx.activate();
  40 +
  41 + EntityManager m1 = Beans.getReference(EntityManager.class, new NameQualifier("pu"));
  42 +
  43 + assertNotNull(m1);
  44 + assertEquals(EntityManagerProxy.class, m1.getClass());
  45 +
  46 + EntityManager m2 = Beans.getReference(EntityManager.class, new NameQualifier("pu"));
  47 +
  48 + assertNotNull(m2);
  49 + assertEquals(EntityManagerProxy.class, m2.getClass());
  50 +
  51 + MyEntity entity = new MyEntity();
  52 + entity.setId(createId("testID"));
  53 +
  54 + m1.persist(entity);
  55 +
  56 + assertTrue(m2.contains(entity));
  57 +
  58 + ctx.deactivate();
  59 + }
  60 +
  61 + @Test(expected=ContextNotActiveException.class)
  62 + public void errorWhenContextNotActive() {
  63 + ViewContext ctx = Beans.getReference(ViewContext.class);
  64 + if (ctx.isActive()){
  65 + ctx.deactivate();
  66 + }
  67 +
  68 + EntityManager m1 = Beans.getReference(EntityManager.class, new NameQualifier("pu"));
  69 +
  70 + assertNotNull(m1);
  71 + assertEquals(EntityManagerProxy.class, m1.getClass());
  72 +
  73 + MyEntity entity = new MyEntity();
  74 + entity.setId(createId("testID"));
  75 +
  76 + m1.persist(entity);
  77 + }
  78 +
  79 + private String createId(String id) {
  80 + return this.getClass().getName() + "_" + id;
  81 + }
  82 +
  83 +}
impl/extension/jpa/src/test/java/transaction/interceptor/JPATransactionTest.java
@@ -66,7 +66,6 @@ public class JPATransactionTest { @@ -66,7 +66,6 @@ public class JPATransactionTest {
66 66
67 @Test 67 @Test
68 public void commitWithSuccess() { 68 public void commitWithSuccess() {
69 -  
70 tb.commitWithSuccess(); 69 tb.commitWithSuccess();
71 70
72 MyEntity1 entity1 = em1.find(MyEntity1.class, tb.createId("id-1")); 71 MyEntity1 entity1 = em1.find(MyEntity1.class, tb.createId("id-1"));
@@ -78,7 +77,6 @@ public class JPATransactionTest { @@ -78,7 +77,6 @@ public class JPATransactionTest {
78 77
79 @Test 78 @Test
80 public void rollbackWithSuccess() { 79 public void rollbackWithSuccess() {
81 -  
82 try { 80 try {
83 tb.rollbackWithSuccess(); 81 tb.rollbackWithSuccess();
84 } catch (Exception e) { 82 } catch (Exception e) {
impl/extension/jpa/src/test/resources/producer/demoiselle_viewscoped.properties 0 → 100644
@@ -0,0 +1,2 @@ @@ -0,0 +1,2 @@
  1 +frameworkdemoiselle.persistence.default.unit.name=pu
  2 +frameworkdemoiselle.persistence.entitymanager.scope=view
0 \ No newline at end of file 3 \ No newline at end of file