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    
020    package org.apache.wiki.tags;
021    
022    import javax.servlet.jsp.JspTagException;
023    
024    import org.apache.wiki.util.TextUtil;
025    
026    /**
027     *  Generates single tabbed page layout.
028     *  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     */
046    
047    public class TabTag extends WikiTagBase
048    {
049        private static final long serialVersionUID = -8534125226484616489L;
050        private String m_accesskey;
051        private String m_tabTitle;
052        private String m_url;
053    
054        /**
055         * {@inheritDoc}
056         */
057        public void doFinally()
058        {
059            super.doFinally();
060    
061            m_accesskey = null;
062            m_tabTitle  = null;
063            m_url       = null;
064        }
065    
066        /**
067         * Sets the tab title.
068         * @param aTabTitle the tab title
069         */
070        public void setTitle(String aTabTitle)
071        {
072            m_tabTitle = TextUtil.replaceEntities( aTabTitle );
073        }
074    
075        /**
076         * Sets the tab access key.
077         * @param anAccesskey the access key
078         */
079        public void setAccesskey(String anAccesskey)
080        {
081            m_accesskey = TextUtil.replaceEntities( anAccesskey ); //take only the first char
082        }
083    
084        /**
085         * Sets the tab URL.
086         * @param url the URL
087         */
088        public void setUrl( String url )
089        {
090            m_url = TextUtil.replaceEntities( url );
091        }
092    
093        // insert <u> ..accesskey.. </u> in title
094        private boolean handleAccesskey()
095        {
096            if( (m_tabTitle == null) || (m_accesskey == null) ) return false;
097    
098            int pos = m_tabTitle.toLowerCase().indexOf( m_accesskey.toLowerCase() );
099            if( pos > -1 )
100            {
101                m_tabTitle = m_tabTitle.substring( 0, pos ) + "<span class='accesskey'>"
102                           + m_tabTitle.charAt( pos ) + "</span>" + m_tabTitle.substring( pos+1 );
103            }
104            return true;
105        }
106    
107        /**
108         * {@inheritDoc}
109         */
110        public int doWikiStartTag() throws JspTagException
111        {
112            TabbedSectionTag parent=(TabbedSectionTag)findAncestorWithClass( this, TabbedSectionTag.class );
113    
114            //
115            //  Sanity checks
116            //
117            if( getId() == null )
118            {
119                throw new JspTagException("Tab Tag without \"id\" attribute");
120            }
121            if( m_tabTitle == null )
122            {
123                throw new JspTagException("Tab Tag without \"tabTitle\" attribute");
124            }
125            if( parent == null )
126            {
127                throw new JspTagException("Tab Tag without parent \"TabbedSection\" Tag");
128            }
129    
130            if( !parent.isStateGenerateTabBody() ) return SKIP_BODY;
131    
132            StringBuffer sb = new StringBuffer(32);
133    
134            sb.append( "<div id=\""+ getId() + "\"" );
135    
136            if( !parent.validateDefaultTab( getId()) )
137            {
138                sb.append( " class=\"hidetab\"" );
139            }
140            sb.append( " >\n" );
141    
142            try
143            {
144                pageContext.getOut().write( sb.toString() );
145            }
146            catch( java.io.IOException e )
147            {
148                throw new JspTagException( "IO Error: " + e.getMessage() );
149            }
150    
151            return EVAL_BODY_INCLUDE;
152        }
153    
154        /**
155         * {@inheritDoc}
156         */
157        public int doEndTag() throws javax.servlet.jsp.JspTagException
158        {
159            TabbedSectionTag parent=(TabbedSectionTag)findAncestorWithClass( this, TabbedSectionTag.class );
160    
161            StringBuffer sb = new StringBuffer();
162    
163            if( parent.isStateFindDefaultTab() )
164            {
165                //inform the parent of each tab
166                parent.validateDefaultTab( getId() );
167            }
168            else if( parent.isStateGenerateTabBody() )
169            {
170                sb.append( "</div>\n" );
171            }
172            else if( parent.isStateGenerateTabMenu() )
173            {
174                sb.append( "<a" );
175    
176                if( parent.validateDefaultTab( getId() ) )
177                {
178                    sb.append( " class=\"activetab\"" );
179                }
180    
181                sb.append( " id=\"menu-" + getId() + "\"" );
182    
183                if( m_url != null )
184                {
185                    sb.append( " href='"+m_url+"'" );
186                }
187    
188                if( handleAccesskey() )
189                {
190                    sb.append( " accesskey=\"" + m_accesskey + "\"" );
191                }
192    
193                sb.append( " >" );
194                sb.append( m_tabTitle );
195                sb.append( "</a>" );
196            }
197    
198            try
199            {
200                pageContext.getOut().write( sb.toString() );
201            }
202            catch( java.io.IOException e )
203            {
204                throw new JspTagException( "IO Error: " + e.getMessage() );
205            }
206    
207            return EVAL_PAGE;
208        }
209    }