Hi,
Mario Ivankovits napsal(a):
... with "serialize in state" disabled.
I've create a small test case which shows that the attributes map is
just copied over into the state. Which means that each and every
Component shares exactly the same map. Any change to this map will be
reflected in ALL saved states.
It's because the "wrong" constructor in api's _ComponentAttributesMap
class, it's assigning the map directly:
1.1 trunk:
_ComponentAttributesMap(UIComponent component, Map attributes)
{
_component = component;
_attributes = attributes;
}
should be
_ComponentAttributesMap(UIComponent component, Map attributes)
{
_component = component;
_attributes = new HashMap();
_attributes.putAll(attributes);
}
the same in 1.2 trunk:
_ComponentAttributesMap(UIComponent component, Map<Object, Object> attributes)
{
_component = component;
_attributes = attributes;
}
should be:
_ComponentAttributesMap(UIComponent component, Map<Object, Object> attributes)
{
_component = component;
_attributes = new HashMap<Object, Object>();
_attributes.putAll(attributes);
}
Regards,
Zdenek
Correct would be to clone the map, but this must not work, at least a
shallow copy of the map should be saved (when "serialize in
state=false") to avoid this problem.
What do you think?
public void testSaveInSessionWithoutSerialize() throws Exception
{
// create a fake viewRoot
UIViewRoot root = new UIViewRoot();
root.getAttributes().put("key", "value");
// simulate server-side-state-saving without serialization
Object state = root.saveState(facesContext);
// restore view
UIViewRoot root1 = new UIViewRoot();
root1.restoreState(facesContext, state);
// restore view .. next request
UIViewRoot root2 = new UIViewRoot();
root2.restoreState(facesContext, state);
// chaange attribute in root1
root1.getAttributes().put("key", "borken");
// and see it changed in root2 too
assertEquals("value", root2.getAttributes().get("key"));
// and see it changed everywhere
assertEquals("value", root.getAttributes().get("key"));
}
Ciao,
Mario