You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@myfaces.apache.org by mb...@apache.org on 2005/10/20 11:59:31 UTC

svn commit: r326877 - in /myfaces: examples/trunk/conf/ impl/trunk/src/java/org/apache/myfaces/application/jsp/ impl/trunk/src/java/org/apache/myfaces/lifecycle/ share/trunk/src/java/org/apache/myfaces/renderkit/

Author: mbr
Date: Thu Oct 20 02:59:21 2005
New Revision: 326877

URL: http://svn.apache.org/viewcvs?rev=326877&view=rev
Log:
improved server side state,
new context parameter org.apache.myfaces.NUMBER_OF_VIEWS_IN_SESSION to define how many latest views should be stored in session,
new context parameter org.apache.myfaces.SERIALIZE_STATE_IN_SESSION to define if the state should be serialized to a byte stream in the session

Modified:
    myfaces/examples/trunk/conf/basic-web.xml
    myfaces/examples/trunk/conf/web-develop.xml
    myfaces/examples/trunk/conf/web.xml
    myfaces/impl/trunk/src/java/org/apache/myfaces/application/jsp/JspStateManagerImpl.java
    myfaces/impl/trunk/src/java/org/apache/myfaces/lifecycle/LifecycleImpl.java
    myfaces/share/trunk/src/java/org/apache/myfaces/renderkit/RendererUtils.java

Modified: myfaces/examples/trunk/conf/basic-web.xml
URL: http://svn.apache.org/viewcvs/myfaces/examples/trunk/conf/basic-web.xml?rev=326877&r1=326876&r2=326877&view=diff
==============================================================================
--- myfaces/examples/trunk/conf/basic-web.xml (original)
+++ myfaces/examples/trunk/conf/basic-web.xml Thu Oct 20 02:59:21 2005
@@ -54,6 +54,26 @@
     </context-param>
 
     <context-param>
+        <param-name>org.apache.myfaces.NUMBER_OF_VIEWS_IN_SESSION</param-name>
+        <param-value>20</param-value>
+        <description>
+            Only applicable if state saving method is "server" (= default).
+            Defines the amount (default = 20) of the latest views are stored in session.
+        </description>
+    </context-param>
+
+    <context-param>
+        <param-name>org.apache.myfaces.SERIALIZE_STATE_IN_SESSION</param-name>
+        <param-value>true</param-value>
+        <description>
+            Only applicable if state saving method is "server" (= default).
+            If true (default) the state will be serialized to a byte stream before it 
+            is written to the session.
+            If false the state will not be serialized to a byte stream.
+        </description>
+    </context-param>
+
+    <context-param>
         <param-name>org.apache.myfaces.ALLOW_JAVASCRIPT</param-name>
         <param-value>true</param-value>
         <description>

Modified: myfaces/examples/trunk/conf/web-develop.xml
URL: http://svn.apache.org/viewcvs/myfaces/examples/trunk/conf/web-develop.xml?rev=326877&r1=326876&r2=326877&view=diff
==============================================================================
--- myfaces/examples/trunk/conf/web-develop.xml (original)
+++ myfaces/examples/trunk/conf/web-develop.xml Thu Oct 20 02:59:21 2005
@@ -54,6 +54,26 @@
     </context-param>
 
     <context-param>
+        <param-name>org.apache.myfaces.NUMBER_OF_VIEWS_IN_SESSION</param-name>
+        <param-value>20</param-value>
+        <description>
+            Only applicable if state saving method is "server" (= default).
+            Defines the amount (default = 20) of the latest views are stored in session.
+        </description>
+    </context-param>
+
+    <context-param>
+        <param-name>org.apache.myfaces.SERIALIZE_STATE_IN_SESSION</param-name>
+        <param-value>true</param-value>
+        <description>
+            Only applicable if state saving method is "server" (= default).
+            If true (default) the state will be serialized to a byte stream before it 
+            is written to the session.
+            If false the state will not be serialized to a byte stream.
+        </description>
+    </context-param>
+
+    <context-param>
         <param-name>org.apache.myfaces.ALLOW_JAVASCRIPT</param-name>
         <param-value>true</param-value>
         <description>

Modified: myfaces/examples/trunk/conf/web.xml
URL: http://svn.apache.org/viewcvs/myfaces/examples/trunk/conf/web.xml?rev=326877&r1=326876&r2=326877&view=diff
==============================================================================
--- myfaces/examples/trunk/conf/web.xml (original)
+++ myfaces/examples/trunk/conf/web.xml Thu Oct 20 02:59:21 2005
@@ -54,6 +54,26 @@
     </context-param>
 
     <context-param>
+        <param-name>org.apache.myfaces.NUMBER_OF_VIEWS_IN_SESSION</param-name>
+        <param-value>20</param-value>
+        <description>
+            Only applicable if state saving method is "server" (= default).
+            Defines the amount (default = 20) of the latest views are stored in session.
+        </description>
+    </context-param>
+
+    <context-param>
+        <param-name>org.apache.myfaces.SERIALIZE_STATE_IN_SESSION</param-name>
+        <param-value>true</param-value>
+        <description>
+            Only applicable if state saving method is "server" (= default).
+            If true (default) the state will be serialized to a byte stream before it 
+            is written to the session.
+            If false the state will not be serialized to a byte stream.
+        </description>
+    </context-param>
+
+    <context-param>
         <param-name>org.apache.myfaces.ALLOW_JAVASCRIPT</param-name>
         <param-value>true</param-value>
         <description>

Modified: myfaces/impl/trunk/src/java/org/apache/myfaces/application/jsp/JspStateManagerImpl.java
URL: http://svn.apache.org/viewcvs/myfaces/impl/trunk/src/java/org/apache/myfaces/application/jsp/JspStateManagerImpl.java?rev=326877&r1=326876&r2=326877&view=diff
==============================================================================
--- myfaces/impl/trunk/src/java/org/apache/myfaces/application/jsp/JspStateManagerImpl.java (original)
+++ myfaces/impl/trunk/src/java/org/apache/myfaces/application/jsp/JspStateManagerImpl.java Thu Oct 20 02:59:21 2005
@@ -33,6 +33,7 @@
 
 import javax.faces.FactoryFinder;
 import javax.faces.application.StateManager;
+import javax.faces.application.StateManager.SerializedView;
 import javax.faces.component.NamingContainer;
 import javax.faces.component.UIComponent;
 import javax.faces.component.UIViewRoot;
@@ -66,6 +67,16 @@
             = JspStateManagerImpl.class.getName() + ".SERIALIZED_VIEW";
     private static final String SERIALIZED_VIEW_REQUEST_ATTR
             = JspStateManagerImpl.class.getName() + ".SERIALIZED_VIEW";
+    private static final String RESTORED_SERIALIZED_VIEW_REQUEST_ATTR
+    = JspStateManagerImpl.class.getName() + ".RESTORED_SERIALIZED_VIEW";
+    
+    private static final String NUMBER_OF_VIEWS_IN_SESSION_PARAM = "org.apache.myfaces.NUMBER_OF_VIEWS_IN_SESSION";
+    
+    private static final int DEFAULT_NUMBER_OF_VIEWS_IN_SESSION = 20;
+
+    private static final String SERIALIZE_STATE_IN_SESSION_PARAM = "org.apache.myfaces.SERIALIZE_STATE_IN_SESSION";
+
+    private static final boolean DEFAULT_SERIALIZE_STATE_IN_SESSION = true;
 
     private RenderKitFactory _renderKitFactory = null;
 
@@ -322,59 +333,130 @@
             viewCollection = new SerializedViewCollection();
             sessionMap.put(SERIALIZED_VIEW_SESSION_ATTR, viewCollection);
         }
-        viewCollection.add(context, serializeView(serializedView));
+        viewCollection.add(context, serializeView(context, serializedView));
+        // replace the value to notify the container about the change
+        sessionMap.put(SERIALIZED_VIEW_SESSION_ATTR, viewCollection);
     }
 
     protected SerializedView getSerializedViewFromServletSession(FacesContext context, String viewId)
     {
-        SerializedViewCollection viewCollection = (SerializedViewCollection) context
-                .getExternalContext().getSessionMap().get(SERIALIZED_VIEW_SESSION_ATTR);
-        if (viewCollection == null)
+        ExternalContext externalContext = context.getExternalContext();
+        Map requestMap = externalContext.getRequestMap();
+        SerializedView serializedView = null;
+        if (requestMap.containsKey(RESTORED_SERIALIZED_VIEW_REQUEST_ATTR))
         {
-            return null; // no state information in session
+            serializedView = (SerializedView) requestMap.get(RESTORED_SERIALIZED_VIEW_REQUEST_ATTR);
         }
-        Object state = viewCollection.get(context, viewId);
-        if (state != null)
+        else
         {
-            return deserializeView(state);
+            SerializedViewCollection viewCollection = (SerializedViewCollection) externalContext
+                    .getSessionMap().get(SERIALIZED_VIEW_SESSION_ATTR);
+            if (viewCollection != null)
+            {
+                String sequence = (String) externalContext.getRequestParameterMap().get(
+                        RendererUtils.SEQUENCE_PARAM);
+                if (sequence != null)
+                {
+                    Object state = viewCollection.get(new Integer(sequence), viewId);
+                    if (state != null)
+                    {
+                        serializedView = deserializeView(state);
+                    }
+                }
+            }
+            requestMap.put(RESTORED_SERIALIZED_VIEW_REQUEST_ATTR, serializedView);
+            nextViewSequence(context);
         }
-        return null;
+        return serializedView;
     }
 
-    protected Object serializeView(SerializedView serializedView)
+    protected void nextViewSequence(FacesContext facescontext)
     {
-        ByteArrayOutputStream baos = new ByteArrayOutputStream(1024);
-        try
-        {
-            ObjectOutputStream out = new ObjectOutputStream(new GZIPOutputStream(baos));
-            out.writeObject(serializedView.getStructure());
-            out.writeObject(serializedView.getState());
-            out.close();
-            baos.close();
-            return baos.toByteArray();
+        ExternalContext externalContext = facescontext.getExternalContext();
+        Object sessionObj = externalContext.getSession(true);
+        synchronized(sessionObj) // synchronized to increase sequence if multiple requests 
+                                 // are handled at the same time for the session
+        {
+            Map map = externalContext.getSessionMap();
+            Integer sequence = (Integer) map.get(RendererUtils.SEQUENCE_PARAM);
+            if(sequence == null || sequence.intValue() == Integer.MAX_VALUE)
+            {
+                sequence = new Integer(1);
+            }
+            else
+            {
+                sequence = new Integer(sequence.intValue() + 1);
+            }
+            map.put(RendererUtils.SEQUENCE_PARAM, sequence);
+            externalContext.getRequestMap().put(RendererUtils.SEQUENCE_PARAM, sequence);
         }
-        catch (IOException e)
+    }
+
+    protected Object serializeView(FacesContext context, SerializedView serializedView)
+    {
+        if(isSerializeStateInSession(context))
         {
-            log.error("Could not serialize state: " + e.getMessage(), e);
+            ByteArrayOutputStream baos = new ByteArrayOutputStream(1024);
+            try
+            {
+                ObjectOutputStream out = new ObjectOutputStream(new GZIPOutputStream(baos));
+                out.writeObject(serializedView.getStructure());
+                out.writeObject(serializedView.getState());
+                out.close();
+                baos.close();
+                return baos.toByteArray();
+            }
+            catch (IOException e)
+            {
+                log.error("Could not serialize state: " + e.getMessage(), e);
+            }
         }
+        else
+        {
+            return new Object[] {serializedView.getStructure(), serializedView.getState()};
+        }        
         return null;
     }
 
-    protected SerializedView deserializeView(Object object)
+    /**
+     * @param context
+     * @return
+     */
+    protected boolean isSerializeStateInSession(FacesContext context)
     {
-        try
+        String value = context.getExternalContext().getInitParameter(
+                SERIALIZE_STATE_IN_SESSION_PARAM);
+        boolean serialize = DEFAULT_SERIALIZE_STATE_IN_SESSION;
+        if (value != null)
         {
-            ObjectInputStream in = new ObjectInputStream(new GZIPInputStream(
-                    new ByteArrayInputStream((byte[]) object)));
-            return new SerializedView(in.readObject(), in.readObject());
+           serialize = new Boolean(value).booleanValue();
         }
-        catch (IOException e)
+        return serialize;
+    }
+
+    protected SerializedView deserializeView(Object state)
+    {
+        if(state instanceof byte[])
         {
-            log.error("Could not deserialize state: " + e.getMessage(), e);
+            try
+            {
+                ObjectInputStream in = new ObjectInputStream(new GZIPInputStream(
+                        new ByteArrayInputStream((byte[]) state)));
+                return new SerializedView(in.readObject(), in.readObject());
+            }
+            catch (IOException e)
+            {
+                log.error("Could not deserialize state: " + e.getMessage(), e);
+            }
+            catch (ClassNotFoundException e)
+            {
+                log.error("Could not deserialize state: " + e.getMessage(), e);
+            }
         }
-        catch (ClassNotFoundException e)
+        else if (state instanceof Object[])
         {
-            log.error("Could not deserialize state: " + e.getMessage(), e);
+            Object[] value = (Object[]) state;
+            return new SerializedView(value[0], value[1]);
         }
         return null;
     }
@@ -383,26 +465,55 @@
     {
         private static final long serialVersionUID = -3734849062185115847L;
 
-        private final List _keys = new ArrayList(15);
+        private final List _keys = new ArrayList(DEFAULT_NUMBER_OF_VIEWS_IN_SESSION);
         private final Map _serializedViews = new HashMap();
 
         // old views will be hold as soft references which will be removed by 
         // the garbage collector if free memory is low
         private transient Map _oldSerializedViews = null;
-
+        
         public synchronized void add(FacesContext context, Object state)
         {
             Object key = new SerializedViewKey(context);
             _serializedViews.put(key, state);
             _keys.add(key);
-
-            while (_keys.size() > 15) // TODO: configure the number for guaranteed views 
+            
+            int views = getNumberOfViewsInSession(context);
+            while (_keys.size() > views) 
             {
                 key = _keys.remove(0);
                 getOldSerializedViewsMap().put(key, _serializedViews.remove(key));
             }
         }
 
+        protected int getNumberOfViewsInSession(FacesContext context)
+        {
+            String value = context.getExternalContext().getInitParameter(
+                    NUMBER_OF_VIEWS_IN_SESSION_PARAM);
+            int views = DEFAULT_NUMBER_OF_VIEWS_IN_SESSION;
+            if (value != null)
+            {
+                try
+                {
+                    views = Integer.parseInt(value);
+                    if (views <= 0)
+                    {
+                        log.error("Configured value for " + NUMBER_OF_VIEWS_IN_SESSION_PARAM
+                                + " is not valid, must be an value > 0, using default value ("
+                                + DEFAULT_NUMBER_OF_VIEWS_IN_SESSION);
+                        views = DEFAULT_NUMBER_OF_VIEWS_IN_SESSION;
+                    }
+                }
+                catch (Throwable e)
+                {
+                    log.error("Error determining the value for " + NUMBER_OF_VIEWS_IN_SESSION_PARAM
+                            + ", expected an integer value > 0, using default value ("
+                            + DEFAULT_NUMBER_OF_VIEWS_IN_SESSION + "): " + e.getMessage(), e);
+                }
+            }
+            return views;
+        }
+
         /**
          * @return
          */
@@ -415,15 +526,9 @@
             return _oldSerializedViews;
         }
 
-        public Object get(FacesContext context, String viewId)
+        public Object get(Integer sequence, String viewId)
         {
-            String sequence = (String) context.getExternalContext().getRequestParameterMap().get(
-                    RendererUtils.SEQUENCE_PARAM);
-            if (sequence == null)
-            {
-                return null;
-            }
-            Object key = new SerializedViewKey(viewId, new Integer(sequence));
+            Object key = new SerializedViewKey(viewId, sequence);
             Object value = _serializedViews.get(key);
             if (value == null)
             {

Modified: myfaces/impl/trunk/src/java/org/apache/myfaces/lifecycle/LifecycleImpl.java
URL: http://svn.apache.org/viewcvs/myfaces/impl/trunk/src/java/org/apache/myfaces/lifecycle/LifecycleImpl.java?rev=326877&r1=326876&r2=326877&view=diff
==============================================================================
--- myfaces/impl/trunk/src/java/org/apache/myfaces/lifecycle/LifecycleImpl.java (original)
+++ myfaces/impl/trunk/src/java/org/apache/myfaces/lifecycle/LifecycleImpl.java Thu Oct 20 02:59:21 2005
@@ -327,8 +327,6 @@
         Application application = facesContext.getApplication();
         ViewHandler viewHandler = application.getViewHandler();
         
-        RendererUtils.nextViewSequence(facesContext);
-        
         try
         {
             viewHandler.renderView(facesContext, facesContext.getViewRoot());

Modified: myfaces/share/trunk/src/java/org/apache/myfaces/renderkit/RendererUtils.java
URL: http://svn.apache.org/viewcvs/myfaces/share/trunk/src/java/org/apache/myfaces/renderkit/RendererUtils.java?rev=326877&r1=326876&r2=326877&view=diff
==============================================================================
--- myfaces/share/trunk/src/java/org/apache/myfaces/renderkit/RendererUtils.java (original)
+++ myfaces/share/trunk/src/java/org/apache/myfaces/renderkit/RendererUtils.java Thu Oct 20 02:59:21 2005
@@ -42,12 +42,14 @@
 import javax.faces.component.UIViewRoot;
 import javax.faces.component.ValueHolder;
 import javax.faces.component.html.HtmlInputText;
+import javax.faces.context.ExternalContext;
 import javax.faces.context.FacesContext;
 import javax.faces.convert.Converter;
 import javax.faces.convert.ConverterException;
 import javax.faces.el.PropertyNotFoundException;
 import javax.faces.el.ValueBinding;
 import javax.faces.model.SelectItem;
+import javax.portlet.PortletSession;
 
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
@@ -755,29 +757,13 @@
 
     public static Integer getViewSequence(FacesContext facescontext)
     {
-        Map map = facescontext.getExternalContext().getSessionMap();
+        Map map = facescontext.getExternalContext().getRequestMap();
         Integer sequence = (Integer) map.get(SEQUENCE_PARAM);
         if(sequence == null)
         {
             sequence = new Integer(1);
             map.put(SEQUENCE_PARAM, sequence);
         }
-        return sequence;
-    }
-    
-    public static Integer nextViewSequence(FacesContext facescontext)
-    {
-        Map map = facescontext.getExternalContext().getSessionMap();
-        Integer sequence = (Integer) map.get(SEQUENCE_PARAM);
-        if(sequence == null)
-        {
-            sequence = new Integer(1);
-        }
-        else
-        {
-            sequence = new Integer(sequence.intValue() + 1);
-        }
-        map.put(SEQUENCE_PARAM, sequence);
         return sequence;
     }
 }