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

org.ajax4jsf.framework.renderer.RendererBase Maven / Gradle / Ivy

Go to download

Ajax4jsf is an open source extension to the JavaServer Faces standard that adds AJAX capability to JSF applications without requiring the writing of any JavaScript.

The newest version!
/**
 * Licensed under the Common Development and Distribution License,
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 *   http://www.sun.com/cddl/
 *   
 * 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.framework.renderer;

import java.io.IOException;
import java.util.Iterator;

import javax.faces.FacesException;
import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.context.ResponseWriter;
import javax.faces.render.Renderer;

import org.ajax4jsf.framework.resource.InternetResource;
import org.ajax4jsf.framework.resource.InternetResourceBuilder;
import org.ajax4jsf.framework.resource.ResourceNotFoundException;
import org.ajax4jsf.framework.skin.Skin;
import org.ajax4jsf.framework.skin.SkinFactory;
import org.ajax4jsf.framework.util.message.Messages;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;


/**
 * Base Renderer for all chameleon Skin's and components.
 * At most, make all common procedures and realise concrete work in "template" methods. 
 * @author [email protected] (latest modification by $Author: alexsmirnov $)
 * @version $Revision: 1.4 $ $Date: 2006/08/18 17:45:26 $
 *
 */
public abstract class RendererBase extends Renderer implements
		ChameleonRenderer {
	
	/**
	 * logger for common cases. 
	 */
	protected static final String JAVASCRIPT_NAMESPACE = "Exadel";
	private static final Log log = LogFactory.getLog(RendererBase.class);
	private static final RendererUtils utils = new RendererUtils();

	private SkinFactory skinFactory = null;
	private InternetResourceBuilder resourceBuilder = null;
	/* (non-Javadoc)
	 * @see javax.faces.render.Renderer#decode(javax.faces.context.FacesContext, javax.faces.component.UIComponent)
	 */
	public void decode(FacesContext context, UIComponent component) {
		// Test for correct parameters.
        if (context == null) throw new NullPointerException(Messages.getMessage(Messages.CONTEXT_NULL_ERROR, "decode"));
        if (component == null) throw new NullPointerException(Messages.getMessage(Messages.COMPONENT_NULL_ERROR, "decode"));
        if (! getComponentClass().isInstance(component)) throw new IllegalArgumentException(Messages.getMessage(Messages.COMPONENT_CLASS_ERROR, "", getComponentClass().getName()));
        if(log.isDebugEnabled()){
        	log.debug(Messages.getMessage(Messages.START_DECODING_COMPONENT_INFO, component.getClientId(context), component.getClass().getName()));
        }		
		preDecode(context,component);
        // TODO - create set od common decoders ( UIInput, ActionSource etc. ) for process decoding.
        if (component.isRendered()) {
			doDecode(context, component);
		}
	}

	protected void preDecode(FacesContext context, UIComponent component)   {
	}

	/* (non-Javadoc)
	 * @see javax.faces.render.Renderer#encodeBegin(javax.faces.context.FacesContext, javax.faces.component.UIComponent)
	 */
	public void encodeBegin(FacesContext context, UIComponent component) throws IOException {
		// Test for correct parameters.
        if (context == null) throw new NullPointerException(Messages.getMessage(Messages.CONTEXT_NULL_ERROR, "encodeBegin"));
        if (component == null) throw new NullPointerException(Messages.getMessage(Messages.COMPONENT_NULL_ERROR, "encodeBegin"));
        if (! getComponentClass().isInstance(component)) throw new IllegalArgumentException(Messages.getMessage(Messages.COMPONENT_CLASS_ERROR, component.getClientId(context), getComponentClass().getName()));
        if(log.isDebugEnabled()){
        	log.debug(Messages.getMessage(Messages.START_ENCODING_COMPONENT_INFO, component.getClientId(context), component.getClass().getName()));
        }
		preEncodeBegin(context,component);
        if (component.isRendered()) {
			ResponseWriter writer = context.getResponseWriter();
			doEncodeBegin(writer, context, component);
		}
	}

	protected void preEncodeBegin(FacesContext context, UIComponent component) throws IOException  {
		
	}
	/* (non-Javadoc)
	 * @see javax.faces.render.Renderer#encodeEnd(javax.faces.context.FacesContext, javax.faces.component.UIComponent)
	 */
	public void encodeEnd(FacesContext context, UIComponent component) throws IOException {
		// Test for correct parameters.
        if (context == null) throw new NullPointerException(Messages.getMessage(Messages.CONTEXT_NULL_ERROR, "encodeEnd"));
        if (component == null) throw new NullPointerException(Messages.getMessage(Messages.COMPONENT_NULL_ERROR, "encodeEnd"));
        if (! getComponentClass().isInstance(component)) throw new IllegalArgumentException(Messages.getMessage(Messages.COMPONENT_CLASS_ERROR, component.getClientId(context), getComponentClass().getName()));
        if (component.isRendered()) {
			ResponseWriter writer = context.getResponseWriter();
			doEncodeEnd(writer, context, component);
		}
        if(log.isDebugEnabled()){
        	log.debug(Messages.getMessage(Messages.FINISH_ENCODING_COMPONENT_INFO, component.getClientId(context), component.getClass().getName()));
        }
	}

	/**
	 * Base stub method for produce internet resource ( image, script ... )
	 * since resources must be implemented in "lightweight" pattern, it instances
	 * put in internal map to caching.
	 * @param resourceURI - relative ( to renderer class ) uri to resource in jar or
	 * key for generate ( in Java2D , for example ). 
	 * @return - resource instance for this uri.
	 * @throws ResourceNotFoundException - if reqested resource not instantiated.
	 */
	public InternetResource getResource(String resourceURI ) throws FacesException {
		return getResourceBuilder().createResource(this,resourceURI);
	}

	private InternetResourceBuilder getResourceBuilder(){
		if (resourceBuilder == null) {
			resourceBuilder = InternetResourceBuilder.getInstance();
			
		}

		return resourceBuilder;
	}
	//==========================================================
	// Protected common methods - for all Renderer's
	
	/**
	 * Calculate current Skin for rendering.
	 * @param context - current {@link FacesContext }
	 * @return
	 */
	protected Skin	getSkin(FacesContext context) {
		if (skinFactory == null) {
			skinFactory = SkinFactory.getInstance();
			
		}

		return skinFactory.getSkin(context);
	}
	
	
	/**
	 * Due to big number of common utility methods, base renderer divide to 2 classes - renderer and utils.
	 * since use static methods of utility class breack object paradigm, we use getter for concrete util instance.
	 * Developer can override any utility metod in 2 stages :
	 * 1) Create subclass of {@link RendererUtils} and override utility method.
	 * 2) Override this method for return instance of such subclass.
	 * 
	 * @return Returns the utils.
	 */
	public RendererUtils getUtils() {
		return utils;
	}


	/**
	 * Get base component slass , targetted for this renderer. Used for check arguments in decode/encode.
	 * @return
	 */
	protected abstract Class getComponentClass();


	/**
	 * Template method for custom decoding of concrete renderer.
	 * All parameters checking if performed in original {@see decode } method.
	 * @param context
	 * @param component
	 */
	protected void doDecode(FacesContext context, UIComponent component) {
		
	}

	/**
	 * Template method for custom start encoding of concrete renderer.
	 * All parameters checking and writer is performed in original {@link encodeBegin } method.
	 * @param writer
	 * @param context
	 * @param component
	 */
	protected void doEncodeBegin(ResponseWriter writer,FacesContext context, UIComponent component) throws IOException {
		
	}
	/**
	 * Template method for custom finish encoding of concrete renderer.
	 * All parameters checking and writer is performed in original {@link encodeEnd } method.
	 * @param writer
	 * @param context
	 * @param component
	 * @throws IOException 
	 */
	protected void doEncodeEnd(ResponseWriter writer, FacesContext context, UIComponent component) throws IOException {
		
	}
	/**
	 * Append new resource to renderer cache.
	 * @param key
	 * @param resource
	 */
	protected void addResource(String key, InternetResource resource) {
		getResourceBuilder().addResource(key,resource);
	}

    /**
     * Render all children for given component.
     * @param facesContext
     * @param component
     * @throws IOException
     */
    public void renderChildren(FacesContext facesContext,
			UIComponent component) throws IOException {
		if (component.getChildCount() > 0) {
			for (Iterator it = component.getChildren().iterator(); it.hasNext();) {
				UIComponent child = (UIComponent) it.next();
				renderChild(facesContext, child);
			}
		}
	}


	/**
	 * Render one component and it childrens
	 * @param facesContext
	 * @param child
	 * @throws IOException
	 */
	public void renderChild(FacesContext facesContext, UIComponent child)
			throws IOException {
		if (!child.isRendered()) {
			return;
		}

		child.encodeBegin(facesContext);
		if (child.getRendersChildren()) {
			child.encodeChildren(facesContext);
		} else {
			renderChildren(facesContext, child);
		}
		child.encodeEnd(facesContext);
	}

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy