/*******************************************************************************
* Copyright (c) 2007, 2009 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.core.language;
import java.util.Collections;
import java.util.Iterator;
import java.util.Map;
import java.util.TreeMap;
import java.util.Map.Entry;
import org.eclipse.cdt.core.settings.model.ICConfigurationDescription;
import org.eclipse.core.resources.IFile;
/**
* Provides programmatic access to language mappings for a project.
*
* <p>
* <strong>EXPERIMENTAL</strong>. This class or interface has been added as
* part of a work in progress. There is no guarantee that this API will work or
* that it will remain the same. Please do not use this API without consulting
* with the CDT team.
* </p>
*
* @since 4.0
* @noextend This class is not intended to be subclassed by clients.
* @noinstantiate This class is not intended to be instantiated by clients.
*/
public class ProjectLanguageConfiguration {
private static final String ALL_CONFIGURATIONS = ""; //$NON-NLS-1$
/**
* Project-wide content type mappings (Configuration ID -> (Content Type ID -> Language ID)).
*/
private Map<String,Map<String,String>> fConfigurationContentTypeMappings;
/**
* Per-file mappings (Path -> (Configuration ID -> Language ID)).
*/
private Map<String,Map<String,String>> fFileConfigurationMappings;
/**
* Creates a new <code>ProjectLanguageConfiguration</code> with no
* language mappings defined.
*/
public ProjectLanguageConfiguration() {
fConfigurationContentTypeMappings = new TreeMap<String, Map<String, String>>();
fFileConfigurationMappings = new TreeMap<String, Map<String, String>>();
}
/**
* Returns the language id that is mapped to the given content type when
* the given configuration is active.
* If <code>configuration</code> is <code>null</code>, the configuration-agnostic
* mapping is returned.
* @return the language id that is mapped to the given content type.
*/
public String getLanguageForContentType(ICConfigurationDescription configuration, String contentTypeId) {
String configurationId = getId(configuration);
Map<String, String> contentTypeMappings = fConfigurationContentTypeMappings.get(configurationId);
if (contentTypeMappings == null) {
return null;
}
return contentTypeMappings.get(contentTypeId);
}
/**
* Returns the language id that is mapped to the given file when the given
* configuration is active.
* If <code>configuration</code> is <code>null</code>, the configuration-agnostic
* mapping is returned.
* @return the language id that is mapped to the given file
*/
public String getLanguageForFile(ICConfigurationDescription configuration, IFile file) {
return getLanguageForFile(configuration, file.getProjectRelativePath().toPortableString());
}
/**
* Returns the language id that is mapped to the file located at the given path
* when the given configuration is active.
* If <code>configuration</code> is <code>null</code>, the configuration-agnostic
* mapping is returned.
* @param path
* @return the language id that is mapped to the file located at the given path
*/
public String getLanguageForFile(ICConfigurationDescription configuration, String path) {
Map<String, String> configurationMappings = fFileConfigurationMappings.get(path);
if (configurationMappings == null) {
return null;
}
String configurationId = getId(configuration);
return configurationMappings.get(configurationId);
}
/**
* Sets the language for a content type.
* If <code>configuration</code> is not <code>null</code>, the language mapping
* will only apply when that configuration is active. Otherwise, the mapping
* will apply for all configurations.
* @param contentType
* @param language
*/
public void addContentTypeMapping(ICConfigurationDescription configuration, String contentType, String language) {
String configurationId = getId(configuration);
Map<String, String> contentTypeMappings = fConfigurationContentTypeMappings.get(configurationId);
if (contentTypeMappings == null) {
contentTypeMappings = new TreeMap<String, String>();
fConfigurationContentTypeMappings.put(configurationId, contentTypeMappings);
}
contentTypeMappings.put(contentType, language);
}
/**
* Removes the given content type mapping (if it exists).
* If <code>configuration</code> is <code>null</code>, the configuration-agnostic
* mapping is removed. Otherwise, the configuration-specific mapping is removed.
* @param contentType
*/
public void removeContentTypeMapping(ICConfigurationDescription configuration, String contentType) {
String configurationId = getId(configuration);
Map<String, String> contentTypeMappings = fConfigurationContentTypeMappings.get(configurationId);
if (contentTypeMappings == null) {
return;
}
contentTypeMappings.remove(contentType);
if (contentTypeMappings.size() == 0) {
fConfigurationContentTypeMappings.remove(configurationId);
}
}
/**
* Sets the language for a file.
* If <code>configuration</code> is not <code>null</code>, the language mapping
* will only apply when that configuration is active. Otherwise, the mapping
* will apply for all configurations.
* @param file
* @param language
*/
public void addFileMapping(ICConfigurationDescription configuration, IFile file, String language) {
addFileMapping(configuration, file.getProjectRelativePath().toPortableString(), language);
}
/**
* Sets the language for a file.
* If <code>configuration</code> is not <code>null</code>, the language mapping
* will only apply when that configuration is active. Otherwise, the mapping
* will apply for all configurations.
* @param filePath
* @param language
*/
public void addFileMapping(ICConfigurationDescription configuration, String filePath, String language) {
Map<String, String> configurationMappings = fFileConfigurationMappings.get(filePath);
if (configurationMappings == null) {
configurationMappings = new TreeMap<String, String>();
fFileConfigurationMappings.put(filePath, configurationMappings);
}
String configurationId = getId(configuration);
configurationMappings.put(configurationId, language);
}
/**
* Removes the given file mapping (if it exists).
* If <code>configuration</code> is <code>null</code>, the configuration-agnostic
* mapping is removed. Otherwise, the configuration-specific mapping is removed.
* @param file
*/
public void removeFileMapping(ICConfigurationDescription configuration, IFile file) {
removeFileMapping(configuration, file.getProjectRelativePath().toPortableString());
}
/**
* Removes the given file mapping (if it exists).
* If <code>configuration</code> is <code>null</code>, the configuration-agnostic
* mapping is removed. Otherwise, the configuration-specific mapping is removed.
* @param filePath
*/
public void removeFileMapping(ICConfigurationDescription configuration, String filePath) {
Map<String, String> fileMappings = fFileConfigurationMappings.get(filePath);
if (fileMappings == null) {
return;
}
String configurationId = getId(configuration);
fileMappings.remove(configurationId);
if (fileMappings.size() == 0) {
fFileConfigurationMappings.remove(configurationId);
}
}
/**
* Removes all language mappings for the given file.
* @param filePath
*/
public void removeAllFileMappings(String filePath) {
fFileConfigurationMappings.remove(filePath);
}
/**
* Removes all language mappings for the given file.
* @param file
*/
public void removeAllFileMappings(IFile file) {
removeAllFileMappings(file.getProjectRelativePath().toPortableString());
}
/**
* Returns a copy of all the per-configuration content type mappings stored in this configuration.
*
* This method is used internally by CDT and should not be used outside of the CDT framework.
* @return a copy of all the per-configuration content type mappings
*/
public Map<String, Map<String, String>> getContentTypeMappings() {
return copyLanguageMappings(fConfigurationContentTypeMappings, false);
}
/**
* This method is used internally by CDT and should not be used outside of the CDT framework.
*/
public void setContentTypeMappings(Map<String, Map<String, String>> mappings) {
fConfigurationContentTypeMappings = copyLanguageMappings(mappings, false);
}
/**
* Returns a copy of all the per-file content type mappings stored in this configuration.
*
* This method is used internally by CDT and should not be used outside of the CDT framework.
* @return a copy of all the per-file content type mappings
*/
public Map<String, Map<String, String>> getFileMappings() {
return copyLanguageMappings(fFileConfigurationMappings, false);
}
/**
* This method is used internally by CDT and should not be used outside of the CDT framework.
* @param file
*/
public void setFileMappings(IFile file, Map<String, String> mappings) {
fFileConfigurationMappings.put(file.getProjectRelativePath().toPortableString(), new TreeMap<String, String>(mappings));
}
private Map<String, Map<String, String>> copyLanguageMappings(Map<String, Map<String, String>> mappings, boolean isReadOnly) {
Map<String, Map<String, String>> result = new TreeMap<String, Map<String, String>>();
Iterator<Entry<String, Map<String, String>>> entries = mappings.entrySet().iterator();
while (entries.hasNext()) {
Entry<String, Map<String, String>> entry = entries.next();
Map<String, String> map = entry.getValue();
if (isReadOnly) {
map = Collections.unmodifiableMap(map);
} else {
map = new TreeMap<String, String>(map);
}
result.put(entry.getKey(), map);
}
if (isReadOnly) {
result = Collections.unmodifiableMap(result);
}
return result;
}
/**
* This method is used internally by CDT and should not be used outside of the CDT framework.
* @param mappings
*/
public void setFileMappings(Map<String, Map<String, String>> mappings) {
fFileConfigurationMappings = copyLanguageMappings(mappings, false);
}
private String getId(ICConfigurationDescription configuration) {
if (configuration == null) {
return ALL_CONFIGURATIONS;
}
return configuration.getId();
}
}