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

org.apache.empire.jsf2.app.FacesApplication Maven / Gradle / Ivy

There is a newer version: 3.3.0
Show newest version
/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you 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.apache.empire.jsf2.app;

import java.sql.Connection;
import java.sql.SQLException;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
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.FacesMessage;
import javax.faces.application.FacesMessage.Severity;
import javax.faces.application.NavigationHandler;
import javax.faces.application.ProjectStage;
import javax.faces.application.Resource;
import javax.faces.application.ResourceHandler;
import javax.faces.application.StateManager;
import javax.faces.application.ViewHandler;
import javax.faces.component.NamingContainer;
import javax.faces.component.UIComponent;
import javax.faces.component.UIViewRoot;
import javax.faces.component.behavior.Behavior;
import javax.faces.context.FacesContext;
import javax.faces.convert.Converter;
import javax.faces.el.MethodBinding;
import javax.faces.el.PropertyResolver;
import javax.faces.el.ReferenceSyntaxException;
import javax.faces.el.ValueBinding;
import javax.faces.el.VariableResolver;
import javax.faces.event.ActionListener;
import javax.faces.event.SystemEvent;
import javax.faces.event.SystemEventListener;
import javax.faces.validator.Validator;
import javax.servlet.ServletContext;
import javax.sql.DataSource;

import org.apache.empire.commons.StringUtils;
import org.apache.empire.data.DataType;
import org.apache.empire.db.DBDatabase;
import org.apache.empire.exceptions.InternalException;
import org.apache.empire.exceptions.InvalidArgumentException;
import org.apache.empire.exceptions.NotSupportedException;
import org.apache.empire.jsf2.controls.TextAreaInputControl;
import org.apache.empire.jsf2.controls.TextInputControl;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

// import com.sun.faces.application.ApplicationImpl;

@SuppressWarnings("deprecation")
public abstract class FacesApplication extends Application
{
    private static final Logger log                   = LoggerFactory.getLogger(FacesApplication.class);

    private static final String CONNECTION_ATTRIBUTE  = "dbConnections";

    public static String        APPLICATION_ATTRIBUTE = "app";

    protected TextResolver[]    textResolvers         = null;

    private String              webRoot               = null;
    
    private Application			applImpl 			  = null;
    
    private FacesImplementation facesImpl			  = null;

    protected FacesApplication()
    { 	// subscribe
    	log.info("FacesApplication {0} created", getClass().getName());
    }
    
    public void setImplementation(FacesImplementation facesImpl, Application applImpl) 
    {
    	this.facesImpl = facesImpl;
    	this.applImpl  = applImpl; 
    }

	protected abstract DataSource getAppDataSource(DBDatabase db);

    protected abstract void init(ServletContext servletContext);

    protected void initComplete(ServletContext servletContext)
    {
        // Get Web Root
        webRoot = servletContext.getContextPath();

        // Check Text resolvers
        if (textResolvers == null)
            initTextResolvers();

        // done
        log.info("FacesApplication initialization complete");
    }

    /* Context handling */

    public void onChangeView(final FacesContext fc, String viewId)
    {
        // allow custom view change logic

        // clear page resources
        Map sm = FacesUtils.getSessionMap(fc);
        if (sm!=null)
            sm.remove(FacesUtils.PAGE_RESOURCE_MAP_ATTRIBUTE);
    }

    public void addJavascriptCall(final FacesContext fc, String function)
    {
        throw new NotSupportedException(this, "addJavascriptCall");
    }

    /**
     * return the interface for Implementation specific features 
     * that are specific for Mojarra or MyFaces
     */
    public FacesImplementation getFacesImplementation() 
    {
		return facesImpl;
	}
    
    /**
     * returns the web context path as returned from ServletContext.getContextPath()
     */
    public String getWebRoot()
    {
        return webRoot;
    }

    /**
     * returns the active locale for a given FacesContext
     */
    public Locale getContextLocale(final FacesContext ctx)
    {
        UIViewRoot root;
        // Start out with the default locale
        Locale locale;
        Locale defaultLocale = Locale.getDefault();
        locale = defaultLocale;
        // See if this FacesContext has a ViewRoot
        if (null != (root = ctx.getViewRoot()))
        {
            // If so, ask it for its Locale
            if (null == (locale = root.getLocale()))
            {
                // If the ViewRoot has no Locale, fall back to the default.
                locale = defaultLocale;
            }
        }
        return locale;
    }

