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

org.richfaces.renderkit.html.ToolbarRendererBase Maven / Gradle / Ivy

There is a newer version: 4.3.7.Final
Show newest version
/*
 * JBoss, Home of Professional Open Source
 * Copyright ${year}, Red Hat, Inc. and individual contributors
 * by the @authors tag. See the copyright.txt in the distribution for a
 * full listing of individual contributors.
 *
 * This is free software; you can redistribute it and/or modify it
 * under the terms of the GNU Lesser General Public License as
 * published by the Free Software Foundation; either version 2.1 of
 * the License, or (at your option) any later version.
 *
 * This software is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this software; if not, write to the Free
 * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
 * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
 */

package org.richfaces.renderkit.html;

import java.io.IOException;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

import javax.faces.application.ResourceDependencies;
import javax.faces.application.ResourceDependency;
import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.context.ResponseWriter;

import org.richfaces.component.AbstractToolbar;
import org.richfaces.component.AbstractToolbarGroup;
import org.richfaces.renderkit.ComponentAttribute;
import org.richfaces.renderkit.HtmlConstants;
import org.richfaces.renderkit.RenderKitUtils;
import org.richfaces.renderkit.RendererBase;
import org.richfaces.renderkit.RenderKitUtils.ScriptHashVariableWrapper;
import org.richfaces.renderkit.util.HtmlDimensions;



@ResourceDependencies({
    @ResourceDependency(name = "jquery.js"),
    @ResourceDependency(library = "org.richfaces", name = "toolbar.js"),
    @ResourceDependency(library = "org.richfaces", name = "toolbar.ecss")
})

public abstract class ToolbarRendererBase extends RendererBase {

    public static final String RENDERER_TYPE = "org.richfaces.ToolbarRenderer";
    
    public static final Map ITEMS_HANDLER_ATTRIBUTES = Collections
    .unmodifiableMap(ComponentAttribute.createMap(
            new ComponentAttribute(HtmlConstants.ONCLICK_ATTRIBUTE)
                .setEventNames("itemclick")
                .setComponentAttributeName("onitemclick"),
            new ComponentAttribute(HtmlConstants.ONDBLCLICK_ATTRIBUTE)
                .setEventNames("itemdblclick")
                .setComponentAttributeName("onitemdblclick"), 
            new ComponentAttribute(HtmlConstants.ONMOUSEDOWN_ATTRIBUTE)
                .setEventNames("itemmousedown")
                .setComponentAttributeName("onitemmousedown"),
            new ComponentAttribute(HtmlConstants.ONMOUSEUP_ATTRIBUTE)
                .setEventNames("itemmouseup")
                .setComponentAttributeName("onitemmouseup"), 
            new ComponentAttribute(HtmlConstants.ONMOUSEOVER_ATTRIBUTE)
                .setEventNames("itemmouseover")
                .setComponentAttributeName("onitemmouseover"), 
            new ComponentAttribute(HtmlConstants.ONMOUSEMOVE_ATTRIBUTE)
                .setEventNames("itemmousemove")
                .setComponentAttributeName("onitemmousemove"), 
            new ComponentAttribute(HtmlConstants.ONMOUSEOUT_ATTRIBUTE)
                .setEventNames("itemmouseout")
                .setComponentAttributeName("onitemmouseout"), 
            new ComponentAttribute(HtmlConstants.ONKEYPRESS_ATTRIBUTE)
                .setEventNames("itemkeypress")
                .setComponentAttributeName("onitemkeypress"),
            new ComponentAttribute(HtmlConstants.ONKEYDOWN_ATTRIBUTE)
                .setEventNames("itemkeydown")
                .setComponentAttributeName("onitemkeydown"),
            new ComponentAttribute(HtmlConstants.ONKEYUP_ATTRIBUTE)
                .setEventNames("itemkeyup")
                .setComponentAttributeName("onitemkeyup")
    ));

    public enum ItemSeparators {
        NONE, SQUARE, DISC, GRID, LINE
    }

    public enum Locations {
        RIGHT, LEFT
    }
    
    private void writeColElement(ResponseWriter writer, UIComponent component) throws IOException {
        writer.startElement(HtmlConstants.COL_ELEMENT, component);
        writer.writeAttribute(HtmlConstants.WIDTH_ATTRIBUTE, "1px", null);
        writer.endElement(HtmlConstants.COL_ELEMENT);
    }
    
    private boolean isSeparatorFacetRendered(UIComponent component) {
        UIComponent separatorFacet = component.getFacet("itemSeparator");
        return (separatorFacet != null) ? separatorFacet.isRendered() : false;
    }
    
    private boolean isSeparatorAttributeRendered(UIComponent component) {
        String itemSeparator = (String) component.getAttributes().get("itemSeparator");
        
        if (itemSeparator != null && itemSeparator.trim().length() != 0
                && !itemSeparator.equalsIgnoreCase(ItemSeparators.NONE.toString())) {
            return true;
        }
        return false;
    }    
   
   
    private int getColumnCount(List components) {
        int result = 0;
        for (UIComponent component : components) {
            if (component instanceof AbstractToolbarGroup) {
                result += component.getChildren().size();
            } else {
                result++;
            }
        }
        
        return result;
    }    
    
    private int getCountSeparators(AbstractToolbar toolBar, List components) {
        int result = 0;
        if (components != null && (isSeparatorFacetRendered(toolBar) || isSeparatorAttributeRendered(toolBar))) {
            result += components.size() - 1;
        }
        
        for (UIComponent component : components) {
            if (component instanceof AbstractToolbarGroup) {
                result += getCountSeparators((AbstractToolbarGroup) component, component.getChildren());
            }
        }
        
        return result;
    }
    
    private int getCountSeparators(AbstractToolbarGroup toolBarGroup, List components) {
        if (components != null && (isSeparatorFacetRendered(toolBarGroup) || isSeparatorAttributeRendered(toolBarGroup))) {
            return components.size() - 1;
        }
        return 0;
    }
    
    protected void renderColElements(FacesContext context, UIComponent component) throws IOException {
        ResponseWriter writer = context.getResponseWriter();
        List childrenToTheLeft = new LinkedList();
        List childrenToTheRight = new LinkedList();
        
        getChildrenToLeftAndRight(context, component, childrenToTheLeft, childrenToTheRight);
        int columnAmount = getCountSeparators((AbstractToolbar) component, childrenToTheLeft) +
            getColumnCount(childrenToTheLeft);
        for (int i = 0; i < columnAmount; i++) {
            writeColElement(writer, component);
        }
        
        writer.startElement(HtmlConstants.COL_ELEMENT, component);
        writer.writeAttribute(HtmlConstants.WIDTH_ATTRIBUTE, "*", null);
        writer.endElement(HtmlConstants.COL_ELEMENT);
        
        columnAmount = getCountSeparators((AbstractToolbar) component, childrenToTheRight) +
            getColumnCount(childrenToTheRight);
        for (int i = 0; i < columnAmount; i++) {
            writeColElement(writer, component);
        }
    }

    private void getChildrenToLeftAndRight(FacesContext context, UIComponent component,
        final List childrenToTheLeft, final List childrenToTheRight) {

        AbstractToolbar toolbar = (AbstractToolbar) component;
        List children = toolbar.getChildren();
        if (children != null) {
            for (UIComponent child : children) {
                if (child.isRendered()) {
                    if (child instanceof AbstractToolbarGroup) {
                        AbstractToolbarGroup group = (AbstractToolbarGroup) child;
                        String location = group.getLocation();
                        if (location != null && location.equalsIgnoreCase(Locations.RIGHT.toString())) {
                            childrenToTheRight.add(child);
                        } else {
                            childrenToTheLeft.add(child);
                        }
                    } else {
                        childrenToTheLeft.add(child);
                    }
                }
            }
        }
    }
    
    @Override
    public void encodeChildren(FacesContext context, UIComponent component) throws IOException {
        AbstractToolbar toolbar = (AbstractToolbar) component;
        String itemClass = (String) toolbar.getAttributes().get("itemClass");
        String itemStyle = (String) toolbar.getAttributes().get("itemStyle");

        List children = toolbar.getChildren();

        if (children != null) {
            List childrenToTheLeft = new LinkedList();
            List childrenToTheRight = new LinkedList();
            
            getChildrenToLeftAndRight(context, component, childrenToTheLeft, childrenToTheRight);
            
            ResponseWriter writer = context.getResponseWriter();
            for (Iterator it = childrenToTheLeft.iterator(); it.hasNext();) {
                
                UIComponent child = it.next();
                
                if (!(child instanceof AbstractToolbarGroup)) {
                    writer.startElement(HtmlConstants.TD_ELEM, component);
                    writer.writeAttribute(HtmlConstants.ID_ATTRIBUTE, encodeClientItemID(child), null);
                    writer.writeAttribute(HtmlConstants.CLASS_ATTRIBUTE, concatClasses("rf-tb-itm", itemClass), null);
                    if (isPropertyRendered(itemStyle)) {
                        writer.writeAttribute(HtmlConstants.STYLE_ATTRIBUTE, itemStyle, null);
                    }
                }
                
                child.encodeAll(context);
                
                if (!(child instanceof AbstractToolbarGroup)) {
                    writer.endElement(HtmlConstants.TD_ELEM);
                }

                if (it.hasNext()) {
                    insertSeparatorIfNeed(context, toolbar, writer);
                }
            }

            writer.startElement(HtmlConstants.TD_ELEM, component);
            writer.writeAttribute(HtmlConstants.CLASS_ATTRIBUTE, concatClasses("rf-tb-emp", itemClass), null);
            writer.writeText("\u00a0", null);
            writer.endElement(HtmlConstants.TD_ELEM);

            for (Iterator it = childrenToTheRight.iterator(); it.hasNext();) {
                UIComponent child = it.next();
                child.encodeAll(context);
                if (it.hasNext()) {
                    insertSeparatorIfNeed(context, toolbar, writer);
                }
            }
        }
    }

    /**
     * Inserts separator between toolbar items. Uses facet "itemSeparator" if it
     * is set and default separator implementation if facet is not set.
     * 
     * @param context
     *            - faces context
     * @param component
     *            - component
     * @param writer
     *            - response writer
     * @throws IOException
     *             - in case of IOException during writing to the ResponseWriter
     */
    protected void insertSeparatorIfNeed(FacesContext context, UIComponent component, ResponseWriter writer)
        throws IOException {
        UIComponent separatorFacet = component.getFacet("itemSeparator");
        boolean isSeparatorFacetRendered = (separatorFacet != null) ? separatorFacet.isRendered() : false;
        if (isSeparatorFacetRendered) {
            writer.startElement(HtmlConstants.TD_ELEM, component);
            writer.writeAttribute(HtmlConstants.CLASS_ATTRIBUTE, "rf-tb-sep", null);
            separatorFacet.encodeAll(context);
            writer.endElement(HtmlConstants.TD_ELEM);
        } else {
            insertDefaultSeparatorIfNeed(context, component, writer);
        }
    }
    
    /**
     * Inserts default separator. Possible values are: "square", "disc", "grid",
     * "line" - for separators provided by component implementation; "none" -
     * for no separators between toolbar items; URI string value - for custom
     * images specified by the page author.
     * 
     * @param context
     *            - faces context
     * @param component
     *            - component
     * @param writer
     *            - response writer
     * @throws IOException
     *             - in case of IOException during writing to the ResponseWriter
     */
    protected void insertDefaultSeparatorIfNeed(FacesContext context, UIComponent component, ResponseWriter writer)
        throws IOException {
        String itemSeparator = (String) component.getAttributes().get("itemSeparator");
       
        if (itemSeparator != null && itemSeparator.trim().length() != 0
                && !itemSeparator.equalsIgnoreCase(ItemSeparators.NONE.toString())) {

            ItemSeparators separator = null;
            if (itemSeparator.equalsIgnoreCase(ItemSeparators.SQUARE.toString())) {
                separator = ItemSeparators.SQUARE;
            } else if (itemSeparator.equalsIgnoreCase(ItemSeparators.DISC.toString())) {
                separator = ItemSeparators.DISC;
            } else if (itemSeparator.equalsIgnoreCase(ItemSeparators.GRID.toString())) {
                separator = ItemSeparators.GRID;
            } else if (itemSeparator.equalsIgnoreCase(ItemSeparators.LINE.toString())) {
                separator = ItemSeparators.LINE;
            }

            writer.startElement(HtmlConstants.TD_ELEM, component);
            String separatorClass = "rf-tb-sep";
            separatorClass = concatClasses(separatorClass, (String) component.getAttributes().get("separatorClass"));
            writer.writeAttribute(HtmlConstants.CLASS_ATTRIBUTE, separatorClass, null);

            if (separator != null) {
                String itemSeparatorClass = "rf-tb-sep-" + separator.toString().toLowerCase();
                writer.startElement(HtmlConstants.DIV_ELEM, component);
                writer.writeAttribute(HtmlConstants.CLASS_ATTRIBUTE, itemSeparatorClass, null);
                writer.writeText("\u00a0", null);
                writer.endElement(HtmlConstants.DIV_ELEM);
            } else {
                
                String uri = RenderKitUtils.getResourceURL(itemSeparator, context);
                writer.startElement(HtmlConstants.IMG_ELEMENT, component);
                writer.writeAttribute(HtmlConstants.SRC_ATTRIBUTE, uri, null);
                writer.writeAttribute(HtmlConstants.ALT_ATTRIBUTE, "", null);
                writer.endElement(HtmlConstants.IMG_ELEMENT);
            }
            
            writer.endElement(HtmlConstants.TD_ELEM);
        }
    }

    protected Class getComponentClass() {
        return AbstractToolbar.class;
    }

    public boolean getRendersChildren() {
        return true;
    }

    protected boolean isPropertyRendered(String property) {
        return (null != property && !"".equals(property));
    }
    
    protected String getWidthToolbar(UIComponent component) {
        if (component instanceof AbstractToolbar) {
            String width = ((AbstractToolbar)component).getWidth();
            if (width == null || width.length() == 0) {
                return "100%";
            }
            return HtmlDimensions.formatSize(width);
        } else {
            return "";
        }
    }
    
    protected String getHeightToolbar(UIComponent component) {
        if (component instanceof AbstractToolbar) {
            return HtmlDimensions.formatSize(((AbstractToolbar)component).getHeight());
        } else {
            return "";
        }
    }    
    
    protected Map getOptions(UIComponent component) {
        if (component == null) {
            return null;
        }
        HashMap results = new HashMap();
        if (component instanceof AbstractToolbar) {
            Map tbEvents = new HashMap();
            for (ComponentAttribute componentAttribute :ITEMS_HANDLER_ATTRIBUTES.values()) {
                Object attr = component.getAttributes().get(componentAttribute.getComponentAttributeName());
                if (attr != null) {
                    RenderKitUtils.addToScriptHash(tbEvents, componentAttribute.getHtmlAttributeName().substring(2),
                        attr, null, ScriptHashVariableWrapper.eventHandler);    
                }
            }
            results.put("id", component.getClientId());
            results.put("events", tbEvents);
            
            List groups = getToolBarGroups((AbstractToolbar) component);
            List> tbgListOptions = new LinkedList>();

            for (AbstractToolbarGroup tbg : groups) {
                
                Map tbgOptions = new HashMap();
                Map tbgEvents = new HashMap();
                List tbgIDs = new LinkedList();
                
                for (UIComponent comp : tbg.getChildren()) {
                    tbgIDs.add(encodeClientItemID(comp));
                }
                
                for (ComponentAttribute componentAttribute :ITEMS_HANDLER_ATTRIBUTES.values()) {
                    Object attr = tbg.getAttributes().get(componentAttribute.getComponentAttributeName());
                    if (attr != null) {
                        RenderKitUtils.addToScriptHash(tbgEvents, componentAttribute.getHtmlAttributeName().substring(2),
                            attr, null, ScriptHashVariableWrapper.eventHandler);    
                    }
                } 
                if (!tbgEvents.isEmpty()) {
                    tbgOptions.put("events", tbgEvents);
                    tbgOptions.put("ids", tbgIDs);
                    tbgListOptions.add(tbgOptions);    
                }
            }
            
            results.put("groups", tbgListOptions);
        } 
        return results;
    }
    
    protected String encodeClientItemID(UIComponent component) {
        return component != null ? component.getClientId() + "_itm":"";
    }
    
    private List getToolBarGroups(AbstractToolbar toolBar) {
        List list = new LinkedList();
        if (toolBar != null) {
            for (UIComponent comp : toolBar.getChildren()) {
                if (comp instanceof AbstractToolbarGroup) {
                    list.add((AbstractToolbarGroup) comp);
                }
            }
        }
        return list;
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy