You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jspwiki.apache.org by aj...@apache.org on 2008/02/23 20:31:45 UTC

svn commit: r630514 - /incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/src/com/ecyrd/jspwiki/ui/

Author: ajaquith
Date: Sat Feb 23 11:31:42 2008
New Revision: 630514

URL: http://svn.apache.org/viewvc?rev=630514&view=rev
Log:
Initial Stripes component commit.

Added:
    incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/src/com/ecyrd/jspwiki/ui/GroupTypeConverter.java
    incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/src/com/ecyrd/jspwiki/ui/PrincipalTypeConverter.java
    incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/src/com/ecyrd/jspwiki/ui/WikiExceptionHandler.java
    incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/src/com/ecyrd/jspwiki/ui/WikiInterceptor.java
    incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/src/com/ecyrd/jspwiki/ui/WikiPageTypeConverter.java
    incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/src/com/ecyrd/jspwiki/ui/WikiRuntimeConfiguration.java
    incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/src/com/ecyrd/jspwiki/ui/WikiTypeConverterFactory.java
Modified:
    incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/src/com/ecyrd/jspwiki/ui/EditorManager.java
    incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/src/com/ecyrd/jspwiki/ui/TemplateManager.java
    incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/src/com/ecyrd/jspwiki/ui/WikiJSPFilter.java
    incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/src/com/ecyrd/jspwiki/ui/WikiServletFilter.java

Modified: incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/src/com/ecyrd/jspwiki/ui/EditorManager.java
URL: http://svn.apache.org/viewvc/incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/src/com/ecyrd/jspwiki/ui/EditorManager.java?rev=630514&r1=630513&r2=630514&view=diff
==============================================================================
--- incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/src/com/ecyrd/jspwiki/ui/EditorManager.java (original)
+++ incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/src/com/ecyrd/jspwiki/ui/EditorManager.java Sat Feb 23 11:31:42 2008
@@ -34,6 +34,7 @@
 import com.ecyrd.jspwiki.NoSuchVariableException;
 import com.ecyrd.jspwiki.WikiContext;
 import com.ecyrd.jspwiki.WikiEngine;
+import com.ecyrd.jspwiki.action.PreviewActionBean;
 import com.ecyrd.jspwiki.modules.ModuleManager;
 import com.ecyrd.jspwiki.modules.WikiModuleInfo;
 import com.ecyrd.jspwiki.plugin.PluginManager;
