Package com.eclipsesource.tabris.xcallbackurl

Source Code of com.eclipsesource.tabris.xcallbackurl.XCallback

/*******************************************************************************
* Copyright (c) 2013 EclipseSource 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:
*    EclipseSource - initial API and implementation
******************************************************************************/
package com.eclipsesource.tabris.xcallbackurl;

import static com.eclipsesource.tabris.internal.Clauses.when;
import static com.eclipsesource.tabris.internal.Clauses.whenNull;
import static com.eclipsesource.tabris.internal.Constants.EVENT_CANCEL;
import static com.eclipsesource.tabris.internal.Constants.EVENT_ERROR;
import static com.eclipsesource.tabris.internal.Constants.EVENT_SUCCESS;
import static com.eclipsesource.tabris.internal.Constants.METHOD_CALL;
import static com.eclipsesource.tabris.internal.Constants.PROPERTY_ACTION_PARAMETERS;
import static com.eclipsesource.tabris.internal.Constants.PROPERTY_ERROR_CODE;
import static com.eclipsesource.tabris.internal.Constants.PROPERTY_ERROR_MESSAGE;
import static com.eclipsesource.tabris.internal.Constants.PROPERTY_PARAMETERS;
import static com.eclipsesource.tabris.internal.Constants.PROPERTY_TARGET_ACTION;
import static com.eclipsesource.tabris.internal.Constants.PROPERTY_TARGET_SCHEME;
import static com.eclipsesource.tabris.internal.Constants.PROPERTY_XSOURCE;
import static com.eclipsesource.tabris.internal.Constants.TYPE_XCALLBACK;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import org.eclipse.rap.json.JsonObject;
import org.eclipse.rap.rwt.Adaptable;
import org.eclipse.rap.rwt.RWT;
import org.eclipse.rap.rwt.remote.AbstractOperationHandler;
import org.eclipse.rap.rwt.remote.RemoteObject;

import com.eclipsesource.tabris.interaction.AppLauncher;


/**
* <p>
* The {@link XCallback} represents an implementation of the x-callback-url specification
* (see http://x-callback-url.com/specifications/). It can be used to accomplish a two way App communication on the
* client's device. This means you can call another App by calling its URL and receive a call when the App has done
* it's work or it has failed. To react to such callbacks the {@link XCallbackListener} needs to be used.
*
* <b>Note:</b> To accomplish a one way communication the {@link AppLauncher} is the better choice.
* </p>
*
* @see AppLauncher
* @see XCallbackListener
*
* @since 1.1
*/
public class XCallback implements Serializable, Adaptable {

  private final RemoteObject remoteObject;
  private final List<XCallbackListener> listeners;
  private final XCallbackConfiguration configuration;
  private boolean destroyed;

  /**
   * <p>
   * Creates a new {@link XCallback} instance with the specified configuration.
   * </p>
   *
   * @see XCallbackConfiguration
   */
  public XCallback( XCallbackConfiguration configuration ) {
    whenNull( configuration ).throwIllegalArgument( "Configuration must not be null" );
    this.configuration = configuration;
    this.listeners = new ArrayList<XCallbackListener>();
    this.remoteObject = RWT.getUISession().getConnection().createRemoteObject( TYPE_XCALLBACK );
    remoteObject.setHandler( createOperationHandler() );
  }

  private AbstractOperationHandler createOperationHandler() {
    return new AbstractOperationHandler() {

      @Override
      public void handleNotify( String event, JsonObject properties ) {
        if( event.equals( EVENT_SUCCESS ) ) {
          dispatchOnSuccess( getParameter( properties ) );
        } else if( event.equals( EVENT_ERROR ) ) {
          dispatchOnError( properties.get( PROPERTY_ERROR_CODE ).asString(),
                           properties.get( PROPERTY_ERROR_MESSAGE ).asString() );
        } else if( event.equals( EVENT_CANCEL ) ) {
          dispatchOnCancel();
        }
      }
    };
  }

  private Map<String, String> getParameter( JsonObject properties ) {
    Map<String, String> parameter = new HashMap<String, String>();
    if( properties != null && properties.get( PROPERTY_PARAMETERS ) != null ) {
      JsonObject object = properties.get( PROPERTY_PARAMETERS ).asObject();
      List<String> names = object.names();
      for( String name : names ) {
        parameter.put( name, object.get( name ).asString() );
      }
    }
    return parameter;
  }

  private void dispatchOnSuccess( Map<String, String> parameter ) {
    for( XCallbackListener listener : listeners ) {
      listener.onSuccess( parameter );
    }
  }

  private void dispatchOnError( String errorCode, String errorMessage ) {
    for( XCallbackListener listener : listeners ) {
      listener.onError( errorCode, errorMessage );
    }
  }

  private void dispatchOnCancel() {
    for( XCallbackListener listener : listeners ) {
      listener.onCancel();
    }
  }

  /**
   * <p>
   * Adds a {@link XCallbackListener} that will be notified when an App calls back.
   * </p>
   *
   * @see XCallbackListener
   */
  public void addXCallbackListener( XCallbackListener listener ) {
    whenNull( listener ).throwIllegalArgument( "Listener must not be null" );
    listeners.add( listener );
  }

  /**
   * <p>
   * Removes a {@link XCallbackListener} object.
   * </p>
   *
   * @see XCallbackListener
   */
  public void removeXCallbackListener( XCallbackListener listener ) {
    whenNull( listener ).throwIllegalArgument( "Listener must not be null" );
    listeners.remove( listener );
  }

  /**
   * <p>
   * Performs the call to the App specified in the {@link XCallbackConfiguration} which was passed into the constructor.
   *
   * If the call was successful, was canceled or has failed the registered {@link XCallbackListener}s will be notified.
   * </p>
   */
  public void call() {
    when( destroyed ).throwIllegalState( "XCallback already disposed" );
    remoteObject.call( METHOD_CALL, createParameters( configuration ) );
  }

  private JsonObject createParameters( XCallbackConfiguration configuration ) {
    JsonObject parameters = new JsonObject();
    parameters.add( PROPERTY_TARGET_SCHEME, configuration.getTargetScheme() );
    parameters.add( PROPERTY_TARGET_ACTION, configuration.getTargetAction() );
    addOptionalParameter( configuration, parameters );
    return parameters;
  }

  private void addOptionalParameter( XCallbackConfiguration configuration, JsonObject parameters ) {
    addXSource( configuration, parameters );
    addActionParameter( configuration, parameters );
  }

  private void addXSource( XCallbackConfiguration configuration, JsonObject parameters ) {
    String xSource = configuration.getXSource();
    if( xSource != null ) {
      parameters.add( PROPERTY_XSOURCE, xSource );
    }
  }

  private void addActionParameter( XCallbackConfiguration configuration, JsonObject parameters ) {
    Map<String, String> actionParameters = configuration.getActionParameters();
    if( actionParameters != null && !actionParameters.isEmpty() ) {
      JsonObject xActionParameter = new JsonObject();
      for( Entry<String, String> actionParameter : actionParameters.entrySet() ) {
        xActionParameter.add( actionParameter.getKey(), actionParameter.getValue() );
      }
      parameters.add( PROPERTY_ACTION_PARAMETERS, xActionParameter );
    }
  }

  /**
   * <p>
   * Destroys the {@link XCallback} object. This means no further {@link XCallback#call()} can be executed.
   * </p>
   */
  public void dispose() {
    when( destroyed ).throwIllegalState( "XCallback already disposed" );
    remoteObject.destroy();
    destroyed = true;
  }

  RemoteObject getRemoteObject() {
    return remoteObject;
  }

  @Override
  @SuppressWarnings("unchecked")
  public <T> T getAdapter( Class<T> adapter ) {
    if( adapter == RemoteObject.class ) {
      return ( T )remoteObject;
    } else if( adapter == XCallbackConfiguration.class ) {
      return ( T )configuration;
    }
    return null;
  }

}
TOP

Related Classes of com.eclipsesource.tabris.xcallbackurl.XCallback

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.