001/* 002 Licensed to the Apache Software Foundation (ASF) under one 003 or more contributor license agreements. See the NOTICE file 004 distributed with this work for additional information 005 regarding copyright ownership. The ASF licenses this file 006 to you under the Apache License, Version 2.0 (the 007 "License"); you may not use this file except in compliance 008 with the License. You may obtain a copy of the License at 009 010 http://www.apache.org/licenses/LICENSE-2.0 011 012 Unless required by applicable law or agreed to in writing, 013 software distributed under the License is distributed on an 014 "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 015 KIND, either express or implied. See the License for the 016 specific language governing permissions and limitations 017 under the License. 018 */ 019 020package org.apache.wiki.tags; 021 022import org.apache.wiki.util.TextUtil; 023 024import javax.servlet.jsp.JspTagException; 025import java.io.IOException; 026 027/** 028 * Generates single tabbed page layout. Works together with the tabbedSection javascript. Note that if you do not 029 * specify an url, the body contents of the tag are loaded by the tag itself. 030 * 031 * <P><B>Attributes</B></P> 032 * <UL> 033 * <LI>id - ID for this tab. (mandatory) 034 * <LI>title - Title of this tab. (mandatory) 035 * <LI>accesskey - Single char usable as quick accesskey (alt- or ctrl-) (optional) 036 * <li>url - If you <i>don't</i> want to create a Javascript-enabled tag, you can use this 037 * to make the tab look just the usual tag, but instead, it will actually link 038 * to that page. This can be useful in certain cases where you have something 039 * that you want to look like a part of a tag, but for example, due to it being 040 * very big in size, don't want to include it as a part of the page content 041 * every time. 042 * </UL> 043 * 044 * @since v2.3.63 045 */ 046public class TabTag extends WikiTagBase { 047 048 private static final long serialVersionUID = -8534125226484616489L; 049 private String m_accesskey; 050 private String m_tabTitle; 051 private String m_url; 052 053 /** 054 * {@inheritDoc} 055 */ 056 @Override 057 public void doFinally() { 058 super.doFinally(); 059 060 m_accesskey = null; 061 m_tabTitle = null; 062 m_url = null; 063 } 064 065 /** 066 * Sets the tab title. 067 * @param aTabTitle the tab title 068 */ 069 public void setTitle( final String aTabTitle ) { 070 m_tabTitle = TextUtil.replaceEntities( aTabTitle ); 071 } 072 073 /** 074 * Sets the tab access key. 075 * 076 * @param anAccesskey the access key 077 */ 078 public void setAccesskey( final String anAccesskey ) { 079 m_accesskey = TextUtil.replaceEntities( anAccesskey ); //take only the first char 080 } 081 082 /** 083 * Sets the tab URL. 084 * 085 * @param url the URL 086 */ 087 public void setUrl( final String url ) { 088 m_url = TextUtil.replaceEntities( url ); 089 } 090 091 // insert <u> ..accesskey.. </u> in title 092 private boolean handleAccesskey() { 093 if( ( m_tabTitle == null ) || ( m_accesskey == null ) ) return false; 094 095 final int pos = m_tabTitle.toLowerCase().indexOf( m_accesskey.toLowerCase() ); 096 if( pos > -1 ) { 097 m_tabTitle = m_tabTitle.substring( 0, pos ) + "<span class='accesskey'>" 098 + m_tabTitle.charAt( pos ) + "</span>" + m_tabTitle.substring( pos + 1 ); 099 } 100 return true; 101 } 102 103 /** 104 * {@inheritDoc} 105 */ 106 @Override 107 public int doWikiStartTag() throws JspTagException { 108 final TabbedSectionTag parent = ( TabbedSectionTag ) findAncestorWithClass( this, TabbedSectionTag.class ); 109 110 // Sanity checks 111 if( getId() == null ) { 112 throw new JspTagException( "Tab Tag without \"id\" attribute" ); 113 } 114 if( m_tabTitle == null ) { 115 throw new JspTagException( "Tab Tag without \"tabTitle\" attribute" ); 116 } 117 if( parent == null ) { 118 throw new JspTagException( "Tab Tag without parent \"TabbedSection\" Tag" ); 119 } 120 if( !parent.isStateGenerateTabBody() ) { 121 return SKIP_BODY; 122 } 123 124 final StringBuilder sb = new StringBuilder( 32 ); 125 sb.append( "<div id=\"" ).append( getId() ).append( "\"" ); 126 if( !parent.validateDefaultTab( getId() ) ) { 127 sb.append( " class=\"hidetab\"" ); 128 } 129 sb.append( " >\n" ); 130 131 try { 132 pageContext.getOut().write( sb.toString() ); 133 } catch( final IOException e ) { 134 throw new JspTagException( "IO Error: " + e.getMessage() ); 135 } 136 137 return EVAL_BODY_INCLUDE; 138 } 139 140 /** 141 * {@inheritDoc} 142 */ 143 @Override 144 public int doEndTag() throws JspTagException { 145 final TabbedSectionTag parent = ( TabbedSectionTag ) findAncestorWithClass( this, TabbedSectionTag.class ); 146 final StringBuilder sb = new StringBuilder(); 147 if( parent.isStateFindDefaultTab() ) { 148 // inform the parent of each tab 149 parent.validateDefaultTab( getId() ); 150 } else if( parent.isStateGenerateTabBody() ) { 151 sb.append( "</div>\n" ); 152 } else if( parent.isStateGenerateTabMenu() ) { 153 sb.append( "<a" ); 154 if( parent.validateDefaultTab( getId() ) ) { 155 sb.append( " class=\"activetab\"" ); 156 } 157 158 sb.append( " id=\"menu-" ).append( getId() ).append( "\"" ); 159 160 if( m_url != null ) { 161 sb.append( " href='" ).append( m_url ).append( "'" ); 162 } 163 164 if( handleAccesskey() ) { 165 sb.append( " accesskey=\"" ).append( m_accesskey ).append( "\"" ); 166 } 167 168 sb.append( " >" ); 169 sb.append( m_tabTitle ); 170 sb.append( "</a>" ); 171 } 172 173 try { 174 pageContext.getOut().write( sb.toString() ); 175 } catch( final IOException e ) { 176 throw new JspTagException( "IO Error: " + e.getMessage() ); 177 } 178 179 return EVAL_PAGE; 180 } 181 182}