// For each session attribute:
String appConfigAttrName = ApplicationConfig.class.getName();
ServletContext servletContext = httpSession.getServletContext();
ApplicationConfig applicationConfig = (ApplicationConfig) servletContext.getAttribute(
appConfigAttrName);
BeanManager beanManager = beanManagerFactory.getBeanManager(applicationConfig.getFacesConfig());
try {
Enumeration<String> attributeNames = (Enumeration<String>) httpSession.getAttributeNames();
while (attributeNames.hasMoreElements()) {
String attributeName = attributeNames.nextElement();
// If the current session attribute name is namespaced with the standard portlet prefix, then it
// 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) {
// If the current session attribute value is a JSF managed-bean, then cleanup the
// bean by invoking methods annotated with {@link PreDestroy}. Note that in a
// webapp/servlet environment, the cleanup is handled by the Mojarra
// WebappLifecycleListener.sessionDestroyed(HttpSessionEvent) method. But in a
// portlet environment, Mojarra fails to recognize the session attribute as
// managed-bean because the attribute name contains the standard portlet prefix. An
// alternative approach would be to have the bridge rename the attribute (by
// stripping off the standard portlet prefix) so that Mojarra could find it. But
// this would not a good solution, because multiple instances of the same portlet
// would have the same session attribute names for managed-beans, and only the last
// one would get cleaned-up by Mojarra.
if (beanManager.isManagedBean(attributeName, attributeValue)) {
beanManager.invokePreDestroyMethods(attributeValue, true);
}
// Otherwise,
else {