diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/language/FileLanguageMappingPropertyPage.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/language/FileLanguageMappingPropertyPage.java index 677eadfadb3..99b7df56805 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/language/FileLanguageMappingPropertyPage.java +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/language/FileLanguageMappingPropertyPage.java @@ -11,6 +11,7 @@ package org.eclipse.cdt.internal.ui.language; import java.util.Map; +import java.util.Set; import java.util.TreeMap; import org.eclipse.core.resources.IFile; @@ -30,6 +31,7 @@ import org.eclipse.swt.widgets.Event; import org.eclipse.swt.widgets.Label; import org.eclipse.swt.widgets.Link; import org.eclipse.swt.widgets.Listener; +import org.eclipse.swt.widgets.MessageBox; import org.eclipse.swt.widgets.Table; import org.eclipse.swt.widgets.TableColumn; import org.eclipse.swt.widgets.TableItem; @@ -72,10 +74,7 @@ public class FileLanguageMappingPropertyPage extends PropertyPage { public FileLanguageMappingPropertyPage() { super(); fLanguages = LanguageManager.getInstance().getRegisteredLanguages(); - fLanguageIds = new TreeMap(); - for (int i = 0; i < fLanguages.length; i++) { - fLanguageIds.put(fLanguages[i].getId(), fLanguages[i]); - } + fLanguageIds = LanguageVerifier.computeAvailableLanguages(); } protected Control createContents(Composite parent) { @@ -201,6 +200,15 @@ public class FileLanguageMappingPropertyPage extends PropertyPage { ProjectLanguageConfiguration config = LanguageManager.getInstance().getLanguageConfiguration(project); + Set missingLanguages = LanguageVerifier.removeMissingLanguages(config, description, fLanguageIds); + if (missingLanguages.size() > 0) { + MessageBox messageBox = new MessageBox(getShell(), SWT.ICON_WARNING | SWT.OK); + messageBox.setText(PreferencesMessages.LanguageMappings_missingLanguageTitle); + String affectedLanguages = LanguageVerifier.computeAffectedLanguages(missingLanguages); + messageBox.setMessage(Messages.format(PreferencesMessages.FileLanguagesPropertyPage_missingLanguage, affectedLanguages)); + messageBox.open(); + } + String defaultLanguageId = config.getLanguageForFile(null, file); LanguageTableData defaultData = new LanguageTableData(null, defaultLanguageId ); defaultItem.setData(defaultData); diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/language/LanguageVerifier.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/language/LanguageVerifier.java new file mode 100644 index 00000000000..8c4e54a5170 --- /dev/null +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/language/LanguageVerifier.java @@ -0,0 +1,112 @@ +/******************************************************************************* + * Copyright (c) 2007 IBM Corporation 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: + * IBM Corporation - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.internal.ui.language; + +import java.util.Iterator; +import java.util.Map; +import java.util.Set; +import java.util.TreeMap; +import java.util.TreeSet; +import java.util.Map.Entry; + +import org.eclipse.cdt.core.language.ProjectLanguageConfiguration; +import org.eclipse.cdt.core.language.WorkspaceLanguageConfiguration; +import org.eclipse.cdt.core.model.ILanguage; +import org.eclipse.cdt.core.model.LanguageManager; +import org.eclipse.cdt.core.settings.model.ICConfigurationDescription; +import org.eclipse.cdt.core.settings.model.ICProjectDescription; + +/** + * Analyzes and repairs language mapping configurations. + */ +public class LanguageVerifier { + + public static Map computeAvailableLanguages() { + ILanguage[] registeredLanguages = LanguageManager.getInstance().getRegisteredLanguages(); + Map languages = new TreeMap(); + for (int i = 0; i < registeredLanguages.length; i++) { + languages.put(registeredLanguages[i].getId(), registeredLanguages[i]); + } + return languages; + } + + public static String computeAffectedLanguages(Set missingLanguages) { + Iterator languages = missingLanguages.iterator(); + StringBuffer buffer = new StringBuffer(); + while (languages.hasNext()) { + buffer.append('\n'); + buffer.append(languages.next()); + } + return buffer.toString(); + } + + public static Set removeMissingLanguages(ProjectLanguageConfiguration config, ICProjectDescription description, Map availableLanguages) { + Set missingLanguages = new TreeSet(); + + // Check file mappings + Iterator fileConfigurationMappings = config.getFileMappings().entrySet().iterator(); + while (fileConfigurationMappings.hasNext()) { + Entry entry = (Entry) fileConfigurationMappings.next(); + String path = (String) entry.getKey(); + Map configurationLanguageMappings = (Map) entry.getValue(); + Iterator mappings = configurationLanguageMappings.entrySet().iterator(); + while (mappings.hasNext()) { + Entry mapping = (Entry) mappings.next(); + String configurationId = (String) mapping.getKey(); + String languageId = (String) mapping.getValue(); + if (!availableLanguages.containsKey(languageId)) { + missingLanguages.add(languageId); + ICConfigurationDescription configuration = description.getConfigurationById(configurationId); + config.removeFileMapping(configuration, path); + } + } + } + + // Check content type mappings + Iterator configurationContentTypeMappings = config.getContentTypeMappings().entrySet().iterator(); + while (configurationContentTypeMappings.hasNext()) { + Entry entry = (Entry) configurationContentTypeMappings.next(); + String configurationId = (String) entry.getKey(); + Map contentTypeLanguageMappings = (Map) entry.getValue(); + Iterator mappings = contentTypeLanguageMappings.entrySet().iterator(); + while (mappings.hasNext()) { + Entry mapping = (Entry) mappings.next(); + String contentTypeId = (String) mapping.getKey(); + String languageId = (String) mapping.getValue(); + if (!availableLanguages.containsKey(languageId)) { + missingLanguages.add(languageId); + ICConfigurationDescription configuration = description.getConfigurationById(configurationId); + config.removeContentTypeMapping(configuration, contentTypeId); + } + } + } + + return missingLanguages; + } + + public static Set removeMissingLanguages(WorkspaceLanguageConfiguration config, Map availableLanguages) { + Set missingLanguages = new TreeSet(); + + // Check content type mappings + Iterator contentTypeMappings = config.getWorkspaceMappings().entrySet().iterator(); + while (contentTypeMappings.hasNext()) { + Entry entry = (Entry) contentTypeMappings.next(); + String contentTypeId = (String) entry.getKey(); + String languageId = (String) entry.getValue(); + if (!availableLanguages.containsKey(languageId)) { + missingLanguages.add(languageId); + config.removeWorkspaceMapping(contentTypeId); + } + } + + return missingLanguages; + } +} diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/language/ProjectLanguageMappingPropertyPage.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/language/ProjectLanguageMappingPropertyPage.java index 5abc293076c..b5aaee55a26 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/language/ProjectLanguageMappingPropertyPage.java +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/language/ProjectLanguageMappingPropertyPage.java @@ -10,6 +10,9 @@ *******************************************************************************/ package org.eclipse.cdt.internal.ui.language; +import java.util.Map; +import java.util.Set; + import org.eclipse.core.resources.IProject; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.content.IContentType; @@ -22,16 +25,20 @@ import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Control; import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Group; +import org.eclipse.swt.widgets.MessageBox; import org.eclipse.ui.dialogs.PropertyPage; import org.eclipse.cdt.core.CCorePlugin; import org.eclipse.cdt.core.language.ProjectLanguageConfiguration; import org.eclipse.cdt.core.language.WorkspaceLanguageConfiguration; +import org.eclipse.cdt.core.model.CoreModel; import org.eclipse.cdt.core.model.ILanguageMappingChangeEvent; import org.eclipse.cdt.core.model.ILanguageMappingChangeListener; import org.eclipse.cdt.core.model.LanguageManager; +import org.eclipse.cdt.core.settings.model.ICProjectDescription; import org.eclipse.cdt.internal.ui.preferences.PreferencesMessages; +import org.eclipse.cdt.internal.ui.util.Messages; public class ProjectLanguageMappingPropertyPage extends PropertyPage { @@ -107,6 +114,18 @@ public class ProjectLanguageMappingPropertyPage extends PropertyPage { try { LanguageManager manager = LanguageManager.getInstance(); fMappings = manager.getLanguageConfiguration(project); + + ICProjectDescription description = CoreModel.getDefault().getProjectDescription(project); + Map availableLanguages = LanguageVerifier.computeAvailableLanguages(); + Set missingLanguages = LanguageVerifier.removeMissingLanguages(fMappings, description, availableLanguages); + if (missingLanguages.size() > 0) { + MessageBox messageBox = new MessageBox(getShell(), SWT.ICON_WARNING | SWT.OK); + messageBox.setText(PreferencesMessages.LanguageMappings_missingLanguageTitle); + String affectedLanguages = LanguageVerifier.computeAffectedLanguages(missingLanguages); + messageBox.setMessage(Messages.format(PreferencesMessages.ProjectLanguagesPropertyPage_missingLanguage, affectedLanguages)); + messageBox.open(); + } + fMappingWidget.setMappings(fMappings.getContentTypeMappings()); } catch (CoreException e) { CCorePlugin.log(e); @@ -117,6 +136,17 @@ public class ProjectLanguageMappingPropertyPage extends PropertyPage { try { LanguageManager manager = LanguageManager.getInstance(); WorkspaceLanguageConfiguration workspaceMappings = manager.getWorkspaceLanguageConfiguration(); + + Map availableLanguages = LanguageVerifier.computeAvailableLanguages(); + Set missingLanguages = LanguageVerifier.removeMissingLanguages(workspaceMappings, availableLanguages); + if (missingLanguages.size() > 0) { + MessageBox messageBox = new MessageBox(getShell(), SWT.ICON_WARNING | SWT.OK); + messageBox.setText(PreferencesMessages.LanguageMappings_missingLanguageTitle); + String affectedLanguages = LanguageVerifier.computeAffectedLanguages(missingLanguages); + messageBox.setMessage(Messages.format(PreferencesMessages.WorkspaceLanguagesPreferencePage_missingLanguage, affectedLanguages)); + messageBox.open(); + } + fInheritedMappingWidget.setMappings(workspaceMappings.getWorkspaceMappings()); } catch (CoreException e) { CCorePlugin.log(e); diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/language/WorkspaceLanguageMappingPreferencePage.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/language/WorkspaceLanguageMappingPreferencePage.java index af57fac6b31..8670c0bfb16 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/language/WorkspaceLanguageMappingPreferencePage.java +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/language/WorkspaceLanguageMappingPreferencePage.java @@ -10,11 +10,16 @@ *******************************************************************************/ package org.eclipse.cdt.internal.ui.language; +import java.util.Map; +import java.util.Set; + import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.content.IContentType; import org.eclipse.jface.preference.PreferencePage; +import org.eclipse.swt.SWT; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.MessageBox; import org.eclipse.ui.IWorkbench; import org.eclipse.ui.IWorkbenchPreferencePage; @@ -23,6 +28,7 @@ import org.eclipse.cdt.core.language.WorkspaceLanguageConfiguration; import org.eclipse.cdt.core.model.LanguageManager; import org.eclipse.cdt.internal.ui.preferences.PreferencesMessages; +import org.eclipse.cdt.internal.ui.util.Messages; public class WorkspaceLanguageMappingPreferencePage extends PreferencePage implements IWorkbenchPreferencePage { @@ -35,14 +41,29 @@ public class WorkspaceLanguageMappingPreferencePage extends PreferencePage imple protected Control createContents(Composite parent) { try { - fMappings = LanguageManager.getInstance().getWorkspaceLanguageConfiguration(); - fMappingWidget.setMappings(fMappings.getWorkspaceMappings()); + fetchMappings(); } catch (CoreException e) { CCorePlugin.log(e); } return fMappingWidget.createContents(parent, PreferencesMessages.WorkspaceLanguagesPreferencePage_description); } + private void fetchMappings() throws CoreException { + fMappings = LanguageManager.getInstance().getWorkspaceLanguageConfiguration(); + + Map availableLanguages = LanguageVerifier.computeAvailableLanguages(); + Set missingLanguages = LanguageVerifier.removeMissingLanguages(fMappings, availableLanguages); + if (missingLanguages.size() > 0) { + MessageBox messageBox = new MessageBox(getShell(), SWT.ICON_WARNING | SWT.OK); + messageBox.setText(PreferencesMessages.LanguageMappings_missingLanguageTitle); + String affectedLanguages = LanguageVerifier.computeAffectedLanguages(missingLanguages); + messageBox.setMessage(Messages.format(PreferencesMessages.WorkspaceLanguagesPreferencePage_missingLanguage, affectedLanguages)); + messageBox.open(); + } + + fMappingWidget.setMappings(fMappings.getWorkspaceMappings()); + } + public void init(IWorkbench workbench) { } @@ -63,9 +84,7 @@ public class WorkspaceLanguageMappingPreferencePage extends PreferencePage imple protected void performDefaults() { super.performDefaults(); try { - LanguageManager manager = LanguageManager.getInstance(); - WorkspaceLanguageConfiguration config = manager.getWorkspaceLanguageConfiguration(); - fMappingWidget.setMappings(config.getWorkspaceMappings()); + fetchMappings(); } catch (CoreException e) { CCorePlugin.log(e); } diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/preferences/PreferencesMessages.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/preferences/PreferencesMessages.java index b1aa53e5f4b..bc2115bfca3 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/preferences/PreferencesMessages.java +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/preferences/PreferencesMessages.java @@ -193,7 +193,10 @@ public final class PreferencesMessages extends NLS { public static String CodeFormatterPreferencePage_title; public static String CodeFormatterPreferencePage_description; + public static String LanguageMappings_missingLanguageTitle; + public static String WorkspaceLanguagesPreferencePage_description; + public static String WorkspaceLanguagesPreferencePage_missingLanguage; public static String ProjectLanguagesPropertyPage_description; public static String ProjectLanguagesPropertyPage_configurationColumn; @@ -203,6 +206,7 @@ public final class PreferencesMessages extends NLS { public static String ProjectLanguagesPropertyPage_removeMappingButton; public static String ProjectLanguagesPropertyPage_inheritedWorkspaceMappingsGroup; public static String ProjectLanguagesPropertyPage_overriddenContentType; + public static String ProjectLanguagesPropertyPage_missingLanguage; public static String ContentTypeMappingsDialog_title; public static String ContentTypeMappingsDialog_configuration; @@ -220,7 +224,8 @@ public final class PreferencesMessages extends NLS { public static String FileLanguagesPropertyPage_description; public static String FileLanguagesPropertyPage_configurationColumn; public static String FileLanguagesPropertyPage_defaultMapping; - + public static String FileLanguagesPropertyPage_missingLanguage; + public static String CPluginPreferencePage_caption; public static String CPluginPreferencePage_structuralParseMode_label; public static String CPluginPreferencePage_note; diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/preferences/PreferencesMessages.properties b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/preferences/PreferencesMessages.properties index 9fa8e6b8e44..3540aa7fb64 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/preferences/PreferencesMessages.properties +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/preferences/PreferencesMessages.properties @@ -227,7 +227,10 @@ PathEntryVariablesBlock_removeVariableButton = &Remove # Language settings +LanguageMappings_missingLanguageTitle = Missing Languages + WorkspaceLanguagesPreferencePage_description = These settings are global to the entire workspace. They are overridden by project-specific language mappings. +WorkspaceLanguagesPreferencePage_missingLanguage = The workspace contains mappings to one or more languages that are not currently installed. References to these languages will be removed:\n{0} ProjectLanguagesPropertyPage_description = These settings are project-specific. The mappings listed here override workspace-wide language mappings. ProjectLanguagesPropertyPage_configurationColumn = Configuration @@ -237,6 +240,7 @@ ProjectLanguagesPropertyPage_addMappingButton = &Add... ProjectLanguagesPropertyPage_removeMappingButton = &Remove ProjectLanguagesPropertyPage_inheritedWorkspaceMappingsGroup = Language settings inherited from the workspace ProjectLanguagesPropertyPage_overriddenContentType = (Overridden) {0} +ProjectLanguagesPropertyPage_missingLanguage = This project contains mappings to one or more languages that are not currently installed. References to these languages will be removed:\n{0} ContentTypeMappingsDialog_title = Add Mapping ContentTypeMappingsDialog_configuration = Configuration @@ -254,6 +258,7 @@ FileLanguagesPropertyPage_inheritedFromWorkspace = Inherited from the workspace FileLanguagesPropertyPage_inheritedFromFile = Inherited from (Default) ({0}) FileLanguagesPropertyPage_configurationColumn = Configuration FileLanguagesPropertyPage_defaultMapping = (Default) +FileLanguagesPropertyPage_missingLanguage = This project contains files that are mapped to one or more languages that are not currently installed. References to these languages will be removed:\n{0} # Others ProposalFilterPreferencesUtil_defaultFilterName=