Package org.geomajas.gwt.client.command

Source Code of org.geomajas.gwt.client.command.GwtCommandDispatcher

/*
* This is part of Geomajas, a GIS framework, http://www.geomajas.org/.
*
* Copyright 2008-2011 Geosparc nv, http://www.geosparc.com/, Belgium.
*
* The program is available in open source according to the GNU Affero
* General Public License. All contributions in this program are covered
* by the Geomajas Contributors License Agreement. For full licensing
* details, see LICENSE.txt in the project root.
*/

package org.geomajas.gwt.client.command;

import org.geomajas.command.CommandResponse;
import org.geomajas.annotation.Api;
import org.geomajas.global.GeomajasConstant;
import org.geomajas.gwt.client.GeomajasService;
import org.geomajas.gwt.client.GeomajasServiceAsync;
import org.geomajas.gwt.client.command.event.DispatchStartedEvent;
import org.geomajas.gwt.client.command.event.DispatchStartedHandler;
import org.geomajas.gwt.client.command.event.DispatchStoppedEvent;
import org.geomajas.gwt.client.command.event.DispatchStoppedHandler;
import org.geomajas.gwt.client.command.event.HasDispatchHandlers;
import org.geomajas.gwt.client.i18n.I18nProvider;
import org.geomajas.gwt.client.widget.ExceptionWindow;

import com.google.gwt.core.client.GWT;
import com.google.gwt.event.shared.HandlerManager;
import com.google.gwt.event.shared.HandlerRegistration;
import com.google.gwt.i18n.client.LocaleInfo;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.rpc.ServiceDefTarget;
import com.smartgwt.client.core.Function;
import com.smartgwt.client.util.SC;

/**
* The central client side dispatcher for all commands. Use the {@link #execute(GwtCommand, CommandCallback...)}
* function to execute an asynchronous command on the server.
*
* @author Pieter De Graef
* @author Oliver May
* @since 1.6.0
*/
@Api(allMethods = true)
public final class GwtCommandDispatcher implements HasDispatchHandlers {

  private static GwtCommandDispatcher INSTANCE;

  private GeomajasServiceAsync service;

  private HandlerManager manager = new HandlerManager(this);

  private int nrOfDispatchedCommands;

  private String locale;

  private String userToken;

  private boolean useLazyLoading;

  private int lazyFeatureIncludesDefault;

  private int lazyFeatureIncludesSelect;

  private int lazyFeatureIncludesAll;
 
  private boolean showError;

  private GwtCommandDispatcher() {
    locale = LocaleInfo.getCurrentLocale().getLocaleName();
    if ("default".equals(locale)) {
      locale = null;
    }
    service = (GeomajasServiceAsync) GWT.create(GeomajasService.class);
    ServiceDefTarget endpoint = (ServiceDefTarget) service;
    String moduleRelativeURL = GWT.getModuleBaseURL() + "geomajasService";
    endpoint.setServiceEntryPoint(moduleRelativeURL);
    setUseLazyLoading(true);
    setShowError(true);
  }

  // -------------------------------------------------------------------------
  // Public methods:
  // -------------------------------------------------------------------------

  /**
   * Get the only static instance of this class. This should be the object you work with.
   *
   * @return singleton instance
   */
  public static GwtCommandDispatcher getInstance() {
    if (INSTANCE == null) {
      INSTANCE = new GwtCommandDispatcher();
    }
    return INSTANCE;
  }

  public HandlerRegistration addDispatchStartedHandler(DispatchStartedHandler handler) {
    return manager.addHandler(DispatchStartedEvent.getType(), handler);
  }

  public HandlerRegistration addDispatchStoppedHandler(DispatchStoppedHandler handler) {
    return manager.addHandler(DispatchStoppedEvent.getType(), handler);
  }

  /**
   * The execution function. Executes a server side command.
   *
   * @param command
   *            The command to be executed. This command is a wrapper around the actual request object.
   * @param callback
   *            A <code>CommandCallback</code> function to be executed when the command successfully returns. The
   *            callbacks may implement CommunicationExceptionCallback or CommandExceptionCallback to allow error
   *            handling.
   * @return deferred object which can be used to add extra callbacks
   */
  public Deferred execute(GwtCommand command, final CommandCallback... callback) {
    incrementDispatched();

    final Deferred deferred = new Deferred();
    for (CommandCallback successCallback : callback) {
      deferred.addCallback(successCallback);
    }

    command.setLocale(locale);
    command.setUserToken(userToken);
    service.execute(command, new AsyncCallback<CommandResponse>() {

      public void onFailure(Throwable error) {
        try {
          for (Function callback : deferred.getErrorCallbacks()) {
            callback.execute();
          }
          boolean errorHandled = false;
          for (CommandCallback callback : deferred.getCallbacks()) {
            if (callback instanceof CommunicationExceptionCallback) {
              ((CommunicationExceptionCallback) callback).onCommunicationException(error);
              errorHandled = true;
            }
          }
          if (!errorHandled) {
            onCommunicationException(error);
          }
        } catch (Throwable t) {
          GWT.log("Command failed on error callback", t);
        } finally {
          decrementDispatched();
        }
      }

      public void onSuccess(CommandResponse response) {
        try {
          if (response.isError()) {
            boolean errorHandled = false;
            for (CommandCallback callback : deferred.getCallbacks()) {
              if (callback instanceof CommandExceptionCallback) {
                ((CommandExceptionCallback) callback).onCommandException(response);
                errorHandled = true;
              }
            }
            // fallback to the default behaviour
            if (!errorHandled) {
              onCommandException(response);
            }
          } else {
            if (!deferred.isCancelled()) {
              for (CommandCallback callback : deferred.getCallbacks()) {
                callback.execute(response);
              }
            }
          }
        } catch (Throwable t) {
          GWT.log("Command failed on success callback", t);
        } finally {
          decrementDispatched();
        }
      }
    });
    return deferred;
  }

  /**
   * Default behaviour for handling a communication exception. Shows a warning window to the user.
   *
   * @since 1.9.0
   * @param error error to report
   */
  public void onCommunicationException(Throwable error) {
    if (isShowError()) {
      GWT.log(I18nProvider.getGlobal().commandError() + ":\n" + error.getMessage(), null);
      SC.warn(I18nProvider.getGlobal().commandError() + ":\n" + error.getMessage(), null);
    }
  }

  /**
   * Default behaviour for handling a command execution exception. Shows an exception report to the user.
   *
   * @since 1.9.0
   * @param response command response with error
   */
  public void onCommandException(CommandResponse response) {
    if (isShowError()) {
      String message = I18nProvider.getGlobal().commandError() + ":";
      for (String error : response.getErrorMessages()) {
        message += "\n" + error;
      }
      GWT.log(message, null);
      if (response.getExceptions() == null || response.getExceptions().size() == 0) {
        SC.warn(message, null);
      } else {
        // The error messaging window only supports 1 exception to display:
        ExceptionWindow window = new ExceptionWindow(response.getExceptions().get(0));
        window.show();
      }
    }
  }

  /**
   * Is the dispatcher busy ?
   *
   * @return true if there are outstanding commands
   */
  public boolean isBusy() {
    return nrOfDispatchedCommands != 0;
  }

  /**
   * Set the user token, so it can be sent in very command.
   *
   * @param userToken
   *            user token
   */
  public void setUserToken(String userToken) {
    this.userToken = userToken;
  }

  /**
   * Is lazy feature loading enabled ?
   *
   * @return true when lazy feature loading is enabled
   */
  public boolean isUseLazyLoading() {
    return useLazyLoading;
  }

  /**
   * Set lazy feature loading status.
   *
   * @param useLazyLoading
   *            lazy feature loading status
   */
  public void setUseLazyLoading(boolean useLazyLoading) {
    if (useLazyLoading != this.useLazyLoading) {
      if (useLazyLoading) {
        lazyFeatureIncludesDefault = GeomajasConstant.FEATURE_INCLUDE_STYLE
            + GeomajasConstant.FEATURE_INCLUDE_LABEL;
        lazyFeatureIncludesSelect = GeomajasConstant.FEATURE_INCLUDE_ALL;
        lazyFeatureIncludesAll = GeomajasConstant.FEATURE_INCLUDE_ALL;
      } else {
        lazyFeatureIncludesDefault = GeomajasConstant.FEATURE_INCLUDE_ALL;
        lazyFeatureIncludesSelect = GeomajasConstant.FEATURE_INCLUDE_ALL;
        lazyFeatureIncludesAll = GeomajasConstant.FEATURE_INCLUDE_ALL;
      }
    }
    this.useLazyLoading = useLazyLoading;
  }

  /**
   * Get default value for "featureIncludes" when getting features.
   *
   * @return default "featureIncludes" value
   */
  public int getLazyFeatureIncludesDefault() {
    return lazyFeatureIncludesDefault;
  }

  /**
   * Set default value for "featureIncludes" when getting features.
   *
   * @param lazyFeatureIncludesDefault
   *            default for "featureIncludes"
   */
  public void setLazyFeatureIncludesDefault(int lazyFeatureIncludesDefault) {
    setUseLazyLoading(false);
    this.lazyFeatureIncludesDefault = lazyFeatureIncludesDefault;
  }

  /**
   * Get "featureIncludes" to use when selecting features.
   *
   * @return default "featureIncludes" for select commands
   */
  public int getLazyFeatureIncludesSelect() {
    return lazyFeatureIncludesSelect;
  }

  /**
   * Set default "featureIncludes" for select commands.
   *
   * @param lazyFeatureIncludesSelect
   *            default "featureIncludes" for select commands
   */
  public void setLazyFeatureIncludesSelect(int lazyFeatureIncludesSelect) {
    setUseLazyLoading(false);
    this.lazyFeatureIncludesSelect = lazyFeatureIncludesSelect;
  }

  /**
   * Value to use for "featureIncludes" when all should be included.
   *
   * @return value for "featureIncludes" when all should be included
   */
  public int getLazyFeatureIncludesAll() {
    return lazyFeatureIncludesAll;
  }

  /**
   * Set "featureIncludes" value when all should be included.
   *
   * @param lazyFeatureIncludesAll
   *            "featureIncludes" value when all should be included
   */
  public void setLazyFeatureIncludesAll(int lazyFeatureIncludesAll) {
    setUseLazyLoading(false);
    this.lazyFeatureIncludesAll = lazyFeatureIncludesAll;
  }
 
  /**
   * Should the dispatcher show error messages ?
   *
   * @return true if showing error messages, false otherwise
   * @since 1.9.0
   */
  public boolean isShowError() {
    return showError;
  }

  /**
   * Sets whether the dispatcher should show error messages.
   *
   * @param showError true if showing error messages, false otherwise
   * @since 1.9.0
   */
  public void setShowError(boolean showError) {
    this.showError = showError;
  }

  // -------------------------------------------------------------------------
  // Protected methods:
  // -------------------------------------------------------------------------

 
  protected void incrementDispatched() {
    boolean started = nrOfDispatchedCommands == 0;
    nrOfDispatchedCommands++;
    if (started) {
      manager.fireEvent(new DispatchStartedEvent());
    }
  }

  protected void decrementDispatched() {
    nrOfDispatchedCommands--;
    if (nrOfDispatchedCommands == 0) {
      manager.fireEvent(new DispatchStoppedEvent());
    }
  }

}
TOP

Related Classes of org.geomajas.gwt.client.command.GwtCommandDispatcher

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.