Author: ajaquith
Date: Mon Feb 23 05:18:58 2009
New Revision: 746883
URL: http://svn.apache.org/viewvc?rev=746883&view=rev
Log:
Re-wrote TabbedSectionTab and TabTag so that they operate across included or
nested JSPs.
Modified:
incubator/jspwiki/trunk/src/java/org/apache/wiki/tags/TabTag.java
incubator/jspwiki/trunk/src/java/org/apache/wiki/tags/TabbedSectionTag.java
Modified: incubator/jspwiki/trunk/src/java/org/apache/wiki/tags/TabTag.java
URL:
http://svn.apache.org/viewvc/incubator/jspwiki/trunk/src/java/org/apache/wiki/tags/TabTag.java?rev=746883&r1=746882&r2=746883&view=diff
==============================================================================
--- incubator/jspwiki/trunk/src/java/org/apache/wiki/tags/TabTag.java (original)
+++ incubator/jspwiki/trunk/src/java/org/apache/wiki/tags/TabTag.java Mon Feb
23 05:18:58 2009
@@ -21,19 +21,17 @@
package org.apache.wiki.tags;
-import java.util.Locale;
-
import javax.servlet.jsp.JspTagException;
-import org.apache.wiki.i18n.InternationalizationManager;
+import org.apache.wiki.tags.TabbedSectionTag.TabCollection;
import org.apache.wiki.util.TextUtil;
-
/**
* <p>
- * Generates single tabbed page layout. Works together with the tabbedSection
- * javascript. Note that if you do not specify an url, the body contents of the
- * tag are loaded by the tag itself.
+ * Generates single tabbed page layout, when nested under a
+ * {...@link TabbedSection} tag. Works together with the tabbedSection
javascript.
+ * Note that if you do not specify an url, the body contents of the tag are
+ * loaded by the tag itself.
* </p>
* <p>
* <b>Attributes</b>
@@ -63,64 +61,135 @@
public class TabTag extends WikiTagBase
{
private static final long serialVersionUID = -8534125226484616489L;
-
- private String m_accesskey;
-
- private String m_outputTitle;
-
- private String m_tabTitle;
-
- private String m_tabTitleKey;
-
- private String m_url;
+
+ private final TabInfo m_tabInfo = new TabInfo();
/**
- * {...@inheritdoc}
+ * Lightweight class that holds information about TabTags.
*/
- public int doEndTag() throws javax.servlet.jsp.JspTagException
+ public static class TabInfo
{
- TabbedSectionTag parent = getParentTag( TabbedSectionTag.class );
-
- StringBuilder sb = new StringBuilder();
-
- if( parent.isStateFindDefaultTab() )
+ private String m_id = null;
+
+ private String m_accesskey = null;
+
+ private String m_tabTitle = null;
+
+ private String m_tabTitleKey = null;
+
+ private String m_url = null;
+
+ /**
+ * Sets the id.
+ * @param id
+ */
+ public void setId( String id )
+ {
+ m_id = id;
+ }
+
+ /**
+ * Sets the tab access key.
+ *
+ * @param accessKey the access key
+ */
+ public void setAccesskey( String accessKey )
+ {
+ m_accesskey = TextUtil.replaceEntities( accessKey ); // take only
the
+ // first char
+ }
+
+ /**
+ * Sets the tab title.
+ *
+ * @param title the tab title
+ */
+ public void setTitle( String title )
+ {
+ m_tabTitle = TextUtil.replaceEntities( title );
+ }
+
+ /**
+ * Sets the tab title key.
+ *
+ * @param key the tab title key
+ */
+ public void setTitleKey( String key )
+ {
+ m_tabTitleKey = TextUtil.replaceEntities( key );
+ }
+
+ /**
+ * Sets the tab URL.
+ *
+ * @param url the URL
+ */
+ public void setUrl( String url )
+ {
+ m_url = TextUtil.replaceEntities( url );
+ }
+
+ /**
+ * Returns the ID for this tab.
+ * @return
+ */
+ public String getId()
+ {
+ return m_id;
+ }
+
+ /**
+ * Returns the URL for this tab, if supplied.
+ *
+ * @return the URL
+ */
+ public String getUrl()
+ {
+ return m_url;
+ }
+
+ /**
+ * Returns the tab access key.
+ *
+ * @return the access key
+ */
+ public String getAccesskey()
+ {
+ return m_accesskey;
+ }
+
+ /**
+ * Returns the tab title.
+ * @return the title
+ */
+ public String getTitle()
+ {
+ return m_tabTitle;
+ }
+
+ /**
+ * Returns the i18n key used to generate the tab title.
+ * @return the title key
+ */
+ public String getTitleKey()
{
- // inform the parent of each tab
- parent.validateDefaultTab( getId() );
- }
- else if( parent.isStateGenerateTabBody() )
- {
- sb.append( "</div>\n" );
- }
- else if( parent.isStateGenerateTabMenu() )
- {
- sb.append( "<a" );
-
- if( parent.validateDefaultTab( getId() ) )
- {
- sb.append( " class=\"activetab\"" );
- }
-
- sb.append( " id=\"menu-" + getId() + "\"" );
-
- if( m_url != null )
- {
- sb.append( " href='" + m_url + "'" );
- }
-
- if( handleAccesskey() )
- {
- sb.append( " accesskey=\"" + m_accesskey + "\"" );
- }
-
- sb.append( " >" );
- sb.append( m_outputTitle );
- sb.append( "</a>" );
+ return m_tabTitleKey;
}
+ }
+ protected TabInfo getTabInfo()
+ {
+ return m_tabInfo;
+ }
+
+ /**
+ * {...@inheritdoc}
+ */
+ public int doEndTag() throws javax.servlet.jsp.JspTagException
+ {
try
{
- pageContext.getOut().write( sb.toString() );
+ pageContext.getOut().write( "</div>\n" );
}
catch( java.io.IOException e )
{
@@ -136,12 +205,10 @@
public void doFinally()
{
super.doFinally();
-
- m_accesskey = null;
- m_outputTitle = null;
- m_tabTitle = null;
- m_tabTitleKey = null;
- m_url = null;
+ m_tabInfo.m_accesskey = null;
+ m_tabInfo.m_tabTitle = null;
+ m_tabInfo.m_tabTitleKey = null;
+ m_tabInfo.m_url = null;
}
/**
@@ -149,8 +216,6 @@
*/
public int doWikiStartTag() throws JspTagException
{
- TabbedSectionTag parent = getParentTag( TabbedSectionTag.class );
-
//
// Sanity checks
//
@@ -158,43 +223,22 @@
{
throw new JspTagException( "Tab Tag without \"id\" attribute" );
}
- if( m_tabTitle == null && m_tabTitleKey == null )
+ if( m_tabInfo.m_tabTitle == null && m_tabInfo.m_tabTitleKey == null )
{
throw new JspTagException( "Tab Tag without \"tabTitle\" or
\"tabTitleKey\" attribute" );
}
- if( parent == null )
- {
- throw new JspTagException( "Tab Tag without parent
\"TabbedSection\" Tag" );
- }
-
- // Generate the actual title
- if( m_tabTitleKey != null )
- {
- Locale locale = m_wikiContext.getHttpRequest().getLocale();
- InternationalizationManager i18n =
m_wikiContext.getEngine().getInternationalizationManager();
- m_outputTitle = i18n.get(
InternationalizationManager.TEMPLATES_BUNDLE, locale, m_tabTitleKey );
- }
- if ( m_outputTitle == null )
- {
- m_outputTitle = m_tabTitle;
- }
-
- if( !parent.isStateGenerateTabBody() )
- return SKIP_BODY;
-
- StringBuilder sb = new StringBuilder( 32 );
-
- sb.append( "<div id=\"" + getId() + "\"" );
- if( !parent.validateDefaultTab( getId() ) )
- {
- sb.append( " class=\"hidetab\"" );
- }
- sb.append( " >\n" );
+ // Add tab to TabCollection so parent TabbedSection can get it later
+ TabCollection tc = TabbedSectionTag.getTabContext(
getPageContext().getRequest() );
+ tc.addTab( this );
+ // Generate the opening <div id=foo> tag, always with "hidetab" class
+ // (TabbedSection#doAfterBody will fix this later...)
try
{
- pageContext.getOut().write( sb.toString() );
+ pageContext.getOut().write( "<div id=\"" );
+ pageContext.getOut().write( getId() );
+ pageContext.getOut().write( "\" class=\"hidetab\">\n" );
}
catch( java.io.IOException e )
{
@@ -203,7 +247,17 @@
return EVAL_BODY_INCLUDE;
}
-
+
+ /**
+ * {...@inheritdoc}. Also sets the ID for the embedded {...@link TabInfo
object}.
+ */
+ @Override
+ public void setId( String id )
+ {
+ super.setId( id );
+ m_tabInfo.setId( id );
+ }
+
/**
* Sets the tab access key.
*
@@ -211,8 +265,7 @@
*/
public void setAccesskey( String accessKey )
{
- m_accesskey = TextUtil.replaceEntities( accessKey ); // take only the
- // first char
+ m_tabInfo.setAccesskey( accessKey );
}
/**
@@ -222,7 +275,7 @@
*/
public void setTitle( String title )
{
- m_tabTitle = TextUtil.replaceEntities( title );
+ m_tabInfo.setTitle( title );
}
/**
@@ -232,7 +285,7 @@
*/
public void setTitleKey( String key )
{
- m_tabTitleKey = TextUtil.replaceEntities( key );
+ m_tabInfo.setTitleKey( key );
}
/**
@@ -242,21 +295,6 @@
*/
public void setUrl( String url )
{
- m_url = TextUtil.replaceEntities( url );
- }
-
- // insert <u> ..accesskey.. </u> in title
- private boolean handleAccesskey()
- {
- if( (m_outputTitle == null) || (m_accesskey == null) )
- return false;
-
- int pos = m_outputTitle.toLowerCase().indexOf(
m_accesskey.toLowerCase() );
- if( pos > -1 )
- {
- m_outputTitle = m_outputTitle.substring( 0, pos ) + "<span
class='accesskey'>" + m_outputTitle.charAt( pos )
- + "</span>" + m_outputTitle.substring( pos + 1 );
- }
- return true;
+ m_tabInfo.setUrl( url );
}
}
Modified:
incubator/jspwiki/trunk/src/java/org/apache/wiki/tags/TabbedSectionTag.java
URL:
http://svn.apache.org/viewvc/incubator/jspwiki/trunk/src/java/org/apache/wiki/tags/TabbedSectionTag.java?rev=746883&r1=746882&r2=746883&view=diff
==============================================================================
--- incubator/jspwiki/trunk/src/java/org/apache/wiki/tags/TabbedSectionTag.java
(original)
+++ incubator/jspwiki/trunk/src/java/org/apache/wiki/tags/TabbedSectionTag.java
Mon Feb 23 05:18:58 2009
@@ -20,121 +20,188 @@
*/
package org.apache.wiki.tags;
-import javax.servlet.jsp.*;
-import javax.servlet.jsp.tagext.*;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Locale;
+
+import javax.servlet.ServletRequest;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.jsp.JspException;
+import javax.servlet.jsp.JspTagException;
+import javax.servlet.jsp.JspWriter;
+import javax.servlet.jsp.tagext.BodyContent;
+import javax.servlet.jsp.tagext.BodyTagSupport;
+
+import org.apache.wiki.WikiEngine;
+import org.apache.wiki.i18n.InternationalizationManager;
+import org.apache.wiki.tags.TabTag.TabInfo;
/**
- * Generates tabbed page section: container for the Tab tag.
- * Works together with the tabbedSection javacript.
- *
- * <P><B>Attributes</B></P>
- * <UL>
- * <LI>defaultTab - Page name to refer to. Default is the current page.
- * </UL>
- *
- * @author Dirk Frederickx
- * @since v2.3.63
+ * <p>
+ * Generates a container for page tabs, as defined by collaborating
+ * {...@link TabTag} tags. Works together with the tabbedSection JavaScript.
The
+ * output of the two collaborating tags is two sets of <code><div></code>
+ * elements. The first one will have a class of <code>tabmenu</code>, and
+ * includes the tab names, accessibility keys and and URL that contains the
+ * tab's contents (if specified). The second <code><div></code>, of
+ * class <code>tabs</code>, contains additional nested
+ * <code><div></code> elements that contain the actual tab content, if
+ * any was enclosed by the <code>wiki:Tab</code> tags.
+ * </p>
+ * <p>
+ * For example, consider the following tags as defined on a JSP:
+ * </p>
+ * <blockquote><code>
+ * <wiki:TabbedSection defaultTab="pagecontent"><br/>
+ * <wiki:Tab id="pagecontent" title="View"
accesskey="V"><br/>
+ * <p>This is the main tab.</p><br/>
+ * </wiki:Tab><br/>
+ * <wiki:Tab id="info" title="Info" accesskey="I"
url="/PageInfo.jsp?page=Main" /><br/>
+ * </wiki:TabbedSection>
+ * </code></blockquote>
+ * <p>
+ * This will cause the following HTML to be generated when the page contents
are
+ * returned to the browser:
+ * </p>
+ * <blockquote><code>
+ * <div class="tabmenu"><br/>
+ * <a class="activetab" id="menu-pagecontent" accesskey="v"
><span class='accesskey'>V</span>iew</a><br/>
+ * <a id="menu-info"
href='<var>web-context</var>/PageInfo.jsp?page=Main' accesskey="i" ><span
class='accesskey'>I</span>nfo</a><br/>
+ * </div><br/>
+ * <div class="tabs"><br/>
+ * <div id="pagecontent"><br/>
+ * <p>This is the main tab.</p><br/>
+ * </div><br/>
+ * <div id="info" class="hidetab" /><br/>
+ * <div style="clear:both;" ></div><br/>
+ * </div>
+ * </code></blockquote>
+ * <h3>Attributes</h3>
+ * <ul>
+ * <li>defaultTab - Page name to refer to. Default is the first tab.</li>
+ * </ul>
+ *
+ * @author Dirk Frederickx
+ * @author Andrew Jaquith
+ * @since v2.3.63
*/
-// FIXME: Needs a bit more of explaining how this tag works.
public class TabbedSectionTag extends BodyTagSupport
{
- private static final long serialVersionUID = 1702437933960026481L;
- private String m_defaultTabId;
- private String m_firstTabId;
- private boolean m_defaultTabFound = false;
+ private static final long serialVersionUID = 2702437933960026481L;
- private StringBuffer m_buffer = new StringBuffer(BUFFER_SIZE);
-
- private static final int FIND_DEFAULT_TAB = 0;
- private static final int GENERATE_TABMENU = 1;
- private static final int GENERATE_TABBODY = 2;
-
- private static final int BUFFER_SIZE = 1024;
-
- private int m_state = FIND_DEFAULT_TAB;
+ private WikiEngine m_engine;
/**
- * {...@inheritdoc}
+ * Returns the TabCollection for the current HttpServletRequest. This
+ * method is always guaranteed to return a valid TabCollection.
+ *
+ * @param request the servlet request
+ * @return the TabCollection
*/
- @Override
- public void release()
+ public static TabCollection getTabContext( ServletRequest request )
{
- super.release();
- m_defaultTabId = m_firstTabId = null;
- m_defaultTabFound = false;
- m_buffer = new StringBuffer();
- m_state = FIND_DEFAULT_TAB;
+ TabCollection tc = (TabCollection) request.getAttribute( ATTR_TABS );
+ if( tc == null )
+ {
+ tc = new TabCollection();
+ request.setAttribute( ATTR_TABS, tc );
+ }
+ return tc;
}
+
+ private static final String ATTR_TABS = "JSPWiki.TabbedSection.Tags";
/**
- * Set the id of the default tab (the tab which should be shown when
- * the page is first loaded).
- *
- * @param anDefaultTabId ID attribute of the default tab.
+ * Holds the current set of related {...@link TabbedSection} and {...@link
TabTag}
+ * tags. One TabCollection is created for each HTTPServletRequest, rather
than
+ * per PageContext, because the tags could span multiple pages.
*/
- public void setDefaultTab(String anDefaultTabId)
+ public static class TabCollection
{
- m_defaultTabId = anDefaultTabId;
- }
+ /**
+ * Private constructor to prevent direct instantiation.
+ */
+ private TabCollection()
+ {
+ super();
+ }
- // FIXME: I don't really understand what this does - so Dirk, please
- // add some documentation.
- public boolean validateDefaultTab( String aTabId )
- {
- if( m_firstTabId == null ) m_firstTabId = aTabId;
- if( aTabId.equals( m_defaultTabId ) ) m_defaultTabFound = true;
+ private final List<TabTag.TabInfo> m_tabs = new
ArrayList<TabTag.TabInfo>();
- return aTabId.equals( m_defaultTabId );
- }
+ /**
+ * Adds a child TabTag to the TabCollection. When the TabbedSection tag
+ * generates its menu and tab <div> elements, they will be
+ * generated in the order added. The tab added will be stored as a
+ * defensive copy, so that calls to
+ * {...@link javax.servlet.jsp.tagext.Tag#release()} won't null out the
+ * cached copies.
+ *
+ * @param tab the tab to add
+ */
+ public void addTab( TabTag tab ) throws JspTagException
+ {
+ if( tab == null )
+ {
+ throw new JspTagException( "Cannot add null TabTag." );
+ }
- /**
- * {...@inheritdoc}
- */
- @Override
- public int doStartTag() throws JspTagException
- {
- return EVAL_BODY_BUFFERED; /* always look inside */
- }
+ TabInfo tabInfo = new TabInfo();
+ tabInfo.setAccesskey( tab.getTabInfo().getAccesskey() );
+ tabInfo.setId( tab.getTabInfo().getId() );
+ tabInfo.setTitle( tab.getTabInfo().getTitle() );
+ tabInfo.setTitleKey( tab.getTabInfo().getTitleKey() );
+ tabInfo.setUrl( tab.getTabInfo().getUrl() );
+ m_tabs.add( tabInfo );
+ }
+
+ /**
+ * Returns the list TabTag objects known to this TabCollection.
+ *
+ * @return the list of tab
+ */
+ public List<TabTag.TabInfo> getTabs()
+ {
+ return m_tabs;
+ }
+
+ /**
+ * Releases the TabCollection by clearing the internally cached list of
+ * TabTag objects. This method is called by
+ * {...@link TabbedSectionTag#doEndTag()}.
+ */
+ public void release()
+ {
+ m_tabs.clear();
+ }
- /**
- * Returns true, if the tab system is currently trying to
- * figure out which is the default tab.
- *
- * @return True, if finding the default tab.
- */
- public boolean isStateFindDefaultTab()
- {
- return m_state == FIND_DEFAULT_TAB;
}
/**
- * Returns true, if the tab system is currently generating
- * the tab menu.
- *
- * @return True, if currently generating the menu itself.
+ * {...@inheritdoc}
*/
- public boolean isStateGenerateTabMenu()
+ @Override
+ public void release()
{
- return m_state == GENERATE_TABMENU;
+ super.release();
+ m_defaultTabID = null;
}
/**
- * Returns true, if the tab system is currently generating
- * the tab body.
- *
- * @return True, if the tab system is currently generating the tab body.
+ * {...@inheritdoc}
*/
- public boolean isStateGenerateTabBody()
+ @Override
+ public int doStartTag() throws JspTagException
{
- return m_state == GENERATE_TABBODY;
+ m_engine = WikiEngine.getInstance( ((HttpServletRequest)
pageContext.getRequest()).getSession().getServletContext(), null );
+ return EVAL_BODY_BUFFERED; /* always look inside */
}
-
/**
- * The tabbed section iterates 3 time through the underlying Tab tags
- * - first it identifies the default tab (displayed by default)
- * - second it generates the tabmenu markup (displays all tab-titles)
- * - finally it generates the content of each tab.
+ * The tabbed section iterates 3 time through the underlying Tab tags -
+ * first it identifies the default tab (displayed by default) - second it
+ * generates the tabmenu markup (displays all tab-titles) - finally it
+ * generates the content of each tab.
*
* @return {...@inheritdoc}
* @throws {...@inheritdoc}
@@ -142,66 +209,152 @@
@Override
public int doAfterBody() throws JspTagException
{
- if( isStateFindDefaultTab() )
- {
- if( !m_defaultTabFound )
- {
- m_defaultTabId = m_firstTabId;
- }
- m_state = GENERATE_TABMENU;
- return EVAL_BODY_BUFFERED;
- }
- else if( isStateGenerateTabMenu() )
+ // Stash the tag body (previously evaluated)
+ BodyContent body = getBodyContent();
+ String bodyString = body.getString();
+
+ // Figure out the active (default) tab
+ TabCollection tc = getTabContext( pageContext.getRequest() );
+ List<TabTag.TabInfo> tabs = tc.getTabs();
+
+ try
{
- if( bodyContent != null )
+ // Generate menu divs; output to enclosing writer
+ body.clear();
+ JspWriter writer = this.getPreviousOut();
+
+ writer.append( "<div class=\"tabmenu\">\n" );
+ for( TabTag.TabInfo tab : tabs )
{
- m_buffer.append( "<div class=\"tabmenu\">" );
- m_buffer.append( bodyContent.getString() );
- bodyContent.clearBody();
- m_buffer.append( "</div>\n" );
+ // Is this the default tab?
+ if( tab.getId().equals( m_defaultTabID ) )
+ {
+ m_defaultTabID = tab.getId();
+ }
+
+ // If default tag still not 't set, use the first one
+ if( m_defaultTabID == null || m_defaultTabID.length() == 0 )
+ {
+ m_defaultTabID = tab.getId();
+ }
+
+ // Generate each menu item div
+ writeTabMenuItem( writer, tab );
}
- m_state = GENERATE_TABBODY;
- return EVAL_BODY_BUFFERED;
+ writer.append( "</div>\n" );
+
+ // Output the opening "tabs" div
+ writer.append( "<div class=\"tabs\">" );
+
+ // Remove the "hidden" class from the active tab
+ String activeTabDiv = "<div id=\"" + m_defaultTabID + "\"
class=\"hidetab\">";
+ bodyString = bodyString.replace( activeTabDiv, "<div id=\"" +
m_defaultTabID + "\">" );
+
+ // Write back the stashed tag body
+ writer.append( bodyString );
+
+ // Append our closing div tags
+ writer.append( " <div style=\"clear:both;\" ></div>\n</div>\n" );
}
- else if( isStateGenerateTabBody() )
+ catch( IOException e )
{
- if( bodyContent != null )
- {
- m_buffer.append( "<div class=\"tabs\">" );
- m_buffer.append( bodyContent.getString() );
- bodyContent.clearBody();
- m_buffer.append( "<div style=\"clear:both;\"
></div>\n</div>\n" );
- }
- return SKIP_BODY;
+ throw new JspTagException( e );
}
+
return SKIP_BODY;
}
+ public int doEndTag() throws JspException
+ {
+ // Clear the TabCollection for the next caller
+ TabCollection tc = getTabContext( pageContext.getRequest() );
+ tc.release();
+
+ return super.doEndTag();
+ }
+
/**
- * {...@inheritdoc}
+ * Outputs a single menu item <code>div</code> element for a supplied tag.
+ *
+ * @param writer the JspWriter to write the output to
+ * @param tab the TabInfo object containing information about the tab
+ * @throws IOException
*/
- @Override
- public int doEndTag() throws JspTagException
+ private void writeTabMenuItem( JspWriter writer, TabTag.TabInfo tab )
throws IOException
{
- try
+ writer.append( " <a" );
+
+ // Generate the ID
+ writer.append( " id=\"menu-" + tab.getId() + "\"" );
+
+ // Active tab?
+ if( tab.getId().equals( m_defaultTabID ) )
{
- if( m_buffer.length() > 0 )
- {
- getPreviousOut().write( m_buffer.toString() );
- }
+ writer.append( " class=\"activetab\"" );
}
- catch(java.io.IOException e)
+
+ // Generate the URL, if supplied
+ if( tab.getUrl() != null )
{
- throw new JspTagException( "IO Error: " + e.getMessage() );
+ writer.append( " href='" + tab.getUrl() + "'" );
}
- //now reset some stuff for the next run -- ugh.
- m_buffer = new StringBuffer(BUFFER_SIZE);
- m_state = FIND_DEFAULT_TAB;
- m_defaultTabId = null;
- m_firstTabId = null;
- m_defaultTabFound = false;
- return EVAL_PAGE;
+ // Generate the tab title
+ String tabTitle = null;
+ if( tab.getTitleKey() != null )
+ {
+ Locale locale = pageContext.getRequest().getLocale();
+ InternationalizationManager i18n =
m_engine.getInternationalizationManager();
+ tabTitle = i18n.get( InternationalizationManager.TEMPLATES_BUNDLE,
locale, tab.getTitleKey() );
+ }
+ if( tabTitle == null )
+ {
+ tabTitle = tab.getTitle();
+ }
+ writer.append( ">" );
+
+ // Output the tab title
+ String accesskey = tab.getAccesskey();
+ if( tabTitle != null )
+ {
+ // Generate the access key, if supplied
+ if( accesskey != null )
+ {
+ int pos = tabTitle.toLowerCase().indexOf(
accesskey.toLowerCase() );
+ if( pos > -1 )
+ {
+ tabTitle = tabTitle.substring( 0, pos ) + "<span
class='accesskey'>" + tabTitle.charAt( pos ) + "</span>"
+ + tabTitle.substring( pos + 1 );
+ }
+ }
+ writer.append( tabTitle );
+ }
+
+ // Output the closing tag
+ writer.append( "</a>\n" );
+ }
+
+ private String m_defaultTabID = null;
+
+ /**
+ * Returns the default tab ID.
+ *
+ * @return the tab ID
+ */
+ protected String getDefaultTab()
+ {
+ return m_defaultTabID;
+ }
+
+ /**
+ * Sets the id of the default tab. If not set, the first {...@link TabTag}
+ * element encountered will be used as the default.
+ *
+ * @param defaultTab the id of tab to use as the default
+ */
+ public void setDefaultTab( String defaultTab )
+ {
+ m_defaultTabID = defaultTab;
}
}