jspwiki-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From ajaqu...@apache.org
Subject svn commit: r746883 - in /incubator/jspwiki/trunk/src/java/org/apache/wiki/tags: TabTag.java TabbedSectionTag.java
Date Mon, 23 Feb 2009 05:18:58 GMT
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>&lt;div&gt;</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>&lt;div&gt;</code>,
of
+ * class <code>tabs</code>, contains additional nested
+ * <code>&lt;div&gt;</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>
+ * &lt;wiki:TabbedSection defaultTab="pagecontent"&gt;<br/>
+ * &nbsp;&nbsp;&lt;wiki:Tab id="pagecontent" title="View" accesskey="V"&gt;<br/>
+ * &nbsp;&nbsp;&nbsp;&nbsp;&lt;p&gt;This is the main tab.&lt;/p&gt;<br/>
+ * &nbsp;&nbsp;&lt;/wiki:Tab&gt;<br/>
+ * &nbsp;&nbsp;&lt;wiki:Tab id="info" title="Info" accesskey="I" url="/PageInfo.jsp?page=Main"
/&gt;<br/>
+ * &lt;/wiki:TabbedSection&gt;
+ * </code></blockquote>
+ * <p>
+ * This will cause the following HTML to be generated when the page contents are
+ * returned to the browser:
+ * </p>
+ * <blockquote><code>
+ * &lt;div class="tabmenu"&gt;<br/>
+ * &nbsp;&nbsp;&lt;a class="activetab" id="menu-pagecontent" accesskey="v" &gt;&lt;span
class='accesskey'&gt;V&lt;/span&gt;iew&lt;/a&gt;<br/>
+ * &nbsp;&nbsp;&lt;a id="menu-info" href='<var>web-context</var>/PageInfo.jsp?page=Main'
accesskey="i" &gt;&lt;span class='accesskey'&gt;I&lt;/span&gt;nfo&lt;/a&gt;<br/>
+ * &lt;/div&gt;<br/>
+ * &lt;div class="tabs"&gt;<br/>
+ * &nbsp;&nbsp;&lt;div id="pagecontent"&gt;<br/>
+ * &nbsp;&nbsp;&nbsp;&nbsp;&lt;p&gt;This is the main tab.&lt;/p&gt;<br/>
+ * &nbsp;&nbsp;&lt;/div&gt;<br/>
+ * &nbsp;&nbsp;&lt;div id="info" class="hidetab" /&gt;<br/>
+ * &nbsp;&nbsp;&lt;div style="clear:both;" &gt;&lt;/div&gt;<br/>
+ * &lt;/div&gt;
+ * </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 &lt;div&gt; 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;
     }
 
 }



Mime
View raw message