com.sun.faces.cdi.clientwindow.ClientWindowScopeContextManager Maven / Gradle / Ivy
/*
* Copyright (c) 1997, 2020 Oracle and/or its affiliates. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0, which is available at
* http://www.eclipse.org/legal/epl-2.0.
*
* This Source Code may also be made available under the following Secondary
* Licenses when the conditions for such availability set forth in the
* Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
* version 2 with the GNU Classpath Exception, which is available at
* https://www.gnu.org/software/classpath/license.html.
*
* SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
*/
// Portions Copyright [2018] [Payara Foundation and/or its affiliates]
package com.sun.faces.cdi.clientwindow;
import com.sun.faces.config.WebConfiguration;
import com.sun.faces.util.FacesLogger;
import com.sun.faces.util.LRUMap;
import jakarta.enterprise.context.spi.Contextual;
import jakarta.enterprise.context.spi.CreationalContext;
import jakarta.enterprise.inject.spi.PassivationCapable;
import jakarta.faces.context.ExternalContext;
import jakarta.faces.context.FacesContext;
import jakarta.faces.lifecycle.ClientWindow;
import jakarta.servlet.http.HttpSession;
import jakarta.servlet.http.HttpSessionEvent;
import java.util.Collections;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.logging.Logger;
import static com.sun.faces.config.WebConfiguration.BooleanWebContextInitParameter.EnableDistributable;
import static java.util.logging.Level.FINEST;
/**
* The manager that deals with CDI ClientWindowScoped beans.
*/
public class ClientWindowScopeContextManager {
private static final Logger LOGGER = FacesLogger.CLIENTWINDOW.getLogger();
private static final String CLIENT_WINDOW_CONTEXTS = "com.sun.faces.cdi.clientwindow.clientWindowContexts";
private final boolean distributable;
public ClientWindowScopeContextManager() {
FacesContext facesContext = FacesContext.getCurrentInstance();
distributable = WebConfiguration.getInstance(facesContext.getExternalContext())
.isOptionEnabled(EnableDistributable);
}
/**
* Create the bean.
*
* @param the type.
* @param facesContext the faces context.
* @param contextual the contextual.
* @param creational the creational.
* @return the value or null if not found.
*/
public T createBean(FacesContext facesContext, Contextual contextual, CreationalContext creational) {
LOGGER.log(FINEST, "Creating @ClientWindowScoped CDI bean using contextual: {0}", contextual);
if (!(contextual instanceof PassivationCapable)) {
throw new IllegalArgumentException("ClientWindowScoped bean " + contextual.toString() + " must be PassivationCapable, but is not.");
}
T contextualInstance = contextual.create(creational);
if (contextualInstance != null) {
String passivationCapableId = ((PassivationCapable) contextual).getId();
getContextMap(facesContext).put(passivationCapableId, new ClientWindowScopeContextObject(passivationCapableId, contextualInstance));
}
return contextualInstance;
}
/**
* Get the value from the ClientWindow-map (or null if not found).
*
* @param the type.
* @param facesContext the faces context.
* @param contextual the contextual.
* @return the value or null if not found.
*/
@SuppressWarnings("unchecked")
public T getBean(FacesContext facesContext, Contextual contextual) {
T result = null;
Map contextMap = getContextMap(facesContext);
if (contextMap != null) {
if (!(contextual instanceof PassivationCapable)) {
throw new IllegalArgumentException("ClientWindowScoped bean " + contextual.toString() + " must be PassivationCapable, but is not.");
}
ClientWindowScopeContextObject contextObject = contextMap.get(((PassivationCapable) contextual).getId());
if (contextObject != null) {
return contextObject.getContextualInstance();
}
}
return result;
}
/**
* Get the context map.
*
* @param facesContext the Faces context.
* @return the context map.
*/
private Map getContextMap(FacesContext facesContext) {
return getContextMap(facesContext, true);
}
/**
* Get the context map.
*
* @param facesContext the Faces context.
* @param create flag to indicate if we are creating the context map.
* @return the context map.
*/
@SuppressWarnings("unchecked")
private Map getContextMap(FacesContext facesContext, boolean create) {
Map result = null;
ExternalContext externalContext = facesContext.getExternalContext();
if (externalContext != null) {
Map sessionMap = externalContext.getSessionMap();
Object session = externalContext.getSession(create);
if (session != null) {
Map