Package org.eclipse.ecf.discovery.ui.model.resource

Source Code of org.eclipse.ecf.discovery.ui.model.resource.ServiceResource$ServiceDiscoveryListener$ECFServiceInfoComparator

/****************************************************************************
* Copyright (c) 2008 Versant Corp. 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:
*    Versant Corp. - initial API and implementation
*****************************************************************************/
package org.eclipse.ecf.discovery.ui.model.resource;

import java.io.IOException;
import java.net.*;
import java.util.*;
import org.eclipse.core.runtime.*;
import org.eclipse.core.runtime.jobs.*;
import org.eclipse.ecf.core.*;
import org.eclipse.ecf.core.util.StringUtils;
import org.eclipse.ecf.core.util.Trace;
import org.eclipse.ecf.discovery.*;
import org.eclipse.ecf.discovery.ui.model.*;
import org.eclipse.ecf.discovery.ui.model.IServiceInfo;
import org.eclipse.emf.common.notify.Notification;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.ecore.resource.URIConverter;
import org.eclipse.emf.ecore.resource.impl.ResourceImpl;
import org.eclipse.emf.ecore.resource.impl.URIConverterImpl;
import org.eclipse.emf.ecore.util.EcoreUtil;
import org.eclipse.osgi.util.NLS;

public class ServiceResource extends ResourceImpl implements Resource {

  private class ServiceDiscoveryListener implements IServiceListener {
    private volatile ILock lock;
    public static final String DISCOVERY_CONTAINER = "ecf.singleton.discovery"; //$NON-NLS-1$

    private IContainer container;

    private IDiscoveryLocator discovery;
    private Comparator aComparator = new ECFServiceInfoComparator();

    private ServiceDiscoveryListener() {
      IJobManager jobManager = Job.getJobManager();
      lock = jobManager.newLock();
    }

    /**
     * Connect to the underlying ECF discovery service
     */
    public void connect() {
      try {
        lock.acquire();
        container = ContainerFactory.getDefault().createContainer(
            DISCOVERY_CONTAINER,
            new Object[] { "ecf.discovery.composite.locator" }); //$NON-NLS-1$
        discovery = (IDiscoveryLocator) container
            .getAdapter(IDiscoveryLocator.class);
        if (discovery != null) {
          discovery.addServiceListener(this);
          container.connect(null, null);
          org.eclipse.ecf.discovery.IServiceInfo[] services = discovery
              .getServices();
          for (int i = 0; i < services.length; i++) {
            serviceDiscovered(services[i]);
            Trace.trace(ModelPlugin.PLUGIN_ID,
                ModelPlugin.PLUGIN_ID + "/methods/tracing", //$NON-NLS-1$
                ServiceResource.class, "connect", //$NON-NLS-1$
                "serviceResolved: " + services[i].toString()); //$NON-NLS-1$
          }
        } else {
          ModelPlugin
              .getDefault()
              .getLog()
              .log(new Status(
                  IStatus.WARNING,
                  ModelPlugin.PLUGIN_ID,
                  Messages.ServiceResource_NO_DISCOVERY_CONTAINER_AVAILABLE));
        }
      } catch (ContainerCreateException e1) {
        container = null;
        discovery = null;
        ModelPlugin
            .getDefault()
            .getLog()
            .log(new Status(
                IStatus.WARNING,
                ModelPlugin.PLUGIN_ID,
                Messages.ServiceResource_NO_DISCOVERY_CONTAINER_AVAILABLE,
                e1));
        return;
      } catch (ContainerConnectException e) {
        ModelPlugin
            .getDefault()
            .getLog()
            .log(new Status(IStatus.ERROR, ModelPlugin.PLUGIN_ID, e
                .getMessage(), e));
      } finally {
        lock.release();
      }
    }

    private void createEMFIServiceInfo(
        org.eclipse.ecf.discovery.IServiceInfo ecfServiceInfo,
        IServiceInfo emfIServiceInfo) {
      emfIServiceInfo.setEcfServiceInfo(ecfServiceInfo);
      emfIServiceInfo.setEcfName(ecfServiceInfo.getServiceID().getName());
      emfIServiceInfo.setEcfLocation(ecfServiceInfo.getLocation());
      emfIServiceInfo.setEcfPriority(ecfServiceInfo.getPriority());
      emfIServiceInfo.setEcfWeight(ecfServiceInfo.getWeight());

      // ECF IServiceID -> EMF IServiceID
      org.eclipse.ecf.discovery.identity.IServiceID ecfServiceID = ecfServiceInfo
          .getServiceID();
      IServiceID emfIServiceID = ModelFactory.eINSTANCE
          .createIServiceID();
      emfIServiceID.setEcfServiceID(ecfServiceID);
      emfIServiceID.setEcfServiceName(ecfServiceID.getServiceName());

      emfIServiceInfo.setServiceID(emfIServiceID);

      // ECF IServiceTypeID -> EMF IServiceTypeID
      org.eclipse.ecf.discovery.identity.IServiceTypeID ecfServiceTypeID = ecfServiceID
          .getServiceTypeID();
      IServiceTypeID emfIServiceTypeID = ModelFactory.eINSTANCE
          .createIServiceTypeID();
      emfIServiceTypeID.setEcfNamingAuthority(ecfServiceTypeID
          .getNamingAuthority());
      emfIServiceTypeID.setEcfServiceName(ecfServiceTypeID.getName());
      emfIServiceTypeID.setEcfServiceTypeID(ecfServiceTypeID);
      emfIServiceTypeID.getEcfScopes().addAll(
          Arrays.asList(ecfServiceTypeID.getScopes()));
      emfIServiceTypeID.getEcfServices().addAll(
          Arrays.asList(ecfServiceTypeID.getServices()));
      emfIServiceTypeID.getEcfProtocols().addAll(
          Arrays.asList(ecfServiceTypeID.getProtocols()));

      emfIServiceID.setServiceTypeID(emfIServiceTypeID);
    }

    private IHost getIHost(InetAddress anAddress) {
      IHost host = ModelFactory.eINSTANCE.createIHost();
      host.setAddress(anAddress);
      host.setName(anAddress.getCanonicalHostName());
      return host;
    }

    /**
     * @param ecfServiceInfo
     * @return
     */
    private IServiceInfo getIServiceInfo(
        org.eclipse.ecf.discovery.IServiceInfo ecfServiceInfo) {
      Trace.entering(ModelPlugin.PLUGIN_ID, ModelPlugin.PLUGIN_ID
          + "/methods/entering", ServiceResource.class, //$NON-NLS-1$
          "getIServiceInfo", ecfServiceInfo); //$NON-NLS-1$
      IServiceInfo emfIServiceInfo;
      URI anUri = null;
      try {
        anUri = convertToURI(ecfServiceInfo);
        emfIServiceInfo = (IServiceInfo) resourceSet.getEObject(anUri,
            true);
        createEMFIServiceInfo(ecfServiceInfo, emfIServiceInfo);
        return emfIServiceInfo;
      } catch (RuntimeException e) {
        if (e.getCause() instanceof MalformedURLException) {
          ModelPlugin
              .getDefault()
              .getLog()
              .log(new Status(
                  IStatus.INFO,
                  ModelPlugin.PLUGIN_ID,
                  NLS.bind(
                      Messages.ServiceResource_NoEMFServiceModel,
                      anUri)));
        } else {
          ModelPlugin
              .getDefault()
              .getLog()
              .log(new Status(IStatus.INFO,
                  ModelPlugin.PLUGIN_ID, e.getMessage()));
        }
      }
      emfIServiceInfo = ModelFactory.eINSTANCE.createIServiceInfo();
      createEMFIServiceInfo(ecfServiceInfo, emfIServiceInfo);
      return emfIServiceInfo;
    }

    /**
     * @param anIServiceInfo
     * @return
     */
    private URI convertToURI(
        org.eclipse.ecf.discovery.IServiceInfo anIServiceInfo) {

      // get rid of the first underscore
      String name = anIServiceInfo.getServiceID().getServiceTypeID()
          .getName().substring(1);

      // replace the ECF delimiter
      name = StringUtils.replaceAll(name, "._", "/"); //$NON-NLS-1$ //$NON-NLS-2$
      name = StringUtils.replaceFirst(name, ".", "/"); //$NON-NLS-1$ //$NON-NLS-2$
      name = "ecf://" + name; //$NON-NLS-1$

      // use an URI Converter to allow possible model extender to rewrite
      // URI
      // TODO replace with ExtensibleURIConverterImpl once EMF dep moves
      // up to 2.4
      URIConverter uriConverter = new URIConverterImpl();
      URI uri = uriConverter.normalize(URI.createURI(name));

      // set Authority to host and port of the service
      final java.net.URI location = anIServiceInfo.getLocation();
      final String authority = location.getAuthority();
      uri = URI.createHierarchicalURI(uri.scheme(), authority,
          uri.device(), uri.segments(), location.getQuery(),
          location.getFragment());

      return uri;
    }

    /**
     * Disconnect from the underlying ECF discovery service
     */
    public void disconnect() {
      container.dispose();
    }

    private IHost findIHost(InetAddress anAddress) {
      INetwork network = (INetwork) ServiceResource.this.getContents()
          .get(0);
      for (java.util.Iterator itr = network.getHosts().iterator(); itr
          .hasNext();) {
        IHost host = (IHost) itr.next();
        if (host.getAddress().equals(anAddress)) {
          return host;
        }
      }
      return null;
    }

    private IServiceInfo findIServiceInfo(
        org.eclipse.ecf.discovery.IServiceInfo ecfServiceInfo) {
      IHost host = findIHost(getInetAddress(ecfServiceInfo.getLocation()));
      if (host != null) {
        for (java.util.Iterator itr = host.getServices().iterator(); itr
            .hasNext();) {
          IServiceInfo emfIServiceInfo = (IServiceInfo) itr.next();
          if (aComparator.compare(ecfServiceInfo,
              emfIServiceInfo.getEcfServiceInfo()) == 0) {
            return emfIServiceInfo;
          }
        }
      }
      return null;
    }

    /*
     * (non-Javadoc)
     *
     * @see
     * org.eclipse.ecf.discovery.IServiceListener#serviceRemoved(org.eclipse
     * .ecf.discovery.IServiceEvent)
     */
    public void serviceUndiscovered(IServiceEvent ecfEvent) {
      try {
        lock.acquire();
        Trace.entering(ModelPlugin.PLUGIN_ID, ModelPlugin.PLUGIN_ID
            + "/methods/entering", ServiceResource.class, //$NON-NLS-1$
            "serviceUndiscovered", ecfEvent); //$NON-NLS-1$
        org.eclipse.ecf.discovery.IServiceInfo ecfServiceInfo = ecfEvent
            .getServiceInfo();

        // remove the IServiceInfo
        IServiceInfo emfIServiceInfo = findIServiceInfo(ecfServiceInfo);

        Assert.isNotNull(emfIServiceInfo);

        EcoreUtil.remove(emfIServiceInfo);

        // remove lazy loaded resources as well
        Set resources = new HashSet();
        Iterator iter = EcoreUtil
            .getAllContents(emfIServiceInfo, false);
        while (iter.hasNext()) {
          resources.add(((EObject) iter.next()).eResource());
        }
        getResourceSet().getResources().removeAll(resources);

        Trace.trace(
            ModelPlugin.PLUGIN_ID,
            ModelPlugin.PLUGIN_ID + "/methods/tracing", ServiceResource.class, //$NON-NLS-1$
            "serviceUndiscovered", "Removed service " + emfIServiceInfo); //$NON-NLS-1$ //$NON-NLS-2$

        // remove the host if no services left for this particular host
        IHost host = findIHost(getInetAddress(ecfServiceInfo
            .getLocation()));
        if (host != null && host.getServices().size() < 1) {
          EcoreUtil.remove(host);
          Trace.trace(ModelPlugin.PLUGIN_ID, ModelPlugin.PLUGIN_ID
              + "/methods/tracing", ServiceResource.class, //$NON-NLS-1$
              "serviceUndiscovered", "Removed host " + host); //$NON-NLS-1$ //$NON-NLS-2$
        }
        Trace.exiting(ModelPlugin.PLUGIN_ID, ModelPlugin.PLUGIN_ID
            + "/methods/exiting", ServiceResource.class, //$NON-NLS-1$
            "serviceUndiscovered", ecfEvent); //$NON-NLS-1$
      } catch (AssertionFailedException e) {
        Trace.catching(ModelPlugin.PLUGIN_ID, ModelPlugin.PLUGIN_ID
            + "/methods/tracing", ServiceResource.class, //$NON-NLS-1$
            "serviceUndiscovered", e); //$NON-NLS-1$
      } finally {
        lock.release();
      }
    }

    /*
     * (non-Javadoc)
     *
     * @see
     * org.eclipse.ecf.discovery.IServiceListener#serviceResolved(org.eclipse
     * .ecf.discovery.IServiceEvent)
     */
    public void serviceDiscovered(IServiceEvent ecfEvent) {
      try {
        lock.acquire();
        serviceDiscovered(ecfEvent.getServiceInfo());
      } finally {
        lock.release();
      }
    }

    private void serviceDiscovered(
        org.eclipse.ecf.discovery.IServiceInfo ecfServiceInfo) {
      Trace.entering(ModelPlugin.PLUGIN_ID, ModelPlugin.PLUGIN_ID
          + "/methods/entering", ServiceResource.class, //$NON-NLS-1$
          "serviceResolved", ecfServiceInfo); //$NON-NLS-1$
      String hostname = ecfServiceInfo.getLocation().getHost();
      if (hostname != null && findIServiceInfo(ecfServiceInfo) == null) { // so
        // far
        // we
        // only
        // support
        // uris
        // which
        // define
        // a
        // host
        IServiceInfo emfIServiceInfo = getIServiceInfo(ecfServiceInfo);
        Trace.trace(ModelPlugin.PLUGIN_ID, ModelPlugin.PLUGIN_ID
            + "/methods/tracing", ServiceResource.class, //$NON-NLS-1$
            "serviceResolved", "Service created " //$NON-NLS-1$ //$NON-NLS-2$
                + emfIServiceInfo);
        InetAddress inetAddress = getInetAddress(ecfServiceInfo
            .getLocation());
        if (inetAddress == null) {
          // ignore broken service
          return;
        }
        IHost host = findIHost(inetAddress);
        if (host == null) {
          host = getIHost(inetAddress);
          INetwork network = (INetwork) ServiceResource.this
              .getContents().get(0);
          network.getHosts().add(host);
          Trace.trace(ModelPlugin.PLUGIN_ID, ModelPlugin.PLUGIN_ID
              + "/methods/tracing", ServiceResource.class, //$NON-NLS-1$
              "serviceResolved", "Host created " //$NON-NLS-1$ //$NON-NLS-2$
                  + emfIServiceInfo);
        }
        host.getServices().add(emfIServiceInfo);
      }
      Trace.exiting(ModelPlugin.PLUGIN_ID, ModelPlugin.PLUGIN_ID
          + "/methods/exiting", ServiceResource.class, //$NON-NLS-1$
          "serviceResolved", ecfServiceInfo); //$NON-NLS-1$
    }

    private InetAddress getInetAddress(java.net.URI anURI) {
      String host = anURI.getHost();
      if (host != null) {
        try {
          return InetAddress.getByName(host);
        } catch (UnknownHostException e) {
          Trace.catching(ModelPlugin.PLUGIN_ID, ModelPlugin.PLUGIN_ID
              + "/methods/catching", ServiceResource.class, //$NON-NLS-1$
              "getInetAddress", e); //$NON-NLS-1$
        }
      }
      return null;
    }

    private class ECFServiceInfoComparator implements Comparator {

      /*
       * (non-Javadoc)
       *
       * @see java.util.Comparator#compare(java.lang.Object,
       * java.lang.Object)
       */
      public int compare(Object anObj1, Object anObj2) {
        if (anObj1 == anObj2) {
          return 0;
        }
        org.eclipse.ecf.discovery.IServiceInfo si1 = (org.eclipse.ecf.discovery.IServiceInfo) anObj1;
        org.eclipse.ecf.discovery.IServiceInfo si2 = (org.eclipse.ecf.discovery.IServiceInfo) anObj2;
        org.eclipse.ecf.discovery.identity.IServiceID sId1 = si1
            .getServiceID();
        org.eclipse.ecf.discovery.identity.IServiceID sId2 = si2
            .getServiceID();
        if (sId1.equals(sId2)) {
          return 0;
        }
        return -1;
      }
    }

    public boolean triggerDiscovery() {
      return false;
    }
  }

  public ServiceResource(URI uri) {
    super(uri);
  }

  /*
   * Javadoc copied from interface.
   */
  public synchronized void load(Map options) throws IOException {
    if (!isLoaded) {
      Notification notification = setLoaded(true);
      isLoading = true;

      if (errors != null) {
        errors.clear();
      }

      if (warnings != null) {
        warnings.clear();
      }
      try {
        INetwork network = ModelFactory.eINSTANCE.createINetwork();
        this.getContents().add(network);
        setModified(true);

        Job job = new Job("ServiceDiscoveryListener") { //$NON-NLS-1$

          /*
           * (non-Javadoc)
           *
           * @see
           * org.eclipse.core.runtime.jobs.Job#run(org.eclipse.core
           * .runtime.IProgressMonitor)
           */
          protected IStatus run(IProgressMonitor monitor) {
            ServiceDiscoveryListener sdl = new ServiceDiscoveryListener();
            sdl.connect();
            return Status.OK_STATUS;
          }
        };
        job.setSystem(true);
        job.schedule();
      } finally {
        isLoading = false;
        if (notification != null) {
          eNotify(notification);
        }
        setModified(false);
      }
    }
  }
}
TOP

Related Classes of org.eclipse.ecf.discovery.ui.model.resource.ServiceResource$ServiceDiscoveryListener$ECFServiceInfoComparator

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.