@@ -191,7 +192,7 @@
      */
     public String getEditorName( WikiContext context )
     {
-        if( context.getRequestContext().equals(WikiContext.PREVIEW) )
+        if( context instanceof PreviewActionBean )
             return EDITOR_PREVIEW;
 
         String editor = null;

Added: incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/src/com/ecyrd/jspwiki/ui/GroupTypeConverter.java
URL: http://svn.apache.org/viewvc/incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/src/com/ecyrd/jspwiki/ui/GroupTypeConverter.java?rev=630514&view=auto
==============================================================================
--- incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/src/com/ecyrd/jspwiki/ui/GroupTypeConverter.java (added)
+++ incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/src/com/ecyrd/jspwiki/ui/GroupTypeConverter.java Sat Feb 23 11:31:42 2008
@@ -0,0 +1,83 @@
+/* Copyright 2005-2006 Tim Fennell
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.ecyrd.jspwiki.ui;
+
+import java.util.Collection;
+import java.util.Locale;
+
+import net.sourceforge.stripes.controller.StripesFilter;
+import net.sourceforge.stripes.validation.LocalizableError;
+import net.sourceforge.stripes.validation.TypeConverter;
+import net.sourceforge.stripes.validation.ValidationError;
+
+import com.ecyrd.jspwiki.WikiEngine;
+import com.ecyrd.jspwiki.auth.NoSuchPrincipalException;
+import com.ecyrd.jspwiki.auth.authorize.Group;
+import com.ecyrd.jspwiki.auth.authorize.GroupManager;
+
+/**
+ * Stripes type converter that converts a Group name, expressed as a String,
+ * into an {@link com.ecyrd.jspwiki.auth.authorize.Group} object. This converter
+ * is looked up and returned by {@link WikiTypeConverterFactory} for HTTP
+ * request parameters that need to be bound to ActionBean properties of type
+ * Group. Stripes executes this TypeConverter during the
+ * {@link net.sourceforge.stripes.controller.LifecycleStage#BindingAndValidation}
+ * stage of request processing.
+ * 
+ * @author Andrew Jaquith
+ */
+public class GroupTypeConverter implements TypeConverter<Group>
+{
+    /**
+     * Converts a named wiki group into a valid
+     * {@link com.ecyrd.jspwiki.auth.authorize.Group} object by retrieving it
+     * via the Wiki{@link com.ecyrd.jspwiki.auth.authorize.GroupManager}. If
+     * the group cannot be found (perhaps because it does not exist), this
+     * method will add a validation error to the supplied Collection of errors.
+     * The error will be of type
+     * {@link net.sourceforge.stripes.validation.LocalizableError} and will have
+     * a message key of <code>pageNotFound</code> and a single parameter
+     * (equal to the value passed for <code>groupName</code>).
+     * 
+     * @param groupName
+     *            the name of the WikiPage to retrieve
+     * @param targetType
+     *            the type to return, which will always be of type
+     *            {@link com.ecyrd.jspwiki.auth.authorize.Group}
+     * @param errors
+     *            the current Collection of validation errors for this field
+     * @return the resolved Group
+     */
+    public Group convert(String groupName, Class<? extends Group> targetType, Collection<ValidationError> errors)
+    {
+        WikiRuntimeConfiguration config = (WikiRuntimeConfiguration)StripesFilter.getConfiguration();
+        WikiEngine engine = config.getEngine();
+        GroupManager mgr = engine.getGroupManager();
+        Group group = null;
+        try
+        {
+            group = mgr.getGroup(groupName);
+        }
+        catch (NoSuchPrincipalException e)
+        {
+            errors.add(new LocalizableError("groupNotFound", groupName));
+        }
+        return group;
+    }
+
+    public void setLocale(Locale locale)
+    {
+    };
+}

Added: incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/src/com/ecyrd/jspwiki/ui/PrincipalTypeConverter.java
URL: http://svn.apache.org/viewvc/incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/src/com/ecyrd/jspwiki/ui/PrincipalTypeConverter.java?rev=630514&view=auto
==============================================================================
--- incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/src/com/ecyrd/jspwiki/ui/PrincipalTypeConverter.java (added)
+++ incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/src/com/ecyrd/jspwiki/ui/PrincipalTypeConverter.java Sat Feb 23 11:31:42 2008
@@ -0,0 +1,62 @@
+/* Copyright 2005-2006 Tim Fennell
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.ecyrd.jspwiki.ui;
+
+import java.security.Principal;
+import java.util.Collection;
+import java.util.Locale;
+
+import net.sourceforge.stripes.validation.TypeConverter;
+import net.sourceforge.stripes.validation.ValidationError;
+
+import com.ecyrd.jspwiki.auth.WikiPrincipal;
+
+/**
+ * Stripes type converter that converts a Principal name, expressed as a String, into an
+ * {@link com.ecyrd.jspwiki.auth.WikiPrincipal} object. This converter is looked up
+ * and returned by {@link WikiTypeConverterFactory} for HTTP request parameters
+ * that need to be bound to ActionBean properties of type Principal. Stripes
+ * executes this TypeConverter during the
+ * {@link net.sourceforge.stripes.controller.LifecycleStage#BindingAndValidation}
+ * stage of request processing.
+ * 
+ * @author Andrew Jaquith
+ */
+public class PrincipalTypeConverter implements TypeConverter<Principal>
+{
+
+    /**
+     * Converts a named user, passed as a String, into a valid
+     * {@link com.ecyrd.jspwiki.auth.WikiPrincipal} object. This method will not
+     * ever return errors.
+     * 
+     * @param principalName
+     *            the name of the Principal to create
+     * @param targetType
+     *            the type to return, which will always be of type
+     *            {@link java.security.Principal}
+     * @param errors
+     *            the current Collection of validation errors for this field
+     * @return the
+     */
+    public Principal convert(String principalName, Class<? extends Principal> targetType, Collection<ValidationError> errors)
+    {
+        return new WikiPrincipal(principalName);
+    }
+
+    public void setLocale(Locale locale)
+    {
+    };
+}

Modified: incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/src/com/ecyrd/jspwiki/ui/TemplateManager.java
URL: http://svn.apache.org/viewvc/incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/src/com/ecyrd/jspwiki/ui/TemplateManager.java?rev=630514&r1=630513&r2=630514&view=diff
==============================================================================
--- incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/src/com/ecyrd/jspwiki/ui/TemplateManager.java (original)
+++ incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/src/com/ecyrd/jspwiki/ui/TemplateManager.java Sat Feb 23 11:31:42 2008
@@ -33,6 +33,7 @@
 import com.ecyrd.jspwiki.InternalWikiException;
 import com.ecyrd.jspwiki.WikiContext;
 import com.ecyrd.jspwiki.WikiEngine;
+import com.ecyrd.jspwiki.action.WikiActionBean;
 import com.ecyrd.jspwiki.modules.ModuleManager;
 
 /**
@@ -415,11 +416,11 @@
      *  @param type the marker
      *  @return the generated marker comment
      */
-    public static String getMarker(WikiContext context, String type )
+    public static String getMarker(WikiActionBean actionBean, String type )
     {
         if( type.equals(RESOURCE_JSLOCALIZEDSTRINGS) )
         {
-            return getJSLocalizedStrings( context );
+            return getJSLocalizedStrings( actionBean );
         }
         else if( type.equals(RESOURCE_JSFUNCTION) )
         {
@@ -437,13 +438,13 @@
      *  @author Dirk Frederickx
      *  @since 2.5.108
      */
-    private static String getJSLocalizedStrings( WikiContext context )
+    private static String getJSLocalizedStrings( WikiActionBean actionBean )
     {
         StringBuffer sb = new StringBuffer();
 
         sb.append( "var LocalizedStrings = {\n");
 
-        ResourceBundle rb = context.getBundle("templates.default");
+        ResourceBundle rb = actionBean.getBundle("templates.default");
 
         boolean first = true;
 
@@ -494,9 +495,9 @@
      *  @param type What kind of a request should be added?
      *  @param resource The resource to add.
      */
-    public static void addResourceRequest( WikiContext ctx, String type, String resource )
+    public static void addResourceRequest( WikiActionBean actionBean, String type, String resource )
     {
-        HashMap resourcemap = (HashMap) ctx.getVariable( RESOURCE_INCLUDES );
+        HashMap resourcemap = (HashMap) actionBean.getVariable( RESOURCE_INCLUDES );
 
         if( resourcemap == null )
         {
@@ -541,7 +542,7 @@
         log.debug("Request to add a resource: "+resourceString);
 
         resourcemap.put( type, resources );
-        ctx.setVariable( RESOURCE_INCLUDES, resourcemap );
+        actionBean.setVariable( RESOURCE_INCLUDES, resourcemap );
     }
 
     /**
@@ -553,9 +554,9 @@
      *  @return a String array for the resource requests
      */
 
-    public static String[] getResourceRequests( WikiContext ctx, String type )
+    public static String[] getResourceRequests( WikiActionBean actionBean, String type )
     {
-        HashMap hm = (HashMap) ctx.getVariable( RESOURCE_INCLUDES );
+        HashMap hm = (HashMap) actionBean.getVariable( RESOURCE_INCLUDES );
 
         if( hm == null ) return new String[0];
 
@@ -574,13 +575,13 @@
      * @param ctx the wiki context
      * @return the array of types requested
      */
-    public static String[] getResourceTypes( WikiContext ctx )
+    public static String[] getResourceTypes( WikiActionBean actionBean )
     {
         String[] res = new String[0];
 
-        if( ctx != null )
+        if( actionBean != null )
         {
-            HashMap hm = (HashMap) ctx.getVariable( RESOURCE_INCLUDES );
+            HashMap hm = (HashMap) actionBean.getVariable( RESOURCE_INCLUDES );
 
             if( hm != null )
             {

Added: incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/src/com/ecyrd/jspwiki/ui/WikiExceptionHandler.java
URL: http://svn.apache.org/viewvc/incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/src/com/ecyrd/jspwiki/ui/WikiExceptionHandler.java?rev=630514&view=auto
==============================================================================
--- incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/src/com/ecyrd/jspwiki/ui/WikiExceptionHandler.java (added)
+++ incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/src/com/ecyrd/jspwiki/ui/WikiExceptionHandler.java Sat Feb 23 11:31:42 2008
@@ -0,0 +1,18 @@
+package com.ecyrd.jspwiki.ui;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import net.sourceforge.stripes.action.Resolution;
+import net.sourceforge.stripes.exception.AutoExceptionHandler;
+
+public class WikiExceptionHandler implements AutoExceptionHandler
+{
+
+    public Resolution handle(Throwable exception, HttpServletRequest req, HttpServletResponse res)
+    {
+        exception.printStackTrace();
+        return null;
+    }
+    
+}

Added: incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/src/com/ecyrd/jspwiki/ui/WikiInterceptor.java
URL: http://svn.apache.org/viewvc/incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/src/com/ecyrd/jspwiki/ui/WikiInterceptor.java?rev=630514&view=auto
==============================================================================
--- incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/src/com/ecyrd/jspwiki/ui/WikiInterceptor.java (added)
+++ incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/src/com/ecyrd/jspwiki/ui/WikiInterceptor.java Sat Feb 23 11:31:42 2008
@@ -0,0 +1,272 @@
+package com.ecyrd.jspwiki.ui;
+
+import java.lang.reflect.Method;
+import java.security.Permission;
+import java.util.Map;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.jsp.PageContext;
+
+import net.sourceforge.stripes.action.RedirectResolution;
+import net.sourceforge.stripes.action.Resolution;
+import net.sourceforge.stripes.controller.*;
+
+import org.apache.log4j.Logger;
+
+import com.ecyrd.jspwiki.WikiEngine;
+import com.ecyrd.jspwiki.WikiSession;
+import com.ecyrd.jspwiki.action.*;
+import com.ecyrd.jspwiki.auth.AuthorizationManager;
+import com.ecyrd.jspwiki.auth.SessionMonitor;
+
+/**
+ * <p>
+ * Stripes {@link net.sourceforge.stripes.controller.Interceptor} that
+ * instantiates the correct WikiContext associated with JSPs, checks for access,
+ * and redirects users if necessary. The interceptor executes during two stages:
+ * after the second lifecycle stage, <em>aka</em>
+ * {@link net.sourceforge.stripes.controller.LifecycleStage#HandlerResolution},
+ * and around (before and after) the third stage,
+ * {@link net.sourceforge.stripes.controller.LifecycleStage#BindingAndValidation}.
+ * </p>
+ * <p>
+ * WikiInterceptor assumes primary responsibility for making JSPWiki objects
+ * available to JSPs as variables. In particular, when WikiInterceptor fires
+ * during the binding and validation stage, sets the following PageContext
+ * attributes, all in {@link PageContext#REQUEST_SCOPE}:
+ * </p>
+ * <ul>
+ * <li><code>wikiEngine</code> - the {@link com.ecyrd.jspwiki.WikiEngine}</li>
+ * <li><code>wikiSession</code> - the user's
+ * {@link com.ecyrd.jspwiki.WikiSession}</li>
+ * <li><code>wikiActionBean</code> - the
+ * {@link com.ecyrd.jspwiki.action.WikiActionBean} injected by Stripes</li>
+ * <li><code>wikiPage</code> - the {@link com.ecyrd.jspwiki.WikiPage}
+ * associated with the WikiActionBean, or the "front page" if the WikiActionBean
+ * is not a WikiContext</li>
+ * </ul>
+ * <p>
+ * After the intercept method fires, calling classes can obtain the saved
+ * WikiActionBean by calling {@link WikiActionBeanFactory#findActionBean(PageContext)}. This is,
+ * indeed, the recommended method for JSP scriptlet code.
+ * </p>
+ * <p>
+ * Because these objects are saved as attributes, they are available to JSPs as
+ * the Expression Language variables <code>${wikiEngine}</code>,
+ * <code>${wikiSession}</code>, <code>${wikiActionBean}</code> and
+ * <code>${wikiPage}</code>.
+ * </p>
+ * 
+ * @author Andrew Jaquith
+ */
+@Intercepts( { LifecycleStage.HandlerResolution, LifecycleStage.BindingAndValidation })
+public class WikiInterceptor implements Interceptor
+{
+    /**
+     * The PageContext attribute name of the WikiActionBean stored by
+     * WikiInterceptor.
+     */
+    public static final String ATTR_ACTIONBEAN = "wikiActionBean";
+
+    /** The PageContext attribute name of the WikiPage stored by WikiInterceptor. */
+    public static final String ATTR_WIKIPAGE = "wikiPage";
+
+    /**
+     * The PageContext attribute name of the WikiEngine stored by
+     * WikiInterceptor.
+     */
+    public static final String ATTR_WIKIENGINE = "wikiEngine";
+
+    /**
+     * The PageContext attribute name of the WikiSession stored by
+     * WikiInterceptor.
+     */
+    public static final String ATTR_WIKISESSION = "wikiSession";
+
+    private static final Logger log = Logger.getLogger(WikiInterceptor.class);
+
+    /**
+     * Facade method that forwards execution to
+     * {@link #interceptHandlerResolution(ExecutionContext)} or
+     * {@link #interceptBindingAndValidation(ExecutionContext)}, depending on
+     * the Stripes {@link net.sourceforge.stripes.controller.LifecycleStage}.
+     * 
+     * @param context
+     *            the current Stripes execution context
+     * @return a Resolution if the delgate intercept method returns one;
+     *         otherwise, <code>null</code>
+     */
+    public Resolution intercept(ExecutionContext context) throws Exception
+    {
+        switch (context.getLifecycleStage())
+        {
+            case HandlerResolution: {
+                return interceptHandlerResolution(context);
+            }
+            case BindingAndValidation: {
+                return interceptBindingAndValidation(context);
+            }
+            default:
+                return null;
+        }
+    }
+
+    /**
+     * <p>
+     * Intercepts the
+     * {@link net.sourceforge.stripes.controller.LifecycleStage#BindingAndValidation}
+     * lifecycle stage and checks for proper access to the current ActionBean
+     * and target event. The access-checking logic runs after after the rest of
+     * the BindingAndValidation processing logic does, after which point Stripes
+     * has already discovered the correct ActionBean, and bound and validated
+     * its request parameters.
+     * </p>
+     * <p>
+     * To determine if the user is allowed to access the target event method,
+     * the method is examined to see if contains a
+     * {@link com.ecyrd.jspwiki.action.EventPermission}) annotation that
+     * specifies the required {@link java.security.Permission}. If the user
+     * does not possess the Permission -- that is,
+     * {@link com.ecyrd.jspwiki.auth.AuthorizationManager#checkPermission(WikiSession, Permission)}
+     * returns <code>false</code> -- this method returns a RedirectResolution
+     * to the login page, with all current parameters appended.
+     * </p>
+     * <p>
+     * If access is allowed, this method injects the WikiEngine, WikiSession,
+     * resolved WikiActionBean and WikiPage as request-scoped PageContext
+     * attributes, and returns a <code>null</code>. After the objects are
+     * injected, downstream classes like WikiTagBase can use them. The attribute
+     * can also be accessed as variables using the JSP Expression Language
+     * (example: <code>${wikiPage}</code>).
+     * 
+     * @param context
+     *            the current execution context
+     * @return a Resolution if the
+     *         {@link net.sourceforge.stripes.controller.LifecycleStage#HandlerResolution}
+     *         lifecycle stage's normal execution returns one; <code>null</code>
+     *         otherwise
+     * @throws Exception
+     *             if the underlying lifcycle stage's execution throws an
+     *             Exception
+     */
+    protected Resolution interceptBindingAndValidation(ExecutionContext context) throws Exception
+    {
+        // Did the handler resolution stage return a Resolution? If so, bail.
+        Resolution r = context.proceed();
+        if (r != null)
+        {
+            return r;
+        }
+
+        // Get the resolved ActionBean and event handler method
+        WikiActionBean actionBean = (WikiActionBean) context.getActionBean();
+        WikiActionBeanContext beanContext = actionBean.getContext();
+        Method handler = context.getHandler();
+
+        // Does the event handler have a required permission?
+        boolean allowed = true;
+        EventPermissionInfo permInfo = beanContext.getPermissionInfo(handler);
+        if (permInfo != null)
+        {
+            Permission requiredPermission = permInfo.getPermission(actionBean);
+            if (requiredPermission != null)
+            {
+                WikiEngine engine = actionBean.getEngine();
+                AuthorizationManager mgr = engine.getAuthorizationManager();
+                WikiSession wikiSession = actionBean.getWikiSession();
+                allowed = mgr.checkPermission(wikiSession, requiredPermission);
+            }
+        }
+
+        // If not allowed, redirect to login page with all parameters intact;
+        // otherwise proceed
+        if (!allowed)
+        {
+            r = new RedirectResolution(LoginActionBean.class);
+            ((RedirectResolution) r).includeRequestParameters(true);
+            if (log.isDebugEnabled())
+            {
+                log.debug("WikiInterceptor rejected access to ActionBean: " + actionBean + ", method " + handler.getName());
+            }
+            return r;
+        }
+
+        if (log.isDebugEnabled())
+        {
+            log.debug("WikiInterceptor resolved ActionBean: " + actionBean);
+        }
+
+        // If not already set, inject WikiEngine as a request attribute (can be
+        // used later as ${wikiEngine} in EL markup)
+        WikiEngine engine = beanContext.getWikiEngine();
+        HttpServletRequest httpRequest = beanContext.getRequest();
+        httpRequest.setAttribute(ATTR_WIKIENGINE, engine);
+
+        // If not already set, Inject the WikiSession as a request attribute
+        WikiSession wikiSession = SessionMonitor.getInstance(engine).find(httpRequest.getSession());
+        httpRequest.setAttribute(ATTR_WIKISESSION, wikiSession);
+
+        // Stash the WikiActionBean and WikiPage in the PageContext
+        // Note: it probably seems a bit tricky that we're grabbing the
+        // PageContext from Stripes. We happen
+        // to know, thanks to the glories of open source code, that Stripes
+        // calls DispatcherHelper's
+        // setPageContext() method immediately before executing the
+        // BindingAndValidation stage,
+        // in *both* the <stripes:useActionBean> case and the StripesFilter
+        // case.
+        // So, the PageContext safe to grab, and boy are we glad that we can!
+        PageContext pageContext = DispatcherHelper.getPageContext();
+        if (pageContext != null)
+        {
+            // Save ActionBean to the current context
+            WikiActionBeanFactory.saveActionBean(pageContext, actionBean);
+        }
+
+        return null;
+    }
+
+    /**
+     * Intercepts the
+     * {@link net.sourceforge.stripes.controller.LifecycleStage#HandlerResolution}
+     * lifecycle stage and injects
+     * {@link com.ecyrd.jspwiki.action.EventPermissionInfo} objects into the
+     * WikiActionBeanContext if indicated by
+     * {@link com.ecyrd.jspwiki.action.EventPermission} annotations on the
+     * current ActionBean.
+     * 
+     * @param context
+     *            the current execution context
+     * @return a Resolution if the
+     *         {@link net.sourceforge.stripes.controller.LifecycleStage#HandlerResolution}
+     *         lifecycle stage's normal execution returns one; <code>null</code>
+     *         otherwise
+     * @throws Exception
+     *             if the underlying lifcycle stage's execution throws an
+     *             Exception
+     */
+    protected Resolution interceptHandlerResolution(ExecutionContext context) throws Exception
+    {
+        // Did the handler resolution stage return a Resolution? If so, bail.
+        Resolution r = context.proceed();
+        if (r != null)
+        {
+            return r;
+        }
+
+        // Get the ActionBean and ActionBeanContext
+        WikiActionBean actionBean = (WikiActionBean) context.getActionBean();
+        WikiActionBeanContext beanContext = actionBean.getContext();
+
+        // Stash the EventPermissionInfo items for this ActionBean's event
+        // handlers
+        Map<Method, EventPermissionInfo> permMap = EventPermissionInfo.getEventPermissionInfo(actionBean.getClass());
+        for (Map.Entry<Method, EventPermissionInfo> entry : permMap.entrySet())
+        {
+            beanContext.addPermissionInfo(entry.getKey(), entry.getValue());
+        }
+
+        return null;
+    }
+
+}

Modified: incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/src/com/ecyrd/jspwiki/ui/WikiJSPFilter.java
URL: http://svn.apache.org/viewvc/incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/src/com/ecyrd/jspwiki/ui/WikiJSPFilter.java?rev=630514&r1=630513&r2=630514&view=diff
==============================================================================
--- incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/src/com/ecyrd/jspwiki/ui/WikiJSPFilter.java (original)
+++ incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/src/com/ecyrd/jspwiki/ui/WikiJSPFilter.java Sat Feb 23 11:31:42 2008
@@ -28,13 +28,14 @@
 import javax.servlet.http.HttpServletResponse;
 import javax.servlet.http.HttpServletResponseWrapper;
 
+import org.apache.log4j.Logger;
 import org.apache.log4j.NDC;
 
 import com.ecyrd.jspwiki.TextUtil;
 import com.ecyrd.jspwiki.WikiContext;
-import com.ecyrd.jspwiki.event.WikiEventManager;
-import com.ecyrd.jspwiki.event.WikiPageEvent;
-import com.ecyrd.jspwiki.url.DefaultURLConstructor;
+import com.ecyrd.jspwiki.WikiEngine;
+import com.ecyrd.jspwiki.action.WikiActionBean;
+import com.ecyrd.jspwiki.event.*;
 import com.ecyrd.jspwiki.util.WatchDog;
 
 /**
@@ -66,9 +67,28 @@
  * @see TemplateManager
  * @see com.ecyrd.jspwiki.tags.RequestResourceTag
  */
-public class WikiJSPFilter extends WikiServletFilter
+public class WikiJSPFilter implements Filter
 {
-    /** {@inheritDoc} */
+    protected static final Logger log = Logger.getLogger( WikiJSPFilter.class );
+    protected WikiEngine m_engine = null;
+
+    public WikiJSPFilter()
+    {
+        super();
+    }
+    
+    public void init(FilterConfig config) throws ServletException
+    {
+        ServletContext context = config.getServletContext();
+        m_engine = WikiEngine.getInstance( context, null );
+    }
+
+    public void destroy()
+    {
+        log.info("WikiJSPFilter destroyed; telling WikiEngine to stop..");
+        m_engine.shutdown();
+    }
+    
     public void doFilter( ServletRequest  request,
                           ServletResponse response,
                           FilterChain     chain )
@@ -84,22 +104,22 @@
             HttpServletResponseWrapper responseWrapper = new MyServletResponseWrapper( (HttpServletResponse)response );
         
             // fire PAGE_REQUESTED event
-            String pagename = DefaultURLConstructor.parsePageFromURL(
-                    (HttpServletRequest)request, response.getCharacterEncoding() );
-            fireEvent( WikiPageEvent.PAGE_REQUESTED, pagename );
+            WikiActionBean actionBean = getWikiActionBean( request );
+            boolean isWikiContext = ( actionBean instanceof WikiContext );
+            if ( isWikiContext )
+            {
+                String pageName = ((WikiContext)actionBean).getPage().getName();
+                fireEvent( WikiPageEvent.PAGE_REQUESTED, pageName );
+            }
 
-            super.doFilter( request, responseWrapper, chain );
+            chain.doFilter( request, responseWrapper );
 
             // The response is now complete. Lets replace the markers now.
         
-            // WikiContext is only available after doFilter! (That is after
-            //   interpreting the jsp)
-
             try
             {
                 w.enterState( "Delivering response", 30 );
-                WikiContext wikiContext = getWikiContext( request );
-                String r = filter( wikiContext, responseWrapper );
+                String r = filter( actionBean, responseWrapper );
         
                 //String encoding = "UTF-8";
                 //if( wikiContext != null ) encoding = wikiContext.getEngine().getContentEncoding();
@@ -111,13 +131,14 @@
                 response.getWriter().write(r);
             
                 // Clean up the UI messages and loggers
-                if( wikiContext != null )
-                {
-                    wikiContext.getWikiSession().clearMessages();
-                }
+                actionBean.getWikiSession().clearMessages();
 
                 // fire PAGE_DELIVERED event
-                fireEvent( WikiPageEvent.PAGE_DELIVERED, pagename );
+                if ( isWikiContext )
+                {
+                    String pageName = ((WikiContext)actionBean).getPage().getName();
+                    fireEvent( WikiPageEvent.PAGE_DELIVERED, pageName );
+                }
 
             }
             finally
@@ -136,27 +157,27 @@
     /**
      * Goes through all types and writes the appropriate response.
      * 
-     * @param wikiContext The usual processing context
+     * @param actionBean The action bean for the current context
      * @param string The source string
      * @return The modified string with all the insertions in place.
      */
-    private String filter(WikiContext wikiContext, HttpServletResponse response )
+    private String filter(WikiActionBean actionBean, HttpServletResponse response )
     {
         String string = response.toString();
 
-        if( wikiContext != null )
+        if( actionBean != null )
         {
-            String[] resourceTypes = TemplateManager.getResourceTypes( wikiContext );
+            String[] resourceTypes = TemplateManager.getResourceTypes( actionBean );
 
             for( int i = 0; i < resourceTypes.length; i++ )
             {
-                string = insertResources( wikiContext, string, resourceTypes[i] );
+                string = insertResources( actionBean, string, resourceTypes[i] );
             }
         
             //
             //  Add HTTP header Resource Requests
             //
-            String[] headers = TemplateManager.getResourceRequests( wikiContext,
+            String[] headers = TemplateManager.getResourceRequests( actionBean,
                                                                     TemplateManager.RESOURCE_HTTPHEADER );
         
             for( int i = 0; i < headers.length; i++ )
@@ -182,19 +203,19 @@
      *  were requested by any plugins or other components for this particular
      *  type.
      *  
-     *  @param wikiContext The usual processing context
+     *  @param actionBean The action bean for the current context
      *  @param string The source string
      *  @param type Type identifier for insertion
      *  @return The filtered string.
      */
-    private String insertResources(WikiContext wikiContext, String string, String type )
+    private String insertResources( WikiActionBean actionBean, String string, String type )
     {
-        if( wikiContext == null )
+        if( actionBean == null )
         {
             return string;
         }
 
-        String marker = TemplateManager.getMarker( wikiContext, type );
+        String marker = TemplateManager.getMarker( actionBean, type );
         int idx = string.indexOf( marker );
         
         if( idx == -1 )
@@ -204,7 +225,7 @@
         
         log.debug("...Inserting...");
         
-        String[] resources = TemplateManager.getResourceRequests( wikiContext, type );
+        String[] resources = TemplateManager.getResourceRequests( actionBean, type );
         
         StringBuffer concat = new StringBuffer( resources.length * 40 );
         
@@ -285,6 +306,21 @@
         }
     }
 
+    /**
+     *  Looks up the WikiActionBean stored in the request.  This method does not create the
+     *  action bean if it does not exist.
+     *  
+     *  @param request The request to examine
+     *  @return A valid WikiActionBean, or <code>null</code> if one could not be located
+     */
+    protected WikiContext getWikiActionBean(ServletRequest  request)
+    {
+        HttpServletRequest httpRequest = (HttpServletRequest) request;
+    
+        WikiContext ctx = (WikiContext) httpRequest.getAttribute( WikiInterceptor.ATTR_ACTIONBEAN );
+        
+        return ctx;
+    }
 
     // events processing .......................................................
 

Added: incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/src/com/ecyrd/jspwiki/ui/WikiPageTypeConverter.java
URL: http://svn.apache.org/viewvc/incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/src/com/ecyrd/jspwiki/ui/WikiPageTypeConverter.java?rev=630514&view=auto
==============================================================================
--- incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/src/com/ecyrd/jspwiki/ui/WikiPageTypeConverter.java (added)
+++ incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/src/com/ecyrd/jspwiki/ui/WikiPageTypeConverter.java Sat Feb 23 11:31:42 2008
@@ -0,0 +1,88 @@
+/* Copyright 2005-2006 Tim Fennell
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.ecyrd.jspwiki.ui;
+
+import java.util.Collection;
+import java.util.Locale;
+
+import net.sourceforge.stripes.controller.StripesFilter;
+import net.sourceforge.stripes.validation.LocalizableError;
+import net.sourceforge.stripes.validation.SimpleError;
+import net.sourceforge.stripes.validation.TypeConverter;
+import net.sourceforge.stripes.validation.ValidationError;
+
+import com.ecyrd.jspwiki.WikiEngine;
+import com.ecyrd.jspwiki.WikiPage;
+import com.ecyrd.jspwiki.providers.ProviderException;
+
+/**
+ * Stripes type converter that converts a WikiPage name, expressed as a String, into an
+ * {@link com.ecyrd.jspwiki.WikiPage} object. This converter is looked up
+ * and returned by {@link WikiTypeConverterFactory} for HTTP request parameters
+ * that need to be bound to ActionBean properties of type WikiPage. Stripes
+ * executes this TypeConverter during the
+ * {@link net.sourceforge.stripes.controller.LifecycleStage#BindingAndValidation}
+ * stage of request processing.
+ * 
+ * @author Andrew Jaquith
+ */
+public class WikiPageTypeConverter implements TypeConverter<WikiPage>
+{
+    /**
+     * Converts a named wiki page into a valid WikiPage object by retrieving it
+     * via the WikiEngine. If the exact page is not found, plural variations
+     * will be tried. If the page cannot be found (perhaps because it does not
+     * exist), this method will add a validation error to the supplied
+     * Collection of errors and return <code>null</code>. The error will be
+     * of type {@link net.sourceforge.stripes.validation.LocalizableError} and
+     * will have a message key of <code>pageNotFound</code> and a single
+     * parameter (equal to the value passed for <code>pageName</code>).
+     * 
+     * @param pageName
+     *            the name of the WikiPage to retrieve
+     * @param targetType
+     *            the type to return, which will always be of type
+     *            {@link com.ecyrd.jspwiki.WikiPage}
+     * @param errors
+     *            the current Collection of validation errors for this field
+     * @return the
+     */
+    public WikiPage convert(String pageName, Class<? extends WikiPage> targetType, Collection<ValidationError> errors)
+    {
+        WikiRuntimeConfiguration config = (WikiRuntimeConfiguration)StripesFilter.getConfiguration();
+        WikiEngine engine = config.getEngine();
+        WikiPage page = engine.getPage(pageName);
+        if (page == null)
+        {
+            try
+            {
+                String finalName = engine.getWikiActionBeanFactory().getFinalPageName(pageName);
+                if (finalName == null || engine.getPage(finalName) == null)
+                {
+                    errors.add(new LocalizableError("pageNotFound", pageName));
+                }
+            }
+            catch (ProviderException e)
+            {
+                errors.add(new SimpleError(e.getMessage()));
+            }
+        }
+        return page;
+    }
+
+    public void setLocale(Locale locale)
+    {
+    }
+}

Added: incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/src/com/ecyrd/jspwiki/ui/WikiRuntimeConfiguration.java
URL: http://svn.apache.org/viewvc/incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/src/com/ecyrd/jspwiki/ui/WikiRuntimeConfiguration.java?rev=630514&view=auto
==============================================================================
--- incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/src/com/ecyrd/jspwiki/ui/WikiRuntimeConfiguration.java (added)
+++ incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/src/com/ecyrd/jspwiki/ui/WikiRuntimeConfiguration.java Sat Feb 23 11:31:42 2008
@@ -0,0 +1,68 @@
+package com.ecyrd.jspwiki.ui;
+
+import javax.servlet.ServletContext;
+
+import net.sourceforge.stripes.config.RuntimeConfiguration;
+import net.sourceforge.stripes.validation.TypeConverterFactory;
+
+import org.apache.log4j.Logger;
+
+import com.ecyrd.jspwiki.WikiEngine;
+
+/**
+ * Subclass of Stripes
+ * {@link net.sourceforge.stripes.config.RuntimeConfiguration} that keeps a
+ * reference to the running WikiEngine. This Configuration is loaded at startup
+ * by the {@link net.sourceforge.stripes.controller.StripesFilter}, so it is
+ * one of the very first things that happens. Because it loads first, it creates
+ * the WikiEngine.
+ * 
+ * @author Andrew Jaquith
+ */
+public class WikiRuntimeConfiguration extends RuntimeConfiguration
+{
+    private Logger log = Logger.getLogger(WikiRuntimeConfiguration.class);
+
+    private WikiEngine m_engine = null;
+
+    /**
+     * Initializes the WikiRuntimeConfiguration by calling the superclass
+     * {@link net.sourceforge.stripes.config.Configuration#init()} method, then
+     * setting the internally cached WikiEngine reference.
+     */
+    @Override
+    public void init()
+    {
+        // Initialize the Stripes configuration
+        super.init();
+
+        // Retrieve the WikiEngine
+        log.info("Attempting to retrieve WikiEngine.");
+        ServletContext context = super.getServletContext();
+        m_engine = WikiEngine.getInstance(context, null);
+        log.info("WikiEngine is running.");
+    }
+
+    /**
+     * Returns the WikiEngine associated with this Stripes configuration.
+     * 
+     * @return the wiki engine
+     */
+    public WikiEngine getEngine()
+    {
+        return m_engine;
+    }
+
+    /**
+     * Initializes the Stripes type converter factory, using a special
+     * {@link WikiTypeConverterFactory} that knows about JSPWiki object types.
+     */
+    @Override
+    protected TypeConverterFactory initTypeConverterFactory()
+    {
+        WikiTypeConverterFactory factory = new WikiTypeConverterFactory();
+        factory.init(this);
+        return factory;
+    }
+
+}

Modified: incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/src/com/ecyrd/jspwiki/ui/WikiServletFilter.java
URL: http://svn.apache.org/viewvc/incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/src/com/ecyrd/jspwiki/ui/WikiServletFilter.java?rev=630514&r1=630513&r2=630514&view=diff
==============================================================================
--- incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/src/com/ecyrd/jspwiki/ui/WikiServletFilter.java (original)
+++ incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/src/com/ecyrd/jspwiki/ui/WikiServletFilter.java Sat Feb 23 11:31:42 2008
@@ -28,13 +28,19 @@
 import org.apache.log4j.Logger;
 import org.apache.log4j.NDC;
 
-import com.ecyrd.jspwiki.WikiContext;
 import com.ecyrd.jspwiki.WikiEngine;
-import com.ecyrd.jspwiki.tags.WikiTagBase;
+
+
 
 /**
- *  Provides basic filtering for JSPWiki.  This filter only makes sure
- *  JSPWiki is running, and also does a bunch of sanitychecks.
+ *  <p>Initial filter for JSPWiki that ensures that the WikiEngine is running, and
+ *  injects a reference to it into the request scope. The WikiEngine is subsequently
+ *  available, for example, as a JSP 2.0 Expression Language variable
+ *  <code>${wikiEngine}</code>. A reference to the WikiSession is also stashed
+ *  and is available as (logically enough) <code>${wikiSession}</code>.</p>
+ *  <p>This filter also does a bunch of sanity-checks. Note that this filter should
+ *  run before any other Filter, including
+ *  {@link net.sourceforge.stripes.controller.StripesFilter}.</p>
  *  
  *  @author Janne Jalkanen
  *
@@ -86,12 +92,8 @@
             return;
         }   
         
-        // Write the response to a dummy response because we want to 
-        //   replace markers with scripts/stylesheet. 
         HttpServletRequest httpRequest = (HttpServletRequest) request;
         
-        httpRequest.setCharacterEncoding( m_engine.getContentEncoding() );
-
         try
         {
             NDC.push( m_engine.getApplicationName()+":"+httpRequest.getRequestURL() );
@@ -104,23 +106,6 @@
             NDC.remove();
         }
 
-    }
-
-
-    /**
-     *  Figures out the wiki context from the request.  This method does not create the
-     *  context if it does not exist.
-     *  
-     *  @param request The request to examine
-     *  @return A valid WikiContext value (or null, if the context could not be located).
-     */
-    protected WikiContext getWikiContext(ServletRequest  request)
-    {
-        HttpServletRequest httpRequest = (HttpServletRequest) request;
-    
-        WikiContext ctx = (WikiContext) httpRequest.getAttribute( WikiTagBase.ATTR_CONTEXT );
-        
-        return ctx;
     }
 
 }

Added: incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/src/com/ecyrd/jspwiki/ui/WikiTypeConverterFactory.java
URL: http://svn.apache.org/viewvc/incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/src/com/ecyrd/jspwiki/ui/WikiTypeConverterFactory.java?rev=630514&view=auto
==============================================================================
--- incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/src/com/ecyrd/jspwiki/ui/WikiTypeConverterFactory.java (added)
+++ incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/src/com/ecyrd/jspwiki/ui/WikiTypeConverterFactory.java Sat Feb 23 11:31:42 2008
@@ -0,0 +1,57 @@
+package com.ecyrd.jspwiki.ui;
+
+import java.security.Principal;
+import java.util.Locale;
+
+import net.sourceforge.stripes.config.Configuration;
+import net.sourceforge.stripes.validation.DefaultTypeConverterFactory;
+import net.sourceforge.stripes.validation.TypeConverter;
+
+import com.ecyrd.jspwiki.WikiPage;
+import com.ecyrd.jspwiki.auth.authorize.Group;
+
+/**
+ * Subclasses Stripes
+ * {@link net.sourceforge.stripes.validation.DefaultTypeConverterFactory} and
+ * adds support for JSPWiki types such as {@link com.ecyrd.jspwiki.WikiPage}.
+ * This implementation differs from the DefaultTypeConverterFactory in only one
+ * respect: the overridden {@link #init(Configuration)} method merely adds
+ * converters for JSPWiki types after normal initialization.
+ * 
+ * @author Andrew Jaquith
+ */
+public class WikiTypeConverterFactory extends DefaultTypeConverterFactory
+{
+    /**
+     * @param configuration
+     *            the Stripes configuration, which must be of type
+     *            {@link WikiRuntimeConfiguration}.
+     * @throws IllegalArgumentException
+     *             if configuration is not of type WikiRuntimeConfiguration
+     */
+    @Override
+    public void init(Configuration configuration)
+    {
+        super.init(configuration);
+        
+        // Add our custom converters
+        super.add(Group.class, GroupTypeConverter.class);
+        super.add(Principal.class, PrincipalTypeConverter.class);
+        super.add(WikiPage.class, WikiPageTypeConverter.class);
+    }
+
+    @Override
+    public TypeConverter getInstance(Class<? extends TypeConverter> arg0, Locale arg1) throws Exception
+    {
+        TypeConverter converter = super.getInstance(arg0, arg1);
+        return converter;
+    }
+
+    @Override
+    public TypeConverter getTypeConverter(Class forType, Locale locale) throws Exception
+    {
+        TypeConverter converter = super.getTypeConverter(forType, locale);
+        return converter;
+    }
+    
+}