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}