jspwiki-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From ajaqu...@apache.org
Subject svn commit: r777924 - in /incubator/jspwiki/trunk/src/java/org/apache/wiki: ./ action/ tags/ ui/stripes/
Date Sat, 23 May 2009 13:39:55 GMT
Author: ajaquith
Date: Sat May 23 13:39:55 2009
New Revision: 777924

URL: http://svn.apache.org/viewvc?rev=777924&view=rev
Log:
Major refactoring of the IteratorTag and its subclasses. The new versions are much, much simpler, have zero redundant code and are easily extensible. As part of this refactoring, direct manipulation of WikiContext state via request attribute WikiTagBase.ATTR_CONTEXT is now officially discouraged; use WikiContextFactory.saveContext() and WikiContextFactory.findContext() instead. Added Javadocs.

Modified:
    incubator/jspwiki/trunk/src/java/org/apache/wiki/WikiEngine.java
    incubator/jspwiki/trunk/src/java/org/apache/wiki/action/WikiContextFactory.java
    incubator/jspwiki/trunk/src/java/org/apache/wiki/tags/AdminBeanIteratorTag.java
    incubator/jspwiki/trunk/src/java/org/apache/wiki/tags/AttachmentsIteratorTag.java
    incubator/jspwiki/trunk/src/java/org/apache/wiki/tags/EditorIteratorTag.java
    incubator/jspwiki/trunk/src/java/org/apache/wiki/tags/HistoryIteratorTag.java
    incubator/jspwiki/trunk/src/java/org/apache/wiki/tags/IteratorTag.java
    incubator/jspwiki/trunk/src/java/org/apache/wiki/tags/SearchResultIteratorTag.java
    incubator/jspwiki/trunk/src/java/org/apache/wiki/tags/WikiBodyTag.java
    incubator/jspwiki/trunk/src/java/org/apache/wiki/tags/WikiTagBase.java
    incubator/jspwiki/trunk/src/java/org/apache/wiki/ui/stripes/WikiInterceptor.java

Modified: incubator/jspwiki/trunk/src/java/org/apache/wiki/WikiEngine.java
URL: http://svn.apache.org/viewvc/incubator/jspwiki/trunk/src/java/org/apache/wiki/WikiEngine.java?rev=777924&r1=777923&r2=777924&view=diff
==============================================================================
--- incubator/jspwiki/trunk/src/java/org/apache/wiki/WikiEngine.java (original)
+++ incubator/jspwiki/trunk/src/java/org/apache/wiki/WikiEngine.java Sat May 23 13:39:55 2009
@@ -45,6 +45,7 @@
 import org.apache.wiki.attachment.AttachmentManager;
 import org.apache.wiki.auth.AuthenticationManager;
 import org.apache.wiki.auth.AuthorizationManager;
+import org.apache.wiki.auth.SessionMonitor;
 import org.apache.wiki.auth.UserManager;
 import org.apache.wiki.auth.acl.AclManager;
 import org.apache.wiki.auth.acl.DefaultAclManager;
@@ -2172,6 +2173,14 @@
         {
             context = m_contextFactory.newContext( request, (HttpServletResponse)null, requestContext );
             
+            // Stash WikiEngine as a request attribute (can be
+            // used later as ${wikiEngine} in EL markup)
+            request.setAttribute( WikiContextFactory.ATTR_WIKIENGINE, this );
+
+            // Stash the WikiSession as a request attribute
+            WikiSession wikiSession = SessionMonitor.getInstance( this ).find( request.getSession() );
+            request.setAttribute( WikiContextFactory.ATTR_WIKISESSION, wikiSession );
+            
             // Stash the action bean/wiki context, and return it!
             WikiContextFactory.saveContext( request, context );
             return context;

Modified: incubator/jspwiki/trunk/src/java/org/apache/wiki/action/WikiContextFactory.java
URL: http://svn.apache.org/viewvc/incubator/jspwiki/trunk/src/java/org/apache/wiki/action/WikiContextFactory.java?rev=777924&r1=777923&r2=777924&view=diff
==============================================================================
--- incubator/jspwiki/trunk/src/java/org/apache/wiki/action/WikiContextFactory.java (original)
+++ incubator/jspwiki/trunk/src/java/org/apache/wiki/action/WikiContextFactory.java Sat May 23 13:39:55 2009
@@ -27,6 +27,7 @@
 import java.util.Properties;
 import java.util.Set;
 
+import javax.servlet.ServletRequest;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
 import javax.servlet.jsp.PageContext;
@@ -50,7 +51,6 @@
 import org.apache.wiki.log.LoggerFactory;
 import org.apache.wiki.parser.MarkupParser;
 import org.apache.wiki.providers.ProviderException;
-import org.apache.wiki.tags.WikiTagBase;
 import org.apache.wiki.ui.stripes.HandlerInfo;
 import org.apache.wiki.ui.stripes.WikiActionBeanContext;
 import org.apache.wiki.url.StripesURLConstructor;
@@ -70,6 +70,9 @@
  */
 public final class WikiContextFactory
 {
+    @SuppressWarnings("unused")
+    private static final String ATTR_CONTEXT = "wikiContext";
+
     /**
      * The PageContext attribute name of the WikiEngine stored by
      * WikiInterceptor.
@@ -99,7 +102,7 @@
      * This method can be used to find the WikiContext programmatically from a
      * JSP PageContext. We check the request context. The wiki context, if it
      * exists, is looked up using the key
-     * {@link org.apache.wiki.tags.WikiTagBase#ATTR_CONTEXT}.
+     * {@link #ATTR_CONTEXT}.
      * 
      * @since 2.4
      * @param pageContext the JSP page context
@@ -108,7 +111,7 @@
     public static WikiContext findContext( PageContext pageContext )
     {
         HttpServletRequest request = (HttpServletRequest) pageContext.getRequest();
-        WikiContext context = (WikiContext) request.getAttribute( WikiTagBase.ATTR_CONTEXT );
+        WikiContext context = (WikiContext) request.getAttribute( ATTR_CONTEXT );
         return context;
     }
 
@@ -116,11 +119,7 @@
      * <p>
      * Saves the supplied WikiContext, and the related WikiEngine and
      * WikiSession, in request scope. The WikiContext is saved as an attribute
-     * named {@link org.apache.wiki.tags.WikiTagBase#ATTR_CONTEXT}. The
-     * WikiEngine is also saved as {@link #ATTR_WIKIENGINE}, and the
-     * WikiSession as {@link #ATTR_WIKISESSION}. Among other things, by saving
-     * these items as attributes, they can be accessed via JSP Expression
-     * Language variables, for example <code>${wikiContext}</code>.
+     * named {@link #ATTR_CONTEXT}.
      * </p>
      * <p>
      * Note: when the WikiContext is saved, it will be guaranteed to have a
@@ -133,17 +132,9 @@
      * @param request the HTTP request
      * @param context the WikiContext to save
      */
-    public static void saveContext( HttpServletRequest request, WikiContext context )
+    public static void saveContext( ServletRequest request, WikiContext context )
     {
-        // Stash WikiEngine as a request attribute (can be
-        // used later as ${wikiEngine} in EL markup)
-        WikiEngine engine = context.getEngine();
-        request.setAttribute( ATTR_WIKIENGINE, engine );
-
-        // Stash the WikiSession as a request attribute
-        WikiSession wikiSession = SessionMonitor.getInstance( engine ).find( request.getSession() );
-        request.setAttribute( ATTR_WIKISESSION, wikiSession );
-        request.setAttribute( WikiTagBase.ATTR_CONTEXT, context );
+        request.setAttribute( ATTR_CONTEXT, context );
     }
 
     private final WikiEngine m_engine;

Modified: incubator/jspwiki/trunk/src/java/org/apache/wiki/tags/AdminBeanIteratorTag.java
URL: http://svn.apache.org/viewvc/incubator/jspwiki/trunk/src/java/org/apache/wiki/tags/AdminBeanIteratorTag.java?rev=777924&r1=777923&r2=777924&view=diff
==============================================================================
--- incubator/jspwiki/trunk/src/java/org/apache/wiki/tags/AdminBeanIteratorTag.java (original)
+++ incubator/jspwiki/trunk/src/java/org/apache/wiki/tags/AdminBeanIteratorTag.java Sat May 23 13:39:55 2009
@@ -26,39 +26,40 @@
 import org.apache.wiki.ui.admin.AdminBean;
 import org.apache.wiki.ui.admin.AdminBeanManager;
 
-
 /**
- *  Provides an iterator for all AdminBeans of a given type.
- *
+ * Iterator tag for all AdminBeans of a given type.
  */
-public class AdminBeanIteratorTag extends IteratorTag
+public class AdminBeanIteratorTag extends IteratorTag<AdminBean>
 {
     private static final long serialVersionUID = 1L;
 
     private int m_type;
 
     /**
-     *  Set the type of the bean.
-     *  
-     *  @param type Type to set
+     * Set the type of the bean to iterate over.
+     * 
+     * @param type type of AdminBean to seek
      */
-    public void setType(String type)
+    public void setType( String type )
     {
         m_type = AdminBeanManager.getTypeFromString( type );
     }
 
     /**
-     *  {@inheritDoc}
+     * Returns the default list of AdminBeans returned by
+     * {@link AdminBeanManager#getAllBeans()}. Only AdminBeans that match the
+     * type set by {@link #setType(String)} will be returned.
+     * 
+     * @return the admin beans
      */
     @Override
-    public void resetIterator()
+    protected Collection<AdminBean> initItems()
     {
         AdminBeanManager mgr = m_wikiContext.getEngine().getAdminBeanManager();
 
+        // Retrieve the list of beans for the specified type
         Collection<AdminBean> beans = mgr.getAllBeans();
-
         ArrayList<AdminBean> typedBeans = new ArrayList<AdminBean>();
-
         for( AdminBean ab : beans )
         {
             if( ab.getType() == m_type )
@@ -67,6 +68,6 @@
             }
         }
 
-        setList( typedBeans );
+        return typedBeans;
     }
 }

Modified: incubator/jspwiki/trunk/src/java/org/apache/wiki/tags/AttachmentsIteratorTag.java
URL: http://svn.apache.org/viewvc/incubator/jspwiki/trunk/src/java/org/apache/wiki/tags/AttachmentsIteratorTag.java?rev=777924&r1=777923&r2=777924&view=diff
==============================================================================
--- incubator/jspwiki/trunk/src/java/org/apache/wiki/tags/AttachmentsIteratorTag.java (original)
+++ incubator/jspwiki/trunk/src/java/org/apache/wiki/tags/AttachmentsIteratorTag.java Sat May 23 13:39:55 2009
@@ -20,144 +20,87 @@
  */
 package org.apache.wiki.tags;
 
-import java.io.IOException;
+import java.util.ArrayList;
 import java.util.Collection;
-import javax.servlet.jsp.JspWriter;
-import javax.servlet.jsp.PageContext;
+import java.util.Collections;
 
 import org.apache.wiki.WikiContext;
 import org.apache.wiki.WikiEngine;
+import org.apache.wiki.action.WikiContextFactory;
 import org.apache.wiki.api.WikiPage;
 import org.apache.wiki.attachment.AttachmentManager;
 import org.apache.wiki.log.Logger;
 import org.apache.wiki.log.LoggerFactory;
 import org.apache.wiki.providers.ProviderException;
 
-
-
 /**
- *  Iterates through the list of attachments one has.
- *
- *  <P><B>Attributes</B></P>
- *  <UL>
- *    <LI>page - Page name to refer to.  Default is the current page.
- *  </UL>
- *
- *  @since 2.0
+ * <p>
+ * Iterator tag for the looping through the attachments of a WikiPage. In
+ * addition to the <code>start</code> and <code>maxItems</code> attributes,
+ * other attributes that can be set are:
+ * </p>
+ * <ul>
+ * <li><code>page</code> - the page name to use. The default is the one
+ * associated with the current WikiContext.</li>
+ * </ul>
+ * 
+ * @see IteratorTag
+ * @since 2.0
  */
-
-// FIXME: Too much in common with IteratorTag - REFACTOR
-public class AttachmentsIteratorTag
-    extends IteratorTag
+public class AttachmentsIteratorTag extends IteratorTag<WikiPage>
 {
-    private static final long serialVersionUID = 0L;
-    
-    static    Logger    log = LoggerFactory.getLogger( AttachmentsIteratorTag.class );
+    private static final long serialVersionUID = 1L;
+
+    private static final Collection<WikiPage> EMPTY_COLLECTION = Collections.unmodifiableCollection( new ArrayList<WikiPage>() );
+
+    static Logger log = LoggerFactory.getLogger( AttachmentsIteratorTag.class );
 
     /**
-     *  {@inheritDoc}
+     * <p>
+     * Returns the attachments for the current WikiContext, or an empty
+     * collection. This method will return an empty collection if:
+     * </p>
+     * <ul>
+     * <li>the attachment manager does not allow attachments</li>
+     * <li>the underlying provider throws an exception</li>
+     * <li>the WikiPage the current WikiContext refers to does not exist
+     * <li>
+     * <li>the WikiPage the current WikiContext has no attachments</li>
+     * </ul>
+     * 
+     * @return the collection attachments
      */
-    @Override
-    public final int doStartTag()
+    private Collection<WikiPage> getAttachments()
     {
-        m_wikiContext = (WikiContext) pageContext.getAttribute( WikiTagBase.ATTR_CONTEXT,
-                                                                PageContext.REQUEST_SCOPE );
-
-        WikiEngine        engine = m_wikiContext.getEngine();
-        AttachmentManager mgr    = engine.getAttachmentManager();
-        WikiPage          page;
-
-        page = m_wikiContext.getPage();
-
+        // Return empty collection if attachments are not enabled
+        WikiContext wikiContext = WikiContextFactory.findContext( pageContext );
+        WikiEngine engine = wikiContext.getEngine();
+        AttachmentManager mgr = engine.getAttachmentManager();
         if( !mgr.attachmentsEnabled() )
         {
-            return SKIP_BODY;
+            return EMPTY_COLLECTION;
         }
 
+        WikiPage page = wikiContext.getPage();
         try
         {
-            if( page != null && engine.pageExists(page) )
-            {
-                Collection<WikiPage> atts = mgr.listAttachments( page );
-
-                if( atts == null )
-                {
-                    log.debug("No attachments to display.");
-                    // There are no attachments included
-                    return SKIP_BODY;
-                }
-
-                m_iterator = atts.iterator();
-
-                if( m_iterator.hasNext() )
-                {
-                    WikiPage  att = (WikiPage)m_iterator.next();
-
-                    WikiContext context = (WikiContext)m_wikiContext.clone();
-                    context.setPage( att );
-                    pageContext.setAttribute( WikiTagBase.ATTR_CONTEXT,
-                                              context,
-                                              PageContext.REQUEST_SCOPE );
-
-                    pageContext.setAttribute( getId(), att );
-                }
-                else
-                {
-                    return SKIP_BODY;
-                }
-            }
-            else
+            if( page != null && engine.pageExists( page ) )
             {
-                return SKIP_BODY;
+                return mgr.listAttachments( page );
             }
-
-            return EVAL_BODY_BUFFERED;
         }
         catch( ProviderException e )
         {
-            log.error("Provider failed while trying to iterator through history",e);
-            // FIXME: THrow something.
+            log.error( "Provider failed while trying to fetch attachments for page " + page.getName(), e );
         }
-
-        return SKIP_BODY;
+        return EMPTY_COLLECTION;
     }
 
     /**
-     *  {@inheritDoc}
+     * Returns the list of attachments that will be iterated over.
      */
-    @Override
-    public final int doAfterBody()
+    protected Collection<WikiPage> initItems()
     {
-        if( bodyContent != null )
-        {
-            try
-            {
-                JspWriter out = getPreviousOut();
-                out.print(bodyContent.getString());
-                bodyContent.clearBody();
-            }
-            catch( IOException e )
-            {
-                log.error("Unable to get inner tag text", e);
-                // FIXME: throw something?
-            }
-        }
-
-        if( m_iterator != null && m_iterator.hasNext() )
-        {
-            WikiPage att = (WikiPage) m_iterator.next();
-
-            WikiContext context = (WikiContext)m_wikiContext.clone();
-            context.setPage( att );
-            pageContext.setAttribute( WikiTagBase.ATTR_CONTEXT,
-                                      context,
-                                      PageContext.REQUEST_SCOPE );
-
-            pageContext.setAttribute( getId(), att );
-
-            return EVAL_BODY_BUFFERED;
-        }
-
-        return SKIP_BODY;
+        return getAttachments();
     }
 }

Modified: incubator/jspwiki/trunk/src/java/org/apache/wiki/tags/EditorIteratorTag.java
URL: http://svn.apache.org/viewvc/incubator/jspwiki/trunk/src/java/org/apache/wiki/tags/EditorIteratorTag.java?rev=777924&r1=777923&r2=777924&view=diff
==============================================================================
--- incubator/jspwiki/trunk/src/java/org/apache/wiki/tags/EditorIteratorTag.java (original)
+++ incubator/jspwiki/trunk/src/java/org/apache/wiki/tags/EditorIteratorTag.java Sat May 23 13:39:55 2009
@@ -23,45 +23,40 @@
 import java.util.ArrayList;
 import java.util.Collection;
 
+import org.apache.wiki.WikiContext;
 import org.apache.wiki.WikiEngine;
 import org.apache.wiki.action.WikiContextFactory;
-import org.apache.wiki.log.Logger;
-import org.apache.wiki.log.LoggerFactory;
 import org.apache.wiki.ui.Editor;
 import org.apache.wiki.ui.EditorManager;
 
-
 /**
- *  Iterates through editors.
- *
- *  @author Chuck Smith
- *  @since 2.4.12
+ * Iterator tag for editors.
+ * 
+ * @author Chuck Smith
+ * @since 2.4.12
  */
-
-public class EditorIteratorTag
-    extends IteratorTag
+public class EditorIteratorTag extends IteratorTag<Editor>
 {
-    private static final long serialVersionUID = 0L;
+    private static final long serialVersionUID = 1L;
 
-    static    Logger    log = LoggerFactory.getLogger( EditorIteratorTag.class );
-
-    public final int doStartTag()
+    /**
+     * Returns the default list of editors into the collection that will be iterated
+     * over, as returned by {@link EditorManager#getEditorList()}.
+     */
+    protected Collection<Editor> initItems()
     {
-        m_wikiContext = WikiContextFactory.findContext(pageContext);
-
-        WikiEngine engine = m_wikiContext.getEngine();
-        EditorManager mgr    = engine.getEditorManager();
-
+        // Retrieve the list of editors
+        WikiContext wikiContext = WikiContextFactory.findContext( pageContext );
+        WikiEngine engine = wikiContext.getEngine();
+        EditorManager mgr = engine.getEditorManager();
         String[] editorList = mgr.getEditorList();
 
+        // Create a new collection of Editors
         Collection<Editor> editors = new ArrayList<Editor>();
-
-        for ( int i = 0; i < editorList.length; i++ )
+        for( int i = 0; i < editorList.length; i++ )
         {
-            editors.add(new Editor(m_wikiContext, editorList[i]));
+            editors.add( new Editor( m_wikiContext, editorList[i] ) );
         }
-        setList( editors );
-
-        return super.doStartTag();
+        return editors;
     }
 }

Modified: incubator/jspwiki/trunk/src/java/org/apache/wiki/tags/HistoryIteratorTag.java
URL: http://svn.apache.org/viewvc/incubator/jspwiki/trunk/src/java/org/apache/wiki/tags/HistoryIteratorTag.java?rev=777924&r1=777923&r2=777924&view=diff
==============================================================================
--- incubator/jspwiki/trunk/src/java/org/apache/wiki/tags/HistoryIteratorTag.java (original)
+++ incubator/jspwiki/trunk/src/java/org/apache/wiki/tags/HistoryIteratorTag.java Sat May 23 13:39:55 2009
@@ -20,12 +20,10 @@
  */
 package org.apache.wiki.tags;
 
-import java.io.IOException;
+import java.util.ArrayList;
 import java.util.Collection;
-import javax.servlet.jsp.JspWriter;
-import javax.servlet.jsp.PageContext;
+import java.util.Collections;
 
-import org.apache.wiki.WikiContext;
 import org.apache.wiki.WikiEngine;
 import org.apache.wiki.api.WikiPage;
 import org.apache.wiki.content.PageNotFoundException;
@@ -33,110 +31,50 @@
 import org.apache.wiki.log.LoggerFactory;
 import org.apache.wiki.providers.ProviderException;
 
-
-
 /**
- *  Iterates through tags.
- *
- *  <P><B>Attributes</B></P>
- *  <UL>
- *    <LI>page - Page name to refer to.  Default is the current page.
- *  </UL>
- *
- *  @since 2.0
+ * <p>
+ * Iterator tag that loops through the historical versions of a WikiPage. In
+ * addition to the <code>start</code> and <code>maxItems</code> attributes,
+ * other attributes that can be set are:
+ * </p>
+ * <ul>
+ * <li><code>page</code> - the page name to use. The default is the one
+ * associated with the current WikiContext.</li>
+ * </ul>
+ * 
+ * @since 2.0
  */
-
-// FIXME: Too much in common with IteratorTag - REFACTOR
-public class HistoryIteratorTag
-    extends IteratorTag
+public class HistoryIteratorTag extends IteratorTag<WikiPage>
 {
-    private static final long serialVersionUID = 0L;
-    
-    static    Logger    log = LoggerFactory.getLogger( HistoryIteratorTag.class );
+    private static final long serialVersionUID = 1L;
 
-    public final int doStartTag()
-    {
-        m_wikiContext = (WikiContext) pageContext.getAttribute( WikiTagBase.ATTR_CONTEXT,
-                                                                PageContext.REQUEST_SCOPE );
-
-        WikiEngine engine = m_wikiContext.getEngine();
-        WikiPage   page;
+    private static final Collection<WikiPage> EMPTY_COLLECTION = Collections.unmodifiableCollection( new ArrayList<WikiPage>() );
 
-        page = m_wikiContext.getPage();
+    static Logger log = LoggerFactory.getLogger( HistoryIteratorTag.class );
 
+    /**
+     * Returns the historical versions of the current WikiPage.
+     */
+    @Override
+    protected Collection<WikiPage> initItems()
+    {
+        WikiPage page = m_wikiContext.getPage();
+        WikiEngine engine = m_wikiContext.getEngine();
         try
         {
-            if( page != null && engine.pageExists(page) )
+            if( page != null && engine.pageExists( page ) )
             {
-                Collection<WikiPage> versions;
-                try
-                {
-                    versions = engine.getVersionHistory( page.getName() );
-                }
-                catch( PageNotFoundException e )
-                {
-                    // There is no history
-                    return SKIP_BODY;
-                }
-
-                m_iterator = versions.iterator();
-
-                if( m_iterator.hasNext() )
-                {
-                    WikiContext context = (WikiContext)m_wikiContext.clone();
-                    context.setPage( (WikiPage)m_iterator.next() );
-                    pageContext.setAttribute( WikiTagBase.ATTR_CONTEXT,
-                                              context,
-                                              PageContext.REQUEST_SCOPE );
-                    pageContext.setAttribute( getId(),
-                                              context.getPage() );
-                }
-                else
-                {
-                    return SKIP_BODY;
-                }
+                return engine.getVersionHistory( page.getName() );
             }
-
-            return EVAL_BODY_BUFFERED;
         }
-        catch( ProviderException e )
+        catch( PageNotFoundException e )
         {
-            log.error("Provider failed while trying to iterator through history",e);
-            // FIXME: THrow something.
+            log.error( "Provider claims page " + page.getName() + " doesn't exists, right after it said it did. This is odd!", e );
         }
-
-        return SKIP_BODY;
-    }
-
-    public final int doAfterBody()
-    {
-        if( bodyContent != null )
-        {
-            try
-            {
-                JspWriter out = getPreviousOut();
-                out.print(bodyContent.getString());
-                bodyContent.clearBody();
-            }
-            catch( IOException e )
-            {
-                log.error("Unable to get inner tag text", e);
-                // FIXME: throw something?
-            }
-        }
-
-        if( m_iterator != null && m_iterator.hasNext() )
+        catch( ProviderException e )
         {
-            WikiContext context = (WikiContext)m_wikiContext.clone();
-            context.setPage( (WikiPage)m_iterator.next() );
-            pageContext.setAttribute( WikiTagBase.ATTR_CONTEXT,
-                                      context,
-                                      PageContext.REQUEST_SCOPE );
-            pageContext.setAttribute( getId(),
-                                      context.getPage() );
-            return EVAL_BODY_BUFFERED;
+            log.error( "Provider failed while trying to fetch history for page " + page.getName(), e );
         }
-
-        return SKIP_BODY;
+        return EMPTY_COLLECTION;
     }
 }

Modified: incubator/jspwiki/trunk/src/java/org/apache/wiki/tags/IteratorTag.java
URL: http://svn.apache.org/viewvc/incubator/jspwiki/trunk/src/java/org/apache/wiki/tags/IteratorTag.java?rev=777924&r1=777923&r2=777924&view=diff
==============================================================================
--- incubator/jspwiki/trunk/src/java/org/apache/wiki/tags/IteratorTag.java (original)
+++ incubator/jspwiki/trunk/src/java/org/apache/wiki/tags/IteratorTag.java Sat May 23 13:39:55 2009
@@ -21,13 +21,14 @@
 package org.apache.wiki.tags;
 
 import java.io.IOException;
+import java.util.ArrayList;
 import java.util.Arrays;
-import java.util.Iterator;
 import java.util.Collection;
+import java.util.Iterator;
+
 import javax.servlet.jsp.JspWriter;
 import javax.servlet.jsp.tagext.BodyTagSupport;
 import javax.servlet.jsp.tagext.TryCatchFinally;
-import javax.servlet.jsp.PageContext;
 
 import org.apache.wiki.WikiContext;
 import org.apache.wiki.action.WikiContextFactory;
@@ -35,191 +36,301 @@
 import org.apache.wiki.log.Logger;
 import org.apache.wiki.log.LoggerFactory;
 
-
-
 /**
- *  Iterates through tags.
- *
- *  <P><B>Attributes</B></P>
- *  <UL>
- *    <LI>list - a collection.
- *  </UL>
- *
- *  @since 2.0
+ * <p>
+ * Abstract base class for tags that iterate through collections.
+ * </p>
+ * <P>
+ * <B>Attributes</B>
+ * </P>
+ * <UL>
+ * <LI>list - a collection.
+ * </UL>
+ * 
+ * @since 2.0
  */
-public abstract class IteratorTag
-    extends BodyTagSupport
-    implements TryCatchFinally
+public abstract class IteratorTag<T> extends BodyTagSupport implements TryCatchFinally
 {
+    private static Logger log = LoggerFactory.getLogger( IteratorTag.class );
 
-    protected String      m_pageName;
-    protected Iterator<?>    m_iterator;
-    protected WikiContext m_wikiContext;
+    private Collection<T> m_items = null;
 
-    private static Logger log = LoggerFactory.getLogger( IteratorTag.class );
+    /**
+     * The WikiContext passed to this tag when initialized. It is stashed by
+     * {@link #doStartTag()} and restored by {@link #doFinally()}.
+     */
+    private WikiContext m_originalContext = null;
+
+    private   int         m_maxItems = Integer.MAX_VALUE;
+    
+    private   int         m_count = 0;
+
+    private   int         m_start = 0;
 
     /**
-     *  Sets the collection that is used to form the iteration.
-     *  
-     *  @param arg A Collection which will be iterated.
+     * Protected Iterator field associated by the collection set by
+     * {@link #setList(Collection)} or {@link #setList(Object[])}.
+     * <em>This variable should not be reassigned by subclasses.</em>
      */
-    public void setList( Collection<?> arg )
-    {
-        if( arg != null )
-            m_iterator = arg.iterator();
-    }
+    private Iterator<T> m_iterator = null;
 
     /**
-     *  Sets the collection list, but using an array.
-     *  @param arg An array of objects which will be iterated.
+     * Protected field that stores the current WikiContext.
+     * <em>This variable should not be reassigned by subclasses.</em>
+     */
+    protected WikiContext m_wikiContext = null;
+    
+    /**
+     * {@inheritDoc}
      */
-    public void setList( Object[] arg )
+    public final int doAfterBody()
     {
-        if( arg != null )
+        if( bodyContent != null )
+        {
+            try
+            {
+                JspWriter out = getPreviousOut();
+                out.print( bodyContent.getString() );
+                bodyContent.clearBody();
+            }
+            catch( IOException e )
+            {
+                log.error( "Unable to get inner tag text", e );
+                // FIXME: throw something?
+            }
+        }
+
+        if( m_iterator.hasNext() && m_count++ < m_maxItems )
         {
-            m_iterator = Arrays.asList(arg).iterator();
+            T item = m_iterator.next();
+            pageContext.setAttribute( getId(), item );
+            nextItem( item );
+            return EVAL_BODY_BUFFERED;
         }
+        return SKIP_BODY;
     }
     
     /**
-     *  Sets the iterator directly that is used to form the iteration.
+     * <p>
+     * Handles any exceptions thrown by the various body tag methods. Subclasses
+     * can override this method if they require specialized handling. By
+     * default, this method does nothing.
+     * </p>
+     * 
+     * @param t The Throwable that the tag threw
+     * @throws Throwable I have no idea why this would throw anything
      */
-    /*
-    public void setList( Iterator arg )
+    public final void doCatch( Throwable t ) throws Throwable
     {
-        m_iterator = arg;
     }
-    */
 
     /**
-     *  Clears the iterator away.  After calling this method doStartTag()
-     *  will always return SKIP_BODY
+     * {@inheritDoc}
      */
-    public void clearList()
+    public final int doEndTag()
     {
-        m_iterator = null;
+        return EVAL_PAGE;
     }
     
     /**
-     *  Override this method to reset your own iterator.
+     * <p>
+     * Cleans up tag state after the tag finishes executing. Subclasses can
+     * override this method to include any cleanup code they need. However,
+     * subclasses <em>must</em> call this superclass method in order for the
+     * tag to work as expected. The default implementation does nothing.
      */
-    public void resetIterator()
+    public final void doFinally()
     {
-        // No operation here
+        if ( !m_iterator.hasNext() )
+        {
+            // Return WikiContext back to the original.
+            WikiContextFactory.saveContext( pageContext.getRequest(), m_originalContext );
+            
+            // Null out everything else
+            m_maxItems = Integer.MAX_VALUE;
+            m_start = 0;
+            m_count = 0;
+            m_items = null;
+            m_iterator = null;
+            m_wikiContext = null;
+            m_originalContext = null;
+        }
     }
-    
+
     /**
-     *  {@inheritDoc}
-     */
-    public int doStartTag()
-    {
-        m_wikiContext = WikiContextFactory.findContext(pageContext);
+     * <p>
+     * Initialization method used by IteratorTag and its subclasses to
+     * initialize tag state, before the first body tag evaluation. Subclasses
+     * can override this method to do just about anything. This implementation
+     * does the following:
+     * </p>
+     * <ul>
+     * <li>sets the internal field {@link #m_wikiContext} to the value returned
+     * by {@link WikiContextFactory#findContext(javax.servlet.jsp.PageContext)}</li>
+     * <li>if {@link #setList(Collection)} or {@link #setList(Object[])} has
+     * not been called, sets the internally cached list of items to an empty
+     * collection of type <var>&lt;T&gt;</var></li>
+     * <li>calls {@link #resetIterator()}, which by default sets the internal
+     * field {@link #m_iterator} to the <code>m_item</code>'s Iterator</li>
+     * </ul>
+     * <p>
+     * Subclasses should generally call this method via
+     * <code>super.doStartTag()</code>, after executing their own
+     * initialization code, to ensure that the iterator tag's internal state
+     * initializes correctly. For subclasses that need to "pre-load" a default
+     * collection of items, all that is needed is to have the overridden method
+     * call {@link #setList(Collection) or {@link #setList(Object[])}, then
+     * call <code>super.doInitBody()</code>.
+     * </p>
+     * <p>
+     * Implementations should return
+     * {@link javax.servlet.jsp.tagext.Tag#EVAL_BODY_INCLUDE},
+     * {@link javax.servlet.jsp.tagext.Tag#SKIP_BODY} or
+     * {@link javax.servlet.jsp.tagext.BodyTag#EVAL_BODY_BUFFERED}. Any
+     * exceptions that are thrown can then be dealt with by
+     * {@link #doCatch(Throwable)} or {@link #doFinally()}.
+     * </p>
+     * The default implementation simply returns
+     * {@link javax.servlet.jsp.tagext.BodyTag#EVAL_BODY_BUFFERED} if
+     * <code>m_items</code> contains one or more values, or
+     * {@link javax.servlet.jsp.tagext.Tag#SKIP_BODY} if not.
+     * 
+     * @see javax.servlet.jsp.tagext.Tag#doStartTag()}
+     *      </p>
+     */
+    public final int doStartTag()
+    {
+        // If first time through, stash the original WikiContext
+        m_wikiContext = WikiContextFactory.findContext( pageContext );
+        if ( m_originalContext == null )
+        {
+            m_originalContext = m_wikiContext;
+            m_wikiContext = (WikiContext)m_wikiContext.clone();
+            WikiContextFactory.saveContext( pageContext.getRequest(), m_wikiContext );
+        }
         
+        // Initialize the items for the iterator
+        if ( m_items == null )
+        {
+            setList( initItems() );
+        }
         resetIterator();
-        
-        if( m_iterator == null ) return SKIP_BODY;
+        if( m_items == null || m_items.size() == 0 )
+        {
+            return SKIP_BODY;
+        }
 
-        if( m_iterator.hasNext() )
+        //  Skip the first few ones...
+        int skip = 0;
+        while( m_iterator.hasNext() && (skip++ < m_start) ) m_iterator.next();
+        
+        // Start with the first one after the skipped number
+        m_count = 0;
+        if( m_iterator.hasNext() && m_count++ < m_maxItems )
         {
-            buildContext();
+            T item = m_iterator.next();
+            pageContext.setAttribute( getId(), item );
+            nextItem( item );
         }
 
         return EVAL_BODY_BUFFERED;
     }
 
     /**
-     *  Arg, I hate globals.
+     * {@inheritDoc}
+     * calls
+     * {@link #resetIterator(), nulls out the internal iterator and wiki context
+     * references, and restores the WikiContext to its original state.     
      */
-    private void buildContext()
+    public void release()
     {
-        //
-        //  Build a clone of the current context
-        //
-        WikiContext context = (WikiContext)m_wikiContext.clone();
-        
-        Object o = m_iterator.next();
-        
-        if( o instanceof WikiPage )
-            context.setPage( (WikiPage)o );
-
-        //
-        //  Push it to the iterator stack, and set the id.
-        //
-        pageContext.setAttribute( WikiTagBase.ATTR_CONTEXT,
-                                  context,
-                                  PageContext.REQUEST_SCOPE );
-        pageContext.setAttribute( getId(),
-                                  o );
+        super.release();
     }
 
     /**
-     *  {@inheritDoc}
+     * Resets the iterator to the first item in the list set by
+     * {@link #setList(Collection)} or
+     * {@link #setList(Object[]). The default implementation sets the current record
+     * to the first one. Override this method to reset your own iterator.
      */
-    public int doEndTag()
+    public final void resetIterator()
     {
-        // Return back to the original.
-        pageContext.setAttribute( WikiTagBase.ATTR_CONTEXT,
-                                  m_wikiContext,
-                                  PageContext.REQUEST_SCOPE );
-
-        return EVAL_PAGE;
+//        m_iterator = m_items.iterator();
     }
 
     /**
-     *  {@inheritDoc}
+     * Sets the collection that is used to form the iteration.
+     * 
+     * @param items A Collection which will be iterated.
      */
-    public int doAfterBody()
+    public final void setList( Collection<T> items )
     {
-        if( bodyContent != null )
+        if( items != null )
         {
-            try
-            {
-                JspWriter out = getPreviousOut();
-                out.print(bodyContent.getString());
-                bodyContent.clearBody();
-            }
-            catch( IOException e )
-            {
-                log.error("Unable to get inner tag text", e);
-                // FIXME: throw something?
-            }
+            m_items = items;
+            m_iterator = items.iterator();
         }
-
-        if( m_iterator != null && m_iterator.hasNext() )
+    }
+    
+    /**
+     * Sets the collection list, but using an array.
+     * 
+     * @param items An array of objects which will be iterated.
+     */
+    public final void setList( T[] items )
+    {
+        if( items != null )
         {
-            buildContext();
-            return EVAL_BODY_BUFFERED;
+            m_items = Arrays.asList( items );
+            m_iterator = m_items.iterator();
         }
+    }
 
-        return SKIP_BODY;
+    /**
+     * Sets the maximum number of items the iterator should iterate over.
+     * @param maxItems the maximum number
+     */
+    public void setMaxItems( int maxItems )
+    {
+        m_maxItems = maxItems;
     }
-    
+
     /**
-     *  In case your tag throws an exception at any point, you can
-     *  override this method and implement a custom exception handler.
-     *  <p>
-     *  By default, this handler does nothing.
-     *  
-     *  @param arg0 The Throwable that the tag threw
-     *  
-     *  @throws Throwable I have no idea why this would throw anything
+     * Sets the start position for the iterator, starting with position 0.
+     * @param start the start position
      */
-    public void doCatch(Throwable arg0) throws Throwable
+    public void setStart( int start )
     {
+        m_start = start;
     }
 
     /**
-     *  Executed after the tag has been finished.  This is a great place
-     *  to put any cleanup code.  However you <b>must</b> call super.doFinally()
-     *  if you override this method, or else some of the things may not
-     *  work as expected.
+     * Initializes the list of items that will be iterated over. This default implementation
+     * returns an empty collection. Subclasses can override this method to provide
+     * a list of default items to iterate over.
+     * @return the collection of items
      */
-    public void doFinally()
+    protected Collection<T> initItems()
     {
-        resetIterator();
-        m_iterator = null;
-        m_pageName = null;
-        m_wikiContext = null;        
+        return new ArrayList<T>();
+    }
+
+    /**
+     * <p>Processes the next item in the iterator. This method is called by {@link #doStartTag()}
+     * if the tag iterates over one or more items. It is also called by {@link #doAfterBody()}
+     * following each iteration. Subclasses should override this class to perform custom
+     * actions on the item.</p>
+     * <p>The default implementation of this method checks to see if the item
+     * is a WikiPage, and if so, calls {@link WikiContext#setPage(WikiPage)} with it
+     * for the current WikiContext.</p>
+     * @param item the next item in the iteration to be processed
+     */
+    protected void nextItem( T item )
+    {
+        if( item instanceof WikiPage )
+        {
+            m_wikiContext.setPage( (WikiPage) item );
+        }
     }
 
 }

Modified: incubator/jspwiki/trunk/src/java/org/apache/wiki/tags/SearchResultIteratorTag.java
URL: http://svn.apache.org/viewvc/incubator/jspwiki/trunk/src/java/org/apache/wiki/tags/SearchResultIteratorTag.java?rev=777924&r1=777923&r2=777924&view=diff
==============================================================================
--- incubator/jspwiki/trunk/src/java/org/apache/wiki/tags/SearchResultIteratorTag.java (original)
+++ incubator/jspwiki/trunk/src/java/org/apache/wiki/tags/SearchResultIteratorTag.java Sat May 23 13:39:55 2009
@@ -20,131 +20,45 @@
  */
 package org.apache.wiki.tags;
 
-import java.io.IOException;
+import java.util.ArrayList;
 import java.util.Collection;
 
-import javax.servlet.jsp.JspWriter;
 import javax.servlet.jsp.PageContext;
 
-import org.apache.wiki.WikiContext;
-import org.apache.wiki.WikiEngine;
-import org.apache.wiki.log.Logger;
-import org.apache.wiki.log.LoggerFactory;
 import org.apache.wiki.search.SearchResult;
 
-
-
 /**
- *  Iterates through Search result results.
- *
- *  <P><B>Attributes</B></P>
- *  <UL>
- *    <LI>max = how many search results should be shown.
- *  </UL>
- *
- *  @since 2.0
+ * Iterator tag for the current search results, as identified by a
+ * request-scoped attribute set elsewhere; for example, by an ActionBean.
  */
-
-// FIXME: Shares MUCH too much in common with IteratorTag.  Must refactor.
-public class SearchResultIteratorTag
-    extends IteratorTag
+public class SearchResultIteratorTag extends IteratorTag<SearchResult>
 {
-    private static final long serialVersionUID = 0L;
-    
-    private   int         m_maxItems;
-    private   int         m_count = 0;
-    private   int         m_start = 0;
-    
-    static Logger log = LoggerFactory.getLogger(SearchResultIteratorTag.class);
-    
-    public void release()
-    {
-        super.release();
-        m_maxItems = m_count = 0;
-    }
-
-    public void setMaxItems( int arg )
-    {
-        m_maxItems = arg;
-    }
+    private static final long serialVersionUID = 1L;
 
-    public void setStart( int arg )
-    {
-        m_start = arg;
-    }
-    
-    @SuppressWarnings("unchecked")
-    public final int doStartTag()
-    {
-        //
-        //  Do lazy eval if the search results have not been set.
-        //
-        if( m_iterator == null )
+    /**
+     * \ Returns the list of SearchResults to iterate over.
+     */
+    @Override
+    @SuppressWarnings( "unchecked" )
+    protected Collection<SearchResult> initItems()
+    {
+        Collection<SearchResult> results = (Collection<SearchResult>) pageContext.getAttribute( "searchresults",
+                                                                                                PageContext.REQUEST_SCOPE );
+        if( results == null )
         {
-            Collection<SearchResult> searchresults = (Collection<SearchResult>) pageContext.getAttribute( "searchresults",
-                                                                              PageContext.REQUEST_SCOPE );
-            setList( searchresults );
-            
-            int skip = 0;
-            
-            //  Skip the first few ones...
-            m_iterator = searchresults.iterator();
-            while( m_iterator.hasNext() && (skip++ < m_start) ) m_iterator.next();
+            return new ArrayList<SearchResult>();
         }
-
-        m_count       = 0;
-        m_wikiContext = (WikiContext) pageContext.getAttribute( WikiTagBase.ATTR_CONTEXT,
-                                                                PageContext.REQUEST_SCOPE );
-
-        return nextResult();
+        return results;
     }
 
-    private int nextResult()
+    /**
+     * When the next iterated item is encountered, this method sets the current
+     * WikiContext's page property to the value of
+     * {@link SearchResult#getPage()}.
+     */
+    @Override
+    protected void nextItem( SearchResult item )
     {
-        if( m_iterator != null && m_iterator.hasNext() && m_count++ < m_maxItems )
-        {
-            SearchResult r = (SearchResult) m_iterator.next();
-            
-            // Create a wiki context for the result
-            WikiEngine engine = m_wikiContext.getEngine();
-            WikiContext context = engine.getWikiContextFactory().newViewContext( r.getPage() );
-            
-            // Stash it in the page context
-            pageContext.setAttribute( WikiTagBase.ATTR_CONTEXT,
-                                      context,
-                                      PageContext.REQUEST_SCOPE );
-            pageContext.setAttribute( getId(), r );
-
-            return EVAL_BODY_BUFFERED;
-        }
-
-        return SKIP_BODY;
-    }
-
-    public int doAfterBody()
-    {
-        if( bodyContent != null )
-        {
-            try
-            {
-                JspWriter out = getPreviousOut();
-                out.print(bodyContent.getString());
-                bodyContent.clearBody();
-            }
-            catch( IOException e )
-            {
-                log.error("Unable to get inner tag text", e);
-                // FIXME: throw something?
-            }
-        }
-
-        return nextResult();
-    }
-
-    public int doEndTag()
-    {
-        m_iterator = null;
-
-        return super.doEndTag();
+        m_wikiContext.setPage( item.getPage() );
     }
 }

Modified: incubator/jspwiki/trunk/src/java/org/apache/wiki/tags/WikiBodyTag.java
URL: http://svn.apache.org/viewvc/incubator/jspwiki/trunk/src/java/org/apache/wiki/tags/WikiBodyTag.java?rev=777924&r1=777923&r2=777924&view=diff
==============================================================================
--- incubator/jspwiki/trunk/src/java/org/apache/wiki/tags/WikiBodyTag.java (original)
+++ incubator/jspwiki/trunk/src/java/org/apache/wiki/tags/WikiBodyTag.java Sat May 23 13:39:55 2009
@@ -23,11 +23,11 @@
 import java.io.IOException;
 
 import javax.servlet.jsp.JspException;
-import javax.servlet.jsp.PageContext;
 import javax.servlet.jsp.tagext.BodyTagSupport;
 import javax.servlet.jsp.tagext.TryCatchFinally;
 
 import org.apache.wiki.WikiContext;
+import org.apache.wiki.action.WikiContextFactory;
 import org.apache.wiki.log.Logger;
 import org.apache.wiki.log.LoggerFactory;
 
@@ -49,14 +49,11 @@
     {
         try
         {
-            m_wikiContext = (WikiContext) pageContext.getAttribute( WikiTagBase.ATTR_CONTEXT,
-                                                                    PageContext.REQUEST_SCOPE );
-
+            m_wikiContext = WikiContextFactory.findContext( pageContext );
             if( m_wikiContext == null )
             {
                 throw new JspException("WikiContext may not be NULL - serious internal problem!");
             }
-
             return doWikiStartTag();
         }
         catch( Exception e )

Modified: incubator/jspwiki/trunk/src/java/org/apache/wiki/tags/WikiTagBase.java
URL: http://svn.apache.org/viewvc/incubator/jspwiki/trunk/src/java/org/apache/wiki/tags/WikiTagBase.java?rev=777924&r1=777923&r2=777924&view=diff
==============================================================================
--- incubator/jspwiki/trunk/src/java/org/apache/wiki/tags/WikiTagBase.java (original)
+++ incubator/jspwiki/trunk/src/java/org/apache/wiki/tags/WikiTagBase.java Sat May 23 13:39:55 2009
@@ -26,6 +26,7 @@
 
 import org.apache.wiki.*;
 import org.apache.wiki.action.WikiActionBean;
+import org.apache.wiki.action.WikiContextFactory;
 import org.apache.wiki.log.Logger;
 import org.apache.wiki.log.LoggerFactory;
 import org.apache.wiki.ui.stripes.WikiInterceptor;
@@ -36,11 +37,12 @@
 
 
 /**
- *  Base class for JSPWiki tags.  You do not necessarily have
- *  to derive from this class, since this does some initialization.
- *  <P>
- *  This tag is only useful if you're having an "empty" tag, with
- *  no body content.
+ *  <p>Base class for JSPWiki tags.  Tags need not necessarily
+ *  derive from this class, since this base class initializes certain
+ *  state properties that not all tag classes need.</p>
+ *  <p>The default method stubs defined in this class are only useful for
+ *  empty element tags, with no body content. Subclasses can override
+ *  any of these methods to provide customized functionality.</p>
  *
  *  @since 2.0
  */
@@ -48,6 +50,10 @@
     extends StripesTagSupport
     implements TryCatchFinally
 {
+    /**
+     * @deprecated use {@link org.apache.wiki.action.WikiContextFactory#saveContext(javax.servlet.ServletRequest, WikiContext)}
+     * and {@link org.apache.wiki.action.WikiContextFactory#findContext(PageContext)} to set the WikiContext instead
+     */
     public static final String ATTR_CONTEXT = "wikiContext";
 
     static    Logger    log = LoggerFactory.getLogger( WikiTagBase.class );
@@ -59,41 +65,52 @@
     private String m_id;
 
     /**
-     *   This method calls the parent setPageContext() but it also
-     *   provides a way for a tag to initialize itself before
-     *   any of the setXXX() methods are called.
+     * {@inheritDoc}
+     * <p>This implementation calls the superclass method setPageContext(),
+     * and also calls {{@link #initTag()} so that the tags (or subclasses) can
+     * initialize <code>set<var>XXX</var>()</code> property methods are
+     * called.</p>
      */
     public void setPageContext(PageContext arg0)
     {
         super.setPageContext(arg0);
-        
         initTag();
     }
 
     /**
-     *  This method is called when the tag is encountered within a new request,
-     *  but before the setXXX() methods are called. 
-     *  The default implementation does nothing.
+     *  Initialization method that resets the tag to a known state.
+     *  This method is called after the tag is encountered within a new request,
+     *  but before the <code>set<var>XXX</var>()</code> methods are called. 
+     *  The default implementation nulls out the internal
+     * references to the WikiActionBean, WikiContext, and tag ID.
      *  @since 2.3.92
      */
     public void initTag()
     {
+        m_wikiActionBean = null;
         m_wikiContext = null;
         m_id = null;
         return;
     }
     
     /**
-     * Initializes the tag, and sets an internal reference to the current WikiActionBean
-     * by delegating to
-     * {@link org.apache.wiki.ui.stripes.WikiInterceptor#findActionBean(PageContext)}.
-     * (That method retrieves the WikiActionBean from page scope.).
-     * If the WikiActionBean is a WikiContext, a specific reference to the WikiContext
-     * will be set also. Both of these available as protected fields {@link #m_wikiActionBean} and
-     * {@link #m_wikiContext}, respectively. It is considered an error condition if the 
-     * WikiActionBean cannot be retrieved from the PageContext.
-     * It's also an error condition if the WikiActionBean is actually a WikiContext, and it
-     * returns a <code>null</code> WikiPage.
+     * <p>Superclass initializer that sets common state attributes for WikiTagBase
+     * subclasses. Subclasses should generally override {@link #doWikiStartTag()}, rather
+     * than this method, to initialize themselves.</p>
+     * <p>This method performs the following initialization steps. First, it sets an
+     * internal reference to the current WikiActionBean obtained by calling
+     * {@link org.apache.wiki.ui.stripes.WikiInterceptor#findActionBean(PageContext)},
+     * which retrieves the WikiActionBean from page scope.
+     * Then, the object returned by {@link WikiActionBean#getContext()} will be 
+     * set as the page's WikiContext. Both of these objects are made available to
+     * subclasses as protected fields {@link #m_wikiActionBean} and
+     * {@link #m_wikiContext}, respectively.</p>
+     * <p> It is considered an error condition if the 
+     * WikiActionBean cannot be retrieved from the PageContext. This can happen if
+     * WikiTagBase (or a subclass tag) is used in a JSP that doesn't set or use an
+     * ActionBean. For this reason, JSPs that use WikiTagBase-subclassed tags should
+     * always contain a &lt;stripes:useActionBean&gt; tag at the top of the page to ensure
+     * that the correct ActionBean is set.</p>
      */
     public int doStartTag()
         throws JspException
@@ -102,16 +119,13 @@
         {
             // Retrieve the ActionBean injected by WikiInterceptor
             m_wikiActionBean = WikiInterceptor.findActionBean( this.getPageContext() );
-            
-            // It's really bad news if the WikiActionBean wasn't injected (or saved as a variable!)
             if ( m_wikiActionBean == null )
             {
                 throw new JspException( "Can't find WikiActionBean in page context! (tag=" + this.getClass() + ")" );
             }
 
-            // The WikiContext is the ActionBean's ActionBeanContext
-            m_wikiContext = m_wikiActionBean.getContext();
-
+            // Retrieve the WikiContext -- always WikiActionBean.getContext() unless IteratorTag changed it
+            m_wikiContext = WikiContextFactory.findContext( pageContext );
             if( m_wikiContext == null )
             {
                 throw new JspException("WikiContext may not be NULL - serious internal problem!");
@@ -127,8 +141,15 @@
     }
 
     /**
-     *  This method is allowed to do pretty much whatever he wants.
-     *  We then catch all mistakes.
+     *  Initialization method used by WikiTagBase subclasses to initialize themselves.
+     *  Subclasses can override this method to do just about anything. Implementations
+     *  should return {@link javax.servlet.jsp.tagext.Tag#EVAL_BODY_INCLUDE},
+     *  or {@link javax.servlet.jsp.tagext.Tag#SKIP_BODY}. If the subclass implements
+     *  {@link javax.servlet.jsp.tagext.BodyTag}, it may also return
+     *  {@link javax.servlet.jsp.tagext.BodyTag#EVAL_BODY_BUFFERED}.
+     *  Any exceptions that are thrown can then be dealt with by
+     *  {@link #doCatch(Throwable)} or {@link #doFinally()}.
+     *  @see javax.servlet.jsp.tagext.Tag#doStartTag()}
      */
     public abstract int doWikiStartTag() throws Exception;
 
@@ -138,26 +159,46 @@
         return EVAL_PAGE;
     }
     
+    /**
+     * {@inheritDoc}
+     */
     public int doAfterBody() throws JspException 
     {
         return SKIP_BODY;
     }
     
+    /**
+     * {@inheritDoc}
+     */
     public String getId()
     {
         return m_id;
     }
 
+    /**
+     * {@inheritDoc}. The default implementation does nothing.
+     */
     public void doCatch(Throwable arg0) throws Throwable
     {
     }
 
+    /**
+     * {@inheritDoc}
+     * <p>The default implementation nulls out the internal
+     * references to the WikiActionBean, WikiContext, and tag ID.</p>
+     */
     public void doFinally()
     {
+        m_wikiActionBean = null;
         m_wikiContext = null;
         m_id = null;
     }
 
+    /**
+     * {@inheritDoc}
+     * <p>The default implementation sanitizes the tag ID before setting
+     * it by escaping potentially dangerous characters.</p>
+     */
     public void setId(String id)
     {
 		m_id = ( TextUtil.replaceEntities( id ) );

Modified: incubator/jspwiki/trunk/src/java/org/apache/wiki/ui/stripes/WikiInterceptor.java
URL: http://svn.apache.org/viewvc/incubator/jspwiki/trunk/src/java/org/apache/wiki/ui/stripes/WikiInterceptor.java?rev=777924&r1=777923&r2=777924&view=diff
==============================================================================
--- incubator/jspwiki/trunk/src/java/org/apache/wiki/ui/stripes/WikiInterceptor.java (original)
+++ incubator/jspwiki/trunk/src/java/org/apache/wiki/ui/stripes/WikiInterceptor.java Sat May 23 13:39:55 2009
@@ -205,6 +205,13 @@
             WikiEngine engine = actionBeanContext.getEngine();
             WikiSession wikiSession = SessionMonitor.getInstance( engine ).find( request.getSession() );
             actionBeanContext.setWikiSession( wikiSession );
+            
+            // Stash WikiEngine as a request attribute (can be
+            // used later as ${wikiEngine} in EL markup)
+            request.setAttribute( WikiContextFactory.ATTR_WIKIENGINE, engine );
+
+            // Stash the WikiSession as a request attribute
+            request.setAttribute( WikiContextFactory.ATTR_WIKISESSION, wikiSession );
         }
 
         // Stash the ActionBean as request attribute, if not saved yet
@@ -213,7 +220,7 @@
             request.setAttribute( ATTR_ACTIONBEAN, actionBean );
         }
 
-        // Stash the WikiContext, WikiEngine
+        // Stash the WikiContext
         WikiContextFactory.saveContext( request, actionBean.getContext() );
 
         if( log.isDebugEnabled() )



Mime
View raw message