All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.ocpsoft.pretty.faces.el.resolver.FacesConfigBeanNameResolver Maven / Gradle / Ivy

The newest version!
/*
 * Copyright 2010 Lincoln Baxter, III
 * 
 * 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 com.ocpsoft.pretty.faces.el.resolver;

import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.faces.webapp.FacesServlet;
import javax.servlet.ServletContext;

import org.apache.commons.digester.Digester;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.xml.sax.SAXException;

import com.ocpsoft.pretty.faces.spi.ELBeanNameResolver;
import com.ocpsoft.pretty.faces.util.EmptyEntityResolver;

/**
 * 
 * 

* Implementation of {@link ELBeanNameResolver} handling beans configured via the * standard XML configuration mechanism. *

* *

* This resolver handles beans specified in faces-config.xml files. The resolver * will pick up the default configuration file /WEB-INF/faces-config.xml, * all /META-INF/faces-config.xml found by the supplied {@link ClassLoader} * and all files specified via the javax.faces.CONFIG_FILES init parameter. *

* * @author Christian Kaltepoth * */ public class FacesConfigBeanNameResolver implements ELBeanNameResolver { private final static Log log = LogFactory.getLog(FacesConfigBeanNameResolver.class); /** * Name of default faces-config.xml loaded via * {@link ServletContext#getResource(String)} */ private final static String WEB_INF_FACES_CONFIG_XML = "/WEB-INF/faces-config.xml"; /** * Name of faces-config.xml loaded via * {@link ClassLoader#getResource(String)} */ private final static String META_INF_FACES_CONFIG_XML = "META-INF/faces-config.xml"; /** * Lookup map: FQCN -> bean name */ private Map beanNameMap = new HashMap(); /** * Initialization procedure. Reads all faces-config.xml files and registers * the beans found. */ public boolean init(ServletContext servletContext, ClassLoader classLoader) { // list of beans found List facesConfigEntries = new ArrayList(); // get the list of faces configuration files to process Set facesConfigs = getFacesConfigFiles(servletContext, classLoader); // process all configuration files for (URL url : facesConfigs) { processFacesConfig(url, facesConfigEntries); } // Create bean name lookup map from all entries found for (FacesConfigEntry entry : facesConfigEntries) { beanNameMap.put(entry.getBeanClass(), entry.getName()); } // debug statement containing number of classes found if (log.isDebugEnabled()) { log.debug("Found " + beanNameMap.size() + " bean names in faces configuration."); } // we will always enable this resolver return true; } /** * Returns a set of faces-config.xml files. This set includes the default * configuration file, all additional files mentioned via the * javax.faces.CONFIG_FILES init parameter and all files found * in META-INF folders. * * @param servletContext * The ServletContext * @param classLoader * The classloader used to find files in META-INF directories * @return A set of URLs */ private Set getFacesConfigFiles(ServletContext servletContext, ClassLoader classLoader) { // set of URLs to process Set result = new HashSet(); try { // get default faces-config.xml URL defaultFacesConfig = servletContext.getResource(WEB_INF_FACES_CONFIG_XML); if (defaultFacesConfig != null) { result.add(defaultFacesConfig); } // get additional configuration files from init parameter result.addAll(getConfigFilesFromInitParameter(servletContext)); // Find configuration files META-INF directories try { Enumeration resources = classLoader.getResources(META_INF_FACES_CONFIG_XML); while (resources.hasMoreElements()) { result.add(resources.nextElement()); } } catch (IOException e) { log.error("Failed to load faces-config.xml files from META-INF directories", e); } } catch (MalformedURLException e) { // should not happen, because URLs are hard-coded throw new IllegalArgumentException(e); } return result; } /** * Returns a collection of faces configuration files mentioned via the * default javax.faces.CONFIG_FILES init parameter * * @param servletContext * The ServletContext * @return A collection of URLs (never null) */ private Collection getConfigFilesFromInitParameter(ServletContext servletContext) { // read init parameter String initParam = servletContext.getInitParameter(FacesServlet.CONFIG_FILES_ATTR); // empty? return empty set if (initParam == null || initParam.trim().length() == 0) { return Collections.emptySet(); } // split string at each comma String[] files = initParam.split(","); // the result Set result = new HashSet(); // process each single file for (String file : files) { // ignore empty entries if (file.trim().length() == 0) { continue; } try { // try get URL for this file URL url = servletContext.getResource(file.trim()); // add it to the result, if it exists if (url != null) { result.add(url); } } catch (MalformedURLException e) { // log on debug level, because the JSF implementation should // handle such a case log.debug("Invalid entry in javax.faces.CONFIG_FILES init parameter: " + file); } } return result; } /** * Process a single faces-config.xml file and add all beans * found to the supplied list of {@link FacesConfigEntry} objects. * * @param url * The faces-config.xml file * @param facesConfigEntries * list of entries to add the beans to */ private void processFacesConfig(URL url, List facesConfigEntries) { // log name of current file if (log.isTraceEnabled()) { log.trace("Loading bean names from: " + url.toString()); } // setup digester Digester digester = new Digester(); /* * We use the context class loader to resolve classes. * This fixes ClassNotFoundExceptions on Geronimo. */ digester.setUseContextClassLoader(true); // prevent downloading of DTDs digester.setEntityResolver(new EmptyEntityResolver()); digester.setValidating(false); digester.push(facesConfigEntries); digester.addObjectCreate("faces-config/managed-bean", FacesConfigEntry.class); digester.addCallMethod("faces-config/managed-bean/managed-bean-name", "setName", 0); digester.addCallMethod("faces-config/managed-bean/managed-bean-class", "setBeanClass", 0); digester.addSetNext("faces-config/managed-bean", "add"); // stream used to read faces-config.xml file InputStream stream = null; try { // open the file and let digester pares it stream = url.openStream(); digester.parse(stream); } catch (IOException e) { // may be thrown when reading the file log.warn("Failed to parse: " + url.toString() + ": " + e.getMessage()); } catch (SAXException e) { // parsing errors log.warn("Failed to parse: " + url.toString() + ": " + e.getMessage()); } finally { // close stream if (stream != null) { try { stream.close(); } catch (IOException e) { // ignore IOExceptions on close } } } } /* * Implementation if interface method */ public String getBeanName(Class clazz) { // first check bean name map containing faces-config.xml entries String name = beanNameMap.get(clazz.getName()); if (name != null) { return name; } return null; } /** * Private class to hold values of single "managed-bean" entries */ public static class FacesConfigEntry { private String name; private String beanClass; public String getName() { return name; } public void setName(String name) { this.name = name; } public String getBeanClass() { return beanClass; } public void setBeanClass(String beanClass) { this.beanClass = beanClass; } } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy