Package org.crank.core.spring.support

Source Code of org.crank.core.spring.support.SpringApplication

package org.crank.core.spring.support;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.crank.crud.controller.CrudUtils;

import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.jsf.FacesContextUtils;

import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.ResourceBundle;

import javax.el.ELContextListener;
import javax.el.ELException;
import javax.el.ELResolver;
import javax.el.ExpressionFactory;
import javax.el.ValueExpression;
import javax.faces.FacesException;
import javax.faces.application.Application;
import javax.faces.application.NavigationHandler;
import javax.faces.application.StateManager;
import javax.faces.application.ViewHandler;
import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.convert.Converter;
import javax.faces.el.MethodBinding;
import javax.faces.el.PropertyResolver;
import javax.faces.el.ValueBinding;
import javax.faces.el.VariableResolver;
import javax.faces.event.ActionListener;
import javax.faces.validator.Validator;


/**
* This class has the ability to obtain Spring-managed Converters,
* Validators, and UIComponents in the case that they are not
* configured in the JSF environment.
* <p>
* For all other behavior, this class delegates to the original
* JSF Application implementation.
* <p>
* @author Rick Hightower
*/
@SuppressWarnings("deprecation")
public class SpringApplication extends Application {
    /**
     * Get logger.
     */
    private final Log logger = LogFactory.getLog(getClass());

    /**
     * Original application object (may be chained).
     */
    private Application originalApplication;

    /**
     * Creates a new SpringApplication object.
     */
    public SpringApplication() {
    }

    /**
     * Creates a new SpringApplication object.
     *
     * @param aOriginalApplication pass original (may be chained)
     */
    public SpringApplication(final Application aOriginalApplication) {
        this.originalApplication = aOriginalApplication;
    }

    /**
     * Delegate to original.
     *
     * @return ActionListner.
     */
    public ActionListener getActionListener() {
        return this.originalApplication.getActionListener();
    }

    /**
     * Delegate to original.
     *
     * @param listener Delegate to original.
     */
    public void setActionListener(final ActionListener listener) {
        this.originalApplication.setActionListener(listener);
    }

    /**
     * Delegate to original.
     *
     * @return Delegate to original.
     */
    public Locale getDefaultLocale() {
        return this.originalApplication.getDefaultLocale();
    }

    /**
     * Delegate to original.
     *
     * @param locale Delegate to original.
     */
    public void setDefaultLocale(final Locale locale) {
        this.originalApplication.setDefaultLocale(locale);
    }

    /**
     * Delegate to original.
     *
     * @return Delegate to original.
     */
    public String getDefaultRenderKitId() {
        return this.originalApplication.getDefaultRenderKitId();
    }

    /**
     * Delegate to original.
     *
     * @param renderKitId Delegate to original.
     */
    public void setDefaultRenderKitId(final String renderKitId) {
        this.originalApplication.setDefaultRenderKitId(renderKitId);
    }

    /**
     * Delegate to original.
     *
     * @return Delegate to original.
     */
    public String getMessageBundle() {
        return this.originalApplication.getMessageBundle();
    }

    /**
     * Delegate to original.
     *
     * @param bundle Delegate to original.
     */
    public void setMessageBundle(final String bundle) {
        this.originalApplication.setMessageBundle(bundle);
    }

    /**
     * Return our own navigation handler.
     *
     * @return special navigation handler.
     */
    public NavigationHandler getNavigationHandler() {
        return originalApplication.getNavigationHandler();
    }

    /**
     * Delegate to original.
     *
     * @param handler Delegate to original.
     */
    public void setNavigationHandler(final NavigationHandler handler) {
        this.originalApplication.setNavigationHandler(handler);
    }

    /**
     * Delegate to original.
     *
     * @return Delegate to original.
     */
    public PropertyResolver getPropertyResolver() {
        return this.originalApplication.getPropertyResolver();
    }

    /**
     * Delegate to original.
     *
     * @param resolver Delegate to original.
     */
    public void setPropertyResolver(final PropertyResolver resolver) {
        this.originalApplication.setPropertyResolver(resolver);
    }

    /**
     * Delegate to original.
     *
     * @return Delegate to original.
     */
    public VariableResolver getVariableResolver() {
        return this.originalApplication.getVariableResolver();
    }

    /**
     * Delegate to original.
     *
     * @param resolver Delegate to original.
     */
    public void setVariableResolver(final VariableResolver resolver) {
        this.originalApplication.setVariableResolver(resolver);
    }

    /**
     * Delegate to original.
     *
     * @return Delegate to original.
     */
    public ViewHandler getViewHandler() {
        return this.originalApplication.getViewHandler();
    }

