Skip to content

Commit

Permalink
Added ApplicationInitializer which checks CDI availability. Merged
Browse files Browse the repository at this point in the history
VersionLoggerEventListener and FacesViewsInitializer into this as well.
Updated Messages javadoc.
  • Loading branch information
Bauke Scholtz committed Jul 9, 2014
1 parent 4442e3b commit bce5f0c
Show file tree
Hide file tree
Showing 7 changed files with 174 additions and 166 deletions.
94 changes: 94 additions & 0 deletions src/main/java/org/omnifaces/ApplicationInitializer.java
@@ -0,0 +1,94 @@
/*
* Copyright 2013 OmniFaces.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
* specific language governing permissions and limitations under the License.
*/
package org.omnifaces;

import java.util.Set;
import java.util.logging.Logger;

import javax.servlet.ServletContainerInitializer;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;

import org.omnifaces.facesviews.FacesViews;
import org.omnifaces.util.Faces;

/**
* <p>OmniFaces application initializer. So far, this performs the following tasks:
* <ul>
* <li>Log the OmniFaces version.
* <li>Check if CDI is present, otherwise log and fail.
* <li>Initialize FacesViews.
* </li>
*
* @author Bauke Scholtz
* @since 2.0
*/
public class ApplicationInitializer implements ServletContainerInitializer {

private static final Logger logger = Logger.getLogger(ApplicationInitializer.class.getName());

@Override
public void onStartup(Set<Class<?>> c, ServletContext servletContext) throws ServletException {
logOmniFacesVersion();
checkCDIAvailability();
FacesViews.initilaize(servletContext);
}

private static void logOmniFacesVersion() {
logger.info("Using OmniFaces version " + Faces.class.getPackage().getSpecificationVersion());
}

private static void checkCDIAvailability() throws ServletException {
try {
Class.forName("javax.enterprise.inject.spi.BeanManager");
}
catch (Throwable e) {
logger.severe(""
+ "\n████████████████████████████████████████████████████████████████████████████████"
+ "\n▌ ▐█ ▐ ▐"
+ "\n▌ ▄ ▄█▓█▌ ▐ OmniFaces failed to initialize! ▐"
+ "\n▌ ▐██▄ ▄▓░░▓▓ ▐ ▐"
+ "\n▌ ▐█░██▓ ▓▓░░░▓▌ ▐ This OmniFaces version requires CDI, but ▐"
+ "\n▌ ▐█▌░▓██ █▓░░░░▓ ▐ none was found on this environment. ▐"
+ "\n▌ ▓█▌░░▓█▄███████▄███▓░▓█ ▐ ▐"
+ "\n▌ ▓██▌░▓██░░░░░░░░░░▓█░▓▌ ▐ OmniFaces 2.x requires a minimum of JSF 2.2.▐"
+ "\n▌ ▓█████░░░░░░░░░░░░▓██ ▐ Since this JSF version, the JSF managed bean▐"
+ "\n▌ ▓██▓░░░░░░░░░░░░░░░▓█ ▐ facility @ManagedBean is semi-official ▐"
+ "\n▌ ▐█▓░░░░░░█▓░░▓█░░░░▓█▌ ▐ deprecated in favour of CDI. JSF 2.2 users ▐"
+ "\n▌ ▓█▌░▓█▓▓██▓░█▓▓▓▓▓░▓█▌ ▐ are strongly encouraged to move to CDI. ▐"
+ "\n▌ ▓▓░▓██████▓░▓███▓▓▌░█▓ ▐ ▐"
+ "\n▌ ▐▓▓░█▄▐▓▌█▓░░▓█▐▓▌▄▓░██ ▐ OmniFaces goes a step further by making CDI ▐"
+ "\n▌ ▓█▓░▓█▄▄▄█▓░░▓█▄▄▄█▓░██▌ ▐ a REQUIRED dependency next to JSF 2.2. This ▐"
+ "\n▌ ▓█▌░▓█████▓░░░▓███▓▀░▓█▓ ▐ not only ensures that your web application ▐"
+ "\n▌ ▐▓█░░░▀▓██▀░░░░░ ▀▓▀░░▓█▓ ▐ represents the state of art, but this also ▐"
+ "\n▌ ▓██░░░░░░░░▀▄▄▄▄▀░░░░░░▓▓ ▐ makes for us easier to develop OmniFaces, ▐"
+ "\n▌ ▓█▌░░░░░░░░░░▐▌░░░░░░░░▓▓▌ ▐ without the need for all sorts of hacks in ▐"
+ "\n▌ ▓█░░░░░░░░░▄▀▀▀▀▄░░░░░░░█▓ ▐ in order to get OmniFaces to deploy on ▐"
+ "\n▌ ▐█▌░░░░░░░░▀░░░░░░▀░░░░░░█▓▌ ▐ environments without CDI. ▐"
+ "\n▌ ▓█░░░░░░░░░░░░░░░░░░░░░░░██▓ ▐ ▐"
+ "\n▌ ▓█░░░░░░░░░░░░░░░░░░░░░░░▓█▓ ▐ You have 3 options: ▐"
+ "\n██████████████████████████████████ 1. Downgrade to OmniFaces 1.x. ▐"
+ "\n█░▀░░░░▀█▀░░░░░░▀█░░░░░░▀█▀░░░░░▀█ 2. Install CDI in this environment. ▐"
+ "\n█░░▐█▌░░█░░░██░░░█░░██░░░█░░░██░░█ 3. Switch to a CDI capable environment. ▐"
+ "\n█░░▐█▌░░█░░░██░░░█░░██░░░█░░░██░░█ ▐"
+ "\n█░░▐█▌░░█░░░██░░░█░░░░░░▄█░░▄▄▄▄▄█ For additional instructions, check ▐"
+ "\n█░░▐█▌░░█░░░██░░░█░░░░████░░░░░░░█ http://omnifaces.org/cdi ▐"
+ "\n█░░░█░░░█▄░░░░░░▄█░░░░████▄░░░░░▄█ ▐"
+ "\n████████████████████████████████████████████████████████████████████████████████"
);

throw new ServletException();
}
}

}
38 changes: 0 additions & 38 deletions src/main/java/org/omnifaces/VersionLoggerEventListener.java

This file was deleted.

71 changes: 71 additions & 0 deletions src/main/java/org/omnifaces/facesviews/FacesViews.java
Expand Up @@ -16,6 +16,10 @@
import static java.util.Collections.unmodifiableSet;
import static java.util.Locale.US;
import static java.util.regex.Pattern.quote;
import static javax.faces.application.ProjectStage.Development;
import static javax.faces.application.ProjectStage.PROJECT_STAGE_PARAM_NAME;
import static javax.faces.view.facelets.ResourceResolver.FACELETS_RESOURCE_RESOLVER_PARAM_NAME;
import static org.omnifaces.facesviews.FacesServletDispatchMethod.DO_FILTER;
import static org.omnifaces.util.Faces.getApplicationAttribute;
import static org.omnifaces.util.Platform.getFacesServletRegistration;
import static org.omnifaces.util.ResourcePaths.getExtension;
Expand All @@ -37,6 +41,7 @@

import javax.faces.context.ExternalContext;
import javax.faces.context.FacesContext;
import javax.servlet.FilterRegistration;
import javax.servlet.ServletContext;
import javax.servlet.ServletRegistration;
import javax.servlet.http.HttpServletRequest;
Expand Down Expand Up @@ -140,6 +145,72 @@ private FacesViews() {

public static final String FACES_VIEWS_ORIGINAL_SERVLET_PATH = "org.omnifaces.facesviews.original.servlet_path";

public static void initilaize(ServletContext servletContext) {

if (!"false".equals(servletContext.getInitParameter(FACES_VIEWS_ENABLED_PARAM_NAME))) {

// Scan our dedicated directory for Faces resources that need to be mapped
Map<String, String> collectedViews = new HashMap<>();
Set<String> collectedExtensions = new HashSet<>();
scanViewsFromRootPaths(servletContext, collectedViews, collectedExtensions);

if (!collectedViews.isEmpty()) {

// Store the resources and extensions that were found in application scope, where others can find it.
servletContext.setAttribute(FACES_VIEWS_RESOURCES, unmodifiableMap(collectedViews));
servletContext.setAttribute(FACES_VIEWS_REVERSE_RESOURCES, unmodifiableMap(reverse(collectedViews)));
servletContext.setAttribute(FACES_VIEWS_RESOURCES_EXTENSIONS, unmodifiableSet(collectedExtensions));

// Register 3 artifacts with the Servlet container and JSF that help implement this feature:

// 1. A Filter that forwards extensionless requests to an extension mapped request, e.g. /index to
// /index.xhtml
// (The FacesServlet doesn't work well with the exact mapping that we use for extensionless URLs).
FilterRegistration facesViewsRegistration = servletContext.addFilter(FacesViewsForwardingFilter.class.getName(),
FacesViewsForwardingFilter.class);

// 2. A Facelets resource resolver that resolves requests like /index.xhtml to
// /WEB-INF/faces-views/index.xhtml
servletContext.setInitParameter(FACELETS_RESOURCE_RESOLVER_PARAM_NAME, FacesViewsResolver.class.getName());

// 3. A ViewHandler that transforms the forwarded extension based URL back to an extensionless one, e.g.
// /index.xhtml to /index
// See FacesViewsForwardingFilter#init


if (Development.name().equals(servletContext.getInitParameter(PROJECT_STAGE_PARAM_NAME)) &&
getFacesServletDispatchMethod(servletContext) != DO_FILTER) {

// In development mode map this Filter to "*", so we can catch requests to extensionless resources that
// have been dynamically added. Note that resources with mapped extensions are already handled by the FacesViewsResolver.
// Adding resources with new extensions still requires a restart.

// Development mode only works when the dispatch mode is not DO_FILTER, since DO_FILTER mode depends
// on the Faces Servlet being "exact"-mapped on the view resources.

facesViewsRegistration.addMappingForUrlPatterns(null, isFilterAfterDeclaredFilters(servletContext), "/*");
} else {

// In non-development mode, only map this Filter to specific resources

// Map the forwarding filter to all the resources we found.
for (String resource : collectedViews.keySet()) {
facesViewsRegistration.addMappingForUrlPatterns(null, isFilterAfterDeclaredFilters(servletContext), resource);
}

// Additionally map the filter to all paths that were scanned and which are also directly
// accessible. This is to give the filter an opportunity to block these.
for (String path : getPublicRootPaths(servletContext)) {
facesViewsRegistration.addMappingForUrlPatterns(null, false, path + "*");
}
}

// We now need to map the Faces Servlet to the extensions we found, but at this point in time
// this Faces Servlet might not be created yet, so we do this part in FacesViewInitializedListener.
}
}
}

public static void scanViewsFromRootPaths(ServletContext servletContext, Map<String, String> collectedViews, Set<String> collectedExtensions) {
for (String rootPath : getRootPaths(servletContext)) {

Expand Down
119 changes: 0 additions & 119 deletions src/main/java/org/omnifaces/facesviews/FacesViewsInitializer.java

This file was deleted.

0 comments on commit bce5f0c

Please sign in to comment.