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 2010/02/20 19:08:03 UTC

svn commit: r912172 - in /incubator/jspwiki/trunk: src/WebContent/templates/default/ src/java/org/apache/wiki/ src/java/org/apache/wiki/action/ src/java/org/apache/wiki/auth/ src/java/org/apache/wiki/content/ src/java/org/apache/wiki/plugin/ src/java/o...

Author: ajaquith
Date: Sat Feb 20 18:08:02 2010
New Revision: 912172

URL: http://svn.apache.org/viewvc?rev=912172&view=rev
Log:
Fixed multiple bugs in Preferences and Preferences.jsp. Asserted names were not being set when "save prefs" button was pushed. PreferencesLocalePicker was not correctly matching incoming browser Locales to those available on the server. Time zones were not correctly being set. Preferences also had a static-method fetish, which was unnatural. It has been refactored completely and thoroughly.

Added:
    incubator/jspwiki/trunk/src/java/org/apache/wiki/ui/stripes/TimeZoneFormatter.java
Modified:
    incubator/jspwiki/trunk/src/WebContent/templates/default/Preferences.jsp
    incubator/jspwiki/trunk/src/java/org/apache/wiki/VariableManager.java
    incubator/jspwiki/trunk/src/java/org/apache/wiki/WikiContext.java
    incubator/jspwiki/trunk/src/java/org/apache/wiki/action/EditActionBean.java
    incubator/jspwiki/trunk/src/java/org/apache/wiki/action/UserPreferencesActionBean.java
    incubator/jspwiki/trunk/src/java/org/apache/wiki/auth/SessionMonitor.java
    incubator/jspwiki/trunk/src/java/org/apache/wiki/content/ReferenceManager.java
    incubator/jspwiki/trunk/src/java/org/apache/wiki/plugin/AbstractFilteredPlugin.java
    incubator/jspwiki/trunk/src/java/org/apache/wiki/plugin/CurrentTimePlugin.java
    incubator/jspwiki/trunk/src/java/org/apache/wiki/plugin/RecentChangesPlugin.java
    incubator/jspwiki/trunk/src/java/org/apache/wiki/plugin/WeblogPlugin.java
    incubator/jspwiki/trunk/src/java/org/apache/wiki/preferences/Preferences.java
    incubator/jspwiki/trunk/src/java/org/apache/wiki/tags/PageDateTag.java
    incubator/jspwiki/trunk/src/java/org/apache/wiki/ui/EditorManager.java
    incubator/jspwiki/trunk/src/java/org/apache/wiki/ui/TemplateManager.java
    incubator/jspwiki/trunk/src/java/org/apache/wiki/ui/stripes/PreferencesLocalePicker.java
    incubator/jspwiki/trunk/src/java/org/apache/wiki/ui/stripes/WikiInterceptor.java
    incubator/jspwiki/trunk/tests/java/org/apache/wiki/VariableManagerTest.java
    incubator/jspwiki/trunk/tests/java/org/apache/wiki/action/UserPreferencesActionBeanTest.java

Modified: incubator/jspwiki/trunk/src/WebContent/templates/default/Preferences.jsp
URL: http://svn.apache.org/viewvc/incubator/jspwiki/trunk/src/WebContent/templates/default/Preferences.jsp?rev=912172&r1=912171&r2=912172&view=diff
==============================================================================
--- incubator/jspwiki/trunk/src/WebContent/templates/default/Preferences.jsp (original)
+++ incubator/jspwiki/trunk/src/WebContent/templates/default/Preferences.jsp Sat Feb 20 18:08:02 2010
@@ -24,7 +24,6 @@
 <%@ taglib uri="http://jakarta.apache.org/jspwiki.tld" prefix="wiki" %>
 <%@ taglib uri="http://stripes.sourceforge.net/stripes.tld" prefix="s" %>
 <%@ page import="javax.servlet.jsp.jstl.fmt.*" %>
-<%@ page errorPage="/Error.jsp" %>
 <s:layout-render name="${templates['layout/DefaultLayout.jsp']}">
 
   <s:layout-component name="script">
@@ -49,7 +48,7 @@
             <wiki:UserCheck status="notauthenticated">
               <div>
                 <s:label for="assertedName" />
-                <s:text id="assertedName" name="assertedName" size="20"><wiki:UserProfile property='wikiname' /></s:text>
+                <s:text id="assertedName" name="assertedName" size="20" />
                 <s:errors field="assertedName" />
                 <div class="description">
                   <fmt:message key="prefs.assertedname.description">
@@ -86,17 +85,17 @@
             <div>
               <s:label for="skin" />
               <s:select id="skin" name="skin">
-                <s:options-collection collection="${skins}" />
+                <s:options-collection collection="${prefs.availableSkins}" />
               </s:select>
               <s:errors field="skin" />
             </div>
             
             <%-- Locale --%>
-            <c:if test='${not empty locales}'>
+            <c:if test='${not empty prefs.availableLocales}'>
               <div>
                 <s:label for="locale" />
                 <s:select name="locale">
-                  <s:options-map map="${locales}" />
+                  <s:options-map map="${prefs.availableLocales}" />
                 </s:select>
                 <s:errors field="locale" />
               </div>
@@ -115,7 +114,7 @@
             <div>
               <s:label for="timeFormat" />
               <s:select id="timeFormat" name="timeFormat">
-                <s:options-map map="${timeformats}" />
+                <s:options-map map="${prefs.availableTimeFormats}" />
               </s:select>
               <s:errors field="timeFormat" />
             </div>
@@ -124,7 +123,9 @@
             <div>
               <s:label for="timeZone" />
               <s:select id="timeZone" name="timeZone">
-                <s:options-map map="${timezones}" />
+                <c:forEach var="item" items="${prefs.availableTimeZones}" >
+                  <s:option value="${item}" formatType="id" ><s:format value="${item}" /></s:option>
+                </c:forEach>
               </s:select>
               <s:errors field="timeZone" />
             </div>

Modified: incubator/jspwiki/trunk/src/java/org/apache/wiki/VariableManager.java
URL: http://svn.apache.org/viewvc/incubator/jspwiki/trunk/src/java/org/apache/wiki/VariableManager.java?rev=912172&r1=912171&r2=912172&view=diff
==============================================================================
--- incubator/jspwiki/trunk/src/java/org/apache/wiki/VariableManager.java (original)
+++ incubator/jspwiki/trunk/src/java/org/apache/wiki/VariableManager.java Sat Feb 20 18:08:02 2010
@@ -348,7 +348,8 @@
                 if( numTokens == 1 )
                 {
                     // no (format) param was given, return the user default
-                    return Preferences.getDateFormat( context, TimeFormat.DATETIME ).format( new Date() );
+                    Preferences prefs = Preferences.getPreferences( req );
+                    return prefs.getDateFormat( TimeFormat.DATETIME ).format( new Date() );
                 }
 
                 if( numTokens >= 2 )

Modified: incubator/jspwiki/trunk/src/java/org/apache/wiki/WikiContext.java
URL: http://svn.apache.org/viewvc/incubator/jspwiki/trunk/src/java/org/apache/wiki/WikiContext.java?rev=912172&r1=912171&r2=912172&view=diff
==============================================================================
--- incubator/jspwiki/trunk/src/java/org/apache/wiki/WikiContext.java (original)
+++ incubator/jspwiki/trunk/src/java/org/apache/wiki/WikiContext.java Sat Feb 20 18:08:02 2010
@@ -117,7 +117,7 @@
     public static final String    VIEW_GROUP = HandlerInfo.getHandlerInfo( GroupActionBean.class, "view" ).getRequestContext();
 
     /** User is editing preferences */
-    public static final String    PREFS    = HandlerInfo.getHandlerInfo( UserPreferencesActionBean.class, "createAssertedName" ).getRequestContext();
+    public static final String    PREFS    = HandlerInfo.getHandlerInfo( UserPreferencesActionBean.class, "save" ).getRequestContext();
 
     /** User is renaming a page. */
     public static final String    RENAME   = HandlerInfo.getHandlerInfo( RenameActionBean.class, "rename" ).getRequestContext();

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=912172&r1=912171&r2=912172&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 Sat Feb 20 18:08:02 2010
@@ -460,7 +460,8 @@
                         signature = "["+m_author+"|"+link+"]";
                     }
                     Calendar cal = Calendar.getInstance();
-                    SimpleDateFormat fmt = Preferences.getDateFormat( wikiContext ,  TimeFormat.DATETIME);
+                    Preferences prefs = Preferences.getPreferences( request );
+                    SimpleDateFormat fmt = prefs.getDateFormat( TimeFormat.DATETIME);
                     pageText.append("\n\n--"+signature+", "+fmt.format(cal.getTime()));
                 }
                 engine.saveText( wikiContext, pageText.toString() );

Modified: incubator/jspwiki/trunk/src/java/org/apache/wiki/action/UserPreferencesActionBean.java
URL: http://svn.apache.org/viewvc/incubator/jspwiki/trunk/src/java/org/apache/wiki/action/UserPreferencesActionBean.java?rev=912172&r1=912171&r2=912172&view=diff
==============================================================================
--- incubator/jspwiki/trunk/src/java/org/apache/wiki/action/UserPreferencesActionBean.java (original)
+++ incubator/jspwiki/trunk/src/java/org/apache/wiki/action/UserPreferencesActionBean.java Sat Feb 20 18:08:02 2010
@@ -23,6 +23,7 @@
 
 import java.security.Principal;
 import java.util.Locale;
+import java.util.TimeZone;
 
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
@@ -32,14 +33,14 @@
 import net.sourceforge.stripes.controller.LifecycleStage;
 import net.sourceforge.stripes.validation.Validate;
 
-import org.apache.wiki.WikiContext;
+import org.apache.wiki.WikiSession;
+import org.apache.wiki.api.WikiException;
 import org.apache.wiki.auth.login.CookieAssertionLoginModule;
 import org.apache.wiki.auth.permissions.WikiPermission;
 import org.apache.wiki.log.Logger;
 import org.apache.wiki.log.LoggerFactory;
 import org.apache.wiki.preferences.Preferences;
 import org.apache.wiki.ui.EditorManager;
-import org.apache.wiki.ui.TemplateManager;
 import org.apache.wiki.ui.stripes.HandlerPermission;
 import org.apache.wiki.ui.stripes.TemplateResolution;
 import org.apache.wiki.ui.stripes.WikiRequestContext;
@@ -64,7 +65,7 @@
 
     private String m_timeFormat = null;
 
-    private String m_timeZone = null;
+    private TimeZone m_timeZone = null;
 
     private boolean m_showQuickLinks = false;
 
@@ -88,32 +89,6 @@
     }
 
     /**
-     * Sets the user's asserted name by setting a cookie in the user's session,
-     * then redirects to the wiki front page. This method will <em>not</em>
-     * set the cookie if the user is already authenticated.
-     * 
-     * @return a redirection to the front page
-     */
-    @HandlesEvent( "createAssertedName" )
-    @HandlerPermission( permissionClass = WikiPermission.class, target = "${context.engine.applicationName}", actions = WikiPermission.EDIT_PREFERENCES_ACTION )
-    public Resolution createAssertedName()
-    {
-        if( !getContext().getWikiSession().isAuthenticated() )
-        {
-            HttpServletRequest request = getContext().getRequest();
-            HttpServletResponse response = getContext().getResponse();
-            String assertedName = request.getParameter( "assertedName" );
-            CookieAssertionLoginModule.setUserCookie( response, assertedName );
-        }
-        if( m_redirect != null )
-        {
-            log.info( "Redirecting user to wiki page " + m_redirect );
-            return new RedirectResolution( ViewActionBean.class ).addParameter( "page", m_redirect );
-        }
-        return new RedirectResolution( ViewActionBean.class );
-    }
-
-    /**
      * Redirects the user to their favorites page.
      * 
      * @return a redirection to the favorites page
@@ -176,7 +151,7 @@
         return m_timeFormat;
     }
 
-    public String getTimeZone()
+    public TimeZone getTimeZone()
     {
         return m_timeZone;
     }
@@ -186,41 +161,31 @@
      * and time zones based on the current template returned by
      * {@link org.apache.wiki.ui.stripes.WikiActionBeanContext#getTemplate()}.
      * It also pre-populates the form values with the preferences stored in the
-     * session attribute
-     * {@link org.apache.wiki.preferences.Preferences#SESSIONPREFS}.
+     * session attribute and retrieved via
+     * {@link org.apache.wiki.preferences.Preferences#getPreferences(HttpServletRequest)}.
      * 
      * @return always returns <code>null</code>
      */
     @Before( stages = LifecycleStage.BindingAndValidation )
     public Resolution initPreferenceOptions()
     {
-        WikiContext c = getContext();
-        TemplateManager t = c.getEngine().getTemplateManager();
-        HttpServletRequest request = getContext().getRequest();
-        HttpSession session = request.getSession();
-        
-        // Set request attributes
-        request.setAttribute( "skins", t.listSkins( request, c.getTemplate() ) );
-        request.setAttribute( "locales", Preferences.listLocales( request ) );
-        request.setAttribute( "timeformats", Preferences.listTimeFormats( getContext() ) );
-        request.setAttribute( "timezones", Preferences.listTimeZones( request ) );
-        
-        // Pre-populate values
-        m_editor = Preferences.getPreference( session, Preferences.PREFS_EDITOR );
-        m_locale = new Locale( Preferences.getPreference( session, Preferences.PREFS_LOCALE ) );
-        try
+        // Load the asserted name
+        WikiSession wikiSession = getContext().getWikiSession();
+        if ( wikiSession.isAsserted() )
         {
-            m_orientation = Preferences.Orientation.valueOf( Preferences.getPreference( session, Preferences.PREFS_ORIENTATION ) );
+            m_assertedName = wikiSession.getUserPrincipal().getName();
         }
-        catch ( Exception e )
-        {
-            m_orientation = Preferences.Orientation.LEFT;
-        }
-        m_sectionEditing = Boolean.parseBoolean( Preferences.getPreference( session, Preferences.PREFS_SECTION_EDITING ) );
-        m_skin = Preferences.getPreference( session, Preferences.PREFS_SKIN );
-        m_timeFormat = Preferences.getPreference( session, Preferences.PREFS_TIME_FORMAT );
-        m_timeZone = Preferences.getPreference( session, Preferences.PREFS_TIME_ZONE );
-        
+
+        // Load preferences
+        HttpServletRequest request = getContext().getRequest();
+        Preferences prefs = Preferences.getPreferences( request );
+        m_editor = (String)prefs.get( Preferences.PREFS_EDITOR );
+        m_locale = (Locale)prefs.get( Preferences.PREFS_LOCALE );
+        m_orientation = (Preferences.Orientation)prefs.get( Preferences.PREFS_ORIENTATION );
+        m_sectionEditing = (Boolean)prefs.get( Preferences.PREFS_SECTION_EDITING );
+        m_skin = (String)prefs.get( Preferences.PREFS_SKIN );
+        m_timeFormat = (String)prefs.get( Preferences.PREFS_TIME_FORMAT );
+        m_timeZone = (TimeZone)prefs.get( Preferences.PREFS_TIME_ZONE );
         return null;
     }
 
@@ -236,23 +201,40 @@
 
     /**
      * Saves the user's currently selected preferences to cookies, and to the
-     * Preferences map associated with the user's session.
+     * Preferences map associated with the user's session. It then redirects
+     * to the wiki front page. Also sets the user's asserted name by setting
+     * if the user is already authenticated.
      * 
      * @return resolution redirecting user to the display JSP for this ActionBean
      */
     @HandlesEvent( "save" )
-    public Resolution save()
+    @HandlerPermission( permissionClass = WikiPermission.class, target = "${context.engine.applicationName}", actions = WikiPermission.EDIT_PREFERENCES_ACTION )
+    public Resolution save() throws WikiException
     {
-        HttpSession session = getContext().getHttpRequest().getSession();
+        HttpServletRequest request = getContext().getRequest();
         HttpServletResponse response = getContext().getResponse();
-        Preferences.setPreference( session, response, Preferences.PREFS_EDITOR, m_editor );
-        Preferences.setPreference( session, response, Preferences.PREFS_LOCALE, m_locale.toString() );
-        Preferences.setPreference( session, response, Preferences.PREFS_ORIENTATION, m_orientation.name() );
-        Preferences.setPreference( session, response, Preferences.PREFS_SECTION_EDITING, Boolean.toString( m_sectionEditing ) );
-        Preferences.setPreference( session, response, Preferences.PREFS_SKIN, m_skin );
-        Preferences.setPreference( session, response, Preferences.PREFS_TIME_FORMAT, m_timeFormat );
-        Preferences.setPreference( session, response, Preferences.PREFS_TIME_ZONE, m_timeZone );
-        return new RedirectResolution( UserPreferencesActionBean.class );
+        
+        if( !getContext().getWikiSession().isAuthenticated() )
+        {
+            CookieAssertionLoginModule.setUserCookie( response, m_assertedName );
+        }
+        Preferences prefs = Preferences.getPreferences( request );
+        prefs.put( Preferences.PREFS_EDITOR, m_editor );
+        prefs.put( Preferences.PREFS_LOCALE, m_locale );
+        prefs.put( Preferences.PREFS_ORIENTATION, m_orientation );
+        prefs.put( Preferences.PREFS_SECTION_EDITING, m_sectionEditing );
+        prefs.put( Preferences.PREFS_SKIN, m_skin );
+        prefs.put( Preferences.PREFS_TIME_FORMAT, m_timeFormat );
+        prefs.put( Preferences.PREFS_TIME_ZONE, m_timeZone );
+        prefs.save( getContext() );
+        
+        // Redirect user
+        if( m_redirect != null )
+        {
+            log.info( "Redirecting user to wiki page " + m_redirect );
+            return new RedirectResolution( ViewActionBean.class ).addParameter( "page", m_redirect );
+        }
+        return new RedirectResolution( ViewActionBean.class );
     }
 
     /**
@@ -260,7 +242,7 @@
      * 
      * @param name the asserted name
      */
-    @Validate( required = true, on = "createAssertedName", minlength = 1, maxlength = 128 )
+    @Validate( required = false, on = "save", minlength = 1, maxlength = 128 )
     public void setAssertedName( String name )
     {
         m_assertedName = name;
@@ -275,7 +257,7 @@
      * 
      * @param editor the editor
      */
-    @Validate( )
+    @Validate( required = true, on = "save" )
     public void setEditor( String editor )
     {
         m_editor = editor;
@@ -286,13 +268,13 @@
         }
     }
 
-    @Validate( )
+    @Validate( required = true, on = "save" )
     public void setLocale( Locale locale )
     {
         m_locale = locale;
     }
 
-    @Validate( )
+    @Validate( required = true, on = "save" )
     public void setOrientation( Preferences.Orientation orientation )
     {
         m_orientation = orientation;
@@ -303,38 +285,38 @@
      * 
      * @param url the URL to redirect to
      */
-    @Validate( )
+    @Validate( required = false )
     public void setRedirect( String url )
     {
         m_redirect = url;
     }
 
-    @Validate( )
+    @Validate( required = false, on = "save" )
     public void setSectionEditing( boolean sectionEditing )
     {
         m_sectionEditing = sectionEditing;
     }
 
-    @Validate( )
+    @Validate( required = false )
     public void setShowQuickLinks( boolean showQuickLinks )
     {
         m_showQuickLinks = showQuickLinks;
     }
 
-    @Validate( )
+    @Validate( required = true, on = "save" )
     public void setSkin( String skin )
     {
         m_skin = skin;
     }
 
-    @Validate( )
+    @Validate( required = true, on = "save" )
     public void setTimeFormat( String timeFormat )
     {
         m_timeFormat = timeFormat;
     }
 
-    @Validate( )
-    public void setTimeZone( String timeZone )
+    @Validate( required = true, on = "save" )
+    public void setTimeZone( TimeZone timeZone )
     {
         m_timeZone = timeZone;
     }

Modified: incubator/jspwiki/trunk/src/java/org/apache/wiki/auth/SessionMonitor.java
URL: http://svn.apache.org/viewvc/incubator/jspwiki/trunk/src/java/org/apache/wiki/auth/SessionMonitor.java?rev=912172&r1=912171&r2=912172&view=diff
==============================================================================
--- incubator/jspwiki/trunk/src/java/org/apache/wiki/auth/SessionMonitor.java (original)
+++ incubator/jspwiki/trunk/src/java/org/apache/wiki/auth/SessionMonitor.java Sat Feb 20 18:08:02 2010
@@ -36,6 +36,7 @@
 import org.apache.wiki.event.*;
 import org.apache.wiki.log.Logger;
 import org.apache.wiki.log.LoggerFactory;
+import org.apache.wiki.preferences.Preferences;
 import org.apache.wiki.rpc.json.JSONRPCManager;
 
 

Modified: incubator/jspwiki/trunk/src/java/org/apache/wiki/content/ReferenceManager.java
URL: http://svn.apache.org/viewvc/incubator/jspwiki/trunk/src/java/org/apache/wiki/content/ReferenceManager.java?rev=912172&r1=912171&r2=912172&view=diff
==============================================================================
--- incubator/jspwiki/trunk/src/java/org/apache/wiki/content/ReferenceManager.java (original)
+++ incubator/jspwiki/trunk/src/java/org/apache/wiki/content/ReferenceManager.java Sat Feb 20 18:08:02 2010
@@ -822,7 +822,7 @@
         Node node = null;
         try
         {
-            node = (Node) cm.getCurrentSession().getItem( jcrNode );
+            node = (Node) s.getItem( jcrNode );
         }
         catch( PathNotFoundException e )
         {
@@ -859,15 +859,13 @@
             
             // There seems to be a bug in Priha that causes property files to bloat,
             // so we remove the property first, then re-add it
-            p.remove();
-            s.save();
+//            p.remove();
             node.setProperty( property, newValues.toArray( new String[newValues.size()] ) );
         }
         catch( PathNotFoundException e )
         {
             node.setProperty( property, new String[] { newValue } );
         }
-        s.save();
     }
 
     /**
@@ -1006,7 +1004,6 @@
         
         // Retrieve (or create) the destination node for the page
         ContentManager cm = m_engine.getContentManager();
-        Session s = cm.getCurrentSession();
         Node node = null;
         try
         {
@@ -1033,15 +1030,12 @@
                     newValues.add( valueString );
                 }
             }
-            /*
             if( newValues.size() == 0 )
             {
                 // There seems to be a bug in Priha that causes property files to bloat,
                 // so we remove the property first, then re-add it
                 p.remove();
-                s.save();
             }
-            */
         }
         catch( PathNotFoundException e )
         {
@@ -1053,7 +1047,6 @@
         {
             node.setProperty( property, newValues.toArray( new String[newValues.size()] ) );
         }
-//        s.save();
     }
     
     /**
@@ -1271,8 +1264,6 @@
 
         // Remove the saved page from the 'uncreated' list
         removeFromProperty( NOT_CREATED, PROPERTY_NOT_CREATED, source.toString() );
-
-        s.save();
     }
 
     /**

Modified: incubator/jspwiki/trunk/src/java/org/apache/wiki/plugin/AbstractFilteredPlugin.java
URL: http://svn.apache.org/viewvc/incubator/jspwiki/trunk/src/java/org/apache/wiki/plugin/AbstractFilteredPlugin.java?rev=912172&r1=912171&r2=912172&view=diff
==============================================================================
--- incubator/jspwiki/trunk/src/java/org/apache/wiki/plugin/AbstractFilteredPlugin.java (original)
+++ incubator/jspwiki/trunk/src/java/org/apache/wiki/plugin/AbstractFilteredPlugin.java Sat Feb 20 18:08:02 2010
@@ -132,7 +132,8 @@
     public void initialize( WikiContext context, Map<String,Object> params )
         throws PluginException
     {
-        m_dateFormat = Preferences.getDateFormat( context, TimeFormat.DATETIME );
+        Preferences prefs = Preferences.getPreferences( context.getHttpRequest() );
+        m_dateFormat = prefs.getDateFormat( TimeFormat.DATETIME );
         m_engine = context.getEngine();
         m_maxwidth = TextUtil.parseIntParameter( (String)params.get( PARAM_MAXWIDTH ), Integer.MAX_VALUE );
         if( m_maxwidth < 0 ) m_maxwidth = 0;

Modified: incubator/jspwiki/trunk/src/java/org/apache/wiki/plugin/CurrentTimePlugin.java
URL: http://svn.apache.org/viewvc/incubator/jspwiki/trunk/src/java/org/apache/wiki/plugin/CurrentTimePlugin.java?rev=912172&r1=912171&r2=912172&view=diff
==============================================================================
--- incubator/jspwiki/trunk/src/java/org/apache/wiki/plugin/CurrentTimePlugin.java (original)
+++ incubator/jspwiki/trunk/src/java/org/apache/wiki/plugin/CurrentTimePlugin.java Sat Feb 20 18:08:02 2010
@@ -58,9 +58,14 @@
             SimpleDateFormat fmt;
             
             if( formatString != null )
+            {
                 fmt = new SimpleDateFormat( formatString );
+            }
             else
-                fmt = Preferences.getDateFormat( context, TimeFormat.DATETIME );
+            {
+                Preferences prefs = Preferences.getPreferences( context.getHttpRequest() );
+                fmt = prefs.getDateFormat( TimeFormat.DATETIME );
+            }
 
             Date d = new Date();  // Now.
 
@@ -69,7 +74,6 @@
         catch( IllegalArgumentException e )
         {
             ResourceBundle rb = context.getBundle(WikiPlugin.CORE_PLUGINS_RESOURCEBUNDLE);
-            
             throw new PluginException( rb.getString("currenttimeplugin.badformat") + e.getMessage() );
         }
     }

Modified: incubator/jspwiki/trunk/src/java/org/apache/wiki/plugin/RecentChangesPlugin.java
URL: http://svn.apache.org/viewvc/incubator/jspwiki/trunk/src/java/org/apache/wiki/plugin/RecentChangesPlugin.java?rev=912172&r1=912171&r2=912172&view=diff
==============================================================================
--- incubator/jspwiki/trunk/src/java/org/apache/wiki/plugin/RecentChangesPlugin.java (original)
+++ incubator/jspwiki/trunk/src/java/org/apache/wiki/plugin/RecentChangesPlugin.java Sat Feb 20 18:08:02 2010
@@ -238,8 +238,6 @@
         return "";
     }
 
-    
-
     // TODO: Ideally the default behavior should be to return the default format for the default
     // locale, but that is at odds with the 1st version of this plugin. We seek to preserve the
     // behaviour of that first version, so to get the default format, the user must explicitly do
@@ -247,35 +245,31 @@
     private DateFormat getTimeFormat( WikiContext context, Map<String,Object> params )
     {
         String formatString = get(params, DEFAULT_TIME_FORMAT, PARAM_TIME_FORMAT);
-
         if ("".equals(formatString.trim()))
-            return Preferences.getDateFormat( context, TimeFormat.TIME );
-
+        {
+            Preferences prefs = Preferences.getPreferences( context.getHttpRequest() );
+            return prefs.getDateFormat( TimeFormat.TIME );
+        }
         return new SimpleDateFormat(formatString);
     }
 
-
-
     private DateFormat getDateFormat( WikiContext context, Map<String,Object> params )
     {
         String formatString = get(params, DEFAULT_DATE_FORMAT, PARAM_DATE_FORMAT);
-
         if ("".equals(formatString.trim()))
-            return Preferences.getDateFormat( context, TimeFormat.DATE );
-
+        {
+            Preferences prefs = Preferences.getPreferences( context.getHttpRequest() );
+            return prefs.getDateFormat( TimeFormat.DATE );
+        }
         return new SimpleDateFormat(formatString);
 
     }
 
-
-
     private String get(Map<String,Object> params, String defaultValue, String paramName)
     {
         String value = (String) params.get(paramName);
         return null == value ? defaultValue : value;
     }
-
-    
 }
 
 

Modified: incubator/jspwiki/trunk/src/java/org/apache/wiki/plugin/WeblogPlugin.java
URL: http://svn.apache.org/viewvc/incubator/jspwiki/trunk/src/java/org/apache/wiki/plugin/WeblogPlugin.java?rev=912172&r1=912171&r2=912172&view=diff
==============================================================================
--- incubator/jspwiki/trunk/src/java/org/apache/wiki/plugin/WeblogPlugin.java (original)
+++ incubator/jspwiki/trunk/src/java/org/apache/wiki/plugin/WeblogPlugin.java Sat Feb 20 18:08:02 2010
@@ -185,7 +185,8 @@
 
         if( ( params.get(PARAM_ENTRYFORMAT)) == null )
         {
-            entryFormat = Preferences.getDateFormat( context, TimeFormat.DATETIME );
+            Preferences prefs = Preferences.getPreferences( context.getHttpRequest() );
+            entryFormat = prefs.getDateFormat( TimeFormat.DATETIME );
         }
         else
         {

Modified: incubator/jspwiki/trunk/src/java/org/apache/wiki/preferences/Preferences.java
URL: http://svn.apache.org/viewvc/incubator/jspwiki/trunk/src/java/org/apache/wiki/preferences/Preferences.java?rev=912172&r1=912171&r2=912172&view=diff
==============================================================================
--- incubator/jspwiki/trunk/src/java/org/apache/wiki/preferences/Preferences.java (original)
+++ incubator/jspwiki/trunk/src/java/org/apache/wiki/preferences/Preferences.java Sat Feb 20 18:08:02 2010
@@ -21,24 +21,27 @@
 package org.apache.wiki.preferences;
 
 import java.net.URL;
-import java.text.DateFormat;
 import java.text.SimpleDateFormat;
 import java.util.*;
 
 import javax.servlet.http.Cookie;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
-import javax.servlet.http.HttpSession;
-import javax.servlet.jsp.PageContext;
+
+import net.sourceforge.stripes.config.Configuration;
+import net.sourceforge.stripes.controller.StripesFilter;
+import net.sourceforge.stripes.validation.TypeConverter;
+import net.sourceforge.stripes.validation.TypeConverterFactory;
+import net.sourceforge.stripes.validation.ValidationError;
 
 import org.apache.wiki.InternalWikiException;
-import org.apache.wiki.WikiContext;
 import org.apache.wiki.WikiEngine;
+import org.apache.wiki.api.WikiException;
 import org.apache.wiki.i18n.InternationalizationManager;
 import org.apache.wiki.log.Logger;
 import org.apache.wiki.log.LoggerFactory;
 import org.apache.wiki.ui.TemplateManager;
-import org.apache.wiki.ui.stripes.LocaleConverter;
+import org.apache.wiki.ui.stripes.WikiActionBeanContext;
 
 /**
  * <p>
@@ -46,63 +49,31 @@
  * and other customizable user interface items. Preferences are initialized by
  * JSPWiki by reading a series of cookies from the user's HTTP request. This
  * happens once per request, during the execution of
- * {@link org.apache.wiki.ui.stripes.WikiInterceptor}.
- * The method {@link #setupPreferences(HttpServletRequest)} performs the actual
- * initialization.
+ * {@link org.apache.wiki.ui.stripes.WikiInterceptor}. The method
+ * {@link #initialize(HttpServletRequest)} performs the actual initialization.
  * <p>
  * After initialization, Preferences are stashed in the user's session as an
- * attribute named {@link #SESSIONPREFS}. Preferences may be subsequently
- * changed by calling
- * {@link org.apache.wiki.action.UserPreferencesActionBean#save()} with
+ * attribute named {@code prefs}. Preferences may be subsequently changed by
+ * calling {@link org.apache.wiki.action.UserPreferencesActionBean#save()} with
  * appropriate parameters, generally from a JSP.
  * </p>
  */
-public class Preferences extends HashMap<String, String>
+public class Preferences implements Map<String, Object>
 {
-    private static final Map<Locale,String> LOCALES;
-
-    /**
-     * Private constructor to prevent direct instantiation.
-     */
-    private Preferences() {}
-
     /**
-     * List of time zones, used by {@link #listTimeZones(HttpServletRequest)}.
+     * Enumeration of the orientation formats for favorites.
      */
-    private static final List<TimeZone> TIME_ZONES;
-
-    static
+    public enum Orientation
     {
-        // Init time zones
-        List<TimeZone> zones = new ArrayList<TimeZone>();
-        String[] ids = { "Pacific/Midway", "Pacific/Honolulu", "America/Anchorage", "PST", "MST", "CST", "EST", "America/Caracas",
-                        "Brazil/East", "Atlantic/South_Georgia", "Atlantic/Cape_Verde", "Etc/Greenwich", "CET", "ART", "EAT",
-                        "Asia/Dubai", "IST", "BST", "VST", "CTT", "JST", "Australia/Sydney", "SST", "NZ", "Pacific/Tongatapu",
-                        "Pacific/Kiritimati" };
-        for( String id : ids )
-        {
-            java.util.TimeZone zone = java.util.TimeZone.getTimeZone( id );
-            zones.add( zone );
-        }
-        TIME_ZONES = Collections.unmodifiableList( zones );
-        
-        // Init locales
-        Locale[] locales = Locale.getAvailableLocales();
-        Map<Locale,String> foundLocales = new HashMap<Locale,String>();
-        for ( Locale locale : locales )
-        {
-            URL url = TemplateManager.class.getClassLoader().getResource( "CoreResources_" + locale.toString() + ".properties" );
-            if ( url != null )
-            {
-                foundLocales.put( locale, locale.getDisplayName( locale ) );
-            }
-        }
-        LOCALES = Collections.unmodifiableMap( foundLocales );
+        /** Favorites to the left. */
+        LEFT,
+        /** Favorites to the right. */
+        RIGHT
     }
 
     /**
      * <p>
-     * Enumeration of three different date formats that JSPWiki supports.
+     * Formatting style for displaying times and dates.
      * </p>
      * <ul>
      * <li>TIME: A time format, without date</li>
@@ -125,17 +96,6 @@
     }
 
     /**
-     * Enumeration of the orientation formats for favorites.
-     */
-    public enum Orientation
-    {
-        /** Favorites to the left. */
-        LEFT,
-        /** Favorites to the right. */
-        RIGHT
-    }
-
-    /**
      * Cookie name for the user's preference for displaying dates and times.
      */
     public static final String PREFS_TIME_FORMAT = "TimeFormat";
@@ -161,70 +121,244 @@
     public static final String PREFS_EDITOR = "Editor";
 
     /**
-     * The name under which a Preferences object is stored in the HttpSession.
-     * Its value is {@value}.
-     */
-    public static final String SESSIONPREFS = "prefs";
-
-    /**
      * Cookie name for the user's preferred {@link java.util.Locale}.
      */
     public static final String PREFS_LOCALE = "Locale";
 
-    /** I18N string to mark the server timezone */
-    public static final String I18NSERVER_TIMEZONE = "prefs.user.timezone.server";
-
     /**
      * Cookie name for the user's preferred template skin.
      */
     public static final String PREFS_SKIN = "Skin";
 
-    private static final long serialVersionUID = 2L;
+    public static final Map<Locale, String> AVAILABLE_LOCALES;
 
-    private static Logger log = LoggerFactory.getLogger( Preferences.class );
+    public static void main( String[] args )
+    {
+        String[] ids = TimeZone.getAvailableIDs();
+        Map<Integer, Set<TimeZone>> tzs = new TreeMap<Integer, Set<TimeZone>>();
+        long now = System.currentTimeMillis();
+        for( String id : ids )
+        {
+            TimeZone tz = TimeZone.getTimeZone( id );
+            int offset = tz.getOffset( now ) / (1000 * 60);
+            Set<TimeZone> tzsForOffset = tzs.get( offset );
+            if( tzsForOffset == null )
+            {
+                tzsForOffset = new HashSet<TimeZone>();
+                tzs.put( offset, tzsForOffset );
+            }
+            if( tzsForOffset.size() < 10 )
+            {
+                tzsForOffset.add( tz );
+            }
+        }
+        System.out.println( "Foo!" );
+        for( Map.Entry<Integer, Set<TimeZone>> entry : tzs.entrySet() )
+        {
+            System.out.print( entry.getKey() + ": " );
+            for( TimeZone tz : entry.getValue() )
+            {
+                String city = tz.getID();
+                int firstSlash = city.indexOf( "/" );
+                if( firstSlash >= 0 )
+                {
+                    city = city.substring( firstSlash + 1 );
+                }
+                city = city.replace( '_', ' ' );
+                System.out.print( city + ", " );
+            }
+            System.out.println( "." );
+        }
+    }
+
+    private final Collection<ValidationError> m_errors;
+
+    /**
+     * List of time zones, used by
+     * {@link #getAvailableTimeZones(HttpServletRequest)}.
+     */
+    public static final List<TimeZone> AVAILABLE_TIME_ZONES;
 
-    private static final LocaleConverter LOCALE_CONVERTER = new LocaleConverter();
+    private static final Map<String, Class<? extends Object>> TYPE_CONVERTERS;
 
     /** Prefix of the default timeformat properties. */
     public static final String TIMEFORMATPROPERTIES = "jspwiki.defaultprefs.timeformat.";
 
     /**
+     * The name under which a Preferences object is stored in the HttpSession.
+     * Its value is {@value} .
+     */
+    private static final String SESSIONPREFS = "prefs";
+
+    private static final long serialVersionUID = 2L;
+
+    private static Logger log = LoggerFactory.getLogger( Preferences.class );
+
+    static
+    {
+        // Init time zones
+        List<TimeZone> zones = new ArrayList<TimeZone>();
+        String[] ids = { "Pacific/Midway", "Pacific/Honolulu", "America/Anchorage", "America/Los_Angeles", "US/Mountain",
+                        "America/Chicago", "America/New_York", "America/Caracas", "Brazil/East", "Atlantic/South_Georgia",
+                        "Atlantic/Cape_Verde", "Etc/Greenwich", "Europe/Rome", "ART", "EAT", "Asia/Dubai", "IST", "BST", "VST",
+                        "CTT", "JST", "Australia/Sydney", "SST", "NZ", "Pacific/Tongatapu", "Pacific/Kiritimati" };
+        for( String id : ids )
+        {
+            java.util.TimeZone zone = java.util.TimeZone.getTimeZone( id );
+            zones.add( zone );
+        }
+        AVAILABLE_TIME_ZONES = Collections.unmodifiableList( zones );
+
+        // Init locales
+        Locale[] locales = Locale.getAvailableLocales();
+        Map<Locale, String> foundLocales = new HashMap<Locale, String>();
+        for( Locale locale : locales )
+        {
+            URL url = TemplateManager.class.getClassLoader().getResource( "CoreResources_" + locale.toString() + ".properties" );
+            if( url != null )
+            {
+                foundLocales.put( locale, locale.getDisplayName( locale ) );
+            }
+        }
+        AVAILABLE_LOCALES = Collections.unmodifiableMap( foundLocales );
+
+        // Init type converter map; default is String unless added here
+        TYPE_CONVERTERS = new HashMap<String, Class<?>>();
+        TYPE_CONVERTERS.put( PREFS_LOCALE, Locale.class );
+        TYPE_CONVERTERS.put( PREFS_ORIENTATION, Orientation.class );
+        TYPE_CONVERTERS.put( PREFS_SECTION_EDITING, Boolean.class );
+        TYPE_CONVERTERS.put( PREFS_TIME_ZONE, TimeZone.class );
+
+    }
+
+    /**
+     * Looks up the Preferences object in the user's HTTP session, lazily
+     * creating and initializing one if it does not already exist.
+     * 
+     * @param request the HTTP request
+     * @return the preferences object
+     */
+    public static Preferences getPreferences( HttpServletRequest request )
+    {
+        Preferences prefs = (Preferences) request.getSession().getAttribute( SESSIONPREFS );
+        if( prefs == null )
+        {
+            WikiEngine engine = WikiEngine.getInstance( request.getSession().getServletContext(), null );
+            prefs = new Preferences( engine );
+            prefs.initialize( request );
+            request.getSession().setAttribute( SESSIONPREFS, prefs );
+        }
+        return prefs;
+    }
+
+    private final WikiEngine m_engine;
+
+    private final Map<String, Object> m_prefs = new HashMap<String, Object>();
+
+    /**
+     * Private constructor to prevent direct instantiation.
+     * 
+     * @param engine the wiki engine
+     */
+    private Preferences( WikiEngine engine )
+    {
+        m_engine = engine;
+        m_errors = new ArrayList<ValidationError>();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public void clear()
+    {
+        m_prefs.clear();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public boolean containsKey( Object key )
+    {
+        return m_prefs.containsKey( key );
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public boolean containsValue( Object value )
+    {
+        return m_prefs.containsKey( value );
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public Set<java.util.Map.Entry<String, Object>> entrySet()
+    {
+        return m_prefs.entrySet();
+    }
+
+    /**
+     * {@inheritDoc}. The special key names {@code availableLocales}, {@code
+     * availableSkins}, {@code availableTimeFormats}, {@code availableTimeZones}
+     * return what you would expect.
+     */
+    public Object get( Object key )
+    {
+        if( "availableLocales".equals( key ) )
+        {
+            return AVAILABLE_LOCALES;
+        }
+        else if( "availableSkins".equals( key ) )
+        {
+            return m_engine.getTemplateManager().listSkins( m_engine.getServletContext(), m_engine.getTemplateDir() );
+        }
+        else if( "availableTimeFormats".equals( key ) )
+        {
+            return availableTimeFormats();
+        }
+        else if( "availableTimeZones".equals( key ) )
+        {
+            return AVAILABLE_TIME_ZONES;
+        }
+        return m_prefs.get( key );
+    }
+
+    /**
      * Get SimpleTimeFormat according to user browser locale and preferred time
      * formats. If not found, it will revert to whichever format is set for the
      * default
      * 
-     * @param context WikiContext to use for rendering.
      * @param tf Which version of the dateformat you are looking for?
      * @return A SimpleTimeFormat object which you can use to render
      * @since 2.8
      */
-    public static SimpleDateFormat getDateFormat( WikiContext context, TimeFormat tf )
+    public SimpleDateFormat getDateFormat( TimeFormat tf )
     {
-        InternationalizationManager imgr = context.getEngine().getInternationalizationManager();
-        Locale clientLocale = getLocale( context.getHttpRequest() );
-        String prefTimeZone = Preferences.getPreference( context, PREFS_TIME_ZONE );
         String prefDateFormat;
+        InternationalizationManager i18n = m_engine.getInternationalizationManager();
 
         log.debug( "Checking for preferences..." );
 
         switch( tf )
         {
             case DATETIME:
-                prefDateFormat = Preferences.getPreference( context, PREFS_TIME_FORMAT );
+                prefDateFormat = (String) get( PREFS_TIME_FORMAT );
                 log.debug( "Preferences fmt = " + prefDateFormat );
                 if( prefDateFormat == null )
                 {
-                    prefDateFormat = imgr.get( InternationalizationManager.CORE_BUNDLE, clientLocale, "common.datetimeformat" );
+                    Locale locale = (Locale) get( PREFS_LOCALE );
+                    prefDateFormat = i18n.get( InternationalizationManager.CORE_BUNDLE, locale, "common.datetimeformat" );
                     log.debug( "Using locale-format = " + prefDateFormat );
                 }
                 break;
 
             case TIME:
-                prefDateFormat = imgr.get( "common.timeformat" );
+                prefDateFormat = i18n.get( "common.timeformat" );
                 break;
 
             case DATE:
-                prefDateFormat = imgr.get( "common.dateformat" );
+                prefDateFormat = i18n.get( "common.dateformat" );
                 break;
 
             default:
@@ -233,17 +367,13 @@
 
         try
         {
-            SimpleDateFormat fmt = new SimpleDateFormat( prefDateFormat, clientLocale );
-
-            if( prefTimeZone != null )
+            Locale locale = (Locale) get( PREFS_LOCALE );
+            SimpleDateFormat fmt = new SimpleDateFormat( prefDateFormat, locale );
+            TimeZone tz = (TimeZone) get( PREFS_TIME_ZONE );
+            if( tz != null )
             {
-                TimeZone tz = TimeZone.getTimeZone( prefTimeZone );
-                // TimeZone tz = TimeZone.getDefault();
-                // tz.setRawOffset(Integer.parseInt(prefTimeZone));
-
                 fmt.setTimeZone( tz );
             }
-
             return fmt;
         }
         catch( Exception e )
@@ -253,265 +383,110 @@
     }
 
     /**
-     * Returns the user's preferred {@link java.util.Locale} according the
-     * contents of the cookie value {@link #PREFS_LOCALE}, or alternatively the
-     * Locale supplied by the HTTP request object.
-     * 
-     * @param request the HTTP request
-     * @return a Locale object.
-     * @since 2.8
+     * {@inheritDoc}
      */
-    public static Locale getLocale( HttpServletRequest request )
+    public boolean isEmpty()
     {
-        String localePref = getCookieValue( request, PREFS_LOCALE, request.getLocale().toString() );
-        Locale locale = LOCALE_CONVERTER.convert( localePref, Locale.class, null );
-
-        // Otherwise use the JVM's default
-        if( locale == null )
-        {
-            locale = Locale.getDefault();
-        }
-        return locale;
+        return m_prefs.isEmpty();
     }
 
     /**
-     * Returns a preference value from the Preferences object stored in the
-     * user's session.
-     * 
-     * @param session the HTTP session
-     * @param name the name of the preference to retrieve
-     * @return the preference value, or <code>null</code> if not found
+     * {@inheritDoc}
      */
-    public static String getPreference( HttpSession session, String name )
+    public Set<String> keySet()
     {
-        Preferences prefs = (Preferences) session.getAttribute( SESSIONPREFS );
-        if( prefs != null )
-        {
-            return prefs.get( name );
-        }
-        return null;
+        return m_prefs.keySet();
     }
 
     /**
-     * Returns a preference value from the Preferences object stored in the
-     * user's session.
-     * 
-     * @param pageContext the page context
-     * @param name the name of the preference to retrieve
-     * @return the preference value, or <code>null</code> if not found
+     * {@inheritDoc}
      */
-    public static String getPreference( PageContext pageContext, String name )
+    public Object put( String key, Object value )
     {
-        return getPreference( pageContext.getSession(), name );
+        return m_prefs.put( key, value );
     }
 
     /**
-     * Returns a preference value from the Preferences object stored in the
-     * user's session.
-     * 
-     * @param wikiContext the wiki context
-     * @param name the name of the preference to retrieve
-     * @return the preference value, or <code>null</code> if not found
-     */
-    public static String getPreference( WikiContext wikiContext, String name )
-    {
-        return getPreference( wikiContext.getHttpRequest().getSession(), name );
-    }
-
-    /**
-     * Saves a preference value as a cookie. If <code>key</code> or
-     * <code>value</code> is <code>null</code>, the cookie is not set.
-     * 
-     * @param session the HTTP session
-     * @param response the HTTP response
-     * @param key the cookie name
-     * @param value the cookie value
+     * {@inheritDoc}
      */
-    public static void setPreference( HttpSession session, HttpServletResponse response, String key, String value )
+    public void putAll( Map<? extends String, ? extends Object> m )
     {
-        if( key != null && value != null )
-        {
-            Cookie cookie = new Cookie( key, value );
-            response.addCookie( cookie );
-            Preferences prefs = (Preferences) session.getAttribute( SESSIONPREFS );
-            if( prefs != null )
-            {
-                prefs.put( key, value );
-            }
-        }
+        m_prefs.putAll( m );
     }
 
     /**
-     * A simple helper function to render a date based on the user preferences.
-     * This is useful for example for all plugins.
-     * 
-     * @param context The context which is used to get the preferences
-     * @param date The date to render.
-     * @param tf In which format the date should be rendered.
-     * @return A ready-rendered date.
-     * @since 2.8
+     * {@inheritDoc}
      */
-    public static String renderDate( WikiContext context, Date date, TimeFormat tf )
+    public Object remove( Object key )
     {
-        DateFormat df = getDateFormat( context, tf );
-
-        return df.format( date );
+        return m_prefs.remove( key );
     }
 
     /**
-     * <p>
-     * This method checks to see if user preferences have been loaded from
-     * request cookies, and if not, loads them. This method is called from three
-     * places: from
-     * {@link org.apache.wiki.ui.stripes.WikiInterceptor#intercept(net.sourceforge.stripes.controller.ExecutionContext)},
-     * {@link org.apache.wiki.action.WikiContextFactory#newContext(HttpServletRequest, javax.servlet.http.HttpServletResponse, String)}
-     * and
-     * {@link org.apache.wiki.action.WikiContextFactory#newViewContext(HttpServletRequest, javax.servlet.http.HttpServletResponse, org.apache.wiki.api.WikiPage)}.
-     * </p>
-     * <p>
-     * Every user preference is read from a unique cookie. This method parses
-     * each value from the respective cookie, and applies a default value if the
-     * cookie is not found in the request. Once all preference values are
-     * parsed, this method stashes the Preferences object in the user's
-     * HTTPSession so that as an attribute named {@link #SESSIONPREFS}, so that
-     * it can be recalled later. So that JSPWiki does not waste excessive cycles
-     * parsing preference cookies on every request, if this method finds the
-     * SESSIONPREFS already present in the session, it returns silently without
-     * doing any more work.
-     * </p>
-     * <p>
-     * To change user preference values after the initial parse, users normally
-     * invoke {@link org.apache.wiki.action.UserPreferencesActionBean#save()}.
-     * </p>
+     * Saves all preferences. At the moment the only persistence mechanism
+     * is to save preferences to cookies. However, future versions will
+     * save authenticated users' preferences to the JCR.
      * 
-     * @param request the HTTP request
+     * @param context the ActionBeanContext FIXME: make this use JCR for
+     *            authenticated users
      */
-    public static void setupPreferences( HttpServletRequest request )
+    public void save( WikiActionBeanContext context )
     {
-        HttpSession session = request.getSession();
-
-        if( session.getAttribute( SESSIONPREFS ) != null )
+        HttpServletResponse response = context.getResponse();
+        for( Map.Entry<String, Object> item : m_prefs.entrySet() )
         {
-            return;
-        }
-
-        // Ok, set up the preferences now
-        WikiEngine engine = WikiEngine.getInstance( session.getServletContext(), null );
-        Preferences prefs = new Preferences();
-        Properties props = engine.getWikiProperties();
-        Locale locale = request.getLocale();
-
-        // FIXME: "editor" property does not get registered, may be related with
-        // http://bugs.jspwiki.org/show_bug.cgi?id=117
-        // disabling it until knowing why it's happening
-        // FIXME: editormanager reads jspwiki.editor -- which of both properties
-        // should continue
-        String defaultValue = props.getProperty( "jspwiki.defaultprefs.template.editor", "plain" );
-        prefs.put( PREFS_EDITOR, getCookieValue( request, PREFS_EDITOR, defaultValue ) );
-
-        // Init the Locale
-        defaultValue = props.getProperty( "jspwiki.defaultprefs.template.language", locale.toString() );
-        prefs.put( PREFS_LOCALE, getCookieValue( request, PREFS_LOCALE, defaultValue ) );
-
-        // Init the orientation
-        defaultValue = props.getProperty( "jspwiki.defaultprefs.template.orientation", Orientation.LEFT.name() );
-        prefs.put( PREFS_ORIENTATION, getCookieValue( request, PREFS_ORIENTATION, defaultValue ) );
-
-        // Init section editing
-        defaultValue = props.getProperty( "jspwiki.defaultprefs.template.sectionediting", "false" );
-        prefs.put( PREFS_SECTION_EDITING, getCookieValue( request, PREFS_SECTION_EDITING, defaultValue ) );
-
-        // Init the template skin
-        defaultValue = props.getProperty( "jspwiki.defaultprefs.template.skinname", "PlainVanilla" );
-        prefs.put( PREFS_SKIN, getCookieValue( request, PREFS_SKIN, defaultValue ) );
-
-        // Init the date format
-        defaultValue = props.getProperty( "jspwiki.defaultprefs.template.dateformat", engine.getInternationalizationManager()
-            .get( InternationalizationManager.CORE_BUNDLE, locale, "common.datetimeformat" ) );
-        prefs.put( PREFS_TIME_FORMAT, getCookieValue( request, PREFS_TIME_FORMAT, defaultValue ) );
-
-        // Init the time zone
-        defaultValue = props.getProperty( "jspwiki.defaultprefs.template.timezone", java.util.TimeZone.getDefault().getID() );
-        prefs.put( PREFS_TIME_ZONE, getCookieValue( request, PREFS_TIME_ZONE, defaultValue ) );
-
-        // We're done here...
-        session.setAttribute( SESSIONPREFS, prefs );
-    }
-
-    private static String getCookieValue( HttpServletRequest request, String key, String defaultValue )
-    {
-        String cookieValue = null;
-        Cookie[] cookies = request.getCookies();
-        if( cookies != null )
-        {
-            for( Cookie cookie : request.getCookies() )
+            String key = item.getKey();
+            Object value = item.getValue();
+            if( key != null && value != null )
             {
-                if( key.equals( cookie.getName() ) )
+                String stringValue = null;
+                if( value instanceof Enum )
                 {
-                    cookieValue = cookie.getValue();
-                    break;
+                    stringValue = ((Enum<?>) value).name();
+                }
+                else if( value instanceof Boolean )
+                {
+                    stringValue = Boolean.toString( (Boolean) value );
                 }
+                else if( value instanceof TimeZone )
+                {
+                    stringValue = ((TimeZone) value).getID();
+                }
+                else
+                {
+                    stringValue = value.toString();
+                }
+                Cookie cookie = new Cookie( key, stringValue );
+                response.addCookie( cookie );
             }
         }
-        return cookieValue == null ? defaultValue : cookieValue;
     }
 
     /**
-     * Returns a Map of localized time zones, with the TimeZone IDs as keys and
-     * localized formatted names as the values.
-     * 
-     * @param request the HTTP request
-     * @return map of TimeZones
-     * @since 2.7.x
+     * {@inheritDoc}
      */
-    public static Map<String, String> listTimeZones( HttpServletRequest request )
+    public int size()
     {
-        WikiEngine engine = WikiEngine.getInstance( request.getSession().getServletContext(), null );
-        LinkedHashMap<String, String> resultMap = new LinkedHashMap<String, String>();
-        java.util.TimeZone serverZone = java.util.TimeZone.getDefault();
-        Date now = new Date();
-
-        // Build a map of TimeZones and their localized display names
-        for( TimeZone zone : TIME_ZONES )
-        {
-            int offset = zone.getRawOffset() / 3600000;
-            String zoneLabel = "[GMT" + (offset > 0 ? "+" : "") + offset + "] "
-                               + zone.getDisplayName( zone.inDaylightTime( now ), TimeZone.LONG, request.getLocale() );
-            if( serverZone.getRawOffset() == zone.getRawOffset() )
-            {
-                InternationalizationManager i18n = engine.getInternationalizationManager();
-                String serverLabel = i18n.get( InternationalizationManager.TEMPLATES_BUNDLE, request.getLocale(),
-                                               I18NSERVER_TIMEZONE );
-                zoneLabel = zoneLabel + " " + serverLabel;
-            }
-            resultMap.put( zone.getID(), zoneLabel );
-        }
-        return resultMap;
+        return m_prefs.size();
     }
 
     /**
-     * List all installed i18n language properties
-     * 
-     * @param request the HTTP request
-     * @return map of installed Languages (with help of Juan Pablo Santos
-     *         Rodriguez)
-     * @since 2.7.x
+     * {@inheritDoc}
      */
-    public static Map<Locale, String> listLocales( HttpServletRequest request )
+    public Collection<Object> values()
     {
-        return LOCALES;
+        return m_prefs.values();
     }
 
     /**
      * List all available timeformats, read from the jspwiki.properties
      * 
-     * @param context the wiki context
      * @return map of TimeFormats
      * @since 2.7.x
      */
-    public static Map<String,String> listTimeFormats( WikiContext context )
+    private Map<String, String> availableTimeFormats()
     {
-        Properties props = context.getEngine().getWikiProperties();
+        Properties props = m_engine.getWikiProperties();
         ArrayList<String> timeFormats = new ArrayList<String>( 40 );
         LinkedHashMap<String, String> resultMap = new LinkedHashMap<String, String>();
 
@@ -528,9 +503,9 @@
 
         /* fetch actual formats */
         if( timeFormats.size() == 0 ) /*
-                                 * no props found - make sure some default
-                                 * formats are avail
-                                 */
+                                       * no props found - make sure some default
+                                       * formats are avail
+                                       */
         {
             timeFormats.add( "dd-MMM-yy" );
             timeFormats.add( "d-MMM-yyyy" );
@@ -546,14 +521,13 @@
             }
         }
 
-        String prefTimeZone = Preferences.getPreference( context.getHttpRequest().getSession(), PREFS_TIME_ZONE );
-        TimeZone timeZone = TimeZone.getTimeZone( prefTimeZone );
+        TimeZone timeZone = (TimeZone) m_prefs.get( PREFS_TIME_ZONE );
 
         Date d = new Date(); // current date
         try
         {
             // dummy format pattern
-            SimpleDateFormat format = Preferences.getDateFormat( context, TimeFormat.DATETIME );
+            SimpleDateFormat format = getDateFormat( TimeFormat.DATETIME );
             format.setTimeZone( timeZone );
 
             for( int i = 0; i < timeFormats.size(); i++ )
@@ -577,4 +551,140 @@
         return resultMap;
     }
 
+    @SuppressWarnings( "unchecked" )
+    private Object coerceCookieValue( HttpServletRequest request, TypeConverterFactory converters, String cookieName,
+                                      String defaultValue )
+    {
+        // Get the cookie value as a String
+        String cookieValue = null;
+        Cookie[] cookies = request.getCookies();
+        if( cookies != null )
+        {
+            for( Cookie cookie : request.getCookies() )
+            {
+                if( cookieName.equals( cookie.getName() ) )
+                {
+                    cookieValue = cookie.getValue();
+                    break;
+                }
+            }
+        }
+        if( cookieValue == null )
+        {
+            cookieValue = defaultValue;
+        }
+
+        // Coerce the value into the target format
+        Locale locale = (Locale) get( PREFS_LOCALE );
+        Class targetClass = TYPE_CONVERTERS.get( cookieName );
+        if( targetClass == null )
+        {
+            targetClass = String.class;
+        }
+        Object value = null;
+        try
+        {
+            TypeConverter<?> converter = converters.getTypeConverter( targetClass, locale );
+            converter.setLocale( locale );
+            value = converter.convert( cookieValue, targetClass, m_errors );
+        }
+        catch( Exception e )
+        {
+            log.error( "Could not coerce cookie " + cookieName + "\"" );
+        }
+
+        // If not coerced, return the default value
+        return value == null ? defaultValue : value;
+    }
+
+    /**
+     * <p>
+     * This method checks to see if user preferences have been loaded from
+     * request cookies, and if not, loads them. This method is called from three
+     * places: from
+     * {@link org.apache.wiki.ui.stripes.WikiInterceptor#intercept(net.sourceforge.stripes.controller.ExecutionContext)},
+     * {@link org.apache.wiki.action.WikiContextFactory#newContext(HttpServletRequest, javax.servlet.http.HttpServletResponse, String)}
+     * and
+     * {@link org.apache.wiki.action.WikiContextFactory#newViewContext(HttpServletRequest, javax.servlet.http.HttpServletResponse, org.apache.wiki.api.WikiPage)}
+     * .
+     * </p>
+     * <p>
+     * Every user preference is read from a unique cookie. This method parses
+     * each value from the respective cookie, and applies a default value if the
+     * cookie is not found in the request. Once all preference values are
+     * parsed, this method stashes the Preferences object in the user's
+     * HTTPSession so that as an attribute named {@link #SESSIONPREFS}, so that
+     * it can be recalled later. So that JSPWiki does not waste excessive cycles
+     * parsing preference cookies on every request, if this method finds the
+     * SESSIONPREFS already present in the session, it returns silently without
+     * doing any more work.
+     * </p>
+     * <p>
+     * To change user preference values after the initial parse, users normally
+     * invoke {@link org.apache.wiki.action.UserPreferencesActionBean#save()}.
+     * </p>
+     * 
+     * @param request the HTTP request
+     * @throws WikiException if the preferences cannot be initialized
+     */
+    private void initialize( HttpServletRequest request )
+    {
+        // Set up the Locale before we do anything else
+        Properties props = m_engine.getWikiProperties();
+        Locale locale = request.getLocale();
+        m_prefs.put( PREFS_LOCALE, locale );
+
+        // Get the type converter factory
+        Configuration stripesConfig = StripesFilter.getConfiguration();
+        if( stripesConfig == null )
+        {
+            throw new InternalWikiException( "Cannot obtain Stripes configuration. This might happen if " + "called outside a JSP." );
+        }
+        TypeConverterFactory converters = stripesConfig.getTypeConverterFactory();
+        m_errors.clear();
+
+        // FIXME: "editor" property does not get registered, may be related with
+        // http://bugs.jspwiki.org/show_bug.cgi?id=117
+        // disabling it until knowing why it's happening
+        // FIXME: editormanager reads jspwiki.editor -- which of both properties
+        // should continue
+        String defaultValue = props.getProperty( "jspwiki.defaultprefs.template.editor", "plain" );
+        Object value = coerceCookieValue( request, converters, PREFS_EDITOR, defaultValue );
+        m_prefs.put( PREFS_EDITOR, value );
+
+        // Init the orientation
+        defaultValue = props.getProperty( "jspwiki.defaultprefs.template.orientation", Orientation.LEFT.name() );
+        value = coerceCookieValue( request, converters, PREFS_ORIENTATION, defaultValue );
+        m_prefs.put( PREFS_ORIENTATION, value );
+
+        // Init section editing
+        defaultValue = props.getProperty( "jspwiki.defaultprefs.template.sectionediting", "false" );
+        value = coerceCookieValue( request, converters, PREFS_SECTION_EDITING, defaultValue );
+        m_prefs.put( PREFS_SECTION_EDITING, value );
+
+        // Init the template skin
+        defaultValue = props.getProperty( "jspwiki.defaultprefs.template.skinname", "PlainVanilla" );
+        value = coerceCookieValue( request, converters, PREFS_SKIN, defaultValue );
+        m_prefs.put( PREFS_SKIN, value );
+
+        // Init the time format
+        defaultValue = props.getProperty( "jspwiki.defaultprefs.template.dateformat", m_engine.getInternationalizationManager()
+            .get( InternationalizationManager.CORE_BUNDLE, locale, "common.datetimeformat" ) );
+        value = coerceCookieValue( request, converters, PREFS_TIME_FORMAT, defaultValue );
+        m_prefs.put( PREFS_TIME_FORMAT, value );
+
+        // Init the time zone
+        defaultValue = props.getProperty( "jspwiki.defaultprefs.template.timezone", java.util.TimeZone.getDefault().getID() );
+        value = coerceCookieValue( request, converters, PREFS_TIME_ZONE, defaultValue );
+        for( TimeZone timeZone : AVAILABLE_TIME_ZONES )
+        {
+            if( timeZone.getRawOffset() == ((TimeZone) value).getRawOffset() )
+            {
+                value = timeZone;
+                break;
+            }
+        }
+        m_prefs.put( PREFS_TIME_ZONE, value );
+    }
+
 }

Modified: incubator/jspwiki/trunk/src/java/org/apache/wiki/tags/PageDateTag.java
URL: http://svn.apache.org/viewvc/incubator/jspwiki/trunk/src/java/org/apache/wiki/tags/PageDateTag.java?rev=912172&r1=912171&r2=912172&view=diff
==============================================================================
--- incubator/jspwiki/trunk/src/java/org/apache/wiki/tags/PageDateTag.java (original)
+++ incubator/jspwiki/trunk/src/java/org/apache/wiki/tags/PageDateTag.java Sat Feb 20 18:08:02 2010
@@ -20,9 +20,9 @@
  */
 package org.apache.wiki.tags;
 
-import java.util.Date;
-import java.text.SimpleDateFormat;
 import java.io.IOException;
+import java.text.SimpleDateFormat;
+import java.util.Date;
 
 import org.apache.wiki.api.WikiPage;
 import org.apache.wiki.preferences.Preferences;
@@ -83,12 +83,15 @@
             if( d != null )
             {
                 SimpleDateFormat fmt;
-                
                 if( m_format == null )
-                    fmt = Preferences.getDateFormat( m_wikiContext, TimeFormat.DATETIME );
+                {
+                    Preferences prefs = Preferences.getPreferences( m_wikiContext.getHttpRequest() );
+                    fmt = prefs.getDateFormat( TimeFormat.DATETIME );
+                }
                 else
+                {
                     fmt = new SimpleDateFormat( m_format );
-
+                }
                 pageContext.getOut().write( fmt.format( d ) );
             }
             else

Modified: incubator/jspwiki/trunk/src/java/org/apache/wiki/ui/EditorManager.java
URL: http://svn.apache.org/viewvc/incubator/jspwiki/trunk/src/java/org/apache/wiki/ui/EditorManager.java?rev=912172&r1=912171&r2=912172&view=diff
==============================================================================
--- incubator/jspwiki/trunk/src/java/org/apache/wiki/ui/EditorManager.java (original)
+++ incubator/jspwiki/trunk/src/java/org/apache/wiki/ui/EditorManager.java Sat Feb 20 18:08:02 2010
@@ -195,7 +195,8 @@
         String editor = null;
 
         // User has set an editor in preferences
-        editor = Preferences.getPreference( context, Preferences.PREFS_EDITOR  );
+        Preferences prefs = Preferences.getPreferences( context.getHttpRequest() );
+        editor = (String)prefs.get( Preferences.PREFS_EDITOR  );
 
         /* FIXME: actual default 'editor' property is read by the Preferences class */
         if (editor == null)

Modified: incubator/jspwiki/trunk/src/java/org/apache/wiki/ui/TemplateManager.java
URL: http://svn.apache.org/viewvc/incubator/jspwiki/trunk/src/java/org/apache/wiki/ui/TemplateManager.java?rev=912172&r1=912171&r2=912172&view=diff
==============================================================================
--- incubator/jspwiki/trunk/src/java/org/apache/wiki/ui/TemplateManager.java (original)
+++ incubator/jspwiki/trunk/src/java/org/apache/wiki/ui/TemplateManager.java Sat Feb 20 18:08:02 2010
@@ -342,19 +342,16 @@
      * whether there is anything actually in the directories, it just lists
      * them. This may change in the future.
      * 
-     * @param request the HTTP request
+     * @param servletContext the servlet context
      * @param template The template to search
      * @return Set of Strings with the skin names.
      * @since 2.3.26
      */
     @SuppressWarnings( "unchecked" )
-    public Set listSkins( HttpServletRequest request, String template )
+    public Set<String> listSkins( ServletContext servletContext, String template )
     {
         String place = makeFullJSPName( template, SKIN_DIRECTORY );
-
-        ServletContext sContext = request.getSession().getServletContext();
-
-        Set<String> skinSet = sContext.getResourcePaths( place );
+        Set<String> skinSet = servletContext.getResourcePaths( place );
         TreeSet<String> resultSet = new TreeSet<String>();
 
         if( log.isDebugEnabled() )

Modified: incubator/jspwiki/trunk/src/java/org/apache/wiki/ui/stripes/PreferencesLocalePicker.java
URL: http://svn.apache.org/viewvc/incubator/jspwiki/trunk/src/java/org/apache/wiki/ui/stripes/PreferencesLocalePicker.java?rev=912172&r1=912171&r2=912172&view=diff
==============================================================================
--- incubator/jspwiki/trunk/src/java/org/apache/wiki/ui/stripes/PreferencesLocalePicker.java (original)
+++ incubator/jspwiki/trunk/src/java/org/apache/wiki/ui/stripes/PreferencesLocalePicker.java Sat Feb 20 18:08:02 2010
@@ -21,36 +21,126 @@
 package org.apache.wiki.ui.stripes;
 
 import java.util.Locale;
+import java.util.Properties;
 
+import javax.servlet.http.Cookie;
 import javax.servlet.http.HttpServletRequest;
 
-import org.apache.wiki.preferences.Preferences;
+import net.sourceforge.stripes.config.Configuration;
+import net.sourceforge.stripes.localization.LocalePicker;
 
-import net.sourceforge.stripes.localization.DefaultLocalePicker;
+import org.apache.wiki.WikiEngine;
+import org.apache.wiki.preferences.Preferences;
 
 /**
- *  This is a simple Stripes LocalePicker which uses {@link Preferences#getLocale(HttpServletRequest)}
- *  to determine the request Locale.
+ * This is a simple Stripes LocalePicker which uses
+ * {@link Preferences#getLocale(HttpServletRequest)} to determine the request
+ * Locale.
  */
-public class PreferencesLocalePicker extends DefaultLocalePicker
+public class PreferencesLocalePicker implements LocalePicker
 {
+    private static final LocaleConverter LOCALE_CONVERTER = new LocaleConverter();
+
+    /**
+     * Cookie name for the user's preferred {@link java.util.Locale}.
+     */
+    private static final String COOKIE_LOCALE = Preferences.PREFS_LOCALE;
+
+    /**
+     * Initializes the locale picker.
+     */
+    public void init( Configuration configuration ) throws Exception
+    {
+    }
 
     /**
-     *  JSPWiki only uses UTF-8.
+     * JSPWiki only uses UTF-8.
      */
-    @Override
     public String pickCharacterEncoding( HttpServletRequest request, Locale locale )
     {
         return "UTF-8";
     }
 
     /**
-     *  Simply calls Preferences.getLocale() to pick the locale.
+     * Picks the Locale by extracting the user's desired value from cookies,
+     * then selecting the closest supported locale/country/variant combination
+     * that is supported by JSPWiki. If the user's locale cookie is not set, the
+     * request's locale will be checked.
      */
-    @Override
     public Locale pickLocale( HttpServletRequest request )
     {
-        return Preferences.getLocale( request );
+        // Extract the user's cookie value (browser's request value is the fallback)
+        Locale locale = null;
+        Cookie[] cookies = request.getCookies();
+        if( cookies != null )
+        {
+            for( Cookie cookie : request.getCookies() )
+            {
+                if( COOKIE_LOCALE.equals( cookie.getName() ) )
+                {
+                    locale = LOCALE_CONVERTER.convert( cookie.getValue(), Locale.class, null );
+                    break;
+                }
+            }
+        }
+        if ( locale == null )
+        {
+            locale = request.getLocale();
+        }
+
+        // See if we can match the user's locale against one we support
+        Locale match = isSupported( locale.getLanguage(), locale.getCountry(), locale.getVariant() );
+        if( match == null )
+        {
+            match = isSupported( locale.getLanguage(), locale.getCountry(), null );
+            if( match == null )
+            {
+                match = isSupported( locale.getLanguage(), null, null );
+            }
+        }
+        if( match == null )
+        {
+            // If we can't, use the WikiEngine's default locale
+            WikiEngine engine = WikiEngine.getInstance( request.getSession().getServletContext(), null );
+            Properties props = engine.getWikiProperties();
+            String defaultPref = props.getProperty( "jspwiki.defaultprefs.template.language", Locale.getDefault().toString() );
+            match = LOCALE_CONVERTER.convert( defaultPref, Locale.class, null );
+        }
+        
+        // Set the preferred locale in Prefs
+        Preferences prefs = Preferences.getPreferences( request );
+        prefs.put( Preferences.PREFS_LOCALE, match );
+        return match;
     }
-    
+
+    /**
+     * Returns true if two strings are equal. Unlike the normal equals function,
+     * two strings that are both {@code null} are considered equal.
+     * 
+     * @param a the first string
+     * @param b the second string
+     * @return the result
+     */
+    private boolean isEqual( String a, String b )
+    {
+        if ( a == null ) a = "";
+        if ( b == null ) b = "";
+        return a.equals( b );
+    }
+
+    private Locale isSupported( String language, String country, String variant )
+    {
+        for( Locale locale : Preferences.AVAILABLE_LOCALES.keySet() )
+        {
+            boolean languageMatch = isEqual( language, locale.getLanguage() );
+            boolean countryMatch = isEqual( country, locale.getCountry() );
+            boolean variantMatch = isEqual( variant, locale.getVariant() );
+            if( languageMatch && countryMatch && variantMatch )
+            {
+                return locale;
+            }
+        }
+        return null;
+    }
+
 }

Added: incubator/jspwiki/trunk/src/java/org/apache/wiki/ui/stripes/TimeZoneFormatter.java
URL: http://svn.apache.org/viewvc/incubator/jspwiki/trunk/src/java/org/apache/wiki/ui/stripes/TimeZoneFormatter.java?rev=912172&view=auto
==============================================================================
--- incubator/jspwiki/trunk/src/java/org/apache/wiki/ui/stripes/TimeZoneFormatter.java (added)
+++ incubator/jspwiki/trunk/src/java/org/apache/wiki/ui/stripes/TimeZoneFormatter.java Sat Feb 20 18:08:02 2010
@@ -0,0 +1,110 @@
+package org.apache.wiki.ui.stripes;
+
+import java.util.Date;
+import java.util.Locale;
+import java.util.ResourceBundle;
+import java.util.TimeZone;
+
+import net.sourceforge.stripes.format.Formatter;
+
+import org.apache.wiki.i18n.InternationalizationManager;
+
+/**
+ * Stripes Formatter class that formats a supplied wiki
+ * {@link java.util.TimeZone}. Two formatting types are available: {@code
+ * localized} produces a long-form, localized label (e.g., {@code [GMT-5]
+ * Eastern Standard Time}); format type {@code id} generates the time zone ID
+ * (e.g., {@code America/New_York}). If an unsupported format type is supplied,
+ * the value will default to {@link TimeZone#toString()}.
+ */
+public class TimeZoneFormatter implements Formatter<TimeZone>
+{
+    private Locale m_locale = null;
+
+    private String m_formatType = null;
+
+    /**
+     * The default format type that produces a localized time zone string.
+     */
+    public static final String LOCALIZED = "localized";
+
+    /**
+     * An alternative format type that produces the time zone ID.
+     */
+    public static final String ID = "id";
+
+    /** I18N string to mark the server timezone */
+    public static final String I18NSERVER_TIMEZONE = "prefs.user.timezone.server";
+
+    /**
+     * {@inheritDoc}
+     * <p>
+     * This implementation produces a formatted String representing the
+     * {@link TimeZone}.
+     * </p>
+     */
+    public String format( TimeZone zone )
+    {
+        if ( m_formatType == null ) m_formatType = LOCALIZED;
+        if( LOCALIZED.equals( m_formatType ) )
+        {
+            java.util.TimeZone serverZone = java.util.TimeZone.getDefault();
+            Date now = new Date();
+
+            int offset = zone.getRawOffset() / 3600000;
+            String zoneLabel = "[GMT" + (offset > 0 ? "+" : "") + offset + "] "
+                               + zone.getDisplayName( zone.inDaylightTime( now ), TimeZone.LONG, m_locale );
+            if( serverZone.getRawOffset() == zone.getRawOffset() )
+            {
+                ResourceBundle b = ResourceBundle.getBundle( InternationalizationManager.TEMPLATES_BUNDLE, m_locale );
+                String serverLabel = b.getString( I18NSERVER_TIMEZONE );
+                zoneLabel = zoneLabel + " " + serverLabel;
+            }
+            return zoneLabel;
+        }
+        else if( ID.equals( m_formatType ) )
+        {
+            return zone.getID();
+        }
+        return zone.toString();
+    }
+
+    /**
+     * {@inheritDoc}
+     * <p>
+     * This implementation does nothing.
+     * </p>
+     */
+    public void init()
+    {
+    }
+
+    /**
+     * {@inheritDoc}
+     * <p>
+     * This implementation does nothing; the time zone name is always used.
+     * </p>
+     */
+    public void setFormatPattern( String formatPattern )
+    {
+    }
+
+    /**
+     * <p>
+     * Sets the format type. The default is {@link #LOCALIZED}
+     * </p>
+     */
+    public void setFormatType( String formatType )
+    {
+        m_formatType = formatType;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public void setLocale( Locale locale )
+    {
+        m_locale = locale;
+    }
+
+}

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=912172&r1=912171&r2=912172&view=diff
==============================================================================
--- incubator/jspwiki/trunk/src/java/org/apache/wiki/ui/stripes/WikiInterceptor.java (original)
+++ incubator/jspwiki/trunk/src/java/org/apache/wiki/ui/stripes/WikiInterceptor.java Sat Feb 20 18:08:02 2010
@@ -319,9 +319,6 @@
         // Stash the WikiContext
         WikiContextFactory.saveContext( request, actionBean.getContext() );
 
-        // Set up user preferences
-        Preferences.setupPreferences( request );
-
         if( log.isDebugEnabled() )
         {
             log.debug( "WikiInterceptor resolved ActionBean: " + actionBean );

Modified: incubator/jspwiki/trunk/tests/java/org/apache/wiki/VariableManagerTest.java
URL: http://svn.apache.org/viewvc/incubator/jspwiki/trunk/tests/java/org/apache/wiki/VariableManagerTest.java?rev=912172&r1=912171&r2=912172&view=diff
==============================================================================
--- incubator/jspwiki/trunk/tests/java/org/apache/wiki/VariableManagerTest.java (original)
+++ incubator/jspwiki/trunk/tests/java/org/apache/wiki/VariableManagerTest.java Sat Feb 20 18:08:02 2010
@@ -215,7 +215,8 @@
     {
         // test for default dateformat
         //
-        String defaultDateFormat = Preferences.getDateFormat( m_context, TimeFormat.DATETIME ).format( new Date() );
+        Preferences prefs = Preferences.getPreferences( m_context.getHttpRequest() );
+        String defaultDateFormat = prefs.getDateFormat( TimeFormat.DATETIME ).format( new Date() );
 
         String res = m_variableManager.expandVariables( m_context, ">>>>>{$timestamp}<<<<<" );
         assertEquals( ">>>>>" + defaultDateFormat + "<<<<<", res );

Modified: incubator/jspwiki/trunk/tests/java/org/apache/wiki/action/UserPreferencesActionBeanTest.java
URL: http://svn.apache.org/viewvc/incubator/jspwiki/trunk/tests/java/org/apache/wiki/action/UserPreferencesActionBeanTest.java?rev=912172&r1=912171&r2=912172&view=diff
==============================================================================
--- incubator/jspwiki/trunk/tests/java/org/apache/wiki/action/UserPreferencesActionBeanTest.java (original)
+++ incubator/jspwiki/trunk/tests/java/org/apache/wiki/action/UserPreferencesActionBeanTest.java Sat Feb 20 18:08:02 2010
@@ -20,6 +20,7 @@
  */
 package org.apache.wiki.action;
 
+import java.util.Locale;
 import java.util.Properties;
 
 import javax.servlet.http.Cookie;
@@ -29,6 +30,7 @@
 import org.apache.wiki.action.UserPreferencesActionBean;
 import org.apache.wiki.auth.Users;
 import org.apache.wiki.auth.login.CookieAssertionLoginModule;
+import org.apache.wiki.preferences.Preferences;
 
 import junit.framework.Test;
 import junit.framework.TestCase;
@@ -63,7 +65,7 @@
     }
     
 
-    public void testCreateAssertedName() throws Exception
+    public void testSave() throws Exception
     {
         MockRoundtrip trip;
         UserPreferencesActionBean bean;
@@ -71,17 +73,44 @@
         // Create session; set 'assertion' param; verify it got saved
         trip = m_engine.guestTrip( "/UserPreferences.jsp" );
         trip.setParameter( "assertedName", "MyAssertedIdentity" );
-        trip.execute( "createAssertedName" );
+        trip.setParameter( "editor", "plain" );
+        trip.setParameter( "locale", Locale.GERMANY.toString() );
+        trip.setParameter( "orientation", Preferences.Orientation.RIGHT.name() );
+        trip.setParameter( "sectionEditing", "true" );
+        trip.setParameter( "skin", "Smart" );
+        trip.setParameter( "timeFormat", "YYYY dd-mm" );
+        trip.setParameter( "timeZone", Preferences.AVAILABLE_TIME_ZONES.get( 1 ).getID() );
+        trip.execute( "save" );
         bean = trip.getActionBean( UserPreferencesActionBean.class );
         assertEquals( "/Wiki.jsp", trip.getDestination() );
 
         // Verify that the asserted name cookie is present in the Response
         MockHttpServletResponse response = (MockHttpServletResponse) bean.getContext().getResponse();
         Cookie[] cookies = response.getCookies();
-        assertEquals( 1, cookies.length );
-        Cookie cookie = cookies[0];
-        assertEquals( CookieAssertionLoginModule.PREFS_COOKIE_NAME, cookie.getName() );
-        assertEquals( "MyAssertedIdentity", cookie.getValue() );
+        assertEquals( 8, cookies.length );
+        boolean foundCookie = false;
+        for ( Cookie cookie : response.getCookies() )
+        {
+            if ( CookieAssertionLoginModule.PREFS_COOKIE_NAME.equals( cookie.getName() ) )
+            {
+                if ( "MyAssertedIdentity".equals( cookie.getValue() ) )
+                {
+                    foundCookie = true;
+                    break;
+                }
+            }
+        }
+        assertTrue( foundCookie );
+        
+        // Verify that the Preference objects were set properly
+        Preferences prefs = Preferences.getPreferences( trip.getRequest() );
+        assertEquals( "plain", prefs.get( Preferences.PREFS_EDITOR ) );
+        assertEquals( Locale.GERMANY, prefs.get( Preferences.PREFS_LOCALE ) );
+        assertEquals( Preferences.Orientation.RIGHT, prefs.get( Preferences.PREFS_ORIENTATION ) );
+        assertEquals( true, prefs.get( Preferences.PREFS_SECTION_EDITING ) );
+        assertEquals( "Smart", prefs.get( Preferences.PREFS_SKIN ) );
+        assertEquals( "YYYY dd-mm", prefs.get( Preferences.PREFS_TIME_FORMAT ) );
+        assertEquals( Preferences.AVAILABLE_TIME_ZONES.get( 1 ), prefs.get( Preferences.PREFS_TIME_ZONE ) );
     }
 
     public void testCreateAssertedNameAfterLogin() throws Exception
@@ -98,15 +127,29 @@
 
         // Set 'assertion' param; verify redirect to front page
         trip.setParameter( "assertedName", "MyAssertedIdentity" );
-        trip.execute( "createAssertedName" );
+        trip.setParameter( "editor", "plain" );
+        trip.setParameter( "locale", Locale.GERMANY.toString() );
+        trip.setParameter( "orientation", Preferences.Orientation.RIGHT.name() );
+        trip.setParameter( "sectionEditing", "true" );
+        trip.setParameter( "skin", "Smart" );
+        trip.setParameter( "timeFormat", "YYYY dd-mm" );
+        trip.setParameter( "timeZone", Preferences.AVAILABLE_TIME_ZONES.get( 1 ).getID() );
+        trip.execute( "save" );
         bean = trip.getActionBean( UserPreferencesActionBean.class );
         assertEquals( "/Wiki.jsp", trip.getDestination() );
 
         // Verify that the asserted name cookie is NOT present in the Response
         // (authenticated users cannot set the assertion cookie)
         MockHttpServletResponse response = (MockHttpServletResponse) bean.getContext().getResponse();
-        Cookie[] cookies = response.getCookies();
-        assertEquals( 0, cookies.length );
+        boolean foundCookie = false;
+        for ( Cookie cookie : response.getCookies() )
+        {
+            if ( CookieAssertionLoginModule.PREFS_COOKIE_NAME.equals( cookie.getName() ) )
+            {
+                foundCookie = true;
+            }
+        }
+        assertFalse( foundCookie );
     }
 
     public void testClearAssertedName() throws Exception