diff --git a/impl/core/src/main/java/br/gov/frameworkdemoiselle/internal/bootstrap/CustomContextBootstrap.java b/impl/core/src/main/java/br/gov/frameworkdemoiselle/internal/bootstrap/CustomContextBootstrap.java index eddc6ff..846c706 100644 --- a/impl/core/src/main/java/br/gov/frameworkdemoiselle/internal/bootstrap/CustomContextBootstrap.java +++ b/impl/core/src/main/java/br/gov/frameworkdemoiselle/internal/bootstrap/CustomContextBootstrap.java @@ -15,6 +15,7 @@ import br.gov.frameworkdemoiselle.internal.context.TemporarySessionContextImpl; import br.gov.frameworkdemoiselle.internal.context.StaticContextImpl; import br.gov.frameworkdemoiselle.internal.context.TemporaryConversationContextImpl; import br.gov.frameworkdemoiselle.internal.context.TemporaryViewContextImpl; +import br.gov.frameworkdemoiselle.lifecycle.AfterShutdownProccess; /** * This portable extension registers and starts custom contexts used by @@ -71,13 +72,17 @@ public class CustomContextBootstrap implements Extension{ } } + public void terminateContexts(@Observes AfterShutdownProccess event){ + if (contexts!=null){ + for (CustomContext context : contexts){ + context.deactivate(); + } + + contexts.clear(); + } + } + public List getCustomContexts(){ return this.contexts; } - - /*public void storeContexts(@Observes AfterDeploymentValidation event){ - CustomContextProducer producer = Beans.getReference(CustomContextProducer.class); - producer.addRegisteredContexts(contexts); - }*/ - } diff --git a/impl/core/src/main/java/br/gov/frameworkdemoiselle/internal/context/AbstractCustomContext.java b/impl/core/src/main/java/br/gov/frameworkdemoiselle/internal/context/AbstractCustomContext.java index 51146fb..f713f1e 100644 --- a/impl/core/src/main/java/br/gov/frameworkdemoiselle/internal/context/AbstractCustomContext.java +++ b/impl/core/src/main/java/br/gov/frameworkdemoiselle/internal/context/AbstractCustomContext.java @@ -37,16 +37,12 @@ package br.gov.frameworkdemoiselle.internal.context; import java.lang.annotation.Annotation; -import java.util.Collections; -import java.util.HashMap; import java.util.Locale; -import java.util.Map; import javax.enterprise.context.ContextNotActiveException; import javax.enterprise.context.spi.Context; import javax.enterprise.context.spi.Contextual; import javax.enterprise.context.spi.CreationalContext; -import javax.enterprise.inject.spi.Bean; import javax.enterprise.inject.spi.BeanManager; import org.slf4j.Logger; @@ -71,7 +67,9 @@ public abstract class AbstractCustomContext implements CustomContext { this.active = false; } - protected abstract Store getStore(); + protected abstract BeanStore getStore(); + + protected abstract ContextualStore getContextualStore(); protected abstract boolean isStoreInitialized(); @@ -89,22 +87,22 @@ public abstract class AbstractCustomContext implements CustomContext { throw new ContextNotActiveException(); } - Class type = getType(contextual); - if (getStore().contains(type)) { - instance = (T) getStore().get(type); - - } else if (creationalContext != null) { + String id = getContextualStore().tryRegisterAndGetId(contextual); + if (getStore().contains(id)) { + instance = (T) getStore().getInstance(id); + } + else if (creationalContext!=null){ instance = contextual.create(creationalContext); - getStore().put(type, instance); + getStore().put(id, instance,creationalContext); } return instance; } - private Class getType(final Contextual contextual) { + /*private Class getType(final Contextual contextual) { Bean bean = (Bean) contextual; return bean.getBeanClass(); - } + }*/ @Override public boolean isActive() { @@ -136,15 +134,27 @@ public abstract class AbstractCustomContext implements CustomContext { return this.active; } + @SuppressWarnings({ "rawtypes", "unchecked" }) @Override public void deactivate(){ if (this.active){ if (isStoreInitialized()){ + for (String id : getStore()){ + Contextual contextual = getContextualStore().getContextual(id); + Object instance = getStore().getInstance(id); + CreationalContext creationalContext = getStore().getCreationalContext(id); + + if (contextual!=null && instance!=null){ + contextual.destroy(instance, creationalContext); + } + } + getStore().clear(); + getContextualStore().clear(); } - + this.active = false; - + Logger logger = getLogger(); ResourceBundle bundle = getBundle(); logger.debug( bundle.getString("custom-context-was-deactivated" , this.getClass().getCanonicalName() , this.getScope().getSimpleName() ) ); @@ -156,8 +166,12 @@ public abstract class AbstractCustomContext implements CustomContext { return this.scope; } - protected static Store createStore() { - return new Store(); + protected static BeanStore createStore() { + return new BeanStore(); + } + + protected static ContextualStore createContextualStore() { + return new ContextualStore(); } private ResourceBundle getBundle(){ @@ -192,39 +206,4 @@ public abstract class AbstractCustomContext implements CustomContext { return false; return true; } - - static class Store { - - private Map, Object>> cache = Collections - .synchronizedMap(new HashMap, Object>>()); - - private Store() { - } - - private boolean contains(final Class type) { - return this.getMap().containsKey(type); - } - - private Object get(final Class type) { - return this.getMap().get(type); - } - - private void put(final Class type, final Object instance) { - this.getMap().put(type, instance); - } - - public void clear() { - cache.clear(); - } - - private Map, Object> getMap() { - ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); - - if (!cache.containsKey(classLoader)) { - cache.put(classLoader, Collections.synchronizedMap(new HashMap, Object>())); - } - - return cache.get(classLoader); - } - } } diff --git a/impl/core/src/main/java/br/gov/frameworkdemoiselle/internal/context/AbstractStaticContext.java b/impl/core/src/main/java/br/gov/frameworkdemoiselle/internal/context/AbstractStaticContext.java index c5b2320..773884c 100644 --- a/impl/core/src/main/java/br/gov/frameworkdemoiselle/internal/context/AbstractStaticContext.java +++ b/impl/core/src/main/java/br/gov/frameworkdemoiselle/internal/context/AbstractStaticContext.java @@ -61,7 +61,9 @@ import br.gov.frameworkdemoiselle.configuration.Configuration; @Priority(Priority.MIN_PRIORITY) public abstract class AbstractStaticContext extends AbstractCustomContext { - private final static Map staticStore = Collections.synchronizedMap(new HashMap()); + private final static Map staticBeanStore = Collections.synchronizedMap(new HashMap()); + + private final static Map staticContextualStore = Collections.synchronizedMap(new HashMap()); /** * Constructs this context to control the provided scope @@ -71,11 +73,22 @@ public abstract class AbstractStaticContext extends AbstractCustomContext { } @Override - protected Store getStore() { - Store store = staticStore.get( this.getClass().getCanonicalName() ); + protected BeanStore getStore() { + BeanStore store = staticBeanStore.get( this.getClass().getCanonicalName() ); if (store==null){ store = createStore(); - staticStore.put(this.getClass().getCanonicalName(), store); + staticBeanStore.put(this.getClass().getCanonicalName(), store); + } + + return store; + } + + @Override + protected ContextualStore getContextualStore() { + ContextualStore store = staticContextualStore.get( this.getClass().getCanonicalName() ); + if (store==null){ + store = createContextualStore(); + staticContextualStore.put(this.getClass().getCanonicalName(), store); } return store; @@ -83,6 +96,6 @@ public abstract class AbstractStaticContext extends AbstractCustomContext { @Override protected boolean isStoreInitialized() { - return staticStore!=null; + return staticBeanStore!=null; } } diff --git a/impl/core/src/main/java/br/gov/frameworkdemoiselle/internal/context/AbstractThreadLocalContext.java b/impl/core/src/main/java/br/gov/frameworkdemoiselle/internal/context/AbstractThreadLocalContext.java index 67958e9..bb67f5c 100644 --- a/impl/core/src/main/java/br/gov/frameworkdemoiselle/internal/context/AbstractThreadLocalContext.java +++ b/impl/core/src/main/java/br/gov/frameworkdemoiselle/internal/context/AbstractThreadLocalContext.java @@ -59,7 +59,9 @@ import java.lang.annotation.Annotation; */ public abstract class AbstractThreadLocalContext extends AbstractCustomContext { - private final ThreadLocal threadLocal = new ThreadLocal(); + private final ThreadLocal threadLocalBeans = new ThreadLocal(); + + private final ThreadLocal threadLocalContextual = new ThreadLocal(); AbstractThreadLocalContext(final Class scope) { super(scope); @@ -67,15 +69,24 @@ public abstract class AbstractThreadLocalContext extends AbstractCustomContext { @Override protected boolean isStoreInitialized() { - return threadLocal.get()!=null; + return threadLocalBeans.get()!=null; } @Override - protected Store getStore() { - if (this.threadLocal.get() == null) { - this.threadLocal.set(createStore()); + protected BeanStore getStore() { + if (this.threadLocalBeans.get() == null) { + this.threadLocalBeans.set(createStore()); + } + + return this.threadLocalBeans.get(); + } + + @Override + protected ContextualStore getContextualStore() { + if (this.threadLocalContextual.get() == null) { + this.threadLocalContextual.set(createContextualStore()); } - return this.threadLocal.get(); + return this.threadLocalContextual.get(); } } diff --git a/impl/core/src/main/java/br/gov/frameworkdemoiselle/internal/context/BeanStore.java b/impl/core/src/main/java/br/gov/frameworkdemoiselle/internal/context/BeanStore.java index a7e96b0..d672b81 100644 --- a/impl/core/src/main/java/br/gov/frameworkdemoiselle/internal/context/BeanStore.java +++ b/impl/core/src/main/java/br/gov/frameworkdemoiselle/internal/context/BeanStore.java @@ -8,25 +8,26 @@ import java.util.Map; import javax.enterprise.context.spi.CreationalContext; -public class BeanStore implements Iterable,Serializable { +@SuppressWarnings("rawtypes") +public class BeanStore implements Iterable,Serializable { private static final long serialVersionUID = 1L; - private Map instanceCache = Collections.synchronizedMap( new HashMap() ); - private Map> creationalCache = Collections.synchronizedMap( new HashMap>() );; + private Map instanceCache = Collections.synchronizedMap( new HashMap() ); + private Map creationalCache = Collections.synchronizedMap( new HashMap() );; - public void put(String id, T instance,CreationalContext creationalContext){ + public void put(String id, T instance,CreationalContext creationalContext){ if (!instanceCache.containsKey(id)){ instanceCache.put(id, instance); creationalCache.put(id, creationalContext); } } - public T getInstance(String id){ + public Object getInstance(String id){ return instanceCache.get(id); } - public CreationalContext getCreationalContext(String id){ + public CreationalContext getCreationalContext(String id){ return creationalCache.get(id); } diff --git a/impl/core/src/main/java/br/gov/frameworkdemoiselle/internal/context/ContextualStore.java b/impl/core/src/main/java/br/gov/frameworkdemoiselle/internal/context/ContextualStore.java index fe6d9dd..53e3724 100644 --- a/impl/core/src/main/java/br/gov/frameworkdemoiselle/internal/context/ContextualStore.java +++ b/impl/core/src/main/java/br/gov/frameworkdemoiselle/internal/context/ContextualStore.java @@ -8,7 +8,8 @@ import javax.enterprise.context.spi.Contextual; import javax.enterprise.inject.spi.PassivationCapable; -public class ContextualStore implements Serializable { +@SuppressWarnings("rawtypes") +public class ContextualStore implements Serializable { private static final long serialVersionUID = 1L; @@ -16,11 +17,18 @@ public class ContextualStore implements Serializable { private AtomicInteger idGenerator = new AtomicInteger(); - private HashMap> idToContextual = new HashMap>(); + private HashMap idToContextual = new HashMap(); - private HashMap, String> contextualToId = new HashMap, String>(); + private HashMap contextualToId = new HashMap(); - public String tryRegisterAndGetId(Contextual contextual){ + /** + * The an unique ID for the given contextual. If it's the first time + * this contextual is accessed, registers the contextual for latter retrieval. + * + * @param contextual The contextual to generate an ID + * @return The unique ID for the contextual + */ + public String tryRegisterAndGetId(Contextual contextual){ String returnedId; if (contextualToId.containsKey(contextual)){ @@ -40,7 +48,7 @@ public class ContextualStore implements Serializable { return returnedId; } - public Contextual getContextual(String id){ + public Contextual getContextual(String id){ return idToContextual.get(id); } diff --git a/impl/extension/jsf/src/main/java/br/gov/frameworkdemoiselle/internal/context/FacesViewContextImpl.java b/impl/extension/jsf/src/main/java/br/gov/frameworkdemoiselle/internal/context/FacesViewContextImpl.java index 3910557..5b70402 100644 --- a/impl/extension/jsf/src/main/java/br/gov/frameworkdemoiselle/internal/context/FacesViewContextImpl.java +++ b/impl/extension/jsf/src/main/java/br/gov/frameworkdemoiselle/internal/context/FacesViewContextImpl.java @@ -70,14 +70,26 @@ public class FacesViewContextImpl extends AbstractCustomContext implements ViewC } @Override - protected Store getStore() { + protected BeanStore getStore() { Map viewMap = Faces.getViewMap(); - String key = Store.class.getName(); + String key = BeanStore.class.getName(); if (!viewMap.containsKey(key)) { viewMap.put(key, createStore()); } - return (Store) viewMap.get(key); + return (BeanStore) viewMap.get(key); + } + + @Override + protected ContextualStore getContextualStore() { + Map viewMap = Faces.getViewMap(); + String key = ContextualStore.class.getName(); + + if (!viewMap.containsKey(key)) { + viewMap.put(key, createContextualStore()); + } + + return (ContextualStore) viewMap.get(key); } } -- libgit2 0.21.2