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

com.dragome.forms.bindings.client.command.AbstractAsyncUiCommand Maven / Gradle / Ivy

The newest version!
package com.dragome.forms.bindings.client.command;

import com.dragome.forms.bindings.client.channel.Channel;
import com.dragome.forms.bindings.extra.user.client.Command;

/**
 * Base class for commands wishing to invoke an asynchronous operation.
 */
public abstract class AbstractAsyncUiCommand extends AbstractTemporalUiCommand implements AsyncUiCommand
{

	private AsyncEventSupport eventSupport= new AsyncEventSupport();

	public AsyncEvents always()
	{
		return eventSupport.always();
	}

	/**
	 * Gets a instance of {@link com.pietschy.gwt.pectin.client.command.AsyncEvents} that will only fire
	 * on the next execution.
	 *
	 * @return the events for the next execution.
	 */
	public AsyncEvents onNextCall()
	{
		return eventSupport.onNextCall();
	}

	/**
	 * Gets the result channel for this command, using this is equivalent using the {@link #always()}
	 * command events.
	 *
	 * @return this command result channel.
	 */
	public Channel getResults()
	{
		return eventSupport.getResultChannel();
	}

	/**
	 * Gets the error channel for this command, using this is equivalent using the {@link #always()}
	 * command events.
	 *
	 * @return this command error channel.
	 */
	public Channel getErrors()
	{
		return eventSupport.getErrorChannel();
	}

	/**
	 * Method for subclasses to perform work after the callback has succeeded.  This
	 * method is called before the result is published.
	 *
	 * @param result the result of the command
	 */
	protected void afterSuccess(R result)
	{
	}

	/**
	 * Method for subclasses to perform work after an error has been generated.  This
	 * method is called before the error is published.
	 *
	 * @param error the error
	 */
	protected void afterError(E error)
	{
	}

	/**
	 * Method for subclasses to perform work after an execution has been aborted..
	 */
	protected void afterAbort()
	{
	}

	@Override
	protected void startExecution(Context context)
	{
		// Create our execution context.
		runWithInterceptors(new ExecutionContext(context, eventSupport.prepareEvents()));
	}

	/**
	 * Returns an async callback that will publish the result to the specified callback and will use
	 * the specified ExceptionManager to process any exceptions.
	 *
	 * @param callback         the callback to use to publish the result and errors.
	 * @param exceptionManager the {@link com.pietschy.gwt.pectin.client.command.ExceptionManager} to use
	 *                         for processing exceptions.
	 * @return a regular AsyncCallback that can be used with GWT RPC services.
	 */
	//   protected AsyncCallback asAsyncCallback(final AsyncCommandCallback callback, final ExceptionManager exceptionManager)
	//   {
	//      return new AsyncCallback()
	//      {
	//         public void onSuccess(R result)
	//         {
	//            callback.publishSuccess(result);
	//         }
	//
	//         public void onFailure(Throwable caught)
	//         {
	//            exceptionManager.processException(caught, callback);
	//         }
	//      };
	//   }

	private class ExecutionContext implements Command, AsyncCommandCallback
	{
		private Context context;
		private AsyncEventSupport.Trigger events;

		public ExecutionContext(Context context, AsyncEventSupport.Trigger trigger)
		{
			this.context= context;
			events= trigger;
		}

		public void execute()
		{
			context.notifyStarted();
			events.fireStart();
			performAsyncOperation(this);
		}

		public void publishSuccess(R result)
		{
			try
			{
				afterSuccess(result);
				events.fireSuccess(result);
				events.fireFinished();
			}
			finally
			{
				// just so our button always gets enabled even if a listener
				// throws an exception.  This is just for debugging ease.
				context.notifyFinished();
			}
		}

		public void publishError(E error)
		{
			try
			{
				afterError(error);
				events.fireError(error);
				events.fireFinished();
			}
			finally
			{
				// just so our button always gets enabled even if a listener
				// throws an exception.  This is just for debugging ease.
				context.notifyFinished();
			}
		}

		public void abort()
		{
			try
			{
				afterAbort();
				events.fireFinished();
			}
			finally
			{
				// just so our button always gets enabled even if a listener
				// throws an exception.  This is just for debugging ease.
				context.notifyFinished();
			}
		}
	}

	protected abstract void performAsyncOperation(AsyncCommandCallback callback);

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy