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 package org.apache.wiki.tags;
020
021 import javax.servlet.jsp.*;
022 import javax.servlet.jsp.tagext.*;
023
024 /**
025 * Generates tabbed page section: container for the Tab tag.
026 * Works together with the tabbedSection javacript.
027 *
028 * <P><B>Attributes</B></P>
029 * <UL>
030 * <LI>defaultTab - Page name to refer to. Default is the current page.
031 * </UL>
032 *
033 * @since v2.3.63
034 */
035 // FIXME: Needs a bit more of explaining how this tag works.
036 public class TabbedSectionTag extends BodyTagSupport
037 {
038 private static final long serialVersionUID = 1702437933960026481L;
039 private String m_defaultTabId;
040 private String m_firstTabId;
041 private boolean m_defaultTabFound = false;
042
043 private StringBuffer m_buffer = new StringBuffer(BUFFER_SIZE);
044
045 private static final int FIND_DEFAULT_TAB = 0;
046 private static final int GENERATE_TABMENU = 1;
047 private static final int GENERATE_TABBODY = 2;
048
049 private static final int BUFFER_SIZE = 1024;
050
051 private int m_state = FIND_DEFAULT_TAB;
052
053 /**
054 * {@inheritDoc}
055 */
056 @Override
057 public void release()
058 {
059 super.release();
060 m_defaultTabId = m_firstTabId = null;
061 m_defaultTabFound = false;
062 m_buffer = new StringBuffer();
063 m_state = FIND_DEFAULT_TAB;
064 }
065
066 /**
067 * Set the id of the default tab (the tab which should be shown when
068 * the page is first loaded).
069 *
070 * @param anDefaultTabId ID attribute of the default tab.
071 */
072 public void setDefaultTab(String anDefaultTabId)
073 {
074 m_defaultTabId = anDefaultTabId;
075 }
076
077 // FIXME: I don't really understand what this does - so Dirk, please
078 // add some documentation.
079 public boolean validateDefaultTab( String aTabId )
080 {
081 if( m_firstTabId == null ) m_firstTabId = aTabId;
082 if( aTabId.equals( m_defaultTabId ) ) m_defaultTabFound = true;
083
084 return aTabId.equals( m_defaultTabId );
085 }
086
087 /**
088 * {@inheritDoc}
089 */
090 @Override
091 public int doStartTag() throws JspTagException
092 {
093 return EVAL_BODY_BUFFERED; /* always look inside */
094 }
095
096 /**
097 * Returns true, if the tab system is currently trying to
098 * figure out which is the default tab.
099 *
100 * @return True, if finding the default tab.
101 */
102 public boolean isStateFindDefaultTab()
103 {
104 return m_state == FIND_DEFAULT_TAB;
105 }
106
107 /**
108 * Returns true, if the tab system is currently generating
109 * the tab menu.
110 *
111 * @return True, if currently generating the menu itself.
112 */
113 public boolean isStateGenerateTabMenu()
114 {
115 return m_state == GENERATE_TABMENU;
116 }
117
118 /**
119 * Returns true, if the tab system is currently generating
120 * the tab body.
121 *
122 * @return True, if the tab system is currently generating the tab body.
123 */
124 public boolean isStateGenerateTabBody()
125 {
126 return m_state == GENERATE_TABBODY;
127 }
128
129
130 /**
131 * The tabbed section iterates 3 time through the underlying Tab tags
132 * - first it identifies the default tab (displayed by default)
133 * - second it generates the tabmenu markup (displays all tab-titles)
134 * - finally it generates the content of each tab.
135 *
136 * @return {@inheritDoc}
137 * @throws {@inheritDoc}
138 */
139 @Override
140 public int doAfterBody() throws JspTagException
141 {
142 if( isStateFindDefaultTab() )
143 {
144 if( !m_defaultTabFound )
145 {
146 m_defaultTabId = m_firstTabId;
147 }
148 m_state = GENERATE_TABMENU;
149 return EVAL_BODY_BUFFERED;
150 }
151 else if( isStateGenerateTabMenu() )
152 {
153 if( bodyContent != null )
154 {
155 m_buffer.append( "<div class=\"tabmenu\">" );
156 m_buffer.append( bodyContent.getString() );
157 bodyContent.clearBody();
158 m_buffer.append( "</div>\n" );
159 }
160 m_state = GENERATE_TABBODY;
161 return EVAL_BODY_BUFFERED;
162 }
163 else if( isStateGenerateTabBody() )
164 {
165 if( bodyContent != null )
166 {
167 m_buffer.append( "<div class=\"tabs\">" );
168 m_buffer.append( bodyContent.getString() );
169 bodyContent.clearBody();
170 m_buffer.append( "<div style=\"clear:both;\" ></div>\n</div>\n" );
171 }
172 return SKIP_BODY;
173 }
174 return SKIP_BODY;
175 }
176
177 /**
178 * {@inheritDoc}
179 */
180 @Override
181 public int doEndTag() throws JspTagException
182 {
183 try
184 {
185 if( m_buffer.length() > 0 )
186 {
187 getPreviousOut().write( m_buffer.toString() );
188 }
189 }
190 catch(java.io.IOException e)
191 {
192 throw new JspTagException( "IO Error: " + e.getMessage() );
193 }
194
195 //now reset some stuff for the next run -- ugh.
196 m_buffer = new StringBuffer(BUFFER_SIZE);
197 m_state = FIND_DEFAULT_TAB;
198 m_defaultTabId = null;
199 m_firstTabId = null;
200 m_defaultTabFound = false;
201 return EVAL_PAGE;
202 }
203
204 }