/****************************************************************************** * Copyright (C) 2005-2013 Fabio Zadrozny 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: * Fabio Zadrozny <fabiofz@gmail.com> - initial API and implementation * Haw-Bin Chai <hbchai@gmail.com> - ongoing maintenance * Hussain Bohra <hussain.bohra@tavant.com> - ongoing maintenance * Jonah Graham <jonah@kichwacoders.com> - ongoing maintenance ******************************************************************************/ package org.python.pydev.shared_core.utils; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; 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.IStatus; import org.eclipse.core.runtime.Platform; import org.python.pydev.shared_core.SharedCorePlugin; import org.python.pydev.shared_core.log.Log; public class BaseExtensionHelper { /** * 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; private static Map<String, IExtension[]> extensionsCache = new HashMap<String, IExtension[]>(); public static IExtension[] getExtensions(String type) { IExtension[] extensions = extensionsCache.get(type); if (extensions == null) { IExtensionRegistry registry = Platform.getExtensionRegistry(); if (registry != null) { // we may not be in eclipse env when testing try { IExtensionPoint extensionPoint = registry.getExtensionPoint(type); extensions = extensionPoint.getExtensions(); extensionsCache.put(type, extensions); } catch (Exception e) { Log.log(IStatus.ERROR, "Error getting extension for:" + type, e); throw new RuntimeException(e); } } else { extensions = new IExtension[0]; } } return extensions; } /** * @param type the name of the extension * @param allowOverride if true, the last registered participant will be * returned, thus "overriding" any previously * registered participants. If false, an exception * is thrown if more than one participant is * registered. * @return the participant for the given extension type, or null if none * is registered. */ public static Object getParticipant(String type, boolean allowOverride) { List<Object> participants = getParticipants(type); if (participants.isEmpty()) { return null; } if (!allowOverride && participants.size() > 1) { // only one participant may be used for this throw new RuntimeException("More than one participant is registered for type:" + type); } return participants.get(participants.size() - 1); } /** * @param type the extension we want to get * @return a list of classes created from those extensions */ public static List getParticipants(String type) { List<Object> list = null; if (SharedCorePlugin.inTestMode()) { if (testingParticipants != null) { list = testingParticipants.get(type); } if (list == null) { list = new ArrayList<Object>(); } return list; } list = new ArrayList<Object>(); // For each extension ... try { for (IExtension extension : getExtensions(type)) { IConfigurationElement[] elements = extension.getConfigurationElements(); // For each member of the extension ... for (IConfigurationElement element : elements) { try { list.add(element.createExecutableExtension("class")); } catch (Throwable e) { Log.log(e); } } } } catch (SecurityException e) { // Catch (and ignore) this error so that at least we can run some tests... // See bug: https://bugs.eclipse.org/bugs/show_bug.cgi?id=401098 // java.lang.SecurityException: class "org.eclipse.core.runtime.IExtension"'s signer information does not match signer information of other classes in the same package // at java.lang.ClassLoader.checkCerts(Unknown Source) // at java.lang.ClassLoader.preDefineClass(Unknown Source) // at java.lang.ClassLoader.defineClass(Unknown Source) // at java.security.SecureClassLoader.defineClass(Unknown Source) // at java.net.URLClassLoader.defineClass(Unknown Source) // at java.net.URLClassLoader.access$100(Unknown Source) // at java.net.URLClassLoader$1.run(Unknown Source) // at java.net.URLClassLoader$1.run(Unknown Source) // at java.security.AccessController.doPrivileged(Native Method) // at java.net.URLClassLoader.findClass(Unknown Source) // at java.lang.ClassLoader.loadClass(Unknown Source) // at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source) // at java.lang.ClassLoader.loadClass(Unknown Source) // at org.python.pydev.core.ExtensionHelper.getExtensions(ExtensionHelper.java:76) // at org.python.pydev.core.ExtensionHelper.getParticipants(ExtensionHelper.java:120) } return list; } }