jspwiki-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From ajaqu...@apache.org
Subject svn commit: r630500 [1/2] - /incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/src/com/ecyrd/jspwiki/action/
Date Sat, 23 Feb 2008 18:33:12 GMT
Author: ajaquith
Date: Sat Feb 23 10:33:08 2008
New Revision: 630500

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

Added:
    incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/src/com/ecyrd/jspwiki/action/
    incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/src/com/ecyrd/jspwiki/action/AbstractActionBean.java
    incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/src/com/ecyrd/jspwiki/action/AdminActionBean.java
    incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/src/com/ecyrd/jspwiki/action/AdministerProfilesActionBean.java
    incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/src/com/ecyrd/jspwiki/action/AttachActionBean.java
    incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/src/com/ecyrd/jspwiki/action/CommentActionBean.java
    incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/src/com/ecyrd/jspwiki/action/DeleteActionBean.java
    incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/src/com/ecyrd/jspwiki/action/DiffActionBean.java
    incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/src/com/ecyrd/jspwiki/action/EditActionBean.java
    incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/src/com/ecyrd/jspwiki/action/ErrorActionBean.java
    incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/src/com/ecyrd/jspwiki/action/EventPermission.java
    incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/src/com/ecyrd/jspwiki/action/EventPermissionInfo.java
    incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/src/com/ecyrd/jspwiki/action/GroupActionBean.java
    incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/src/com/ecyrd/jspwiki/action/GroupContext.java
    incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/src/com/ecyrd/jspwiki/action/InstallActionBean.java
    incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/src/com/ecyrd/jspwiki/action/LoginActionBean.java
    incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/src/com/ecyrd/jspwiki/action/MessageActionBean.java
    incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/src/com/ecyrd/jspwiki/action/NewBlogEntryActionBean.java
    incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/src/com/ecyrd/jspwiki/action/NewPageActionBean.java
    incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/src/com/ecyrd/jspwiki/action/NoneActionBean.java
    incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/src/com/ecyrd/jspwiki/action/PageInfoActionBean.java
    incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/src/com/ecyrd/jspwiki/action/PageModifiedActionBean.java
    incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/src/com/ecyrd/jspwiki/action/PreviewActionBean.java
    incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/src/com/ecyrd/jspwiki/action/RSSActionBean.java
    incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/src/com/ecyrd/jspwiki/action/RenameActionBean.java
    incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/src/com/ecyrd/jspwiki/action/SearchActionBean.java
    incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/src/com/ecyrd/jspwiki/action/UploadActionBean.java
    incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/src/com/ecyrd/jspwiki/action/UserPreferencesActionBean.java
    incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/src/com/ecyrd/jspwiki/action/UserProfileActionBean.java
    incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/src/com/ecyrd/jspwiki/action/ViewActionBean.java
    incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/src/com/ecyrd/jspwiki/action/WikiActionBean.java
    incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/src/com/ecyrd/jspwiki/action/WikiActionBeanContext.java
    incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/src/com/ecyrd/jspwiki/action/WikiActionBeanFactory.java
    incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/src/com/ecyrd/jspwiki/action/WikiRequestContext.java
    incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/src/com/ecyrd/jspwiki/action/WikiUrlPattern.java
    incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/src/com/ecyrd/jspwiki/action/WorkflowActionBean.java
    incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/src/com/ecyrd/jspwiki/action/package.html

Added: incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/src/com/ecyrd/jspwiki/action/AbstractActionBean.java
URL: http://svn.apache.org/viewvc/incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/src/com/ecyrd/jspwiki/action/AbstractActionBean.java?rev=630500&view=auto
==============================================================================
--- incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/src/com/ecyrd/jspwiki/action/AbstractActionBean.java (added)
+++ incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/src/com/ecyrd/jspwiki/action/AbstractActionBean.java Sat Feb 23 10:33:08 2008
@@ -0,0 +1,238 @@
+package com.ecyrd.jspwiki.action;
+
+import java.security.Principal;
+import java.util.*;
+
+import javax.servlet.http.HttpServletRequest;
+
+import net.sourceforge.stripes.action.ActionBeanContext;
+
+import com.ecyrd.jspwiki.WikiEngine;
+import com.ecyrd.jspwiki.WikiSession;
+
+/**
+ * <p>Abstract ActionBean superclass for all wiki actions, such as page actions ({@link com.ecyrd.jspwiki.WikiContext} and subclasses),
+ * group actions (e.g., {@link ViewGroupActionBean}), user actions (e.g., {@link UserPreferencesActionBean}) and others.</p>
+ * 
+ * 
+ * @author Andrew Jaquith
+ */
+@WikiRequestContext("none")
+public abstract class AbstractActionBean implements WikiActionBean
+{
+    protected  Map<String,Object> m_variableMap = new HashMap<String,Object>();
+    
+    private WikiActionBeanContext m_actionBeanContext = null;
+
+    /**
+     * The JSP for this WikiContext.
+     */
+    private String m_skin = null;
+
+    private String m_template = null;
+    
+    private static final String DEFAULT_TEMPLATE = "default";
+    
+    private final String m_requestContext;
+    
+    /**
+     * Creates a new instance of this class, without a WikiEngine, Request or
+     * WikiPage.
+     */
+    protected AbstractActionBean()
+    {
+        super();
+        m_requestContext = getClass().getAnnotation( WikiRequestContext.class ).value();
+    }
+
+    /**
+     * Returns the content template for this ActionBean.
+     */
+    public final String getContentTemplate()
+    {
+        return this.getClass().getAnnotation(WikiRequestContext.class).value();
+    }
+
+    /**
+     * Returns the Stripes ActionBeanContext associated this WikiContext, lazily
+     * creating one if necessary.
+     * 
+     * @throws IllegalStateException
+     */
+    public WikiActionBeanContext getContext()
+    {
+        if (m_actionBeanContext == null)
+        {
+            setContext(new WikiActionBeanContext());
+        }
+        return m_actionBeanContext;
+    }
+
+    /**
+     * Convenience method that gets the current user. Delegates the lookup to
+     * the WikiSession associated with this WikiContect. May return null, in
+     * case the current user has not yet been determined; or this is an internal
+     * system. If the WikiSession has not been set, <em>always</em> returns
+     * null.
+     */
+    public Principal getCurrentUser()
+    {
+        return getWikiSession().getUserPrincipal();
+    }
+
+    /**
+     * Returns the WikiEngine, which may be <code>null</code> if this instance
+     * was created without invoking the WikiActionBeanContext methods
+     * {@link WikiActionBeanContext#setRequest(HttpServletRequest)} or
+     * {@link WikiActionBeanContext#setServletContext(javax.servlet.ServletContext)}.
+     */
+    public WikiEngine getEngine()
+    {
+        return getContext().getWikiEngine();
+    }
+
+    /**
+     * Returns the request context for this ActionBean by looking up the 
+     * value of the annotation {@link WikiRequestContext}. Note that if the
+     * annotation is not present, this method will return {@link ecyrd.jspwiki.WikiContext#NONE}.
+     */
+    public String getRequestContext()
+    {
+        return m_requestContext;
+    }
+    
+    /**
+     * Returns the "skin" to be used for this ActionBean.
+     * 
+     * @return the skin
+     */
+    public String getSkin()
+    {
+        return m_skin;
+    }
+
+    /**
+     * <p>
+     * Gets the template that is to be used throughout this request. The value
+     * returned depends on the whether the current HTTP request has supplied a
+     * custom skin or template name. In order of preference:
+     * </p>
+     * <ul>
+     * <li>The "skin", if set by {@link #setSkin(String)} or if the HTTP
+     * parameter <code>skin</code> was bound by Stripes</li>
+     * <li>The template, if set by {@link #setTemplate(String)} or if the HTTP
+     * parameter <code>template</code> was bound by Stripes</li>
+     * <li>The WikiEngine's default template, as returned by
+     * {@link WikiEngine#getTemplateDir()}</li>
+     * <li>The value <code>default</code></li>
+     * </ul>
+     * 
+     * @since 2.1.15.
+     */
+    public String getTemplate()
+    {
+        if ( m_skin != null ) 
+        {
+            return m_skin;
+        }
+        else if ( m_template != null )
+        {
+            return m_template;
+        }
+        else if ( getEngine() != null ) 
+        {
+            return getEngine().getTemplateDir();
+        }
+        return DEFAULT_TEMPLATE;
+    }
+
+    /**
+     * Returns the WikiSession associated with the context. This method is
+     * guaranteed to always return a valid WikiSession. If this context was
+     * constructed without an associated HttpServletRequest, it will return
+     * {@link WikiSession#guestSession(WikiEngine)}.
+     */
+    public WikiSession getWikiSession()
+    {
+        return getContext().getWikiSession();
+    }
+
+    /**
+     *  Gets a previously set variable.
+     *
+     *  @param key The variable name.
+     *  @return The variable contents.
+     */
+    public Object getVariable( String key )
+    {
+        return m_variableMap.get( key );
+    }
+
+    /**
+     *  Sets a variable.  The variable is valid while the WikiContext is valid,
+     *  i.e. while page processing continues.  The variable data is discarded
+     *  once the page processing is finished.
+     *
+     *  @param key The variable name.
+     *  @param data The variable value.
+     */
+    public void setVariable( String key, Object data )
+    {
+        m_variableMap.put( key, data );
+    }
+
+    /**
+     * Sets the Stripes ActionBeanContext associated with this WikiContext. It
+     * will also update the cached HttpRequest.
+     */
+    public void setContext(ActionBeanContext context)
+    {
+        m_actionBeanContext = ((WikiActionBeanContext) context);
+    }
+
+    /**
+     * Sets the skin to be used with this ActionBean. This value will override
+     * the template returned by {@link #getTemplate()}. Normally, this method
+     * is invoked by Stripes when binding request parameters to the ActionBean.
+     * 
+     * @param skin
+     *            the skin to use
+     */
+    public void setSkin(String skin)
+    {
+        m_skin = skin;
+    }
+
+    /**
+     * Sets the template to be used for this request.
+     * 
+     * @since 2.1.15.
+     */
+    public void setTemplate(String dir)
+    {
+        m_template = dir;
+    }
+    
+    /**
+     *  Locates the i18n ResourceBundle given.  This method interprets
+     *  the request locale, and uses that to figure out which language the
+     *  user wants.
+     *  @see com.ecyrd.jspwiki.i18n.InternationalizationManager
+     *  @param bundle The name of the bundle you are looking for.
+     *  @return A resource bundle object
+     *  @throws MissingResourceException If the bundle cannot be found
+     */
+    // FIXME: This method should really cache the ResourceBundles or something...
+    public ResourceBundle getBundle( String bundle ) throws MissingResourceException
+    {
+        Locale loc = null;
+
+        if( m_actionBeanContext != null && m_actionBeanContext.getRequest() != null )
+        {
+            loc = m_actionBeanContext.getRequest().getLocale();
+        }
+        ResourceBundle b = getEngine().getInternationalizationManager().getBundle(bundle, loc);
+
+        return b;
+    }
+}

Added: incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/src/com/ecyrd/jspwiki/action/AdminActionBean.java
URL: http://svn.apache.org/viewvc/incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/src/com/ecyrd/jspwiki/action/AdminActionBean.java?rev=630500&view=auto
==============================================================================
--- incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/src/com/ecyrd/jspwiki/action/AdminActionBean.java (added)
+++ incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/src/com/ecyrd/jspwiki/action/AdminActionBean.java Sat Feb 23 10:33:08 2008
@@ -0,0 +1,12 @@
+package com.ecyrd.jspwiki.action;
+
+import net.sourceforge.stripes.action.UrlBinding;
+
+import com.ecyrd.jspwiki.WikiContext;
+
+@WikiRequestContext("admin")
+@UrlBinding("/admin/Admin.action")
+public class AdminActionBean extends WikiContext
+{
+    
+}

Added: incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/src/com/ecyrd/jspwiki/action/AdministerProfilesActionBean.java
URL: http://svn.apache.org/viewvc/incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/src/com/ecyrd/jspwiki/action/AdministerProfilesActionBean.java?rev=630500&view=auto
==============================================================================
--- incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/src/com/ecyrd/jspwiki/action/AdministerProfilesActionBean.java (added)
+++ incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/src/com/ecyrd/jspwiki/action/AdministerProfilesActionBean.java Sat Feb 23 10:33:08 2008
@@ -0,0 +1,87 @@
+package com.ecyrd.jspwiki.action;
+
+import java.util.List;
+
+import net.sourceforge.stripes.action.*;
+import net.sourceforge.stripes.validation.EmailTypeConverter;
+import net.sourceforge.stripes.validation.Validate;
+import net.sourceforge.stripes.validation.ValidateNestedProperties;
+
+import com.ecyrd.jspwiki.auth.NoSuchPrincipalException;
+import com.ecyrd.jspwiki.auth.WikiSecurityException;
+import com.ecyrd.jspwiki.auth.user.DefaultUserProfile;
+import com.ecyrd.jspwiki.auth.user.UserDatabase;
+import com.ecyrd.jspwiki.auth.user.UserProfile;
+
+/**
+ * Manages the administration of UserProfiles, from the Administer Profiles page. Receives a List
+ * of UserProfiles, which may include a new profile, and persists the changes. Also receives an
+ * Array of Strings (login names) for UserProfiles that are to be deleted, and deletes them.
+ *
+ * @author Andrew Jaquith
+ */
+@WikiRequestContext("adminProfiles")
+@UrlBinding("/AdministerProfiles.action")
+public class AdministerProfilesActionBean extends AbstractActionBean {
+    
+    private String[] m_deleteLoginNames;
+    private List<UserProfile> m_profiles;
+    
+    @ValidateNestedProperties ({
+        @Validate(field="loginName", required=true, minlength=3, maxlength=50),
+        @Validate(field="password", required=true, minlength=6, maxlength=128),
+        @Validate(field="fullName", required=true, minlength=3, maxlength=50),
+        @Validate(field="wikiName", required=true, minlength=3, maxlength=50),
+        @Validate(field="email", required=false, converter=EmailTypeConverter.class)
+    })
+
+    public String[] getDeleteLoginNames() { return m_deleteLoginNames; }
+    public void setDeleteLoginNames(String[] deleteLoginNames) { m_deleteLoginNames = deleteLoginNames; }
+
+    public List<UserProfile> getUserProfiles() { return m_profiles; }
+    
+    public void setUserProfiles(List<UserProfile> profiles) { this.m_profiles = profiles; }
+
+    @HandlesEvent("Save") @DefaultHandler
+    public Resolution saveChanges() throws WikiSecurityException {
+        UserDatabase db = super.getContext().getWikiEngine().getUserManager().getUserDatabase();
+
+        // Apply any changes to existing profiles (and create new ones)
+        for (UserProfile profile : m_profiles) {
+            
+            // Look up profile; create new if not found
+            UserProfile existingProfile;
+            try {
+                existingProfile = db.findByLoginName(profile.getLoginName());
+            }
+            catch (NoSuchPrincipalException e)
+            {
+                existingProfile = new DefaultUserProfile();
+            }
+
+            // Make changes to things that have changed
+            existingProfile.setLoginName(profile.getLoginName());
+            existingProfile.setFullname(profile.getFullname());
+            existingProfile.setEmail(profile.getEmail());
+            if (profile.getPassword() != null && profile.getPassword().length() > 0) {
+                existingProfile.setPassword(profile.getPassword());
+            }
+            db.save(existingProfile);
+        }
+
+        // Then, if the user checked anyone off to be deleted, delete them
+        if (m_deleteLoginNames != null) {
+            for (String loginName : m_deleteLoginNames) {
+                try {
+                    db.deleteByLoginName(loginName);
+                }
+                catch (NoSuchPrincipalException e)
+                {
+                    throw new WikiSecurityException(e.getMessage());
+                }
+            }
+        }
+
+        return new RedirectResolution("/AdministerProfiles.jsp");
+    }
+}
\ No newline at end of file

Added: incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/src/com/ecyrd/jspwiki/action/AttachActionBean.java
URL: http://svn.apache.org/viewvc/incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/src/com/ecyrd/jspwiki/action/AttachActionBean.java?rev=630500&view=auto
==============================================================================
--- incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/src/com/ecyrd/jspwiki/action/AttachActionBean.java (added)
+++ incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/src/com/ecyrd/jspwiki/action/AttachActionBean.java Sat Feb 23 10:33:08 2008
@@ -0,0 +1,20 @@
+package com.ecyrd.jspwiki.action;
+
+import net.sourceforge.stripes.action.HandlesEvent;
+import net.sourceforge.stripes.action.Resolution;
+import net.sourceforge.stripes.action.UrlBinding;
+
+import com.ecyrd.jspwiki.WikiContext;
+import com.ecyrd.jspwiki.auth.permissions.PagePermission;
+
+@WikiRequestContext("att")
+@UrlBinding("/attach/")
+public class AttachActionBean extends WikiContext
+{
+    @HandlesEvent("upload")
+    @EventPermission(permissionClass=PagePermission.class,target="${page.qualifiedName}",actions=PagePermission.UPLOAD_ACTION)
+    public Resolution upload()
+    {
+        return null;
+    }
+}

Added: incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/src/com/ecyrd/jspwiki/action/CommentActionBean.java
URL: http://svn.apache.org/viewvc/incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/src/com/ecyrd/jspwiki/action/CommentActionBean.java?rev=630500&view=auto
==============================================================================
--- incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/src/com/ecyrd/jspwiki/action/CommentActionBean.java (added)
+++ incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/src/com/ecyrd/jspwiki/action/CommentActionBean.java Sat Feb 23 10:33:08 2008
@@ -0,0 +1,20 @@
+package com.ecyrd.jspwiki.action;
+
+import net.sourceforge.stripes.action.HandlesEvent;
+import net.sourceforge.stripes.action.Resolution;
+import net.sourceforge.stripes.action.UrlBinding;
+
+import com.ecyrd.jspwiki.WikiContext;
+import com.ecyrd.jspwiki.auth.permissions.PagePermission;
+
+@WikiRequestContext("comment")
+@UrlBinding("/Comment.action")
+public class CommentActionBean extends WikiContext
+{
+    @HandlesEvent("comment")
+    @EventPermission(permissionClass=PagePermission.class, target="${page.qualifiedName}", actions=PagePermission.COMMENT_ACTION)
+    public Resolution comment()
+    {
+        return null;
+    }
+}

Added: incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/src/com/ecyrd/jspwiki/action/DeleteActionBean.java
URL: http://svn.apache.org/viewvc/incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/src/com/ecyrd/jspwiki/action/DeleteActionBean.java?rev=630500&view=auto
==============================================================================
--- incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/src/com/ecyrd/jspwiki/action/DeleteActionBean.java (added)
+++ incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/src/com/ecyrd/jspwiki/action/DeleteActionBean.java Sat Feb 23 10:33:08 2008
@@ -0,0 +1,20 @@
+package com.ecyrd.jspwiki.action;
+
+import net.sourceforge.stripes.action.HandlesEvent;
+import net.sourceforge.stripes.action.Resolution;
+import net.sourceforge.stripes.action.UrlBinding;
+
+import com.ecyrd.jspwiki.WikiContext;
+import com.ecyrd.jspwiki.auth.permissions.PagePermission;
+
+@WikiRequestContext("del")
+@UrlBinding("/Delete.action")
+public class DeleteActionBean extends WikiContext
+{
+    @HandlesEvent("delete")
+    @EventPermission(permissionClass=PagePermission.class, target="${page.qualifiedName}", actions=PagePermission.DELETE_ACTION)
+    public Resolution delete()
+    {
+        return null;
+    }
+}

Added: incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/src/com/ecyrd/jspwiki/action/DiffActionBean.java
URL: http://svn.apache.org/viewvc/incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/src/com/ecyrd/jspwiki/action/DiffActionBean.java?rev=630500&view=auto
==============================================================================
--- incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/src/com/ecyrd/jspwiki/action/DiffActionBean.java (added)
+++ incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/src/com/ecyrd/jspwiki/action/DiffActionBean.java Sat Feb 23 10:33:08 2008
@@ -0,0 +1,20 @@
+package com.ecyrd.jspwiki.action;
+
+import net.sourceforge.stripes.action.HandlesEvent;
+import net.sourceforge.stripes.action.Resolution;
+import net.sourceforge.stripes.action.UrlBinding;
+
+import com.ecyrd.jspwiki.WikiContext;
+import com.ecyrd.jspwiki.auth.permissions.PagePermission;
+
+@WikiRequestContext("diff")
+@UrlBinding("/Diff.action")
+public class DiffActionBean extends WikiContext
+{
+    @HandlesEvent("diff")
+    @EventPermission(permissionClass=PagePermission.class, target="${page.qualifiedName}", actions=PagePermission.VIEW_ACTION)
+    public Resolution diff()
+    {
+        return null;
+    }
+}

Added: incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/src/com/ecyrd/jspwiki/action/EditActionBean.java
URL: http://svn.apache.org/viewvc/incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/src/com/ecyrd/jspwiki/action/EditActionBean.java?rev=630500&view=auto
==============================================================================
--- incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/src/com/ecyrd/jspwiki/action/EditActionBean.java (added)
+++ incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/src/com/ecyrd/jspwiki/action/EditActionBean.java Sat Feb 23 10:33:08 2008
@@ -0,0 +1,20 @@
+package com.ecyrd.jspwiki.action;
+
+import net.sourceforge.stripes.action.HandlesEvent;
+import net.sourceforge.stripes.action.Resolution;
+import net.sourceforge.stripes.action.UrlBinding;
+
+import com.ecyrd.jspwiki.WikiContext;
+import com.ecyrd.jspwiki.auth.permissions.PagePermission;
+
+@WikiRequestContext("edit")
+@UrlBinding("/Edit.action")
+public class EditActionBean extends WikiContext
+{
+    @HandlesEvent("edit")
+    @EventPermission(permissionClass=PagePermission.class, target="${page.qualifiedName}", actions=PagePermission.EDIT_ACTION)
+    public Resolution edit()
+    {
+        return null;
+    }
+}

Added: incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/src/com/ecyrd/jspwiki/action/ErrorActionBean.java
URL: http://svn.apache.org/viewvc/incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/src/com/ecyrd/jspwiki/action/ErrorActionBean.java?rev=630500&view=auto
==============================================================================
--- incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/src/com/ecyrd/jspwiki/action/ErrorActionBean.java (added)
+++ incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/src/com/ecyrd/jspwiki/action/ErrorActionBean.java Sat Feb 23 10:33:08 2008
@@ -0,0 +1,9 @@
+package com.ecyrd.jspwiki.action;
+
+import net.sourceforge.stripes.action.UrlBinding;
+
+@WikiRequestContext("error")
+@UrlBinding("/Error.action")
+public class ErrorActionBean extends AbstractActionBean
+{
+}

Added: incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/src/com/ecyrd/jspwiki/action/EventPermission.java
URL: http://svn.apache.org/viewvc/incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/src/com/ecyrd/jspwiki/action/EventPermission.java?rev=630500&view=auto
==============================================================================
--- incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/src/com/ecyrd/jspwiki/action/EventPermission.java (added)
+++ incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/src/com/ecyrd/jspwiki/action/EventPermission.java Sat Feb 23 10:33:08 2008
@@ -0,0 +1,76 @@
+/**
+ * 
+ */
+package com.ecyrd.jspwiki.action;
+
+import java.lang.annotation.*;
+import java.security.Permission;
+
+/**
+ * <p>Permission annotation that specifies the the class, target and actions of a
+ * Permission required to execute a Stripes event method. Annotations are
+ * specified as follows:</p>
+ * <blockquote>
+ * <code>
+ * &#64;EventPermission(permissionClass="<var>className</var>",target="<var>target</var>",actions="<var>actions</var>")
+ * </code>
+ * </blockquote>
+ * </p>
+ * <p>The target and actions can be expression language (EL) expressions;
+ * if so, they must start with <code>${</code> and end with <code>}</code>.
+ * The expression is evaluated with the ActionBean as the "root." Thus, the expression
+ * <code>${foo}</code> evaluates to the value of the bean's <code>foo</code>
+ * property, typically as returned by an accessor such as <code>getFoo()</code>.
+ *  Mapped properties can also be used. For example, if the <code>Map</code>
+ *  property's accessor method <code>getBarMap()</code> returns a Map, the expression
+ * <code>${barMap['Alice']}</code> evaluates to the Map value whose key is
+ * <code>Alice</code>. <em>EL expressions that do not evaluate to valid values
+ * should be discarded by callers.</em></p>
+ * <p>When the target or actions parameter values are <em>not</em> EL expressions, they
+ * are interpreted as literals.</p>
+ * <p>For example, the following are all valid annotations:</p>
+ * <blockquote>
+ * <code>
+ * &#64;EventPermission(permissionClass="java.io.FilePermission", target="/tmp/-", actions="read,write")
+ * <br/><br/>
+ * &#64;EventPermission(permissionClass="com.ecyrd.jspwiki.auth.permissions.PagePermission", target="${page.name}", actions = "edit")
+ * <br/><br/>
+ * &#64;EventPermission(permissionClass="com.ecyrd.jspwiki.auth.permissions.GroupPermission", target="${context.request.parameterMap['group'][0]}",actions="view")
+ * </code>
+ * </blockquote>
+ * <p>These examples assume that the ActionBeans they annotate contain the appropriate properties;
+ * in this case, <code>page</code> is assumed to be a {@link com.ecyrd.jspwiki.WikiPage} property,
+ * and <code>context</code> is assumed to be a {@link com.ecyrd.jspwiki.action.WikiActionBeanContext}
+ * property.</p>
+ * <p>This Annotation class does not parse, process or instantiate Permissions; it merely specifies
+ * the syntax for annotating event handler methods. The collaborating class {@link EventPermissionInfo}
+ * actually does the heavy lifting.</p>
+ * @author Andrew Jaquith
+ */
+@Retention(RetentionPolicy.RUNTIME)
+@Target( { ElementType.METHOD })
+@Documented
+@Inherited
+public @interface EventPermission
+{
+    /**
+     * The class of the Permission.
+     */
+    Class<? extends Permission> permissionClass();
+
+    /**
+     * The Permission target, supplied as a static String or as an EL
+     * expression.
+     * 
+     * @return the target
+     */
+    String target();
+
+    /**
+     * The Permission actions, supplied as a static String or as an EL
+     * expression.
+     * 
+     * @return the actions
+     */
+    String actions();
+}

Added: incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/src/com/ecyrd/jspwiki/action/EventPermissionInfo.java
URL: http://svn.apache.org/viewvc/incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/src/com/ecyrd/jspwiki/action/EventPermissionInfo.java?rev=630500&view=auto
==============================================================================
--- incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/src/com/ecyrd/jspwiki/action/EventPermissionInfo.java (added)
+++ incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/src/com/ecyrd/jspwiki/action/EventPermissionInfo.java Sat Feb 23 10:33:08 2008
@@ -0,0 +1,223 @@
+package com.ecyrd.jspwiki.action;
+
+import java.lang.annotation.AnnotationFormatError;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Method;
+import java.security.Permission;
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.servlet.jsp.el.ELException;
+
+import net.sourceforge.stripes.action.ActionBean;
+import net.sourceforge.stripes.action.HandlesEvent;
+import net.sourceforge.stripes.util.bean.PropertyExpression;
+import net.sourceforge.stripes.util.bean.PropertyExpressionEvaluation;
+
+import com.ecyrd.jspwiki.auth.permissions.GroupPermission;
+import com.ecyrd.jspwiki.auth.permissions.PagePermission;
+import com.ecyrd.jspwiki.auth.permissions.PermissionFactory;
+import com.ecyrd.jspwiki.auth.permissions.WikiPermission;
+
+/**
+ * Extracts {@link EventPermission} annotation metadata for a supplied ActionBean
+ * class using introspection, and allows instantiation of dynamic Permissions.
+ * This class caches EventPermissionInfo objects for each ActionBean class, so introspection operations
+ * only happen once per class.
+ * @author Andrew Jaquith
+ */
+public class EventPermissionInfo
+{
+    private static final Map<Class<? extends ActionBean>,Map<Method,EventPermissionInfo>> CACHED_INFO
+        = new HashMap<Class<? extends ActionBean>,Map<Method,EventPermissionInfo>>();
+    private final Class m_clazz;
+    private final String m_target;
+    private final String m_actions;
+    private final PropertyExpression m_targetExpression;
+    private final PropertyExpression m_actionExpression;
+    
+    private EventPermissionInfo(Class clazz, String target, String actions)
+    {
+        m_clazz = clazz;
+        m_target = target.trim();
+        m_actions = actions.trim();
+        if (m_target.startsWith("${") && m_target.endsWith("}"))
+        {
+            m_targetExpression = PropertyExpression.getExpression(m_target.substring(2,m_target.length() -1));
+        }
+        else
+        {
+            m_targetExpression = null;
+        }
+        if (m_actions.startsWith("${") && m_actions.endsWith("}"))
+        {
+            m_actionExpression = PropertyExpression.getExpression(m_target.substring(2,m_target.length() -1));
+        }
+        else
+        {
+            m_actionExpression = null;
+        }
+    }
+    
+    public String getActions()
+    {
+        return m_actions;
+    }
+
+    public Class getPermissionClass()
+    {
+        return m_clazz;
+    }
+
+    public String getTarget()
+    {
+        return m_target;
+    }
+
+    /**
+     * Returns the property expression for the target, if it specifies a valid expression, or <code>null</code> otherwise.
+     * @return the property expression
+     */
+    public PropertyExpression getTargetExpression()
+    {
+        return m_targetExpression;
+    }
+    
+    /**
+     * Returns the property expression for the actions, if it specifies a valid expression, or <code>null</code> otherwise.
+     * @return the property expression
+     */
+    public PropertyExpression getActionsExpression()
+    {
+        return m_actionExpression;
+    }
+    
+    /**
+     * For a supplied ActionBean class, returns a Map with the Stripes event handler methods as keys, and
+     * EventPermissionInfo objects as values.
+     * @param beanClass the ActionBean subclass to inspect
+     * @return the map
+     */
+    public static final Map<Method,EventPermissionInfo> getEventPermissionInfo( Class<? extends ActionBean> beanClass)
+    {
+        // If we've already figured out the method info, return the cached Map
+        Map<Method,EventPermissionInfo> methodInfo = CACHED_INFO.get(beanClass);
+        if (methodInfo != null)
+        {
+            return methodInfo;
+        }
+        
+        // Not there, eh? Ok, let's figure it out.
+        methodInfo = new HashMap<Method,EventPermissionInfo>();
+        CACHED_INFO.put(beanClass, methodInfo);
+        
+        Method[] methods = beanClass.getMethods();
+        for (int i = 0; i < methods.length; i++)
+        {
+            // Does the method have a @HandlesEvent annotation?
+            Method method = methods[i];
+            HandlesEvent eventAnnotation = method.getAnnotation(HandlesEvent.class);
+            if (eventAnnotation != null)
+            {
+                // If yes, does it have an @EventHandlerPermission?
+                EventPermission permAnnotation = method.getAnnotation(EventPermission.class);
+                if ( permAnnotation != null)
+                {
+                    Class permClass = permAnnotation.permissionClass();
+                    String target = permAnnotation.target();
+                    String actions = permAnnotation.actions();
+                    
+                    // If the class or target are null, this is an error (a mistake by some developer or a classloader problem)
+                    if ( permClass == null || target == null )
+                    {
+                        throw new AnnotationFormatError("Malformed annotation: " + beanClass.getName() + "." + method.getName());
+                    }
+                    
+                    EventPermissionInfo info = new EventPermissionInfo(permClass, target, actions);
+                    methodInfo.put(method,info);
+                }
+            }
+        }
+        return methodInfo;
+    }
+    
+    /**
+     * Creates a Permission based on the class, target and actions metadata, evaluating any EL expressions
+     * found in the target or actions. In order for EL expressions to be evaluated, this method <em>must</em>
+     * be called from inside an Interceptor (or other StripesFilter delegate) at runtime.
+     * @param actionBean the ActionBean that will be used as the base for any EL expressions
+     * @return the resolved and instantiated Permission
+     * @throws ELException if EL expressions cannot be parsed, or of the Permission itself
+     * cannot be instantiated for any reason
+     */
+    public Permission getPermission(WikiActionBean actionBean) throws ELException
+    {
+        // Get the target class, target and actions
+        boolean hasOneParameter = m_actions == null;
+        String target = m_target;
+        String actions = m_actions;
+
+        // Evaluate the target, if it's an expression
+        if (m_targetExpression != null)
+        {
+            PropertyExpressionEvaluation evaluation = new PropertyExpressionEvaluation( m_targetExpression, actionBean );
+            target = (String)evaluation.getValue();
+            if ( target == null )
+            {
+                // If the target didn't evaluate, assume it's because some property wasn't set (probably normal)
+                // FIXME: should we throw a checked exception instead?
+                return null;
+            }
+        }
+
+        // Evaluate the actions, if it's an expression
+        if (m_actionExpression != null)
+        {
+            PropertyExpressionEvaluation evaluation = new PropertyExpressionEvaluation( m_actionExpression, actionBean );
+            actions = (String)evaluation.getValue();
+            if ( actions == null )
+            {
+                throw new ELException("Actions expression '${" + m_targetExpression + "} ' returned null!");
+            }
+        }
+
+        // Instantiate the permission!
+        Permission perm = null;
+        
+        // Filthy hack to use caching for Permission classes we know about
+        if ( PagePermission.class.isAssignableFrom(m_clazz) )
+        {
+            return PermissionFactory.getPagePermission(target,actions);
+        }
+        if ( WikiPermission.class.isAssignableFrom(m_clazz) )
+        {
+            return PermissionFactory.getWikiPermission(target, actions);
+        }
+        if ( GroupPermission.class.isAssignableFrom(m_clazz) )
+        {
+            return PermissionFactory.getGroupPermission(target, actions);
+        }
+        
+        try
+        {
+            if (hasOneParameter)
+            {
+                Constructor c = m_clazz.getConstructor(new Class[] { String.class });
+                perm = (Permission) c.newInstance(new Object[] { target });
+            }
+            else
+            {
+                Constructor c = m_clazz.getConstructor(new Class[] { String.class, String.class });
+                perm = (Permission) c.newInstance(new Object[] { target, actions });
+            }
+        }
+        catch (Exception e)
+        {
+            e.printStackTrace();
+            throw new ELException("Could not evaluate permission info: " + e.getMessage());
+        }
+
+        return perm;
+    }
+
+}

Added: incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/src/com/ecyrd/jspwiki/action/GroupActionBean.java
URL: http://svn.apache.org/viewvc/incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/src/com/ecyrd/jspwiki/action/GroupActionBean.java?rev=630500&view=auto
==============================================================================
--- incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/src/com/ecyrd/jspwiki/action/GroupActionBean.java (added)
+++ incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/src/com/ecyrd/jspwiki/action/GroupActionBean.java Sat Feb 23 10:33:08 2008
@@ -0,0 +1,124 @@
+package com.ecyrd.jspwiki.action;
+
+import java.security.Principal;
+import java.util.ArrayList;
+import java.util.List;
+
+import net.sourceforge.stripes.action.*;
+import net.sourceforge.stripes.exception.StripesRuntimeException;
+import net.sourceforge.stripes.validation.*;
+
+import org.apache.commons.lang.ArrayUtils;
+
+import com.ecyrd.jspwiki.WikiEngine;
+import com.ecyrd.jspwiki.auth.WikiSecurityException;
+import com.ecyrd.jspwiki.auth.authorize.Group;
+import com.ecyrd.jspwiki.auth.authorize.GroupManager;
+import com.ecyrd.jspwiki.auth.permissions.GroupPermission;
+
+@WikiRequestContext("group")
+@UrlBinding("/Group.action")
+public class GroupActionBean extends AbstractActionBean implements GroupContext
+{
+    private Group m_group = null;
+
+    private List<Principal> m_members = new ArrayList<Principal>();
+
+    public Group getGroup()
+    {
+        return m_group;
+    }
+
+    public List<Principal> getMembers()
+    {
+        return m_members;
+    }
+
+    public boolean isNew()
+    {
+        return (m_group.getCreated() == null);
+    }
+
+    @Validate(required = true)
+    public void setGroup(Group group)
+    {
+        m_group = group;
+        m_members.clear();
+        m_members.addAll( m_group.getMembers() );
+    }
+
+    /**
+     * Sets the member list for the ActionBean, and for the underlying Group.
+     * @param members the members, separated by carriage returns
+     */
+    @Validate(required = true, converter=OneToManyTypeConverter.class)
+    public void setMembers(List<Principal> members)
+    {
+        m_members = members;
+        m_group.clear();
+        for ( Principal member : members ) 
+        {
+            m_group.add( member );
+        }
+    }
+
+    @ValidationMethod(on = "save")
+    public void validateBeforeSave(ValidationErrors errors)
+    {
+        // Name cannot be one of the restricted names either
+        String name = m_group.getName();
+        if (ArrayUtils.contains(Group.RESTRICTED_GROUPNAMES, name )); 
+        {
+            errors.add("group", new SimpleError("The group name '" + name + "' is illegal. Choose another."));
+        }
+    }
+
+    /**
+     * Handler method for that deletes the group supplied by {@link #getGroup()}. If the GroupManager
+     * throws a WikiSecurityException because it cannot delete the group for some reason, the 
+     * exception is re-thrown as a StripesRuntimeException.
+     * <code>/Group.jsp</code>.
+     * @throws StripesRuntimeException if the group cannot be deleted for any reason
+     */
+    @DefaultHandler
+    @HandlesEvent("delete")
+    @EventPermission(permissionClass = GroupPermission.class, target="${group.qualifiedName}", actions=GroupPermission.DELETE_ACTION)
+    public Resolution delete() throws StripesRuntimeException
+    {
+        try 
+        {
+            WikiEngine engine = getEngine();
+            GroupManager groupMgr = engine.getGroupManager();
+            groupMgr.removeGroup( m_group.getName() );
+        }
+        catch ( WikiSecurityException e )
+        {
+            throw new StripesRuntimeException(e);
+        }
+        return new RedirectResolution(ViewActionBean.class);
+    }
+    
+    @HandlesEvent("save")
+    @EventPermission(permissionClass = GroupPermission.class, target = "${group.qualifiedName}", actions = GroupPermission.EDIT_ACTION)
+    public Resolution save() throws WikiSecurityException
+    {
+        GroupManager mgr = getContext().getWikiEngine().getGroupManager();
+        mgr.setGroup(getContext().getWikiSession(), m_group);
+        RedirectResolution r = new RedirectResolution( "/Group.jsp" );
+        r.addParameter("group",m_group.getName());
+        return r;
+    }
+    
+    /**
+     * Default handler method for "view" events that simply forwards the user to
+     * <code>/Group.jsp</code>.
+     */
+    @DefaultHandler
+    @HandlesEvent("view")
+    @EventPermission(permissionClass = GroupPermission.class, target = "${group.qualifiedName}", actions = GroupPermission.VIEW_ACTION)
+    public Resolution view()
+    {
+        return new ForwardResolution("/Group,jsp");
+    }
+
+}

Added: incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/src/com/ecyrd/jspwiki/action/GroupContext.java
URL: http://svn.apache.org/viewvc/incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/src/com/ecyrd/jspwiki/action/GroupContext.java?rev=630500&view=auto
==============================================================================
--- incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/src/com/ecyrd/jspwiki/action/GroupContext.java (added)
+++ incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/src/com/ecyrd/jspwiki/action/GroupContext.java Sat Feb 23 10:33:08 2008
@@ -0,0 +1,17 @@
+package com.ecyrd.jspwiki.action;
+
+import com.ecyrd.jspwiki.auth.authorize.Group;
+
+/**
+ * Represents an ActionBean that acts on a Group.
+ * @author Andrew Jaquith
+ *
+ */
+public interface GroupContext
+{
+
+    public abstract Group getGroup();
+
+    public abstract void setGroup(Group group);
+
+}

Added: incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/src/com/ecyrd/jspwiki/action/InstallActionBean.java
URL: http://svn.apache.org/viewvc/incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/src/com/ecyrd/jspwiki/action/InstallActionBean.java?rev=630500&view=auto
==============================================================================
--- incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/src/com/ecyrd/jspwiki/action/InstallActionBean.java (added)
+++ incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/src/com/ecyrd/jspwiki/action/InstallActionBean.java Sat Feb 23 10:33:08 2008
@@ -0,0 +1,37 @@
+package com.ecyrd.jspwiki.action;
+
+import java.security.Permission;
+
+import net.sourceforge.stripes.action.UrlBinding;
+
+import com.ecyrd.jspwiki.WikiEngine;
+import com.ecyrd.jspwiki.auth.NoSuchPrincipalException;
+import com.ecyrd.jspwiki.auth.UserManager;
+import com.ecyrd.jspwiki.auth.permissions.AllPermission;
+import com.ecyrd.jspwiki.auth.user.UserDatabase;
+import com.ecyrd.jspwiki.ui.Installer;
+
+@WikiRequestContext("install")
+@UrlBinding("/Install.action")
+public class InstallActionBean extends AbstractActionBean
+{
+    public Permission requiredPermission()
+    {
+        // See if admin users exists
+        Permission perm = null;
+        WikiEngine engine = getContext().getWikiEngine();
+        try
+        {
+            UserManager userMgr = engine.getUserManager();
+            UserDatabase userDb = userMgr.getUserDatabase();
+            userDb.findByLoginName( Installer.ADMIN_ID );
+            perm = new AllPermission( engine.getApplicationName() );
+        }
+        catch ( NoSuchPrincipalException e )
+        {
+            // No admin user; thus, no permission required
+        }
+            
+        return perm;
+    }
+}

Added: incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/src/com/ecyrd/jspwiki/action/LoginActionBean.java
URL: http://svn.apache.org/viewvc/incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/src/com/ecyrd/jspwiki/action/LoginActionBean.java?rev=630500&view=auto
==============================================================================
--- incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/src/com/ecyrd/jspwiki/action/LoginActionBean.java (added)
+++ incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/src/com/ecyrd/jspwiki/action/LoginActionBean.java Sat Feb 23 10:33:08 2008
@@ -0,0 +1,26 @@
+package com.ecyrd.jspwiki.action;
+
+import net.sourceforge.stripes.action.HandlesEvent;
+import net.sourceforge.stripes.action.Resolution;
+import net.sourceforge.stripes.action.UrlBinding;
+
+import com.ecyrd.jspwiki.auth.permissions.WikiPermission;
+
+@WikiRequestContext("login")
+@UrlBinding("/Login.action")
+public class LoginActionBean extends AbstractActionBean
+{
+    @HandlesEvent("login")
+    @EventPermission(permissionClass=WikiPermission.class, target="${engine.applicationName}", actions=WikiPermission.LOGIN_ACTION)
+    public Resolution login()
+    {
+        return null;
+    }
+
+    @HandlesEvent("logout")
+    @EventPermission(permissionClass=WikiPermission.class, target="${engine.applicationName}", actions=WikiPermission.LOGIN_ACTION)
+    public Resolution logout()
+    {
+        return null;
+    }
+}

Added: incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/src/com/ecyrd/jspwiki/action/MessageActionBean.java
URL: http://svn.apache.org/viewvc/incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/src/com/ecyrd/jspwiki/action/MessageActionBean.java?rev=630500&view=auto
==============================================================================
--- incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/src/com/ecyrd/jspwiki/action/MessageActionBean.java (added)
+++ incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/src/com/ecyrd/jspwiki/action/MessageActionBean.java Sat Feb 23 10:33:08 2008
@@ -0,0 +1,10 @@
+package com.ecyrd.jspwiki.action;
+
+import net.sourceforge.stripes.action.UrlBinding;
+
+@WikiRequestContext("message")
+@UrlBinding("/Message.action")
+public class MessageActionBean extends AbstractActionBean
+{
+
+}

Added: incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/src/com/ecyrd/jspwiki/action/NewBlogEntryActionBean.java
URL: http://svn.apache.org/viewvc/incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/src/com/ecyrd/jspwiki/action/NewBlogEntryActionBean.java?rev=630500&view=auto
==============================================================================
--- incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/src/com/ecyrd/jspwiki/action/NewBlogEntryActionBean.java (added)
+++ incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/src/com/ecyrd/jspwiki/action/NewBlogEntryActionBean.java Sat Feb 23 10:33:08 2008
@@ -0,0 +1,20 @@
+package com.ecyrd.jspwiki.action;
+
+import net.sourceforge.stripes.action.HandlesEvent;
+import net.sourceforge.stripes.action.Resolution;
+import net.sourceforge.stripes.action.UrlBinding;
+
+import com.ecyrd.jspwiki.WikiContext;
+import com.ecyrd.jspwiki.auth.permissions.WikiPermission;
+
+@WikiRequestContext("newBlogEntry")
+@UrlBinding("/NewBlogEntry.action")
+public class NewBlogEntryActionBean extends WikiContext
+{
+    @HandlesEvent("create")
+    @EventPermission(permissionClass=WikiPermission.class, target="${engine.applicationName}", actions=WikiPermission.CREATE_PAGES_ACTION)
+    public Resolution create()
+    {
+        return null;
+    }
+}

Added: incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/src/com/ecyrd/jspwiki/action/NewPageActionBean.java
URL: http://svn.apache.org/viewvc/incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/src/com/ecyrd/jspwiki/action/NewPageActionBean.java?rev=630500&view=auto
==============================================================================
--- incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/src/com/ecyrd/jspwiki/action/NewPageActionBean.java (added)
+++ incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/src/com/ecyrd/jspwiki/action/NewPageActionBean.java Sat Feb 23 10:33:08 2008
@@ -0,0 +1,20 @@
+package com.ecyrd.jspwiki.action;
+
+import net.sourceforge.stripes.action.HandlesEvent;
+import net.sourceforge.stripes.action.Resolution;
+import net.sourceforge.stripes.action.UrlBinding;
+
+import com.ecyrd.jspwiki.WikiContext;
+import com.ecyrd.jspwiki.auth.permissions.WikiPermission;
+
+@WikiRequestContext("newPage")
+@UrlBinding("/NewPage.action")
+public class NewPageActionBean extends WikiContext
+{
+    @HandlesEvent("create")
+    @EventPermission(permissionClass=WikiPermission.class, target="${engine.applicationName}", actions=WikiPermission.CREATE_PAGES_ACTION)
+    public Resolution create()
+    {
+        return null;
+    }
+}

Added: incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/src/com/ecyrd/jspwiki/action/NoneActionBean.java
URL: http://svn.apache.org/viewvc/incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/src/com/ecyrd/jspwiki/action/NoneActionBean.java?rev=630500&view=auto
==============================================================================
--- incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/src/com/ecyrd/jspwiki/action/NoneActionBean.java (added)
+++ incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/src/com/ecyrd/jspwiki/action/NoneActionBean.java Sat Feb 23 10:33:08 2008
@@ -0,0 +1,17 @@
+package com.ecyrd.jspwiki.action;
+
+import com.ecyrd.jspwiki.WikiContext;
+
+/**
+ * Represents a dummy WikiContext that doesn't bind to a URL, and doesn't
+ * contain any embedded logic. When the NoneActionBean class is passed as a
+ * parameter to {@link WikiActionBeanContext#getURL(Class, String)}, for
+ * example, the resulting URL does not prepend anything before the page.
+ * 
+ * @author Andrew Jaquith
+ * 
+ */
+@WikiRequestContext("none")
+public class NoneActionBean extends WikiContext
+{
+}

Added: incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/src/com/ecyrd/jspwiki/action/PageInfoActionBean.java
URL: http://svn.apache.org/viewvc/incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/src/com/ecyrd/jspwiki/action/PageInfoActionBean.java?rev=630500&view=auto
==============================================================================
--- incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/src/com/ecyrd/jspwiki/action/PageInfoActionBean.java (added)
+++ incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/src/com/ecyrd/jspwiki/action/PageInfoActionBean.java Sat Feb 23 10:33:08 2008
@@ -0,0 +1,20 @@
+package com.ecyrd.jspwiki.action;
+
+import net.sourceforge.stripes.action.HandlesEvent;
+import net.sourceforge.stripes.action.Resolution;
+import net.sourceforge.stripes.action.UrlBinding;
+
+import com.ecyrd.jspwiki.WikiContext;
+import com.ecyrd.jspwiki.auth.permissions.PagePermission;
+
+@WikiRequestContext("info")
+@UrlBinding("/PageInfo.action")
+public class PageInfoActionBean extends WikiContext
+{
+    @HandlesEvent("info")
+    @EventPermission(permissionClass=PagePermission.class, target="${page.qualifiedName}", actions=PagePermission.VIEW_ACTION)
+    public Resolution info()
+    {
+        return null;
+    }
+}

Added: incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/src/com/ecyrd/jspwiki/action/PageModifiedActionBean.java
URL: http://svn.apache.org/viewvc/incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/src/com/ecyrd/jspwiki/action/PageModifiedActionBean.java?rev=630500&view=auto
==============================================================================
--- incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/src/com/ecyrd/jspwiki/action/PageModifiedActionBean.java (added)
+++ incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/src/com/ecyrd/jspwiki/action/PageModifiedActionBean.java Sat Feb 23 10:33:08 2008
@@ -0,0 +1,20 @@
+package com.ecyrd.jspwiki.action;
+
+import net.sourceforge.stripes.action.HandlesEvent;
+import net.sourceforge.stripes.action.Resolution;
+import net.sourceforge.stripes.action.UrlBinding;
+
+import com.ecyrd.jspwiki.WikiContext;
+import com.ecyrd.jspwiki.auth.permissions.PagePermission;
+
+@WikiRequestContext("conflict")
+@UrlBinding("/PageModified.action")
+public class PageModifiedActionBean extends WikiContext
+{
+    @HandlesEvent("conflict")
+    @EventPermission(permissionClass=PagePermission.class, target="${page.qualifiedName}", actions=PagePermission.VIEW_ACTION)
+    public Resolution conflict()
+    {
+        return null;
+    }
+}

Added: incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/src/com/ecyrd/jspwiki/action/PreviewActionBean.java
URL: http://svn.apache.org/viewvc/incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/src/com/ecyrd/jspwiki/action/PreviewActionBean.java?rev=630500&view=auto
==============================================================================
--- incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/src/com/ecyrd/jspwiki/action/PreviewActionBean.java (added)
+++ incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/src/com/ecyrd/jspwiki/action/PreviewActionBean.java Sat Feb 23 10:33:08 2008
@@ -0,0 +1,32 @@
+package com.ecyrd.jspwiki.action;
+
+import net.sourceforge.stripes.action.*;
+
+import com.ecyrd.jspwiki.WikiContext;
+import com.ecyrd.jspwiki.auth.permissions.PagePermission;
+
+/**
+ * Displays the wiki page a users requested, resolving special page names and
+ * redirecting if needed.
+ * @author Andrew Jaquith
+ *
+ */
+@WikiRequestContext("preview")
+@UrlBinding("/Preview.action")
+public class PreviewActionBean extends WikiContext
+{
+    /**
+     * Default handler that simply forwards the user back to the same page. 
+     * Every ActionBean needs a default handler to function properly, so we use
+     * this (very simple) one.
+     * @return a forward resolution back to the same page
+     */
+    @DefaultHandler
+    @HandlesEvent("preview")
+    @EventPermission(permissionClass=PagePermission.class, target="${page.qualifiedName}", actions=PagePermission.VIEW_ACTION)
+    public Resolution view()
+    {
+        return new ForwardResolution(PreviewActionBean.class);
+    }
+    
+}

Added: incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/src/com/ecyrd/jspwiki/action/RSSActionBean.java
URL: http://svn.apache.org/viewvc/incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/src/com/ecyrd/jspwiki/action/RSSActionBean.java?rev=630500&view=auto
==============================================================================
--- incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/src/com/ecyrd/jspwiki/action/RSSActionBean.java (added)
+++ incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/src/com/ecyrd/jspwiki/action/RSSActionBean.java Sat Feb 23 10:33:08 2008
@@ -0,0 +1,45 @@
+package com.ecyrd.jspwiki.action;
+
+import net.sourceforge.stripes.action.HandlesEvent;
+import net.sourceforge.stripes.action.Resolution;
+import net.sourceforge.stripes.action.UrlBinding;
+
+import com.ecyrd.jspwiki.WikiContext;
+import com.ecyrd.jspwiki.WikiEngine;
+import com.ecyrd.jspwiki.WikiPage;
+import com.ecyrd.jspwiki.auth.permissions.PagePermission;
+
+@WikiRequestContext("rss")
+@UrlBinding("/rss.action")
+public class RSSActionBean extends WikiContext
+{
+    /**
+     * Retrieves a new RSSActionBean for the given WikiPage.
+     * 
+     * @param engine
+     *            The WikiEngine that is handling the request.
+     * @param page
+     *            The WikiPage. If you want to create an RSSActionBean for an older
+     *            version of a page, you must use this constructor.
+     */
+    public static RSSActionBean getRSSActionBean(WikiEngine engine, WikiPage page)
+    {
+        if (engine == null)
+        {
+            throw new IllegalArgumentException("Parameter engine must not be null.");
+        }
+        WikiActionBeanContext context = new WikiActionBeanContext();
+        context.setWikiEngine( engine );
+        RSSActionBean rssBean = new RSSActionBean();
+        rssBean.setContext(context);
+        rssBean.setPage(page);
+        return rssBean;
+    }
+    
+    @HandlesEvent("rss")
+    @EventPermission(permissionClass=PagePermission.class, target="${page.qualifiedName}", actions=PagePermission.VIEW_ACTION)
+    public Resolution rss()
+    {
+        return null;
+    }
+}

Added: incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/src/com/ecyrd/jspwiki/action/RenameActionBean.java
URL: http://svn.apache.org/viewvc/incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/src/com/ecyrd/jspwiki/action/RenameActionBean.java?rev=630500&view=auto
==============================================================================
--- incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/src/com/ecyrd/jspwiki/action/RenameActionBean.java (added)
+++ incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/src/com/ecyrd/jspwiki/action/RenameActionBean.java Sat Feb 23 10:33:08 2008
@@ -0,0 +1,152 @@
+package com.ecyrd.jspwiki.action;
+
+import javax.servlet.http.HttpServletRequest;
+
+import net.sourceforge.stripes.action.HandlesEvent;
+import net.sourceforge.stripes.action.RedirectResolution;
+import net.sourceforge.stripes.action.Resolution;
+import net.sourceforge.stripes.action.UrlBinding;
+import net.sourceforge.stripes.validation.SimpleError;
+import net.sourceforge.stripes.validation.Validate;
+import net.sourceforge.stripes.validation.ValidationErrors;
+import net.sourceforge.stripes.validation.ValidationMethod;
+
+import org.apache.log4j.Logger;
+
+import com.ecyrd.jspwiki.WikiContext;
+import com.ecyrd.jspwiki.WikiEngine;
+import com.ecyrd.jspwiki.WikiException;
+import com.ecyrd.jspwiki.auth.permissions.PagePermission;
+
+/**
+ * <p>
+ * Renames a wiki page. This ActionBean parses and extracts two request
+ * parameters:
+ * </p>
+ * <h3>Request parameters</h3>
+ * <ul>
+ * <li><code>page</code> - the existing page name. Returned by
+ * {@ link #getPage()}
+ * <li><code>renameTo</code> - the proposed new name for the page. This
+ * parameter is required, and it is a validation error if not</li>
+ * <li><code>changeReferences</code> - whether to change all referring pages'
+ * references to this page also. If not supplied, this parameter defaults to
+ * <code>false</code></li>
+ * </ul>
+ * <h3>Actions</h3>
+ * <ul>
+ * <li><code>rename</code> - executes the rename action, using the value of
+ * field <code>renameTo</code> as the new name</li>
+ * </ul>
+ * <h3>Special validation</h3>
+ * <p>
+ * Before the <code>rename</code> handler executes, the validation method
+ * {@link #validateBeforeRename(ValidationErrors)} checks to make sure that the
+ * proposed page name (supplied by {@link #setRenameTo(String)} is not already
+ * used by an existing wiki page.
+ * </p>
+ * 
+ * @author Andrew Jaquith
+ */
+@WikiRequestContext("rename")
+@UrlBinding("/Rename.action")
+public class RenameActionBean extends WikiContext
+{
+    private static final Logger log = Logger.getLogger(RenameActionBean.class);
+
+    private boolean m_changeReferences = false;
+
+    private String m_renameTo = null;
+
+    /**
+     * Returns the proposed new name for the page; defaults to <code>null</code>
+     * if not set.
+     * 
+     * @return the proposed new page name
+     */
+    public String getRenameTo()
+    {
+        return m_renameTo;
+    }
+
+    /**
+     * Returns <code>true</code> if the rename operation should also change
+     * references to/from the page; <code>false</code> otherwise.
+     * 
+     * @return the result
+     */
+    public boolean isChangeReferences()
+    {
+        return m_changeReferences;
+    }
+
+    /**
+     * Handler method that renames the current wiki page. If the rename
+     * operation does not succeed for any reason, this method throws a
+     * {@link com.ecyrd.jspwiki.WikiException}.
+     * 
+     * @return a redirection to the renamed wiki page
+     * @throws WikiException
+     *             if the page cannot be renamed
+     */
+    @HandlesEvent("rename")
+    @EventPermission(permissionClass = PagePermission.class, target = "${page.qualifiedName}", actions = PagePermission.RENAME_ACTION)
+    public Resolution rename() throws WikiException
+    {
+        WikiEngine engine = this.getEngine();
+        String renameFrom = getPage().getName();
+        HttpServletRequest request = getContext().getRequest();
+        log.info("Page rename request for page '" + renameFrom + "' to new name '" + m_renameTo + "' from "
+                 + request.getRemoteAddr() + " by " + request.getRemoteUser());
+        String renamedTo = engine.renamePage(this, renameFrom, m_renameTo, m_changeReferences);
+        log.info("Page successfully renamed to '" + renamedTo + "'");
+        RedirectResolution r = new RedirectResolution(ViewActionBean.class);
+        r.addParameter("page", renamedTo);
+        return r;
+    }
+
+    /**
+     * Tells JSPWiki to change references to/from the page when the
+     * {@link #rename()} handler is executed. If not supplied, defaults to
+     * <code>false</code>.
+     * 
+     * @param changeReferences
+     *            the decision
+     */
+    @Validate(required = false)
+    public void setChangeReferences(boolean changeReferences)
+    {
+        m_changeReferences = changeReferences;
+    }
+
+    /**
+     * Sets the new name for the page, which will be set when the
+     * {@link #rename()} handler is executed.
+     * 
+     * @param pageName
+     *            the new page name
+     */
+    @Validate(required = true, minlength = 1, maxlength = 100, expression = "page.name != renameTo")
+    public void setRenameTo(String pageName)
+    {
+        m_renameTo = pageName;
+    }
+
+    /**
+     * Before the {@link #rename()} handler method executes, this method
+     * validates that the proposed new name does not collide with an existing
+     * page.
+     * 
+     * @param errors
+     *            the current set of validation errors for this ActionBean
+     */
+    @ValidationMethod(on = "rename")
+    public void validateBeforeRename(ValidationErrors errors)
+    {
+        if (getContext().getWikiEngine().pageExists(m_renameTo))
+        {
+            errors.add("renameTo", new SimpleError("The page name '" + m_renameTo + "' already exists. Choose another."));
+        }
+    }
+
+}

Added: incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/src/com/ecyrd/jspwiki/action/SearchActionBean.java
URL: http://svn.apache.org/viewvc/incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/src/com/ecyrd/jspwiki/action/SearchActionBean.java?rev=630500&view=auto
==============================================================================
--- incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/src/com/ecyrd/jspwiki/action/SearchActionBean.java (added)
+++ incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/src/com/ecyrd/jspwiki/action/SearchActionBean.java Sat Feb 23 10:33:08 2008
@@ -0,0 +1,9 @@
+package com.ecyrd.jspwiki.action;
+
+import net.sourceforge.stripes.action.UrlBinding;
+
+@WikiRequestContext("find")
+@UrlBinding("/Search.action")
+public class SearchActionBean extends AbstractActionBean
+{
+}

Added: incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/src/com/ecyrd/jspwiki/action/UploadActionBean.java
URL: http://svn.apache.org/viewvc/incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/src/com/ecyrd/jspwiki/action/UploadActionBean.java?rev=630500&view=auto
==============================================================================
--- incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/src/com/ecyrd/jspwiki/action/UploadActionBean.java (added)
+++ incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/src/com/ecyrd/jspwiki/action/UploadActionBean.java Sat Feb 23 10:33:08 2008
@@ -0,0 +1,20 @@
+package com.ecyrd.jspwiki.action;
+
+import net.sourceforge.stripes.action.HandlesEvent;
+import net.sourceforge.stripes.action.Resolution;
+import net.sourceforge.stripes.action.UrlBinding;
+
+import com.ecyrd.jspwiki.WikiContext;
+import com.ecyrd.jspwiki.auth.permissions.PagePermission;
+
+@WikiRequestContext("upload")
+@UrlBinding("/Upload.action")
+public class UploadActionBean extends WikiContext
+{
+    @HandlesEvent("diff")
+    @EventPermission(permissionClass=PagePermission.class, target="${page.qualifiedName}", actions=PagePermission.UPLOAD_ACTION)
+    public Resolution upload()
+    {
+        return null;
+    }
+}

Added: incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/src/com/ecyrd/jspwiki/action/UserPreferencesActionBean.java
URL: http://svn.apache.org/viewvc/incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/src/com/ecyrd/jspwiki/action/UserPreferencesActionBean.java?rev=630500&view=auto
==============================================================================
--- incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/src/com/ecyrd/jspwiki/action/UserPreferencesActionBean.java (added)
+++ incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/src/com/ecyrd/jspwiki/action/UserPreferencesActionBean.java Sat Feb 23 10:33:08 2008
@@ -0,0 +1,94 @@
+package com.ecyrd.jspwiki.action;
+
+import java.security.Principal;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import net.sourceforge.stripes.action.*;
+import net.sourceforge.stripes.validation.Validate;
+
+import com.ecyrd.jspwiki.auth.login.CookieAssertionLoginModule;
+import com.ecyrd.jspwiki.auth.permissions.WikiPermission;
+
+/**
+ * @author Andrew Jaquith
+ */
+@WikiRequestContext("prefs")
+@UrlBinding("/UserPreferences.action")
+public class UserPreferencesActionBean extends AbstractActionBean
+{
+    private String m_assertedName = null;
+
+    /**
+     * Clears the user's asserted name by removing the cookie from the user's
+     * session, then logs out the user by redirecting to <code>/Login.jsp</code>.
+     * 
+     * @return a redirection to the logout page
+     */
+    @HandlesEvent("clearAssertedName")
+    @EventPermission(permissionClass=WikiPermission.class, target="${engine.applicationName}", actions=WikiPermission.EDIT_PREFERENCES_ACTION)
+    public Resolution clearAssertedName()
+    {
+        HttpServletResponse response = getContext().getResponse();
+        CookieAssertionLoginModule.clearUserCookie(response);
+        return new RedirectResolution("/Logout.jsp");
+    }
+
+    /**
+     * Redirects the user to their favorites page.
+     * 
+     * @return a redirection to the favorites page
+     */
+    @HandlesEvent("editFavorites")
+    public Resolution editFavorites()
+    {
+        Principal principal = this.getCurrentUser();
+        return new RedirectResolution("/Edit.jsp?"+principal.getName()+"Favorites");
+    }
+    
+    /**
+     * Sets the user's asserted name by setting a cookie in the user's session,
+     * then redirects to the wiki front page. This method will <em>not</em>
+     * set the cookie if the user is already authenticated.
+     * 
+     * @return a redirection to the front page
+     */
+    @DefaultHandler
+    @HandlesEvent("createAssertedName")
+    @EventPermission(permissionClass=WikiPermission.class, target="${engine.applicationName}", actions=WikiPermission.EDIT_PREFERENCES_ACTION)
+    public Resolution createAssertedName()
+    {
+        if ( !getWikiSession().isAuthenticated() )
+        {
+            HttpServletRequest request = getContext().getRequest();
+            HttpServletResponse response = getContext().getResponse();
+            String assertedName = request.getParameter("assertedName");
+            CookieAssertionLoginModule.setUserCookie(response, assertedName);
+        }
+        return new RedirectResolution("/");
+    }
+
+    /**
+     * Returns the asserted name for the user prefererences.
+     * 
+     * @return the asserted name
+     */
+    public String getAssertedName()
+    {
+        return m_assertedName;
+    }
+
+    /**
+     * Sets the asserted name for the user prefererences.
+     * 
+     * @param name
+     *            the asserted name
+     */
+    @Validate(required=true, on="createAssertedName")
+    public void setAssertedName(String name)
+    {
+        m_assertedName = name;
+    }
+
+}

Added: incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/src/com/ecyrd/jspwiki/action/UserProfileActionBean.java
URL: http://svn.apache.org/viewvc/incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/src/com/ecyrd/jspwiki/action/UserProfileActionBean.java?rev=630500&view=auto
==============================================================================
--- incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/src/com/ecyrd/jspwiki/action/UserProfileActionBean.java (added)
+++ incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/src/com/ecyrd/jspwiki/action/UserProfileActionBean.java Sat Feb 23 10:33:08 2008
@@ -0,0 +1,214 @@
+package com.ecyrd.jspwiki.action;
+
+import net.sourceforge.stripes.action.*;
+import net.sourceforge.stripes.controller.LifecycleStage;
+import net.sourceforge.stripes.validation.*;
+
+import com.ecyrd.jspwiki.WikiEngine;
+import com.ecyrd.jspwiki.WikiSession;
+import com.ecyrd.jspwiki.auth.AuthenticationManager;
+import com.ecyrd.jspwiki.auth.NoSuchPrincipalException;
+import com.ecyrd.jspwiki.auth.UserManager;
+import com.ecyrd.jspwiki.auth.login.CookieAssertionLoginModule;
+import com.ecyrd.jspwiki.auth.permissions.WikiPermission;
+import com.ecyrd.jspwiki.auth.user.UserDatabase;
+import com.ecyrd.jspwiki.auth.user.UserProfile;
+
+/**
+ * @author Andrew Jaquith
+ */
+@WikiRequestContext("profile")
+@UrlBinding("/UserProfile.action")
+public class UserProfileActionBean extends AbstractActionBean
+{
+    private UserProfile m_profile = null;
+    private String m_passwordAgain = null;
+
+    public String getPasswordAgain()
+    {
+        return m_passwordAgain;
+    }
+    
+    public UserProfile getProfile() 
+    {
+        return m_profile;
+    }
+    
+    /**
+     * Before user-supplied parameters are bound to the ActionBean, this method loads the
+     * UserProfile.
+     * @return <code>null</code>, always
+     */
+    @Before(LifecycleStage.BindingAndValidation)
+    public Resolution init()
+    {
+        // Retrieve the user profile
+        WikiEngine engine = getEngine();
+        WikiSession session = getWikiSession();
+        UserManager manager = engine.getUserManager();
+        m_profile = manager.getUserProfile(session);
+        
+        // Null out the password, so that we don't re-encrypt it by accident
+        m_profile.setPassword( null );
+        return null;
+    }
+
+    /**
+     * Saves the user profile to the wiki's UserDatabase.
+     * 
+     * @return a {@link net.sourceforge.stripes.action.ForwardResolution} back
+     *         to itself if the save activity returned errors, or
+     *         <code>null</code> otherwise
+     */
+    @HandlesEvent("save")
+    @EventPermission(permissionClass=WikiPermission.class, target="${engine.applicationName}", actions=WikiPermission.EDIT_PROFILE_ACTION)
+    public Resolution save()
+    {
+        Resolution r = null;
+        WikiActionBeanContext context = getContext();
+        try
+        {
+            // Save the profile
+            WikiEngine engine = getEngine();
+            engine.getUserManager().setUserProfile( getWikiSession(), m_profile);
+            CookieAssertionLoginModule.setUserCookie(context.getResponse(), m_profile.getFullname());
+            r = new RedirectResolution("/");
+        }
+        catch (Exception e)
+        {
+            ValidationErrors errors = context.getValidationErrors();
+            errors.addGlobalError( new LocalizableError( "saveError", e.getMessage() ) );
+            r = new ForwardResolution(UserProfileActionBean.class);
+        }
+        return r;
+    }
+
+    /**
+     * <p>
+     * Default handler method that views the user's profile. This method 
+     * loads the current user's UserProfile and sets the
+     * ActionBean's e-mail and fullName properties. It will override
+     * user-supplied values that should not change, namely the
+     * <code>loginName</code> and <code>password</code> fields
+     * if AuthenticationManager is using container-managed authentication
+     * and accounts aren't shared with JSPWiki. It will also
+     * set the <code>e-mail</code> field if a value was not supplied by the
+     * user as a request parameter. If a profile does not already exist, 
+     * this method does nothing, with
+     * the caveat that if the user is authenticated via the container, the
+     * container identifer (the value returned by the <code>getRemoteUser</code>
+     * or the <code>getUserPrincipal</code>).
+     * </p>
+     */
+
+    public void setPasswordAgain(String password)
+    {
+        m_passwordAgain = password;
+    }
+    
+    @ValidateNestedProperties( {
+                               @Validate(field="loginName", required=true, maxlength=100), 
+                               @Validate(field="fullname", required=true, maxlength=100),
+                               @Validate(field="password", required = false, minlength = 8, maxlength = 100),
+                               @Validate(field="email", required = false, converter = EmailTypeConverter.class) } )
+    public void setProfile(UserProfile profile)
+    {
+        m_profile = profile;
+    }
+    
+    /**
+     * If the user profile is new, this method verifies that the user
+     * has supplied matching passwords.
+     * @param errors
+     *            the current validation errors for this ActionBean
+     */
+    @ValidationMethod(when = ValidationState.ALWAYS)
+    public void validatePasswords(ValidationErrors errors)
+    {
+        // All new profiles must have a supplied password
+        if ( m_profile.isNew() )
+        {
+            if ( m_profile.getPassword() == null )
+            {
+                errors.add( "profile.password", new ScopedLocalizableError( "validation.required", "valueNotPresent" ) );
+            }
+        }
+        
+        // If a password was supplied, the same value must also have been passed to passwordAgain
+        if ( m_profile.getPassword() != null )
+        {
+            if ( !m_profile.getPassword().equals( m_passwordAgain ) )
+            {
+                errors.add( "profile.password", new ScopedLocalizableError( "validation.required", "noPasswordMatch" ) );
+            }
+        }
+    }
+
+
+    /**
+     * After all fields validate correctly, this method verifies that the user
+     * has the correct permissions to save the UserProfile, and checks that the
+     * supplied full name or login name don't collide with those used by
+     * somebody else.
+     * 
+     * @param errors
+     *            the current validation errors for this ActionBean
+     */
+    @ValidationMethod(when = ValidationState.NO_ERRORS)
+    public void validateNoCollision(ValidationErrors errors)
+    {
+        WikiEngine engine = getEngine();
+        WikiSession session = getWikiSession();
+        UserManager manager = getEngine().getUserManager();
+        UserDatabase database = manager.getUserDatabase();
+
+        // Locate the old user profile
+        UserProfile oldProfile = manager.getUserProfile( session );
+
+        // If container authenticated, and accounts not shared, override the login name and password
+        // The login name should always be the one provided by the container
+        AuthenticationManager authMgr = engine.getAuthenticationManager();
+        if ( authMgr.isContainerAuthenticated() && !manager.getUserDatabase().isSharedWithContainer() )
+        {
+            m_profile.setLoginName( oldProfile.getLoginName() );
+            m_profile.setPassword( null );
+        }
+        
+        // User profiles that may already have fullname or loginname
+        UserProfile otherProfile;
+        try
+        {
+            otherProfile = database.findByLoginName( m_profile.getLoginName() );
+            if ( otherProfile != null && !otherProfile.equals( oldProfile ) )
+            {
+                errors.add("profile.loginName", new LocalizableError( "nameCollision" ) );
+            }
+        }
+        catch (NoSuchPrincipalException e)
+        {
+        }
+        try
+        {
+            otherProfile = database.findByFullName( m_profile.getFullname() );
+            if (otherProfile != null && !otherProfile.equals(oldProfile))
+            {
+                errors.add("profile.fullname", new LocalizableError( "nameCollision" ) );
+            }
+        }
+        catch (NoSuchPrincipalException e)
+        {
+        }
+    }
+    
+    /**
+     * Default handler that forwards the user back to itself.
+     * @return the resolution
+     */
+    @HandlesEvent("view")
+    @DefaultHandler
+    public Resolution view()
+    {
+        return new ForwardResolution(ViewActionBean.class);
+    }
+    
+}

Added: incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/src/com/ecyrd/jspwiki/action/ViewActionBean.java
URL: http://svn.apache.org/viewvc/incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/src/com/ecyrd/jspwiki/action/ViewActionBean.java?rev=630500&view=auto
==============================================================================
--- incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/src/com/ecyrd/jspwiki/action/ViewActionBean.java (added)
+++ incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/src/com/ecyrd/jspwiki/action/ViewActionBean.java Sat Feb 23 10:33:08 2008
@@ -0,0 +1,144 @@
+package com.ecyrd.jspwiki.action;
+
+import net.sourceforge.stripes.action.*;
+import net.sourceforge.stripes.controller.LifecycleStage;
+import net.sourceforge.stripes.validation.Validate;
+import net.sourceforge.stripes.validation.ValidationError;
+import net.sourceforge.stripes.validation.ValidationErrors;
+
+import org.apache.log4j.Logger;
+
+import com.ecyrd.jspwiki.WikiContext;
+import com.ecyrd.jspwiki.WikiEngine;
+import com.ecyrd.jspwiki.WikiException;
+import com.ecyrd.jspwiki.WikiPage;
+import com.ecyrd.jspwiki.auth.permissions.PagePermission;
+
+/**
+ * Displays the wiki page a users requested, resolving special page names and
+ * redirecting if needed.
+ * @author Andrew Jaquith
+ *
+ */
+@WikiRequestContext("view")
+@UrlBinding("/Wiki.action")
+public class ViewActionBean extends WikiContext
+{
+    private Logger log = Logger.getLogger(ViewActionBean.class);
+
+    public ViewActionBean()
+    {
+        super();
+    }
+
+    /**
+     * <p>After the binding and validation  {@link LifecycleStage.BindingAndValidation}
+     * lifecycle stage executes, this method determines whether the
+     * page name specified in the request is actually a special page and
+     * redirects the user if needed. If no page was specified in the request, this method
+     * sets the wiki page to the main page.</p>
+     * <p>For cases where the user specifies a page, JSPWiki needs to determine
+     * what page the user is really going to; that is, either an existing page, an alias
+     * for one, or a "special page" reference. This method considers
+     * special page names from <code>jspwiki.properties</code>, and possible aliases.
+     * To determine whether the page is a special page, this method calls
+     *  {@link com.ecyrd.jspwiki.action.WikiActionBeanFactory#getSpecialPageReference(String)}.
+     *  @return a {@link net.sourceforge.stripes.action.RedirectResolution} to the special
+     *  page's real URL, if a special page was specified, or <code>null</code> otherwise
+     */
+    @After(LifecycleStage.BindingAndValidation)
+    public Resolution resolvePage() throws WikiException
+    {
+        WikiPage page = getPage();
+        ValidationErrors errors = this.getContext().getValidationErrors();
+        WikiEngine engine = getContext().getWikiEngine();
+        
+        // If user supplied a page that doesn't exist, redirect to the "create pages" ActionBean
+        if ( errors.get("page" )!= null )
+        {
+            for (ValidationError pageParamError : errors.get("page"))
+            {
+                if ( "page".equals(pageParamError.getFieldName()) )
+                {
+                    String newPage = pageParamError.getFieldValue();
+                    log.info("User supplied page name '" + newPage + "' that doesn't exist; redirecting to create pages JSP." );
+                    RedirectResolution resolution = new RedirectResolution(NewPageActionBean.class);
+                    resolution.addParameter("page", newPage);
+                    return resolution;
+                }
+            }
+        }
+
+        // If page not supplied, try retrieving the front page to avoid NPEs
+        if (page == null)
+        {
+            if ( log.isDebugEnabled() )
+            {
+                log.debug("User did not supply a page name: defaulting to front page.");
+            }
+            if ( engine != null )
+            {
+                // Bind the front page to the action bean
+                page = engine.getPage( engine.getFrontPage() );
+                setPage(page);
+                return null;
+            }
+        }
+
+        // If page still missing, it's an error condition
+        if ( page == null )
+        {
+            throw new WikiException("Page not supplied, and WikiEngine does not define a front page! This is highly unusual.") ;
+        }
+        
+        // Ok, the user supplied a page. That's nice. But is it a special page?
+        String pageName = page.getName();
+        String specialUrl = getEngine().getWikiActionBeanFactory().getSpecialPageReference( pageName );
+        if ( specialUrl != null )
+        {
+            return new RedirectResolution( getViewURL( specialUrl ) );
+        }
+
+        // Is there an ALIAS attribute in the wiki pge?
+        specialUrl = (String)page.getAttribute( WikiPage.ALIAS );
+        if( specialUrl != null )
+        {
+            return new RedirectResolution( getViewURL( specialUrl ) );
+        }
+        
+        // Is there a REDIRECT attribute in the wiki page?
+        specialUrl = (String)page.getAttribute( WikiPage.REDIRECT );
+        if( specialUrl != null )
+        {
+            return new RedirectResolution( getViewURL( specialUrl ) );
+        }
+        
+        // If we got this far, it means the user supplied a page parameter, AND it exists
+        return null;
+    }
+
+    /**
+     * Calls the superclass {@link WikiContext#setPage(WikiPage)} method, but disables validation.
+     */
+    @Override
+    @Validate( required = false)
+    public void setPage( WikiPage page )
+    {
+        super.setPage( page );
+    }
+    
+    /**
+     * Default handler that simply forwards the user back to the same page. 
+     * Every ActionBean needs a default handler to function properly, so we use
+     * this (very simple) one.
+     * @return a forward resolution back to the same page
+     */
+    @DefaultHandler
+    @HandlesEvent("view")
+    @EventPermission(permissionClass=PagePermission.class, target="${page.qualifiedName}", actions=PagePermission.VIEW_ACTION)
+    public Resolution view()
+    {
+        return new ForwardResolution(ViewActionBean.class);
+    }
+    
+}

Added: incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/src/com/ecyrd/jspwiki/action/WikiActionBean.java
URL: http://svn.apache.org/viewvc/incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/src/com/ecyrd/jspwiki/action/WikiActionBean.java?rev=630500&view=auto
==============================================================================
--- incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/src/com/ecyrd/jspwiki/action/WikiActionBean.java (added)
+++ incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/src/com/ecyrd/jspwiki/action/WikiActionBean.java Sat Feb 23 10:33:08 2008
@@ -0,0 +1,135 @@
+package com.ecyrd.jspwiki.action;
+
+import java.security.Principal;
+import java.util.MissingResourceException;
+import java.util.ResourceBundle;
+
+import javax.servlet.http.HttpServletRequest;
+
+import net.sourceforge.stripes.action.ActionBean;
+import net.sourceforge.stripes.action.ActionBeanContext;
+
+import com.ecyrd.jspwiki.WikiEngine;
+import com.ecyrd.jspwiki.WikiSession;
+
+/**
+ * ActionBean sub-interface that includes getter/setter methods used by JSPWiki, including the
+ * request context, skin, template, URL pattern, wiki session and wiki engine.
+ * @author Andrew Jaquith
+ *
+ */
+public interface WikiActionBean extends ActionBean
+{
+    
+    /**
+     * Returns the ActionBeanContext for the WikiActionBean, using a co-variant
+     * return type of WikiActionBeanContext. 
+     */
+    public abstract WikiActionBeanContext getContext();
+
+    /**
+     * Convenience method that gets the current user. Delegates the lookup to
+     * the WikiSession associated with this WikiActionBean. May return null, in
+     * case the current user has not yet been determined; or this is an internal
+     * system. If the WikiSession has not been set, <em>always</em> returns
+     * null.
+     */
+    public abstract Principal getCurrentUser();
+    
+    /**
+     * Sets the WikiActionBeanContext for the ActionBean. This method <em>should</em>
+     * be called immediately after bean creation.
+     */
+    public void setContext(ActionBeanContext context);
+
+    /**
+     * Returns the WikiEngine, which may be <code>null</code> if this instance
+     * was created without invoking the WikiActionBeanContext methods
+     * {@link WikiActionBeanContext#setRequest(HttpServletRequest)} or
+     * {@link WikiActionBeanContext#setServletContext(javax.servlet.ServletContext)}.
+     */
+    public abstract WikiEngine getEngine();
+
+    /**
+     * Returns the request context for the WikiActionBean. By convention,
+     * this method will return the string value of the annotation 
+     * {@link WikiRequestContext}, which is required for all concrete WikiActionBean 
+     * classes.
+     * @deprecated perform <code>instanceof</code> comparisons instead
+     */
+    public abstract String getRequestContext();
+
+    /**
+     * Returns the "skin" to be used for this ActionBean.
+     * 
+     * @return the skin
+     */
+    public abstract String getSkin();
+
+    /**
+     * <p>
+     * Gets the template that is to be used throughout this request. The value
+     * returned depends on the whether the current HTTP request has supplied a
+     * custom skin or template name. In order of preference:
+     * </p>
+     * <ul>
+     * <li>The "skin", if set by {@link #setSkin(String)} or if the HTTP
+     * parameter <code>skin</code> was bound by Stripes</li>
+     * <li>The template, if set by {@link #setTemplate(String)} or if the HTTP
+     * parameter <code>template</code> was bound by Stripes</li>
+     * <li>The WikiEngine's default template, as returned by
+     * {@link WikiEngine#getTemplateDir()}</li>
+     * <li>The value <code>default</code></li>
+     * </ul>
+     * 
+     * @since 2.1.15.
+     */
+    public abstract String getTemplate();
+
+    /**
+     * Returns the WikiSession associated with the context. This method is
+     * guaranteed to always return a valid WikiSession. If this context was
+     * constructed without an associated HttpServletRequest, it will return
+     * {@link WikiSession#guestSession(WikiEngine)}.
+     */
+    public abstract WikiSession getWikiSession();
+
+    /**
+     * Sets the skin to be used with this ActionBean. This value will override
+     * the template returned by {@link #getTemplate()}. Normally, this method
+     * is invoked by Stripes when binding request parameters to the ActionBean.
+     * 
+     * @param skin
+     *            the skin to use
+     */
+    public abstract void setSkin(String skin);
+
+    /**
+     * Sets the template to be used for this request.
+     * 
+     * @since 2.1.15.
+     */
+    public abstract void setTemplate(String dir);
+
+    /**
+     *  Gets a previously set variable.
+     *
+     *  @param key The variable name.
+     *  @return The variable contents.
+     */
+    public Object getVariable(String key);
+
+    /**
+     *  Sets a variable.  The variable is valid while the WikiContext is valid,
+     *  i.e. while page processing continues.  The variable data is discarded
+     *  once the page processing is finished.
+     *
+     *  @param key The variable name.
+     *  @param data The variable value.
+     */
+    public void setVariable(String key, Object data);
+
+    
+    // FIXME: This method should really cache the ResourceBundles or something...
+    public ResourceBundle getBundle( String bundle ) throws MissingResourceException;
+}



Mime
View raw message