    /**
     * Delegate to original.
     *
     * @param handler Delegate to original.
     */
    public void setViewHandler(final ViewHandler handler) {
        this.originalApplication.setViewHandler(handler);
    }

    /**
     * Delegate to original.
     *
     * @return Delegate to original.
     */
    public StateManager getStateManager() {
        return this.originalApplication.getStateManager();
    }

    /**
     * Delegate to original.
     *
     * @param manager Delegate to original.
     */
    public void setStateManager(final StateManager manager) {
        this.originalApplication.setStateManager(manager);
    }

    /**
     * Delegate to original.
     *
     * @param componentType Delegate to original.
     * @param componentClass Delegate to original.
     */
    public void addComponent(final String componentType,
        final String componentClass) {
        this.originalApplication.addComponent(componentType, componentClass);
    }

    /**
     * Tries to create a UI component via the original Application and looks for
     * the UI component in Spring's root application context if it is not
     * obtainable through JSF's Application.
     * @param componentType the component type and Spring bean name for the UIComponent
     * @return the resulting UIComponent
     *         through either the JSF Application or Spring Application Context.
     */
    public UIComponent createComponent(final String componentType) {
        FacesException originalException = null;

        try {
            // Create component with original application
            if (logger.isDebugEnabled()) {
                logger.debug("Attempting to create component with type '" +
                    componentType + "' using original Application");
            }

            UIComponent originalComponent = this.originalApplication.createComponent(componentType);

            if (originalComponent != null) {
                return originalComponent;
            }

            originalException = new FacesException(
                    "Original Application returned a null component");
        } catch (FacesException e) {
            originalException = e;
        }

        // Get component from Spring root context
        if (logger.isDebugEnabled()) {
            logger.debug("Attempting to find component '" + componentType +
                "' in root WebApplicationContext");
        }

        FacesContext facesContext = FacesContext.getCurrentInstance();

        WebApplicationContext wac = getWebApplicationContext(facesContext);

        if (wac.containsBean(componentType)) {
            if (logger.isDebugEnabled()) {
                logger.debug("Successfully found component '" + componentType +
                    "' in root WebApplicationContext");
            }

            return (UIComponent) wac.getBean(componentType);
        }

        if (logger.isDebugEnabled()) {
            logger.debug("Could not create component '" + componentType + "'");
        }

        throw new FacesException(
            "Could not create component using original Application.  " +
            "Also, could not find component in root WebApplicationContext",
            originalException);
    }

    /**
     * Tries to obtain a UI component though the given value binding.
     * If a non-null component is not obtained, then this method simply
     * delegates to {@link #createComponent(String)}, passing the componentType.
     * @param componentBinding the component value binding
     * @param context the FacesContext
     * @param componentType the component type
     * @return the resulting UIComponent
     *         through either the value binding, JSF Application or Spring Application Context.
     */
    public UIComponent createComponent(final ValueBinding componentBinding,
        final FacesContext context, final String componentType) {
        FacesException originalException = null;

        try {
            // Create component with value binding
            if (logger.isDebugEnabled()) {
                logger.debug(
                    "Attempting to create component with value binding");
            }

            Object value = componentBinding.getValue(context);

            if ((value != null) && value instanceof UIComponent) {
                return (UIComponent) value;
            }

            originalException = new FacesException(
                    "Original Application returned a null component");
        } catch (FacesException e) {
            originalException = e;
        }

        try {
            // Value binding did not return a UIComponent, so attempt creation by type
            return this.createComponent(componentType);
        } catch (FacesException e) {
            throw new FacesException(originalException.getMessage() +
                " Additionally, the component could not be created based on the component type",
                e);
        }
    }

    /**
     * Delegate to original.
     *
     * @return Delegate to original.
     */
    @SuppressWarnings("unchecked")
  public Iterator getComponentTypes() {
        return this.originalApplication.getComponentTypes();
    }

    /**
     * Delegate to original.
     *
     * @param converterId Delegate to original.
     * @param converterClass Delegate to original.
     */
    public void addConverter(final String converterId,
        final String converterClass) {
        this.originalApplication.addConverter(converterId, converterClass);
    }

    /**
     * Delegate to original.
     *
     * @param targetClass Delegate to original.
     * @param converterClass Delegate to original.
     */
    @SuppressWarnings("unchecked")
  public void addConverter(final Class targetClass,
        final String converterClass) {
        this.originalApplication.addConverter(targetClass, converterClass);
    }

    /**
     * Tries to create converter via the original Application and looks for
     * the converter in Spring's root application context if it is not
     * obtainable through JSF's Application.
     * @param converterId the converter ID and Spring bean name for the Converter
     * @return the resulting Converter
     */
    public Converter createConverter(final String converterId) {
        FacesException originalException = null;
        try {
            // Create converter with original application
            if (logger.isDebugEnabled()) {
                logger.debug("Attempting to create converter with id '" +
                    converterId + "' using original Application");
            }

            Converter originalConverter = this.originalApplication.createConverter(converterId);

            if (originalConverter != null) {
                return originalConverter;
            }

            originalException = new FacesException(
                    "Original Application returned a null Converter");
        } catch (FacesException e) {
            originalException = e;
        }

        // Get converter from Spring root context
        if (logger.isDebugEnabled()) {
            logger.debug("Attempting to find converter '" + converterId +
                "' in root WebApplicationContext");
        }

        FacesContext facesContext = FacesContext.getCurrentInstance();

        WebApplicationContext wac = getWebApplicationContext(facesContext);

        if (wac.containsBean(converterId)) {
            if (logger.isDebugEnabled()) {
                logger.debug("Successfully found converter '" + converterId +
                    "' in root WebApplicationContext");
            }

            return (Converter) wac.getBean(converterId);
        }

        if (logger.isDebugEnabled()) {
            logger.debug("Could not create converter '" + converterId + "'");
        }

        throw new FacesException(
            "Could not create converter using original Application.  " +
            "Also, could not find converter in root WebApplicationContext",
            originalException);
    }

    /**
     * Tries to create converter via the original Application and looks for
     * the converter in Spring's root application context if it is not
     * obtainable through JSF's Application.
     * <p>
     * When looking for the converter in Spring, the bean name will be a
     * concatenation of the fully-qualified class name of the targetClass with
     * the suffix <code>-Converter</code>.  For example, if the target class is
     * <code>java.util.Locale</code>, then the corresponding converter would need
     * to have the bean name <code>java.util.Locale-Converter</code>.
     * @param targetClass the class on which the converter operates
     * @return the resulting Converter
     */
    @SuppressWarnings("unchecked")
  public Converter createConverter(final Class targetClass) {
        FacesException originalException = null;
       
        try {
            // Create converter with original application
            if (logger.isDebugEnabled()) {
                logger.debug("Attempting to create converter for class '" +
                    targetClass.getName() + "' using original Application");
            }

            Converter originalConverter = this.originalApplication.createConverter(targetClass);

            if (originalConverter != null) {
                return originalConverter;
            }

            originalException = new FacesException(
                    "Original Application returned a null Converter");
        } catch (FacesException e) {
            originalException = e;
        }


        FacesContext facesContext = FacesContext.getCurrentInstance();

        WebApplicationContext wac = getWebApplicationContext(facesContext);

        if (wac.containsBean("converters")) {
            Map<String, Converter> converters = (Map<String, Converter>)wac.getBean("converters");
            
            Converter converter = converters.get(CrudUtils.getClassEntityName(targetClass));
            return converter;
        }
        throw originalException;
    }

    /**
     * Delegate to original.
     *
     * @return Delegate to original.
     */
    @SuppressWarnings("unchecked")
  public Iterator getConverterIds() {
        return this.originalApplication.getConverterIds();
    }

    @SuppressWarnings("unchecked")
  private List<Class> jsfConverterTypes;
    /**
     * Delegate to original.
     *
     * @return Delegate to original.
     */
    @SuppressWarnings("unchecked")
    public Iterator<Class> getConverterTypes() {
        if (jsfConverterTypes==null) {
                FacesContext facesContext = FacesContext.getCurrentInstance();
                WebApplicationContext wac = getWebApplicationContext(facesContext);
                jsfConverterTypes = (List<Class>) wac.getBean("jsfConverterTypes");
                Iterator<Class> converterTypes = this.originalApplication.getConverterTypes();
                while ( converterTypes.hasNext() ) {
                    jsfConverterTypes.add( converterTypes.next() );
                }
               
        }
        return jsfConverterTypes.iterator();
    }

    /**
     * Delegate to original.
     *
     * @param ref Delegate to original.
     * @param params Delegate to original.
     *
     * @return Delegate to original.
     *
     */
    @SuppressWarnings("unchecked")
  public MethodBinding createMethodBinding(final String ref,
        final Class[] params) {
        return this.originalApplication.createMethodBinding(ref, params);
    }

