Package org.eclipse.ecf.internal.core

Source Code of org.eclipse.ecf.internal.core.ECFPlugin

/*******************************************************************************
* Copyright (c) 2004 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.internal.core;

import java.util.*;
import org.eclipse.core.runtime.*;
import org.eclipse.ecf.core.*;
import org.eclipse.ecf.core.provider.IContainerInstantiator;
import org.eclipse.ecf.core.start.ECFStartJob;
import org.eclipse.ecf.core.start.IECFStart;
import org.eclipse.ecf.core.util.*;
import org.eclipse.ecf.internal.core.identity.Activator;
import org.osgi.framework.*;
import org.osgi.service.log.LogService;
import org.osgi.util.tracker.ServiceTracker;
import org.osgi.util.tracker.ServiceTrackerCustomizer;

public class ECFPlugin implements BundleActivator {

  public static final String PLUGIN_ID = "org.eclipse.ecf"; //$NON-NLS-1$

  private static final String ECFNAMESPACE = PLUGIN_ID;

  private static final String CONTAINER_FACTORY_NAME = "containerFactory"; //$NON-NLS-1$

  private static final String CONTAINER_FACTORY_EPOINT = ECFNAMESPACE + "." + CONTAINER_FACTORY_NAME; //$NON-NLS-1$

  private static final String STARTUP_NAME = "start"; //$NON-NLS-1$

  public static final String START_EPOINT = ECFNAMESPACE + "." + STARTUP_NAME; //$NON-NLS-1$

  public static final String PLUGIN_RESOURCE_BUNDLE = ECFNAMESPACE + ".ECFPluginResources"; //$NON-NLS-1$

  public static final String CLASS_ATTRIBUTE = "class"; //$NON-NLS-1$

  public static final String NAME_ATTRIBUTE = "name"; //$NON-NLS-1$

  public static final String DESCRIPTION_ATTRIBUTE = "description"; //$NON-NLS-1$

  public static final String VALUE_ATTRIBUTE = "value"; //$NON-NLS-1$

  public static final String SERVER_ATTRIBUTE = "server"; //$NON-NLS-1$

  public static final String HIDDEN_ATTRIBUTE = "hidden"; //$NON-NLS-1$

  public static final String ASYNCH_ATTRIBUTE = "asynchronous"; //$NON-NLS-1$

  public static final String CONTAINER_NAME = "container"; //$NON-NLS-1$

  public static final String CONTAINER_EPOINT = ECFNAMESPACE + "." + CONTAINER_NAME; //$NON-NLS-1$

  public static final String FACTORY_ATTRIBUTE = "factoryName"; //$NON-NLS-1$

  public static final String ID_ATTRIBUTE = "containerId"; //$NON-NLS-1$

  public static final String PARAMETER_ELEMENT = "parameter"; //$NON-NLS-1$

  public static final String PARAMETER_NAME = "name"; //$NON-NLS-1$

  public static final String PARAMETER_VALUE = "value"; //$NON-NLS-1$

  // The shared instance.
  private static ECFPlugin plugin;

  BundleContext context = null;

  private Map disposables = new WeakHashMap();

  // This is Object rather than IExtensionRegistryManager to avoid loading
  // IRegistryChangeListener class (optional)
  Object registryManager = null;

  private ServiceRegistration containerFactoryServiceRegistration;

  private ServiceRegistration containerManagerServiceRegistration;

  private ServiceTracker logServiceTracker = null;

  private LogService logService = null;

  private AdapterManagerTracker adapterManagerTracker = null;

  private BundleActivator ecfTrustManager;

  /**
   * Returns the shared instance.
   * @return ECFPlugin
   */
  public synchronized static ECFPlugin getDefault() {
    if (plugin == null)
      plugin = new ECFPlugin();
    return plugin;
  }

  public ECFPlugin() {
    // null constructor
  }

  public void start(BundleContext ctxt) throws Exception {
    plugin = this;
    this.context = ctxt;

    // initialize the default ssl socket factory
    try {
      Class ecfSocketFactoryClass = Class.forName("org.eclipse.ecf.internal.ssl.ECFTrustManager"); //$NON-NLS-1$
      ecfTrustManager = (BundleActivator) ecfSocketFactoryClass.newInstance();
      ecfTrustManager.start(ctxt);
    } catch (ClassNotFoundException e) {
      // will occur if fragment is not installed or not on proper execution environment
    } catch (Throwable t) {
      log(new Status(IStatus.ERROR, getDefault().getBundle().getSymbolicName(), "Unexpected Error in ECFPlugin.start", t)); //$NON-NLS-1$
    }

    // initialize from ContainerTypeDescription services
    if (containerTypeDescriptionTracker == null) {
      containerTypeDescriptionTracker = new ServiceTracker(this.context, ContainerTypeDescription.class.getName(), new ServiceTrackerCustomizer() {
        public Object addingService(ServiceReference reference) {
          ContainerTypeDescription ctd = (ContainerTypeDescription) context.getService(reference);
          if (ctd != null && ctd.getName() != null)
            ContainerFactory.getDefault().addDescription(ctd);
          return ctd;
        }

        public void modifiedService(ServiceReference reference, Object service) {
          // nothing
        }

        public void removedService(ServiceReference reference, Object service) {
          IContainerFactory cf = ContainerFactory.getDefault();
          cf.removeDescription((ContainerTypeDescription) service);
        }
      });
      containerTypeDescriptionTracker.open();
    }

    SafeRunner.run(new ExtensionRegistryRunnable(this.context) {
      protected void runWithRegistry(IExtensionRegistry registry) throws Exception {
        if (registry != null) {
          registryManager = new IRegistryChangeListener() {
            public void registryChanged(IRegistryChangeEvent event) {
              final IExtensionDelta factoryDeltas[] = event.getExtensionDeltas(ECFNAMESPACE, CONTAINER_FACTORY_NAME);
              for (int i = 0; i < factoryDeltas.length; i++) {
                switch (factoryDeltas[i].getKind()) {
                  case IExtensionDelta.ADDED :
                    addContainerFactoryExtensions(factoryDeltas[i].getExtension().getConfigurationElements());
                    break;
                  case IExtensionDelta.REMOVED :
                    removeContainerFactoryExtensions(factoryDeltas[i].getExtension().getConfigurationElements());
                    break;
                }
              }
              final IExtensionDelta containerDeltas[] = event.getExtensionDeltas(ECFNAMESPACE, CONTAINER_NAME);
              for (int i = 0; i < containerDeltas.length; i++) {
                switch (containerDeltas[i].getKind()) {
                  case IExtensionDelta.ADDED :
                    addContainerExtensions(containerDeltas[i].getExtension().getConfigurationElements());
                    break;
                  case IExtensionDelta.REMOVED :
                    removeContainerExtensions(containerDeltas[i].getExtension().getConfigurationElements());
                    break;
                }
              }
            }
          };
          registry.addRegistryChangeListener((IRegistryChangeListener) registryManager);
        }
      }
    });

    // defer extension execution until first consumer calls
    final ServiceFactory sf = new ServiceFactory() {
      public Object getService(Bundle bundle, ServiceRegistration registration) {
        return ContainerFactory.getDefault();
      }

      public void ungetService(Bundle bundle, ServiceRegistration registration, Object service) {
        // NOP
      }
    };

    containerFactoryServiceRegistration = ctxt.registerService(IContainerFactory.class.getName(), sf, null);
    containerManagerServiceRegistration = ctxt.registerService(IContainerManager.class.getName(), sf, null);

    SafeRunner.run(new ExtensionRegistryRunnable(this.context) {
      protected void runWithRegistry(IExtensionRegistry registry) throws Exception {
        if (registry != null) {
          final IExtensionPoint extensionPoint = registry.getExtensionPoint(START_EPOINT);
          if (extensionPoint == null) {
            return;
          }
          IConfigurationElement[] configurationElements = extensionPoint.getConfigurationElements();
          final String method = "runStartExtensions"; //$NON-NLS-1$
          // For each configuration element
          for (int m = 0; m < configurationElements.length; m++) {
            final IConfigurationElement member = configurationElements[m];
            try {
              // The only required attribute is "class"
              boolean sync = (member.getAttribute(ASYNCH_ATTRIBUTE) == null);
              IECFStart clazz = (IECFStart) member.createExecutableExtension(CLASS_ATTRIBUTE);
              // Create job to do start, and schedule
              if (sync) {
                IStatus result = null;
                try {
                  result = clazz.run(new NullProgressMonitor());
                } catch (final Throwable e) {
                  final String message = "startup extension error"; //$NON-NLS-1$
                  logException(new Status(IStatus.ERROR, PLUGIN_ID, IStatus.ERROR, message, e), message, e);
                }
                if (result != null && !result.isOK())
                  logException(result, result.getMessage(), result.getException());
              } else {
                final ECFStartJob job = new ECFStartJob(clazz.getClass().getName(), clazz);
                job.schedule();
              }
            } catch (final CoreException e) {
              logException(e.getStatus(), method, e);
            } catch (final Exception e) {
              logException(new Status(IStatus.ERROR, getDefault().getBundle().getSymbolicName(), IStatus.ERROR, "Unknown start exception", e), method, e); //$NON-NLS-1$
            }
          }
        }
      }
    });

    SafeRunner.run(new ExtensionRegistryRunnable(this.context) {
      protected void runWithoutRegistry() throws Exception {
        ECFPlugin.this.context.registerService(ContainerTypeDescription.class, new ContainerTypeDescription(BaseContainer.Instantiator.NAME, new BaseContainer.Instantiator()), null);
      }
    });
  }

  private ServiceTracker containerTypeDescriptionTracker;

  public void initializeExtensions() {
    SafeRunner.run(new ExtensionRegistryRunnable(this.context) {
      protected void runWithRegistry(IExtensionRegistry registry) throws Exception {
        if (registry != null) {
          IExtensionPoint extensionPoint = registry.getExtensionPoint(CONTAINER_FACTORY_EPOINT);
          if (extensionPoint == null)
            return;
          addContainerFactoryExtensions(extensionPoint.getConfigurationElements());
          extensionPoint = registry.getExtensionPoint(CONTAINER_EPOINT);
          if (extensionPoint == null)
            return;
          addContainerExtensions(extensionPoint.getConfigurationElements());
        }
      }
    });
  }

  public void stop(BundleContext ctxt) throws Exception {
    fireDisposables();
    this.disposables = null;
    SafeRunner.run(new ExtensionRegistryRunnable(ctxt) {
      protected void runWithRegistry(IExtensionRegistry registry) throws Exception {
        if (registry != null)
          registry.removeRegistryChangeListener((IRegistryChangeListener) registryManager);
      }
    });
    this.registryManager = null;
    if (containerTypeDescriptionTracker != null) {
      containerTypeDescriptionTracker.close();
      containerTypeDescriptionTracker = null;
    }
    if (ecfTrustManager != null) {
      ecfTrustManager.stop(ctxt);
      ecfTrustManager = null;
    }
    if (logServiceTracker != null) {
      logServiceTracker.close();
      logServiceTracker = null;
      logService = null;
    }
    if (containerFactoryServiceRegistration != null) {
      containerFactoryServiceRegistration.unregister();
      containerFactoryServiceRegistration = null;
    }
    if (containerManagerServiceRegistration != null) {
      containerManagerServiceRegistration.unregister();
      containerManagerServiceRegistration = null;
    }
    if (adapterManagerTracker != null) {
      adapterManagerTracker.close();
      adapterManagerTracker = null;
    }
    this.context = null;
  }

  public void addDisposable(IDisposable disposable) {
    disposables.put(disposable, null);
  }

  public void removeDisposable(IDisposable disposable) {
    disposables.remove(disposable);
  }

  protected void fireDisposables() {
    for (final Iterator i = disposables.keySet().iterator(); i.hasNext();) {
      final IDisposable d = (IDisposable) i.next();
      if (d != null)
        d.dispose();
    }
  }

  public Bundle getBundle() {
    if (context == null)
      return null;
    return context.getBundle();
  }

  private LogService systemLogService;

  protected LogService getLogService() {
    if (context == null) {
      if (systemLogService == null)
        systemLogService = new SystemLogService(PLUGIN_ID);
      return systemLogService;
    }
    if (logServiceTracker == null) {
      logServiceTracker = new ServiceTracker(this.context, LogService.class.getName(), null);
      logServiceTracker.open();
    }
    logService = (LogService) logServiceTracker.getService();
    if (logService == null)
      logService = new SystemLogService(PLUGIN_ID);
    return logService;
  }

  public void log(IStatus status) {
    if (logService == null)
      logService = getLogService();
    if (logService != null)
      logService.log(LogHelper.getLogCode(status), LogHelper.getLogMessage(status), status.getException());
  }

  protected void logException(IStatus status, String method, Throwable exception) {
    log(status);
    Trace.catching(ECFPlugin.PLUGIN_ID, ECFDebugOptions.EXCEPTIONS_CATCHING, ECFPlugin.class, method, exception);
  }

  /**
   * Remove extensions for container factory extension point
   *
   * @param members
   *            the members to remove
   */
  protected void removeContainerFactoryExtensions(IConfigurationElement[] members) {
    final String method = "removeContainerFactoryExtensions"; //$NON-NLS-1$
    Trace.entering(ECFPlugin.PLUGIN_ID, ECFDebugOptions.METHODS_ENTERING, ECFPlugin.class, method, members);
    // For each configuration element
    for (int m = 0; m < members.length; m++) {
      final IConfigurationElement member = members[m];
      // Get the label of the extender plugin and the ID of the extension.
      final IExtension extension = member.getDeclaringExtension();
      String name = null;
      try {
        // Get name and get version, if available
        name = member.getAttribute(NAME_ATTRIBUTE);
        if (name == null) {
          name = member.getAttribute(CLASS_ATTRIBUTE);
        }
        final IContainerFactory factory = ContainerFactory.getDefault();
        final ContainerTypeDescription cd = factory.getDescriptionByName(name);
        if (cd == null || !factory.containsDescription(cd)) {
          continue;
        }
        // remove
        factory.removeDescription(cd);
        Trace.trace(ECFPlugin.PLUGIN_ID, ECFDebugOptions.DEBUG, method + ".removed " + cd + " from factory"); //$NON-NLS-1$ //$NON-NLS-2$
      } catch (final Exception e) {
        logException(new Status(IStatus.ERROR, getDefault().getBundle().getSymbolicName(), IStatus.ERROR, "ECF container factory with name=" + name + " already found. Ignoring registration for containerFactory extension point=" + extension.getExtensionPointUniqueIdentifier(), null), method, e); //$NON-NLS-1$//$NON-NLS-2$
      }
    }
  }

  void removeContainerExtensions(IConfigurationElement[] members) {
    final String method = "removeContainerExtensions"; //$NON-NLS-1$
    Trace.entering(ECFPlugin.PLUGIN_ID, ECFDebugOptions.METHODS_ENTERING, ECFPlugin.class, method, members);
    // For each configuration element
    for (int m = 0; m < members.length; m++) {
      final IConfigurationElement member = members[m];
      // The only required attribute is "factoryName"
      String factoryName = member.getAttribute(FACTORY_ATTRIBUTE);
      // Skip over if factory name is invalid
      if (factoryName == null || "".equals(factoryName))continue; //$NON-NLS-1$
      IContainerManager manager = (IContainerManager) ContainerFactory.getDefault();
      IContainer[] containers = manager.getAllContainers();
      if (containers == null)
        continue;
      for (int i = 0; i < containers.length; i++) {
        ContainerTypeDescription containerTypeDescription = manager.getContainerTypeDescription(containers[i].getID());
        if (containerTypeDescription != null && containerTypeDescription.getName().equals(factoryName)) {
          // Remove from manager
          IContainer removedContainer = manager.removeContainer(containers[i]);
          if (removedContainer != null) {
            try {
              containers[i].dispose();
            } catch (Exception e) {
              logException(new Status(IStatus.ERROR, PLUGIN_ID, IStatus.ERROR, "Unexpected exception disposing container with factoryName=" + factoryName + " and id=" + containers[i].getID(), null), method, e); //$NON-NLS-1$ //$NON-NLS-2$
            }
          }
        }
      }
    }
  }

  /**
   * Add container factory extension point extensions
   *
   * @param members
   *            to add
   */
  protected void addContainerFactoryExtensions(IConfigurationElement[] members) {
    final String method = "addContainerFactoryExtensions"; //$NON-NLS-1$
    Trace.entering(ECFPlugin.PLUGIN_ID, ECFDebugOptions.METHODS_ENTERING, ECFPlugin.class, method, members);
    final IContainerFactory factory = ContainerFactory.getDefault();
    // For each configuration element
    for (int m = 0; m < members.length; m++) {
      final IConfigurationElement member = members[m];
      // Get the label of the extender plugin and the ID of the extension.
      final IExtension extension = member.getDeclaringExtension();
      Object exten = null;
      String name = null;
      try {
        // Get value of containerFactory name attribute
        name = member.getAttribute(NAME_ATTRIBUTE);
        if (name != null) {
          ContainerTypeDescription ctd = factory.getDescriptionByName(name);
          // If we've got one already by this name, then we skip this new one
          if (ctd != null) {
            // log with warning
            log(new Status(IStatus.WARNING, Activator.PLUGIN_ID, "Factory already has container type description with name=" + name + ".  Ignoring extension from " + member.getContributor().getName())); //$NON-NLS-1$ //$NON-NLS-2$
            // and continue
            continue;
          }
        }
        // The only required attribute is "class"
        exten = member.createExecutableExtension(CLASS_ATTRIBUTE);
        final String clazz = exten.getClass().getName();

        if (name == null) {
          name = clazz;
        }

        // Get description, if present
        String description = member.getAttribute(DESCRIPTION_ATTRIBUTE);
        if (description == null) {
          description = ""; //$NON-NLS-1$
        }

        String s = member.getAttribute(SERVER_ATTRIBUTE);
        final boolean server = (s == null) ? false : Boolean.valueOf(s).booleanValue();
        s = member.getAttribute(HIDDEN_ATTRIBUTE);
        final boolean hidden = (s == null) ? false : Boolean.valueOf(s).booleanValue();

        // Now make description instance
        final ContainerTypeDescription scd = new ContainerTypeDescription(name, (IContainerInstantiator) exten, description, server, hidden);

        if (factory.containsDescription(scd)) {
          log(new Status(IStatus.WARNING, Activator.PLUGIN_ID, "Factory already has container type description=" + scd + ".  Ignoring extension from " + member.getContributor().getName())); //$NON-NLS-1$ //$NON-NLS-2$
          continue;
        }
        // Now add the description and we're ready to go.
        factory.addDescription(scd);
        Trace.trace(ECFPlugin.PLUGIN_ID, ECFDebugOptions.DEBUG, method + ".added " + scd + " to factory " + factory); //$NON-NLS-1$ //$NON-NLS-2$
      } catch (final CoreException e) {
        logException(e.getStatus(), method, e);
      } catch (final Exception e) {
        logException(new Status(IStatus.ERROR, getDefault().getBundle().getSymbolicName(), IStatus.ERROR, "ECF container factory with name=" + name + " already found. Ignoring registration for containerFactory extension point=" + extension.getExtensionPointUniqueIdentifier(), null), method, e); //$NON-NLS-1$ //$NON-NLS-2$
      }
    }
  }

  void addContainerExtensions(IConfigurationElement[] members) {
    final String method = "addContainerExtensions"; //$NON-NLS-1$
    Trace.entering(ECFPlugin.PLUGIN_ID, ECFDebugOptions.METHODS_ENTERING, ECFPlugin.class, method, members);
    // For each configuration element
    for (int m = 0; m < members.length; m++) {
      final IConfigurationElement member = members[m];
      String factory = null;
      String id = null;
      try {
        // The only required attribute is "factoryName"
        factory = member.getAttribute(FACTORY_ATTRIBUTE);
        // Skip over if factory name is invalid
        if (factory == null || "".equals(factory))continue; //$NON-NLS-1$
        // get id attribute
        id = member.getAttribute(ID_ATTRIBUTE);
        id = (id == null || "".equals(id)) ? null : id; //$NON-NLS-1$
        Map parameters = getParametersForContainer(member);
        ContainerFactory.getDefault().createContainer(factory, id, parameters);
        Trace.trace(ECFPlugin.PLUGIN_ID, ECFDebugOptions.DEBUG, method + ".added container with factoryName=" + factory + " and id=" + id); //$NON-NLS-1$ //$NON-NLS-2$
      } catch (final CoreException e) {
        logException(e.getStatus(), method, e);
      } catch (final Exception e) {
        logException(new Status(IStatus.ERROR, PLUGIN_ID, IStatus.ERROR, "Unexpected exception creating container with factoryName=" + factory + " and id=" + id, null), method, e); //$NON-NLS-1$ //$NON-NLS-2$
      }
    }
  }

  Map getParametersForContainer(IConfigurationElement member) {
    IConfigurationElement[] elements = member.getChildren(PARAMETER_ELEMENT);
    if (elements == null)
      return null;
    Map results = null;
    for (int i = 0; i < elements.length; i++) {
      String name = elements[i].getAttribute(PARAMETER_NAME);
      String value = elements[i].getAttribute(PARAMETER_VALUE);
      if (name != null && !"".equals(name) && value != null && !"".equals(value)) { //$NON-NLS-1$ //$NON-NLS-2$
        if (results == null)
          results = new Properties();
        results.put(name, value);
      }
    }
    return results;
  }

  public IAdapterManager getAdapterManager() {
    if (context == null)
      return null;
    // First, try to get the adapter manager via
    if (adapterManagerTracker == null) {
      adapterManagerTracker = new AdapterManagerTracker(this.context);
      adapterManagerTracker.open();
    }
    return adapterManagerTracker.getAdapterManager();
  }

}
TOP

Related Classes of org.eclipse.ecf.internal.core.ECFPlugin

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.