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

org.ajax4jsf.ajax.UIAjaxSupport Maven / Gradle / Ivy

/**
 * Copyright 2004 The Apache Software Foundation.
 *
 * 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.ajax4jsf.ajax;

import java.io.Serializable;

import javax.faces.FacesException;
import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.el.ValueBinding;

import org.ajax4jsf.framework.ajax.AjaxActionComponent;
import org.ajax4jsf.framework.ajax.AjaxSupport;
import org.ajax4jsf.framework.ajax.EventValueBinding;
import org.ajax4jsf.framework.renderer.AjaxRendererUtils;
import org.ajax4jsf.framework.util.message.Messages;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;


/**
 * Component for append ajax functions to any control component.
 * Append action functionality to non-action control,
 * setup javascript events for parent component,
 * @author shura (latest modification by $Author: alexsmirnov $)
 * @version $Revision: 1.11 $ $Date: 2006/12/08 15:20:45 $
 *
 */
public abstract class UIAjaxSupport extends AjaxActionComponent implements  AjaxSupport
{

    //~ Static fields/initializers ---------------------------------------------

    public static final String COMPONENT_TYPE = "org.ajax4jsf.ajax.Support";
    public static final String COMPONENT_FAMILY = "javax.faces.Command";
    public static final String DEFAULT_RENDERER_TYPE = "org.ajax4jsf.components.AjaxSupportRenderer";
    public static final String AJAX_SUPPORT_SET = "com.exadel.components.ajax.support.";
    private static final Log log = LogFactory.getLog(UIAjaxSupport.class);

    /**
     * String, Collection or array of component's Id , updated in case of Ajax request by parent component.
     */
    private Object _reRender = null;

    /* (non-Javadoc)
     * @see org.ajax4jsf.components.custom.ajax.AjaxComponent#setTargetId(java.lang.Object)
     */
    public void setReRender(Object targetId)
    {
        this._reRender = targetId;
    }

    /* (non-Javadoc)
     * @see org.ajax4jsf.components.custom.ajax.AjaxComponent#getTargetId()
     */
    public Object getReRender()
    {
        return getValueOrBinding(_reRender, "reRender");
    }

    /**
     * Name of event property of parent component for build JavaScript AJAX.Submit call
     */
    private String _event = null;

    /* (non-Javadoc)
     * @see org.ajax4jsf.components.custom.ajax.AjaxComponent#setEvent(java.lang.String)
     */
    public void setEvent(String event)
    {
        this._event = event;
    }

    /* (non-Javadoc)
     * @see org.ajax4jsf.components.custom.ajax.AjaxComponent#getEvent()
     */
    public String getEvent()
    {
        return this._event;
    }

    /**
     * Id ( in format of UIComponent.findComponent() call ) of request status indicator 
     */
    private String _status = null;

    /* (non-Javadoc)
     * @see org.ajax4jsf.components.custom.ajax.AjaxComponent#setStatus(java.lang.String)
     */
    public void setStatus(String status)
    {
        this._status = status;
    }

    /* (non-Javadoc)
     * @see org.ajax4jsf.components.custom.ajax.AjaxComponent#getStatus()
     */
    public String getStatus()
    {
        return (String) getValueOrBinding(_status, "status");
    }

    /**
     * Name of JavaScript function, called on complete Ajax request
     */
    private String _oncomplete = null;

    /* (non-Javadoc)
     * @see org.ajax4jsf.components.custom.ajax.AjaxComponent#setOncomplete(java.lang.String)
     */
    public void setOncomplete(String oncomplete)
    {
        this._oncomplete = oncomplete;
    }

    /* (non-Javadoc)
     * @see org.ajax4jsf.components.custom.ajax.AjaxComponent#getOncomplete()
     */
    public String getOncomplete()
    {
        return (String) getValueOrBinding(_oncomplete, "oncomplete");
    }

    /**
     * Name of JavaScript function, called before submit Ajax request
     */
    private String _onsubmit = null;

    public void setOnsubmit(String onsubmit)
    {
        this._onsubmit = onsubmit;
    }

    public String getOnsubmit()
    {
        return (String) getValueOrBinding(_onsubmit, "onsubmit");
    }
    /**
     * Submit ( or not ) full form on Ajax action.
     */
    private boolean _limitToList = false;
    private boolean _limitToListSet = false;

    /* (non-Javadoc)
     * @see org.ajax4jsf.components.custom.ajax.AjaxComponent#setLimitToList(boolean)
     */
    public void setLimitToList(boolean submitForm)
    {
        this._limitToList = submitForm;
        this._limitToListSet = true;
    }

    
    /* (non-Javadoc)
     * @see org.ajax4jsf.components.custom.ajax.AjaxComponent#isLimitToList()
     */
    public boolean isLimitToList()
    {
        return isValueOrBinding(_limitToList, _limitToListSet, "limitToList");
    }