    /**
     * checks if the current context contains an error
     * @param fc the FacesContext
     * @return true if the context has an error set or false otherwise
     */
    public boolean hasError(final FacesContext fc)
    {
        Iterator msgIterator = fc.getMessages();
        if (msgIterator != null)
        { // Check Messages
            while (msgIterator.hasNext())
            { // Check Severity
                Severity fms = msgIterator.next().getSeverity();
                if (fms == FacesMessage.SEVERITY_ERROR || fms == FacesMessage.SEVERITY_FATAL)
                    return true;
            }
        }
        return false;
    }

    /**
     * returns true if a form input element has been partially submitted
     * @param fc the Faces Context
     * @return the componentId or null if no partial submit was been performed
     */
    public boolean isPartialSubmit(final FacesContext fc)
    {
        // Override for your JSF component Framework. e.g. for IceFaces
        // Map parameterMap = fc.getExternalContext().getRequestParameterMap();
        // return ObjectUtils.getBoolean(parameterMap.get("ice.submit.partial"));
        return false;
    }

    /**
     * returns the componentId for which a partial submit has been performed.
     * @param fc the Faces Context
     * @return the componentId or null if no partial submit was been performed
     */
    public String getPartialSubmitComponentId(final FacesContext fc)
    {
        // Override for your JSF component Framework. e.g. for IceFaces
        // Map parameterMap = fc.getExternalContext().getRequestParameterMap();
        // return parameterMap.get("ice.event.captured");
        return null;
    }

    /**
     * finds the component with the given id that is located in the same NamingContainer as a given component 
     * @param fc the FacesContext
     * @param componentId the component id
     * @param nearComponent a component within the same naming container from which to start the search (optional)
     * @return the component or null if no component was found
     */
    public UIComponent findComponent(FacesContext fc, String componentId, UIComponent nearComponent)
    {
        if (StringUtils.isEmpty(componentId))
            throw new InvalidArgumentException("componentId", componentId);
        // Begin search near given component (if any)
        UIComponent component = null;
        if (nearComponent != null)
        {   // Search below the nearest naming container  
            component = nearComponent.findComponent(componentId);
            if (component == null)
            {   // Recurse upwards
                UIComponent nextParent = nearComponent;
                while (true)
                {
                    nextParent = nextParent.getParent();
                    // search NamingContainers only
                    while (nextParent != null && !(nextParent instanceof NamingContainer))
                    {
                        nextParent = nextParent.getParent();
                    }
                    if (nextParent == null)
                    {
                        break;
                    }
                    else
                    {
                        component = nextParent.findComponent(componentId);
                    }
                    if (component != null)
                    {
                        break;
                    }
                }
            }
        }
        // Not found. Search the entire tree 
        if (component == null)
            component = findChildComponent(fc.getViewRoot(), componentId);
        // done
        return component;
    }

    /**
     * finds a child component with the given id that is located below the given parent component 
     * @param parent the parent
     * @param componentId the component id
     * @return the component or null if no component was found
     */
    public static UIComponent findChildComponent(UIComponent parent, String componentId)
    {
        UIComponent component = null;
        if (parent.getChildCount() == 0)
            return null;
        Iterator children = parent.getChildren().iterator();
        while (children.hasNext())
        {
            UIComponent nextChild = children.next();
            if (nextChild instanceof NamingContainer)
            {
                component = nextChild.findComponent(componentId);
            }
            if (component == null)
            {
                component = findChildComponent(nextChild, componentId);
            }
            if (component != null)
            {
                break;
            }
        }
        return component;
    }

    /**
     * returns the default input control type for a given data Type
     * @see org.apache.empire.jsf2.controls.InputControlManager
     * @param dataType
     * @return an Input Cnotrol type
     */
    public String getDefaultControlType(DataType dataType)
    {
        switch (dataType)
        {
            case CLOB:
                return TextAreaInputControl.NAME;
            default:
                return TextInputControl.NAME;
        }
    }

    /* Message handling */

    protected void initTextResolvers()
    {
        int count = 0;
        Iterator locales = getSupportedLocales();
        for (count = 0; locales.hasNext(); count++)
        {
            locales.next();
        }

        // get message bundles
        String messageBundle = this.getMessageBundle();
        textResolvers = new TextResolver[count];
        locales = getSupportedLocales();
        for (int i = 0; locales.hasNext(); i++)
        {
            Locale locale = locales.next();
            textResolvers[i] = new TextResolver(ResourceBundle.getBundle(messageBundle, locale));
        }
    }

    public TextResolver getTextResolver(Locale locale)
    {
        // No text Resolvers provided
        if (textResolvers == null || textResolvers.length == 0)
        {
            throw new NotSupportedException(this, "getTextResolver");
        }
        // Lookup resolver for locale
        for (int i = 0; i < textResolvers.length; i++)
            if (locale.equals(textResolvers[i].getLocale()))
                return textResolvers[i];
        // locale not found: return default
        return textResolvers[0];
    }

    public TextResolver getTextResolver(FacesContext ctx)
    {
        return getTextResolver(getContextLocale(ctx));
    }

    /**
     * @see javax.faces.application.Application#getResourceBundle(javax.faces.context.FacesContext,
     *      String)
     */
    @Override
    public ResourceBundle getResourceBundle(final FacesContext fc, final String var)
    {
        if (var.equals("msg"))
        {
            TextResolver resolver = getTextResolver(fc);
            return resolver.getResourceBundle();
        }
        return applImpl.getResourceBundle(fc, var);
    }

    /**
     * returns a connection from the connection pool
     * 
     * @return
     */
    protected Connection getConnection(DBDatabase db)
    {
        // Get From Pool
        try
        { // Obtain a connection
            Connection conn = getAppDataSource(db).getConnection();
            conn.setAutoCommit(false);
            return conn;
        }
        catch (SQLException e)
        {
            log.error("Failed to get connection from pool.", e);
            throw new InternalException(e);
        }
    }

    /**
     * releases a connection from the connection pool
     */
    protected void releaseConnection(DBDatabase db, Connection conn, boolean commit)
    {
        try
        { // release connection
            if (conn == null)
            {
                return;
            }
            // Commit or rollback connection depending on the exit code
            if (commit)
            { // success: commit all changes
                db.commit(conn);
                log.debug("REQUEST {}: commited.");
            }
            else
            { // failure: rollback all changes
                db.rollback(conn);
                log.debug("REQUEST {}: rolled back.");
            }
            // Release Connection
            conn.close();
            // done
            if (log.isDebugEnabled())
                log.debug("REQUEST {}: returned connection to pool.");
        }
        catch (SQLException e)
        {
            log.error("Error releasing connection", e);
            e.printStackTrace();
        }
    }

    /**
     * returns a connection for the current Request
     */
    public Connection getConnectionForRequest(FacesContext fc, DBDatabase db)
    {
        if (fc == null)
            throw new InvalidArgumentException("FacesContext", fc);
        if (db == null)
            throw new InvalidArgumentException("DBDatabase", db);
        // Get Conneciton map
        @SuppressWarnings("unchecked")
        Map connMap = (Map) FacesUtils.getRequestAttribute(fc, CONNECTION_ATTRIBUTE);
        if (connMap != null && connMap.containsKey(db))
            return connMap.get(db);
        // Pooled Connection
        Connection conn = getConnection(db);
        if (conn == null)
            return null;
        // Add to map
        if (connMap == null)
        {
            connMap = new HashMap();
            FacesUtils.setRequestAttribute(fc, CONNECTION_ATTRIBUTE, connMap);
        }
        connMap.put(db, conn);
        return conn;
    }

    /**
     * releases the current request connection
     * @param fc the FacesContext
     * @param commit when true changes are committed otherwise they are rolled back
     */
    public void releaseAllConnections(final FacesContext fc, boolean commit)
    {
        @SuppressWarnings("unchecked")
        Map connMap = (Map) FacesUtils.getRequestAttribute(fc, CONNECTION_ATTRIBUTE);
        if (connMap != null)
        { // Walk the connection map
            for (Map.Entry e : connMap.entrySet())
            {
                releaseConnection(e.getKey(), e.getValue(), commit);
            }
            // remove from request map
            FacesUtils.setRequestAttribute(fc, CONNECTION_ATTRIBUTE, null);
        }
    }

    public void releaseAllConnections(final FacesContext fc)
    {
        releaseAllConnections(fc, !hasError(fc));
    }

    public void releaseConnection(final FacesContext fc, DBDatabase db, boolean commit)
    {
        @SuppressWarnings("unchecked")
        Map connMap = (Map) FacesUtils.getRequestAttribute(fc, CONNECTION_ATTRIBUTE);
        if (connMap != null && connMap.containsKey(db))
        { // Walk the connection map
            releaseConnection(db, connMap.get(db), commit);
            connMap.remove(db);
            if (connMap.size() == 0)
                FacesUtils.setRequestAttribute(fc, CONNECTION_ATTRIBUTE, null);
        }
    }

    public void releaseConnection(final FacesContext fc, DBDatabase db)
    {
        releaseConnection(fc, db, !hasError(fc));
    }
    
    /************************************************************/

	@Override
	public void addBehavior(String behaviorId, String behaviorClass) {
		// Forward to implementation
		applImpl.addBehavior(behaviorId, behaviorClass);
	}

