/**
*
*/
package com.joe.jsf.component;
import java.io.IOException;
import java.util.Iterator;
import java.util.List;
import javax.faces.component.UICommand;
import javax.faces.component.UIParameter;
import javax.faces.component.html.HtmlCommandLink;
import javax.faces.context.FacesContext;
import javax.faces.context.ResponseWriter;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import com.joe.jsf.web.view.BreadCrumbInfo;
/**
* This is the component class for the breadCrumb tag.
*
* @author John J. Jones III
*
* Creation date: Jun 8, 2007
* Copyright (c) 2007 MEDecision, Inc. All rights reserved.
*/
public class UIBreadCrumb extends UICommand {
private static Log log = LogFactory.getLog(UIBreadCrumb.class);
/* (non-Javadoc)
* @see javax.faces.component.UIComponentBase#encodeBegin(javax.faces.context.FacesContext)
*/
@Override
public void encodeBegin(FacesContext context) throws IOException {
ResponseWriter writer = context.getResponseWriter();
List<BreadCrumbInfo> breadCrumbList = (List)getAttributes().get("breadCrumbList");
String styleClass = (String)getAttributes().get("styleClass");
writer.startElement("div", null);
writer.writeAttribute("id", "bcr", null);
// write class attribute for header
writer.writeAttribute("class", styleClass, null);
// write end cap div
writer.startElement("div", null);
writer.writeAttribute("class", "bcr_right_end_cap", null);
writer.endElement("div");
writer.startElement("ul", null);
final String liClassFirst = "first";
String liClass = "";
// encode bread crumb
int iternum = 0;
for (BreadCrumbInfo crumb : breadCrumbList) {
if (iternum==0) {
liClass=liClassFirst;
}
else {
liClass="";
}
// if this breadcrumb is not the last in the list
if (iternum+1 < breadCrumbList.size()) {
encodeListItem(writer, context, liClass, true, crumb);
}
// if the crumb is the last one (represents active crumb)
else {
liClass = new String("on");
if (iternum==0) {
liClass = liClass.concat(" first");
}
encodeListItem(writer, context, liClass, false, crumb);
}
iternum++;
}
writer.endElement("ul");
}
@Override
public void encodeChildren(FacesContext arg0) throws IOException {
//In SUN RI JSF 1.2: Override the parents encodeChildren method to prevent duplicate encode of CommandLink
}
/* (non-Javadoc)
* @see javax.faces.component.UIComponentBase#encodeEnd(javax.faces.context.FacesContext)
*/
@Override
public void encodeEnd(FacesContext context) throws IOException {
ResponseWriter writer = context.getResponseWriter();
writer.endElement("div");
}
/**
* Method encodes a list item for the unordered breadcrumb list
*
* @param writer
* @param context
* @param liClass
* @param linkable
* @param crumb
* @throws IOException
*/
private void encodeListItem(ResponseWriter writer,FacesContext context,
String liClass,boolean linkable, BreadCrumbInfo crumb) throws IOException {
writer.startElement("li", null);
if (liClass!=null && !liClass.equals("")) {
writer.writeAttribute("class", liClass, null);
}
if (linkable) {
if (crumb.getBindingMethod()==null || crumb.getBindingMethod().equals("")) {
/*
UIOutput uiOutput = new UIOutput();
uiOutput.setValue(crumb.getDisplayText());
uiOutput.encodeBegin(context);
uiOutput.encodeChildren(context);
uiOutput.encodeEnd(context);
*/
writer.startElement("a", null);
writer.writeText(crumb.getDisplayText(), null);
writer.endElement("a");
writer.startElement("div", null);
writer.endElement("div");
}
else {
UICommand uiCommandLink = generateCommandLinkFromBreadCrumb(context, crumb);
// encode the commandlink
uiCommandLink.encodeBegin(context);
uiCommandLink.encodeChildren(context);
uiCommandLink.encodeEnd(context);
}
writer.startElement("div", null);
writer.writeAttribute("class", "off", null);
writer.endElement("div");
writer.startElement("div", null);
writer.writeAttribute("class", "over", null);
writer.endElement("div");
}
else {
writer.startElement("a", null);
writer.writeText(crumb.getDisplayText(), null);
writer.endElement("a");
writer.startElement("div", null);
writer.endElement("div");
}
writer.endElement("li");
}
/**
* Method generates and returns an HTMLCommandLink object based on the passed in BreadCrumbInfo object.
*
* @param context
* @param crumb
* @return
*/
private UICommand generateCommandLinkFromBreadCrumb(FacesContext context,BreadCrumbInfo crumb) {
UICommand uiCommandLink = new HtmlCommandLink();
// set display value of command link
uiCommandLink.setValue(crumb.getDisplayText());
// set action attribute (this is a method binding attribute based on the string
// equivilent within the breadcrumbinfo object)
uiCommandLink.setAction(context.getApplication().createMethodBinding(crumb.getBindingMethod(), null));
// set immediate to true for now to bypass jsf validation phase
uiCommandLink.setImmediate(true);
// set this (the UIBreadCrumb) as the parent of this commandlink object since needs
// to have context of form or parent to render correctly
this.getChildren().add(uiCommandLink);
if (crumb.getParams()!=null) {
// iterate through all map keys
Iterator keyIter = crumb.getParams().keySet().iterator();
while (keyIter.hasNext()) {
// Create UIParameter object and set name and value attributes
String key = (String)keyIter.next();
UIParameter uiParam = new UIParameter();
uiParam.setName(key);
uiParam.setValue(crumb.getParams().get(key));
// add parameter as child to commandlink object
uiCommandLink.getChildren().add(uiParam);
}
}
// create unique id in tree for command link
uiCommandLink.setId(context.getViewRoot().createUniqueId());
return uiCommandLink;
}
}