    /**
     * Submit ( or not ) full form on Ajax action.
     */
    private boolean _ajaxSingle = false;
    private boolean _ajaxSingleSet = false;

    /* (non-Javadoc)
     * @see org.ajax4jsf.components.custom.ajax.AjaxComponent#setLimitToList(boolean)
     */
    public void setAjaxSingle(boolean submitForm)
    {
        this._ajaxSingle = submitForm;
        this._ajaxSingleSet = true;
    }

    
    /* (non-Javadoc)
     * @see org.ajax4jsf.components.custom.ajax.AjaxComponent#isLimitToList()
     */
    public boolean isAjaxSingle()
    {
        return isValueOrBinding(_ajaxSingle, _ajaxSingleSet, "ajaxSingle");
    }
    
    
    /* (non-Javadoc)
	 * @see javax.faces.component.UIComponentBase#setValueBinding(java.lang.String, javax.faces.el.ValueBinding)
	 */
	public void setValueBinding(String arg0, ValueBinding arg1) {
		// var - not allowed name. must be literal.
		if("var".equals(arg0)){
			throw new FacesException(
					Messages.getMessage(Messages.VAR_MUST_BE_LITERAL, getClientId(getFacesContext())));
		}
		if("event".equals(arg0)){
			throw new FacesException(
					Messages.getMessage(Messages.EVENT_MUST_BE_LITERAL, getClientId(getFacesContext())));
		}
		super.setValueBinding(arg0, arg1);
	}

	/**
     * @param field - value of field to get.
     * @param name - name of field, to get from ValueBinding
     * @return field or value of binding expression.
     */
    private Object getValueOrBinding(Object field, String name)
    {
        if (null != field)
        {
            return field;
        }
        ValueBinding vb = getValueBinding(name);
        if (null != vb)
        {
            return vb.getValue(getFacesContext());
        }
        else
        {
            return null;
        }

    }

    /**
     * @param field - value of field to get.
     * @param name - name of field, to get from ValueBinding
     * @return boolean value, based on field or valuebinding.
     */
    private boolean isValueOrBinding(boolean field, boolean fieldSet,
            String name)
    {
        if (fieldSet)
        {
            return field;
        }
        ValueBinding vb = getValueBinding(name);
        if (null != vb)
        {
            return ((Boolean) vb.getValue(getFacesContext())).booleanValue();
        }
        else
        {
            return false;
        }

    }

    /**
     * Create Special ValueBinding for build JavaScrept
     * event code in parent component from this.
     * @return EventValueBinding based on properties of current component
     */
    private ValueBinding getEventValueBinding()
    {
        if (log.isDebugEnabled())
        {
            log.debug(Messages.getMessage(Messages.CREATE_JAVASCRIPT_EVENT, getId()));
        }
        return new EventValueBinding(this);
    }

    /**
     * @return JavaScript eventString. Rebuild on every call, since
     * can be in loop ( as in dataTable ) with different parameters.
     */
    public String getEventString()
    {
        StringBuffer buildOnEvent = new StringBuffer();
        String onsubmit = getOnsubmit();
        // Insert script to call before submit ajax request.
        if (null != onsubmit) {
			buildOnEvent.append(onsubmit).append(";");
		}
        // Due to JSF RI 1.1 bug, clear cached clientId
        setId(getId());
		buildOnEvent.append(AjaxRendererUtils.buildOnEvent(this, getFacesContext(),
				                getEvent()));
		String script = buildOnEvent.toString();
		return script;
    }

    
    /**
     * After nornal setting parent property in case of
     * created component set Ajax properties for parent.
     * @see javax.faces.component.UIComponentBase#setParent(javax.faces.component.UIComponent)
     */
    public void setParent(UIComponent parent)
    {
        super.setParent(parent);
        if (null != parent && parent.getFamily() != null ) {
			if (log.isDebugEnabled()) {
				log.debug(Messages.getMessage(Messages.CALLED_SET_PARENT, parent.getClass().getName()));
			}
			// TODO If this comopnent configured, set properties for parent component.
			// NEW created component have parent, restored view - null in My faces.
			// and SUN RI not call at restore saved view. 
			// In other case - set in restoreState method.
			//        if (parent.getParent() != null)
			{
				if (log.isDebugEnabled()) {
					log.debug(Messages.getMessage(Messages.DETECT_NEW_COMPONENT));
				}
				setParentProperties(parent);

			}
		}
    }

