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/08/08 05:19:09 UTC
svn commit: r683820 -
/incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/src/com/ecyrd/jspwiki/action/
Author: ajaquith
Date: Thu Aug 7 20:19:09 2008
New Revision: 683820
URL: http://svn.apache.org/viewvc?rev=683820&view=rev
Log:
Beginning of Stripes JSP-tier refactoring.
Added:
incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/src/com/ecyrd/jspwiki/action/AbstractUserProfileActionBean.java
Modified:
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/EditActionBean.java
incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/src/com/ecyrd/jspwiki/action/HandlerInfo.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/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/WikiActionBeanFactory.java
incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/src/com/ecyrd/jspwiki/action/WikiInterceptor.java
Modified: 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=683820&r1=683819&r2=683820&view=diff
==============================================================================
--- incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/src/com/ecyrd/jspwiki/action/AbstractActionBean.java (original)
+++ incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/src/com/ecyrd/jspwiki/action/AbstractActionBean.java Thu Aug 7 20:19:09 2008
@@ -13,16 +13,18 @@
import com.ecyrd.jspwiki.preferences.Preferences;
/**
- * <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>
- *
+ * <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
*/
public abstract class AbstractActionBean implements WikiActionBean
{
- protected Map<String,Object> m_variableMap = new HashMap<String,Object>();
-
+ protected Map<String, Object> m_variableMap = new HashMap<String, Object>();
+
private WikiActionBeanContext m_actionBeanContext = null;
/**
@@ -31,9 +33,9 @@
private String m_skin = null;
private String m_template = null;
-
+
private static final String DEFAULT_TEMPLATE = "default";
-
+
/**
* Creates a new instance of this class, without a WikiEngine, Request or
* WikiPage.
@@ -44,18 +46,9 @@
}
/**
- * Returns the content template for this ActionBean.
- * TODO: make final at some point
- */
- public String getContentTemplate()
- {
- return this.getClass().getAnnotation(WikiRequestContext.class).value();
- }
-
- /**
* Returns the Stripes ActionBeanContext associated this WikiContext. This
- * method may return <code>null</code>, and callers should check for
- * this condition.
+ * method may return <code>null</code>, and callers should check for this
+ * condition.
*
* @throws IllegalStateException
*/
@@ -73,7 +66,7 @@
*/
public Principal getCurrentUser()
{
- if ( getWikiSession() == null )
+ if( getWikiSession() == null )
{
// This shouldn't happen, really...
return WikiPrincipal.GUEST;
@@ -93,29 +86,32 @@
}
/**
- * Returns the request context for this ActionBean by looking up the
- * value of the annotation {@link WikiRequestContext} associated with the current event handler
- * method for this ActionBean. The current event handler is obtained from {@link WikiActionBeanContext#getEventName()}.
- * Note that if this ActionBean does not have a a current event handler assigned, or if the event handler method
- * does not contain the WikiRequestContext annotation, this method will return {@link ecyrd.jspwiki.WikiContext#NONE}.
+ * Returns the request context for this ActionBean by looking up the value
+ * of the annotation {@link WikiRequestContext} associated with the current
+ * event handler method for this ActionBean. The current event handler is
+ * obtained from {@link WikiActionBeanContext#getEventName()}. Note that if
+ * this ActionBean does not have a a current event handler assigned, or if
+ * the event handler method does not contain the WikiRequestContext
+ * annotation, this method will return
+ * {@link ecyrd.jspwiki.WikiContext#NONE}.
*/
public String getRequestContext()
{
WikiActionBeanContext wac = getContext();
- if ( wac == null )
+ if( wac == null )
{
return "none";
}
String eventName = wac.getEventName();
- if ( eventName == null )
+ if( eventName == null )
{
return "none";
}
-
+
return HandlerInfo.getHandlerInfo( this.getClass(), eventName ).getRequestContext();
}
-
+
/**
* Returns the "skin" to be used for this ActionBean.
*
@@ -146,15 +142,15 @@
*/
public String getTemplate()
{
- if ( m_skin != null )
+ if( m_skin != null )
{
return m_skin;
}
- else if ( m_template != null )
+ else if( m_template != null )
{
return m_template;
}
- else if ( getEngine() != null )
+ else if( getEngine() != null )
{
return getEngine().getTemplateDir();
}
@@ -173,10 +169,10 @@
}
/**
- * Gets a previously set variable.
- *
- * @param key The variable name.
- * @return The variable contents.
+ * Gets a previously set variable.
+ *
+ * @param key The variable name.
+ * @return The variable contents.
*/
public Object getVariable( String key )
{
@@ -184,12 +180,12 @@
}
/**
- * 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.
+ * 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 )
{
@@ -200,7 +196,7 @@
* Sets the Stripes ActionBeanContext associated with this WikiContext. It
* will also update the cached HttpRequest.
*/
- public void setContext(ActionBeanContext context)
+ public void setContext( ActionBeanContext context )
{
m_actionBeanContext = ((WikiActionBeanContext) context);
}
@@ -210,10 +206,9 @@
* 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
+ * @param skin the skin to use
*/
- public void setSkin(String skin)
+ public void setSkin( String skin )
{
m_skin = skin;
}
@@ -223,21 +218,22 @@
*
* @since 2.1.15.
*/
- public void setTemplate(String dir)
+ 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
+ * 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...
+ // FIXME: This method should really cache the ResourceBundles or
+ // something...
public ResourceBundle getBundle( String bundle ) throws MissingResourceException
{
Locale loc = Preferences.getLocale( this );
@@ -246,23 +242,26 @@
{
loc = m_actionBeanContext.getRequest().getLocale();
}
- ResourceBundle b = getEngine().getInternationalizationManager().getBundle(bundle, loc);
-
+ ResourceBundle b = getEngine().getInternationalizationManager().getBundle( bundle, loc );
+
return b;
}
-
- // ------------------------------------ Deprecated methods we are reluctantly pulling up from WikiContext
-
- /**
- * If the request did originate from a HTTP request,
- * then the HTTP request can be fetched here. However, it the request
- * did NOT originate from a HTTP request, then this method will
- * return null, and YOU SHOULD CHECK FOR IT!
- *
- * @return Null, if no HTTP request was done.
- * @deprecated use the method {@link #getContext()} to obtain the ActionBeanContext,
- * and call {@link com.ecyrd.jspwiki.action.WikiActionBeanContext#getRequest()} method.
- * @since 2.0.13.
+
+ // ------------------------------------ Deprecated methods we are
+ // reluctantly pulling up from WikiContext
+
+ /**
+ * If the request did originate from a HTTP request, then the HTTP request
+ * can be fetched here. However, it the request did NOT originate from a
+ * HTTP request, then this method will return null, and YOU SHOULD CHECK FOR
+ * IT!
+ *
+ * @return Null, if no HTTP request was done.
+ * @deprecated use the method {@link #getContext()} to obtain the
+ * ActionBeanContext, and call
+ * {@link com.ecyrd.jspwiki.action.WikiActionBeanContext#getRequest()}
+ * method.
+ * @since 2.0.13.
*/
public HttpServletRequest getHttpRequest()
{
@@ -270,15 +269,14 @@
}
/**
- * This method will safely return any HTTP parameters that
- * might have been defined. You should use this method instead
- * of peeking directly into the result of getHttpRequest(), since
- * this method is smart enough to do all of the right things,
- * figure out UTF-8 encoded parameters, etc.
- *
- * @since 2.0.13.
- * @param paramName Parameter name to look for.
- * @return HTTP parameter, or null, if no such parameter existed.
+ * This method will safely return any HTTP parameters that might have been
+ * defined. You should use this method instead of peeking directly into the
+ * result of getHttpRequest(), since this method is smart enough to do all
+ * of the right things, figure out UTF-8 encoded parameters, etc.
+ *
+ * @since 2.0.13.
+ * @param paramName Parameter name to look for.
+ * @return HTTP parameter, or null, if no such parameter existed.
*/
public String getHttpParameter( String paramName )
{
@@ -292,12 +290,6 @@
return result;
}
- public String getJSP()
- {
- // TODO: should calculate the JSP based on the WikiURLPattern annotation
- return null;
- }
-
/**
* Sets the request context. See above for the different request contexts
* (VIEW, EDIT, etc.) This argument must correspond exactly to the value of
@@ -311,14 +303,15 @@
* documentation for more details.
*
* @param arg The request context (one of the predefined contexts.)
- * @throws IllegalArgumentException if the supplied request context does not correspond
- * to a {@linkplain com.ecyrd.jspwiki.action.WikiRequestContext}
- * annotation, or the automatically request context name
+ * @throws IllegalArgumentException if the supplied request context does not
+ * correspond to a
+ * {@linkplain com.ecyrd.jspwiki.action.WikiRequestContext}
+ * annotation, or the automatically request context name
*/
public void setRequestContext( String arg )
{
HandlerInfo handler = HandlerInfo.getHandlerInfo( this.getClass(), arg );
- if ( getContext() == null )
+ if( getContext() == null )
{
throw new IllegalStateException( "WikiActionBean did not set a WikiActionBeanContext!" );
}
Added: incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/src/com/ecyrd/jspwiki/action/AbstractUserProfileActionBean.java
URL: http://svn.apache.org/viewvc/incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/src/com/ecyrd/jspwiki/action/AbstractUserProfileActionBean.java?rev=683820&view=auto
==============================================================================
--- incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/src/com/ecyrd/jspwiki/action/AbstractUserProfileActionBean.java (added)
+++ incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/src/com/ecyrd/jspwiki/action/AbstractUserProfileActionBean.java Thu Aug 7 20:19:09 2008
@@ -0,0 +1,181 @@
+package com.ecyrd.jspwiki.action;
+
+import net.sourceforge.stripes.action.Before;
+import net.sourceforge.stripes.action.HandlesEvent;
+import net.sourceforge.stripes.action.Resolution;
+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.permissions.WikiPermission;
+import com.ecyrd.jspwiki.auth.user.UserDatabase;
+import com.ecyrd.jspwiki.auth.user.UserProfile;
+
+/**
+ * <p>
+ * Abstract WikiActionBean that provides the scaffolding needed to create and
+ * validate a user profile. Subclasses {@link LoginActionBean} and
+ * {@link UserProfileActionBean} rely on the fields and event handlers in this
+ * class. This abstract class contains no handler methods; subclasses must
+ * implement them.
+ * </p>
+ *
+ * @author Andrew Jaquith
+ */
+public abstract class AbstractUserProfileActionBean extends AbstractActionBean
+{
+ protected UserProfile m_profile = null;
+
+ protected String m_passwordAgain = null;
+
+ public String getPasswordAgain()
+ {
+ return m_passwordAgain;
+ }
+
+ public UserProfile getProfile()
+ {
+ return m_profile;
+ }
+
+ /**
+ * Pre-action that loads the UserProfile before user-supplied parameters are
+ * bound to the ActionBean.
+ *
+ * @return <code>null</code>, always
+ */
+ @Before( stages = LifecycleStage.BindingAndValidation )
+ public Resolution initUserProfile()
+ {
+ // 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;
+ }
+
+ 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;
+ }
+
+ /**
+ * Abstract "save profile" methods that subclasses must implement.
+ * @return
+ */
+ @HandlesEvent( "saveProfile" )
+ @HandlerPermission( permissionClass = WikiPermission.class, target = "${engine.applicationName}", actions = WikiPermission.EDIT_PROFILE_ACTION )
+ public abstract Resolution save();
+
+ /**
+ * 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( on="saveProfile", 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, 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() )
+ {
+ 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 )
+ {
+ }
+ }
+
+ /**
+ * After all fields validate correctly, this method validates that the user
+ * account is not spam.
+ *
+ * @param errors the current validation errors for this ActionBean
+ */
+ @ValidationMethod( on="saveProfile", when = ValidationState.NO_ERRORS )
+ public void validateNotSpam( ValidationErrors errors )
+ {
+ // TODO: code this up!
+ }
+
+ /**
+ * 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( on="saveProfile", 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" ) );
+ }
+ }
+ }
+}
Modified: 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=683820&r1=683819&r2=683820&view=diff
==============================================================================
--- incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/src/com/ecyrd/jspwiki/action/EditActionBean.java (original)
+++ incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/src/com/ecyrd/jspwiki/action/EditActionBean.java Thu Aug 7 20:19:09 2008
@@ -10,7 +10,7 @@
{
@DefaultHandler
@HandlesEvent("edit")
- @HandlerPermission(permissionClass=PagePermission.class, target="${page.name}", actions=PagePermission.EDIT_ACTION)
+ @HandlerPermission(permissionClass=PagePermission.class, target="${page.qualifiedName}", actions=PagePermission.EDIT_ACTION)
@WikiRequestContext("edit")
public Resolution edit()
{
@@ -23,7 +23,7 @@
* @return a forward resolution back to the preview page.
*/
@HandlesEvent( "preview" )
- @HandlerPermission( permissionClass = PagePermission.class, target = "${page.name}", actions = PagePermission.VIEW_ACTION )
+ @HandlerPermission( permissionClass = PagePermission.class, target = "${page.qualifiedName}", actions = PagePermission.VIEW_ACTION )
@WikiRequestContext( "preview" )
public Resolution preview()
{
@@ -37,7 +37,7 @@
*/
@WikiRequestContext("diff")
@HandlesEvent("diff")
- @HandlerPermission(permissionClass=PagePermission.class, target="${page.name}", actions=PagePermission.VIEW_ACTION)
+ @HandlerPermission(permissionClass=PagePermission.class, target="${page.qualifiedName}", actions=PagePermission.VIEW_ACTION)
public Resolution diff()
{
return new ForwardResolution( "/Diff.jsp" );
Modified: incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/src/com/ecyrd/jspwiki/action/HandlerInfo.java
URL: http://svn.apache.org/viewvc/incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/src/com/ecyrd/jspwiki/action/HandlerInfo.java?rev=683820&r1=683819&r2=683820&view=diff
==============================================================================
--- incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/src/com/ecyrd/jspwiki/action/HandlerInfo.java (original)
+++ incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/src/com/ecyrd/jspwiki/action/HandlerInfo.java Thu Aug 7 20:19:09 2008
@@ -323,6 +323,8 @@
* Returns the Permission required to execute the method in the context of the supplied
* WikiActionBean, based on its {@link HandlerPermission} annotation.
* Any EL expressions found in the annotated target or actions are evaluated.
+ * Note that this method returns <code>null</code> if no Permission is required
+ * to execute this method, and <em>callers should check for nulls</code>.
*
* @param actionBean the ActionBean that will be used as the base for any EL
* expressions
@@ -332,6 +334,11 @@
*/
public Permission getPermission( WikiActionBean actionBean ) throws ELException
{
+ if ( m_permissionClass == null )
+ {
+ return null;
+ }
+
// Get the target class, target and actions
boolean hasOneParameter = m_permissionActions == null;
String target = m_permissionTarget;
Modified: 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=683820&r1=683819&r2=683820&view=diff
==============================================================================
--- incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/src/com/ecyrd/jspwiki/action/LoginActionBean.java (original)
+++ incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/src/com/ecyrd/jspwiki/action/LoginActionBean.java Thu Aug 7 20:19:09 2008
@@ -1,29 +1,271 @@
package com.ecyrd.jspwiki.action;
-import net.sourceforge.stripes.action.DefaultHandler;
-import net.sourceforge.stripes.action.HandlesEvent;
-import net.sourceforge.stripes.action.Resolution;
-import net.sourceforge.stripes.action.UrlBinding;
+import java.security.Principal;
+import java.util.ResourceBundle;
+import javax.servlet.http.HttpSession;
+
+import net.sourceforge.stripes.action.*;
+import net.sourceforge.stripes.util.UrlBuilder;
+import net.sourceforge.stripes.validation.LocalizableError;
+import net.sourceforge.stripes.validation.SimpleError;
+import net.sourceforge.stripes.validation.ValidationErrors;
+
+import org.apache.log4j.Logger;
+
+import com.ecyrd.jspwiki.WikiEngine;
+import com.ecyrd.jspwiki.WikiSession;
+import com.ecyrd.jspwiki.auth.WikiSecurityException;
+import com.ecyrd.jspwiki.auth.login.CookieAssertionLoginModule;
+import com.ecyrd.jspwiki.auth.login.CookieAuthenticationLoginModule;
import com.ecyrd.jspwiki.auth.permissions.WikiPermission;
+import com.ecyrd.jspwiki.workflow.DecisionRequiredException;
-@UrlBinding("/Login.jsp")
-public class LoginActionBean extends AbstractActionBean
+@UrlBinding( "/Login.jsp" )
+public class LoginActionBean extends AbstractUserProfileActionBean
{
- @DefaultHandler
- @HandlesEvent("login")
- @HandlerPermission(permissionClass=WikiPermission.class, target="${engine.applicationName}", actions=WikiPermission.LOGIN_ACTION)
- @WikiRequestContext("login")
+ private String m_redirect = null;
+
+ private String m_username = null;
+
+ private boolean m_remember = false;
+
+ private String m_password;
+
+ private static final Logger log = Logger.getLogger( LoginActionBean.class );
+
+ public String getJ_userName()
+ {
+ return m_username;
+ }
+
+ public String getJ_password()
+ {
+ return m_password;
+ }
+
+ public void setJ_username( String username )
+ {
+ m_username = username;
+ }
+
+ public void setJ_password( String password )
+ {
+ m_password = password;
+ }
+
+ public void setJ_remember( boolean remember )
+ {
+ m_remember = remember;
+ }
+
+ public boolean getJ_remember()
+ {
+ return m_remember;
+ }
+
+ public String getRedirect()
+ {
+ return m_redirect;
+ }
+
+ @HandlesEvent( "login" )
+ @HandlerPermission( permissionClass = WikiPermission.class, target = "${engine.applicationName}", actions = WikiPermission.LOGIN_ACTION )
public Resolution login()
{
- return null;
+ WikiSession wikiSession = this.getWikiSession();
+
+ // If user got here and is already authenticated, it means
+ // they just aren't allowed access to what they asked for.
+ // Weepy tears and hankies all 'round.
+ if( getWikiSession().isAuthenticated() )
+ {
+ ResourceBundle rb = getBundle( "CoreResources" );
+ String message = rb.getString( "login.error.noaccess" );
+ getContext().getValidationErrors().addGlobalError( new SimpleError( message ) );
+ return new RedirectResolution( MessageActionBean.class ).flash( this );
+ }
+
+ log.debug( "Attempting to authenticate user " + m_username );
+
+ // Log the user in!
+ Resolution r = null;
+ ValidationErrors errors = getContext().getValidationErrors();
+ try
+ {
+ if( getEngine().getAuthenticationManager().login( wikiSession, m_username, m_password ) )
+ {
+ // Set cookies as needed and redirect
+ log.info( "Successfully authenticated user " + m_username + " (custom auth)" );
+ r = redirectToOriginalPage();
+ }
+ else
+ {
+ log.info( "Failed to authenticate user " + m_username );
+ errors.addGlobalError( new SimpleError( "login.error.password" ) );
+
+ }
+ }
+ catch( WikiSecurityException e )
+ {
+ errors.addGlobalError( new SimpleError( "login.error", e.getMessage() ) );
+ }
+
+ // Any errors?
+ if( !errors.isEmpty() )
+ {
+ UrlBuilder builder = new UrlBuilder( getContext().getLocale(), LoginActionBean.class, false );
+ builder.addParameter( "tab", "logincontent" );
+ r = new RedirectResolution( builder.toString() );
+ }
+
+ return r;
}
- @HandlesEvent("logout")
- @HandlerPermission(permissionClass=WikiPermission.class, target="${engine.applicationName}", actions=WikiPermission.LOGIN_ACTION)
- @WikiRequestContext("logout")
+ @HandlesEvent( "logout" )
+ @HandlerPermission( permissionClass = WikiPermission.class, target = "${engine.applicationName}", actions = WikiPermission.LOGIN_ACTION )
+ @WikiRequestContext( "logout" )
public Resolution logout()
{
return null;
}
+
+ public void setRedirect( String redirect )
+ {
+ m_redirect = redirect;
+ setVariable( "redirect", redirect );
+ }
+
+ /**
+ * Attempts to save the user profile, after all other validation routines
+ * have executed. If the save executes without error, this method will
+ * return <code>null</code>. Otherwise, any error conditions will return
+ * a non-null Resolution. For example, if an approval is required to save
+ * the profile, a RedirectResolution redirecting the user to the
+ * <code>ApprovalRequiredForUserProfiles</code> will be returned. Other
+ * validation errors will cause redirection back to the profile tab.
+ *
+ * @return
+ */
+ @HandlesEvent( "saveProfile" )
+ @HandlerPermission( permissionClass = WikiPermission.class, target = "${engine.applicationName}", actions = WikiPermission.EDIT_PROFILE_ACTION )
+ public Resolution save()
+ {
+ WikiActionBeanContext context = getContext();
+ Resolution r = null;
+ try
+ {
+ // Save the profile
+ WikiEngine engine = getEngine();
+ engine.getUserManager().setUserProfile( getWikiSession(), m_profile );
+ CookieAssertionLoginModule.setUserCookie( context.getResponse(), m_profile.getFullname() );
+ }
+
+ // Not so fast my friend! Approvals are required...
+ catch( DecisionRequiredException e )
+ {
+ UrlBuilder builder = new UrlBuilder( this.getContext().getLocale(), ViewActionBean.class, false );
+ builder.addParameter( "page", "ApprovalRequiredForUserProfiles" );
+ r = new RedirectResolution( builder.toString() );
+ }
+
+ // Any other errors are either UI or config problems, so let the user
+ // know about them
+ catch( Exception e )
+ {
+ ValidationErrors errors = context.getValidationErrors();
+ errors.addGlobalError( new LocalizableError( "saveError", e.getMessage() ) );
+ UrlBuilder builder = new UrlBuilder( this.getContext().getLocale(), LoginActionBean.class, false );
+ builder.addParameter( "tab", "profile" );
+ r = new RedirectResolution( builder.toString() );
+ }
+
+ // Set cookies as needed and redirect
+ r = redirectToOriginalPage();
+
+ return r;
+ }
+
+ /**
+ * Executes after a successful profile creation or login
+ */
+ private Resolution redirectToOriginalPage()
+ {
+ // Set user cookie
+ Principal principal = getWikiSession().getUserPrincipal();
+ CookieAssertionLoginModule.setUserCookie( getContext().getResponse(), principal.getName() );
+
+ // Set "remember me?" cookie
+ if( m_remember )
+ {
+ CookieAuthenticationLoginModule.setLoginCookie( getEngine(), getContext().getResponse(), principal.getName() );
+ }
+
+ Resolution r = null;
+ if( m_redirect != null )
+ {
+ UrlBuilder builder = new UrlBuilder( this.getContext().getLocale(), ViewActionBean.class, false );
+ builder.addParameter( "page", m_redirect );
+ r = new RedirectResolution( builder.toString() );
+ }
+ return r;
+ }
+
+ /**
+ * Default handler that executes when the login page is viewed. It checks to
+ * see if the user is already authenticated, and if so, sents a "forbidden"
+ * message.
+ *
+ * @return the resolution
+ */
+ @DefaultHandler
+ @HandlesEvent( "view" )
+ @HandlerPermission( permissionClass = WikiPermission.class, target = "${engine.applicationName}", actions = WikiPermission.LOGIN_ACTION )
+ @WikiRequestContext( "login" )
+ public Resolution view()
+ {
+ Resolution r = null;
+
+ if( getWikiSession().isAuthenticated() )
+ {
+ // Set cookies as needed and redirect
+ r = redirectToOriginalPage();
+ if( r == null )
+ {
+ r = new RedirectResolution( ViewActionBean.class );
+ }
+ }
+
+ if( getEngine().getAuthenticationManager().isContainerAuthenticated() )
+ {
+ //
+ // Have we already been submitted? If yes, then we can assume that
+ // we have been logged in before.
+ //
+
+ HttpSession session = getContext().getRequest().getSession();
+ Object seen = session.getAttribute( "_redirect" );
+ if( seen != null )
+ {
+ ResourceBundle rb = getBundle( "CoreResources" );
+ String message = rb.getString( "login.error.noaccess" );
+ getContext().getValidationErrors().addGlobalError( new SimpleError( message ) );
+ return new RedirectResolution( MessageActionBean.class ).flash( this );
+ }
+ session.setAttribute( "_redirect", "I love Outi" ); // Just any
+ // marker will
+ // do
+
+ // If using container auth, the container will have automatically
+ // attempted to log in the user before Login.jsp was loaded.
+ // Thus, if we got here, the container must have authenticated
+ // the user already. All we do is simply record that fact.
+ // Nice and easy.
+
+ Principal user = getWikiSession().getLoginPrincipal();
+ log.info( "Successfully authenticated user " + user.getName() + " (container auth)" );
+ }
+
+ return r;
+ }
}
Modified: 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=683820&r1=683819&r2=683820&view=diff
==============================================================================
--- incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/src/com/ecyrd/jspwiki/action/MessageActionBean.java (original)
+++ incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/src/com/ecyrd/jspwiki/action/MessageActionBean.java Thu Aug 7 20:19:09 2008
@@ -2,18 +2,32 @@
import net.sourceforge.stripes.action.*;
-@UrlBinding("/Message.jsp")
+@UrlBinding( "/Message.jsp" )
public class MessageActionBean extends AbstractActionBean
{
+ private String m_message = null;
+
/**
* Default event that forwards control to /Message.jsp.
+ *
* @return the forward resolution
*/
@DefaultHandler
- @HandlesEvent("message")
- @WikiRequestContext("message")
- public Resolution view() {
+ @HandlesEvent( "message" )
+ @WikiRequestContext( "message" )
+ public Resolution view()
+ {
return new ForwardResolution( "/Message.jsp" );
}
+ public String getMessage()
+ {
+ return m_message;
+ }
+
+ public void setMessage( String message )
+ {
+ m_message = message;
+ }
+
}
Modified: 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=683820&r1=683819&r2=683820&view=diff
==============================================================================
--- incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/src/com/ecyrd/jspwiki/action/UserProfileActionBean.java (original)
+++ incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/src/com/ecyrd/jspwiki/action/UserProfileActionBean.java Thu Aug 7 20:19:09 2008
@@ -1,214 +1,78 @@
package com.ecyrd.jspwiki.action;
import net.sourceforge.stripes.action.*;
-import net.sourceforge.stripes.controller.LifecycleStage;
-import net.sourceforge.stripes.validation.*;
+import net.sourceforge.stripes.util.UrlBuilder;
+import net.sourceforge.stripes.validation.LocalizableError;
+import net.sourceforge.stripes.validation.ValidationErrors;
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;
+import com.ecyrd.jspwiki.workflow.DecisionRequiredException;
/**
* @author Andrew Jaquith
*/
-@UrlBinding("/UserProfile.jsp")
-public class UserProfileActionBean extends AbstractActionBean
+@UrlBinding( "/UserProfile.jsp" )
+public class UserProfileActionBean extends AbstractUserProfileActionBean
{
- 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(stages=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
+ * Attempts to save the user profile, after all other validation routines have executed.
+ * If the save executes without error, this method will return <code>null</code>.
+ * Otherwise, any error conditions will return a non-null Resolution.
+ * For example, if an approval is required to save the profile, a RedirectResolution
+ * redirecting the user to the <code>ApprovalRequiredForUserProfiles</code>
+ * will be returned. Other validation errors will cause redirection back to the profile tab.
+ * @return
*/
- @HandlesEvent("save")
- @HandlerPermission(permissionClass=WikiPermission.class, target="${engine.applicationName}", actions=WikiPermission.EDIT_PROFILE_ACTION)
+ @HandlesEvent( "saveProfile" )
+ @HandlerPermission( permissionClass = WikiPermission.class, target = "${engine.applicationName}", actions = WikiPermission.EDIT_PROFILE_ACTION )
public Resolution save()
{
- Resolution r = null;
WikiActionBeanContext context = getContext();
+ Resolution r = null;
try
{
// Save the profile
WikiEngine engine = getEngine();
engine.getUserManager().setUserProfile( getWikiSession(), m_profile);
CookieAssertionLoginModule.setUserCookie(context.getResponse(), m_profile.getFullname());
- r = new RedirectResolution("/");
}
+
+ // Not so fast my friend! Approvals are required...
+ catch( DecisionRequiredException e )
+ {
+ UrlBuilder builder = new UrlBuilder( this.getContext().getLocale(), ViewActionBean.class, false );
+ builder.addParameter( "page", "ApprovalRequiredForUserProfiles" );
+ r = new RedirectResolution( builder.toString() );
+ }
+
+ // Any other errors are either UI or config problems, so let the user know about them
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" ) );
- }
+ UrlBuilder builder = new UrlBuilder( this.getContext().getLocale(), UserProfileActionBean.class, false );
+ builder.addParameter( "tab", "profile" );
+ r = new RedirectResolution( builder.toString() );
}
- // 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" ) );
- }
- }
+ // The save executed correctly and without errors, so return nothing
+ return r;
}
-
- /**
- * 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, 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() )
- {
- 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")
+ @HandlesEvent( "view" )
@DefaultHandler
- @WikiRequestContext("profile")
+ @WikiRequestContext( "profile" )
public Resolution view()
{
- return new ForwardResolution(ViewActionBean.class);
+ return new ForwardResolution( ViewActionBean.class );
}
-
+
}
Modified: 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=683820&r1=683819&r2=683820&view=diff
==============================================================================
--- incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/src/com/ecyrd/jspwiki/action/ViewActionBean.java (original)
+++ incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/src/com/ecyrd/jspwiki/action/ViewActionBean.java Thu Aug 7 20:19:09 2008
@@ -134,7 +134,7 @@
*/
@DefaultHandler
@HandlesEvent("view")
- @HandlerPermission(permissionClass=PagePermission.class, target="${page.name}", actions=PagePermission.VIEW_ACTION)
+ @HandlerPermission(permissionClass=PagePermission.class, target="${page.qualifiedName}", actions=PagePermission.VIEW_ACTION)
@WikiRequestContext("view")
public Resolution view()
{
Modified: incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/src/com/ecyrd/jspwiki/action/WikiActionBeanFactory.java
URL: http://svn.apache.org/viewvc/incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/src/com/ecyrd/jspwiki/action/WikiActionBeanFactory.java?rev=683820&r1=683819&r2=683820&view=diff
==============================================================================
--- incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/src/com/ecyrd/jspwiki/action/WikiActionBeanFactory.java (original)
+++ incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/src/com/ecyrd/jspwiki/action/WikiActionBeanFactory.java Thu Aug 7 20:19:09 2008
@@ -9,7 +9,6 @@
import javax.servlet.ServletRequest;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
-import javax.servlet.jsp.PageContext;
import net.sourceforge.stripes.action.RedirectResolution;
import net.sourceforge.stripes.mock.MockHttpServletRequest;
@@ -20,6 +19,7 @@
import org.apache.log4j.Logger;
import com.ecyrd.jspwiki.*;
+import com.ecyrd.jspwiki.auth.SessionMonitor;
import com.ecyrd.jspwiki.parser.MarkupParser;
import com.ecyrd.jspwiki.providers.ProviderException;
import com.ecyrd.jspwiki.tags.WikiTagBase;
@@ -65,6 +65,24 @@
*/
public final class WikiActionBeanFactory
{
+ /**
+ * The PageContext attribute name of the WikiActionBean stored by
+ * WikiInterceptor.
+ */
+ public static final String ATTR_ACTIONBEAN = "wikiActionBean";
+
+ /**
+ * 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( WikiActionBeanFactory.class );
private static final long serialVersionUID = 1L;
@@ -586,13 +604,13 @@
*/
public static WikiActionBean findActionBean( ServletRequest request )
{
- return (WikiActionBean) request.getAttribute( WikiInterceptor.ATTR_ACTIONBEAN );
+ return (WikiActionBean) request.getAttribute( ATTR_ACTIONBEAN );
}
/**
* <p>
* Saves the supplied WikiActionBean and its associated WikiPage as
- * PageContext attributes, in request scope. The action bean is saved as an
+ * in request scope. The action bean is saved as an
* attribute named {@link WikiInterceptor#ATTR_ACTIONBEAN}. If the action
* bean was also a WikiContext instance, it is saved as an attribute named
* {@link com.ecyrd.jspwiki.tags.WikiTagBase#ATTR_CONTEXT}. Among other
@@ -609,14 +627,22 @@
* and that page will be used.
* </p>
*
- * @param pageContext the page context
+ * @param request the HTTP request
* @param actionBean the WikiActionBean to save
*/
- public static void saveActionBean( PageContext pageContext, WikiActionBean actionBean )
+ public static void saveActionBean( HttpServletRequest request, WikiActionBean actionBean )
{
- // Stash the WikiActionBean
+ // Stash WikiEngine as a request attribute (can be
+ // used later as ${wikiEngine} in EL markup)
WikiEngine engine = actionBean.getEngine();
- pageContext.setAttribute( WikiInterceptor.ATTR_ACTIONBEAN, actionBean, PageContext.REQUEST_SCOPE );
+ request.setAttribute( ATTR_WIKIENGINE, engine );
+
+ // Stash the WikiSession as a request attribute
+ WikiSession wikiSession = SessionMonitor.getInstance( engine ).find( request.getSession() );
+ request.setAttribute( ATTR_WIKISESSION, wikiSession );
+
+ // Stash the WikiActionBean
+ request.setAttribute( ATTR_ACTIONBEAN, actionBean );
// Stash it again as a WikiContext (or synthesize a fake one)
WikiContext wikiContext;
@@ -640,12 +666,11 @@
}
else
{
- HttpServletRequest request = actionBean.getContext().getRequest();
HttpServletResponse response = actionBean.getContext().getResponse();
page = engine.getPage( engine.getFrontPage() );
wikiContext = engine.getWikiActionBeanFactory().newViewActionBean( request, response, page );
}
- pageContext.setAttribute( WikiTagBase.ATTR_CONTEXT, actionBean, PageContext.REQUEST_SCOPE );
+ request.setAttribute( WikiTagBase.ATTR_CONTEXT, wikiContext );
// Debug messages
if( log.isDebugEnabled() )
Modified: incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/src/com/ecyrd/jspwiki/action/WikiInterceptor.java
URL: http://svn.apache.org/viewvc/incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/src/com/ecyrd/jspwiki/action/WikiInterceptor.java?rev=683820&r1=683819&r2=683820&view=diff
==============================================================================
--- incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/src/com/ecyrd/jspwiki/action/WikiInterceptor.java (original)
+++ incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/src/com/ecyrd/jspwiki/action/WikiInterceptor.java Thu Aug 7 20:19:09 2008
@@ -9,24 +9,30 @@
import net.sourceforge.stripes.action.RedirectResolution;
import net.sourceforge.stripes.action.Resolution;
-import net.sourceforge.stripes.controller.*;
+import net.sourceforge.stripes.controller.ExecutionContext;
+import net.sourceforge.stripes.controller.Interceptor;
+import net.sourceforge.stripes.controller.Intercepts;
+import net.sourceforge.stripes.controller.LifecycleStage;
import org.apache.log4j.Logger;
import com.ecyrd.jspwiki.WikiEngine;
import com.ecyrd.jspwiki.WikiSession;
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 after the second
- * lifecycle stage, <em>aka</em>
- * {@link net.sourceforge.stripes.controller.LifecycleStage#HandlerResolution},
+ * and redirects users if necessary. The interceptor executes twice: the first
+ * time is after the first lifecycle state, <em>aka</em>
+ * {@link net.sourceforge.stripes.controller.LifecycleStage#ActionBeanResolution}
+ * but before the second stage.
+ * {@link net.sourceforge.stripes.controller.LifecycleStage#HandlerResolution}.
+ * The second time the interceptor executes is after the second lifecycle stage,
* but before the third stage,
* {@link net.sourceforge.stripes.controller.LifecycleStage#BindingAndValidation}.
+ * See the
* </p>
* <p>
* WikiInterceptor assumes primary responsibility for making JSPWiki objects
@@ -47,8 +53,8 @@
* <p>
* After the intercept method fires, calling classes can obtain the saved
* WikiActionBean by calling
- * {@link WikiActionBeanFactory#findActionBean(javax.servlet.ServletRequest)}. This is
- * the recommended method that JSP scriptlet code should use.
+ * {@link WikiActionBeanFactory#findActionBean(javax.servlet.ServletRequest)}.
+ * This is the recommended method that JSP scriptlet code should use.
* </p>
* <p>
* Because these objects are saved as attributes, they are available to JSPs as
@@ -59,28 +65,78 @@
*
* @author Andrew Jaquith
*/
-@Intercepts( { LifecycleStage.HandlerResolution } )
+@Intercepts( { LifecycleStage.ActionBeanResolution, LifecycleStage.BindingAndValidation } )
public class WikiInterceptor implements Interceptor
{
- /**
- * The PageContext attribute name of the WikiActionBean stored by
- * WikiInterceptor.
- */
- public static final String ATTR_ACTIONBEAN = "wikiActionBean";
+ private static final Logger log = Logger.getLogger( WikiInterceptor.class );
/**
- * The PageContext attribute name of the WikiEngine stored by
- * WikiInterceptor.
+ * Intercepts the Stripes lifecycle stages and dispatches execution to
+ * delegate methods {@link #interceptActionBeanResolution(ExecutionContext)}
+ * and {@link #interceptBindingAndValidation(ExecutionContext)}, whichever
+ * is appropriate.
+ *
+ * @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
*/
- public static final String ATTR_WIKIENGINE = "wikiEngine";
+ public Resolution intercept( ExecutionContext context ) throws Exception
+ {
+ if( LifecycleStage.ActionBeanResolution.equals( context.getLifecycleStage() ) )
+ {
+ return interceptActionBeanResolution( context );
+ }
+ else if( LifecycleStage.BindingAndValidation.equals( context.getLifecycleStage() ) )
+ {
+ return interceptBindingAndValidation( context );
+ }
+ return null;
+ }
/**
- * The PageContext attribute name of the WikiSession stored by
- * WikiInterceptor.
+ * After the Stripes
+ * {@link net.sourceforge.stripes.controller.LifecycleStage#ActionBeanResolution}
+ * executes, this method injects the current WikiEngine, WikiSession and
+ * WikiActionBean into request scope, and returns <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 execution context
+ * @return a Resolution if the
+ * {@link net.sourceforge.stripes.controller.LifecycleStage#ActionBeanResolution}
+ * lifecycle stage's normal execution returns one; <code>null</code>
+ * otherwise
+ * @throws Exception if the underlying lifcycle stage's execution throws an
+ * Exception
*/
- public static final String ATTR_WIKISESSION = "wikiSession";
+ protected Resolution interceptActionBeanResolution( ExecutionContext context ) throws Exception
+ {
+ // Did the handler resolution stage return a Resolution? If so, bail.
+ Resolution r = context.proceed();
+ if( r != null )
+ {
+ return r;
+ }
- private static final Logger log = Logger.getLogger( WikiInterceptor.class );
+ WikiActionBean actionBean = (WikiActionBean) context.getActionBean();
+ WikiActionBeanContext beanContext = actionBean.getContext();
+ HttpServletRequest httpRequest = beanContext.getRequest();
+
+ // Stash the WikiActionBean and WikiPage in the request
+ WikiActionBeanFactory.saveActionBean( httpRequest, actionBean );
+
+ if( log.isDebugEnabled() )
+ {
+ log.debug( "WikiInterceptor resolved ActionBean: " + actionBean );
+ }
+
+ return null;
+ }
/**
* <p>
@@ -102,23 +158,16 @@
* 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
+ * @param context the execution context
* @return a Resolution if the
- * {@link net.sourceforge.stripes.controller.LifecycleStage#HandlerResolution}
+ * {@link net.sourceforge.stripes.controller.LifecycleStage#BindingAndValidation}
* lifecycle stage's normal execution returns one; <code>null</code>
* otherwise
* @throws Exception if the underlying lifcycle stage's execution throws an
* Exception
*/
- public Resolution intercept( ExecutionContext context ) throws Exception
+ protected Resolution interceptBindingAndValidation( ExecutionContext context ) throws Exception
{
// Did the handler resolution stage return a Resolution? If so, bail.
Resolution r = context.proceed();
@@ -129,7 +178,6 @@
// 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?
@@ -156,43 +204,12 @@
((RedirectResolution) r).includeRequestParameters( true );
if( log.isDebugEnabled() )
{
- log.debug( "WikiInterceptor rejected access to ActionBean=" + actionBean.getClass().getCanonicalName() + ", method=" + handler.getName() );
+ log.debug( "WikiInterceptor rejected access to ActionBean=" + actionBean.getClass().getCanonicalName()
+ + ", 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;
}