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

org.richfaces.renderkit.ListRendererBase Maven / Gradle / Ivy

There is a newer version: 4.3.7.Final
Show newest version
/*
 * JBoss, Home of Professional Open Source
 * Copyright 2010, 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;

import java.io.IOException;
import java.text.MessageFormat;
import java.util.Collections;
import java.util.Map;

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

import org.ajax4jsf.model.DataVisitResult;
import org.ajax4jsf.model.DataVisitor;
import org.ajax4jsf.renderkit.RendererUtils;
import org.ajax4jsf.renderkit.RendererUtils.HTML;
import org.richfaces.component.AbstractList;
import org.richfaces.component.ListType;
import org.richfaces.component.UISequence;
import org.richfaces.component.util.HtmlUtil;
import org.richfaces.log.RichfacesLogger;

/**
 * @author Nick Belaevski
 *
 */
@ResourceDependency(library = "org.richfaces", name = "list.ecss")
public abstract class ListRendererBase extends Renderer {

    private static final Map ROW_HANDLER_ATTRIBUTES = Collections
    .unmodifiableMap(ComponentAttribute.createMap(
        new ComponentAttribute(HTML.ONCLICK_ATTRIBUTE).setEventNames("rowclick").
            setComponentAttributeName("onrowclick"),
        new ComponentAttribute(HTML.ONDBLCLICK_ATTRIBUTE).setEventNames("rowdblclick").
            setComponentAttributeName("onrowdblclick"),
        new ComponentAttribute(HTML.ONMOUSEDOWN_ATTRIBUTE).setEventNames("rowmousedown").
            setComponentAttributeName("onrowmousedown"),
        new ComponentAttribute(HTML.ONMOUSEUP_ATTRIBUTE).setEventNames("rowmouseup").
            setComponentAttributeName("onrowmouseup"),
        new ComponentAttribute(HTML.ONMOUSEOVER_ATTRIBUTE).setEventNames("rowmouseover").
            setComponentAttributeName("onrowmouseover"),
        new ComponentAttribute(HTML.ONMOUSEMOVE_ATTRIBUTE).setEventNames("rowmousemove").
            setComponentAttributeName("onrowmousemove"),
        new ComponentAttribute(HTML.ONMOUSEOUT_ATTRIBUTE).setEventNames("rowmouseout").
            setComponentAttributeName("onrowmouseout"),
        new ComponentAttribute(HTML.ONKEYPRESS_ATTRIBUTE).setEventNames("rowkeypress").
            setComponentAttributeName("onrowkeypress"),
        new ComponentAttribute(HTML.ONKEYDOWN_ATTRIBUTE).setEventNames("rowkeydown").
            setComponentAttributeName("onrowkeydown"),
        new ComponentAttribute(HTML.ONKEYUP_ATTRIBUTE).setEventNames("rowkeyup").
            setComponentAttributeName("onrowkeyup")
    ));

    private RendererUtils rendererUtils = RendererUtils.getInstance();

    /**
     * @author Nick Belaevski
     *
     */
    private class SimpleItemsEncoder extends ItemsEncoder {

        private String itemClass;

        public SimpleItemsEncoder(String itemClass) {
            super();
            this.itemClass = itemClass;
        }

        @Override
        protected void encodeRow(FacesContext context, UISequence sequence, SequenceRendererHelper helper)
            throws IOException {
            ResponseWriter writer = context.getResponseWriter();

            writer.startElement(HTML.LI_ELEMENT, sequence);

            if (rendererUtils.hasExplicitId(sequence)) {
                rendererUtils.writeAttribute(writer, HTML.ID_ATTRIBUTE, sequence.getClientId(context));
            }

            rendererUtils.writeAttribute(writer, HTML.CLASS_ATTRIBUTE,
                HtmlUtil.concatClasses(helper.getRowClass(), helper.getColumnClass(), itemClass));
            renderHandlers(context, sequence);
            rendererUtils.encodeChildren(context, sequence);
            writer.endElement(HTML.LI_ELEMENT);
        }

        public void encodeFakeItem(FacesContext context, UIComponent component) throws IOException {
            ResponseWriter writer = context.getResponseWriter();
            writer.startElement(HTML.LI_ELEMENT, component);
            writer.writeAttribute(HTML.STYLE_ATTRIBUTE, "display:none", null);
            writer.endElement(HTML.LI_ELEMENT);
        }
    }

    /**
     * @author Nick Belaevski
     *
     */
    private final class DefinitionItemsEncoder extends ItemsEncoder {
        @Override
        protected void encodeRow(FacesContext context, UISequence sequence, SequenceRendererHelper helper)
            throws IOException {
            ResponseWriter writer = context.getResponseWriter();

            UIComponent termFacet = sequence.getFacet(AbstractList.TERM);
            if (termFacet != null) {
                writer.startElement(HTML.DT_ELEMENT, sequence);

                if (rendererUtils.hasExplicitId(sequence)) {
                    rendererUtils.writeAttribute(writer, HTML.ID_ATTRIBUTE, sequence.getClientId(context) + ".dt");
                }

                rendererUtils.writeAttribute(writer, HTML.CLASS_ATTRIBUTE,
                    HtmlUtil.concatClasses(helper.getRowClass(), helper.getColumnClass(), "rf-dlst-t"));
                termFacet.encodeAll(context);
                writer.endElement(HTML.DT_ELEMENT);
            }

            writer.startElement(HTML.DD_ELEMENT, sequence);

            if (rendererUtils.hasExplicitId(sequence)) {
                rendererUtils.writeAttribute(writer, HTML.ID_ATTRIBUTE, sequence.getClientId(context));
            }

            rendererUtils.writeAttribute(writer, HTML.CLASS_ATTRIBUTE,
                HtmlUtil.concatClasses(helper.getRowClass(), helper.getColumnClass(), "rf-dlst-d"));
            renderHandlers(context, sequence);
            rendererUtils.encodeChildren(context, sequence);
            writer.endElement(HTML.DD_ELEMENT);
        }

        public void encodeFakeItem(FacesContext context, UIComponent component) throws IOException {
            ResponseWriter writer = context.getResponseWriter();
            writer.startElement(HTML.DD_ELEMENT, component);
            writer.writeAttribute(HTML.STYLE_ATTRIBUTE, "display:none", null);
            writer.endElement(HTML.DD_ELEMENT);
        }
    }

    private abstract class ItemsEncoder implements DataVisitor {

        protected void renderHandlers(FacesContext context, UISequence sequence) throws IOException {
            RenderKitUtils.renderPassThroughAttributesOptimized(context, sequence, ROW_HANDLER_ATTRIBUTES);
        }

        protected abstract void encodeRow(FacesContext context, UISequence sequence, SequenceRendererHelper helper)
            throws IOException;

        public DataVisitResult process(FacesContext context, Object rowKey, Object argument) {
            SequenceRendererHelper helper = (SequenceRendererHelper) argument;
            UISequence sequence = helper.getSequence();
            sequence.setRowKey(context, rowKey);
            if (sequence.isRowAvailable()) {
                helper.nextRow();

                try {
                    encodeRow(context, sequence, helper);
                } catch (IOException e) {
                    throw new FacesException(e.getMessage(), e);
                }

                return DataVisitResult.CONTINUE;
            } else {
                return DataVisitResult.STOP;
            }
        }

        public abstract void encodeFakeItem(FacesContext context, UIComponent component) throws IOException;

    }

    private ItemsEncoder unorderedListItemsEncoder = new SimpleItemsEncoder("rf-ulst-i");

    private ItemsEncoder orderedListItemsEncoder = new SimpleItemsEncoder("rf-olst-i");

    private ItemsEncoder definitionItemsEncoder = new DefinitionItemsEncoder();

    protected String getListClass(ListType type) {
        switch (type) {
            case ordered:
                return "rf-olst";
            case unordered:
                return "rf-ulst";
            case definitions:
                return "rf-dlst";

            default:
                throw new IllegalArgumentException(type.toString());
        }
    }

    protected ItemsEncoder getItemsEncoderByType(ListType type) {
        switch (type) {
            case ordered:
                return orderedListItemsEncoder;
            case unordered:
                return unorderedListItemsEncoder;
            case definitions:
                return definitionItemsEncoder;

            default:
                throw new IllegalArgumentException(type.toString());
        }
    }

    protected ListType getType(UIComponent component) {
        ListType type = ((AbstractList) component).getType();
        if (type == null) {
            String exceptionMessage = MessageFormat.format("Type for rich:list {0} is required!", RichfacesLogger.getComponentPath(component));
            throw new IllegalArgumentException(exceptionMessage);
        }

        return type;
    }

    protected String getStyleClass(UIComponent component, ListType listType) {
        String styleClass = (String) component.getAttributes().get(HTML.STYLE_CLASS_ATTR);
        return HtmlUtil.concatClasses(styleClass, getListClass(listType));
    }

    protected String getElementId(FacesContext facesContext, UIComponent component) {
        if (rendererUtils.hasExplicitId(component)) {
            return component.getClientId(facesContext);
        }

        return null;
    }

    protected void encodeListItems(FacesContext context, UIComponent component, ListType listType)
        throws IOException {
        AbstractList list = (AbstractList) component;
        try {
            ItemsEncoder itemsEncoder = getItemsEncoderByType(listType);
            SequenceRendererHelper rendererHelper = new SequenceRendererHelper(list);
            list.walk(context, itemsEncoder, rendererHelper);

            if (!rendererHelper.hasWalkedOverRows()) {
                itemsEncoder.encodeFakeItem(context, component);
            }
        } catch (FacesException e) {
            // TODO nick - review
            if (e.getCause() instanceof IOException) {
                throw (IOException) e.getCause();
            } else {
                throw e;
            }
        }
    }
    
    @Override
    public void encodeBegin(FacesContext context, UIComponent component) throws IOException {
        //do nothing
    }
    
    @Override
    public void encodeChildren(FacesContext context, UIComponent component) throws IOException {
        //do nothing
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy