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 55 @Inherited
56 56 @Target({ METHOD, TYPE, FIELD })
57 57 @Retention(RUNTIME)
58   -@NormalScope
  58 +@NormalScope(passivating=true)
59 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 40 import java.lang.reflect.Member;
41 41 import java.lang.reflect.Type;
42 42 import java.util.Arrays;
43   -import java.util.Collections;
44   -import java.util.HashMap;
45 43 import java.util.HashSet;
46   -import java.util.Map;
47 44 import java.util.NoSuchElementException;
48 45 import java.util.Set;
49 46  
... ... @@ -66,24 +63,19 @@ import br.gov.frameworkdemoiselle.DemoiselleException;
66 63 */
67 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 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 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 80 * Obtains a injectble instance of a bean, which have the given required type and qualifiers, and are available for
89 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   -/*
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 @@
  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 @@
  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 @@
  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 @@
  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 37 package br.gov.frameworkdemoiselle.internal.producer;
38 38  
39 39 import java.io.Serializable;
40   -import java.util.Collections;
41   -import java.util.HashMap;
42 40 import java.util.Map;
43 41 import java.util.Set;
44 42  
45   -import javax.annotation.PostConstruct;
46   -import javax.annotation.PreDestroy;
  43 +import javax.enterprise.context.ApplicationScoped;
47 44 import javax.enterprise.inject.Default;
  45 +import javax.enterprise.inject.Instance;
48 46 import javax.enterprise.inject.Produces;
49 47 import javax.enterprise.inject.spi.InjectionPoint;
50 48 import javax.inject.Inject;
51 49 import javax.persistence.EntityManager;
52   -import javax.persistence.FlushModeType;
53 50  
54 51 import org.slf4j.Logger;
55 52  
... ... @@ -66,6 +63,7 @@ import br.gov.frameworkdemoiselle.util.ResourceBundle;
66 63 * persistence.xml, demoiselle.properties or @PersistenceUnit annotation.
67 64 * </p>
68 65 */
  66 +@ApplicationScoped
69 67 public class EntityManagerProducer implements Serializable{
70 68  
71 69 private static final long serialVersionUID = 1L;
... ... @@ -76,12 +74,16 @@ public class EntityManagerProducer implements Serializable{
76 74 @Inject
77 75 @Name("demoiselle-jpa-bundle")
78 76 private ResourceBundle bundle;
79   -
80   - private final Map<String, EntityManager> cache = Collections.synchronizedMap(new HashMap<String, EntityManager>());
81   -
  77 +
82 78 @Inject
83 79 private EntityManagerFactoryProducer factory;
84 80  
  81 + @Inject
  82 + private Instance<EntityManagerStore> storeInstance;
  83 +
  84 + @Inject
  85 + private EntityManagerConfig configuration;
  86 +
85 87 /**
86 88 * <p>
87 89 * Default EntityManager factory. Tries two strategies to produces EntityManager instances.
... ... @@ -125,23 +127,6 @@ public class EntityManagerProducer implements Serializable{
125 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 131 * Tries to get persistence unit name from demoiselle.properties.
147 132 *
... ... @@ -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 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 @@
  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 @@
  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 @@
  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 @@
  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 70  
71 71 private static final long serialVersionUID = 1L;
72 72  
73   - /**
  73 + /*
74 74 * Persistence unit of the delegated EntityManager.
75 75 */
76 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 87 * Constructor based on persistence unit name.
... ... @@ -91,8 +99,15 @@ public class EntityManagerProxy implements EntityManager, Serializable {
91 99 * @return Cached EntityManager
92 100 */
93 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 128 @Override
114 129 public <T> T merge(T entity) {
115 130 joinTransactionIfNecessary();
116   - checkEntityManagerScopePassivable(entity);
  131 + T managedEntity = getEntityManagerDelegate().merge(entity);
  132 + checkEntityManagerScopePassivable(managedEntity);
117 133 return getEntityManagerDelegate().merge(entity);
118 134 }
119 135  
... ... @@ -155,6 +171,7 @@ public class EntityManagerProxy implements EntityManager, Serializable {
155 171 @Override
156 172 public <T> T find(Class<T> entityClass, Object primaryKey, LockModeType lockMode) {
157 173 joinTransactionIfNecessary();
  174 + checkEntityManagerScopePassivable(lockMode);
158 175 return getEntityManagerDelegate().find(entityClass, primaryKey, lockMode);
159 176 }
160 177  
... ... @@ -166,6 +183,7 @@ public class EntityManagerProxy implements EntityManager, Serializable {
166 183 @Override
167 184 public <T> T find(Class<T> entityClass, Object primaryKey, LockModeType lockMode, Map<String, Object> properties) {
168 185 joinTransactionIfNecessary();
  186 + checkEntityManagerScopePassivable(lockMode);
169 187 return getEntityManagerDelegate().find(entityClass, primaryKey, lockMode, properties);
170 188 }
171 189  
... ... @@ -213,6 +231,7 @@ public class EntityManagerProxy implements EntityManager, Serializable {
213 231 @Override
214 232 public void lock(Object entity, LockModeType lockMode) {
215 233 joinTransactionIfNecessary();
  234 + checkEntityManagerScopePassivable(lockMode);
216 235 getEntityManagerDelegate().lock(entity, lockMode);
217 236 }
218 237  
... ... @@ -223,6 +242,7 @@ public class EntityManagerProxy implements EntityManager, Serializable {
223 242 @Override
224 243 public void lock(Object entity, LockModeType lockMode, Map<String, Object> properties) {
225 244 joinTransactionIfNecessary();
  245 + checkEntityManagerScopePassivable(lockMode);
226 246 getEntityManagerDelegate().lock(entity, lockMode, properties);
227 247 }
228 248  
... ... @@ -363,7 +383,7 @@ public class EntityManagerProxy implements EntityManager, Serializable {
363 383 */
364 384 @Override
365 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 427 */
408 428 protected final void joinTransactionIfNecessary() {
409 429 try {
410   - getEntityManagerDelegate().getTransaction();
  430 + /*EntityTransaction transaction = */getEntityManagerDelegate().getTransaction();
411 431 } catch (IllegalStateException cause) {
412 432 //IllegalStateException is launched if we are on a JTA entity manager, so
413 433 //we assume we need to join transaction instead of creating one.
... ... @@ -521,29 +541,50 @@ public class EntityManagerProxy implements EntityManager, Serializable {
521 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 559 EntityManagerConfig configuration = getConfiguration();
538 560 if (configuration.getEntityManagerScope()==EntityManagerScope.CONVERSATION
539 561 || configuration.getEntityManagerScope()==EntityManagerScope.SESSION
540 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 568 getLogger().error(message);
545 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   -br.gov.frameworkdemoiselle.internal.bootstrap.EntityManagerBootstrap
2 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 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 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 50 defining-entity-manager-scope=Definindo escopo [{0}] para produtor de Entity Manager
51 51 \ No newline at end of file
... ...
impl/extension/jpa/src/test/java/producer/NoScopedProducerTest.java 0 → 100644
... ... @@ -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   -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 @@
  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 @@
  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 66  
67 67 @Test
68 68 public void commitWithSuccess() {
69   -
70 69 tb.commitWithSuccess();
71 70  
72 71 MyEntity1 entity1 = em1.find(MyEntity1.class, tb.createId("id-1"));
... ... @@ -78,7 +77,6 @@ public class JPATransactionTest {
78 77  
79 78 @Test
80 79 public void rollbackWithSuccess() {
81   -
82 80 try {
83 81 tb.rollbackWithSuccess();
84 82 } catch (Exception e) {
... ...
impl/extension/jpa/src/test/resources/producer/demoiselle_viewscoped.properties 0 → 100644
... ... @@ -0,0 +1,2 @@
  1 +frameworkdemoiselle.persistence.default.unit.name=pu
  2 +frameworkdemoiselle.persistence.entitymanager.scope=view
0 3 \ No newline at end of file
... ...