Markus Jung created MYFACES-4770:
------------------------------------

             Summary: ViewScopeCDIMap.put() returns internal 
ContextualInstanceInfo instead of the previous value
                 Key: MYFACES-4770
                 URL: https://issues.apache.org/jira/browse/MYFACES-4770
             Project: MyFaces Core
          Issue Type: Bug
    Affects Versions: 4.0.4, 4.1.4
            Reporter: Markus Jung


When CDI is available, UIViewRoot#getViewMap() is backed by ViewScopeCDIMap. 
Its put() returns whatever the underlying contextual storage returns, which is 
the previous internal ContextualInstanceInfo wrapper and not the previous value:
{code:java}
ContextualInstanceInfo info = new ContextualInstanceInfo();
info.setContextualInstance(value);
return getCreationalContextInstances().put(beanKey, info);
{code}
get() and remove() in the same class unwrap via info.getContextualInstance(), 
put() doesn't.

UIViewRoot#getViewMap(boolean) specifies the view scope as a plain Map[String, 
Object] ([Faces 4.1 
Javadoc|https://jakarta.ee/specifications/faces/4.1/apidocs/jakarta.faces/jakarta/faces/component/UIViewRoot.html#getViewMap(boolean)])
 and only adds requirements for clear(), so the java.util.Map contract applies 
([Map#put|https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/util/Map.html#put(K,V)]):
bq. Returns: the previous value associated with key, or null if there was no 
mapping for key.

Example:
{code:java}
Map[String, Object] viewMap = facesContext.getViewRoot().getViewMap();
viewMap.put("key", "first");
Object previous = viewMap.put("key", "second");
// expected "first", actual 
org.apache.myfaces.cdi.util.ContextualInstanceInfo@608f1caa
{code}
I ran into this in an application that does
{code:java}
if (value.equals(viewMap.put(KEY, value))) { return; }
{code}
which never matches with MyFaces + CDI, so the "only act when the value 
changed" logic ran on every request.

Fix is to unwrap the previous ContextualInstanceInfo in put() the same way 
remove() already does. The behavior goes back to the original implementation 
and is still present in 4.0.4, 4.1.4 and main.



--
This message was sent by Atlassian Jira
(v8.20.10#820010)

Reply via email to