/**
* This file Copyright (c) 2012 Magnolia International
* Ltd. (http://www.magnolia-cms.com). All rights reserved.
*
*
* This file is dual-licensed under both the Magnolia
* Network Agreement and the GNU General Public License.
* You may elect to use one or the other of these licenses.
*
* This file is distributed in the hope that it will be
* useful, but AS-IS and WITHOUT ANY WARRANTY; without even the
* implied warranty of MERCHANTABILITY or FITNESS FOR A
* PARTICULAR PURPOSE, TITLE, or NONINFRINGEMENT.
* Redistribution, except as permitted by whichever of the GPL
* or MNA you select, is prohibited.
*
* 1. For the GPL license (GPL), you can redistribute and/or
* modify this file under the terms of the GNU General
* Public License, Version 3, as published by the Free Software
* Foundation. You should have received a copy of the GNU
* General Public License, Version 3 along with this program;
* if not, write to the Free Software Foundation, Inc., 51
* Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* 2. For the Magnolia Network Agreement (MNA), this file
* and the accompanying materials are made available under the
* terms of the MNA which accompanies this distribution, and
* is available at http://www.magnolia-cms.com/mna.html
*
* Any modifications to this file must keep this entire header
* intact.
*
*/
package info.magnolia.templating.jsp.taglib;
import info.magnolia.cms.beans.config.ServerConfiguration;
import info.magnolia.context.MgnlContext;
import java.io.IOException;
import javax.jcr.Node;
import javax.jcr.RepositoryException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.JspWriter;
import javax.servlet.jsp.tagext.TagSupport;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.exception.NestableRuntimeException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.tldgen.annotations.BodyContent;
import org.tldgen.annotations.Tag;
/**
* Outputs "breadcrumbs" with links to parents of the current page.
* @jsp.tag name="breadcrumb" body-content="empty"
* @author Marcel Salathe
* @author Fabrizio Giustina
* @version $Revision $ ($Author $)
*/
@Tag(name="breadcrumb", bodyContent=BodyContent.EMPTY)
public class Breadcrumb extends TagSupport {
/**
* Stable serialVersionUID.
*/
private static final long serialVersionUID = 222L;
/**
* Logger.
*/
private static Logger log = LoggerFactory.getLogger(Breadcrumb.class);
/**
* Delimeter between links.
*/
private String delimiter;
private int startLevel = 1;
/**
* Exclude current page from breadcrumb.
*/
private boolean excludeCurrent;
/**
* Add current page but without links.
*/
private boolean nolinkCurrent;
/**
* Output as link. (default: true)
*/
private boolean link = true;
private String hideProperty;
/**
* Name for the property used as page title.
*/
private String titleProperty;
/**
* Css class for active page.
*/
private String activeCss = "active";
/**
* displayed between the page names, e.g. ">"
* @jsp.attribute required="false" rtexprvalue="true"
*/
public void setDelimiter(String delimiter) {
this.delimiter = delimiter;
}
/**
* At which level to start.
* Often you will want to omit top levels, e.g. if you split your site into multiple languages.
* @jsp.attribute required="false" rtexprvalue="true"
*/
public void setStartLevel(String startLevel) {
this.startLevel = (new Integer(startLevel)).intValue();
if (this.startLevel < 1) {
this.startLevel = 1;
}
}
/**
* Name for a page property which, if set, will make the page hidden in the breadcrumb.
* @jsp.attribute required="false" rtexprvalue="true"
*/
public void setHideProperty(String hideProperty) {
this.hideProperty = hideProperty;
}
/**
* Exclude the current (active) page from the breadcrumb. Defaults to false. If true, the current (active) page is
* not included in breadcrumb.
* @jsp.attribute required="false" rtexprvalue="true" type="boolean"
*/
public void setExcludeCurrent(boolean excludeCurrent) {
this.excludeCurrent = excludeCurrent;
}
/**
* Add current page but without links. Defaults to false (also current page is linked)
* @jsp.attribute required="false" rtexprvalue="true" type="boolean"
*/
public void setNolinkCurrent(boolean nolinkCurrent) {
this.nolinkCurrent = nolinkCurrent;
}
/**
* Create links to pages. Defaults to true.
* @jsp.attribute required="false" rtexprvalue="true" type="boolean"
*/
public void setLink(boolean link) {
this.link = link;
}
/**
* Name for a page property which holds the title to display in breadcrumbs. If empty, the standard title is used.
* @jsp.attribute required="false" rtexprvalue="true"
*/
public void setTitleProperty(String titleProperty) {
this.titleProperty = titleProperty;
}
/**
* Css class added to the current page link.
* @jsp.attribute required="false" rtexprvalue="true"
*/
public void setActiveCss(String activeCss) {
this.activeCss = activeCss;
}
@Override
public int doStartTag() throws JspException {
HttpServletRequest request = (HttpServletRequest) pageContext.getRequest();
int endLevel = 0;
try {
Node node = MgnlContext.getJCRSession(MgnlContext.getAggregationState().getRepository()).getNode(MgnlContext.getAggregationState().getHandle());
endLevel = node.getDepth();
if (this.excludeCurrent) {
endLevel--;
}
int addedcount = 0;
JspWriter out = pageContext.getOut();
for (int j = this.startLevel; j <= endLevel; j++) {
Node ancestor = (Node) node.getAncestor(j);
if (StringUtils.isNotEmpty(hideProperty) && ancestor.getProperty(hideProperty).getBoolean()) {
continue;
}
String title = null;
if (StringUtils.isNotEmpty(titleProperty)) {
title = ancestor.getProperty(titleProperty).getString();
}
if (StringUtils.isEmpty(title)) {
title = ancestor.getName();
}
if (StringUtils.isNotEmpty(title)) {
if (addedcount != 0) {
out.print(StringUtils.defaultString(this.delimiter, " > "));
}
if (this.link && !(endLevel == j && nolinkCurrent)) {
out.print("<a href=\"");
out.print(request.getContextPath());
out.print(ancestor.getPath());
out.print(".");
out.print(ServerConfiguration.getInstance().getDefaultExtension());
if (node.getPath().equals(ancestor.getPath())) {
out.print("\" class=\"");
out.print(activeCss);
}
out.print("\">");
}
out.print(title);
if (this.link && !(endLevel == j && nolinkCurrent)) {
out.print("</a>");
}
addedcount++;
}
}
}
catch (RepositoryException e) {
log.debug("Exception caught: " + e.getMessage(), e);
}
catch (IOException e) {
throw new NestableRuntimeException(e);
}
return super.doStartTag();
}
/**
* @see javax.servlet.jsp.tagext.TagSupport#release()
*/
@Override
public void release() {
this.startLevel = 1;
this.delimiter = null;
this.excludeCurrent = false;
this.nolinkCurrent = false;
this.link = true;
this.hideProperty = null;
this.titleProperty = null;
this.activeCss = "active";
super.release();
}
}