/*******************************************************************************
* Copyright (c) 2009, 2013 Andrew Gvozdev 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:
* Andrew Gvozdev - initial API and implementation
* Sergey Prigogin (Google)
*******************************************************************************/
package org.eclipse.cdt.core.language.settings.providers;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.eclipse.cdt.core.CCorePlugin;
import org.eclipse.cdt.core.model.CoreModel;
import org.eclipse.cdt.core.settings.model.ICConfigurationDescription;
import org.eclipse.cdt.core.settings.model.ICProjectDescription;
import org.eclipse.cdt.internal.core.LocalProjectScope;
import org.eclipse.cdt.internal.core.language.settings.providers.ReferencedProjectsLanguageSettingsProvider;
import org.eclipse.cdt.internal.core.language.settings.providers.ScannerInfoExtensionLanguageSettingsProvider;
import org.eclipse.cdt.internal.core.model.PathEntryManager;
import org.eclipse.cdt.internal.core.settings.model.CProjectDescriptionManager;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.runtime.preferences.InstanceScope;
import org.osgi.service.prefs.BackingStoreException;
import org.osgi.service.prefs.Preferences;
/**
* Collection of utilities for legacy support of older Scanner Discovery functionality.
* This class is temporary and not intended to be used by clients.
*
* @noextend This class is not intended to be subclassed by clients.
* @noinstantiate This class is not intended to be instantiated by clients.
*
* @since 5.4
*/
public class ScannerDiscoveryLegacySupport {
/** ID of User language settings provider (from org.eclipse.cdt.ui) */
public static final String USER_LANGUAGE_SETTINGS_PROVIDER_ID = "org.eclipse.cdt.ui.UserLanguageSettingsProvider"; //$NON-NLS-1$
/** ID of MBS language settings provider (from org.eclipse.cdt.managedbuilder.core) */
public static final String MBS_LANGUAGE_SETTINGS_PROVIDER_ID = "org.eclipse.cdt.managedbuilder.core.MBSLanguageSettingsProvider"; //$NON-NLS-1$
/**
* ID of ScannerInfo language settings provider wrapping ScannerInfoProvider defined by org.eclipse.cdt.core.ScannerInfoProvider extension point
* @since 5.5
*/
public static final String SI_LANGUAGE_SETTINGS_PROVIDER_ID = "org.eclipse.cdt.core.LegacyScannerInfoLanguageSettingsProvider"; //$NON-NLS-1$
/**
* ID of language settings provider wrapping {@link org.eclipse.cdt.core.resources.ScannerProvider} of {@link PathEntryManager} for 3.X projects
* @since 5.5
*/
public static final String PATH_ENTRY_MANAGER_LANGUAGE_SETTINGS_PROVIDER_ID = "org.eclipse.cdt.core.PathEntryScannerInfoLanguageSettingsProvider"; //$NON-NLS-1$
private static String DISABLE_LSP_PREFERENCE = "language.settings.providers.disabled"; //$NON-NLS-1$
private static boolean DISABLE_LSP_DEFAULT_PROJECT = false;
private static boolean DISABLE_LSP_DEFAULT_WORKSPACE = false;
private static final String PREFERENCES_QUALIFIER_CCORE = CCorePlugin.PLUGIN_ID;
private static Map<String, String> legacyProfiles = null;
/**
* Get preferences node for org.eclipse.cdt.core.
*
* @param project - project to get preferences or {@code null} for workspace preferences
* @return
*/
private static Preferences getPreferences(IProject project) {
if (project == null) {
return InstanceScope.INSTANCE.getNode(PREFERENCES_QUALIFIER_CCORE);
} else {
return new LocalProjectScope(project).getNode(PREFERENCES_QUALIFIER_CCORE);
}
}
/**
* Checks if Language Settings functionality is defined for given project in preferences.
*
* @param project - project to check the preference or {@code null} for workspace preference
* @return {@code true} if functionality is defined
*
* @noreference This method is temporary and not intended to be referenced by clients.
*
* @since 5.5
*/
public static boolean isLanguageSettingsProvidersFunctionalityDefined(IProject project) {
Preferences pref = getPreferences(project);
String value = pref.get(DISABLE_LSP_PREFERENCE, null);
return value != null;
}
/**
* Checks if Language Settings functionality is enabled for given project.
* Note that disabling on workspace level will disable it for all projects.
*
* @param project - project to check the preference or {@code null} for workspace preference
* @return {@code true} if functionality is enabled
*
* @noreference This method is temporary and not intended to be referenced by clients.
*/
public static boolean isLanguageSettingsProvidersFunctionalityEnabled(IProject project) {
boolean isEnabledInWorkspace = !getPreferences(null).getBoolean(DISABLE_LSP_PREFERENCE, DISABLE_LSP_DEFAULT_WORKSPACE);
if (isEnabledInWorkspace && project != null) {
return !getPreferences(project).getBoolean(DISABLE_LSP_PREFERENCE, DISABLE_LSP_DEFAULT_PROJECT);
}
return isEnabledInWorkspace;
}
/**
* Enable/disable Language Settings functionality for the given project.
*
* @param project or {@code null} for workspace preference
* @param value {@code true} to enable or {@code false} to disable the functionality.
*
* @noreference This method is temporary and not intended to be referenced by clients.
*/
public static void setLanguageSettingsProvidersFunctionalityEnabled(IProject project, boolean value) {
Preferences pref = getPreferences(project);
if (value == isLanguageSettingsProvidersFunctionalityEnabled(project))
return;
pref.putBoolean(DISABLE_LSP_PREFERENCE, !value);
// Scanner info provider have changed - clear the cached copy (http://bugs.eclipse.org/413357).
CCorePlugin.getDefault().resetCachedScannerInfoProvider(project);
try {
pref.flush();
} catch (BackingStoreException e) {
CCorePlugin.log(e);
}
}
/**
* Check if legacy Scanner Discovery in MBS should be active.
* @noreference This is internal helper method to support compatibility with previous versions
* which is not intended to be referenced by clients.
*/
public static boolean isMbsLanguageSettingsProviderOn(ICConfigurationDescription cfgDescription) {
if (cfgDescription instanceof ILanguageSettingsProvidersKeeper) {
List<ILanguageSettingsProvider> lsProviders = ((ILanguageSettingsProvidersKeeper) cfgDescription).getLanguageSettingProviders();
for (ILanguageSettingsProvider lsp : lsProviders) {
if (MBS_LANGUAGE_SETTINGS_PROVIDER_ID.equals(lsp.getId())) {
return true;
}
}
}
return false;
}
/**
* Check if legacy Scanner Discovery should be active.
* which is not intended to be referenced by clients.
*/
private static boolean isLegacyProviderOn(ICConfigurationDescription cfgDescription) {
if (cfgDescription instanceof ILanguageSettingsProvidersKeeper) {
List<ILanguageSettingsProvider> lsProviders = ((ILanguageSettingsProvidersKeeper) cfgDescription).getLanguageSettingProviders();
for (ILanguageSettingsProvider lsp : lsProviders) {
String id = lsp.getId();
if (MBS_LANGUAGE_SETTINGS_PROVIDER_ID.equals(id) || SI_LANGUAGE_SETTINGS_PROVIDER_ID.equals(id) || PATH_ENTRY_MANAGER_LANGUAGE_SETTINGS_PROVIDER_ID.equals(id)) {
return true;
}
}
}
return false;
}
/**
* @noreference This is internal helper method to support compatibility with previous versions
* which is not intended to be referenced by clients.
*/
public static boolean isLegacyScannerDiscoveryOn(ICConfigurationDescription cfgDescription) {
IProject project = null;
if (cfgDescription != null) {
ICProjectDescription prjDescription = cfgDescription.getProjectDescription();
if (prjDescription != null) {
project = prjDescription.getProject();
}
}
return !isLanguageSettingsProvidersFunctionalityEnabled(project) || isLegacyProviderOn(cfgDescription);
}
/**
* @noreference This is internal helper method to support compatibility with previous versions
* which is not intended to be referenced by clients.
*/
public static boolean isLegacyScannerDiscoveryOn(IProject project) {
ICConfigurationDescription cfgDescription = null;
ICProjectDescription prjDescription = CoreModel.getDefault().getProjectDescription(project);
if (prjDescription != null) {
cfgDescription = prjDescription.getActiveConfiguration();
}
return !isLanguageSettingsProvidersFunctionalityEnabled(project) || isLegacyProviderOn(cfgDescription);
}
/**
* Return list containing User provider and one of wrapper providers to support legacy projects (backward compatibility).
*
* @noreference This is internal helper method to support compatibility with previous versions
* which is not intended to be referenced by clients.
* @since 5.5
*/
public static String[] getDefaultProviderIdsLegacy(ICConfigurationDescription cfgDescription) {
boolean useScannerInfoProviderExtension = new ScannerInfoExtensionLanguageSettingsProvider().getScannerInfoProvider(cfgDescription) != null;
String legacyProviderId;
if (useScannerInfoProviderExtension) {
legacyProviderId = SI_LANGUAGE_SETTINGS_PROVIDER_ID;
} else if (CProjectDescriptionManager.getInstance().isNewStyleCfg(cfgDescription)) {
legacyProviderId = MBS_LANGUAGE_SETTINGS_PROVIDER_ID;
} else {
legacyProviderId = PATH_ENTRY_MANAGER_LANGUAGE_SETTINGS_PROVIDER_ID;
}
return new String[] {USER_LANGUAGE_SETTINGS_PROVIDER_ID, ReferencedProjectsLanguageSettingsProvider.ID, legacyProviderId};
}
/**
* Checks if the provider is applicable for configuration from backward compatibility point of view
*
* @noreference This is internal helper method to support compatibility with previous versions
* which is not intended to be referenced by clients.
* @since 5.5
*/
public static boolean isProviderCompatible(String providerId, ICConfigurationDescription cfgDescription) {
if (cfgDescription != null) {
boolean useScannerInfoProviderExtension = new ScannerInfoExtensionLanguageSettingsProvider().getScannerInfoProvider(cfgDescription) != null;
if (SI_LANGUAGE_SETTINGS_PROVIDER_ID.equals(providerId)) {
return useScannerInfoProviderExtension;
}
boolean isNewStyleCfg = CProjectDescriptionManager.getInstance().isNewStyleCfg(cfgDescription);
if (MBS_LANGUAGE_SETTINGS_PROVIDER_ID.equals(providerId)) {
return !useScannerInfoProviderExtension && isNewStyleCfg;
}
if (PATH_ENTRY_MANAGER_LANGUAGE_SETTINGS_PROVIDER_ID.equals(providerId)) {
return !useScannerInfoProviderExtension && !isNewStyleCfg;
}
}
return true;
}
/**
* If not defined yet, define property that controls if language settings providers functionality enabled for a given project.
* Workspace preference is checked and the project property is set to match it.
*
* @param project - project to define enablement.
* @since 5.5
*/
public static void defineLanguageSettingsEnablement(IProject project) {
if (project != null && ! ScannerDiscoveryLegacySupport.isLanguageSettingsProvidersFunctionalityDefined(project)) {
boolean isPreferenceEnabled = ScannerDiscoveryLegacySupport.isLanguageSettingsProvidersFunctionalityEnabled(null);
ScannerDiscoveryLegacySupport.setLanguageSettingsProvidersFunctionalityEnabled(project, isPreferenceEnabled);
}
}
/**
* Returns the values of scanner discovery profiles (scannerConfigDiscoveryProfileId) which were deprecated
* and replaced with language settings providers in plugin.xml.
* This (temporary) function serves as fail-safe switch during the transition.
*
* @param id - can be id of either org.eclipse.cdt.managedbuilder.internal.core.InputType
* or org.eclipse.cdt.managedbuilder.internal.core.ToolChain.
* @return legacy scannerConfigDiscoveryProfileId.
*/
@SuppressWarnings("nls")
public static String getDeprecatedLegacyProfiles(String id) {
if (legacyProfiles == null) {
legacyProfiles = new HashMap<String, String>();
// InputTypes
legacyProfiles.put("cdt.managedbuild.tool.gnu.c.compiler.input", "org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileC|org.eclipse.cdt.make.core.GCCStandardMakePerFileProfile");
legacyProfiles.put("cdt.managedbuild.tool.gnu.cpp.compiler.input", "org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileCPP|org.eclipse.cdt.make.core.GCCStandardMakePerFileProfile");
legacyProfiles.put("cdt.managedbuild.tool.gnu.c.compiler.input.cygwin", "org.eclipse.cdt.managedbuilder.core.GCCWinManagedMakePerProjectProfileC");
legacyProfiles.put("cdt.managedbuild.tool.gnu.cpp.compiler.input.cygwin", "org.eclipse.cdt.managedbuilder.core.GCCWinManagedMakePerProjectProfileCPP");
legacyProfiles.put("cdt.managedbuild.tool.xlc.c.compiler.input", "org.eclipse.cdt.managedbuilder.xlc.core.XLCManagedMakePerProjectProfile");
legacyProfiles.put("cdt.managedbuild.tool.xlc.cpp.c.compiler.input", "org.eclipse.cdt.managedbuilder.xlc.core.XLCManagedMakePerProjectProfile");
legacyProfiles.put("cdt.managedbuild.tool.xlc.cpp.compiler.input", "org.eclipse.cdt.managedbuilder.xlc.core.XLCManagedMakePerProjectProfileCPP");
// Toolchains
}
return legacyProfiles.get(id);
}
}