org.apache.myfaces.custom.skin.SkinRenderer.java Source code

Java tutorial

Introduction

Here is the source code for org.apache.myfaces.custom.skin.SkinRenderer.java

Source

/*
 *  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.myfaces.custom.skin;

import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.convert.ConverterException;
import javax.faces.render.Renderer;

import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.myfaces.trinidad.context.SkinRenderingContext;
import org.apache.myfaces.trinidad.skin.Icon;
import org.apache.myfaces.trinidadinternal.skin.icon.ContextImageIcon;

/**
 * This class encapsulate Renderers of other RenderKits and add trinidad
 * skinning features. It implements a Decorator pattern style
 * 
 * @author Leonardo Uribe
 */
public abstract class SkinRenderer extends Renderer {

    /**
     * The renderer that encapsulate it
     */
    protected Renderer _delegate;

    /**
     * The log factory used to debug messages
     */
    private static final Log log = LogFactory.getLog(SkinRenderer.class);

    private String _componentTagName = null;

    private String _namespace = null;

    /**
     * Constructor
     * 
     * Save its delegate renderer
     * 
     * @param delegate
     */
    public SkinRenderer(Renderer delegate) {
        _delegate = delegate;
    }

    public SkinRenderer() {
    }

    @Override
    public String convertClientId(FacesContext context, String clientId) {
        if (_delegate == null) {
            return super.convertClientId(context, clientId);
        } else {
            return _delegate.convertClientId(context, clientId);
        }
    }

    @Override
    public void decode(FacesContext context, UIComponent component) {
        if (_delegate == null) {
            super.decode(context, component);
        } else {
            _delegate.decode(context, component);
        }
    }

    protected abstract void _addStyleClassesToComponent(FacesContext context, UIComponent component,
            SkinRenderingContext arc) throws IOException;

    @Override
    public void encodeBegin(FacesContext context, UIComponent component) throws IOException {

        SkinRenderingContext arc = SkinRenderingContext.getCurrentInstance();
        if (arc == null)
            throw new IllegalStateException(("NO_RENDERINGCONTEXT"));

        this._addStyleClassesToComponent(context, component, arc);

        // Call encode of delegate or parent
        if (_delegate == null) {
            super.encodeBegin(context, component);
        } else {
            _delegate.encodeBegin(context, component);
        }
    }

    @Override
    public void encodeChildren(FacesContext context, UIComponent component) throws IOException {
        if (_delegate == null) {
            super.encodeChildren(context, component);
        } else {
            _delegate.encodeChildren(context, component);
        }
    }

    @Override
    public void encodeEnd(FacesContext context, UIComponent component) throws IOException {

        if (_delegate == null) {
            super.encodeEnd(context, component);
        } else {
            _delegate.encodeEnd(context, component);
        }
    }

    @Override
    public Object getConvertedValue(FacesContext context, UIComponent component, Object submittedValue)
            throws ConverterException {
        if (_delegate == null) {
            return super.getConvertedValue(context, component, submittedValue);
        } else {
            return _delegate.getConvertedValue(context, component, submittedValue);
        }
    }

    @Override
    public boolean getRendersChildren() {
        if (_delegate == null) {
            return super.getRendersChildren();
        } else {
            return _delegate.getRendersChildren();
        }
    }

    public Renderer getDelegate() {
        return this._delegate;
    }

    public void setDelegate(Renderer delegate) {
        this._delegate = delegate;
    }

    /**
     * Render a generic CSS styleClass (not one derived from an attribute). The
     * styleclass will be passed through the RenderingContext getStyleClass()
     * API.
     * 
     * @param context
     *            the FacesContext
     * @param styleClass
     *            the style class
     */
    protected void _renderStyleClass(UIComponent component, FacesContext context, SkinRenderingContext arc,
            String styleClass) throws IOException {
        if (styleClass != null) {
            styleClass = arc.getStyleClass(styleClass);

            if (styleClass != null) {
                if (styleClass.startsWith((this.getNamespace() == null) ? "af_" : this.getNamespace())
                        && !isDisableContentCompression(context)) {
                    //no styleClass found
                    return;
                }
                // log.info("Writing styleClass:" + styleClass+" to
                // "+component.toString());
                String oldStyle = (String) component.getAttributes().get("styleClass");

                if (oldStyle != null) {
                    if (oldStyle.equals("")) {
                        component.getAttributes().put("styleClass", styleClass);
                    } else if (!StringUtils.contains(oldStyle, styleClass)) {
                        // Do not set the component, because it has another
                        // class
                        // already set

                        component.getAttributes().put("styleClass", oldStyle + " " + styleClass);

                    }
                } else {
                    if (styleClass != null) {
                        component.getAttributes().put("styleClass", styleClass);
                    }
                }
            }
        }
    }

    protected void _renderStyleClass(UIComponent component, FacesContext context, SkinRenderingContext arc,
            String styleClass, String property) throws IOException {
        if (styleClass != null) {
            styleClass = arc.getStyleClass(styleClass);

            if (styleClass != null) {
                if (styleClass.startsWith((this.getNamespace() == null) ? "af_" : this.getNamespace())
                        && !isDisableContentCompression(context)) {
                    //no styleClass found
                    return;
                }
                // log.info("Writing styleClass:" + styleClass+" to
                // "+component.toString());
                String oldStyle = (String) component.getAttributes().get(property);

                if (oldStyle != null) {
                    if (oldStyle.equals("")) {
                        component.getAttributes().put(property, styleClass);
                    } else if (!StringUtils.contains(oldStyle, styleClass)) {
                        // Do not set the component, because it has another
                        // class
                        // already set

                        component.getAttributes().put(property, oldStyle + " " + styleClass);

                    }
                } else {
                    if (styleClass != null) {
                        component.getAttributes().put(property, styleClass);
                    }
                }
            }
        }
    }