    /**
     * Delegate to original.
     *
     * @return Delegate to original.
     */
    @SuppressWarnings("unchecked")
  public Iterator getSupportedLocales() {
        return this.originalApplication.getSupportedLocales();
    }

    /**
     * Delegate to original.
     *
     * @param locales Delegate to original.
     */
    @SuppressWarnings("unchecked")
  public void setSupportedLocales(final Collection locales) {
        this.originalApplication.setSupportedLocales(locales);
    }

    /**
     * Delegate to original.
     *
     * @param validatorId Delegate to original.
     * @param validatorClass Delegate to original.
     */
    public void addValidator(final String validatorId,
        final String validatorClass) {
        this.originalApplication.addValidator(validatorId, validatorClass);
    }

    /**
     * Tries to create validator via the original Application and looks for
     * the validator in Spring's root application context if it is not
     * obtainable through JSF's Application.
     * @param validatorId the validator ID and Spring bean name for the Validator
     * @return the resulting Validator
     */
    public Validator createValidator(final String validatorId) {
        FacesException originalException = null;

        try {
            // Create validator with original application
            if (logger.isDebugEnabled()) {
                logger.debug("Attempting to create validator with id '" +
                    validatorId + "' using original Application");
            }

            Validator originalValidator = this.originalApplication.createValidator(validatorId);

            if (originalValidator != null) {
                return originalValidator;
            }

            originalException = new FacesException(
                    "Original Application returned a null Validator");
        } catch (FacesException e) {
            originalException = e;
        }

        // Get validator from Spring root context
        if (logger.isDebugEnabled()) {
            logger.debug("Attempting to find validator '" + validatorId +
                "' in root WebApplicationContext");
        }

        FacesContext facesContext = FacesContext.getCurrentInstance();

        WebApplicationContext wac = getWebApplicationContext(facesContext);

        if (wac.containsBean(validatorId)) {
            if (logger.isDebugEnabled()) {
                logger.debug("Successfully found validator '" + validatorId +
                    "' in root WebApplicationContext");
            }

            return (Validator) wac.getBean(validatorId);
        }

        if (logger.isDebugEnabled()) {
            logger.debug("Could not create validator '" + validatorId + "'");
        }

        throw new FacesException(
            "Could not create validator using original Application.  " +
            "Also, could not find validator in root WebApplicationContext",
            originalException);
    }

    /**
     * Delegate to original.
     *
     * @return Delegate to original.
     */
    @SuppressWarnings("unchecked")
    public Iterator getValidatorIds() {
        return this.originalApplication.getValidatorIds();
    }

    /**
     * Delegate to original.
     *
     * @param ref Delegate to original.
     *
     * @return Delegate to original.
     *
     */
    public ValueBinding createValueBinding(final String ref) {
        return this.originalApplication.createValueBinding(ref);
    }

    /**
     * Retrieve the web application context to delegate bean name resolution to.
     * Default implementation delegates to FacesContextUtils.
     * @param facesContext the current JSF context
     * @return the Spring web application context
     * @see FacesContextUtils#getRequiredWebApplicationContext
     */
    protected WebApplicationContext getWebApplicationContext(
        final FacesContext facesContext) {
        return FacesContextUtils.getRequiredWebApplicationContext(facesContext);
    }

    @Override
    public void addELContextListener( ELContextListener listener ) {
        this.originalApplication.addELContextListener( listener );
    }

    @Override
    public void addELResolver( ELResolver resolver ) {
        this.originalApplication.addELResolver( resolver );
    }

    @Override
    public UIComponent createComponent( ValueExpression componentExpression, FacesContext context, String componentType ) throws FacesException {
        return this.originalApplication.createComponent( componentExpression, context, componentType );
    }

    @SuppressWarnings("unchecked")
  @Override
    public Object evaluateExpressionGet( FacesContext context, String expression, Class expectedType ) throws ELException {
        return this.originalApplication.evaluateExpressionGet( context, expression, expectedType );
    }

    @Override
    public ELContextListener[] getELContextListeners() {
        return this.originalApplication.getELContextListeners();
    }

    @Override
    public ELResolver getELResolver() {
        return this.originalApplication.getELResolver();
    }

    @Override
    public ExpressionFactory getExpressionFactory() {
        return this.originalApplication.getExpressionFactory();
    }

    @Override
    public ResourceBundle getResourceBundle( FacesContext ctx, String name ) {
        return this.originalApplication.getResourceBundle( ctx, name );
    }

    @Override
    public void removeELContextListener( ELContextListener listener ) {
        this.originalApplication.removeELContextListener( listener );
    }
}
TOP

Related Classes of org.crank.core.spring.support.SpringApplication

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.