blob: e5c4ab572bb85bd8e34bf6923c40146d3e5e21f5 [file] [log] [blame]
/*
* 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.empire.jsf2.components;
import java.io.IOException;
import javax.faces.component.UIComponent;
import javax.faces.component.UINamingContainer;
import javax.faces.component.html.HtmlOutcomeTargetLink;
import javax.faces.context.FacesContext;
import javax.faces.context.ResponseWriter;
import org.apache.empire.commons.ObjectUtils;
import org.apache.empire.commons.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class MenuItemTag extends LinkTag
{
// Logger
private static final Logger log = LoggerFactory.getLogger(MenuItemTag.class);
protected MenuListTag parentMenu = null;
protected String menuId;
public MenuItemTag()
{
super();
}
@Override
public String getFamily()
{
return UINamingContainer.COMPONENT_FAMILY;
}
@Override
public void encodeBegin(FacesContext context)
throws IOException
{
// Detect Parent Menu
parentMenu = getParentMenu();
menuId = helper.getTagAttributeString("menuId");
if(!isRendered())
return;
// render components
ResponseWriter writer = context.getResponseWriter();
writer.startElement("li", this);
writer.writeAttribute("id", getClientId(context), null);
helper.writeAttribute(writer, "class", getStyleClass());
String wrap = (parentMenu!=null ? parentMenu.getItemWrapTag() : null);
if (StringUtils.isNotEmpty(wrap))
{ // Wrap-Element
writer.startElement(wrap, this);
// writer.writeAttribute("class", "item", null);
}
// begin
super.encodeBegin(context);
// End Wrapper
if (StringUtils.isNotEmpty(wrap))
writer.endElement(wrap);
}
@Override
public boolean getRendersChildren()
{
return true;
}
@Override
public void encodeChildren(FacesContext context)
throws IOException
{
if (isExpanded())
{
UIComponent c = getChildren().get(0);
if (c instanceof HtmlOutcomeTargetLink)
{ if (c.isRendered())
{ log.warn("WARN: Unexpected rendering of output link. Rendering is ignored.");
c.setRendered(false);
}
}
else
log.warn("WARN: Unexpected child element as first child of MenuItemTag!");
// encode children
super.forceEncodeChildren(context);
}
}
@Override
public void encodeEnd(FacesContext context)
throws IOException
{
if(!isRendered())
return;
// call base
if (isExpanded())
{
super.encodeEnd(context);
}
// EndElement
ResponseWriter writer = context.getResponseWriter();
writer.endElement("li");
}
/*
private void printChildTree(UIComponent comp, int level)
{
List<UIComponent> cl = comp.getChildren();
for (UIComponent c : cl)
{
boolean isRendered = c.isRendered();
log.info("-{}- rendering {} "+String.valueOf(isRendered), level, c.getClass().getSimpleName());
printChildTree(c, level+1);
}
}
*/
@Override
protected String getLinkStyleClass()
{
return null;
}
protected MenuListTag getParentMenu()
{
// walk upwards the parent component tree and return the first record component found (if
// any)
UIComponent parent = this;
while ((parent = parent.getParent()) != null)
{
if (parent instanceof MenuListTag)
{
return (MenuListTag) parent;
}
}
return null;
}
protected boolean isCurrent()
{
if (menuId==null || parentMenu==null || parentMenu.getCurrentId()==null)
return false;
// All present
return menuId.equals(parentMenu.getCurrentId());
}
protected boolean isParent()
{
if (menuId==null || parentMenu==null || parentMenu.getCurrentId()==null)
return false;
// All present
String currentId = parentMenu.getCurrentId();
return (currentId.length()>menuId.length() && currentId.startsWith(menuId));
}
protected boolean isDisabled()
{
Object value = helper.getTagAttributeValue("disabled");
if (value!=null)
return ObjectUtils.getBoolean(value);
return false;
}
protected boolean isExpanded()
{
Object value = helper.getTagAttributeValue("expanded");
boolean auto = false;
if (value!=null)
{ // is current?
auto = "auto".equals(value);
if (auto==false)
return ObjectUtils.getBoolean(value);
// check current
if (isCurrent())
return true;
}
// Check parent
if (menuId==null || parentMenu==null || parentMenu.getCurrentId()==null)
return auto;
// All present
String currentId = parentMenu.getCurrentId();
return currentId.startsWith(menuId+".");
}
@Override
public boolean isRendered()
{
Object value = helper.getTagAttributeValue("currentOnly");
boolean currentOnly = false;
if (value!=null)
currentOnly = ObjectUtils.getBoolean(value);
// Check parent
if (currentOnly && menuId!=null && parentMenu!=null && parentMenu.getCurrentId()!=null)
{
return isCurrent() || isParent();
}
return super.isRendered();
}
protected String getStyleClass()
{
String styleClass = helper.getTagAttributeString("styleClass");
if (parentMenu!=null)
{
// Style Class
if (StringUtils.isEmpty(styleClass))
styleClass = parentMenu.getItemStyleClass();
// Menu Class
if (isCurrent())
styleClass = appendStyleClass(styleClass, parentMenu.getCurrentClass());
else if (isParent())
styleClass = appendStyleClass(styleClass, parentMenu.getParentClass());
// expanded
if (isExpanded())
styleClass = appendStyleClass(styleClass, parentMenu.getExpandedClass());
// Disabled / enabled
if (isDisabled())
styleClass = appendStyleClass(styleClass, parentMenu.getDisabledClass());
}
else
{ // disabled
if (isDisabled())
styleClass = appendStyleClass(styleClass, "disabled");
}
// both supplied
return styleClass;
}
protected String appendStyleClass(String styleClass, String newClass)
{
if (StringUtils.isEmpty(newClass))
return styleClass;
return (styleClass==null) ? newClass : styleClass+" "+newClass;
}
@Override
protected boolean isEncodeLinkChildren(Object linkValue)
{
return false;
}
}