blob: fa23022d81dba4d09b94d9cd18faabb2102e986e [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2011, 2012 Oracle. All rights reserved.
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v1.0, which accompanies this distribution
* and is available at http://www.eclipse.org/legal/epl-v10.html.
*
* Contributors:
* Oracle - initial API and implementation
******************************************************************************/
package org.eclipse.jpt.common.utility.internal.model.value;
import org.eclipse.jpt.common.utility.model.value.ModifiablePropertyValueModel;
/**
* Wrap a writable property value model and cache its value so any changes
* made via the wrapper model will not fire any events to its listeners.
* Thus, a client can modify and listen to the wrapper model and not receive
* a change event when the client modifies the wrapper model; but any changes
* made by other clients (directly to the original model) will fire events
* to the client.
*
* @param <V> the type of the model's value
*/
public class CachingPropertyValueModelWrapper<V>
extends PropertyValueModelWrapper<V>
implements ModifiablePropertyValueModel<V>
{
/**
* Cache the value so we ignore any property change events
* we ourselves trigger.
*/
protected volatile V value;
/**
* Construct a caching writable property value model with the specified
* nested writable property value model.
*/
public CachingPropertyValueModelWrapper(ModifiablePropertyValueModel<V> valueModel) {
super(valueModel);
}
/**
* Return the cached value, since it is up-to-date.
*/
public V getValue() {
return this.value;
}
/**
* Cache the new value so we ignore the resulting property change event.
*/
public void setValue(V value) {
this.value = value;
this.getValueModel().setValue(value);
}
@Override
protected void wrappedValueChanged(V oldValue, V newValue) {
V old = this.value;
// the new event will be suppressed if it is the result of a new value
// forwarded from this wrapper (i.e. 'old' and 'newValue' are equal)
this.firePropertyChanged(VALUE, old, this.value = newValue);
}
/**
* Our constructors accept only a
* {@link ModifiablePropertyValueModel}{@code<V>},
* so this cast should be safe.
*/
@SuppressWarnings("unchecked")
protected ModifiablePropertyValueModel<V> getValueModel() {
return (ModifiablePropertyValueModel<V>) this.valueModel;
}
@Override
public void toString(StringBuilder sb) {
sb.append(this.value);
}
// ********** listeners **********
/**
* We have listeners, cache the nested value.
*/
@Override
protected void engageModel() {
super.engageModel();
this.value = this.valueModel.getValue();
}
/**
* We have no more listeners, clear the cached value.
*/
@Override
protected void disengageModel() {
this.value = null;
super.disengageModel();
}
}