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 36 */
37 37 package br.gov.frameworkdemoiselle.internal.context;
38 38  
  39 +import java.io.Serializable;
39 40 import java.lang.annotation.Annotation;
40 41 import java.util.Collections;
41 42 import java.util.HashMap;
... ... @@ -156,8 +157,8 @@ public abstract class AbstractCustomContext implements CustomContext {
156 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 164 private ResourceBundle getBundle(){
... ... @@ -193,38 +194,47 @@ public abstract class AbstractCustomContext implements CustomContext {
193 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 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 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 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 224 public void clear() {
217 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 233 if (!cache.containsKey(classLoader)) {
224 234 cache.put(classLoader, Collections.synchronizedMap(new HashMap<Class<?>, Object>()));
225 235 }
226 236  
227 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 37 package br.gov.frameworkdemoiselle.internal.context;
38 38  
39 39 import java.lang.annotation.Annotation;
  40 +import java.util.Collections;
  41 +import java.util.HashMap;
  42 +import java.util.Map;
40 43  
41 44 import br.gov.frameworkdemoiselle.annotation.Priority;
42 45 import br.gov.frameworkdemoiselle.annotation.StaticScoped;
... ... @@ -58,7 +61,7 @@ import br.gov.frameworkdemoiselle.configuration.Configuration;
58 61 @Priority(Priority.MIN_PRIORITY)
59 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 67 * Constructs this context to control the provided scope
... ... @@ -69,11 +72,16 @@ public abstract class AbstractStaticContext extends AbstractCustomContext {
69 72  
70 73 @Override
71 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 80 return store;
73 81 }
74 82  
75 83 @Override
76 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 73 @Override
74 74 protected Store getStore() {
75 75 if (this.threadLocal.get() == null) {
76   - this.threadLocal.set(createStore());
  76 + this.threadLocal.set(createStore(getClass()));
77 77 }
78 78  
79 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 60  
61 61 import org.slf4j.Logger;
62 62  
  63 +import br.gov.frameworkdemoiselle.annotation.Priority;
63 64 import br.gov.frameworkdemoiselle.context.ConversationContext;
64 65 import br.gov.frameworkdemoiselle.context.CustomContext;
65 66 import br.gov.frameworkdemoiselle.context.RequestContext;
... ... @@ -133,7 +134,7 @@ public class CustomContextProducer {
133 134 /////////////PRODUCERS///////////////////
134 135  
135 136 @Produces
136   - public RequestContext getRequestContext(InjectionPoint ip){
  137 + protected RequestContext getRequestContext(InjectionPoint ip){
137 138 if (ip!=null){
138 139 return getContext(ip);
139 140 }
... ... @@ -143,7 +144,7 @@ public class CustomContextProducer {
143 144 }
144 145  
145 146 @Produces
146   - public SessionContext getSessionContext(InjectionPoint ip){
  147 + protected SessionContext getSessionContext(InjectionPoint ip){
147 148 if (ip!=null){
148 149 return getContext(ip);
149 150 }
... ... @@ -153,7 +154,7 @@ public class CustomContextProducer {
153 154 }
154 155  
155 156 @Produces
156   - public ViewContext getViewContext(InjectionPoint ip){
  157 + protected ViewContext getViewContext(InjectionPoint ip){
157 158 if (ip!=null){
158 159 return getContext(ip);
159 160 }
... ... @@ -163,7 +164,7 @@ public class CustomContextProducer {
163 164 }
164 165  
165 166 @Produces
166   - public StaticContext getStaticContext(InjectionPoint ip){
  167 + protected StaticContext getStaticContext(InjectionPoint ip){
167 168 if (ip!=null){
168 169 return getContext(ip);
169 170 }
... ... @@ -173,7 +174,7 @@ public class CustomContextProducer {
173 174 }
174 175  
175 176 @Produces
176   - public ConversationContext getConversationContext(InjectionPoint ip){
  177 + protected ConversationContext getConversationContext(InjectionPoint ip){
177 178 if (ip!=null){
178 179 return getContext(ip);
179 180 }
... ... @@ -184,8 +185,17 @@ public class CustomContextProducer {
184 185  
185 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 197 @SuppressWarnings("unchecked")
188   - private <T extends CustomContext> T getContext(InjectionPoint ip){
  198 + public <T extends CustomContext> T getContext(InjectionPoint ip){
189 199 T producedContext = null;
190 200  
191 201 if (ip!=null){
... ... @@ -200,8 +210,16 @@ public class CustomContextProducer {
200 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 221 @SuppressWarnings("unchecked")
204   - private <T extends CustomContext> T getContext(Class<T> contextClass){
  222 + public <T extends CustomContext> T getContext(Class<T> contextClass){
205 223 CustomContext producedContext = null;
206 224  
207 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 41 import java.util.Map;
42 42  
43 43 import javax.enterprise.context.RequestScoped;
44   -import javax.inject.Inject;
45 44 import javax.persistence.EntityManager;
46 45 import javax.persistence.FlushModeType;
47 46  
48 47 import org.slf4j.Logger;
49 48  
50   -import br.gov.frameworkdemoiselle.annotation.Name;
51 49 import br.gov.frameworkdemoiselle.internal.configuration.EntityManagerConfig;
52 50 import br.gov.frameworkdemoiselle.internal.configuration.EntityManagerConfig.EntityManagerScope;
53 51 import br.gov.frameworkdemoiselle.util.Beans;
... ... @@ -74,19 +72,6 @@ public abstract class AbstractEntityManagerStore implements EntityManagerStore {
74 72  
75 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 75 public EntityManager getEntityManager(String persistenceUnit) {
91 76 EntityManager entityManager = null;
92 77  
... ... @@ -114,6 +99,7 @@ public abstract class AbstractEntityManagerStore implements EntityManagerStore {
114 99 //Se o produtor não possui escopo, então o ciclo de vida
115 100 //de EntityManager produzidos é responsabilidade do desenvolvedor. Não
116 101 //fechamos os EntityManagers aqui.
  102 + EntityManagerConfig configuration = getConfiguration();
117 103 if (configuration.getEntityManagerScope() != EntityManagerScope.NOSCOPE){
118 104 for (EntityManager entityManager : cache.values()) {
119 105 entityManager.close();
... ... @@ -131,23 +117,18 @@ public abstract class AbstractEntityManagerStore implements EntityManagerStore {
131 117 }
132 118  
133 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 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 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 117 @Override
118 118 public void persist(Object entity) {
119 119 joinTransactionIfNecessary();
120   - checkEntityManagerScopePassivable(entity);
121 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 75 String key = Store.class.getName();
76 76  
77 77 if (!viewMap.containsKey(key)) {
78   - viewMap.put(key, createStore());
  78 + viewMap.put(key, createStore( getClass() ));
79 79 }
80 80  
81 81 return (Store) viewMap.get(key);
... ...