You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@myfaces.apache.org by we...@apache.org on 2008/11/27 10:56:21 UTC

svn commit: r721138 - in /myfaces/core/branches/2_0_0/impl/src: main/java/org/apache/myfaces/context/servlet/FacesContextImpl.java test/java/org/apache/myfaces/context/ExecutePhaseClientIdsTest.java

Author: werpu
Date: Thu Nov 27 01:56:21 2008
New Revision: 721138

URL: http://svn.apache.org/viewvc?rev=721138&view=rev
Log:
https://issues.apache.org/jira/browse/MYFACES-1991

https://issues.apache.org/jira/browse/MYFACES-1990

Added:
    myfaces/core/branches/2_0_0/impl/src/test/java/org/apache/myfaces/context/ExecutePhaseClientIdsTest.java   (with props)
Modified:
    myfaces/core/branches/2_0_0/impl/src/main/java/org/apache/myfaces/context/servlet/FacesContextImpl.java

Modified: myfaces/core/branches/2_0_0/impl/src/main/java/org/apache/myfaces/context/servlet/FacesContextImpl.java
URL: http://svn.apache.org/viewvc/myfaces/core/branches/2_0_0/impl/src/main/java/org/apache/myfaces/context/servlet/FacesContextImpl.java?rev=721138&r1=721137&r2=721138&view=diff
==============================================================================
--- myfaces/core/branches/2_0_0/impl/src/main/java/org/apache/myfaces/context/servlet/FacesContextImpl.java (original)
+++ myfaces/core/branches/2_0_0/impl/src/main/java/org/apache/myfaces/context/servlet/FacesContextImpl.java Thu Nov 27 01:56:21 2008
@@ -58,8 +58,7 @@
 import org.apache.myfaces.shared_impl.util.NullIterator;
 import sun.misc.Regexp;
 
-
-    /**
+/**
  * @author Manfred Geiler (latest modification by $Author$)
  * @author Anton Koinov
  * @version $Revision$ $Date$
@@ -97,11 +96,8 @@
     private static final String METHOD_GETVIEWROOT = "getViewRoot";
     private static final String METHOD_ISRENDERALL = "isRenderAll";
     private static final String METHOD_SETRENDERALL = "setRenderAll";
-
     static final String RE_SPLITTER = "[\\s\\t\\r\\n]*\\,[\\s\\t\\r\\n]*";
     public static final String AJAX_REQ_KEY = "javax.faces.partial.ajax";
-
-
     // ~ Instance fields ----------------------------------------------------------------------------
 
     // TODO: I think a Map<String, List<FacesMessage>> would more efficient than those two -= Simon Lessard =-
@@ -123,14 +119,8 @@
     private ResponseSwitch _responseWrapper = null;
     private List<String> _renderPhaseClientIds = null;
     private List<String> _executePhaseClientIds = null;
-
     private Boolean _renderAll = null;
 
-
-
-  
-
-
     // ~ Constructors -------------------------------------------------------------------------------
     public FacesContextImpl(final ServletContext servletContext, final ServletRequest servletRequest,
             final ServletResponse servletResponse) {
@@ -144,8 +134,6 @@
         }
     }
 
-
-
     private void init(final ReleaseableExternalContext externalContext) {
         _application = ((ApplicationFactory) FactoryFinder.getFactory(FactoryFinder.APPLICATION_FACTORY)).getApplication();
         _renderKitFactory = (RenderKitFactory) FactoryFinder.getFactory(FactoryFinder.RENDER_KIT_FACTORY);
@@ -259,7 +247,7 @@
 
     @Override
     public final boolean getResponseComplete() {
-       assertNotReleased(METHOD_GETRESPONSECOMPLETE);
+        assertNotReleased(METHOD_GETRESPONSECOMPLETE);
 
         return _responseComplete;
     }
@@ -318,7 +306,7 @@
     @Override
     public final void addMessage(final String clientId, final FacesMessage message) {
         assertNotReleased(METHOD_ADDMESSAGE);
-        
+
         if (message == null) {
             throw new NullPointerException("message");
         }
@@ -348,13 +336,26 @@
             _externalContext = null;
         }
 
+        /*
+         * Spec JSF 2 section getAttributes
+         * when release is called the attributes map
+         * must!!! be cleared!
+         *
+         * (probably to trigger some clearance methods
+         * on possible added entries before nullifying everything)
+         */
+        if(_attributes != null) {
+            _attributes.clear();
+            _attributes = null;
+        }
+
         _messageClientIds = null;
         _messages = null;
         _application = null;
         _responseStream = null;
         _responseWriter = null;
         _viewRoot = null;
-        _attributes = null;
+       
 
         _released = true;
         FacesContext.setCurrentInstance(null);
@@ -370,14 +371,14 @@
     @Override
     public final void renderResponse() {
         assertNotReleased(METHOD_RENDERRESPONSE);
-        
+
         _renderResponse = true;
     }
 
     @Override
     public final void responseComplete() {
         assertNotReleased(METHOD_RESPONSECOMPLETE);
-      
+
         _responseComplete = true;
     }
 
@@ -416,7 +417,25 @@
     }
 
     /**
-     * @since JSF 2.0 
+     * Returns a mutable map of attributes associated
+     * with this faces context
+     * when {@link javax.faces.context.FacesContext.release} is called
+     * the map must be cleared!
+     *
+     * Note this map is not associated with the request map
+     * the request map still is accessible via the
+     * {@link javax.faces.context.FacesContext.getExternalContext.getRequestMap}
+     * method!
+     *
+     * Also the scope is different to the request map, this map has the scope
+     * of the context, and is cleared once the release method
+     * on the context is called!
+     *
+     * Also the map does not cause any events according to the spec!
+     *
+     * @since JSF 2.0
+     *
+     * @throws IllegalStateException if the current context already is released!
      */
     @Override
     public Map<Object, Object> getAttributes() {
@@ -435,6 +454,8 @@
      *
      * @param enable if set to true the response is routed through if set to false
      * the response is suppressed!
+     *
+     * @throws IllegalStateException if the current context already is released!
      */
     @Override
     public void enableResponseWriting(boolean enable) {
@@ -447,14 +468,26 @@
     /**
      * @return the list of client ids to be processed in the execute phase
      * null if all have to be processed
+     * The client ids either must be set via the setter
+     * or being present by having a PARTIAL_EXECUTE_PARAM_NAME with a value set
+     * non existent or NO_PARTIAL_PHASE_CLIENT_IDS values in the request map
+     * and a non set local list result in an empty list as return value!
+     *
+     * @since 2.0
+     * @throws IllegalStateException if the current context already is released!
      */
     @Override
     public List<String> getExecutePhaseClientIds() {
         assertNotReleased(METHOD_GETEXECUTEPHASECLIENTIDS);
 
-        return super.getExecutePhaseClientIds();
-    }
+        if(_executePhaseClientIds != null) {
+            return _executePhaseClientIds;
+        }
 
+        _executePhaseClientIds = getRequestParameterList(PARTIAL_EXECUTE_PARAM_NAME, NO_PARTIAL_PHASE_CLIENT_IDS);
+
+        return _executePhaseClientIds;
+    }
 
     /**
      *
@@ -475,20 +508,36 @@
         assertNotReleased(METHOD_GETRENDERPHASECLIENTIDS);
 
         /*already processed or set from the outside*/
-        if(null != _renderPhaseClientIds) {
+        if (null != _renderPhaseClientIds) {
             return _renderPhaseClientIds;
         }
 
+        _renderPhaseClientIds = getRequestParameterList(PARTIAL_RENDER_PARAM_NAME, NO_PARTIAL_PHASE_CLIENT_IDS);
+
+        return _renderPhaseClientIds;
+    }
+
+    /**
+     * private helper method to split incoming
+     * request parameter lists according to the JSF2 specs
+     * the JSF2 spec usually sees empty lists as either not being
+     * set (null), or empty == "" or with an optional special value
+     * being set marking it as empty!
+     * 
+     * @param key the request parameter key holding the list
+     * @param emptyValue the special empty value
+     * @return a list of strings or an empty list if nothing was found
+     */
+    private final List<String> getRequestParameterList(String key, String emptyValue) {
+
         Map paramMap = ((ServletRequest) getExternalContext().getRequest()).getParameterMap();
-        String clientIds = (String) paramMap.get(PARTIAL_RENDER_PARAM_NAME);
-        if(clientIds == null ) {//no value given
-            _renderPhaseClientIds = Collections.EMPTY_LIST;
-            return _renderPhaseClientIds;
+        String clientIds = (String) paramMap.get(key);
+        if (clientIds == null) {//no value given
+            return Collections.EMPTY_LIST;
         }
         clientIds = clientIds.trim();
-        if(clientIds.equals("") || clientIds.equals(NO_PARTIAL_PHASE_CLIENT_IDS)) {//empty String!
-            _renderPhaseClientIds = Collections.EMPTY_LIST;
-            return _renderPhaseClientIds;
+        if (clientIds.equals("") || (emptyValue != null && clientIds.equals(emptyValue))) {//empty String!
+            return Collections.EMPTY_LIST;
         }
 
         /**
@@ -497,16 +546,13 @@
          */
         String[] splitted = clientIds.split(RE_SPLITTER);
         /*we have to retrim the first and last entry we could
-         have pending blanks!*/
+        have pending blanks!*/
         splitted[0] = splitted[0].trim();
-        int trimLast = splitted.length-1;
-        if(trimLast > 0) {//all others trimmed by the re
-            splitted[trimLast] =  splitted[trimLast].trim();
+        int trimLast = splitted.length - 1;
+        if (trimLast > 0) {//all others trimmed by the re
+            splitted[trimLast] = splitted[trimLast].trim();
         }
-        _renderPhaseClientIds = Arrays.asList(splitted);
-
-      
-        return _renderPhaseClientIds;
+        return Arrays.asList(splitted);
     }
 
     /**
@@ -520,7 +566,7 @@
     public void setExecutePhaseClientIds(List<String> executePhaseClientIds) {
         assertNotReleased(METHOD_SETEXECUTEPHASECLIENTIDS);
 
-        super.setExecutePhaseClientIds(executePhaseClientIds);
+        _executePhaseClientIds = executePhaseClientIds;
     }
 
     /**
@@ -547,13 +593,11 @@
      * can push in a request wrapper!
      *
      */
-  /*  @Override
+    /*  @Override
     public boolean isAjaxRequest() {
-        Map requestMap = getExternalContext().getRequestMap();
-        return requestMap.containsKey(AJAX_REQ_KEY);
+    Map requestMap = getExternalContext().getRequestMap();
+    return requestMap.containsKey(AJAX_REQ_KEY);
     }*/
-
-   
     /**
      * @return is render none return true if {@link #PARTIAL_EXECUTE_PARAM_NAME} is set in the current request
      * map!
@@ -568,7 +612,6 @@
         return NO_PARTIAL_PHASE_CLIENT_IDS.equals(param);
     }
 
-
     /**
      * @return true in case of PARTIAL_RENDER_PARAM_NAME being set and its value is
      * NO_PARTIAL_PHASE_CLIENT_IDS. Otherwise return false
@@ -592,7 +635,7 @@
     public boolean isRenderAll() {
         assertNotReleased(METHOD_ISRENDERALL);
 
-        if(_renderAll != null) {
+        if (_renderAll != null) {
             return _renderAll;
         }
         //I assume doing the check once per request is correct
@@ -616,18 +659,16 @@
     @Override
     public void setRenderAll(boolean renderAll) {
         assertNotReleased(METHOD_SETRENDERALL);
-        
+
         _renderAll = renderAll;//autoboxing does the conversation here, no need to do casting
     }
 
-   
-
     /**
      * has to be thrown in many of the methods
      * if the method is called after the instance has been released!
      */
-    private void assertNotReleased(String string) {
-        if(_released) {
+    private final void assertNotReleased(String string) {
+        if (_released) {
             StringBuilder errorMessage = new StringBuilder(128);
             errorMessage.append("Error in method call on javax.faces.context.FacesContext.");
             errorMessage.append(string);
@@ -635,5 +676,4 @@
             throw new IllegalStateException(errorMessage.toString());
         }
     }
- 
 }

Added: myfaces/core/branches/2_0_0/impl/src/test/java/org/apache/myfaces/context/ExecutePhaseClientIdsTest.java
URL: http://svn.apache.org/viewvc/myfaces/core/branches/2_0_0/impl/src/test/java/org/apache/myfaces/context/ExecutePhaseClientIdsTest.java?rev=721138&view=auto
==============================================================================
--- myfaces/core/branches/2_0_0/impl/src/test/java/org/apache/myfaces/context/ExecutePhaseClientIdsTest.java (added)
+++ myfaces/core/branches/2_0_0/impl/src/test/java/org/apache/myfaces/context/ExecutePhaseClientIdsTest.java Thu Nov 27 01:56:21 2008
@@ -0,0 +1,127 @@
+/*
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ * 
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *  under the License.
+ */
+
+package org.apache.myfaces.context;
+
+import java.util.HashMap;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import javax.faces.context.FacesContext;
+import org.apache.myfaces.context.servlet.FacesContextImpl;
+import org.apache.shale.test.base.AbstractJsfTestCase;
+
+/**
+ * °
+ *
+ * @author Werner Punz(latest modification by $Author$)
+ * @version $Revision$ $Date$
+ */
+public class ExecutePhaseClientIdsTest extends AbstractJsfTestCase {
+     public ExecutePhaseClientIdsTest() {
+        super("ExecutePhaseClientIdsTest");
+    }
+
+    /**
+     * Empty String as request param
+     * has to result in an empty list
+     */
+    public void testRequestParams1() {
+        String empty = "    \n \t  ";
+        Map<String, String> requestParamMap = new HashMap<String, String>();
+        requestParamMap.put(FacesContext.PARTIAL_EXECUTE_PARAM_NAME, empty);
+        ContextTestRequestWrapper wrapper = new ContextTestRequestWrapper(request, requestParamMap);
+
+        FacesContext context = new FacesContextImpl(servletContext, wrapper, response);
+        assertTrue(context.getExecutePhaseClientIds().isEmpty());
+    }
+
+    /**
+     * no request param, has to result in an empty list
+     */
+    public void testRequestParams2() {
+        String empty = "";
+        Map<String, String> requestParamMap = new HashMap<String, String>();
+        ContextTestRequestWrapper wrapper = new ContextTestRequestWrapper(request, requestParamMap);
+
+        FacesContext context = new FacesContextImpl(servletContext, wrapper, response);
+        assertTrue(context.getExecutePhaseClientIds().isEmpty());
+    }
+
+    /**
+     * NO_PARTIAL_PHASE_CLIENT_IDS as request param, has to result in an empty list
+     */
+    public void testRequestParams4() {
+        Map<String, String> requestParamMap = new HashMap<String, String>();
+        requestParamMap.put(FacesContext.PARTIAL_EXECUTE_PARAM_NAME, FacesContext.NO_PARTIAL_PHASE_CLIENT_IDS);
+        ContextTestRequestWrapper wrapper = new ContextTestRequestWrapper(request, requestParamMap);
+
+        FacesContext context = new FacesContextImpl(servletContext, wrapper, response);
+        assertTrue(context.getExecutePhaseClientIds().isEmpty());
+    }
+
+    /**
+     * list with one element has to result in a list with one element
+     */
+    public void testRequestParams5() {
+        String params = " view1:panel1:_component1  ";
+        Map<String, String> requestParamMap = new HashMap<String, String>();
+        requestParamMap.put(FacesContext.PARTIAL_EXECUTE_PARAM_NAME, params);
+        ContextTestRequestWrapper wrapper = new ContextTestRequestWrapper(request, requestParamMap);
+
+        FacesContext context = new FacesContextImpl(servletContext, wrapper, response);
+        assertTrue("Length must be one",context.getExecutePhaseClientIds().size() == 1);
+        assertTrue("Value match",context.getExecutePhaseClientIds().get(0).equals("view1:panel1:_component1"));
+    }
+
+    /**
+     * test on a full blown list containing various
+     * blank chars
+     */
+    public void testRequestParams6() {
+        String params = " view1:panel1:_component1,view1:panel1:_component2 \n , component3, component4  ";
+        Map<String, String> requestParamMap = new HashMap<String, String>();
+        requestParamMap.put(FacesContext.PARTIAL_EXECUTE_PARAM_NAME, params);
+        ContextTestRequestWrapper wrapper = new ContextTestRequestWrapper(request, requestParamMap);
+
+        FacesContext context = new FacesContextImpl(servletContext, wrapper, response);
+        assertTrue("Length must be four",context.getExecutePhaseClientIds().size() == 4);
+
+        assertTrue("Value match",context.getExecutePhaseClientIds().get(0).equals("view1:panel1:_component1"));
+        assertTrue("Value match",context.getExecutePhaseClientIds().get(2).equals("component3"));
+
+
+        assertTrue("Value match",context.getExecutePhaseClientIds().get(3).equals("component4"));
+    }
+
+    /**
+     * priority the setter has higer priority
+     * than the request query
+     */
+    public void testSetter1() {
+        List<String> executePhaseClientIds = new LinkedList<String>();
+        executePhaseClientIds.add("component1");
+        executePhaseClientIds.add("component2");
+        String params = " view1:panel1:_component1,view1:panel1:_component2 \n , component3, component4  ";
+        Map<String, String> requestParamMap = new HashMap<String, String>();
+        requestParamMap.put(FacesContext.PARTIAL_EXECUTE_PARAM_NAME, params);
+        ContextTestRequestWrapper wrapper = new ContextTestRequestWrapper(request, requestParamMap);
+
+        FacesContext context = new FacesContextImpl(servletContext, wrapper, response);
+        context.setExecutePhaseClientIds(executePhaseClientIds);
+        assertTrue(context.getExecutePhaseClientIds().size() == 2);
+
+    }
+}

Propchange: myfaces/core/branches/2_0_0/impl/src/test/java/org/apache/myfaces/context/ExecutePhaseClientIdsTest.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: myfaces/core/branches/2_0_0/impl/src/test/java/org/apache/myfaces/context/ExecutePhaseClientIdsTest.java
------------------------------------------------------------------------------
    svn:keywords = Date Author Id Revision HeadURL