Package org.eclipse.ecf.remoteservice.client

Source Code of org.eclipse.ecf.remoteservice.client.AbstractClientService$AsyncResult

/*******************************************************************************
* Copyright (c) 2009 Composent, Inc. 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:
*   Composent, Inc. - initial API and implementation
******************************************************************************/
package org.eclipse.ecf.remoteservice.client;

import java.io.NotSerializableException;
import java.lang.reflect.Method;
import java.util.Map;
import org.eclipse.core.runtime.Assert;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.ecf.core.util.ECFException;
import org.eclipse.ecf.remoteservice.*;
import org.eclipse.ecf.remoteservice.events.IRemoteCallCompleteEvent;
import org.eclipse.ecf.remoteservice.events.IRemoteCallStartEvent;
import org.eclipse.equinox.concurrent.future.*;

/**
* Remote service client service.  Implements {@link IRemoteService}.
*
* @since 4.0
*/
public abstract class AbstractClientService extends AbstractRemoteService {

  private long nextID = 0;
  protected RemoteServiceClientRegistration registration;
  protected AbstractClientContainer container;

  public AbstractClientService(AbstractClientContainer container, RemoteServiceClientRegistration registration) {
    this.container = container;
    Assert.isNotNull(container);
    this.registration = registration;
    Assert.isNotNull(this.registration);
  }

  public Object callSync(IRemoteCall call) throws ECFException {
    IRemoteCallable callable = getRegistration().lookupCallable(call);
    if (callable == null)
      throw new ECFException("Callable not found for call=" + call); //$NON-NLS-1$
    return invokeRemoteCall(call, callable);
  }

  public IFuture callAsync(final IRemoteCall call) {
    return callAsync(call, getRegistration().lookupCallable(call));
  }

  public void callAsync(IRemoteCall call, IRemoteCallListener listener) {
    callAsync(call, getRegistration().lookupCallable(call), listener);
  }

  public void fireAsync(IRemoteCall call) throws ECFException {
    IRemoteCallable callable = getRegistration().lookupCallable(call);
    if (callable == null)
      throw new ECFException("Remote callable not found"); //$NON-NLS-1$
    callAsync(call, callable);
  }

  protected Object invokeSync(IRemoteCall remoteCall) throws ECFException {
    // Now lookup callable
    IRemoteCallable callable = getRegistration().lookupCallable(remoteCall);
    // If not found...we're finished
    if (callable == null)
      throw new ECFException("Callable not found for call=" + remoteCall); //$NON-NLS-1$
    return invokeRemoteCall(remoteCall, callable);

  }

  protected Object[] getCallParametersForProxyInvoke(String callMethod, Method proxyMethod, Object[] args) {
    return args;
  }

  protected String getCallMethodNameForProxyInvoke(Method method, Object[] args) {
    return RemoteServiceClientRegistration.getFQMethod(method.getDeclaringClass().getName(), method.getName());
  }

  protected long getNextRequestID() {
    return nextID++;
  }

  protected void callAsync(IRemoteCall call, IRemoteCallable restClientCallable, IRemoteCallListener listener) {
    final AbstractExecutor executor = new ThreadsExecutor();
    executor.execute(new AsyncResult(call, restClientCallable, listener), null);
  }

  protected IFuture callAsync(final IRemoteCall call, final IRemoteCallable callable) {
    final AbstractExecutor executor = new ThreadsExecutor();
    return executor.execute(new IProgressRunnable() {
      public Object run(IProgressMonitor monitor) throws Exception {
        if (callable == null)
          throw new ECFException("Callable not found"); //$NON-NLS-1$
        return invokeRemoteCall(call, callable);
      }
    }, null);
  }

  /**
   * inner class implementing the asynchronous result object. This
   * implementation also provides the calling infrastructure.
   */
  protected class AsyncResult implements IProgressRunnable {

    IRemoteCall call;
    // the remote call object.
    IRemoteCallable callable;
    // the callback listener, if provided.
    IRemoteCallListener listener;

    // the result of the call.
    Object result;
    // the exception, if any happened during the call.
    Throwable exception;

    // constructor
    public AsyncResult(final IRemoteCall call, final IRemoteCallable callable, final IRemoteCallListener listener) {
      this.call = call;
      this.callable = callable;
      this.listener = listener;
    }

    public Object run(IProgressMonitor monitor) throws Exception {
      Object r = null;
      Throwable e = null;

      final long reqID = getNextRequestID();

      if (listener != null) {
        listener.handleEvent(new IRemoteCallStartEvent() {
          public IRemoteCall getCall() {
            return call;
          }

          public IRemoteServiceReference getReference() {
            return getRegistration().getReference();
          }

          public long getRequestId() {
            return reqID;
          }
        });
      }

      try {
        if (callable == null)
          throw new ECFException("Restcall not found for method=" + call.getMethod()); //$NON-NLS-1$
        r = invokeRemoteCall(call, callable);
      } catch (Throwable t) {
        e = t;
      }

      synchronized (AsyncResult.this) {
        result = r;
        exception = e;
        AsyncResult.this.notify();
      }

      if (listener != null) {
        listener.handleEvent(new IRemoteCallCompleteEvent() {

          public Throwable getException() {
            return exception;
          }

          public Object getResponse() {
            return result;
          }

          public boolean hadException() {
            return exception != null;
          }

          public long getRequestId() {
            return reqID;
          }
        });
      }
      return null;
    }
  }

  protected void handleInvokeException(String message, Throwable e) throws ECFException {
    throw new ECFException(message, e);
  }

  protected AbstractClientContainer getClientContainer() {
    return container;
  }

  protected RemoteServiceClientRegistration getRegistration() {
    return registration;
  }

  protected String prepareEndpointAddress(IRemoteCall call, IRemoteCallable callable) {
    return getClientContainer().prepareEndpointAddress(call, callable);
  }

  protected IRemoteCallParameter[] prepareParameters(String uri, IRemoteCall call, IRemoteCallable callable) throws NotSerializableException {
    return getClientContainer().prepareParameters(uri, call, callable);
  }

  /**
   * @since 8.0
   */
  protected Object processResponse(String uri, IRemoteCall call, IRemoteCallable callable, Map responseHeaders, byte[] responseBody) throws NotSerializableException {
    return getClientContainer().processResponse(uri, call, callable, responseHeaders, responseBody);
  }

  protected IRemoteServiceID getRemoteServiceID() {
    return registration.getID();
  }

  protected IRemoteServiceReference getRemoteServiceReference() {
    return registration.getReference();
  }

  protected String[] getInterfaceClassNames() {
    return registration.getClazzes();
  }

  /**
   * Invoke remote call.  The implementation of this method should actually
   * make the remote call for the given call and associated callable.
   *
   * @param call the call for the remote call.  Will not be <code>null</code>.
   * @param callable the callable associated with the remote call.  Will not be <code>null</code>.
   * @return Object the result of the remote call.  May be <code>null</code>.
   * @throws ECFException thrown if the call fails.
   */
  protected abstract Object invokeRemoteCall(final IRemoteCall call, final IRemoteCallable callable) throws ECFException;

}
TOP

Related Classes of org.eclipse.ecf.remoteservice.client.AbstractClientService$AsyncResult

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.