	@Override
	public void addComponent(String componentType, String componentClass) {
		// Forward to implementation
		applImpl.addComponent(componentType, componentClass);
	}

	@Override
	public void addConverter(Class targetClass, String converterClass) {
		// Forward to implementation
		applImpl.addConverter(targetClass, converterClass);
	}

	@Override
	public void addConverter(String converterId, String converterClass) {
		// Forward to implementation
		applImpl.addConverter(converterId, converterClass);
	}

	@Override
	public void addDefaultValidatorId(String validatorId) {
		// Forward to implementation
		applImpl.addDefaultValidatorId(validatorId);
	}

	@Override
	public void addELContextListener(ELContextListener listener) {
		// Forward to implementation
		applImpl.addELContextListener(listener);
	}

	@Override
	public void addELResolver(ELResolver resolver) {
		// Forward to implementation
		applImpl.addELResolver(resolver);
	}

	@Override
	public void addValidator(String validatorId, String validatorClass) {
		// Forward to implementation
		applImpl.addValidator(validatorId, validatorClass);
	}

	@Override
	public Behavior createBehavior(String behaviorId) throws FacesException {
		// Forward to implementation
		return applImpl.createBehavior(behaviorId);
	}

	@Override
	public UIComponent createComponent(FacesContext context,
			Resource componentResource) {
		// Forward to implementation
		return applImpl.createComponent(context, componentResource);
	}

	@Override
	public UIComponent createComponent(FacesContext context,
			String componentType, String rendererType) {
		// Forward to implementation
		return applImpl.createComponent(context, componentType, rendererType);
	}

	@Override
	public UIComponent createComponent(String componentType)
			throws FacesException {
		// Forward to implementation
		return applImpl.createComponent(componentType);
	}

	@Override
	public UIComponent createComponent(ValueBinding componentBinding,
			FacesContext context, String componentType) throws FacesException {
		// Forward to implementation
		return applImpl.createComponent(componentBinding, context, componentType);
	}

	@Override
	public UIComponent createComponent(ValueExpression componentExpression,
			FacesContext context, String componentType) throws FacesException {
		// Forward to implementation
		return applImpl.createComponent(componentExpression, context, componentType);
	}

	@Override
	public UIComponent createComponent(ValueExpression componentExpression,
			FacesContext context, String componentType, String rendererType) {
		// Forward to implementation
		return applImpl.createComponent(componentExpression, context, componentType, rendererType);
	}

	@Override
	public Converter createConverter(Class targetClass) {
		// Forward to implementation
		return applImpl.createConverter(targetClass);
	}

	@Override
	public Converter createConverter(String converterId) {
		// Forward to implementation
		return applImpl.createConverter(converterId);
	}

	@Override
	public MethodBinding createMethodBinding(String ref, Class[] params)
			throws ReferenceSyntaxException {
		// Forward to implementation
		return applImpl.createMethodBinding(ref, params);
	}

	@Override
	public Validator createValidator(String validatorId) throws FacesException {
		// Forward to implementation
		return applImpl.createValidator(validatorId);
	}

	@Override
	public ValueBinding createValueBinding(String ref)
			throws ReferenceSyntaxException {
		// Forward to implementation
		return applImpl.createValueBinding(ref);
	}

	@Override
	public  T evaluateExpressionGet(FacesContext context, String expression,
			Class expectedType) throws ELException {
		// Forward to implementation
		return applImpl.evaluateExpressionGet(context, expression, expectedType);
	}

	@Override
	public ActionListener getActionListener() {
		// Forward to implementation
		return applImpl.getActionListener();
	}

	@Override
	public Iterator getBehaviorIds() {
		// Forward to implementation
		return applImpl.getBehaviorIds();
	}

	@Override
	public Iterator getComponentTypes() {
		// Forward to implementation
		return applImpl.getComponentTypes();
	}

	@Override
	public Iterator getConverterIds() {
		// Forward to implementation
		return applImpl.getConverterIds();
	}

	@Override
	public Iterator> getConverterTypes() {
		// Forward to implementation
		return applImpl.getConverterTypes();
	}

	@Override
	public Locale getDefaultLocale() {
		// Forward to implementation
		return applImpl.getDefaultLocale();
	}

	@Override
	public String getDefaultRenderKitId() {
		// Forward to implementation
		return applImpl.getDefaultRenderKitId();
	}

	@Override
	public Map getDefaultValidatorInfo() {
		// Forward to implementation
		return applImpl.getDefaultValidatorInfo();
	}

	@Override
	public ELContextListener[] getELContextListeners() {
		// Forward to implementation
		return applImpl.getELContextListeners();
	}

	@Override
	public ELResolver getELResolver() {
		// Forward to implementation
		return applImpl.getELResolver();
	}

