/* * RHQ Management Platform * Copyright (C) 2005-2008 Red Hat, Inc. * All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation version 2 of the License. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ package org.rhq.enterprise.gui.common.tabbar; import java.io.IOException; import java.util.List; import javax.faces.component.UIComponent; import javax.faces.context.FacesContext; import javax.faces.context.ResponseWriter; import javax.faces.render.Renderer; import org.rhq.core.gui.util.FacesComponentUtility; /** * A renderer that renders a {@link TabBarComponent} component as XHTML. * * @author Ian Springer * @author Joseph Marques */ public class TabBarRenderer extends Renderer { /** * Encode the beginning of this component. * * @param facesContext <code>FacesContext</code> for the current request * @param component <code>TabBarComponent</code> to be encoded */ public void encodeBegin(FacesContext facesContext, UIComponent component) throws IOException { TabBarComponent tabBar = (TabBarComponent) component; processAttributes(tabBar); if (tabBar.getTabs().isEmpty()) { throw new IllegalStateException("The 'tabBar' element requires at least one 'tab' child element."); } // Process f:param child tags... tabBar.setParameters(FacesComponentUtility.getParameters(tabBar)); ResponseWriter writer = facesContext.getResponseWriter(); // <table width="100%" border="0" cellspacing="0" cellpadding="0"> writer.startElement("table", tabBar); writer.writeAttribute("width", "100%", null); writer.writeAttribute("border", "0", null); writer.writeAttribute("border-spacing", "0", null); writer.writeAttribute("cellspacing", "0", null); writer.writeAttribute("cellpadding", "0", null); writer.startElement("tr", tabBar); writeCSSEdgeSpacerCell(writer, tabBar, true, false); } /** * Encode the ending of this component. * * @param facesContext <code>FacesContext</code> for the current request * @param component <code>TabBarComponent</code> to be encoded */ public void encodeEnd(FacesContext facesContext, UIComponent component) throws IOException { TabBarComponent tabBar = (TabBarComponent) component; ResponseWriter writer = facesContext.getResponseWriter(); // Add a spacer cell to fill up any remaining horizontal space remaining in the row of tabs. writeCSSEdgeSpacerCell(writer, tabBar, false, false); writer.endElement("tr"); writeSubTabs(writer, tabBar); writer.endElement("tr"); writer.endElement("table"); } private void processAttributes(TabBarComponent tabBar) { if (tabBar.getSelectedTabName() == null) { throw new IllegalStateException("The 'tabBar' element requires a 'selectedTabName' attribute."); } tabBar.selectTab(tabBar.getSelectedTabName()); } private void writeSubTabs(ResponseWriter writer, TabBarComponent tabBar) throws IOException { writer.startElement("tr", tabBar); // <td colspan="x"> writer.startElement("td", tabBar); int tabs = 1; // the spacer for (TabComponent tab : tabBar.getTabs()) { if (tab.isRendered()) { tabs++; } } writer.writeAttribute("colspan", tabs * 2, null); // <table width="100%" border="0" cellspacing="0" cellpadding="0"> writer.startElement("table", tabBar); writer.writeAttribute("class", "subtab-bar", null); writer.writeAttribute("width", "100%", null); writer.writeAttribute("border", "0", null); writer.writeAttribute("cellspacing", "0", null); writer.writeAttribute("cellpadding", "0", null); writer.startElement("tr", tabBar); writeCSSEdgeSpacerCell(writer, tabBar, true, true); // Write out the actual subtabs, which already rendered themselves earlier. List<SubtabComponent> subtabs = tabBar.getSelectedTab().getSubtabs(); for (SubtabComponent subtab : subtabs) { if (subtab.getRendererOutput() == null) { throw new IllegalStateException("Subtabs for selected tab '" + tabBar.getSelectedTab().getName() + "' were not rendered - the tab is most likely not legitimate for the current Resource or Group."); } writer.write(subtab.getRendererOutput()); } // Add a spacer cell to fill up any remaining horizontal space remaining in the row of subtabs. writeCSSEdgeSpacerCell(writer, tabBar, false, true); writer.endElement("tr"); writer.endElement("table"); writer.endElement("td"); } private void writeCSSEdgeSpacerCell(ResponseWriter writer, TabBarComponent tabBar, boolean isLeft, boolean isSub) throws IOException { writer.startElement("td", tabBar); writer.writeAttribute("style", "vertical-align: bottom;", null); if (!isLeft) { // last column takes up remainder of width writer.writeAttribute("width", "100%", null); } writer.startElement("div", tabBar); String prefix = (isSub) ? "sub" : ""; String styleClass = prefix + "tab-spacer"; writer.writeAttribute("class", styleClass, null); writer.write("."); // won't see this because text color will match background color writer.endElement("div"); writer.endElement("td"); } }