Skip to main content


Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Eclipse Projects » JFace » Databinding to mutable property stops in SimplePropertyObserverValue
Databinding to mutable property stops in SimplePropertyObserverValue [message #1753185] Thu, 02 February 2017 14:25
Felix Hirsch is currently offline Felix HirschFriend
Messages: 9
Registered: May 2016
Location: Aachen, Germany
Junior Member
Hi,

I'm using databinding and I found a problem in my application regarding the class org.eclipse.core.internal.databinding.property.value.SimplePropertyObserverValue.

The object I want to observe consists of many attributes and is part of a container object. I am observing changes to the inner object as property of the container.
In our implementation calling the setter method for the inner object mutates the inner object instead of replacing the object reference in the container.

This is not the usual approach and I can think of a better design but sometimes there can be a reason to act this way.
So perhaps the following problem can affect others too.

Here is an example which describes my problem:

public class MyContainer {

    // implements property change support
    private PropertyChangeSupport changeSupport = ...;

    // this is the observable object
    private MyData data;

    public void addPropertyChangeListener(PropertyChangeListener l) {...}
    public void removePropertyChangeListener(PropertyChangeListener l) {...}
    public void firePropertyChange(String propertyName, Object oldValue, Object newValue) {...}

    public MyData getData() {...}

    public MyData setData(MyData newValue) {
            // create oldValue from member
            MyData oldValue = data.clone();
 
            // Mutate member instead of replacing the reference
            data.setAttributes(newValue);

            // fire change and provide correct old and new value
            firePropertyChange("data", oldValue, data);
    }
}


We call "container.setData" with an non equal new object and we have an observer created via "BeanProperties" and connected via "DataBindingContext" to the "container" object. The non equal old and new values are passed to "firePropertyChange".

When I debug the observation at one point I will end in the method SimplePropertyObservableValue.notifyIfChanged(ValueDiff<? extends T>) .
Here I can see a valid provided (non null) parameter "diff" of type "ValueDiff", which consist of exactly the objects which I provided to "firePropertyChange".

This method itself checks (again), if the objects differ from each other but uses a cached object reference for "oldValue" which refers to the same object (object identity) as the "data" member of my container and is therefore the same object as the "newValue" in the "diff" parameter. So here in this method the local variables "oldValue" and "newValue" will be references to the same object.

The objects provided by"diff.getOldValue()" and "diff.getNewValue()" are not considered for evaluation here and the observation stops as the result of "Util.equals(oldValue, newValue)" is true due to object identity.

If this method calls fireValueChanged and "diff" is NOT NULL it will be passed unmodified to all following observers. So for further evaluation the cached value is never considered anyway.

private void notifyIfChanged(ValueDiff<? extends T> diff) {
        if (hasListeners()) {
            // here diff.getOldValue() is not considered
            T oldValue = cachedValue;

            // here diff.getNewValue() is not considered
            T newValue = cachedValue = property.getValue(source);
    
            if (diff == null)
                    diff = Diffs.createValueDiff(oldValue, newValue);
            if (!Util.equals(oldValue, newValue) || stale) {
                    stale = false;
                    // here diff is transmitted untouched in case it is not null
                    fireValueChange(Diffs.unmodifiableDiff(diff));
            }
        }
}


Is it correct that "diff.getOldValue()" and "diff.getNewValue()" are not considered in this method? Wouln't it be better to check, if an old value is provided by a non null "diff" parameter, and only if it is not provided, to use the cached value?

Thanks for your help
Previous Topic:TextEditor substring Content proposals`?
Next Topic:Why is ObservableListTreeContentProvider not meant to be subclassed?
Goto Forum:
  


Current Time: Fri Sep 21 09:44:30 GMT 2018

Powered by FUDForum. Page generated in 0.02554 seconds
.:: Contact :: Home ::.

Powered by: FUDforum 3.0.2.
Copyright ©2001-2010 FUDforum Bulletin Board Software

Back to the top