com.ocpsoft.pretty.faces.el.LazyBeanNameFinder.java Source code

Java tutorial

Introduction

Here is the source code for com.ocpsoft.pretty.faces.el.LazyBeanNameFinder.java

Source

/*
 * 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;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import javax.servlet.ServletContext;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.ocpsoft.common.services.ServiceLoader;
import org.ocpsoft.rewrite.el.spi.BeanNameResolver;

/**
 * <p>
 * Class implementing lazy resolving of bean names.
 * </p>
 * <p>
 * This class is typically created once and is than supplied to {@link LazyExpression} instances in the
 * {@link LazyExpression#LazyExpression(LazyBeanNameFinder, Class, String)} constructor.
 * </p>
 * 
 * @author Christian Kaltepoth
 */
public class LazyBeanNameFinder {

    private final static Log log = LogFactory.getLog(LazyBeanNameFinder.class);

    /**
     * List of all resolvers. Initialized once on object creation
     */
    private final List<BeanNameResolver> resolvers = new ArrayList<BeanNameResolver>();

    /**
     * Creates a new {@link LazyBeanNameFinder}. The constructor will find all implementations of
     * {@link ELBeanNameResolver} by using the {@link ServiceLoader} mechanism.
     * 
     * @param servletContext The servlet context
     */
    public LazyBeanNameFinder(ServletContext servletContext) {

        // we use the context classloader
        ClassLoader classLoader = Thread.currentThread().getContextClassLoader();

        // fallback, if no context classloader exists
        if (classLoader == null) {
            classLoader = this.getClass().getClassLoader();
        }

        // find resolvers via ServiceLoader
        @SuppressWarnings("unchecked")
        Iterator<BeanNameResolver> beanNameFinderIterator = ServiceLoader.load(BeanNameResolver.class).iterator();

        // call init() method on all resolvers
        while (beanNameFinderIterator.hasNext()) {

            // log resolver name
            BeanNameResolver resolver = beanNameFinderIterator.next();
            if (log.isTraceEnabled()) {
                log.trace("Initializing BeanNameResolver: " + resolver.getClass().getName());
            }

            try {
                resolvers.add(resolver);
            } catch (ClassFormatError e) {
                /*
                 * Seems to happen for CDI classes when using GWT
                 * In this case just ignore the resolver
                 * See: http://code.google.com/p/prettyfaces/issues/detail?id=101
                 */
                log.warn("Failed to initialize " + resolver.getClass().getSimpleName() + ": " + e.getMessage());
            }
        }
    }

    /**
     * Find the bean name of the supplied class. This method will try to resolve the bean name by calling all registered
     * implementations of {@link ELBeanNameResolver}. This method will either return the resolved name or throw an
     * {@link IllegalStateException}, if no resolver knows the name of the bean.
     * 
     * @param clazz The class of the bean
     * @return The resolved bean name
     * @throws IllegalStateException If the name of the bean cannot be resolved
     */
    public String findBeanName(Class<?> clazz) throws IllegalStateException {

        // process all resolvers
        for (BeanNameResolver resolver : resolvers) {

            // try to resolve bean name with current resolver
            String name = resolver.getBeanName(clazz);

            // return the bean name, if the resolver was successful
            if (name != null) {
                return name;
            }

        }

        // No resolver knows the name of the bean
        throw new IllegalStateException("Cannot find name of bean '" + clazz.getName()
                + "'! You should place a @URLBeanName annotation on this class to let PrettyFaces know its name.");

    }

}