Search in sources :

Example 1 with PreDestroyInvoker

use of com.liferay.faces.bridge.bean.PreDestroyInvoker in project liferay-faces-bridge-impl by liferay.

the class BridgeSessionListener method sessionDestroyed.

@Override
public void sessionDestroyed(HttpSessionEvent httpSessionEvent) {
    if (firstInstance) {
        // Discover Factories
        BeanManagerFactory beanManagerFactory = null;
        BridgeRequestScopeManagerFactory bridgeRequestScopeManagerFactory = null;
        HttpSession httpSession = null;
        ServletContext servletContext = null;
        PortletContext portletContext = null;
        try {
            httpSession = httpSessionEvent.getSession();
            servletContext = httpSession.getServletContext();
            portletContext = new PortletContextAdapter(servletContext);
            beanManagerFactory = (BeanManagerFactory) BridgeFactoryFinder.getFactory(portletContext, BeanManagerFactory.class);
            bridgeRequestScopeManagerFactory = (BridgeRequestScopeManagerFactory) BridgeFactoryFinder.getFactory(portletContext, BridgeRequestScopeManagerFactory.class);
        } catch (Exception e) {
            String contextPath = "unknown";
            if (servletContext != null) {
                contextPath = servletContext.getContextPath();
            }
            logger.error("Unable to discover factories for contextPath=[{0}] possibly because the portlet never received a RenderRequest", contextPath);
        }
        if ((beanManagerFactory != null) && (bridgeRequestScopeManagerFactory != null)) {
            // Cleanup instances of BridgeRequestScope that are associated with the expiring session.
            BridgeRequestScopeManager bridgeRequestScopeManager = bridgeRequestScopeManagerFactory.getBridgeRequestScopeManager(portletContext);
            bridgeRequestScopeManager.removeBridgeRequestScopesBySession(httpSession);
            // For each session attribute:
            String appConfigAttrName = ApplicationConfig.class.getName();
            ApplicationConfig applicationConfig = (ApplicationConfig) servletContext.getAttribute(appConfigAttrName);
            BeanManager beanManager = beanManagerFactory.getBeanManager(applicationConfig.getFacesConfig());
            try {
                Enumeration<String> attributeNames = httpSession.getAttributeNames();
                while (attributeNames.hasMoreElements()) {
                    String attributeName = attributeNames.nextElement();
                    // is an attribute that was set using PortletSession.setAttribute(String, Object).
                    if ((attributeName != null) && attributeName.startsWith("javax.portlet.p.")) {
                        int pos = attributeName.indexOf("?");
                        if (pos > 0) {
                            Object attributeValue = httpSession.getAttribute(attributeName);
                            httpSession.removeAttribute(attributeName);
                            if (attributeValue != null) {
                                // one would get cleaned-up by Mojarra.
                                if (beanManager.isManagedBean(attributeName, attributeValue)) {
                                    PreDestroyInvokerFactory preDestroyInvokerFactory = (PreDestroyInvokerFactory) BridgeFactoryFinder.getFactory(portletContext, PreDestroyInvokerFactory.class);
                                    PreDestroyInvoker preDestroyInvoker = preDestroyInvokerFactory.getPreDestroyInvoker(servletContext);
                                    preDestroyInvoker.invokeAnnotatedMethods(attributeValue, true);
                                } else // Otherwise,
                                {
                                    // If the current session attribute is Mojarra-vendor-specific, then
                                    String attributeValueClassName = attributeValue.getClass().getName();
                                    if (attributeName.contains(MOJARRA_ACTIVE_VIEW_MAPS) || attributeValueClassName.contains(MOJARRA_PACKAGE_PREFIX)) {
                                        // Rename the namespaced attribute by stripping off the standard portlet
                                        // prefix. This will enable Mojarra's session expiration features to find
                                        // attributes that it is expecting.
                                        String nonPrefixedName = attributeName.substring(pos + 1);
                                        logger.debug("Renaming Mojarra session attributeName=[{0}] -> [{1}]", attributeName, nonPrefixedName);
                                        httpSession.setAttribute(nonPrefixedName, attributeValue);
                                        // If this is the attribute that contains all of the active view maps, then
                                        if (MOJARRA_ACTIVE_VIEW_MAPS.equals(nonPrefixedName)) {
                                            if (mojarraAbleToCleanUpViewScopedDataAccessor.get(portletContext)) {
                                                // Invoke the Mojarra
                                                // ViewScopeManager.sessionDestroyed(HttpSessionEvent) method in
                                                // order to cleanup the active view maps. Rather than waiting for
                                                // the servlet container to call the method during session
                                                // expiration, it is important to call it directly within this
                                                // while-loop for two reasons: 1) If the developer did not
                                                // explicitly specify the order of the Mojarra ConfigureListener and
                                                // this BridgeSessionListener in WEB-IN/web.xml descriptor
                                                // (FACES-1483) then there is no guarantee that the method would get
                                                // called. 2) In the case of multiple portlet instances, each
                                                // instance has its own namespaced attribute in the session.
                                                // Renaming each namespaced attribute to
                                                // "com.sun.faces.application.view.activeViewMaps" would only enable
                                                // Mojarra to cleanup the last one.
                                                HttpSessionListener viewScopeManager = (HttpSessionListener) servletContext.getAttribute(MOJARRA_VIEW_SCOPE_MANAGER);
                                                if (viewScopeManager != null) {
                                                    try {
                                                        logger.debug("Asking Mojarra ViewScopeManager to cleanup @ViewScoped managed-beans");
                                                        viewScopeManager.sessionDestroyed(httpSessionEvent);
                                                    } catch (Exception e) {
                                                        logger.error(e);
                                                    }
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            } catch (IllegalStateException e) {
                logger.warn("Server does not permit cleanup of Mojarra managed-beans during session expiration");
            }
        }
    }
}
Also used : BridgeRequestScopeManagerFactory(com.liferay.faces.bridge.scope.internal.BridgeRequestScopeManagerFactory) PreDestroyInvoker(com.liferay.faces.bridge.bean.PreDestroyInvoker) HttpSessionListener(javax.servlet.http.HttpSessionListener) HttpSession(javax.servlet.http.HttpSession) PreDestroyInvokerFactory(com.liferay.faces.bridge.bean.PreDestroyInvokerFactory) ApplicationConfig(com.liferay.faces.util.config.ApplicationConfig) BeanManagerFactory(com.liferay.faces.bridge.bean.BeanManagerFactory) ServletContext(javax.servlet.ServletContext) PortletContext(javax.portlet.PortletContext) PortletContextAdapter(com.liferay.faces.bridge.context.internal.PortletContextAdapter) BeanManager(com.liferay.faces.bridge.bean.BeanManager) BridgeRequestScopeManager(com.liferay.faces.bridge.scope.internal.BridgeRequestScopeManager)

Aggregations

BeanManager (com.liferay.faces.bridge.bean.BeanManager)1 BeanManagerFactory (com.liferay.faces.bridge.bean.BeanManagerFactory)1 PreDestroyInvoker (com.liferay.faces.bridge.bean.PreDestroyInvoker)1 PreDestroyInvokerFactory (com.liferay.faces.bridge.bean.PreDestroyInvokerFactory)1 PortletContextAdapter (com.liferay.faces.bridge.context.internal.PortletContextAdapter)1 BridgeRequestScopeManager (com.liferay.faces.bridge.scope.internal.BridgeRequestScopeManager)1 BridgeRequestScopeManagerFactory (com.liferay.faces.bridge.scope.internal.BridgeRequestScopeManagerFactory)1 ApplicationConfig (com.liferay.faces.util.config.ApplicationConfig)1 PortletContext (javax.portlet.PortletContext)1 ServletContext (javax.servlet.ServletContext)1 HttpSession (javax.servlet.http.HttpSession)1 HttpSessionListener (javax.servlet.http.HttpSessionListener)1