    public void setParentProperties(UIComponent parent) {
        ValueBinding valueBinding;
//        Map parentAttributes = parent.getAttributes();
/*        if (parent instanceof ActionSource && null == getEvent())
        {
            log.debug("Set properties for parent as ActionSource");
            // Translate AJAX properties to parent component.
            if (_reRender != null)
            {
                parentAttributes
                        .put(AjaxRendererUtils.AJAX_REGIONS_ATTRIBUTE,
                                _reRender);
            }
            else if ((valueBinding = getValueBinding("reRender")) != null)
            {
                parent.setValueBinding(
                        AjaxRendererUtils.AJAX_REGIONS_ATTRIBUTE,
                        valueBinding);
            }
            if (_oncomplete != null)
            {
                parentAttributes
                        .put(AjaxRendererUtils.ONCOMPLETE_ATTR_NAME,
                                _oncomplete);
            }
            else if ((valueBinding = getValueBinding("oncomplete")) != null)
            {
                parent.setValueBinding(
                        AjaxRendererUtils.ONCOMPLETE_ATTR_NAME,
                        valueBinding);
            }
            if (_status != null)
            {
                parentAttributes.put(AjaxRendererUtils.STATUS_ATTR_NAME,
                        _status);
            }
            else if ((valueBinding = getValueBinding("status")) != null)
            {
                parent.setValueBinding(AjaxRendererUtils.STATUS_ATTR_NAME,
                        valueBinding);
            }
            if (_limitToListSet)
            {
                parentAttributes.put(
                        AjaxRendererUtils.LIMITTOLIST_ATTR_NAME, Boolean
                                .valueOf(_limitToList));
            }
            else if ((valueBinding = getValueBinding("limitToList")) != null)
            {
                parent.setValueBinding(
                        AjaxRendererUtils.LIMITTOLIST_ATTR_NAME,
                        valueBinding);
            }
            // Add Listener for all supported types.
            AjaxRegionListener listener = new AjaxRegionListener();
            ((ActionSource) parent).addActionListener(listener);
        }
        else*/ if (null != getEvent())
        {
            if (log.isDebugEnabled())
            {
                log.debug(Messages.getMessage(Messages.SET_VALUE_BINDING_FOR_EVENT, getEvent()));
            }
            // for non action/data components, or for non-default events - build listener for this instance. 
            valueBinding = getEventValueBinding();
            // test for valid event attribute name.
            // TODO - test for compability with concrete element.
            parent.setValueBinding(getEvent(), valueBinding);
        }

    }
    /* (non-Javadoc)
     * @see javax.faces.component.UICommand#restoreState(javax.faces.context.FacesContext, java.lang.Object)
     */
    public void restoreState(FacesContext context, Object state)
    {
        State myState = (State) state;
        _reRender = myState._reRender;
        _event = myState._event;
        _status = myState._status;
        _oncomplete = myState._oncomplete;
        _onsubmit = myState._onsubmit;
        _limitToList = myState._limitToList;
        _limitToListSet = myState._limitToListSet;
        _ajaxSingle = myState._ajaxSingle;
        _ajaxSingleSet = myState._ajaxSingleSet;
        super.restoreState(context, myState._parentState);
    }

    /* (non-Javadoc)
     * @see javax.faces.component.UICommand#saveState(javax.faces.context.FacesContext)
     */
    public Object saveState(FacesContext context)
    {
        State state = new State();
        state._parentState = super.saveState(context);
        state._event = _event;
        state._oncomplete = _oncomplete;
        state._onsubmit = _onsubmit;
        state._status = _status;
        state._reRender = _reRender;
        state._limitToList = _limitToList;
        state._limitToListSet = _limitToListSet;
        state._ajaxSingle = _ajaxSingle;
        state._ajaxSingleSet = _ajaxSingleSet;
        return state;
    }

    /**
     * Memento pattern state class for save component state.
     * @author shura (latest modification by $Author: alexsmirnov $)
     * @version $Revision: 1.11 $ $Date: 2006/12/08 15:20:45 $
     *
     */
    public static class State implements Serializable
    {
        /**
         * 
         */
        private static final long serialVersionUID = -8985312824443671L;
        Object _parentState = null;
        Object _reRender = null;
        String _event = null;
        String _status = null;
        String _oncomplete = null;
        String _onsubmit = null;
        boolean _limitToList = false;
        boolean _limitToListSet = false;
        String _ajaxType = null;
        boolean _ajaxSingle = false;
        boolean _ajaxSingleSet = false;
    }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy