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

org.apache.myfaces.custom.navmenu.htmlnavmenu.HtmlNavigationMenuRendererUtils Maven / Gradle / Ivy

Go to download

JSF components and utilities that can be used with any JSF implementation. This library is based on the JSF1.1 version of Tomahawk, but with minor source code and build changes to take advantage of JSF2.1 features. A JSF2.1 implementation is required to use this version of the Tomahawk library.

The newest version!
/*
 * 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.navmenu.htmlnavmenu;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.myfaces.custom.navmenu.NavigationMenuUtils;
import org.apache.myfaces.custom.navmenu.UINavigationMenuItem;
import org.apache.myfaces.shared_tomahawk.el.SimpleActionMethodBinding;
import org.apache.myfaces.shared_tomahawk.renderkit.RendererUtils;
import org.apache.myfaces.shared_tomahawk.renderkit.html.HTML;
import org.apache.myfaces.shared_tomahawk.renderkit.html.HtmlRendererUtils;

import javax.faces.component.UIComponent;
import javax.faces.component.UIOutput;
import javax.faces.component.UIViewRoot;
import javax.faces.context.FacesContext;
import javax.faces.context.ResponseWriter;
import javax.faces.el.MethodBinding;
import javax.faces.el.ValueBinding;
import javax.faces.event.ActionEvent;
import java.io.IOException;
import java.util.Iterator;
import java.util.List;

/**
 * @author Thomas Spiegl
 * @author Manfred Geiler
 */
class HtmlNavigationMenuRendererUtils {
    private static final Log log = LogFactory.getLog(HtmlNavigationMenuRendererUtils.class);

    private static final Class[] ACTION_LISTENER_ARGS = {ActionEvent.class};

    private HtmlNavigationMenuRendererUtils() {
    }

    public static void renderChildrenListLayout(FacesContext facesContext,
                                                ResponseWriter writer,
                                                HtmlPanelNavigationMenu panelNav,
                                                List children,
                                                int level) throws IOException {
        for (Iterator it = children.iterator(); it.hasNext();) {
            UIComponent child = (UIComponent) it.next();
            if (!child.isRendered()) continue;

            if (child instanceof UINavigationMenuItem) {
                renderChildrenListLayout(facesContext, writer, panelNav, child.getChildren(), level);
            }
            if (child instanceof HtmlCommandNavigationItem) {
                //navigation item
                HtmlRendererUtils.writePrettyLineSeparator(facesContext);

                HtmlCommandNavigationItem navItem = (HtmlCommandNavigationItem) child;

                String externalLink = navItem.getExternalLink();

                String style = HtmlNavigationMenuRendererUtils.getNavigationItemStyle(panelNav, navItem);
                String styleClass = HtmlNavigationMenuRendererUtils.getNavigationItemClass(panelNav, navItem);

                writer.startElement(HTML.LI_ELEM, panelNav);
                HtmlNavigationMenuRendererUtils.writeStyleAttributes(writer, style, styleClass);

                Object value = navItem.getValue();
                boolean renderAsOutputLink = externalLink != null && value != null;

                if (!renderAsOutputLink) {
                    //if there is an external link specified don't render the command nav item, its content
                    //will be wrapped by a output link in the renderChildren() method
                    if (externalLink == null) {
                        navItem.setValue(null); // unset value, value must not be rendered
                        navItem.encodeBegin(facesContext);
                    }
                    HtmlNavigationMenuRendererUtils.renderChildren(facesContext, navItem, panelNav);
                    if (externalLink == null) {
                        navItem.encodeEnd(facesContext);
                        navItem.setValue(value); // restore value
                    }
                }
                else {
                    //there is an external link value and display value exists, so, just render its children
                    renderChildren(facesContext, navItem, panelNav);
                }

                if (hasCommandNavigationItemChildren(navItem)) {
                    writer.startElement(HTML.UL_ELEM, panelNav);

                    if (panelNav.isRenderAll())
                        HtmlNavigationMenuRendererUtils.writeStyleAttributes(writer, navItem.getStyle(), navItem.getStyleClass());

                    HtmlRendererUtils.renderHTMLAttributes(writer, panelNav, HTML.UL_PASSTHROUGH_ATTRIBUTES);
                    renderChildrenListLayout(facesContext, writer, panelNav, child.getChildren(), level + 1);
                    writer.endElement(HTML.UL_ELEM);
                }

                writer.endElement(HTML.LI_ELEM);
            }
        }
    }

    private static boolean hasCommandNavigationItemChildren(HtmlCommandNavigationItem item) {
        List children = item.getChildren();
        for (int i = 0, sizei = children.size(); i < sizei; i++) {
            if (children.get(i) instanceof HtmlCommandNavigationItem) {
                return true;
            }
        }
        return false;
    }

    public static void renderChildrenTableLayout(FacesContext facesContext,
                                                 ResponseWriter writer,
                                                 HtmlPanelNavigationMenu panelNav,
                                                 List children,
                                                 int level) throws IOException {
        for (Iterator it = children.iterator(); it.hasNext();) {
            UIComponent child = (UIComponent) it.next();
            if (!child.isRendered()) continue;
            if (child instanceof HtmlCommandNavigationItem) {
                //navigation item
                HtmlRendererUtils.writePrettyLineSeparator(facesContext);

                String style = getNavigationItemStyle(panelNav, (HtmlCommandNavigationItem) child);
                String styleClass = getNavigationItemClass(panelNav, (HtmlCommandNavigationItem) child);

                writer.startElement(HTML.TR_ELEM, panelNav);
                writer.startElement(HTML.TD_ELEM, panelNav);
                writeStyleAttributes(writer, style, styleClass);

                if (style != null || styleClass != null) {
                    writer.startElement(HTML.SPAN_ELEM, panelNav);
                    writeStyleAttributes(writer, style, styleClass);
                }
                indent(writer, level);
                child.encodeBegin(facesContext);

                child.encodeEnd(facesContext);
                if (style != null || styleClass != null) {
                    writer.endElement(HTML.SPAN_ELEM);
                }

                writer.endElement(HTML.TD_ELEM);
                writer.endElement(HTML.TR_ELEM);

                if (child.getChildCount() > 0) {
                    renderChildrenTableLayout(facesContext, writer, panelNav, child.getChildren(), level + 1);
                }
            }
            else {
                //separator
                HtmlRendererUtils.writePrettyLineSeparator(facesContext);

                String style = panelNav.getSeparatorStyle();
                String styleClass = panelNav.getSeparatorClass();

                writer.startElement(HTML.TR_ELEM, panelNav);
                writer.startElement(HTML.TD_ELEM, panelNav);
                writeStyleAttributes(writer, style, styleClass);

                if (style != null || styleClass != null) {
                    writer.startElement(HTML.SPAN_ELEM, panelNav);
                    writeStyleAttributes(writer, style, styleClass);
                }
                indent(writer, level);
                RendererUtils.renderChild(facesContext, child);
                if (style != null || styleClass != null) {
                    writer.endElement(HTML.SPAN_ELEM);
                }

                writer.endElement(HTML.TD_ELEM);
                writer.endElement(HTML.TR_ELEM);
            }
        }
    }

    public static void indent(ResponseWriter writer, int level) throws IOException {
        StringBuffer buf = new StringBuffer();
        for (int i = 0; i < level; i++) {
            buf.append("    ");
        }
        writer.write(buf.toString());
    }

    public static String getNavigationItemStyle(HtmlPanelNavigationMenu navPanel, HtmlCommandNavigationItem navItem) {
        if (navItem.isActive()) {
            return navPanel.getActiveItemStyle();
        }
        else if (navItem.isOpen()) {
            return navPanel.getOpenItemStyle();
        }
        else {
            return navPanel.getItemStyle();
        }
    }

    public static String getNavigationItemClass(HtmlPanelNavigationMenu navPanel,
                                                HtmlCommandNavigationItem navItem) {
        // MYFACES-117, if a styleClass is supplied for a HtmlCommandNavigationItem,
        // panelNavigation active/open/normal styles for items will be overriden                       
        if (navItem.getStyleClass() != null) {
            return navItem.getStyleClass();
        }
        if (navItem.isActive()) {
            return navPanel.getActiveItemClass();
        }
        else if (navItem.isOpen()) {
            return navPanel.getOpenItemClass();
        }
        else {
            return navPanel.getItemClass();
        }
    }

    public static void writeStyleAttributes(ResponseWriter writer,
                                            String style,
                                            String styleClass) throws IOException {
        HtmlRendererUtils.renderHTMLAttribute(writer, HTML.STYLE_ATTR, HTML.STYLE_ATTR, style);
        HtmlRendererUtils.renderHTMLAttribute(writer, HTML.STYLE_CLASS_ATTR, HTML.STYLE_CLASS_ATTR, styleClass);
    }

    public static UIComponent getPanel(UIComponent link) {
        UIComponent navPanel = link.getParent();
        while (navPanel != null && !(navPanel instanceof HtmlPanelNavigationMenu)) {
            navPanel = navPanel.getParent();
        }
        if (navPanel == null) {
            throw new IllegalStateException("HtmlCommandNavigationItem not nested in HtmlPanelNavigation!?");
        }
        return navPanel;
    }

    public static boolean isListLayout(HtmlPanelNavigationMenu panelNav) {
        return !"Table".equalsIgnoreCase(panelNav.getLayout());
    }

    public static void renderChildren(FacesContext facesContext, HtmlCommandNavigationItem component, HtmlPanelNavigationMenu parentPanelNav) throws IOException {
        if (component.getChildCount() > 0) {
            //if there is an external link value, wrapp the content with an output link
            if (component.getExternalLink() != null) {
                ResponseWriter writer = facesContext.getResponseWriter();

                writer.startElement(HTML.ANCHOR_ELEM, null);
                writer.writeAttribute(HTML.HREF_ATTR, component.getExternalLink(), null);
                if (component.getTarget() != null)
                    writer.writeAttribute(HTML.TARGET_ATTR, component.getTarget(), null);

                //the style attributes need to be taken from the parent panel nav, because the command panel navigation item
                //is not rendered in this case which would have render them
                String style = HtmlNavigationMenuRendererUtils.getNavigationItemStyle(parentPanelNav, component);
                String styleClass = HtmlNavigationMenuRendererUtils.getNavigationItemClass(parentPanelNav, component);
                HtmlNavigationMenuRendererUtils.writeStyleAttributes(writer, style, styleClass);
            }

            for (Iterator it = component.getChildren().iterator(); it.hasNext();) {
                UIComponent child = (UIComponent) it.next();
                if (!(child instanceof HtmlCommandNavigationItem)) {
                    RendererUtils.renderChild(facesContext, child);
                }
            }

            //end wrapper output link
            if (component.getExternalLink() != null) {
                ResponseWriter writer = facesContext.getResponseWriter();
                writer.endElement(HTML.ANCHOR_ELEM);
            }
        }
    }

    public static void debugTree(Log log, FacesContext facesContext, List children, int level) {
        for (Iterator it = children.iterator(); it.hasNext();) {
            UIComponent child = (UIComponent) it.next();
            if (child instanceof UINavigationMenuItem) {
                UINavigationMenuItem item = (UINavigationMenuItem) child;
                StringBuffer buf = new StringBuffer();
                for (int i = 0; i < level * 4; i++) buf.append(' ');
                log.debug(buf.toString() + "--> " + item.getItemLabel() + " id:" + item.getClientId(facesContext));
                debugTree(log, facesContext, child.getChildren(), level + 1);
            }
            else if (child instanceof HtmlCommandNavigationItem) {
                HtmlCommandNavigationItem item = (HtmlCommandNavigationItem) child;
                StringBuffer buf = new StringBuffer();
                for (int i = 0; i < level * 4; i++) buf.append(' ');
                String value;
                if (item.getChildren().size() > 0 && item.getChildren().get(0) instanceof UIOutput) {
                    UIOutput uiOutput = (UIOutput) item.getChildren().get(0);
                    value = uiOutput.getValue() != null ? uiOutput.getValue().toString() : "?";
                }
                else {
                    value = item.getValue() != null ? item.getValue().toString() : "";
                }
                log.debug(buf.toString() + value + " id:" + item.getClientId(facesContext));
                debugTree(log, facesContext, child.getChildren(), level + 1);
            }
        }
    }

    public static HtmlCommandNavigationItem findPreviousItem(UIViewRoot previousViewRoot, String clientId) {
        HtmlCommandNavigationItem previousItem = null;
        if (previousViewRoot != null) {
            UIComponent previousComp = previousViewRoot.findComponent(clientId);
            if (previousComp instanceof HtmlCommandNavigationItem) {
                previousItem = (HtmlCommandNavigationItem) previousComp;
            }
        }
        return previousItem;
    }

    public static MethodBinding getMethodBinding(FacesContext facesContext, String value, boolean actionListener) {
        MethodBinding mb;
        if (NavigationMenuUtils.isValueReference(value)) {
            mb = facesContext.getApplication().createMethodBinding(value, actionListener ? ACTION_LISTENER_ARGS : null);
        }
        else {
            if (actionListener) {
                log.error("Invalid actionListener value " + value + " (has to be ValueReference!)");
                mb = null;
            }
            else {
                mb = new SimpleActionMethodBinding(value);
            }
        }
        return mb;
    }

    public static void setAttributeValue(FacesContext facesContext, UIComponent comp, String attribute, String value) {
        if (value == null)
            return;
        if (NavigationMenuUtils.isValueReference(value)) {
            ValueBinding vb = facesContext.getApplication().createValueBinding(value);
            comp.setValueBinding(attribute, vb);
        }
        else {
            comp.getAttributes().put(attribute, value);
        }
    }
   
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy