Commit 9fedd5e5ceb6d930281e8b54c21418b2bef2d3cf
Exists in
master
Merge branch 'master' of git@github.com:demoiselle/framework.git
Showing
12 changed files
with
435 additions
and
53 deletions
Show diff stats
documentation/reference/pt-BR/mensagem.xml
@@ -277,6 +277,41 @@ ALUNO_EXCLUIR_OK=L'étudiant {0} a été supprimé avec succès]]></programlisti | @@ -277,6 +277,41 @@ ALUNO_EXCLUIR_OK=L'étudiant {0} a été supprimé avec succès]]></programlisti | ||
277 | </para> | 277 | </para> |
278 | </note> | 278 | </note> |
279 | </section> | 279 | </section> |
280 | + | ||
281 | + <section> | ||
282 | + <title>Destino das mensagens</title> | ||
283 | + | ||
284 | + <para> | ||
285 | + O Framework Demoiselle permite configurar o destino das mensagens enviadas. Por padrão, mensagens enviadas em um ambiente SE (Swing por exemplo) | ||
286 | + são exibidas como registros de log no console, já mensagens enviadas em um ambiente WEB usando JSF 2.0 são redirecionadas para a classe | ||
287 | + <code>FacesContext</code>. Caso esse comportamento padrão não seja suficiente para você, é possível personalizar o mecanismo de redirecionamento | ||
288 | + de mensagens, fazendo-o enviar as mensagens para um local de seu interesse. | ||
289 | + </para> | ||
290 | + | ||
291 | + <para> | ||
292 | + Para isso existe a interface <code>MessageAppender</code>. Para toda mensagem enviada, o Framework Demoiselle vai determinar a implementação | ||
293 | + mais adequada de <code>MessageAppender</code> a utilizar e vai redirecionar qualquer mensagem para essa implementação. | ||
294 | + </para> | ||
295 | + | ||
296 | + <programlisting role="JAVA">public interface MessageAppender extends Serializable { | ||
297 | + | ||
298 | + /** | ||
299 | + * Method that must hold message in an appropriate way and in an appropriate local. | ||
300 | + * Demoiselle holds a message in a Logger or in a FacesContext, depending on the project. | ||
301 | + * | ||
302 | + * @param message | ||
303 | + * message to be stored. | ||
304 | + */ | ||
305 | + void append(Message message); | ||
306 | +}</programlisting> | ||
307 | + | ||
308 | + <para> | ||
309 | + Para criar seu próprio <code>MessageAppender</code>, implemente essa interface e anote-a com a anotação <code>@Priority</code> - o Framework | ||
310 | + Demoiselle irá selecionar a implementação adequada paseada na maior prioridade. Não é necessário configurar mais nada, o Framework Demoiselle | ||
311 | + selecionará a implementação automaticamente. Cabe-lhe então a tarefa de implementar o método <code>append(Message message)</code> para tratar | ||
312 | + a mensagem da forma que melhor se adequar a seu projeto. | ||
313 | + </para> | ||
314 | + </section> | ||
280 | 315 | ||
281 | <section> | 316 | <section> |
282 | <title>Exemplos de implementação</title> | 317 | <title>Exemplos de implementação</title> |
documentation/reference/pt-BR/persistencia.xml
@@ -18,6 +18,181 @@ | @@ -18,6 +18,181 @@ | ||
18 | é apenas injetar o recurso adequado em seu código e o Framework Demoiselle se encarregará de | 18 | é apenas injetar o recurso adequado em seu código e o Framework Demoiselle se encarregará de |
19 | produzi-lo e configurá-lo. | 19 | produzi-lo e configurá-lo. |
20 | </para> | 20 | </para> |
21 | + | ||
22 | + <section> | ||
23 | + <title>JPA</title> | ||
24 | + | ||
25 | + <para> | ||
26 | + O Framework Demoiselle fornece um produtor padrão para contextos de persistência da JPA. Esse produtor lê o arquivo | ||
27 | + de configuração <code>persistence.xml</code> de seu projeto e toma as providências necessárias para fabricar uma instância | ||
28 | + da classe <code>EntityManager</code> que pode ser usada para gerenciar as entidades de sua aplicação. Além disso, instâncias | ||
29 | + de <code>EntityManager</code> produzidas pelo Framework Demoiselle participam automaticamente de transações abertas através da | ||
30 | + anotação <code>@Transactional</code>, conforme apresentado no capítulo sobre <link linkend="transacao">Transações</link>. | ||
31 | + </para> | ||
32 | + | ||
33 | + <tip> | ||
34 | + <para> | ||
35 | + Para acrescentar a dependência à extensão <literal>demoiselle-jpa</literal>, adicione esse código | ||
36 | + em seu arquivo <literal>pom.xml</literal>, na seção <literal>dependencies</literal>. | ||
37 | + </para> | ||
38 | + | ||
39 | + <programlisting role="XML"><![CDATA[<dependency> | ||
40 | + <groupId>br.gov.frameworkdemoiselle</groupId> | ||
41 | + <artifactId>demoiselle-jpa</artifactId> | ||
42 | + <scope>compile</scope> | ||
43 | +</dependency>]]></programlisting> | ||
44 | + </tip> | ||
45 | + | ||
46 | + <section> | ||
47 | + <title>Introdução ao mecanismo</title> | ||
48 | + | ||
49 | + <para> | ||
50 | + Para injetar uma instância de <code>EntityManager</code> em sua aplicação, basta usar a anotação <code>@Inject</code>. | ||
51 | + </para> | ||
52 | + | ||
53 | + <programlisting role="JAVA">@PersistenceController | ||
54 | +public class BookmarkDAO extends JPACrud<Bookmark, Long> { | ||
55 | + | ||
56 | + private static final long serialVersionUID = 1L; | ||
57 | + | ||
58 | + @Inject | ||
59 | + private EntityManager entityManager; | ||
60 | + | ||
61 | + public void persistBookmark(Bookmark bookmark){ | ||
62 | + entityManager.persist(bookmark); | ||
63 | + } | ||
64 | + | ||
65 | +}</programlisting> | ||
66 | + | ||
67 | + <para> | ||
68 | + O produtor padrão injetará o <code>EntityManager</code> configurado no arquivo <code>persistence.xml</code>. Se houver | ||
69 | + mais de um contexto de persistência configurado em <code>persistence.xml</code>, será necessário especificar qual será | ||
70 | + injetado no ponto de injeção. Para isso use a anotação <code>@Name</code>. | ||
71 | + </para> | ||
72 | + | ||
73 | + <programlisting role="JAVA">@PersistenceController | ||
74 | +public class BookmarkDAO extends JPACrud<Bookmark, Long> { | ||
75 | + | ||
76 | + private static final long serialVersionUID = 1L; | ||
77 | + | ||
78 | + @Inject | ||
79 | + @Name("persistence_unit_1") | ||
80 | + private EntityManager entityManager; | ||
81 | + | ||
82 | + public void persistBookmark(Bookmark bookmark){ | ||
83 | + entityManager.persist(bookmark); | ||
84 | + } | ||
85 | + | ||
86 | +}</programlisting> | ||
87 | + | ||
88 | + <para> | ||
89 | + É possível invocar o utilitário <code>Beans</code> para injetar instâncias de <code>EntityManager</code> programaticamente. | ||
90 | + </para> | ||
91 | + | ||
92 | + <programlisting role="JAVA">@PersistenceController | ||
93 | +public class BookmarkDAO extends JPACrud<Bookmark, Long> { | ||
94 | + | ||
95 | + private static final long serialVersionUID = 1L; | ||
96 | + | ||
97 | + public void persistBookmark(Bookmark bookmark){ | ||
98 | + EntityManager entityManager = Beans.getReference(EntityManager.class); | ||
99 | + entityManager.persist(bookmark); | ||
100 | + } | ||
101 | + | ||
102 | + public void persistBookmarkInHistory(Bookmark bookmark){ | ||
103 | + EntityManager entityManager = Beans.getReference(EntityManager.class , new NameQualifier("history_persistence_unit")); | ||
104 | + entityManager.persist(bookmark); | ||
105 | + } | ||
106 | + | ||
107 | +}</programlisting> | ||
108 | + </section> | ||
109 | + | ||
110 | + <section> | ||
111 | + <title>Configuração</title> | ||
112 | + | ||
113 | + <para> | ||
114 | + Alguns comportamentos do produtor podem ser configurados através das propriedades abaixo, que devem ser configuradas | ||
115 | + no arquivo <code>demoiselle.properties</code>. | ||
116 | + </para> | ||
117 | + | ||
118 | + <informaltable width="100%"> | ||
119 | + <tgroup cols="3"> | ||
120 | + <colspec align="left"/> | ||
121 | + <colspec align="left"/> | ||
122 | + <colspec align="right"/> | ||
123 | + | ||
124 | + <thead> | ||
125 | + <row valign="top"> | ||
126 | + <entry><emphasis role="bold">Propriedade</emphasis></entry> | ||
127 | + <entry><emphasis role="bold">Descrição</emphasis></entry> | ||
128 | + <entry><emphasis role="bold">Padrão</emphasis></entry> | ||
129 | + </row> | ||
130 | + </thead> | ||
131 | + | ||
132 | + <tbody> | ||
133 | + <row valign="top"> | ||
134 | + <entry>frameworkdemoiselle.​persistence.​default.​unit.​name</entry> | ||
135 | + <entry> | ||
136 | + <para> | ||
137 | + Define o nome da unidade de persistência padrão (configurada em <code>persistence.xml</code>) que será injetada | ||
138 | + caso a anotação <code>@Name</code> não seja usada. Não é necessário se apenas uma unidade de persistência for configurada. | ||
139 | + </para> | ||
140 | + </entry> | ||
141 | + <entry></entry> | ||
142 | + </row> | ||
143 | + | ||
144 | + <row valign="top"> | ||
145 | + <entry>frameworkdemoiselle.​persistence.​entitymanager.​scope</entry> | ||
146 | + <entry> | ||
147 | + <para> | ||
148 | + Permite determinar o escopo de unidades de persistência injetadas. Dentro do escopo determinado, todos os pontos | ||
149 | + de injeção receberão a mesma instância de <code>EntityManager</code>. | ||
150 | + </para> | ||
151 | + <para> | ||
152 | + Os valores possíveis são: | ||
153 | + <simplelist type="inline"> | ||
154 | + <member>request</member> | ||
155 | + <member>session</member> | ||
156 | + <member>view</member> | ||
157 | + <member>conversation</member> | ||
158 | + <member>application</member> | ||
159 | + <member>noscope</member> | ||
160 | + </simplelist> | ||
161 | + </para> | ||
162 | + </entry> | ||
163 | + <entry>request</entry> | ||
164 | + </row> | ||
165 | + </tbody> | ||
166 | + </tgroup> | ||
167 | + </informaltable> | ||
168 | + | ||
169 | + <tip> | ||
170 | + <para> | ||
171 | + O escopo especial <emphasis>noscope</emphasis> desliga o gerenciamento de escopo de instâncias de <code>EntityManager</code> | ||
172 | + produzidas pelo Framework Demoiselle. Isso permite ao desenvolvedor controlar totalmente o ciclo de vida de um | ||
173 | + <code>EntityManager</code> injetado e ainda reter o recurso do produtor padrão. | ||
174 | + </para> | ||
175 | + <para> | ||
176 | + Note que ao usar a opção <emphasis>noscope</emphasis>, o desenvolvedor é o responsável por controlar o ciclo de vida do gerenciador | ||
177 | + de persistência. Ele não participará de transações JPA abertas através da anotação <code>@Transactional</code> (transações JTA funcionam normalmente) | ||
178 | + e multiplos pontos de injeção durante uma requisição receberão múltiplas instâncias de <code>EntityManager</code>. | ||
179 | + </para> | ||
180 | + </tip> | ||
181 | + | ||
182 | + <caution> | ||
183 | + <para> | ||
184 | + Deve-se usar cautela ao alterar o escopo padrão das instâncias de <code>EntityManager</code>. Na grande maioria dos casos o escopo | ||
185 | + padrão <emphasis>request</emphasis> é o suficiente e alterar esse padrão deve ser feito apenas após extensa análise dos prós e contras | ||
186 | + de cada escopo. | ||
187 | + </para> | ||
188 | + <para> | ||
189 | + Dê especial atenção aos escopos que podem ser serializados pelo servidor de aplicação (<emphasis>session</emphasis>, <emphasis>view</emphasis> | ||
190 | + e <emphasis>conversation</emphasis>) pois a especificação não define o comportamento de instâncias de <code>EntityManager</code> que são | ||
191 | + serializadas. | ||
192 | + </para> | ||
193 | + </caution> | ||
194 | + </section> | ||
195 | + </section> | ||
21 | 196 | ||
22 | <section> | 197 | <section> |
23 | 198 |
documentation/reference/pt-BR/properties.xml
@@ -251,12 +251,34 @@ | @@ -251,12 +251,34 @@ | ||
251 | <entry>frameworkdemoiselle.​persistence.​default.​unit.​name</entry> | 251 | <entry>frameworkdemoiselle.​persistence.​default.​unit.​name</entry> |
252 | <entry> | 252 | <entry> |
253 | <para> | 253 | <para> |
254 | - Define a unidade de persistência padrão para aplicações que possuem mais | ||
255 | - de um persistence-unit definido no arquivo persistence.xml. | 254 | + Define o nome da unidade de persistência padrão (configurada em <code>persistence.xml</code>) que será injetada |
255 | + caso a anotação <code>@Name</code> não seja usada. Não é necessário se apenas uma unidade de persistência for configurada. | ||
256 | </para> | 256 | </para> |
257 | </entry> | 257 | </entry> |
258 | <entry></entry> | 258 | <entry></entry> |
259 | </row> | 259 | </row> |
260 | + | ||
261 | + <row valign="top"> | ||
262 | + <entry>frameworkdemoiselle.​persistence.​entitymanager.​scope</entry> | ||
263 | + <entry> | ||
264 | + <para> | ||
265 | + Permite determinar o escopo de unidades de persistência injetadas. Dentro do escopo determinado, todos os pontos | ||
266 | + de injeção receberão a mesma instância de <code>EntityManager</code>. | ||
267 | + </para> | ||
268 | + <para> | ||
269 | + Os valores possíveis são: | ||
270 | + <simplelist type="inline"> | ||
271 | + <member>request</member> | ||
272 | + <member>session</member> | ||
273 | + <member>view</member> | ||
274 | + <member>conversation</member> | ||
275 | + <member>application</member> | ||
276 | + <member>noscope</member> | ||
277 | + </simplelist> | ||
278 | + </para> | ||
279 | + </entry> | ||
280 | + <entry>request</entry> | ||
281 | + </row> | ||
260 | </tbody> | 282 | </tbody> |
261 | </tgroup> | 283 | </tgroup> |
262 | </table> | 284 | </table> |
documentation/reference/pt-BR/transacao.xml
@@ -135,7 +135,7 @@ public class AbacaxiException { | @@ -135,7 +135,7 @@ public class AbacaxiException { | ||
135 | <para> | 135 | <para> |
136 | Esta estratégia, que está disponível na extensão <literal>demoiselle-jpa</literal>, delega o | 136 | Esta estratégia, que está disponível na extensão <literal>demoiselle-jpa</literal>, delega o |
137 | controle das transações para o <literal>javax.persistence.EntityManager</literal> da | 137 | controle das transações para o <literal>javax.persistence.EntityManager</literal> da |
138 | - especificação JPA. Você deve escolher esta estratégia quando estiver persisteindo dados | 138 | + especificação JPA. Você deve escolher esta estratégia quando estiver persistindo dados |
139 | com JPA e utilizando apenas uma base de dados em sua aplicação. Como um <literal>EntityManager</literal> | 139 | com JPA e utilizando apenas uma base de dados em sua aplicação. Como um <literal>EntityManager</literal> |
140 | acessa apenas uma unidade de persistência, não há como fazer o controle transacional de unidades distintas. | 140 | acessa apenas uma unidade de persistência, não há como fazer o controle transacional de unidades distintas. |
141 | </para> | 141 | </para> |
impl/core/src/main/java/br/gov/frameworkdemoiselle/internal/context/AbstractCustomContext.java
@@ -36,6 +36,7 @@ | @@ -36,6 +36,7 @@ | ||
36 | */ | 36 | */ |
37 | package br.gov.frameworkdemoiselle.internal.context; | 37 | package br.gov.frameworkdemoiselle.internal.context; |
38 | 38 | ||
39 | +import java.io.Serializable; | ||
39 | import java.lang.annotation.Annotation; | 40 | import java.lang.annotation.Annotation; |
40 | import java.util.Collections; | 41 | import java.util.Collections; |
41 | import java.util.HashMap; | 42 | import java.util.HashMap; |
@@ -193,38 +194,40 @@ public abstract class AbstractCustomContext implements CustomContext { | @@ -193,38 +194,40 @@ public abstract class AbstractCustomContext implements CustomContext { | ||
193 | return true; | 194 | return true; |
194 | } | 195 | } |
195 | 196 | ||
196 | - static class Store { | 197 | + static class Store implements Serializable { |
197 | 198 | ||
198 | - private Map<ClassLoader, Map<Class<?>, Object>> cache = Collections | ||
199 | - .synchronizedMap(new HashMap<ClassLoader, Map<Class<?>, Object>>()); | ||
200 | - | ||
201 | - private Store() { | ||
202 | - } | 199 | + private static final long serialVersionUID = -8237464177510563034L; |
200 | + | ||
201 | + private final String SEPARATOR = "#"; | ||
202 | + | ||
203 | + private Map<String, Object> cache = Collections.synchronizedMap(new HashMap<String, Object>()); | ||
203 | 204 | ||
204 | private boolean contains(final Class<?> type) { | 205 | private boolean contains(final Class<?> type) { |
205 | - return this.getMap().containsKey(type); | 206 | + return cache.containsKey( prefixId(type) ); |
206 | } | 207 | } |
207 | 208 | ||
208 | private Object get(final Class<?> type) { | 209 | private Object get(final Class<?> type) { |
209 | - return this.getMap().get(type); | 210 | + return cache.get( prefixId(type) ); |
210 | } | 211 | } |
211 | 212 | ||
212 | private void put(final Class<?> type, final Object instance) { | 213 | private void put(final Class<?> type, final Object instance) { |
213 | - this.getMap().put(type, instance); | 214 | + cache.put( prefixId(type) , instance); |
214 | } | 215 | } |
215 | 216 | ||
216 | public void clear() { | 217 | public void clear() { |
217 | cache.clear(); | 218 | cache.clear(); |
218 | } | 219 | } |
220 | + | ||
221 | + private String prefixId(Class<?> type){ | ||
222 | + return Thread.currentThread().getContextClassLoader().toString() + SEPARATOR + type.getCanonicalName(); | ||
223 | + } | ||
219 | 224 | ||
220 | - private Map<Class<?>, Object> getMap() { | ||
221 | - ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); | ||
222 | - | 225 | + /*private Map<String, Object> getMap() { |
223 | if (!cache.containsKey(classLoader)) { | 226 | if (!cache.containsKey(classLoader)) { |
224 | cache.put(classLoader, Collections.synchronizedMap(new HashMap<Class<?>, Object>())); | 227 | cache.put(classLoader, Collections.synchronizedMap(new HashMap<Class<?>, Object>())); |
225 | } | 228 | } |
226 | 229 | ||
227 | return cache.get(classLoader); | 230 | return cache.get(classLoader); |
228 | - } | 231 | + }*/ |
229 | } | 232 | } |
230 | } | 233 | } |
impl/core/src/main/java/br/gov/frameworkdemoiselle/internal/context/AbstractStaticContext.java
@@ -37,6 +37,9 @@ | @@ -37,6 +37,9 @@ | ||
37 | package br.gov.frameworkdemoiselle.internal.context; | 37 | package br.gov.frameworkdemoiselle.internal.context; |
38 | 38 | ||
39 | import java.lang.annotation.Annotation; | 39 | import java.lang.annotation.Annotation; |
40 | +import java.util.Collections; | ||
41 | +import java.util.HashMap; | ||
42 | +import java.util.Map; | ||
40 | 43 | ||
41 | import br.gov.frameworkdemoiselle.annotation.Priority; | 44 | import br.gov.frameworkdemoiselle.annotation.Priority; |
42 | import br.gov.frameworkdemoiselle.annotation.StaticScoped; | 45 | import br.gov.frameworkdemoiselle.annotation.StaticScoped; |
@@ -58,7 +61,7 @@ import br.gov.frameworkdemoiselle.configuration.Configuration; | @@ -58,7 +61,7 @@ import br.gov.frameworkdemoiselle.configuration.Configuration; | ||
58 | @Priority(Priority.MIN_PRIORITY) | 61 | @Priority(Priority.MIN_PRIORITY) |
59 | public abstract class AbstractStaticContext extends AbstractCustomContext { | 62 | public abstract class AbstractStaticContext extends AbstractCustomContext { |
60 | 63 | ||
61 | - private final static Store store = createStore(); | 64 | + private final static Map<String, Store> staticStore = Collections.synchronizedMap(new HashMap<String, Store>()); |
62 | 65 | ||
63 | /** | 66 | /** |
64 | * Constructs this context to control the provided scope | 67 | * Constructs this context to control the provided scope |
@@ -69,11 +72,17 @@ public abstract class AbstractStaticContext extends AbstractCustomContext { | @@ -69,11 +72,17 @@ public abstract class AbstractStaticContext extends AbstractCustomContext { | ||
69 | 72 | ||
70 | @Override | 73 | @Override |
71 | protected Store getStore() { | 74 | protected Store getStore() { |
75 | + Store store = staticStore.get( this.getClass().getCanonicalName() ); | ||
76 | + if (store==null){ | ||
77 | + store = createStore(); | ||
78 | + staticStore.put(this.getClass().getCanonicalName(), store); | ||
79 | + } | ||
80 | + | ||
72 | return store; | 81 | return store; |
73 | } | 82 | } |
74 | 83 | ||
75 | @Override | 84 | @Override |
76 | protected boolean isStoreInitialized() { | 85 | protected boolean isStoreInitialized() { |
77 | - return store!=null; | 86 | + return staticStore!=null; |
78 | } | 87 | } |
79 | } | 88 | } |
impl/core/src/main/java/br/gov/frameworkdemoiselle/internal/context/CustomContextProducer.java
@@ -60,6 +60,7 @@ import javax.enterprise.inject.spi.InjectionPoint; | @@ -60,6 +60,7 @@ import javax.enterprise.inject.spi.InjectionPoint; | ||
60 | 60 | ||
61 | import org.slf4j.Logger; | 61 | import org.slf4j.Logger; |
62 | 62 | ||
63 | +import br.gov.frameworkdemoiselle.annotation.Priority; | ||
63 | import br.gov.frameworkdemoiselle.context.ConversationContext; | 64 | import br.gov.frameworkdemoiselle.context.ConversationContext; |
64 | import br.gov.frameworkdemoiselle.context.CustomContext; | 65 | import br.gov.frameworkdemoiselle.context.CustomContext; |
65 | import br.gov.frameworkdemoiselle.context.RequestContext; | 66 | import br.gov.frameworkdemoiselle.context.RequestContext; |
@@ -133,7 +134,7 @@ public class CustomContextProducer { | @@ -133,7 +134,7 @@ public class CustomContextProducer { | ||
133 | /////////////PRODUCERS/////////////////// | 134 | /////////////PRODUCERS/////////////////// |
134 | 135 | ||
135 | @Produces | 136 | @Produces |
136 | - public RequestContext getRequestContext(InjectionPoint ip){ | 137 | + protected RequestContext getRequestContext(InjectionPoint ip){ |
137 | if (ip!=null){ | 138 | if (ip!=null){ |
138 | return getContext(ip); | 139 | return getContext(ip); |
139 | } | 140 | } |
@@ -143,7 +144,7 @@ public class CustomContextProducer { | @@ -143,7 +144,7 @@ public class CustomContextProducer { | ||
143 | } | 144 | } |
144 | 145 | ||
145 | @Produces | 146 | @Produces |
146 | - public SessionContext getSessionContext(InjectionPoint ip){ | 147 | + protected SessionContext getSessionContext(InjectionPoint ip){ |
147 | if (ip!=null){ | 148 | if (ip!=null){ |
148 | return getContext(ip); | 149 | return getContext(ip); |
149 | } | 150 | } |
@@ -153,7 +154,7 @@ public class CustomContextProducer { | @@ -153,7 +154,7 @@ public class CustomContextProducer { | ||
153 | } | 154 | } |
154 | 155 | ||
155 | @Produces | 156 | @Produces |
156 | - public ViewContext getViewContext(InjectionPoint ip){ | 157 | + protected ViewContext getViewContext(InjectionPoint ip){ |
157 | if (ip!=null){ | 158 | if (ip!=null){ |
158 | return getContext(ip); | 159 | return getContext(ip); |
159 | } | 160 | } |
@@ -163,7 +164,7 @@ public class CustomContextProducer { | @@ -163,7 +164,7 @@ public class CustomContextProducer { | ||
163 | } | 164 | } |
164 | 165 | ||
165 | @Produces | 166 | @Produces |
166 | - public StaticContext getStaticContext(InjectionPoint ip){ | 167 | + protected StaticContext getStaticContext(InjectionPoint ip){ |
167 | if (ip!=null){ | 168 | if (ip!=null){ |
168 | return getContext(ip); | 169 | return getContext(ip); |
169 | } | 170 | } |
@@ -173,7 +174,7 @@ public class CustomContextProducer { | @@ -173,7 +174,7 @@ public class CustomContextProducer { | ||
173 | } | 174 | } |
174 | 175 | ||
175 | @Produces | 176 | @Produces |
176 | - public ConversationContext getConversationContext(InjectionPoint ip){ | 177 | + protected ConversationContext getConversationContext(InjectionPoint ip){ |
177 | if (ip!=null){ | 178 | if (ip!=null){ |
178 | return getContext(ip); | 179 | return getContext(ip); |
179 | } | 180 | } |
@@ -184,8 +185,17 @@ public class CustomContextProducer { | @@ -184,8 +185,17 @@ public class CustomContextProducer { | ||
184 | 185 | ||
185 | /////////////END OF PRODUCERS/////////////////// | 186 | /////////////END OF PRODUCERS/////////////////// |
186 | 187 | ||
188 | + /** | ||
189 | + * Obtain a custom context for the provided injection point. | ||
190 | + * | ||
191 | + * @param ip The object containing information about the injection point - most importantly | ||
192 | + * the declared type of the injection point, to decide the context to return | ||
193 | + * | ||
194 | + * @return A context of a type compatible with the type of the injection point, or <code>null</code> if there is | ||
195 | + * no such context. | ||
196 | + */ | ||
187 | @SuppressWarnings("unchecked") | 197 | @SuppressWarnings("unchecked") |
188 | - private <T extends CustomContext> T getContext(InjectionPoint ip){ | 198 | + public <T extends CustomContext> T getContext(InjectionPoint ip){ |
189 | T producedContext = null; | 199 | T producedContext = null; |
190 | 200 | ||
191 | if (ip!=null){ | 201 | if (ip!=null){ |
@@ -200,8 +210,16 @@ public class CustomContextProducer { | @@ -200,8 +210,16 @@ public class CustomContextProducer { | ||
200 | return producedContext; | 210 | return producedContext; |
201 | } | 211 | } |
202 | 212 | ||
213 | + /** | ||
214 | + * Obtain a context compatible with the provided type. | ||
215 | + * | ||
216 | + * @param contextClass The type of the desired context. The returned context will be compatible with this type, if there | ||
217 | + * is more than one compatible type, this method will decide witch one to return based on the {@link Priority} annotation. | ||
218 | + * | ||
219 | + * @return A context of a type compatible with the informed type, or <code>null</code> if there is no such context. | ||
220 | + */ | ||
203 | @SuppressWarnings("unchecked") | 221 | @SuppressWarnings("unchecked") |
204 | - private <T extends CustomContext> T getContext(Class<T> contextClass){ | 222 | + public <T extends CustomContext> T getContext(Class<T> contextClass){ |
205 | CustomContext producedContext = null; | 223 | CustomContext producedContext = null; |
206 | 224 | ||
207 | ArrayList<CustomContext> selectableContexts = new ArrayList<CustomContext>(); | 225 | ArrayList<CustomContext> selectableContexts = new ArrayList<CustomContext>(); |
impl/core/src/test/java/context/staticcontext/ConversationBean.java
0 → 100644
@@ -0,0 +1,25 @@ | @@ -0,0 +1,25 @@ | ||
1 | +package context.staticcontext; | ||
2 | + | ||
3 | +import javax.enterprise.context.ConversationScoped; | ||
4 | +import java.io.Serializable; | ||
5 | + | ||
6 | +@ConversationScoped | ||
7 | +public class ConversationBean implements Serializable { | ||
8 | + | ||
9 | + private static final long serialVersionUID = 1L; | ||
10 | + | ||
11 | + private String data = "test"; | ||
12 | + | ||
13 | + | ||
14 | + public String getData() { | ||
15 | + return data; | ||
16 | + } | ||
17 | + | ||
18 | + | ||
19 | + public void setData(String data) { | ||
20 | + this.data = data; | ||
21 | + } | ||
22 | + | ||
23 | + | ||
24 | + | ||
25 | +} |
impl/core/src/test/java/context/staticcontext/SessionBean.java
0 → 100644
@@ -0,0 +1,26 @@ | @@ -0,0 +1,26 @@ | ||
1 | +package context.staticcontext; | ||
2 | + | ||
3 | +import java.io.Serializable; | ||
4 | + | ||
5 | +import javax.enterprise.context.SessionScoped; | ||
6 | + | ||
7 | +@SessionScoped | ||
8 | +public class SessionBean implements Serializable{ | ||
9 | + | ||
10 | + private static final long serialVersionUID = 1L; | ||
11 | + | ||
12 | + private String data = "test"; | ||
13 | + | ||
14 | + | ||
15 | + public String getData() { | ||
16 | + return data; | ||
17 | + } | ||
18 | + | ||
19 | + | ||
20 | + public void setData(String data) { | ||
21 | + this.data = data; | ||
22 | + } | ||
23 | + | ||
24 | + | ||
25 | + | ||
26 | +} |
impl/core/src/test/java/context/staticcontext/StaticContextTest.java
0 → 100644
@@ -0,0 +1,88 @@ | @@ -0,0 +1,88 @@ | ||
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 context.staticcontext; | ||
38 | + | ||
39 | +import javax.enterprise.inject.spi.Bean; | ||
40 | + | ||
41 | +import org.jboss.arquillian.container.test.api.Deployment; | ||
42 | +import org.jboss.arquillian.junit.Arquillian; | ||
43 | +import org.jboss.shrinkwrap.api.spec.JavaArchive; | ||
44 | +import org.junit.Assert; | ||
45 | +import org.junit.Test; | ||
46 | +import org.junit.runner.RunWith; | ||
47 | + | ||
48 | +import br.gov.frameworkdemoiselle.context.ConversationContext; | ||
49 | +import br.gov.frameworkdemoiselle.context.SessionContext; | ||
50 | +import br.gov.frameworkdemoiselle.util.Beans; | ||
51 | +import test.Tests; | ||
52 | + | ||
53 | +@RunWith(Arquillian.class) | ||
54 | +public class StaticContextTest { | ||
55 | + | ||
56 | + @Deployment | ||
57 | + public static JavaArchive createDeployment() { | ||
58 | + JavaArchive deployment = Tests.createDeployment(StaticContextTest.class); | ||
59 | + return deployment; | ||
60 | + } | ||
61 | + | ||
62 | + @Test | ||
63 | + public void checkSeparatedStores(){ | ||
64 | + | ||
65 | + ConversationContext conversationContext = Beans.getReference(ConversationContext.class); | ||
66 | + SessionContext sessionContext = Beans.getReference(SessionContext.class); | ||
67 | + | ||
68 | + conversationContext.activate(); | ||
69 | + sessionContext.activate(); | ||
70 | + | ||
71 | + ConversationBean conversationBean = Beans.getReference(ConversationBean.class); | ||
72 | + conversationBean.getData(); | ||
73 | + | ||
74 | + SessionBean sessionBean = Beans.getReference(SessionBean.class); | ||
75 | + sessionBean.getData(); | ||
76 | + | ||
77 | + Bean<?> conversationContextual = Beans.getBeanManager().getBeans(ConversationBean.class).iterator().next(); | ||
78 | + Bean<?> sessionContextual = Beans.getBeanManager().getBeans(SessionBean.class).iterator().next(); | ||
79 | + | ||
80 | + Assert.assertNotNull( conversationContext.get(conversationContextual) ); | ||
81 | + Assert.assertNull( conversationContext.get(sessionContextual) ); | ||
82 | + | ||
83 | + Assert.assertNotNull( sessionContext.get(sessionContextual) ); | ||
84 | + Assert.assertNull( sessionContext.get(conversationContextual) ); | ||
85 | + | ||
86 | + } | ||
87 | + | ||
88 | +} |
impl/extension/jpa/src/main/java/br/gov/frameworkdemoiselle/internal/producer/AbstractEntityManagerStore.java
@@ -41,13 +41,11 @@ import java.util.HashMap; | @@ -41,13 +41,11 @@ import java.util.HashMap; | ||
41 | import java.util.Map; | 41 | import java.util.Map; |
42 | 42 | ||
43 | import javax.enterprise.context.RequestScoped; | 43 | import javax.enterprise.context.RequestScoped; |
44 | -import javax.inject.Inject; | ||
45 | import javax.persistence.EntityManager; | 44 | import javax.persistence.EntityManager; |
46 | import javax.persistence.FlushModeType; | 45 | import javax.persistence.FlushModeType; |
47 | 46 | ||
48 | import org.slf4j.Logger; | 47 | import org.slf4j.Logger; |
49 | 48 | ||
50 | -import br.gov.frameworkdemoiselle.annotation.Name; | ||
51 | import br.gov.frameworkdemoiselle.internal.configuration.EntityManagerConfig; | 49 | import br.gov.frameworkdemoiselle.internal.configuration.EntityManagerConfig; |
52 | import br.gov.frameworkdemoiselle.internal.configuration.EntityManagerConfig.EntityManagerScope; | 50 | import br.gov.frameworkdemoiselle.internal.configuration.EntityManagerConfig.EntityManagerScope; |
53 | import br.gov.frameworkdemoiselle.util.Beans; | 51 | import br.gov.frameworkdemoiselle.util.Beans; |
@@ -74,19 +72,6 @@ public abstract class AbstractEntityManagerStore implements EntityManagerStore { | @@ -74,19 +72,6 @@ public abstract class AbstractEntityManagerStore implements EntityManagerStore { | ||
74 | 72 | ||
75 | private final Map<String, EntityManager> cache = Collections.synchronizedMap(new HashMap<String, EntityManager>()); | 73 | private final Map<String, EntityManager> cache = Collections.synchronizedMap(new HashMap<String, EntityManager>()); |
76 | 74 | ||
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) { | 75 | public EntityManager getEntityManager(String persistenceUnit) { |
91 | EntityManager entityManager = null; | 76 | EntityManager entityManager = null; |
92 | 77 | ||
@@ -114,6 +99,7 @@ public abstract class AbstractEntityManagerStore implements EntityManagerStore { | @@ -114,6 +99,7 @@ public abstract class AbstractEntityManagerStore implements EntityManagerStore { | ||
114 | //Se o produtor não possui escopo, então o ciclo de vida | 99 | //Se o produtor não possui escopo, então o ciclo de vida |
115 | //de EntityManager produzidos é responsabilidade do desenvolvedor. Não | 100 | //de EntityManager produzidos é responsabilidade do desenvolvedor. Não |
116 | //fechamos os EntityManagers aqui. | 101 | //fechamos os EntityManagers aqui. |
102 | + EntityManagerConfig configuration = getConfiguration(); | ||
117 | if (configuration.getEntityManagerScope() != EntityManagerScope.NOSCOPE){ | 103 | if (configuration.getEntityManagerScope() != EntityManagerScope.NOSCOPE){ |
118 | for (EntityManager entityManager : cache.values()) { | 104 | for (EntityManager entityManager : cache.values()) { |
119 | entityManager.close(); | 105 | entityManager.close(); |
@@ -131,23 +117,18 @@ public abstract class AbstractEntityManagerStore implements EntityManagerStore { | @@ -131,23 +117,18 @@ public abstract class AbstractEntityManagerStore implements EntityManagerStore { | ||
131 | } | 117 | } |
132 | 118 | ||
133 | private EntityManagerFactoryProducer getFactory(){ | 119 | private EntityManagerFactoryProducer getFactory(){ |
134 | - if (factory==null){ | ||
135 | - factory = Beans.getReference(EntityManagerFactoryProducer.class); | ||
136 | - } | ||
137 | - return factory; | 120 | + return Beans.getReference(EntityManagerFactoryProducer.class); |
138 | } | 121 | } |
139 | 122 | ||
140 | private Logger getLogger(){ | 123 | private Logger getLogger(){ |
141 | - if (logger==null){ | ||
142 | - logger = Beans.getReference(Logger.class); | ||
143 | - } | ||
144 | - return logger; | 124 | + return Beans.getReference(Logger.class); |
145 | } | 125 | } |
146 | 126 | ||
147 | private ResourceBundle getBundle(){ | 127 | private ResourceBundle getBundle(){ |
148 | - if (bundle==null){ | ||
149 | - bundle = Beans.getReference(ResourceBundle.class , new NameQualifier("demoiselle-jpa-bundle")); | ||
150 | - } | ||
151 | - return bundle; | 128 | + return Beans.getReference(ResourceBundle.class , new NameQualifier("demoiselle-jpa-bundle")); |
129 | + } | ||
130 | + | ||
131 | + private EntityManagerConfig getConfiguration(){ | ||
132 | + return Beans.getReference(EntityManagerConfig.class); | ||
152 | } | 133 | } |
153 | } | 134 | } |
impl/extension/jpa/src/main/java/br/gov/frameworkdemoiselle/internal/proxy/EntityManagerProxy.java
@@ -117,8 +117,8 @@ public class EntityManagerProxy implements EntityManager, Serializable { | @@ -117,8 +117,8 @@ public class EntityManagerProxy implements EntityManager, Serializable { | ||
117 | @Override | 117 | @Override |
118 | public void persist(Object entity) { | 118 | public void persist(Object entity) { |
119 | joinTransactionIfNecessary(); | 119 | joinTransactionIfNecessary(); |
120 | - checkEntityManagerScopePassivable(entity); | ||
121 | getEntityManagerDelegate().persist(entity); | 120 | getEntityManagerDelegate().persist(entity); |
121 | + checkEntityManagerScopePassivable(entity); | ||
122 | } | 122 | } |
123 | 123 | ||
124 | /* | 124 | /* |