Package org.erlide.util.services

Source Code of org.erlide.util.services.ExtensionUtils

package org.erlide.util.services;

import java.lang.reflect.Array;
import java.lang.reflect.GenericArrayType;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.List;
import java.util.Map;

import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IConfigurationElement;
import org.eclipse.core.runtime.IExtension;
import org.eclipse.core.runtime.IExtensionPoint;
import org.eclipse.core.runtime.IExtensionRegistry;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.RegistryFactory;
import org.erlide.util.ErlLogger;

import com.google.common.collect.Lists;

public final class ExtensionUtils {

    /**
     * Get an executable extension that has only one implementor. We do no hard
     * checks, but take the first one.
     */
    public static <T> T getSingletonExtension(final String id,
            final Class<? extends T> clazz) {
        final IExtensionRegistry reg = RegistryFactory.getRegistry();
        final IConfigurationElement[] elements = reg.getConfigurationElementsFor(id);
        if (elements.length > 1) {
            ErlLogger.warn("There are multiple implementors of extension %s! "
                    + "Picking one of them...", id);
        }
        for (final IConfigurationElement element : elements) {
            try {
                final Object object = element.createExecutableExtension("class");
                if (clazz.isInstance(object)) {
                    return clazz.cast(object);
                }
            } catch (final CoreException e) {
                e.printStackTrace();
                // for some reason, ErlLogger only is printed if the above is
                // here...
                ErlLogger.error(e);
            }
        }
        return null;
    }

    public static <T> Provider<? extends T> getSingletonProviderExtension(
            final String id, final Class<? extends Provider<? extends T>> clazz) {
        final IExtensionRegistry reg = RegistryFactory.getRegistry();
        final IConfigurationElement[] elements = reg.getConfigurationElementsFor(id);
        for (final IConfigurationElement element : elements) {
            try {
                final Object object = element.createExecutableExtension("provider");
                if (clazz.isInstance(object)) {
                    return clazz.cast(object);
                }
            } catch (final CoreException e) {
                ErlLogger.error(e);
            }
        }
        return null;
    }

    /**
     * Get the underlying class for a type, or null if the type is a variable
     * type.
     *
     * @param type
     *            the type
     * @return the underlying class
     */
    @SuppressWarnings("rawtypes")
    public static Class<?> getClass(final Type type) {
        if (type instanceof Class) {
            return (Class) type;
        } else if (type instanceof ParameterizedType) {
            return getClass(((ParameterizedType) type).getRawType());
        } else if (type instanceof GenericArrayType) {
            final Type componentType = ((GenericArrayType) type)
                    .getGenericComponentType();
            final Class<?> componentClass = getClass(componentType);
            if (componentClass != null) {
                return Array.newInstance(componentClass, 0).getClass();
            }
            return null;
        } else {
            return null;
        }
    }

    public static <T> List<T> getExtensions(final String id, final Class<T> clazz) {
        final List<T> result = Lists.newArrayList();
        final IExtensionRegistry reg = RegistryFactory.getRegistry();
        final IConfigurationElement[] elements = reg.getConfigurationElementsFor(id);
        for (final IConfigurationElement element : elements) {
            try {
                final Object object = element.createExecutableExtension("class");
                if (clazz.isInstance(object)) {
                    result.add(clazz.cast(object));
                }
            } catch (final CoreException e) {
                ErlLogger.error(e);
            }
        }
        return result;
    }

    /**
     * This should be used to add participants at test-time. It should be the
     * name of the extension point to a list (which will be returned)
     */
    public static Map<String, List<Object>> testingParticipants;

    public static IExtension[] getExtensions(final String type) {
        IExtension[] extensions;
        final IExtensionRegistry registry = Platform.getExtensionRegistry();
        // we may not be in eclipse env when testing
        if (registry != null) {
            try {
                final IExtensionPoint extensionPoint = registry.getExtensionPoint(type);
                extensions = extensionPoint.getExtensions();
            } catch (final Exception e) {
                ErlLogger.error("Error getting extension for:" + type + " -- "
                        + e.getMessage());
                throw new RuntimeException(e);
            }
        } else {
            extensions = new IExtension[0];
        }
        return extensions;
    }

    @SuppressWarnings("unchecked")
    public static Object getParticipant(final String type) {
        // only one participant may be used for this
        final List<Object> participants = (List<Object>) getParticipants(type);
        if (participants.size() == 1) {
            return participants.get(0);
        }
        if (participants.isEmpty()) {
            return null;
        }
        if (participants.size() > 1) {
            throw new RuntimeException(
                    "More than one participant is registered for type:" + type);
        }
        throw new RuntimeException("Should never get here!");
    }

    /**
     * @param type
     *            the extension we want to get
     * @return a list of classes created from those extensions
     */
    public static List<?> getParticipants(final String type) {
        if (testingParticipants != null) {
            return testingParticipants.get(type);
        }

        final List<Object> list = Lists.newArrayList();
        final IExtension[] extensions = getExtensions(type);
        // For each extension ...
        for (int i = 0; i < extensions.length; i++) {
            final IExtension extension = extensions[i];
            final IConfigurationElement[] elements = extension.getConfigurationElements();
            // For each member of the extension ...
            for (int j = 0; j < elements.length; j++) {
                final IConfigurationElement element = elements[j];

                try {
                    list.add(element.createExecutableExtension("class"));
                } catch (final Exception e) {
                    ErlLogger.warn(e);
                }
            }
        }
        return list;
    }

    private ExtensionUtils() {
    }

}
TOP

Related Classes of org.erlide.util.services.ExtensionUtils

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.