com.sun.faces.config.FacesInitializer Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of jakarta.faces Show documentation
Show all versions of jakarta.faces Show documentation
EE4J Compatible Implementation for Jakarta Faces API
/*
* Copyright (c) 2009, 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
*/
package com.sun.faces.config;
import static com.sun.faces.RIConstants.ANNOTATED_CLASSES;
import static com.sun.faces.RIConstants.FACES_INITIALIZER_MAPPINGS_ADDED;
import static com.sun.faces.RIConstants.FACES_SERVLET_MAPPINGS;
import static com.sun.faces.util.Util.isEmpty;
import static java.lang.Boolean.TRUE;
import java.net.MalformedURLException;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import com.sun.faces.cdi.CdiExtension;
import jakarta.annotation.Resource;
import jakarta.enterprise.inject.Instance;
import jakarta.enterprise.inject.spi.CDI;
import jakarta.faces.annotation.FacesConfig;
import jakarta.faces.application.ResourceDependencies;
import jakarta.faces.application.ResourceDependency;
import jakarta.faces.bean.ManagedBean;
import jakarta.faces.component.FacesComponent;
import jakarta.faces.component.UIComponent;
import jakarta.faces.component.behavior.FacesBehavior;
import jakarta.faces.convert.Converter;
import jakarta.faces.convert.FacesConverter;
import jakarta.faces.event.ListenerFor;
import jakarta.faces.event.ListenersFor;
import jakarta.faces.event.NamedEvent;
import jakarta.faces.event.PhaseListener;
import jakarta.faces.render.FacesBehaviorRenderer;
import jakarta.faces.render.Renderer;
import jakarta.faces.validator.FacesValidator;
import jakarta.faces.validator.Validator;
import jakarta.faces.view.facelets.FaceletsResourceResolver;
import jakarta.faces.webapp.FacesServlet;
import jakarta.servlet.ServletContainerInitializer;
import jakarta.servlet.ServletContext;
import jakarta.servlet.ServletException;
import jakarta.servlet.ServletRegistration;
import jakarta.servlet.annotation.HandlesTypes;
import jakarta.websocket.Endpoint;
import jakarta.websocket.server.ServerApplicationConfig;
import jakarta.websocket.server.ServerContainer;
import jakarta.websocket.server.ServerEndpoint;
/**
* Adds mappings *.xhtml, /faces, *.jsf, and *.faces for the FacesServlet (if it
* hasn't already been mapped) if the following conditions are met:
*
*
* - The
Set
of classes passed to this initializer is not empty, or
* - /WEB-INF/faces-config.xml exists, or
* - A CDI enabled bean with qualifier FacesConfig can be obtained
*
*/
@HandlesTypes({ Converter.class, Endpoint.class, FaceletsResourceResolver.class, FacesBehavior.class, FacesBehaviorRenderer.class, FacesComponent.class,
FacesConverter.class, FacesConfig.class, // Should actually be check for enabled bean, but difficult to guarantee, see SERVLET_SPEC-79
FacesValidator.class, ListenerFor.class, ListenersFor.class, ManagedBean.class, NamedEvent.class, PhaseListener.class, Renderer.class, Resource.class,
ResourceDependencies.class, ResourceDependency.class, ServerApplicationConfig.class, ServerEndpoint.class, UIComponent.class, Validator.class })
public class FacesInitializer implements ServletContainerInitializer {
// NOTE: Loggins should not be used with this class.
private static final String FACES_SERVLET_CLASS = FacesServlet.class.getName();
// -------------------------------- Methods from ServletContainerInitializer
@Override
public void onStartup(Set> classes, ServletContext servletContext) throws ServletException {
Set> annotatedClasses = new HashSet<>();
if (classes != null) {
annotatedClasses.addAll(classes);
}
servletContext.setAttribute(ANNOTATED_CLASSES, annotatedClasses);
boolean appHasSomeJsfContent = appMayHaveSomeJsfContent(classes, servletContext);
boolean appHasFacesServlet = getExistingFacesServletRegistration(servletContext) != null;
if (appHasSomeJsfContent || appHasFacesServlet) {
InitFacesContext initFacesContext = new InitFacesContext(servletContext);
try {
if (appHasSomeJsfContent) {
// Only look at mapping concerns if there is JSF content
handleMappingConcerns(servletContext);
}
// Other concerns also handled if there is an existing Faces Servlet mapping
handleWebSocketConcerns(servletContext);
} finally {
// Bug 20458755: The InitFacesContext was not being cleaned up, resulting in
// a partially constructed FacesContext being made available
// to other code that re-uses this Thread at init time.
initFacesContext.releaseCurrentInstance();
initFacesContext.release();
}
}
}
// --------------------------------------------------------- Private Methods
private boolean appMayHaveSomeJsfContent(Set> classes, ServletContext context) {
if (!isEmpty(classes)) {
return true;
}
// No JSF specific classes found, check for a WEB-INF/faces-config.xml
try {
if (context.getResource("/WEB-INF/faces-config.xml") != null) {
return true;
}
} catch (MalformedURLException mue) {
}
// In the future remove FacesConfig.class from the @HandlesTypes annotation
// and only check via CDI
try {
CDI