/******************************************************************************* * Copyright (c) 2012 Red Hat, Inc. * 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: * Red Hat initial API and implementation *******************************************************************************/ package org.eclipse.linuxtools.internal.profiling.launch.provider.launch; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; import java.util.Set; import java.util.SortedMap; import java.util.TreeMap; import java.util.TreeSet; import org.eclipse.cdt.launch.AbstractCLaunchDelegate; import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IResource; import org.eclipse.core.resources.ProjectScope; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IConfigurationElement; import org.eclipse.core.runtime.IExtensionPoint; import org.eclipse.core.runtime.Platform; import org.eclipse.core.runtime.preferences.ConfigurationScope; import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy; import org.eclipse.linuxtools.internal.profiling.launch.ProfileLaunchPlugin; import org.eclipse.linuxtools.internal.profiling.launch.provider.ProviderProfileConstants; import org.eclipse.linuxtools.profiling.launch.ProfileLaunchConfigurationTabGroup; import org.eclipse.linuxtools.profiling.launch.ProfileLaunchShortcut; import org.eclipse.ui.preferences.ScopedPreferenceStore; /** * This class has various methods to access relevant information from * the extension point defined by the schema : * * org.eclipse.linuxtools.profiling.launch.launchProvider * */ public class ProviderFramework { /** * Get a profiling launch shortcut that provides the specified type of profiling. This * looks through extensions of the extension point * <code>org.eclipse.linuxtools.profiling.launch.launchProvider</code> that have a * specific type attribute. * * @param type A profiling type (eg. memory, snapshot, timing, etc.) * @return a profiling launch shortcut that implements <code>ProfileLaunchShortcut</code> * and provides the necessary profiling type, or <code>null</code> if none could be found. * @since 1.2 */ public static ProfileLaunchShortcut getProfilingProvider(String type) { ArrayList<IConfigurationElement> configList = getOrderedConfigElements(type); for (IConfigurationElement config : configList) { try { Object obj = config.createExecutableExtension("shortcut"); //$NON-NLS-1$ if (obj instanceof ProfileLaunchShortcut) { return (ProfileLaunchShortcut) obj; } } catch (CoreException e) { // continue, other configuration may succeed } } return null; } /** * Get a profiling launch shortcut that is associated with the specified id. * This looks through extensions of the extension point * <code>org.eclipse.linuxtools.profiling.launch.launchProvider</code> * that have a specific id. * * @param id A unique identifier * @return a profiling launch shortcut that implements <code>ProfileLaunchShortcut</code> * and provides the necessary profiling type, or <code>null</code> if none could be found. * @since 1.2 */ public static ProfileLaunchShortcut getLaunchShortcutProviderFromId( String id) { IConfigurationElement[] configs = getConfigurationElements(); for (IConfigurationElement config : configs) { if (config.getName().equals("provider")) { //$NON-NLS-1$ String currentId = config.getAttribute("id"); //$NON-NLS-1$ String shortcut = config.getAttribute("shortcut"); //$NON-NLS-1$ if (currentId != null && shortcut != null && currentId.equals(id)) { try { Object obj = config .createExecutableExtension("shortcut"); //$NON-NLS-1$ if (obj instanceof ProfileLaunchShortcut) { return (ProfileLaunchShortcut) obj; } } catch (CoreException e) { // continue, perhaps another configuration will succeed } } } } return null; } /** * Get a launch configuration delegate that is associated with the specified id. * This looks through extensions of the extension point * <code>org.eclipse.linuxtools.profiling.launch.launchProvider</code> that * have a specific delegate attribute. * * @param id a unique identifier * @return a launch configuration delegate that implements * <code>AbstractCLaunchDelegate</code> , or <code>null</code> if * none could be found. * @since 1.2 */ public static AbstractCLaunchDelegate getConfigurationDelegateFromId( String id) { IConfigurationElement[] configs = getConfigurationElements(); for (IConfigurationElement config : configs) { if (config.getName().equals("provider")) { //$NON-NLS-1$ String currentId = config.getAttribute("id"); //$NON-NLS-1$ String tabgroup = config.getAttribute("delegate"); //$NON-NLS-1$ if (currentId != null && tabgroup != null && currentId.equals(id)) { try { Object obj = config .createExecutableExtension("delegate"); //$NON-NLS-1$ if (obj instanceof AbstractCLaunchDelegate) { return (AbstractCLaunchDelegate) obj; } } catch (CoreException e) { // continue, perhaps another configuration will succeed } } } } return null; } /** * Get id of highest priority profiling tabgroup launch configuration that * provides the type of profiling. This looks through extensions of the * <code>org.eclipse.linuxtools.profiling.launch.launchProvider</code> * extension point that have a specific type attribute. * * @param type A profiling type (eg. memory, snapshot, timing, etc.) * @return an id of the profiling launch shortcut that implements * <code>ProfileLaunchShortcut</code> and provides the necessary * profiling type, or <code>null</code> if none could be found. * @since 1.2 */ public static String getHighestProviderId(String type) { ArrayList<IConfigurationElement> list = getOrderedConfigElements(type); if (list.size() > 0) { return list.get(0).getAttribute("id"); //$NON-NLS-1$ } return null; } /** * Get map of all pairs of names and IDs of the specific provider type. This * looks through extensions of the extension point * <code>org.eclipse.linuxtools.profiling.launch.launchProvider</code> * that have a specific type. * * @param type A profiling type (eg. memory, snapshot, timing, etc.) * @return A <code>HashMap<String, String></code> of all pairs of names and IDs * of the specific type. * @since 1.2 */ public static HashMap<String, String> getProviderNamesForType(String type) { HashMap<String, String> ret = new HashMap<>(); IConfigurationElement[] configs = getConfigurationElements(); for (IConfigurationElement config : configs) { if (config.getName().equals("provider")) { //$NON-NLS-1$ String currentId = config.getAttribute("id"); //$NON-NLS-1$ String currentName = config.getAttribute("name"); //$NON-NLS-1$ String currentType = config.getAttribute("type"); //$NON-NLS-1$ if (currentType != null && type != null && currentType.equals(type) && currentName != null) { ret.put(currentName, currentId); } } } return ret; } /** * Get map of all pairs of names and IDs of profiling providers. This * looks through extensions of the extension point * <code>org.eclipse.linuxtools.profiling.launch.launchProvider</code>. * * @return A <code>SortedMap<String, String></code> of all pairs of names and IDs * of profiling providers. * @since 2.0 */ public static SortedMap<String, String> getAllProviderNames() { SortedMap<String, String> ret = new TreeMap<>(); IConfigurationElement[] configs = getConfigurationElements(); for (IConfigurationElement config : configs) { if (config.getName().equals("provider")) { //$NON-NLS-1$ String currentId = config.getAttribute("id"); //$NON-NLS-1$ String currentName = config.getAttribute("name"); //$NON-NLS-1$ if (currentName != null && currentId != null) { ret.put(currentName, currentId); } } } return ret; } /** * Get launch providers for a given type and order them with regards to highest priority first. * * @param type Type of launch providers requested. * @return Array of launch provider configuration elements in prioritized order * @since 1.2 */ public static ArrayList<IConfigurationElement> getOrderedConfigElements(String type) { IConfigurationElement[] configs = getConfigurationElements(); ArrayList<IConfigurationElement> configList = new ArrayList<>(); for (IConfigurationElement config : configs) { if (config.getName().equals("provider")) { //$NON-NLS-1$ String currentType = config.getAttribute("type"); //$NON-NLS-1$ if (currentType != null && currentType.equals(type)) { String priority = config.getAttribute("priority"); //$NON-NLS-1$ if (priority != null) { try { Integer.parseInt(priority); configList.add(config); } catch (NumberFormatException e) { // continue } } } } } Collections.sort(configList, (c1, c2) -> { int p1, p2; // If priority is not an int or is < 0, corresponding config has // lowest priority. try { p1 = Integer.parseInt(c1.getAttribute("priority")); //$NON-NLS-1$ if (p1 <= 0) { return 1; } } catch (NumberFormatException e1) { return 1; } try { p2 = Integer.parseInt(c2.getAttribute("priority")); //$NON-NLS-1$ if (p2 <= 0) { return -1; } } catch (NumberFormatException e2) { return -1; } return p1 < p2 ? -1 : 1; }); return configList; } /** * Helper method to return the list of extensions that contribute the the * provider framework. * @return All extensions that contribute to the provider framework. */ private static IConfigurationElement [] getConfigurationElements () { IExtensionPoint extPoint = Platform.getExtensionRegistry() .getExtensionPoint(ProfileLaunchPlugin.PLUGIN_ID, "launchProvider"); //$NON-NLS-1$ return extPoint.getConfigurationElements(); } /** * Get name of tool with plug-in id <code>id</code>. This looks through * extensions of the * <code>org.eclipse.linuxtools.profiling.launch.launchProvider</code> * extensions point. * @param id The id attribute requested. * @return The name of the tool if found. * * @since 2.0 */ public static String getProviderToolNameFromId(String id) { IConfigurationElement[] configs = getConfigurationElements(); for (IConfigurationElement config : configs) { if (config.getName().equals("provider")) { //$NON-NLS-1$ String currentId = config.getAttribute("id"); //$NON-NLS-1$ if (currentId != null && currentId.equals(id)) { return config.getAttribute("name"); //$NON-NLS-1$ } } } return null; } /** * Get content of attribute <code>attribute</code> from the launch provider * with id <code>toolId</code>. * * @param toolId String unique id of the tool. * @param attribute The attribute requested. * @return String description of tool. * @since 2.0 */ public static String getToolInformationFromId(String toolId, String attribute) { IConfigurationElement[] configs = getConfigurationElements(); for (IConfigurationElement config : configs) { if (config.getName().equals("provider")) { //$NON-NLS-1$ String currentId = config.getAttribute("id"); //$NON-NLS-1$ String currentToolDescription = config.getAttribute(attribute); if (currentId != null && currentToolDescription != null && currentId.equals(toolId)) { return currentToolDescription; } } } return null; } /** * Get a profiling tab that provides the specified type of profiling. This * looks through extensions of the extension point * <code>org.eclipse.linuxtools.profiling.launch.launchProvider</code> that have a * specific type attribute. * * @param type A profiling type (eg. memory, snapshot, timing, etc.) * @return a tab that implements <code>ProfileLaunchConfigurationTabGroup</code> * and provides the necessary profiling type, or <code>null</code> if none could be found. * @since 2.0 */ public static ProfileLaunchConfigurationTabGroup getTabGroupProvider(String type) { IConfigurationElement[] configs = getConfigurationElements(); for (IConfigurationElement config : configs) { if (config.getName().equals("provider")) { //$NON-NLS-1$ String currentType = config.getAttribute("type"); //$NON-NLS-1$ String shortcut = config.getAttribute("tabgroup"); //$NON-NLS-1$ if (currentType != null && shortcut != null && currentType.equals(type)) { try { Object obj = config .createExecutableExtension("tabgroup"); //$NON-NLS-1$ if (obj instanceof ProfileLaunchConfigurationTabGroup) { return (ProfileLaunchConfigurationTabGroup) obj; } } catch (CoreException e) { // continue, perhaps another configuration will succeed } } } } return null; } /** * Get a profiling tab that is associated with the specified id. * This looks through extensions of the extension point * <code>org.eclipse.linuxtools.profiling.launch.launchProvider</code> that have a * specific id. * * @param id A unique identifier * @return a tab that implements <code>ProfileLaunchConfigurationTabGroup</code> * and provides the necessary profiling type, or <code>null</code> if none could be found. * @since 2.0 */ public static ProfileLaunchConfigurationTabGroup getTabGroupProviderFromId( String id) { IConfigurationElement[] configs = getConfigurationElements(); for (IConfigurationElement config : configs) { if (config.getName().equals("provider")) { //$NON-NLS-1$ String currentId = config.getAttribute("id"); //$NON-NLS-1$ String tabgroup = config.getAttribute("tabgroup"); //$NON-NLS-1$ if (currentId != null && tabgroup != null && currentId.equals(id)) { try { Object obj = config .createExecutableExtension("tabgroup"); //$NON-NLS-1$ if (obj instanceof ProfileLaunchConfigurationTabGroup) { return (ProfileLaunchConfigurationTabGroup) obj; } } catch (CoreException e) { // continue, perhaps another configuration will succeed } } } } return null; } /** * Get all IDs of the specific type. This looks through extensions of * the extension point <code>org.eclipse.linuxtools.profiling.launch.launchProvider</code> * that have a specific type. * * @param type A profiling type (eg. memory, snapshot, timing, etc.) * @return A <code>String []</code> of all IDs of the specific type. * @since 2.0 */ public static String[] getProviderIdsForType(String type) { ArrayList<String> ret = new ArrayList<> (); IConfigurationElement[] configs = getConfigurationElements(); for (IConfigurationElement config : configs) { if (config.getName().equals("provider")) { //$NON-NLS-1$ String currentId = config.getAttribute("id"); //$NON-NLS-1$ String currentType = config.getAttribute("type"); //$NON-NLS-1$ if (currentType != null && type != null && currentType.equals(type)) { ret.add(currentId); } } } return ret.toArray(new String [] {}); } /** * Get all the profiling categories. This looks through extensions of * the extension point <code>org.eclipse.linuxtools.profiling.launch.launchProvider</code> * and stores the different categories found. * * @return A <code>String []</code> of all profiling categories. * @since 2.0 */ public static String[] getProviderCategories() { Set<String> ret = new TreeSet<> (); IConfigurationElement[] configs = getConfigurationElements(); for (IConfigurationElement config : configs) { if (config.getName().equals("provider")) { //$NON-NLS-1$ String currentType = config.getAttribute("type"); //$NON-NLS-1$ if (currentType != null) { ret.add(currentType); } } } return ret.toArray(new String [] {}); } /** * Get a provider id to run for the given profiling type. * * This first checks for a provider in the project properties if the project * can be found and has indicated that project preferences are to override * the workspace preferences. If no project is obtainable or the project * has not indicated override, then it looks at provider preferences. If these * are not set or the specified preference points to a non-installed provider, * it will look for the provider with the highest priority for the specified type. * If this fails, it will look for the default provider. * * @param wc The launch configuration. * @param type A profiling type * @return A provider id that contributes to the specified type * @since 2.0 */ public static String getProviderIdToRun(ILaunchConfigurationWorkingCopy wc, String type) { String providerId = null; // Look for a project first if (wc != null) { try { IResource[] resources = wc.getMappedResources(); if(resources != null){ for (int i = 0; i < resources.length; ++i) { IResource resource = resources[i]; if (resource instanceof IProject) { IProject project = (IProject)resource; ScopedPreferenceStore store = new ScopedPreferenceStore(new ProjectScope(project), ProviderProfileConstants.PLUGIN_ID); boolean use_project_settings = store.getBoolean(ProviderProfileConstants.USE_PROJECT_SETTINGS + type); if (use_project_settings) { String provider = store.getString(ProviderProfileConstants.PREFS_KEY + type); if (!provider.isEmpty()) providerId = provider; } } } } } catch (CoreException e) { e.printStackTrace(); } } // if no providerId specified for project, get one from the preferences if (providerId == null) { // Look in the preferences for a provider providerId = ConfigurationScope.INSTANCE.getNode( ProviderProfileConstants.PLUGIN_ID).get( ProviderProfileConstants.PREFS_KEY + type, ""); //$NON-NLS-1$ if (providerId.isEmpty() || getConfigurationDelegateFromId(providerId) == null) { // Get highest priority provider providerId = getHighestProviderId(type); } } return providerId; } }