Package org.eclipse.core.databinding.observable

Source Code of org.eclipse.core.databinding.observable.Observables

/*******************************************************************************
* Copyright (c) 2006, 2009 Cerner Corporation and others.
* 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:
*     Brad Reynolds - initial API and implementation
*     Matt Carter - bug 212518 (constantObservableValue)
*     Matthew Hall - bugs 208332, 212518, 219909, 184830, 237718, 245647,
*         226289
*     Marko Topolnik - bug 184830
******************************************************************************/

package org.eclipse.core.databinding.observable;

import java.util.List;
import java.util.Set;

import org.eclipse.core.databinding.observable.list.DecoratingObservableList;
import org.eclipse.core.databinding.observable.list.IListChangeListener;
import org.eclipse.core.databinding.observable.list.IObservableList;
import org.eclipse.core.databinding.observable.list.ObservableList;
import org.eclipse.core.databinding.observable.map.DecoratingObservableMap;
import org.eclipse.core.databinding.observable.map.IObservableMap;
import org.eclipse.core.databinding.observable.masterdetail.IObservableFactory;
import org.eclipse.core.databinding.observable.masterdetail.MasterDetailObservables;
import org.eclipse.core.databinding.observable.set.DecoratingObservableSet;
import org.eclipse.core.databinding.observable.set.IObservableSet;
import org.eclipse.core.databinding.observable.set.ISetChangeListener;
import org.eclipse.core.databinding.observable.set.ObservableSet;
import org.eclipse.core.databinding.observable.value.DecoratingObservableValue;
import org.eclipse.core.databinding.observable.value.IObservableValue;
import org.eclipse.core.databinding.observable.value.IValueChangeListener;
import org.eclipse.core.databinding.observable.value.IVetoableValue;
import org.eclipse.core.databinding.observable.value.ValueChangeEvent;
import org.eclipse.core.databinding.observable.value.ValueChangingEvent;
import org.eclipse.core.internal.databinding.observable.ConstantObservableValue;
import org.eclipse.core.internal.databinding.observable.DelayedObservableValue;
import org.eclipse.core.internal.databinding.observable.EmptyObservableList;
import org.eclipse.core.internal.databinding.observable.EmptyObservableSet;
import org.eclipse.core.internal.databinding.observable.MapEntryObservableValue;
import org.eclipse.core.internal.databinding.observable.StalenessObservableValue;
import org.eclipse.core.internal.databinding.observable.UnmodifiableObservableList;
import org.eclipse.core.internal.databinding.observable.UnmodifiableObservableMap;
import org.eclipse.core.internal.databinding.observable.UnmodifiableObservableSet;
import org.eclipse.core.internal.databinding.observable.UnmodifiableObservableValue;
import org.eclipse.core.runtime.Assert;

/**
* Contains static methods to operate on or return {@link IObservable
* Observables}.
*
* @since 1.0
*/
public class Observables {
  /**
   * Returns an observable which delays notification of value change events
   * from <code>observable</code> until <code>delay</code> milliseconds have
   * elapsed since the last change event. This observable helps to boost
   * performance in situations where an observable has computationally
   * expensive listeners or many dependencies. A common use of this observable
   * is to delay validation of user input until the user stops typing in a UI
   * field.
   * <p>
   * To notify about pending changes, the returned observable fires a stale
   * event when the wrapped observable value fires a change event, and remains
   * stale until the delay has elapsed and the value change is fired. A call
   * to {@link IObservableValue#getValue() getValue()} while a value change is
   * pending will fire the value change immediately, short-circuiting the
   * delay.
   * <p>
   * <b>Note:</b>
   * <ul>
   * <li>Use SWTObservables.observeDelayedValue() instead when the target
   * observable is observing a SWT Control, or
   * ViewersObservables.observeDelayedValue() when the target observable is
   * observing a JFace Viewer. These observables ensure that pending value
   * changes are fired when the underlying control loses focus. (Otherwise, it
   * is possible for pending changes to be lost if a window is closed before
   * the delay has elapsed.)
   * <li>This observable does not forward {@link ValueChangingEvent} events
   * from a wrapped {@link IVetoableValue}.
   * </ul>
   *
   * @param delay
   *            the delay in milliseconds
   * @param observable
   *            the observable being delayed
   * @return an observable which delays notification of value change events
   *         from <code>observable</code> until <code>delay</code>
   *         milliseconds have elapsed since the last change event.
   *
   * @since 1.2
   */
  public static IObservableValue observeDelayedValue(int delay,
      IObservableValue observable) {
    return new DelayedObservableValue(delay, observable);
  }

