package org.marketcetera.photon.commons.databinding; import java.text.MessageFormat; import org.eclipse.core.databinding.observable.value.DecoratingObservableValue; import org.eclipse.core.databinding.observable.value.IObservableValue; import org.eclipse.core.databinding.observable.value.WritableValue; import org.marketcetera.util.misc.ClassVersion; /* $License$ */ /** * A {@link DecoratingObservableValue} that adds strongly typed semantics to an * existing observable value. * * @author <a href="mailto:will@marketcetera.com">Will Horn</a> * @version $Id: TypedObservableValueDecorator.java 16154 2012-07-14 16:34:05Z colin $ * @since 2.0.0 */ @ClassVersion("$Id: TypedObservableValueDecorator.java 16154 2012-07-14 16:34:05Z colin $") public class TypedObservableValueDecorator<T> extends DecoratingObservableValue implements ITypedObservableValue<T> { /** * Adds strongly typed semantics to an observable. * * @param decorated * the observable value being decorated, must have same type as * clazz * @param disposeDecoratedOnDispose * whether the decorated observable should be disposed when the * decorator is disposed * @param type * type parameter * @return a typed observable value * @throws IllegalArgumentException * if decorated does not have the correct type */ public static <T> ITypedObservableValue<T> decorate( IObservableValue decorated, boolean disposeDecoratedOnDispose, Class<T> type) { return new TypedObservableValueDecorator<T>(decorated, disposeDecoratedOnDispose, type); } /** * Creates a strongly typed observable value. * * @param type * type parameter * @return a typed observable value * @throws IllegalArgumentException * if decorated does not have the correct type */ public static <T> ITypedObservableValue<T> create(Class<T> type) { return new TypedObservableValueDecorator<T>(WritableValue .withValueType(type), true, type); } /** * Constructor. * * @param decorated * the observable value being decorated, must have same type as * the type parameter * @param disposeDecoratedOnDispose * whether the decorated observable should be disposed when the * decorator is disposed * @param type * type parameter * @throws IllegalArgumentException * if decorated does not have the correct type */ protected TypedObservableValueDecorator(IObservableValue decorated, boolean disposeDecoratedOnDispose, Class<T> type) { super(decorated, disposeDecoratedOnDispose); Class<?> decoratedType = (Class<?>) decorated.getValueType(); if (!type.isAssignableFrom(decoratedType)) { throw new IllegalArgumentException(MessageFormat.format( "invalid type {0}, expected {1}", decoratedType, type)); //$NON-NLS-1$ } } /** * Returns the typed value, equivalent to {@link #getValue()}. * * @return the typed value */ @SuppressWarnings("unchecked") @Override public final T getTypedValue() { return (T) getValue(); } }