org.apache.myfaces.custom.navmenu.htmlnavmenu.HtmlNavigationMenuRendererUtils Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of tomahawk Show documentation
Show all versions of tomahawk Show documentation
JSF components and utilities that can be used with any JSF implementation.
This library is compatible with both JSF1.1 and JSF1.2; however for JSF1.2 users there
is an alternative build of Tomahawk available that takes advantage of JSF1.2 features to
offer some additional benefits.
/*
* 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);
}
}
}