    protected void _renderReplaceStyleClass(UIComponent component, FacesContext context, SkinRenderingContext arc,
            String styleClass, String property) throws IOException {
        if (styleClass != null) {
            styleClass = arc.getStyleClass(styleClass);

            if (styleClass != null) {
                if (styleClass.startsWith((this.getNamespace() == null) ? "af_" : this.getNamespace())
                        && !isDisableContentCompression(context)) {
                    //no styleClass found
                    return;
                }
                // log.info("Writing styleClass:" + styleClass+" to
                // "+component.toString());
                String oldStyle = (String) component.getAttributes().get(property);

                if (oldStyle != null) {
                    if (oldStyle.equals("")) {
                        component.getAttributes().put(property, styleClass);
                    }
                } else {
                    if (styleClass != null) {
                        component.getAttributes().put(property, styleClass);
                    }
                }
            }
        }
    }

    /**
     * Render an array of CSS styleClasses as space-separated values. NOTE: the
     * array is mutated during this method, and cannot be reused! Each
     * styleclass will be passed through the RenderingContext getStyleClass()
     * API.
     * 
     * @param context
     *            the FacesContext
     * @param styleClasses
     *            the style classes
     */
    protected void _renderStyleClasses(UIComponent component, FacesContext context, SkinRenderingContext arc,
            String[] styleClasses) throws IOException {
        int length = 0;
        for (int i = 0; i < styleClasses.length; i++) {
            if (styleClasses[i] != null) {
                String styleClass = arc.getStyleClass(styleClasses[i]);

                if (styleClass.startsWith((this.getNamespace() == null) ? "af_" : this.getNamespace())
                        && !isDisableContentCompression(context)) {
                    //No add any that startsWith af_
                    styleClass = null;
                }
                if (styleClass != null)
                    length += styleClass.length() + 1;
                styleClasses[i] = styleClass;
            }
        }

        StringBuilder builder = new StringBuilder(length);
        for (int i = 0; i < styleClasses.length; i++) {
            if (styleClasses[i] != null) {
                if (builder.length() != 0)
                    builder.append(' ');
                builder.append(styleClasses[i]);
            }
        }

        component.getAttributes().put("styleClass", builder.toString());
        // context.getResponseWriter().writeAttribute("class",
        // builder.toString(), null);
    }

    protected void _setIconDirection(FacesContext context, UIComponent component, SkinRenderingContext arc,
            String styleClass, String getProperty, String setProperty) {

        //This case is something strange. The style properties that
        //i set throught component.getAttributes.put(....) works, but
        //the image properties like in HtmlTree NOT!!!!

        Method method;
        String oldIcon = null;
        // Check it has a getStyleClass property
        try {
            method = component.getClass().getMethod(getProperty, (Class[]) null);
            oldIcon = (String) method.invoke(component, (Object[]) null);
        } catch (SecurityException e) {
            log.debug("SecurityException" + e.getMessage());
            return;
        } catch (NoSuchMethodException e) {
            // Nothing happends
            // e.printStackTrace();
            log.debug("NoSuchMethodException" + e.getMessage());
            return;
        } catch (InvocationTargetException e) {
            // Nothing happends
            log.debug("InvocationTargetException" + e.getMessage());
            return;
        } catch (IllegalAccessException e) {
            // Nothing happends
            log.debug("IllegalAccessException" + e.getMessage());
            return;
        }

        // if the user specified a icon path for this property
        if (oldIcon == null) {
            //log.info("ICON NULO:"+arc.getIcon(styleClass)+" "+arc.getSkin().getIcon(styleClass));
            Icon icon = arc.getIcon(styleClass);
            if (icon != null) {
                String value = null;
                String baseContextPath = context.getExternalContext().getRequestContextPath() + '/';

                //For now i substract the request context path
                if (icon instanceof ContextImageIcon) {
                    value = (String) icon.getImageURI(context, arc);
                    if (value.startsWith(baseContextPath)) {
                        value = value.substring(baseContextPath.length() - 1);
                    }
                } else {
                    value = (String) icon.getImageURI(context, arc);
                }
                //log.info("ICON PATH:"+value);

                //I have to substract the base 

                // Check it has a getStyleClass property
                try {
                    Class[] classes = new Class[] { String.class };
                    method = component.getClass().getMethod(setProperty, classes);
                    Object[] params = new Object[] { value };
                    method.invoke(component, params);
                } catch (SecurityException e) {
                    log.debug("SecurityException" + e.getMessage());
                    return;
                } catch (NoSuchMethodException e) {
                    // Nothing happends
                    // e.printStackTrace();
                    log.debug("NoSuchMethodException" + e.getMessage());
                    return;
                } catch (InvocationTargetException e) {
                    // Nothing happends
                    log.debug("InvocationTargetException" + e.getMessage());
                    return;
                } catch (IllegalAccessException e) {
                    // Nothing happends
                    log.debug("IllegalAccessException" + e.getMessage());
                    return;
                }
            }
        }
    }

    public String getComponentTagName() {
        return _componentTagName;
    }

    public void setComponentTagName(String componentTag) {
        this._componentTagName = componentTag;
    }

    public String getNamespace() {
        return _namespace;
    }

    public void setNamespace(String namespace) {
        this._namespace = namespace;
    }

    private boolean isDisableContentCompression(FacesContext context) {
        boolean disableContentCompression = false;
        if (context.getExternalContext() != null) {
            disableContentCompression = ("true").equalsIgnoreCase(
                    context.getExternalContext().getInitParameter(SkinConstants.DISABLE_CONTENT_COMPRESSION));
        }

        return disableContentCompression;
    }
}