Package org.eclipse.ecf.remoteservice

Source Code of org.eclipse.ecf.remoteservice.RemoteServiceContainerAdapterImpl

package org.eclipse.ecf.remoteservice;

import java.security.AccessController;
import java.security.PrivilegedAction;
import java.util.*;
import org.eclipse.core.runtime.Assert;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.ecf.core.ContainerConnectException;
import org.eclipse.ecf.core.IContainer;
import org.eclipse.ecf.core.identity.*;
import org.eclipse.ecf.core.security.IConnectContext;
import org.eclipse.ecf.core.util.Trace;
import org.eclipse.ecf.internal.remoteservice.Activator;
import org.eclipse.ecf.remoteservice.events.*;
import org.eclipse.ecf.remoteservice.util.RemoteFilterImpl;
import org.eclipse.equinox.concurrent.future.*;
import org.osgi.framework.InvalidSyntaxException;

/**
* @since 8.3
*/
public class RemoteServiceContainerAdapterImpl implements IRemoteServiceContainerAdapter {

  private IExecutor executor;
  private IContainer container;
  private IRemoteServiceCallPolicy remoteServiceCallPolicy;
  private IConnectContext connectContext;

  protected RemoteServiceRegistryImpl registry;

  protected final List<IRemoteServiceListener> listeners;

  protected final Map<IRemoteServiceReference, List<AbstractRemoteService>> refToImplMap;

  public RemoteServiceContainerAdapterImpl(IContainer container, IExecutor executor) {
    Assert.isNotNull(container);
    this.container = container;
    listeners = new ArrayList<IRemoteServiceListener>();
    refToImplMap = new HashMap<IRemoteServiceReference, List<AbstractRemoteService>>();
    setRegistry(new RemoteServiceRegistryImpl());
    setExecutor(executor);
  }

  public RemoteServiceContainerAdapterImpl(IContainer container) {
    this(container, null);
  }

  public void dispose() {
    synchronized (refToImplMap) {
      refToImplMap.clear();
    }
    synchronized (listeners) {
      listeners.clear();
    }
    if (registry != null) {
      registry.unpublishServices();
      registry = null;
    }
    this.connectContext = null;
    this.remoteServiceCallPolicy = null;
    this.container = null;
    this.executor = null;
  }

  public void addRemoteServiceListener(IRemoteServiceListener listener) {
    synchronized (listeners) {
      listeners.add(listener);
    }
  }

  public void removeRemoteServiceListener(IRemoteServiceListener listener) {
    synchronized (listeners) {
      listeners.remove(listener);
    }
  }

  public void setConnectContextForAuthentication(IConnectContext connectContext) {
    this.connectContext = connectContext;
  }

  public boolean setRemoteServiceCallPolicy(IRemoteServiceCallPolicy policy) {
    this.remoteServiceCallPolicy = policy;
    return true;
  }

  public Object getAdapter(Class adapter) {
    return null;
  }

  public IRemoteServiceRegistration registerRemoteService(String[] clazzes, Object service, Dictionary properties) {
    Trace.entering(Activator.PLUGIN_ID, IRemoteServiceImplDebugOptions.METHODS_ENTERING, this.getClass(), "registerRemoteService", new Object[] {clazzes, service, properties}); //$NON-NLS-1$
    if (service == null)
      throw new NullPointerException("service cannot be null"); //$NON-NLS-1$
    final int size = clazzes.length;

    if (size == 0)
      throw new IllegalArgumentException("service classes list is empty"); //$NON-NLS-1$

    final String[] copy = new String[clazzes.length];
    for (int i = 0; i < clazzes.length; i++)
      copy[i] = new String(clazzes[i].getBytes());
    clazzes = copy;

    final String invalidService = checkServiceClass(clazzes, service);
    if (invalidService != null)
      throw new IllegalArgumentException("Service=" + invalidService + " is invalid"); //$NON-NLS-1$ //$NON-NLS-2$

    RemoteServiceRegistryImpl reg = getRegistry();
    if (reg == null)
      throw new NullPointerException("registry cannot be null"); //$NON-NLS-1$

    RemoteServiceRegistrationImpl registration = createRegistration();
    synchronized (registry) {
      registration.publish(reg, service, clazzes, properties);
    }
    fireRemoteServiceListeners(createRegisteredEvent(registration));
    Trace.exiting(Activator.PLUGIN_ID, IRemoteServiceImplDebugOptions.METHODS_EXITING, this.getClass(), "registerRemoteService", registration); //$NON-NLS-1$
    return registration;
  }

  public IRemoteServiceReference[] getRemoteServiceReferences(ID target, ID[] idFilter, String clazz, String filter) throws InvalidSyntaxException, ContainerConnectException {
    Trace.entering(Activator.PLUGIN_ID, IRemoteServiceImplDebugOptions.METHODS_ENTERING, this.getClass(), "getRemoteServiceReferences", new Object[] {target, idFilter, clazz, filter}); //$NON-NLS-1$
    RemoteServiceRegistryImpl reg = getRegistry();
    if (reg == null)
      return null;
    if (target != null)
      connectToRemoteServiceTarget(target);

    final IRemoteFilter remoteFilter = (filter == null) ? null : new RemoteFilterImpl(filter);
    // then from the local registry
    ID localContainerID = getLocalContainerID();
    // Now we lookup remote service references
    final List<IRemoteServiceReference> references = new ArrayList();
    if (idFilter == null || Arrays.asList(idFilter).contains(localContainerID)) {
      synchronized (reg) {
        final IRemoteServiceReference[] rs = registry.lookupServiceReferences(clazz, remoteFilter);
        if (rs != null)
          for (int j = 0; j < rs.length; j++)
            references.add(rs[j]);
      }
    }
    // And we return the result
    final IRemoteServiceReference[] result = references.toArray(new IRemoteServiceReference[references.size()]);
    Trace.exiting(Activator.PLUGIN_ID, IRemoteServiceImplDebugOptions.METHODS_EXITING, this.getClass(), "getRemoteServiceReferences", result); //$NON-NLS-1$
    return (result.length == 0) ? null : result;
  }

  public IFuture asyncGetRemoteServiceReferences(final ID target, final ID[] idFilter, final String clazz, final String filter) {
    IExecutor exec = getExecutor();
    if (exec == null)
      throw new NullPointerException("Executor is null.  Cannot asynchronously get remote service references"); //$NON-NLS-1$
    return exec.execute(new IProgressRunnable() {
      public Object run(IProgressMonitor monitor) throws Exception {
        return getRemoteServiceReferences(target, idFilter, clazz, filter);
      }
    }, null);
  }

  public IRemoteServiceReference[] getRemoteServiceReferences(ID[] idFilter, String clazz, String filter) throws InvalidSyntaxException {
    try {
      return getRemoteServiceReferences(null, idFilter, clazz, filter);
    } catch (ContainerConnectException e) {
      // can't occur, because first parameter is null
      return null;
    }
  }

  public IRemoteServiceReference[] getRemoteServiceReferences(ID target, String clazz, String filter) throws InvalidSyntaxException, ContainerConnectException {
    return getRemoteServiceReferences(target, null, clazz, filter);
  }

  public IFuture asyncGetRemoteServiceReferences(final ID[] idFilter, final String clazz, final String filter) {
    IExecutor exec = getExecutor();
    if (exec == null)
      throw new NullPointerException("Executor is null.  Cannot asynchronously get remote service references"); //$NON-NLS-1$
    return executor.execute(new IProgressRunnable() {
      public Object run(IProgressMonitor monitor) throws Exception {
        return getRemoteServiceReferences(idFilter, clazz, filter);
      }
    }, null);
  }

  public IFuture asyncGetRemoteServiceReferences(final ID target, final String clazz, final String filter) {
    IExecutor exec = getExecutor();
    if (exec == null)
      throw new NullPointerException("Executor is null.  Cannot asynchronously get remote service references"); //$NON-NLS-1$
    return executor.execute(new IProgressRunnable() {
      public Object run(IProgressMonitor monitor) throws Exception {
        return getRemoteServiceReferences(target, clazz, filter);
      }
    }, null);
  }

  public IRemoteServiceReference[] getAllRemoteServiceReferences(String clazz, String filter) throws InvalidSyntaxException {
    final IRemoteServiceReference[] result = getRemoteServiceReferences((ID[]) null, clazz, filter);
    if (result == null)
      return null;
    return (result.length == 0) ? null : result;
  }

  public Namespace getRemoteServiceNamespace() {
    return IDFactory.getDefault().getNamespaceByName(RemoteServiceNamespace.NAME);
  }

  public IRemoteServiceID getRemoteServiceID(ID containerID, long containerRelativeID) {
    if (containerID == null)
      return null;
    RemoteServiceRegistryImpl reg = getRegistry();
    if (reg == null)
      return null;
    ID localContainerID = getLocalContainerID();
    if (containerID.equals(localContainerID)) {
      synchronized (reg) {
        RemoteServiceRegistrationImpl registration = reg.findRegistrationForServiceId(containerRelativeID);
        if (registration != null)
          return registration.getID();
      }
    }
    return null;
  }

  public IRemoteServiceReference getRemoteServiceReference(IRemoteServiceID serviceID) {
    ID containerID = serviceID.getContainerID();
    if (containerID == null)
      return null;
    RemoteServiceRegistryImpl reg = getRegistry();
    if (reg == null)
      return null;
    RemoteServiceRegistrationImpl registration = null;
    ID localContainerID = getLocalContainerID();
    if (containerID.equals(localContainerID)) {
      synchronized (reg) {
        registration = reg.findRegistrationForServiceId(serviceID.getContainerRelativeID());
        if (registration != null)
          return registration.getReference();
      }
    }
    return (registration == null) ? null : registration.getReference();
  }

  public IRemoteService getRemoteService(IRemoteServiceReference reference) {
    Trace.entering(Activator.PLUGIN_ID, IRemoteServiceImplDebugOptions.METHODS_ENTERING, this.getClass(), "getRemoteService", reference); //$NON-NLS-1$
    final RemoteServiceRegistrationImpl registration = getRemoteServiceRegistrationImpl(reference);
    if (registration == null)
      return null;
    final AbstractRemoteService remoteService = createRemoteService(registration);
    if (remoteService == null)
      return null;
    synchronized (refToImplMap) {
      List<AbstractRemoteService> remoteServiceImplList = refToImplMap.get(reference);
      if (remoteServiceImplList == null)
        remoteServiceImplList = new ArrayList();
      remoteServiceImplList.add(remoteService);
      refToImplMap.put(reference, remoteServiceImplList);
    }
    Trace.exiting(Activator.PLUGIN_ID, IRemoteServiceImplDebugOptions.METHODS_EXITING, this.getClass(), "getRemoteService", remoteService); //$NON-NLS-1$
    return remoteService;
  }

  public boolean ungetRemoteService(IRemoteServiceReference ref) {
    if (ref == null)
      return false;
    IRemoteServiceID serviceID = ref.getID();
    if (serviceID == null)
      return false;
    synchronized (refToImplMap) {
      List<AbstractRemoteService> remoteServiceImplList = refToImplMap.remove(ref);
      if (remoteServiceImplList != null) {
        for (Iterator<AbstractRemoteService> i = remoteServiceImplList.iterator(); i.hasNext();) {
          AbstractRemoteService rsImpl = i.next();
          if (rsImpl != null)
            rsImpl.dispose();
          i.remove();
        }
        return true;
      }
    }
    return false;
  }

  public IRemoteFilter createRemoteFilter(String filter) throws InvalidSyntaxException {
    return new RemoteServiceFilterImpl(filter);
  }

  protected IRemoteServiceCallPolicy getRemoteServiceCallPolicy() {
    return remoteServiceCallPolicy;
  }

  protected IConnectContext getConnectContext() {
    return this.connectContext;
  }

  protected void setExecutor(IExecutor executor) {
    this.executor = executor;
  }

  protected IExecutor getExecutor() {
    return this.executor;
  }

  protected IContainer getContainer() {
    return this.container;
  }

  protected ID getLocalContainerID() {
    return getContainer().getID();
  }

  protected RemoteServiceRegistryImpl getRegistry() {
    return this.registry;
  }

  protected void setRegistry(RemoteServiceRegistryImpl registry) {
    this.registry = registry;
  }

  protected AbstractRemoteService createRemoteService(RemoteServiceRegistrationImpl registration) {
    return null;
  }

  protected IRemoteServiceRegisteredEvent createRegisteredEvent(final RemoteServiceRegistrationImpl registration) {
    return new IRemoteServiceRegisteredEvent() {

      public ID getLocalContainerID() {
        return RemoteServiceContainerAdapterImpl.this.getLocalContainerID();
      }

      public String[] getClazzes() {
        return registration.getClasses();
      }

      public ID getContainerID() {
        return registration.getContainerID();
      }

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

      public String toString() {
        final StringBuffer buf = new StringBuffer("RemoteServiceRegisteredEvent["); //$NON-NLS-1$
        buf.append("localContainerID=").append(getLocalContainerID()); //$NON-NLS-1$
        buf.append(";containerID=").append(registration.getContainerID()); //$NON-NLS-1$
        buf.append(";clazzes=").append(Arrays.asList(registration.getClasses())); //$NON-NLS-1$
        buf.append(";reference=").append(registration.getReference()).append("]"); //$NON-NLS-1$ //$NON-NLS-2$
        return buf.toString();
      }
    };
  }

  protected void fireRemoteServiceListeners(IRemoteServiceEvent event) {
    List<IRemoteServiceListener> entries;
    synchronized (listeners) {
      entries = new ArrayList(listeners);
    }
    for (final Iterator i = entries.iterator(); i.hasNext();) {
      final IRemoteServiceListener l = (IRemoteServiceListener) i.next();
      l.handleServiceEvent(event);
    }
  }

  protected RemoteServiceRegistrationImpl createRegistration() {
    return new RemoteServiceRegistrationImpl(new IRegistrationListener() {
      public void unregister(RemoteServiceRegistrationImpl registration) {
        handleServiceUnregister(registration);
      }
    });
  }

  protected IRemoteServiceUnregisteredEvent createUnregisteredEvent(final RemoteServiceRegistrationImpl registration) {
    return new IRemoteServiceUnregisteredEvent() {

      public String[] getClazzes() {
        return registration.getClasses();
      }

      public ID getLocalContainerID() {
        return RemoteServiceContainerAdapterImpl.this.getLocalContainerID();
      }

      public ID getContainerID() {
        return registration.getContainerID();
      }

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

      public String toString() {
        final StringBuffer buf = new StringBuffer("RemoteServiceUnregisteredEvent["); //$NON-NLS-1$
        buf.append("localContainerID=").append(getLocalContainerID()); //$NON-NLS-1$
        buf.append(";containerID=").append(registration.getContainerID()); //$NON-NLS-1$
        buf.append(";clazzes=").append(Arrays.asList(registration.getClasses())); //$NON-NLS-1$
        buf.append(";reference=").append(registration.getReference()).append("]"); //$NON-NLS-1$ //$NON-NLS-2$
        return buf.toString();
      }
    };
  }

  protected void handleServiceUnregister(RemoteServiceRegistrationImpl registration) {
    fireRemoteServiceListeners(createUnregisteredEvent(registration));
  }

  protected RemoteServiceRegistrationImpl getRemoteServiceRegistrationImpl(IRemoteServiceReference reference) {
    if (reference instanceof RemoteServiceReferenceImpl) {
      final RemoteServiceReferenceImpl ref = (RemoteServiceReferenceImpl) reference;
      if (!ref.isActive()) {
        return null;
      }
      return ref.getRegistration();
    }
    return null;
  }

  /**
   * @throws ContainerConnectException 
   */
  protected void connectToRemoteServiceTarget(ID target) throws ContainerConnectException {
    // Do nothing by default
  }

  protected static String checkServiceClass(final String[] clazzes, final Object serviceObject) {
    final ClassLoader cl = (ClassLoader) AccessController.doPrivileged(new PrivilegedAction() {
      public Object run() {
        return serviceObject.getClass().getClassLoader();
      }
    });
    for (int i = 0; i < clazzes.length; i++) {
      try {
        final Class serviceClazz = cl == null ? Class.forName(clazzes[i]) : cl.loadClass(clazzes[i]);
        if (!serviceClazz.isInstance(serviceObject))
          return clazzes[i];
      } catch (final ClassNotFoundException e) {
        // This check is rarely done
        if (extensiveCheckServiceClass(clazzes[i], serviceObject.getClass()))
          return clazzes[i];
      }
    }
    return null;
  }

  private static boolean extensiveCheckServiceClass(String clazz, Class serviceClazz) {
    if (clazz.equals(serviceClazz.getName()))
      return false;
    final Class[] interfaces = serviceClazz.getInterfaces();
    for (int i = 0; i < interfaces.length; i++)
      if (!extensiveCheckServiceClass(clazz, interfaces[i]))
        return false;
    final Class superClazz = serviceClazz.getSuperclass();
    if (superClazz != null)
      if (!extensiveCheckServiceClass(clazz, superClazz))
        return false;
    return true;
  }

}
TOP

Related Classes of org.eclipse.ecf.remoteservice.RemoteServiceContainerAdapterImpl

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.