Package org.eclipse.ecf.osgi.services.remoteserviceadmin

Source Code of org.eclipse.ecf.osgi.services.remoteserviceadmin.AbstractHostContainerSelector

/*******************************************************************************
* Copyright (c) 2010-2011 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.osgi.services.remoteserviceadmin;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.eclipse.ecf.core.ContainerConnectException;
import org.eclipse.ecf.core.ContainerCreateException;
import org.eclipse.ecf.core.ContainerTypeDescription;
import org.eclipse.ecf.core.IContainer;
import org.eclipse.ecf.core.identity.ID;
import org.eclipse.ecf.core.identity.IDCreateException;
import org.eclipse.ecf.core.identity.Namespace;
import org.eclipse.ecf.core.security.IConnectContext;
import org.eclipse.ecf.internal.osgi.services.remoteserviceadmin.IDUtil;
import org.eclipse.ecf.remoteservice.IRemoteServiceContainer;
import org.eclipse.ecf.remoteservice.IRemoteServiceContainerAdapter;
import org.eclipse.ecf.remoteservice.RemoteServiceContainer;
import org.osgi.framework.ServiceReference;

/**
* Abstract superclass for host container selectors...i.e. implementers of
* {@link IHostContainerSelector}.
*
*/
public abstract class AbstractHostContainerSelector extends
    AbstractContainerSelector {

  protected String[] defaultConfigTypes;

  public AbstractHostContainerSelector(String[] defaultConfigTypes) {
    this.defaultConfigTypes = defaultConfigTypes;
  }

  /**
   * @since 2.0
   */
  protected Collection selectExistingHostContainers(
      ServiceReference serviceReference,
      Map<String, Object> overridingProperties,
      String[] serviceExportedInterfaces,
      String[] serviceExportedConfigs, String[] serviceIntents) {
    List results = new ArrayList();
    // Get all existing containers
    IContainer[] containers = getContainers();
    // If nothing there, then return empty array
    if (containers == null || containers.length == 0)
      return results;

    for (int i = 0; i < containers.length; i++) {
      // Check to make sure it's a rs container adapter. If it's not go
      // onto next one
      IRemoteServiceContainerAdapter adapter = hasRemoteServiceContainerAdapter(containers[i]);
      if (adapter == null)
        continue;
      // Get container type description and intents
      ContainerTypeDescription description = getContainerTypeDescription(containers[i]);
      // If it has no description go onto next
      if (description == null)
        continue;

      // http://bugs.eclipse.org/331532
      if (!description.isServer()) {
        continue;
      }

      if (matchExistingHostContainer(serviceReference,
          overridingProperties, containers[i], adapter, description,
          serviceExportedConfigs, serviceIntents)) {
        trace("selectExistingHostContainers", "INCLUDING containerID=" //$NON-NLS-1$ //$NON-NLS-2$
            + containers[i].getID()
            + " configs=" //$NON-NLS-1$
            + ((serviceExportedConfigs == null) ? "null" : Arrays //$NON-NLS-1$
                .asList(serviceExportedConfigs).toString())
            + " intents=" //$NON-NLS-1$
            + ((serviceIntents == null) ? "null" : Arrays.asList( //$NON-NLS-1$
                serviceIntents).toString()));
        results.add(new RemoteServiceContainer(containers[i], adapter));
      } else {
        trace("selectExistingHostContainers", "EXCLUDING containerID=" //$NON-NLS-1$ //$NON-NLS-2$
            + containers[i].getID()
            + " configs=" //$NON-NLS-1$
            + ((serviceExportedConfigs == null) ? "null" : Arrays //$NON-NLS-1$
                .asList(serviceExportedConfigs).toString())
            + " intents=" //$NON-NLS-1$
            + ((serviceIntents == null) ? "null" : Arrays.asList( //$NON-NLS-1$
                serviceIntents).toString()));
      }
    }
    return results;
  }

  /**
   * @since 2.0
   */
  protected boolean matchHostContainerToConnectTarget(
      ServiceReference serviceReference, Map<String, Object> properties,
      IContainer container) {
    String target = (String) properties
        .get(RemoteConstants.ENDPOINT_CONNECTTARGET_ID);
    if (target == null)
      return true;
    // If a targetID is specified, make sure it either matches what the
    // container
    // is already connected to, or that we connect an unconnected container
    ID connectedID = container.getConnectedID();
    // If the container is not already connected to anything
    // then we connect it to the given target
    if (connectedID == null) {
      // connect to the target and we have a match
      try {
        connectHostContainer(serviceReference, properties, container,
            target);
      } catch (Exception e) {
        logException("doConnectContainer containerID=" //$NON-NLS-1$
            + container.getID() + " target=" + target, e); //$NON-NLS-1$
        return false;
      }
      return true;
    } else {
      ID targetID = createTargetID(container, target);
      // We check here if the currently connectedID equals the target.
      // If it does we have a match
      if (connectedID.equals(targetID))
        return true;
    }
    return false;
  }

  /**
   * @since 2.0
   */
  protected boolean matchExistingHostContainer(
      ServiceReference serviceReference, Map<String, Object> properties,
      IContainer container, IRemoteServiceContainerAdapter adapter,
      ContainerTypeDescription description, String[] requiredConfigTypes,
      String[] requiredServiceIntents) {

    return matchHostSupportedConfigTypes(requiredConfigTypes, description)
        && matchHostSupportedIntents(requiredServiceIntents,
            description)
        && matchHostContainerID(serviceReference, properties, container)
        && matchHostContainerToConnectTarget(serviceReference,
            properties, container);
  }

  /**
   * @since 2.0
   */
  protected boolean matchHostContainerID(ServiceReference serviceReference,
      Map<String, Object> properties, IContainer container) {

    ID containerID = container.getID();
    // No match if the container has no ID
    if (containerID == null)
      return false;

    // Then get containerid if specified directly by user in properties
    ID requiredContainerID = (ID) properties
        .get(RemoteConstants.SERVICE_EXPORTED_CONTAINER_ID);
    // If the CONTAINER_I
    if (requiredContainerID != null) {
      return requiredContainerID.equals(containerID);
    }
    // Else get the container factory arguments, create an ID from the
    // arguments
    // and check if the ID matches that
    Namespace ns = containerID.getNamespace();
    Object cid = properties
        .get(RemoteConstants.SERVICE_EXPORTED_CONTAINER_FACTORY_ARGS);
    // If no arguments are present, then any container ID should match
    if (cid == null)
      return true;
    ID cID = null;
    if (cid instanceof ID) {
      cID = (ID) cid;
    } else if (cid instanceof String) {
      cID = IDUtil.createID(ns, (String) cid);
    } else if (cid instanceof Object[]) {
      Object cido = ((Object[]) cid)[0];
      cID = IDUtil.createID(ns, new Object[] { cido });
    }
    if (cID == null)
      return true;
    return containerID.equals(cID);
  }

  protected boolean matchHostSupportedConfigTypes(
      String[] requiredConfigTypes,
      ContainerTypeDescription containerTypeDescription) {
    // if no config type is set the spec requires to create a default
    // endpoint (see section 122.5.1)
    if (requiredConfigTypes == null)
      return true;
    // Get supported config types for this description
    String[] supportedConfigTypes = getSupportedConfigTypes(containerTypeDescription);
    // If it doesn't support anything, return false
    if (supportedConfigTypes == null || supportedConfigTypes.length == 0)
      return false;
    // Turn supported config types for this description into list
    List supportedConfigTypesList = Arrays.asList(supportedConfigTypes);
    List requiredConfigTypesList = Arrays.asList(requiredConfigTypes);
    // We check all of the required config types and make sure
    // that they are present in the supportedConfigTypes
    boolean result = true;
    for (Iterator i = requiredConfigTypesList.iterator(); i.hasNext();)
      result &= supportedConfigTypesList.contains(i.next());
    return result;
  }

  /**
   * @since 2.0
   */
  protected Collection createAndConfigureHostContainers(
      ServiceReference serviceReference, Map<String, Object> properties,
      String[] serviceExportedInterfaces, String[] requiredConfigs,
      String[] requiredIntents) throws SelectContainerException {

    List results = new ArrayList();
    ContainerTypeDescription[] descriptions = getContainerTypeDescriptions();
    if (descriptions == null)
      return Collections.EMPTY_LIST;
    // If there are no required configs specified, then create any defaults
    if (requiredConfigs == null || requiredConfigs.length == 0) {
      createAndAddDefaultContainers(serviceReference, properties,
          serviceExportedInterfaces, requiredIntents, descriptions,
          results);
    } else {
      // See if we have a match
      for (int i = 0; i < descriptions.length; i++) {
        IRemoteServiceContainer matchingContainer = createMatchingContainer(
            descriptions[i], serviceReference, properties,
            serviceExportedInterfaces, requiredConfigs,
            requiredIntents);
        if (matchingContainer != null)
          results.add(matchingContainer);
      }
    }
    return results;
  }

  private void createAndAddDefaultContainers(
      ServiceReference serviceReference, Map<String, Object> properties,
      String[] serviceExportedInterfaces, String[] requiredIntents,
      ContainerTypeDescription[] descriptions, Collection results)
      throws SelectContainerException {
    ContainerTypeDescription[] ctds = getContainerTypeDescriptionsForDefaultConfigTypes(descriptions);
    if (ctds != null) {
      for (int i = 0; i < ctds.length; i++) {
        IRemoteServiceContainer matchingContainer = createMatchingContainer(
            ctds[i], serviceReference, properties,
            serviceExportedInterfaces, null, requiredIntents);
        if (matchingContainer != null)
          results.add(matchingContainer);
      }
    }
  }

  protected ContainerTypeDescription[] getContainerTypeDescriptionsForDefaultConfigTypes(
      ContainerTypeDescription[] descriptions) {
    String[] defaultConfigTypes = getDefaultConfigTypes();
    if (defaultConfigTypes == null || defaultConfigTypes.length == 0)
      return null;
    List results = new ArrayList();
    for (int i = 0; i < descriptions.length; i++) {
      // For each description, get supported config types
      String[] supportedConfigTypes = descriptions[i]
          .getSupportedConfigs();
      if (supportedConfigTypes != null
          && matchDefaultConfigTypes(defaultConfigTypes,
              supportedConfigTypes))
        results.add(descriptions[i]);
    }
    return (ContainerTypeDescription[]) results
        .toArray(new ContainerTypeDescription[] {});
  }

  protected boolean matchDefaultConfigTypes(String[] defaultConfigTypes,
      String[] supportedConfigTypes) {
    List supportedConfigTypesList = Arrays.asList(supportedConfigTypes);
    for (int i = 0; i < defaultConfigTypes.length; i++) {
      if (supportedConfigTypesList.contains(defaultConfigTypes[i]))
        return true;
    }
    return false;
  }

  protected String[] getDefaultConfigTypes() {
    return defaultConfigTypes;
  }

  /**
   * @throws ContainerCreateException
   * @since 2.0
   */
  protected IRemoteServiceContainer createMatchingContainer(
      ContainerTypeDescription containerTypeDescription,
      ServiceReference serviceReference, Map<String, Object> properties,
      String[] serviceExportedInterfaces, String[] requiredConfigs,
      String[] requiredIntents) throws SelectContainerException {

    if (matchHostSupportedConfigTypes(requiredConfigs,
        containerTypeDescription)
        && matchHostSupportedIntents(requiredIntents,
            containerTypeDescription)) {
      return createRSContainer(serviceReference, properties,
          containerTypeDescription);
    }
    return null;
  }

  /**
   * @throws ContainerCreateException
   * @since 2.0
   */
  protected IRemoteServiceContainer createRSContainer(
      ServiceReference serviceReference, Map<String, Object> properties,
      ContainerTypeDescription containerTypeDescription)
      throws SelectContainerException {
    IContainer container = createContainer(serviceReference, properties,
        containerTypeDescription);
    IRemoteServiceContainerAdapter adapter = (IRemoteServiceContainerAdapter) container
        .getAdapter(IRemoteServiceContainerAdapter.class);
    if (adapter == null)
      throw new SelectContainerException(
          "Container does not implement IRemoteServiceContainerAdapter", null, containerTypeDescription); //$NON-NLS-1$
    return new RemoteServiceContainer(container, adapter);
  }

  /**
   * @since 2.0
   */
  protected void connectHostContainer(ServiceReference serviceReference,
      Map<String, Object> properties, IContainer container, Object target)
      throws ContainerConnectException, IDCreateException {
    ID targetID = (target instanceof String) ? IDUtil.createID(
        container.getConnectNamespace(), (String) target) : IDUtil
        .createID(container.getConnectNamespace(),
            new Object[] { target });
    Object context = properties
        .get(RemoteConstants.SERVICE_EXPORTED_CONTAINER_CONNECT_CONTEXT);
    IConnectContext connectContext = null;
    if (context != null) {
      connectContext = createConnectContext(serviceReference, properties,
          container, context);
    }
    // connect the container
    container.connect(targetID, connectContext);
  }

  protected boolean matchHostSupportedIntents(
      String[] serviceRequiredIntents,
      ContainerTypeDescription containerTypeDescription) {
    // If there are no required intents then we have a match
    if (serviceRequiredIntents == null)
      return true;

    String[] supportedIntents = getSupportedIntents(containerTypeDescription);

    if (supportedIntents == null)
      return false;

    List supportedIntentsList = Arrays.asList(supportedIntents);

    boolean result = true;
    for (int i = 0; i < serviceRequiredIntents.length; i++)
      result = result
          && supportedIntentsList.contains(serviceRequiredIntents[i]);

    return result;
  }

}
TOP

Related Classes of org.eclipse.ecf.osgi.services.remoteserviceadmin.AbstractHostContainerSelector

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.