  /**
   * Returns an unmodifiable observable value backed by the given observable
   * value.
   *
   * @param value
   *            the value to wrap in an unmodifiable value
   * @return an unmodifiable observable value backed by the given observable
   *         value
   * @since 1.1
   */
  public static IObservableValue unmodifiableObservableValue(
      IObservableValue value) {
    Assert.isNotNull(value, "Argument 'value' cannot be null"); //$NON-NLS-1$
    return new UnmodifiableObservableValue(value);
  }

  /**
   * Returns an observable value with the given constant value.
   *
   * @param realm
   *            the observable's realm
   * @param value
   *            the observable's constant value
   * @param valueType
   *            the observable's value type
   * @return an immutable observable value with the given constant value
   * @since 1.1
   */
  public static IObservableValue constantObservableValue(Realm realm,
      Object value, Object valueType) {
    return new ConstantObservableValue(realm, value, valueType);
  }

  /**
   * Returns an observable value with the given constant value.
   *
   * @param realm
   *            the observable's realm
   * @param value
   *            the observable's constant value
   * @return an immutable observable value with the given constant value
   * @since 1.1
   */
  public static IObservableValue constantObservableValue(Realm realm,
      Object value) {
    return constantObservableValue(realm, value, null);
  }

  /**
   * Returns an observable value with the given constant value.
   *
   * @param value
   *            the observable's constant value
   * @param valueType
   *            the observable's value type
   * @return an immutable observable value with the given constant value
   * @since 1.1
   */
  public static IObservableValue constantObservableValue(Object value,
      Object valueType) {
    return constantObservableValue(Realm.getDefault(), value, valueType);
  }

  /**
   * Returns an observable value with the given constant value.
   *
   * @param value
   *            the observable's constant value
   * @return an immutable observable value with the given constant value
   * @since 1.1
   */
  public static IObservableValue constantObservableValue(Object value) {
    return constantObservableValue(Realm.getDefault(), value, null);
  }

  /**
   * Returns an unmodifiable observable list backed by the given observable
   * list.
   *
   * @param list
   *            the list to wrap in an unmodifiable list
   * @return an unmodifiable observable list backed by the given observable
   *         list
   */
  public static IObservableList unmodifiableObservableList(
      IObservableList list) {
    if (list == null) {
      throw new IllegalArgumentException("List parameter cannot be null."); //$NON-NLS-1$
    }

    return new UnmodifiableObservableList(list);
  }

  /**
   * Returns an unmodifiable observable set backed by the given observable
   * set.
   *
   * @param set
   *            the set to wrap in an unmodifiable set
   * @return an unmodifiable observable set backed by the given observable set
   * @since 1.1
   */
  public static IObservableSet unmodifiableObservableSet(IObservableSet set) {
    if (set == null) {
      throw new IllegalArgumentException("Set parameter cannot be null"); //$NON-NLS-1$
    }

    return new UnmodifiableObservableSet(set);
  }

  /**
   * Returns an unmodifiable observable map backed by the given observable
   * map.
   *
   * @param map
   *            the map to wrap in an unmodifiable map
   * @return an unmodifiable observable map backed by the given observable
   *         map.
   * @since 1.2
   */
  public static IObservableMap unmodifiableObservableMap(IObservableMap map) {
    if (map == null) {
      throw new IllegalArgumentException("Map parameter cannot be null"); //$NON-NLS-1$
    }

    return new UnmodifiableObservableMap(map);
  }

  /**
   * Returns an empty observable list. The returned list continues to work
   * after it has been disposed of and can be disposed of multiple times.
   *
   * @return an empty observable list.
   */
  public static IObservableList emptyObservableList() {
    return emptyObservableList(Realm.getDefault(), null);
  }

  /**
   * Returns an empty observable list of the given element type. The returned
   * list continues to work after it has been disposed of and can be disposed
   * of multiple times.
   *
   * @param elementType
   *            the element type of the returned list
   * @return an empty observable list
   * @since 1.1
   */
  public static IObservableList emptyObservableList(Object elementType) {
    return emptyObservableList(Realm.getDefault(), elementType);
  }

  /**
   * Returns an empty observable list belonging to the given realm. The
   * returned list continues to work after it has been disposed of and can be
   * disposed of multiple times.
   *
   * @param realm
   *            the realm of the returned list
   * @return an empty observable list.
   */
  public static IObservableList emptyObservableList(Realm realm) {
    return emptyObservableList(realm, null);
  }

  /**
   * Returns an empty observable list of the given element type and belonging
   * to the given realm. The returned list continues to work after it has been
   * disposed of and can be disposed of multiple times.
   *
   * @param realm
   *            the realm of the returned list
   * @param elementType
   *            the element type of the returned list
   * @return an empty observable list
   * @since 1.1
   */
  public static IObservableList emptyObservableList(Realm realm,
      Object elementType) {
    return new EmptyObservableList(realm, elementType);
  }

  /**
   * Returns an empty observable set. The returned set continues to work after
   * it has been disposed of and can be disposed of multiple times.
   *
   * @return an empty observable set.
   */
  public static IObservableSet emptyObservableSet() {
    return emptyObservableSet(Realm.getDefault(), null);
  }

  /**
   * Returns an empty observable set of the given element type. The returned
   * set continues to work after it has been disposed of and can be disposed
   * of multiple times.
   *
   * @param elementType
   *            the element type of the returned set
   * @return an empty observable set
   * @since 1.1
   */
  public static IObservableSet emptyObservableSet(Object elementType) {
    return emptyObservableSet(Realm.getDefault(), elementType);
  }

  /**
   * Returns an empty observable set belonging to the given realm. The
   * returned set continues to work after it has been disposed of and can be
   * disposed of multiple times.
   *
   * @param realm
   *            the realm of the returned set
   * @return an empty observable set.
   */
  public static IObservableSet emptyObservableSet(Realm realm) {
    return emptyObservableSet(realm, null);
  }

  /**
   * Returns an empty observable set of the given element type and belonging
   * to the given realm. The returned set continues to work after it has been
   * disposed of and can be disposed of multiple times.
   *
   * @param realm
   *            the realm of the returned set
   * @param elementType
   *            the element type of the returned set
   * @return an empty observable set
   * @since 1.1
   */
  public static IObservableSet emptyObservableSet(Realm realm,
      Object elementType) {
    return new EmptyObservableSet(realm, elementType);
  }

  /**
   * Returns an observable set backed by the given set.
   *
   * @param set
   *            the set to wrap in an IObservableSet
   * @return an observable set backed by the given set
   */
  public static IObservableSet staticObservableSet(Set set) {
    return staticObservableSet(Realm.getDefault(), set, Object.class);
  }

  /**
   * Returns an observable set of the given element type, backed by the given
   * set.
   *
   * @param set
   *            the set to wrap in an IObservableSet
   * @param elementType
   *            the element type of the returned set
   * @return Returns an observable set backed by the given unchanging set
   * @since 1.1
   */
  public static IObservableSet staticObservableSet(Set set, Object elementType) {
    return staticObservableSet(Realm.getDefault(), set, elementType);
  }

  /**
   * Returns an observable set belonging to the given realm, backed by the
   * given set.
   *
   * @param realm
   *            the realm of the returned set
   * @param set
   *            the set to wrap in an IObservableSet
   * @return an observable set backed by the given unchanging set
   */
  public static IObservableSet staticObservableSet(Realm realm, Set set) {
    return staticObservableSet(realm, set, Object.class);
  }

  /**
   * Returns an observable set of the given element type and belonging to the
   * given realm, backed by the given set.
   *
   * @param realm
   *            the realm of the returned set
   * @param set
   *            the set to wrap in an IObservableSet
   * @param elementType
   *            the element type of the returned set
   * @return an observable set backed by the given set
   * @since 1.1
   */
  public static IObservableSet staticObservableSet(Realm realm, Set set,
      Object elementType) {
    return new ObservableSet(realm, set, elementType) {
      public synchronized void addChangeListener(IChangeListener listener) {
      }

      public synchronized void addStaleListener(IStaleListener listener) {
      }

      public synchronized void addSetChangeListener(
          ISetChangeListener listener) {
      }
    };
  }

  /**
   * Returns an observable value that contains the same value as the given
   * observable, and fires the same events as the given observable, but can be
   * disposed of without disposing of the wrapped observable.
   *
   * @param target
   *            the observable value to wrap
   * @return a disposable proxy for the given observable value.
   * @since 1.2
   */
  public static IObservableValue proxyObservableValue(IObservableValue target) {
    return new DecoratingObservableValue(target, false);
  }

  /**
   * Returns an observable set that contains the same elements as the given
   * set, and fires the same events as the given set, but can be disposed of
   * without disposing of the wrapped set.
   *
   * @param target
   *            the set to wrap
   * @return a disposable proxy for the given observable set
   */
  public static IObservableSet proxyObservableSet(IObservableSet target) {
    return new DecoratingObservableSet(target, false);
  }

  /**
   * Returns an observable list that contains the same elements as the given
   * list, and fires the same events as the given list, but can be disposed of
   * without disposing of the wrapped list.
   *
   * @param target
   *            the list to wrap
   * @return a disposable proxy for the given observable list
   * @since 1.1
   */
  public static IObservableList proxyObservableList(IObservableList target) {
    return new DecoratingObservableList(target, false);
  }

  /**
   * Returns an observable map that contains the same entries as the given
   * map, and fires the same events as the given map, but can be disposed of
   * without disposing of the wrapped map.
   *
   * @param target
   *            the map to wrap
   * @return a disposable proxy for the given observable map
   * @since 1.2
   */
  public static IObservableMap proxyObservableMap(IObservableMap target) {
    return new DecoratingObservableMap(target, false);
  }

  /**
   * Returns an observable list backed by the given list.
   *
   * @param list
   *            the list to wrap in an IObservableList
   * @return an observable list backed by the given unchanging list
   */
  public static IObservableList staticObservableList(List list) {
    return staticObservableList(Realm.getDefault(), list, Object.class);
  }

  /**
   * Returns an observable list of the given element type, backed by the given
   * list.
   *
   * @param list
   *            the list to wrap in an IObservableList
   * @param elementType
   *            the element type of the returned list
   * @return an observable list backed by the given unchanging list
   * @since 1.1
   */
  public static IObservableList staticObservableList(List list,
      Object elementType) {
    return staticObservableList(Realm.getDefault(), list, elementType);
  }

  /**
   * Returns an observable list belonging to the given realm, backed by the
   * given list.
   *
   * @param realm
   *            the realm of the returned list
   * @param list
   *            the list to wrap in an IObservableList
   * @return an observable list backed by the given unchanging list
   */
  public static IObservableList staticObservableList(Realm realm, List list) {
    return staticObservableList(realm, list, Object.class);
  }

  /**
   * Returns an observable list of the given element type and belonging to the
   * given realm, backed by the given list.
   *
   * @param realm
   *            the realm of the returned list
   * @param list
   *            the list to wrap in an IObservableList
   * @param elementType
   *            the element type of the returned list
   * @return an observable list backed by the given unchanging list
   * @since 1.1
   */
  public static IObservableList staticObservableList(Realm realm, List list,
      Object elementType) {
    return new ObservableList(realm, list, elementType) {
      public synchronized void addChangeListener(IChangeListener listener) {
      }

      public synchronized void addStaleListener(IStaleListener listener) {
      }

      public synchronized void addListChangeListener(
          IListChangeListener listener) {
      }
    };
  }

  /**
   * Returns an observable value of type <code>Boolean.TYPE</code> which
   * tracks whether the given observable is stale.
   *
   * @param observable
   *            the observable to track
   * @return an observable value which tracks whether the given observable is
   *         stale
   *
   * @since 1.1
   */
  public static IObservableValue observeStale(IObservable observable) {
    return new StalenessObservableValue(observable);
  }

  /**
   * Returns an observable value that tracks changes to the value of an
   * observable map's entry specified by its key.
   * <p>
   * The state where the key does not exist in the map is equivalent to the
   * state where the key exists and its value is <code>null</code>. The
   * transition between these two states is not considered a value change and
   * no event is fired.
   *
   * @param map
   *            the observable map whose entry will be tracked.
   * @param key
   *            the key identifying the map entry to track.
   * @return an observable value that tracks the value associated with the
   *         specified key in the given map
   * @since 1.2
   */
  public static IObservableValue observeMapEntry(IObservableMap map,
      Object key) {
    return observeMapEntry(map, key, map.getValueType());
  }

  /**
   * Returns an observable value that tracks changes to the value of an
   * observable map's entry specified by its key.
   * <p>
   * The state where the key does not exist in the map is equivalent to the
   * state where the key exists and its value is <code>null</code>. The
   * transition between these two states is not considered a value change and
   * no event is fired.
   *
   * @param map
   *            the observable map whose entry will be tracked.
   * @param key
   *            the key identifying the map entry to track.
   * @param valueType
   *            the type of the value. May be <code>null</code>, meaning the
   *            value is untyped.
   * @return an observable value that tracks the value associated with the
   *         specified key in the given map
   * @since 1.1
   */
  public static IObservableValue observeMapEntry(IObservableMap map,
      Object key, Object valueType) {
    if (valueType == null)
      valueType = map.getValueType();
    return new MapEntryObservableValue(map, key, valueType);
  }

  /**
   * Returns a factory for creating obervable values tracking the value of the
   * {@link IObservableMap observable map} entry identified by a particular
   * key.
   *
   * @param map
   *            the observable map whose entry will be tracked.
   * @param valueType
   *            the type of the value. May be <code>null</code>, meaning the
   *            value is untyped.
   * @return a factory for creating observable values tracking the value of
   *         the observable map entry identified by a particular key object.
   * @since 1.1
   */
  public static IObservableFactory mapEntryValueFactory(
      final IObservableMap map, final Object valueType) {
    return new IObservableFactory() {
      public IObservable createObservable(Object key) {
        return observeMapEntry(map, key, valueType);
      }
    };
  }

  /**
   * Helper method for <code>MasterDetailObservables.detailValue(master,
   * mapEntryValueFactory(map, valueType), valueType)</code>.
   *
   * @param map
   *            the observable map whose entry will be tracked.
   * @param master
   *            the observable value that identifies which map entry to track.
   * @param valueType
   *            the type of the value. May be <code>null</code>, meaning the
   *            value is untyped.
   * @return an observable value tracking the current value of the specified
   *         key in the given map an observable value that tracks the current
   *         value of the named property for the current value of the master
   *         observable value
   * @since 1.1
   */
  public static IObservableValue observeDetailMapEntry(IObservableMap map,
      IObservableValue master, Object valueType) {
    return MasterDetailObservables.detailValue(master,
        mapEntryValueFactory(map, valueType), valueType);
  }

  /**
   * Copies the current value of the source observable to the destination
   * observable, and upon value change events fired by the source observable,
   * updates the destination observable accordingly, until the source
   * observable is disposed. This method assumes that both observables are on
   * the same realm.
   *
   * @param source
   *            the source observable
   * @param destination
   *            the destination observable
   * @since 1.2
   */
  public static void pipe(IObservableValue source,
      final IObservableValue destination) {
    destination.setValue(source.getValue());
    source.addValueChangeListener(new IValueChangeListener() {
      public void handleValueChange(ValueChangeEvent event) {
        destination.setValue(event.diff.getNewValue());
      }
    });
  }
}
TOP

Related Classes of org.eclipse.core.databinding.observable.Observables

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.