	@Override
	public ExpressionFactory getExpressionFactory() {
		// Forward to implementation
		return applImpl.getExpressionFactory();
	}

	@Override
	public String getMessageBundle() {
		// Forward to implementation
		return applImpl.getMessageBundle();
	}

	@Override
	public NavigationHandler getNavigationHandler() {
		// Forward to implementation
		return applImpl.getNavigationHandler();
	}

	@Override
	public ProjectStage getProjectStage() {
		// Forward to implementation
		return applImpl.getProjectStage();
	}

	@Override
	public PropertyResolver getPropertyResolver() {
		// Forward to implementation
		return applImpl.getPropertyResolver();
	}

	@Override
	public ResourceHandler getResourceHandler() {
		// Forward to implementation
		return applImpl.getResourceHandler();
	}

	@Override
	public StateManager getStateManager() {
		// Forward to implementation
		return applImpl.getStateManager();
	}

	@Override
	public Iterator getSupportedLocales() {
		// Forward to implementation
		return applImpl.getSupportedLocales();
	}

	@Override
	public Iterator getValidatorIds() {
		// Forward to implementation
		return applImpl.getValidatorIds();
	}

	@Override
	public VariableResolver getVariableResolver() {
		// Forward to implementation
		return applImpl.getVariableResolver();
	}

	@Override
	public ViewHandler getViewHandler() {
		// Forward to implementation
		return applImpl.getViewHandler();
	}

	@Override
	public void publishEvent(FacesContext facesContext,
			Class systemEventClass,
			Class sourceBaseType, Object source) {
		// Forward to implementation
		applImpl.publishEvent(facesContext, systemEventClass, sourceBaseType, source);
	}

	@Override
	public void publishEvent(FacesContext facesContext,
			Class systemEventClass, Object source) {
		// Forward to implementation
		applImpl.publishEvent(facesContext, systemEventClass, source);
	}

	@Override
	public void removeELContextListener(ELContextListener listener) {
		// Forward to implementation
		applImpl.removeELContextListener(listener);
	}

	@Override
	public void setActionListener(ActionListener listener) {
		// Forward to implementation
		applImpl.setActionListener(listener);
	}

	@Override
	public void setDefaultLocale(Locale locale) {
		// Forward to implementation
		applImpl.setDefaultLocale(locale);
	}

	@Override
	public void setDefaultRenderKitId(String renderKitId) {
		// Forward to implementation
		applImpl.setDefaultRenderKitId(renderKitId);
	}

	@Override
	public void setMessageBundle(String bundle) {
		// Forward to implementation
		applImpl.setMessageBundle(bundle);
	}

	@Override
	public void setNavigationHandler(NavigationHandler handler) {
		// Forward to implementation
		applImpl.setNavigationHandler(handler);
	}

	@Override
	public void setPropertyResolver(PropertyResolver resolver) {
		// Forward to implementation
		applImpl.setPropertyResolver(resolver);
	}

	@Override
	public void setResourceHandler(ResourceHandler resourceHandler) {
		// Forward to implementation
		applImpl.setResourceHandler(resourceHandler);
	}

	@Override
	public void setStateManager(StateManager manager) {
		// Forward to implementation
		applImpl.setStateManager(manager);
	}

	@Override
	public void setSupportedLocales(Collection locales) {
		// Forward to implementation
		applImpl.setSupportedLocales(locales);
	}

	@Override
	public void setVariableResolver(VariableResolver resolver) {
		// Forward to implementation
		applImpl.setVariableResolver(resolver);
	}

	@Override
	public void setViewHandler(ViewHandler handler) {
		// Forward to implementation
		applImpl.setViewHandler(handler);
	}

	@Override
	public void subscribeToEvent(Class systemEventClass,
			Class sourceClass, SystemEventListener listener) {
		// Forward to implementation
		applImpl.subscribeToEvent(systemEventClass, sourceClass, listener);
	}

	@Override
	public void subscribeToEvent(Class systemEventClass,
			SystemEventListener listener) {
		// Forward to implementation
		applImpl.subscribeToEvent(systemEventClass, listener);
	}

	@Override
	public void unsubscribeFromEvent(
			Class systemEventClass,
			Class sourceClass, SystemEventListener listener) {
		// Forward to implementation
		applImpl.unsubscribeFromEvent(systemEventClass, sourceClass, listener);
	}

	@Override
	public void unsubscribeFromEvent(
			Class systemEventClass,
			SystemEventListener listener) {
		// Forward to implementation
		applImpl.unsubscribeFromEvent(systemEventClass, listener);
	}

    /************************************************************/
    
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy