jspwiki-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From ajaqu...@apache.org
Subject svn commit: r915545 - in /incubator/jspwiki/trunk/src: WebContent/WEB-INF/classes/ WebContent/scripts/ java/org/apache/wiki/action/ java/org/apache/wiki/ui/stripes/
Date Tue, 23 Feb 2010 22:02:48 GMT
Author: ajaquith
Date: Tue Feb 23 22:02:47 2010
New Revision: 915545

URL: http://svn.apache.org/viewvc?rev=915545&view=rev
Log:
Useful tweaks to the AJAX-related Stripes JavaScript. The client-side JavaScript now injects
validation errors and messages that were generated server-side by an EventResolution, using
the same prefixes and headers defined in CoreResources for "normal" JSP validation errors
and messages. Generation of an EventResolution for AJAX methods that generate errors is automatic
when the event method is annotated with @AjaxEvent. Practically speaking, what it means is
this: to call an Stripes method via Ajax, just annotate the method with @AjaxEvent. Then,
client-side scripts need only call the JavaScript function Stripes.submitFormEvent(). The
rest is MAGIC.

Added:
    incubator/jspwiki/trunk/src/java/org/apache/wiki/ui/stripes/AjaxEvent.java
Modified:
    incubator/jspwiki/trunk/src/WebContent/WEB-INF/classes/CoreResources.properties
    incubator/jspwiki/trunk/src/WebContent/WEB-INF/classes/CoreResources_es.properties
    incubator/jspwiki/trunk/src/WebContent/WEB-INF/classes/CoreResources_nl.properties
    incubator/jspwiki/trunk/src/WebContent/scripts/jspwiki-common.js
    incubator/jspwiki/trunk/src/java/org/apache/wiki/action/EditActionBean.java
    incubator/jspwiki/trunk/src/java/org/apache/wiki/action/EditDialogActionBean.java
    incubator/jspwiki/trunk/src/java/org/apache/wiki/action/InstallActionBean.java
    incubator/jspwiki/trunk/src/java/org/apache/wiki/action/SearchActionBean.java
    incubator/jspwiki/trunk/src/java/org/apache/wiki/ui/stripes/EventResolution.java
    incubator/jspwiki/trunk/src/java/org/apache/wiki/ui/stripes/WikiInterceptor.java

Modified: incubator/jspwiki/trunk/src/WebContent/WEB-INF/classes/CoreResources.properties
URL: http://svn.apache.org/viewvc/incubator/jspwiki/trunk/src/WebContent/WEB-INF/classes/CoreResources.properties?rev=915545&r1=915544&r2=915545&view=diff
==============================================================================
--- incubator/jspwiki/trunk/src/WebContent/WEB-INF/classes/CoreResources.properties (original)
+++ incubator/jspwiki/trunk/src/WebContent/WEB-INF/classes/CoreResources.properties Tue Feb
23 22:02:47 2010
@@ -303,10 +303,6 @@
 install.ldap.title=LDAP Configuration
 #Formerly named install.jsp.instr.submit.
 org.apache.wiki.action.InstallActionBean.save=Configure!
-org.apache.wiki.action.InstallActionBean.testLdapConnection=Test connection
-org.apache.wiki.action.InstallActionBean.testLdapAuthentication=Test authentication
-org.apache.wiki.action.InstallActionBean.testLdapUsers=Test user lookups
-org.apache.wiki.action.InstallActionBean.testLdapRoles=Test role lookups
 Default.ACTIVE_DIRECTORY=Active Directory
 Default.OPEN_LDAP=OpenLDAP
 test.connection=Test connection
@@ -396,3 +392,11 @@
 SearchScope.ATTACHMENTS=Attachments
 #Copied from src/WebContent/WEB-INF/classes/templates/default.properties.. Formerly named
find.scope.pagename.. Formerly named SearchScope.PAGE_NAME.
 SearchScope.PAGE_NAMES=Page names
+#Formerly named org.apache.wiki.action.InstallActionBean.testLdapConnection.
+org.apache.wiki.action.InstallActionBean.ldapConnection=Test connection
+#Formerly named org.apache.wiki.action.InstallActionBean.testLdapAuthentication.
+org.apache.wiki.action.InstallActionBean.ldapAuthentication=Test authentication
+#Formerly named org.apache.wiki.action.InstallActionBean.testLdapUsers.
+org.apache.wiki.action.InstallActionBean.ldapUsers=Test user lookups
+#Formerly named org.apache.wiki.action.InstallActionBean.testLdapRoles.
+org.apache.wiki.action.InstallActionBean.ldapRoles=Test role lookups

Modified: incubator/jspwiki/trunk/src/WebContent/WEB-INF/classes/CoreResources_es.properties
URL: http://svn.apache.org/viewvc/incubator/jspwiki/trunk/src/WebContent/WEB-INF/classes/CoreResources_es.properties?rev=915545&r1=915544&r2=915545&view=diff
==============================================================================
--- incubator/jspwiki/trunk/src/WebContent/WEB-INF/classes/CoreResources_es.properties (original)
+++ incubator/jspwiki/trunk/src/WebContent/WEB-INF/classes/CoreResources_es.properties Tue
Feb 23 22:02:47 2010
@@ -290,10 +290,6 @@
 attach.bad.filetype=No puede adjuntarse el fichero {2} debido a que contiene una extensión
no permitida
 #Formerly named install.jsp.instr.submit.
 org.apache.wiki.action.InstallActionBean.save=¡Configura!
-org.apache.wiki.action.InstallActionBean.testLdapConnection=Probar conexión
-org.apache.wiki.action.InstallActionBean.testLdapAuthentication=Probar autenticación
-org.apache.wiki.action.InstallActionBean.testLdapUsers=Probar búsquedas de usuario
-org.apache.wiki.action.InstallActionBean.testLdapRoles=Probar búsquedas de rol
 Default.ACTIVE_DIRECTORY=Active Directory
 Default.OPEN_LDAP=OpenLDAP
 test.connection=Probar conexión
@@ -365,3 +361,11 @@
 SearchScope.ATTACHMENTS=Adjuntos
 #Copied from src/WebContent/WEB-INF/classes/templates/default.properties.. Formerly named
find.scope.pagename.. Formerly named SearchScope.PAGE_NAME.
 SearchScope.PAGE_NAMES=Nombre de las Páginas
+#Formerly named org.apache.wiki.action.InstallActionBean.testLdapConnection.
+org.apache.wiki.action.InstallActionBean.ldapConnection=Probar conexión
+#Formerly named org.apache.wiki.action.InstallActionBean.testLdapAuthentication.
+org.apache.wiki.action.InstallActionBean.ldapAuthentication=Probar autenticación
+#Formerly named org.apache.wiki.action.InstallActionBean.testLdapUsers.
+org.apache.wiki.action.InstallActionBean.ldapUsers=Probar búsquedas de usuario
+#Formerly named org.apache.wiki.action.InstallActionBean.testLdapRoles.
+org.apache.wiki.action.InstallActionBean.ldapRoles=Probar búsquedas de rol

Modified: incubator/jspwiki/trunk/src/WebContent/WEB-INF/classes/CoreResources_nl.properties
URL: http://svn.apache.org/viewvc/incubator/jspwiki/trunk/src/WebContent/WEB-INF/classes/CoreResources_nl.properties?rev=915545&r1=915544&r2=915545&view=diff
==============================================================================
--- incubator/jspwiki/trunk/src/WebContent/WEB-INF/classes/CoreResources_nl.properties (original)
+++ incubator/jspwiki/trunk/src/WebContent/WEB-INF/classes/CoreResources_nl.properties Tue
Feb 23 22:02:47 2010
@@ -244,10 +244,6 @@
 install.ldap.title=LDAP Configuratie
 #Formerly named install.jsp.instr.submit.
 org.apache.wiki.action.InstallActionBean.save=Configureer!
-org.apache.wiki.action.InstallActionBean.testLdapConnection=Test verbinding
-org.apache.wiki.action.InstallActionBean.testLdapAuthentication=Test authenticatie
-org.apache.wiki.action.InstallActionBean.testLdapUsers=Test gebruikers lookups
-org.apache.wiki.action.InstallActionBean.testLdapRoles=Test rol lookups
 Default.ACTIVE_DIRECTORY=Actieve Directory
 Default.OPEN_LDAP=OpenLDAP
 test.connection=Test verbinding
@@ -325,3 +321,11 @@
 SearchScope.ATTACHMENTS=Bijlagen
 #Copied from src/WebContent/WEB-INF/classes/templates/default.properties.. Formerly named
find.scope.pagename.. Formerly named SearchScope.PAGE_NAME.
 SearchScope.PAGE_NAMES=Pagina naam
+#Formerly named org.apache.wiki.action.InstallActionBean.testLdapConnection.
+org.apache.wiki.action.InstallActionBean.ldapConnection=Test verbinding
+#Formerly named org.apache.wiki.action.InstallActionBean.testLdapAuthentication.
+org.apache.wiki.action.InstallActionBean.ldapAuthentication=Test authenticatie
+#Formerly named org.apache.wiki.action.InstallActionBean.testLdapUsers.
+org.apache.wiki.action.InstallActionBean.ldapUsers=Test gebruikers lookups
+#Formerly named org.apache.wiki.action.InstallActionBean.testLdapRoles.
+org.apache.wiki.action.InstallActionBean.ldapRoles=Test rol lookups

Modified: incubator/jspwiki/trunk/src/WebContent/scripts/jspwiki-common.js
URL: http://svn.apache.org/viewvc/incubator/jspwiki/trunk/src/WebContent/scripts/jspwiki-common.js?rev=915545&r1=915544&r2=915545&view=diff
==============================================================================
--- incubator/jspwiki/trunk/src/WebContent/scripts/jspwiki-common.js (original)
+++ incubator/jspwiki/trunk/src/WebContent/scripts/jspwiki-common.js Tue Feb 23 22:02:47 2010
@@ -1915,8 +1915,8 @@
 	render: function(page, name){
 		page = $(page); if(!page) return;
 
-		var cookie = Wiki.Context.test(/view|edit|comment/) ? "JSPWiki"+name : "";
-		//var cookie = "";  //activate this line if you want to deactivatie cookie handling
+		//var cookie = Wiki.Context.test(/view|edit|comment/) ? "JSPWiki"+name : "";
+		var cookie = "";  //activate this line if you want to deactivatie cookie handling
 
 		if(!this.bullet) {
 			this.bullet = new Element('div',{'class':'collapseBullet'}).set('html','•');
@@ -2929,15 +2929,18 @@
                 event method must return an EventResolution, the response
                 for which will be eval'ed and be assigned to the variable
                 'eventResponse.' See org.apache.wiki.ui.stripes.EventResolution.
-    divTarget - if the 'eventResponse' variable returned by the AJAX call
-                has an 'html' property whose boolean value is true,
-                the results will be injected into this target div.
+    divTarget - if the 'callback' function is not supplied, the results returned
+                by the AJAX call will be injected into this target div as a
+                single string that includes the HTML representation of any Stripes
+                messages or validation errors prepended, plus the result object(s).
+                The entire string will be wrapped in a <div> whose class is
+                "eventResponse".
     callback -  a callback function to invoke. The 'eventResponse' variable
-                will be passed to this function. It contains the response
-                object, which can be any primitive type, an array, map
+                will be passed to this function as a parameter. It contains the
+                response object, which can be any primitive type, an array, map
                 or anything supported by net.sourceforge.stripes.ajax.JavaScriptBuilder.
-                It also contains a list of validation errors messages and
-                the 'html' boolean property.
+                It also contains two properties that contain HTML representations of
+                any errors or Stripes messages set server-side.
   */
   submitFormEvent: function( formName, event, divTarget, callback ){
     var form = $(formName);
@@ -2949,12 +2952,17 @@
       method: 'post',
       evalResponse: true,
       onComplete: function(response) {
-        // If HTML response, put results into the div
-        if (eventResponse.html) {
+        // If no custom callback function supplied, put results into the div
+        if (!callback) {
+          var newContent = '<div class="eventResponse">';
+          if (eventResponse.errors) { newContent += eventResponse.errors; }
+          if (eventResponse.messages) { newContent += eventResponse.messages; }
+          if (eventResponse.results) { newContent += eventResponse.results; }
+          newContent += "</div>";
           $(divTarget).empty();
-          $(divTarget).set('html',eventResponse.results);
+          $(divTarget).set('html',newContent);
         }
-        // Call the callback function
+        // Otherwise, call the callback function
         if (callback) {
           callback(eventResponse);
         }

Modified: incubator/jspwiki/trunk/src/java/org/apache/wiki/action/EditActionBean.java
URL: http://svn.apache.org/viewvc/incubator/jspwiki/trunk/src/java/org/apache/wiki/action/EditActionBean.java?rev=915545&r1=915544&r2=915545&view=diff
==============================================================================
--- incubator/jspwiki/trunk/src/java/org/apache/wiki/action/EditActionBean.java (original)
+++ incubator/jspwiki/trunk/src/java/org/apache/wiki/action/EditActionBean.java Tue Feb 23
22:02:47 2010
@@ -107,6 +107,7 @@
      * @return always returns a {@link EventResolution} containing the
      * results
      */
+    @AjaxEvent
     @HandlesEvent( "preview" )
     @HandlerPermission( permissionClass = PagePermission.class, target = "${page.path}",
actions = PagePermission.VIEW_ACTION )
     @WikiRequestContext( "preview" )
@@ -123,7 +124,7 @@
         String result = renderer.getHTML( context, doc );
 
         // Return an EventResolution
-        Resolution r = new EventResolution( context, result, true );
+        Resolution r = new EventResolution( context, result );
         return r;
     }
 

Modified: incubator/jspwiki/trunk/src/java/org/apache/wiki/action/EditDialogActionBean.java
URL: http://svn.apache.org/viewvc/incubator/jspwiki/trunk/src/java/org/apache/wiki/action/EditDialogActionBean.java?rev=915545&r1=915544&r2=915545&view=diff
==============================================================================
--- incubator/jspwiki/trunk/src/java/org/apache/wiki/action/EditDialogActionBean.java (original)
+++ incubator/jspwiki/trunk/src/java/org/apache/wiki/action/EditDialogActionBean.java Tue
Feb 23 22:02:47 2010
@@ -80,6 +80,6 @@
             log.debug("Suggestion request for "+wikiName+" done in "+sw );
         }
         
-        return new EventResolution( getContext(), list, false );
+        return new EventResolution( getContext(), list );
     }
 }

Modified: incubator/jspwiki/trunk/src/java/org/apache/wiki/action/InstallActionBean.java
URL: http://svn.apache.org/viewvc/incubator/jspwiki/trunk/src/java/org/apache/wiki/action/InstallActionBean.java?rev=915545&r1=915544&r2=915545&view=diff
==============================================================================
--- incubator/jspwiki/trunk/src/java/org/apache/wiki/action/InstallActionBean.java (original)
+++ incubator/jspwiki/trunk/src/java/org/apache/wiki/action/InstallActionBean.java Tue Feb
23 22:02:47 2010
@@ -38,9 +38,11 @@
 import javax.servlet.ServletContext;
 
 import net.sourceforge.stripes.action.*;
-import net.sourceforge.stripes.ajax.JavaScriptResolution;
 import net.sourceforge.stripes.controller.LifecycleStage;
-import net.sourceforge.stripes.validation.*;
+import net.sourceforge.stripes.validation.SimpleError;
+import net.sourceforge.stripes.validation.Validate;
+import net.sourceforge.stripes.validation.ValidateNestedProperties;
+import net.sourceforge.stripes.validation.ValidationErrors;
 
 import org.apache.wiki.WikiEngine;
 import org.apache.wiki.auth.AuthenticationManager;
@@ -53,7 +55,7 @@
 import org.apache.wiki.auth.user.UserDatabase;
 import org.apache.wiki.auth.user.UserProfile;
 import org.apache.wiki.auth.user.XMLUserDatabase;
-import org.apache.wiki.ui.stripes.WikiRequestContext;
+import org.apache.wiki.ui.stripes.*;
 import org.apache.wiki.util.CommentedProperties;
 import org.apache.wiki.util.CryptoUtil;
 import org.apache.wiki.util.PropertyReader;
@@ -61,7 +63,7 @@
 import org.freshcookies.security.Keychain;
 
 @HttpCache( allow = false )
-public class InstallActionBean extends AbstractActionBean implements ValidationErrorHandler
+public class InstallActionBean extends AbstractActionBean
 {
     /**
      * Wrapper class that encapsulates a properties file as a Stripes-friendly
@@ -403,29 +405,6 @@
     }
 
     /**
-     * Intercepts any validation errors generated by the various AJAX "text"
-     * methods and returns them to the client as an array of JSON-encoded
-     * strings.
-     */
-    public Resolution handleValidationErrors( ValidationErrors errors ) throws Exception
-    {
-        String event = getContext().getEventName();
-        if( event.startsWith( "test" ) && errors.size() > 0 )
-        {
-            Set<String> errorStrings = new HashSet<String>();
-            for( Map.Entry<String, List<ValidationError>> errorList : errors.entrySet()
)
-            {
-                for( ValidationError error : errorList.getValue() )
-                {
-                    errorStrings.add( error.getMessage( getContext().getLocale() ) );
-                }
-            }
-            return new JavaScriptResolution( errorStrings.toArray( new String[errorStrings.size()]
) );
-        }
-        return null;
-    }
-
-    /**
      * Pre-action that loads the JSPWiki properties file before user-supplied
      * parameters are bound to the ActionBean.
      * 
@@ -482,9 +461,9 @@
         initKeychain( path, jspwiki );
 
         // Set some sensible defaults
-        if( !jspwiki.containsKey( CONFIG_BASE_URL ) )
+        if( !jspwiki.containsKey( CONFIG_BASE_URL ) || jspwiki.get( CONFIG_BASE_URL ).trim().length()
==  0 )
         {
-            jspwiki.put( CONFIG_BASE_URL, "http://localhost:8080/JSPWiki" );
+            jspwiki.put( CONFIG_BASE_URL, "http://localhost:8080/JSPWiki/" );
         }
         if( !jspwiki.containsKey( CONFIG_USERDATABASE ) )
         {
@@ -513,9 +492,10 @@
 
     /**
      * Default Stripes event handler method that loads up the current
-     * configuration settings and forwards the user to the display JSP.
+     * configuration settings and forwards the user to the template JSP.
      * 
-     * @return always returns a ForwardResolution to {@code /admin/Install.jsp}
+     * @return always returns a TemplateResolution to template JSP
+     * {@code admin/Install.jsp}
      */
     @DefaultHandler
     @DontValidate
@@ -523,14 +503,14 @@
     @WikiRequestContext( "install" )
     public Resolution install()
     {
-        return new ForwardResolution( "/admin/Install.jsp" );
+        return new TemplateResolution( "admin/Install.jsp" );
     }
 
     /**
      * Saves the properties files with updated settings, and restarts the wiki.
      * 
      * @return if successful, always returns a {@link ForwardResolution} to
-     *         {@code /admin/InstallSuccess.jsp}.
+     *         template JSP {@code admin/InstallSuccess.jsp}.
      * @throws Exception
      */
     @HandlesEvent( "save" )
@@ -580,7 +560,7 @@
         WikiEngine engine = getContext().getEngine();
         engine.restart();
 
-        return new RedirectResolution( "/admin/InstallSuccess.jsp" );
+        return new TemplateResolution( "admin/InstallSuccess.jsp" );
     }
 
     /**
@@ -645,11 +625,13 @@
 
     /**
      * AJAX event method that tests LDAP authentication based on the bind-user
-     * settings, returning any results as an array of JavaScript strings.
+     * settings, returning an {@link EventResolution} whose response object is
+     * an array of strings.
      * 
      * @return the results
      * @throws WikiSecurityException
      */
+    @AjaxEvent
     @HandlesEvent( "testLdapAuthentication" )
     public Resolution testLdapAuthentication() throws WikiSecurityException
     {
@@ -661,118 +643,126 @@
 
     /**
      * AJAX event method that tests the connection to the LDAP server, returning
-     * any results as an array of JavaScript strings.
+     * an {@link EventResolution} whose response object is
+     * an array of strings.
      * 
      * @return the results
      * @throws WikiSecurityException
      */
+    @AjaxEvent
     @HandlesEvent( "testLdapConnection" )
     public Resolution testLdapConnection() throws WikiSecurityException
     {
-        List<String> messages = new ArrayList<String>();
+        WikiActionBeanContext context = getContext();
         try
         {
-            initLdapConnection( messages );
-            messages.add( "Success!" );
+            initLdapConnection();
+            List<Message> messages = context.getMessages();
+            messages.add( new SimpleMessage( "Success!" ) );
         }
         catch( Exception e )
         {
-            messages.add( "Error: " + e.getMessage() );
+            ValidationErrors errors = context.getValidationErrors();
+            errors.addGlobalError( new SimpleError( e.getMessage() ) );
             if( e.getCause() != null )
             {
-                messages.add( " Cause: " + e.getCause().getMessage() );
+                errors.addGlobalError( new SimpleError( " Cause: " + e.getCause().getMessage()
) );
             }
         }
-        Resolution r = new JavaScriptResolution( messages.toArray( new String[messages.size()]
) );
-        return r;
+        return new EventResolution( getContext() );
     }
 
     /**
      * AJAX event method that tests the LDAP role lookups based on the
-     * configured user base.
+     * configured user base, returning an {@link EventResolution}
+     * whose response object is an array of strings.
      * 
      * @return the results
      * @throws WikiSecurityException
      */
+    @AjaxEvent
     @HandlesEvent( "testLdapRoles" )
     public Resolution testLdapRoleLookup() throws WikiSecurityException
     {
-        WikiEngine engine = getContext().getEngine();
+        WikiActionBeanContext context = getContext();
         PropertiesMap<String, String> jspwiki = m_properties.get( "jspwiki" );
-        List<String> messages = new ArrayList<String>();
         try
         {
             // Initialize a new user authorizer
             Authorizer authorizer = new LdapAuthorizer();
-            authorizer.initialize( engine, jspwiki.m_props );
+            authorizer.initialize( context.getEngine(), jspwiki.m_props );
 
             // Count roles
+            List<Message> messages = context.getMessages();
             Principal[] principals = authorizer.getRoles();
-            messages.add( "Found " + principals.length + " roles." );
+            messages.add( new SimpleMessage( "Found " + principals.length + " roles." ) );
 
             // Get first role details
             if( principals.length > 0 )
             {
-                messages.add( "Details for first role..." );
-                messages.add( "Name: " + principals[0].getName() );
+                messages.add( new SimpleMessage( "Details for first role..." ) );
+                messages.add( new SimpleMessage( "Name: " + principals[0].getName() ) );
             }
         }
         catch( Exception e )
         {
-            messages.add( "Error: " + e.getMessage() );
+            ValidationErrors errors = context.getValidationErrors();
+            errors.addGlobalError( new SimpleError( "Error: " + e.getMessage() ) );
             if( e.getCause() != null )
             {
-                messages.add( " Cause: " + e.getCause().getMessage() );
+                errors.addGlobalError( new SimpleError( " Cause: " + e.getCause().getMessage()
) );
             }
         }
-        return new JavaScriptResolution( messages.toArray( new String[messages.size()] )
);
+        return new EventResolution( getContext() );
     }
 
     /**
      * AJAX event method that tests the LDAP user lookups based on the
-     * configured user base. server, returning any results as an array of
-     * JavaScript strings.
+     * configured user base, returning an {@link EventResolution} whose
+     * response object is an array of strings.
      * 
      * @return the results
      * @throws WikiSecurityException
      */
+    @AjaxEvent
     @HandlesEvent( "testLdapUsers" )
     public Resolution testLdapUserLookup()
     {
-        WikiEngine engine = getContext().getEngine();
+        WikiActionBeanContext context = getContext();
         PropertiesMap<String, String> jspwiki = m_properties.get( "jspwiki" );
-        List<String> messages = new ArrayList<String>();
         try
         {
             // Initialize a new user database
             UserDatabase db = new LdapUserDatabase();
-            db.initialize( engine, jspwiki.m_props );
+            db.initialize( context.getEngine(), jspwiki.m_props );
 
             // Count users
+            List<Message> messages = context.getMessages();
             Principal[] principals = db.getWikiNames();
-            messages.add( "Found " + principals.length + " users." );
+            messages.add( new SimpleMessage( "Found " + principals.length + " users." ) );
 
             // Get first user details
             if( principals.length > 0 )
             {
                 UserProfile user = db.findByWikiName( principals[0].getName() );
-                messages.add( "Details for first user..." );
-                messages.add( "Uid: " + user.getUid() );
-                messages.add( "Login name: " + user.getLoginName() );
-                messages.add( "Full name: " + user.getFullname() );
-                messages.add( "Wiki name: " + user.getWikiName() );
-                messages.add( "E-mail: " + user.getEmail() );
+                messages.add( new SimpleMessage( "Details for first user..." ) );
+                messages.add( new SimpleMessage( "Uid: " + user.getUid() ) );
+                messages.add( new SimpleMessage( "Login name: " + user.getLoginName() ) );
+                messages.add( new SimpleMessage( "Full name: " + user.getFullname() ) );
+                messages.add( new SimpleMessage( "Wiki name: " + user.getWikiName() ) );
+                messages.add( new SimpleMessage( "E-mail: " + user.getEmail() ) );
             }
         }
         catch( Exception e )
         {
-            messages.add( "Error: " + e.getMessage() );
+            ValidationErrors errors = context.getValidationErrors();
+            errors.addGlobalError( new SimpleError( e.getMessage() ) );
             if( e.getCause() != null )
             {
-                messages.add( " Cause: " + e.getCause().getMessage() );
+                errors.addGlobalError( new SimpleError( " Cause: " + e.getCause().getMessage()
) );
             }
         }
-        return new JavaScriptResolution( messages.toArray( new String[messages.size()] )
);
+        return new EventResolution( getContext() );
     }
 
     /**
@@ -828,22 +818,23 @@
      * @throws NamingException if a connection cannot be made to the LDAP server
      *             for any reason
      */
-    private LdapContext initLdapConnection( List<String> messages ) throws NamingException
+    private LdapContext initLdapConnection() throws NamingException
     {
         PropertiesMap<String, String> jspwiki = m_properties.get( "jspwiki" );
         LdapConfig config = LdapConfig.getInstance( m_keychain, jspwiki.m_props, new String[0]
);
         Hashtable<String, String> env;
+        List<Message> messages = getContext().getMessages();
         if( !jspwiki.containsKey( "ldap_bindUser" ) )
         {
             env = config.newJndiEnvironment();
-            messages.add( "Binding as anonymous user." );
+            messages.add( new SimpleMessage( "Binding as anonymous user." ) );
         }
         else
         {
             String username = jspwiki.get( "ldap_bindUser" );
             env = config.newJndiEnvironment( username, m_bindPassword );
             Object principal = env.get( Context.SECURITY_PRINCIPAL );
-            messages.add( "Binding with principal: " + principal.toString() );
+            messages.add( new SimpleMessage( "Binding with principal: " + principal.toString()
) );
         }
         return new InitialLdapContext( env, null );
     }

Modified: incubator/jspwiki/trunk/src/java/org/apache/wiki/action/SearchActionBean.java
URL: http://svn.apache.org/viewvc/incubator/jspwiki/trunk/src/java/org/apache/wiki/action/SearchActionBean.java?rev=915545&r1=915544&r2=915545&view=diff
==============================================================================
--- incubator/jspwiki/trunk/src/java/org/apache/wiki/action/SearchActionBean.java (original)
+++ incubator/jspwiki/trunk/src/java/org/apache/wiki/action/SearchActionBean.java Tue Feb
23 22:02:47 2010
@@ -36,6 +36,7 @@
 import org.apache.wiki.log.Logger;
 import org.apache.wiki.log.LoggerFactory;
 import org.apache.wiki.search.SearchResult;
+import org.apache.wiki.ui.stripes.AjaxEvent;
 import org.apache.wiki.ui.stripes.EventResolution;
 import org.apache.wiki.ui.stripes.TemplateResolution;
 import org.apache.wiki.ui.stripes.WikiRequestContext;
@@ -214,9 +215,10 @@
      * for this ActionBean. Results are streamed back to the client as an array
      * of JSON-encoded SearchResult objects.
      * 
-     * @return always returns a {@link JavaScriptResolution} containing the
+     * @return always returns an {@link EventResolution} containing the
      *         results; this may be a zero-length array
      */
+    @AjaxEvent
     @HandlesEvent( "ajaxSearch" )
     public Resolution ajaxSearch()
     {
@@ -230,6 +232,7 @@
      * @return a {@link EventResolution} containing HTML to be inserted into an
      *         element.
      */
+    @AjaxEvent
     @HandlesEvent( "quickSearch" )
     public Resolution quickSearch()
     {
@@ -250,6 +253,6 @@
             b.append( "</ul>" );
             html = b.toString();
         }
-        return new EventResolution( getContext(), html, true );
+        return new EventResolution( getContext(), html );
     }
 }

Added: incubator/jspwiki/trunk/src/java/org/apache/wiki/ui/stripes/AjaxEvent.java
URL: http://svn.apache.org/viewvc/incubator/jspwiki/trunk/src/java/org/apache/wiki/ui/stripes/AjaxEvent.java?rev=915545&view=auto
==============================================================================
--- incubator/jspwiki/trunk/src/java/org/apache/wiki/ui/stripes/AjaxEvent.java (added)
+++ incubator/jspwiki/trunk/src/java/org/apache/wiki/ui/stripes/AjaxEvent.java Tue Feb 23
22:02:47 2010
@@ -0,0 +1,17 @@
+package org.apache.wiki.ui.stripes;
+
+import java.lang.annotation.*;
+
+/**
+ * Method-level annotation indicating that an event is an AJAX event. Any
+ * validation errors will be intercepted after the
+ * {@link net.sourceforge.stripes.controller.LifecycleStage#CustomValidation}
+ * stage and returned as an {@link org.apache.wiki.ui.stripes.EventResolution}.
+ */
+@Documented
+@Inherited
+@Retention( value = RetentionPolicy.RUNTIME )
+@Target( { ElementType.METHOD } )
+public @interface AjaxEvent
+{
+}

Modified: incubator/jspwiki/trunk/src/java/org/apache/wiki/ui/stripes/EventResolution.java
URL: http://svn.apache.org/viewvc/incubator/jspwiki/trunk/src/java/org/apache/wiki/ui/stripes/EventResolution.java?rev=915545&r1=915544&r2=915545&view=diff
==============================================================================
--- incubator/jspwiki/trunk/src/java/org/apache/wiki/ui/stripes/EventResolution.java (original)
+++ incubator/jspwiki/trunk/src/java/org/apache/wiki/ui/stripes/EventResolution.java Tue Feb
23 22:02:47 2010
@@ -1,8 +1,9 @@
 package org.apache.wiki.ui.stripes;
 
-import java.util.ArrayList;
 import java.util.List;
-import java.util.Set;
+import java.util.Locale;
+import java.util.MissingResourceException;
+import java.util.ResourceBundle;
 
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
@@ -11,6 +12,9 @@
 import net.sourceforge.stripes.action.Message;
 import net.sourceforge.stripes.action.Resolution;
 import net.sourceforge.stripes.ajax.JavaScriptBuilder;
+import net.sourceforge.stripes.controller.StripesFilter;
+import net.sourceforge.stripes.tag.ErrorsTag;
+import net.sourceforge.stripes.tag.MessagesTag;
 import net.sourceforge.stripes.validation.ValidationError;
 import net.sourceforge.stripes.validation.ValidationErrors;
 
@@ -22,67 +26,82 @@
  * ActionBeanContext messages and validation errors. It has four properties:
  * </p>
  * <ul>
- * <li>{@code results} - the Object that contains the results of the AJAX call.
- * This can be just about anything that
- * {@link net.sourceforge.stripes.ajax.JavaScriptBuilder} can encode.</li>
- * <li>{@code fieldErrors} - any field-level errors</li>
- * <li>{@code globalErrors} - any global errors</li>
- * <li>{@code messages} - any messages</li>
- * <li>{@code isHtml} - whether the results should be treated as HTML (for
- * example, to inject directly into a {@code div})</li>
+ * <li>{@code results} - the Object (or an array of Objects) that represents
+ * the results of the AJAX call. The object or objects can be just about anything that
+ * {@link net.sourceforge.stripes.ajax.JavaScriptBuilder} can encode.
+ * It is most commonly a single HTML string.</li>
+ * <li>{@code errors} - any global or field-level errors, as an HTML string. If
+ * no errors, this property will be {@code null}</li>
+ * <li>{@code messages} - any messages, as an HTML string. If no messages, this
+ * property will be {@code null}</li>
  * </ul>
+ * <p>
+ * Error and message strings are generated in the same way that the Stripes
+ * {@link net.sourceforge.stripes.tag.ErrorsTag} and
+ * {@link net.sourceforge.stripes.tag.MessagesTag} work. For errors, the
+ * contents of i18n message {@code stripes.errors.header} is prepended. Then,
+ * for each error, the message {@code stripes.errors.beforeError} is added, then
+ * the error text, then {@code stripes.errors.afterError}. Finally, the message
+ * {@code stripes.errors.footer} is appended. For messages, the string is
+ * generated the same way except that the messages {@code
+ * stripes.messages.header}, {@code stripes.messages.beforeMessage}, {@code
+ * stripes.messages.afterMessage} and {@code stripes.messages.footer} are used.
+ * </p>
  */
 public class EventResolution implements Resolution
 {
+    /**
+     * Lightweight class that represents the result of an AJAX call, including
+     * any Stripes messages or validation errors.
+     */
     public static class Result
     {
-        private final List<ValidationError> m_globalErrors = new ArrayList<ValidationError>();
-
-        private final List<ValidationError> m_fieldErrors = new ArrayList<ValidationError>();
+        private final String m_errors;
 
-        private final List<Message> m_messages;
+        private final String m_messages;
 
         private final Object m_rootObject;
 
-        private final boolean m_isHtml;
-
         /**
          * Constructs a new EventResolution.
          * 
          * @param context the ActionBeanContext that supplies the messages and
          *            validation errors.
-         * @param rootObject the Object to be encoded
-         * @param isHtml whether the results should be interpreted as HTML
+         * @param objects zero or more Objects to be returned
          */
-        public Result( ActionBeanContext context, Object rootObject, boolean isHtml )
+        public Result( ActionBeanContext context, Object... objects )
         {
             super();
 
             // Set the messages
-            m_messages = context.getMessages();
+            m_messages = context.getMessages().size() > 0 ? generateMessages( context
) : null;
 
             // Set the validation errors
-            ValidationErrors errors = context.getValidationErrors();
-            Set<String> fields = errors.keySet();
-            for( String field : fields )
+            m_errors = context.getValidationErrors().size() > 0 ? generateErrors( context
) : null;
+
+            // Set the root object
+            if ( objects.length == 1 )
             {
-                List<ValidationError> fieldErrors = errors.get( field );
-                if( fieldErrors != null )
-                {
-                    if( ValidationErrors.GLOBAL_ERROR.equals( field ) )
-                    {
-                        m_globalErrors.addAll( fieldErrors );
-                    }
-                    else
-                    {
-                        m_fieldErrors.addAll( fieldErrors );
-                    }
-                }
+                m_rootObject = objects[0];
+            }
+            else if ( objects.length > 0 )
+            {
+                m_rootObject = objects;
             }
+            else
+            {
+                m_rootObject = null;
+            }
+        }
 
-            // Set the root object & HTML properties
-            m_rootObject = rootObject;
-            m_isHtml = isHtml;
+        /**
+         * Return the errors set by the event.
+         * 
+         * @return the errors
+         */
+        public String getErrors()
+        {
+            return m_errors;
         }
 
         /**
@@ -90,58 +109,129 @@
          * 
          * @return the messages
          */
-        public List<Message> getMessages()
+        public String getMessages()
         {
             return m_messages;
         }
 
         /**
-         * Return the global ValidationErrors set by the event.
+         * Returns the result of the AJAX call. If no objects were passed
+         * to the constructor, this method returns {@code null}. If one
+         * was passed, that object will be returned. Otherwise, an array of
+         * objects will be returned.
          * 
-         * @return the errors
+         * @return the root object; {@code null}, one object, or an array of objects
          */
-        public List<ValidationError> getGlobalErrors()
+        public Object getResults()
         {
-            return m_globalErrors;
+            return m_rootObject;
         }
 
         /**
-         * Return the field-level ValidationErrors set by the event.
-         * 
-         * @return the errors
-         */
-        public List<ValidationError> getFieldErrors()
-        {
-            return m_fieldErrors;
+         * Generates an HTML-formatted String representing the errors contained by
+         * an ActionBeanContext. Global errors will be first, followed by
+         * field-level errors. The contents will be localized according to the
+         * user's locale.
+         * 
+         * @param context the context
+         * @return the form
+         */
+        private String generateErrors( ActionBeanContext context )
+        {
+            Locale locale = context.getLocale();
+            ResourceBundle bundle = StripesFilter.getConfiguration().getLocalizationBundleFactory().getErrorMessageBundle(
locale );
+
+            // Fetch the error headers and footers
+            String header = getMessage( bundle, "stripes.errors.header", ErrorsTag.DEFAULT_HEADER
);
+            String footer = getMessage( bundle, "stripes.errors.footer", ErrorsTag.DEFAULT_FOOTER
);
+            String beforeError = getMessage( bundle, "stripes.errors.beforeError", "<li>"
);
+            String afterError = getMessage( bundle, "stripes.errors.afterError", "</li>"
);
+
+            // Write out the error messages
+            StringBuilder s = new StringBuilder();
+            s.append( header );
+            ValidationErrors errors = context.getValidationErrors();
+            for( List<ValidationError> errorList : errors.values() )
+            {
+                for ( ValidationError error : errorList )
+                {
+                    s.append( beforeError );
+                    s.append( error.getMessage( locale ) );
+                    s.append( afterError );
+                }
+            }
+            s.append( footer );
+            return s.toString();
         }
 
         /**
-         * Returns the root object.
+         * Generates an HTML-formatted String representing the messages contained by
+         * an ActionBeanContext. The contents will be localized according to the
+         * user's locale.
          * 
-         * @return the root object
+         * @param context the context
+         * @return the form
          */
-        public Object getResults()
+        private String generateMessages( ActionBeanContext context )
         {
-            return m_rootObject;
+            Locale locale = context.getLocale();
+            ResourceBundle bundle = StripesFilter.getConfiguration().getLocalizationBundleFactory().getErrorMessageBundle(
locale );
+
+            // Fetch the message headers and footers
+            String header = getMessage( bundle, "stripes.messages.header", MessagesTag.DEFAULT_HEADER
);
+            String footer = getMessage( bundle, "stripes.messages.footer", MessagesTag.DEFAULT_FOOTER
);
+            String beforeMessage = getMessage( bundle, "stripes.messages.beforeMessage",
"<li>" );
+            String afterMessage = getMessage( bundle, "stripes.messages.afterMessage", "</li>"
);
+
+            // Write out the error messages
+            StringBuilder s = new StringBuilder();
+            s.append( header );
+            for( Message message : context.getMessages() )
+            {
+                s.append( beforeMessage );
+                s.append( message.getMessage( locale ) );
+                s.append( afterMessage );
+            }
+            s.append( footer );
+            return s.toString();
         }
 
         /**
-         * Returns {@code true} if the result should be interpreted as HTML,
-         * rather than as a JavaScript object that should be {@code eval}-ed.
-         * 
-         * @return the result
+         * Looks up a message in a MessageBundle with a given key. If the key is not
+         * found in the ResourceBundle, a default value is returned. 
+         * @param bundle the message bundle
+         * @param key the message key to loop up
+         * @param defaultValue the value to return if the message is not found
+         * @return
          */
-        public boolean isHtml()
+        private String getMessage( ResourceBundle bundle, String key, String defaultValue
)
         {
-            return m_isHtml;
+            String value = null;
+            try
+            {
+                value = bundle.getString( key );
+            }
+            catch( MissingResourceException mre )
+            {
+                value = defaultValue;
+            }
+            return value;
         }
     }
 
     private final JavaScriptBuilder m_builder;
-
-    public EventResolution( ActionBeanContext context, Object rootObject, boolean isHtml
)
+    
+    /**
+     * Constructs a new EventResolution for a supplied ActionBeanContext and
+     * result objects.
+     * @param context the ActionBeanContext
+     * @param objects zero, one or more objects that represent the result
+     * of an {@link org.apache.wiki.ui.stripes.AjaxEvent}-annotated
+     * event method
+     */
+    public EventResolution( ActionBeanContext context, Object... objects )
     {
-        m_builder = new JavaScriptBuilder( new Result( context, rootObject, isHtml ) );
+        m_builder = new JavaScriptBuilder( new Result( context, objects ) );
     }
 
     /**

Modified: incubator/jspwiki/trunk/src/java/org/apache/wiki/ui/stripes/WikiInterceptor.java
URL: http://svn.apache.org/viewvc/incubator/jspwiki/trunk/src/java/org/apache/wiki/ui/stripes/WikiInterceptor.java?rev=915545&r1=915544&r2=915545&view=diff
==============================================================================
--- incubator/jspwiki/trunk/src/java/org/apache/wiki/ui/stripes/WikiInterceptor.java (original)
+++ incubator/jspwiki/trunk/src/java/org/apache/wiki/ui/stripes/WikiInterceptor.java Tue Feb
23 22:02:47 2010
@@ -32,9 +32,11 @@
 import javax.servlet.jsp.PageContext;
 
 import net.sourceforge.stripes.action.ActionBean;
+import net.sourceforge.stripes.action.ActionBeanContext;
 import net.sourceforge.stripes.action.RedirectResolution;
 import net.sourceforge.stripes.action.Resolution;
 import net.sourceforge.stripes.controller.*;
+import net.sourceforge.stripes.validation.ValidationErrors;
 
 import org.apache.wiki.WikiEngine;
 import org.apache.wiki.WikiSession;
@@ -333,11 +335,14 @@
      * {@link net.sourceforge.stripes.controller.LifecycleStage#CustomValidation}
      * lifecycle stage, to ensure that it runs after all
      * {@link net.sourceforge.stripes.controller.LifecycleStage#BindingAndValidation}
-     * interceptors, and checks for proper access to the current ActionBean and
-     * target event. The access-checking logic runs after after the rest of the
-     * BindingAndValidation processing logic does, after which point Stripes has
-     * already discovered the correct ActionBean, and bound and validated its
-     * request parameters.
+     * interceptors, checks for validation errors generated by AJAX event methods,
+     * and then checks for proper access to the current ActionBean and
+     * target event.</p>
+     * <p>
+     * To ensure that AJAX-related validation errors are handled correctly, if the
+     * current event method is annotated with {@link org.apache.wiki.ui.stripes.AjaxEvent},
+     * an {@link org.apache.wiki.ui.stripes.EventResolution} will be returned
+     * if one or more validation errors were generated earlier in the lifecycle.
      * </p>
      * <p>
      * To determine if the user is allowed to access the target event method,
@@ -349,6 +354,11 @@
      * returns <code>false</code> -- this method returns a RedirectResolution
to
      * the login page, with all current parameters appended.
      * </p>
+     * <p>Both the AJAX-error and access-checking logic run after after the
+     * rest of the BindingAndValidation processing logic does, after which
+     * point Stripes will have already discovered the correct ActionBean,
+     * and bound and validated its request parameters.
+     * </p>
      * 
      * @param context the execution context
      * @return a Resolution if the
@@ -367,9 +377,17 @@
             return r;
         }
 
+        // If handler is AJAX method, check for validation errors (and bail if there were
any)
+        ActionBeanContext actionBeanContext = context.getActionBeanContext();
+        ValidationErrors errors = actionBeanContext.getValidationErrors();
+        Method handler = context.getHandler();
+        if ( handler.getAnnotation( AjaxEvent.class ) != null && errors.size() >
0 )
+        {
+            return new EventResolution( actionBeanContext );
+        }
+
         // Get the event handler method
         WikiActionBean actionBean = (WikiActionBean) context.getActionBean();
-        Method handler = context.getHandler();
         Map<Method, HandlerInfo> eventinfos = HandlerInfo.getHandlerInfoCollection(
actionBean.getClass() );
         HandlerInfo eventInfo = eventinfos.get( handler );
 



Mime
View raw message