From 14f7073f6feeb873448d858c0b2c7c7fbd32764c Mon Sep 17 00:00:00 2001 From: Danilo Costa Viana Date: Thu, 20 Nov 2014 13:21:23 -0300 Subject: [PATCH] [FWK-205] Otimizado processo para associar beans de escopo de visão diretamente a sessão (antes apenas uma referência era mantida na sessão). Assim objetos estão diretamente atrelados ao ciclo de vida da sessão e são destruídos corretamente no fim da sessão. --- impl/extension/jsf/src/main/java/br/gov/frameworkdemoiselle/internal/context/FacesViewContextImpl.java | 42 +++++++++++++++++++----------------------- impl/extension/servlet/src/main/java/br/gov/frameworkdemoiselle/lifecycle/AfterSessionCreated.java | 6 ++++-- impl/extension/servlet/src/main/java/br/gov/frameworkdemoiselle/lifecycle/BeforeSessionDestroyed.java | 13 ++++++++++--- impl/extension/servlet/src/main/java/br/gov/frameworkdemoiselle/util/SessionListener.java | 10 ++++------ 4 files changed, 37 insertions(+), 34 deletions(-) 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 d583051..307a5e2 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 @@ -36,7 +36,6 @@ */ package br.gov.frameworkdemoiselle.internal.context; -import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.atomic.AtomicLong; import javax.enterprise.context.ApplicationScoped; @@ -70,23 +69,24 @@ public class FacesViewContextImpl extends AbstractCustomContext implements ViewC private final AtomicLong atomicLong = new AtomicLong(); - private ConcurrentHashMap sessionBeanStore = new ConcurrentHashMap(); - + //private ConcurrentHashMap sessionBeanStore = new ConcurrentHashMap(); + private static final String FACES_KEY = FacesViewContextImpl.class.getCanonicalName(); - + private static final String VIEW_STORE_KEY = FacesViewBeanStore.class.getCanonicalName(); + public FacesViewContextImpl() { super(ViewScoped.class); } @Override protected boolean isStoreInitialized() { - return FacesContext.getCurrentInstance()!=null && getSessionId()!=null; + return FacesContext.getCurrentInstance()!=null && getSession()!=null; } @Override protected BeanStore getStore() { - String sessionId = getSessionId(); - if (sessionId == null){ + HttpSession session = getSession(); + if (session == null){ return null; } @@ -108,16 +108,16 @@ public class FacesViewContextImpl extends AbstractCustomContext implements ViewC } } } - + //A mesma técnica de bloqueio de thread acima é usada aqui para //criar um SessionBeanStore caso o mesmo ainda não exista. - FacesViewBeanStore currentStore = sessionBeanStore.get(sessionId); + FacesViewBeanStore currentStore = (FacesViewBeanStore) session.getAttribute(VIEW_STORE_KEY); if (currentStore==null){ synchronized (this) { - currentStore = (FacesViewBeanStore) sessionBeanStore.get(sessionId); + currentStore = (FacesViewBeanStore) session.getAttribute(VIEW_STORE_KEY); if (currentStore==null){ currentStore = new FacesViewBeanStore(); - sessionBeanStore.put(sessionId, currentStore); + session.setAttribute(VIEW_STORE_KEY, currentStore); } } } @@ -129,22 +129,18 @@ public class FacesViewContextImpl extends AbstractCustomContext implements ViewC * Called before the session is invalidated for that user. * Destroys all view scoped beans stored on that session. */ - private void clearInvalidatedSession(String sessionId){ - if (sessionId != null){ - final FacesViewBeanStore store = sessionBeanStore.get(sessionId); + private void clearInvalidatedSession(HttpSession session){ + if (session != null){ + FacesViewBeanStore store = (FacesViewBeanStore) session.getAttribute(VIEW_STORE_KEY); if (store!=null){ + session.removeAttribute(VIEW_STORE_KEY); store.clear(this); - sessionBeanStore.remove(sessionId); } } } - /* - * Returns the current session ID. Creates a session if one doesn't exist. Returns NULL if the session can't be created. - */ - private String getSessionId(){ - final HttpSession session = (HttpSession) FacesContext.getCurrentInstance().getExternalContext().getSession(true); - return session!=null ? session.getId() : null; + private HttpSession getSession(){ + return (HttpSession) FacesContext.getCurrentInstance().getExternalContext().getSession(true); } /** @@ -162,11 +158,11 @@ public class FacesViewContextImpl extends AbstractCustomContext implements ViewC * Destroys all view scoped beans stored on that session. */ protected void clearInvalidatedSession(@Observes BeforeSessionDestroyed event){ - String sessionId = event.getSessionId(); + HttpSession session = event.getSession(); try{ Context context = Beans.getBeanManager().getContext(ViewScoped.class); if ( FacesViewContextImpl.class.isInstance(context) ){ - ((FacesViewContextImpl)context).clearInvalidatedSession(sessionId); + ((FacesViewContextImpl)context).clearInvalidatedSession(session); } } catch(ContextNotActiveException ce){ diff --git a/impl/extension/servlet/src/main/java/br/gov/frameworkdemoiselle/lifecycle/AfterSessionCreated.java b/impl/extension/servlet/src/main/java/br/gov/frameworkdemoiselle/lifecycle/AfterSessionCreated.java index 1a2421c..fa48697 100644 --- a/impl/extension/servlet/src/main/java/br/gov/frameworkdemoiselle/lifecycle/AfterSessionCreated.java +++ b/impl/extension/servlet/src/main/java/br/gov/frameworkdemoiselle/lifecycle/AfterSessionCreated.java @@ -1,5 +1,7 @@ package br.gov.frameworkdemoiselle.lifecycle; +import javax.servlet.http.HttpSession; + /** * This interface represents an event fired after a new HTTP session is created. * @@ -10,8 +12,8 @@ public interface AfterSessionCreated { /** * - * @return The ID of the recently created session + * @return The recently created session */ - public String getSessionId(); + public HttpSession getSession(); } diff --git a/impl/extension/servlet/src/main/java/br/gov/frameworkdemoiselle/lifecycle/BeforeSessionDestroyed.java b/impl/extension/servlet/src/main/java/br/gov/frameworkdemoiselle/lifecycle/BeforeSessionDestroyed.java index 0453179..a8efa7e 100644 --- a/impl/extension/servlet/src/main/java/br/gov/frameworkdemoiselle/lifecycle/BeforeSessionDestroyed.java +++ b/impl/extension/servlet/src/main/java/br/gov/frameworkdemoiselle/lifecycle/BeforeSessionDestroyed.java @@ -1,5 +1,7 @@ package br.gov.frameworkdemoiselle.lifecycle; +import javax.servlet.http.HttpSession; + /** * This interface represents an event fired before an HTTP session is destroyed. * @@ -9,9 +11,14 @@ package br.gov.frameworkdemoiselle.lifecycle; public interface BeforeSessionDestroyed { /** + *

When calling this method the session still hasn't been invalidated so + * you can access attributes that are about to be removed from the session.

+ * + *

Don't call {@link HttpSession#invalidate()} on the returned session, this operation + * is unsupported.

* - * @return The session ID of the session about to be destroyed + * @return The session about to be destroyed */ - public String getSessionId(); + public HttpSession getSession(); -} +} \ No newline at end of file diff --git a/impl/extension/servlet/src/main/java/br/gov/frameworkdemoiselle/util/SessionListener.java b/impl/extension/servlet/src/main/java/br/gov/frameworkdemoiselle/util/SessionListener.java index 508a5dc..5da6ab7 100644 --- a/impl/extension/servlet/src/main/java/br/gov/frameworkdemoiselle/util/SessionListener.java +++ b/impl/extension/servlet/src/main/java/br/gov/frameworkdemoiselle/util/SessionListener.java @@ -24,9 +24,8 @@ public class SessionListener implements HttpSessionListener { public void sessionCreated(final HttpSessionEvent sessionEvent) { Beans.getBeanManager().fireEvent(new AfterSessionCreated() { @Override - public String getSessionId() { - HttpSession session = sessionEvent.getSession(); - return session!=null ? session.getId() : null; + public HttpSession getSession() { + return sessionEvent.getSession(); } }); } @@ -35,9 +34,8 @@ public class SessionListener implements HttpSessionListener { public void sessionDestroyed(final HttpSessionEvent sessionEvent) { Beans.getBeanManager().fireEvent(new BeforeSessionDestroyed() { @Override - public String getSessionId() { - HttpSession session = sessionEvent.getSession(); - return session!=null ? session.getId() : null; + public HttpSession getSession() { + return sessionEvent.getSession(); } }); } -- libgit2 0.21.2