Sochor Zdeněk schrieb:
> 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);
> }
But as Mario says..
>
>> 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.
Your solution fixes one more level, but not every possibility. It's
certainly better, but not complete.
If the attributes map has a mutable object in it (eg a StringBuffer, or
something more complex) then the problem remains; a change to the object
state via one UIViewRoot will cause it to change in the other.
Using java.io.serialize stuff forces a real "deep" clone which solves
this issue. But it does then require that every object put into a
component's attributes is serializable.
Regards,
Simon