Commit 9f3eff34910cb89943b4ded1c5defb349a98e562

Authored by Dancovich
1 parent 1267e2a2
Exists in master

Implementando fix para bug que impede a serialização de beans presentes

nos contextos personalizados, devido ao uso de ClassLoader como chave do
mapa interno dos contextos.
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;
@@ -156,8 +157,8 @@ public abstract class AbstractCustomContext implements CustomContext { @@ -156,8 +157,8 @@ public abstract class AbstractCustomContext implements CustomContext {
156 return this.scope; 157 return this.scope;
157 } 158 }
158 159
159 - protected static Store createStore() {  
160 - return new Store(); 160 + protected static Store createStore(Class<?> owningClass) {
  161 + return new Store(owningClass);
161 } 162 }
162 163
163 private ResourceBundle getBundle(){ 164 private ResourceBundle getBundle(){
@@ -193,38 +194,47 @@ public abstract class AbstractCustomContext implements CustomContext { @@ -193,38 +194,47 @@ 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>>()); 199 + private static final long serialVersionUID = -8237464177510563034L;
  200 +
  201 + private final String SEPARATOR = "#";
  202 +
  203 + private final String ID_PREFIX;
  204 +
  205 + private Map<String, Object> cache = Collections.synchronizedMap(new HashMap<String, Object>());
200 206
201 - private Store() { 207 + private Store(Class<?> owningClass) {
  208 + ID_PREFIX = Thread.currentThread().getContextClassLoader().toString()
  209 + + SEPARATOR + owningClass.getCanonicalName();
202 } 210 }
203 211
204 private boolean contains(final Class<?> type) { 212 private boolean contains(final Class<?> type) {
205 - return this.getMap().containsKey(type); 213 + return cache.containsKey( prefixId(type.getCanonicalName()) );
206 } 214 }
207 215
208 private Object get(final Class<?> type) { 216 private Object get(final Class<?> type) {
209 - return this.getMap().get(type); 217 + return cache.get( prefixId(type.getCanonicalName()) );
210 } 218 }
211 219
212 private void put(final Class<?> type, final Object instance) { 220 private void put(final Class<?> type, final Object instance) {
213 - this.getMap().put(type, instance); 221 + cache.put( prefixId(type.getCanonicalName()) , instance);
214 } 222 }
215 223
216 public void clear() { 224 public void clear() {
217 cache.clear(); 225 cache.clear();
218 } 226 }
  227 +
  228 + private String prefixId(String id){
  229 + return ID_PREFIX + SEPARATOR + id;
  230 + }
219 231
220 - private Map<Class<?>, Object> getMap() {  
221 - ClassLoader classLoader = Thread.currentThread().getContextClassLoader();  
222 - 232 + /*private Map<String, Object> getMap() {
223 if (!cache.containsKey(classLoader)) { 233 if (!cache.containsKey(classLoader)) {
224 cache.put(classLoader, Collections.synchronizedMap(new HashMap<Class<?>, Object>())); 234 cache.put(classLoader, Collections.synchronizedMap(new HashMap<Class<?>, Object>()));
225 } 235 }
226 236
227 return cache.get(classLoader); 237 return cache.get(classLoader);
228 - } 238 + }*/
229 } 239 }
230 } 240 }
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 static Map<String, Store> cache = 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,16 @@ public abstract class AbstractStaticContext extends AbstractCustomContext { @@ -69,11 +72,16 @@ public abstract class AbstractStaticContext extends AbstractCustomContext {
69 72
70 @Override 73 @Override
71 protected Store getStore() { 74 protected Store getStore() {
  75 + Store store = cache.get( this.getClass().getCanonicalName() );
  76 + if ( store==null ){
  77 + store = createStore(this.getClass());
  78 + cache.put(this.getClass().getCanonicalName(), store);
  79 + }
72 return store; 80 return store;
73 } 81 }
74 82
75 @Override 83 @Override
76 protected boolean isStoreInitialized() { 84 protected boolean isStoreInitialized() {
77 - return store!=null; 85 + return cache.get( this.getClass().getCanonicalName() )!=null;
78 } 86 }
79 } 87 }
impl/core/src/main/java/br/gov/frameworkdemoiselle/internal/context/AbstractThreadLocalContext.java
@@ -73,7 +73,7 @@ public abstract class AbstractThreadLocalContext extends AbstractCustomContext { @@ -73,7 +73,7 @@ public abstract class AbstractThreadLocalContext extends AbstractCustomContext {
73 @Override 73 @Override
74 protected Store getStore() { 74 protected Store getStore() {
75 if (this.threadLocal.get() == null) { 75 if (this.threadLocal.get() == null) {
76 - this.threadLocal.set(createStore()); 76 + this.threadLocal.set(createStore(getClass()));
77 } 77 }
78 78
79 return this.threadLocal.get(); 79 return this.threadLocal.get();
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/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 /*
impl/extension/jsf/src/main/java/br/gov/frameworkdemoiselle/internal/context/FacesViewContextImpl.java
@@ -75,7 +75,7 @@ public class FacesViewContextImpl extends AbstractCustomContext implements ViewC @@ -75,7 +75,7 @@ public class FacesViewContextImpl extends AbstractCustomContext implements ViewC
75 String key = Store.class.getName(); 75 String key = Store.class.getName();
76 76
77 if (!viewMap.containsKey(key)) { 77 if (!viewMap.containsKey(key)) {
78 - viewMap.put(key, createStore()); 78 + viewMap.put(key, createStore( getClass() ));
79 } 79 }
80 80
81 return (Store) viewMap.get(key); 81 return (Store) viewMap.get(key);