
org.apache.myfaces.custom.navmenu.htmlnavmenu.HtmlNavigationMenuRendererUtils Maven / Gradle / Ivy
/*
* 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 - 2025 Weber Informatics LLC | Privacy Policy