All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.sencha.gxt.state.client.StateManager Maven / Gradle / Ivy

/**
 * Ext GWT 3.0.0-beta2 - Ext for GWT
 * Copyright(c) 2007-2011, Sencha, Inc.
 * [email protected]
 *
 * http://sencha.com/license
 */
package com.sencha.gxt.state.client;

import com.google.gwt.core.client.Callback;
import com.google.gwt.core.client.GWT;
import com.google.gwt.event.shared.SimpleEventBus;
import com.google.web.bindery.autobean.shared.AutoBean;
import com.google.web.bindery.autobean.shared.AutoBeanCodex;
import com.google.web.bindery.autobean.shared.AutoBeanFactory;
import com.google.web.bindery.autobean.shared.AutoBeanUtils;

/**
 * This is the global state manager. In order for this class to be useful, it
 * must be initialized with a provider when your application initializes. By
 * default, GXT initializes the StateManager with a CookieProvider. The provider
 * can be replaced as needed.
 * 
 * The Provider is treated as an asynchronous String persistence mechanism, as
 * to be compatible with RPC, RequestFactory, Cookies, and HTML5 storage. The
 * StateManager then has tools to map these strings to and from bean-like
 * interfaces, using AutoBeans.
 */
public abstract class StateManager {

  private static final StateManager instance = GWT.create(StateManager.class);

  /**
   * Returns the singleton instance.
   * 
   * @return the state manager
   */
  public static StateManager get() {
    return instance;
  }

  private Provider provider;
  private SimpleEventBus eventBus;

  public void clear(String name) {
    provider.clear(name);
  }

  public  void get(String name, final Class stateBeanType, final Callback callback) {
    provider.getValue(name, new Callback() {
      @Override
      public void onFailure(Throwable reason) {
        callback.onFailure(reason);
      }

      @Override
      public void onSuccess(String result) {
        if (result == null || result.length() == 0) {
          callback.onSuccess(getDefaultStateInstance(stateBeanType));
        } else {
          AutoBean autoBean = AutoBeanCodex.decode(getStateBeanFactory(), stateBeanType, result);
          callback.onSuccess(autoBean.as());
        }
      }
    });
  }

  public  S getDefaultStateInstance(Class stateType) {
    AutoBean autoBean = getStateBeanFactory().create(stateType);
    assert autoBean != null : "Type " + stateType + " is not registered as a type that can be used for state";

    return autoBean.as();
  }
  
  /**
   * Returns the manager's state provider.
   * 
   * @return the provider
   */
  public Provider getProvider() {
    return provider;
  }

  public  void set(String name, T stateBean) {
    AutoBean wrappedBean = AutoBeanUtils. getAutoBean(stateBean);
    String value = AutoBeanCodex.encode(wrappedBean).getPayload();

    // TODO consider comparing the value with the default instance, and calling
    // clear instead

    provider.setValue(name, value);
  }
  
  /**
   * Sets the manager's state provider.
   * 
   * @param stateProvider the provider
   */
  public void setProvider(Provider stateProvider) {
    provider = stateProvider;

    // TODO cancel outgoing save/loads? do we expect this to change on the fly?

    provider.bind(this);
  }

  /**
   * Return the state bean factory responsible for creating and
   * decoding the state beans.
   * 
   * @return the state bean factory
   */
  protected abstract AutoBeanFactory getStateBeanFactory();

  SimpleEventBus ensureHandlers() {
    return eventBus == null ? eventBus = new SimpleEventBus() : eventBus;
  }
}