/*******************************************************************************
* Copyright (c) 2007, 2013 Intel 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:
* Intel Corporation - Initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.internal.core.settings.model;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import org.eclipse.cdt.core.CCorePlugin;
import org.eclipse.cdt.core.model.ICProject;
import org.eclipse.cdt.core.model.IPathEntry;
import org.eclipse.cdt.core.settings.model.ICConfigExtensionReference;
import org.eclipse.cdt.core.settings.model.ICConfigurationDescription;
import org.eclipse.cdt.core.settings.model.ICExternalSetting;
import org.eclipse.cdt.core.settings.model.ICSettingBase;
import org.eclipse.cdt.core.settings.model.extension.CConfigurationData;
import org.eclipse.cdt.core.settings.model.extension.CConfigurationDataProvider;
import org.eclipse.cdt.core.settings.model.extension.CFileData;
import org.eclipse.cdt.core.settings.model.extension.CFolderData;
import org.eclipse.cdt.core.settings.model.extension.CLanguageData;
import org.eclipse.cdt.core.settings.model.extension.CResourceData;
import org.eclipse.cdt.core.settings.model.extension.impl.CDataFactory;
import org.eclipse.cdt.core.settings.model.extension.impl.CDefaultConfigurationData;
import org.eclipse.cdt.core.settings.model.extension.impl.CDefaultFileData;
import org.eclipse.cdt.core.settings.model.extension.impl.CDefaultFolderData;
import org.eclipse.cdt.core.settings.model.extension.impl.CDefaultLanguageData;
import org.eclipse.cdt.core.settings.model.util.CDataUtil;
import org.eclipse.cdt.core.settings.model.util.EntryStore;
import org.eclipse.cdt.core.settings.model.util.PathEntryResolveInfo;
import org.eclipse.cdt.core.settings.model.util.PathEntryTranslator;
import org.eclipse.cdt.core.settings.model.util.PathEntryTranslator.ReferenceSettingsInfo;
import org.eclipse.cdt.internal.core.model.CModelManager;
import org.eclipse.cdt.internal.core.model.PathEntryManager;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.NullProgressMonitor;
public class PathEntryConfigurationDataProvider extends CConfigurationDataProvider {
private static PathEntryDataFactory fFactory;
public static CDataFactory getDataFactory() {
if(fFactory == null) {
fFactory = new PathEntryDataFactory();
}
return fFactory;
}
public PathEntryConfigurationDataProvider() {
getDataFactory();
}
private static class PathEntryFolderData extends CDefaultFolderData {
private EntryStore fStore;
// public PathEntryFolderData(CConfigurationData cfg, CDataFacroty factory) {
// super(cfg, factory);
// }
// public PathEntryFolderData(String id, IPath path,
// CConfigurationData cfg, CDataFacroty factory) {
// super(id, path, cfg, factory);
// }
public PathEntryFolderData(String id, IPath path, PathEntryFolderData base,
CConfigurationData cfgData, CDataFactory factory, boolean clone) {
super(id, path, cfgData, factory);
if(base != null)
fStore = new EntryStore(base.fStore, true);
else
fStore = new EntryStore(true);
copyDataFrom(base, clone);
}
}
private static class PathEntryFileData extends CDefaultFileData {
private EntryStore fStore;
// public PathEntryFileData(CConfigurationData cfg, CDataFacroty factory) {
// super(cfg, factory);
// }
// public PathEntryFileData(String id, IPath path, CConfigurationData cfg,
// CDataFacroty factory) {
// super(id, path, cfg, factory);
// }
public PathEntryFileData(String id, IPath path, PathEntryFileData base,
CConfigurationData cfg, CDataFactory factory, boolean clone) {
super(id, path, cfg, factory);
fStore = new EntryStore(base.fStore, true);
copyDataFrom(base, clone);
}
public PathEntryFileData(String id, IPath path, PathEntryFolderData base,
CLanguageData baseLangData, CConfigurationData cfgData,
CDataFactory factory) {
super(id, path, cfgData, factory);
fStore = new EntryStore(base.fStore, true);
copyDataFrom(base, baseLangData);
}
}
private static class PathEntryLanguageData extends CDefaultLanguageData {
public PathEntryLanguageData(String id, CLanguageData base, EntryStore store) {
fId = id;
fStore = store;
copySettingsFrom(base);
}
public PathEntryLanguageData(String id, String name, String languageId, int kinds,
String[] ids, boolean isContentTypes, EntryStore store) {
super(id, languageId, ids, isContentTypes);
fStore = store;
fName = name;
fSupportedKinds = kinds;
}
@Override
protected EntryStore createStore() {
return fStore;
}
@Override
protected EntryStore createStore(CLanguageData data) {
return fStore;
}
}
private static class PathEntryDataFactory extends CDataFactory {
@Override
public CConfigurationData createConfigurationdata(String id,
String name, CConfigurationData base, boolean clone) {
if(clone){
id = base.getId();
} else if(id == null){
id = CDataUtil.genId(null);
}
return new CfgData(id, name, base, clone);
}
@Override
public CFileData createFileData(CConfigurationData cfg,
CResourceData base, CLanguageData base2,
String id, boolean clone,
IPath path) {
if(id == null)
id = clone ? base.getId() : CDataUtil.genId(cfg.getId());
if(base.getType() == ICSettingBase.SETTING_FILE)
return new PathEntryFileData(id, path, (PathEntryFileData)base, cfg, this, clone);
return new PathEntryFileData(id, path, (PathEntryFolderData)base,
base2, cfg, this);
}
@Override
public CFolderData createFolderData(CConfigurationData cfg,
CFolderData base, String id, boolean clone, IPath path) {
if(id == null)
id = clone ? base.getId() : CDataUtil.genId(cfg.getId());
return new PathEntryFolderData(id, path, (PathEntryFolderData)base, cfg, this, clone);
}
@Override
public CLanguageData createLanguageData(CConfigurationData cfg,
CResourceData rcBase, CLanguageData base, String id, boolean clone) {
if(id == null)
id = clone ? base.getId() : CDataUtil.genId(rcBase.getId());
EntryStore store;
if(rcBase.getType() == ICSettingBase.SETTING_FOLDER)
store = ((PathEntryFolderData)rcBase).fStore;
else
store = ((PathEntryFileData)rcBase).fStore;
return new PathEntryLanguageData(id, base, store);
}
@Override
public CLanguageData createLanguageData(CConfigurationData cfg,
CResourceData rcBase, String id, String name, String languageId, int supportedEntryKinds, String[] rcTypes,
boolean isContentTypes) {
if(id == null)
id = CDataUtil.genId(rcBase.getId());
EntryStore store;
if(rcBase.getType() == ICSettingBase.SETTING_FOLDER)
store = ((PathEntryFolderData)rcBase).fStore;
else
store = ((PathEntryFileData)rcBase).fStore;
return new PathEntryLanguageData(id, name, languageId, supportedEntryKinds, rcTypes, isContentTypes, store);
}
}
private static class CfgData extends CDefaultConfigurationData {
// private PathEntryResolveInfo fResolveInfo;
public CfgData(String id, String name, CConfigurationData base, boolean clone) {
super(id, name, base, fFactory, clone);
}
public CfgData(String id, String name) {
super(id, name, fFactory);
}
// public PathEntryResolveInfo getResolveInfo(){
// return fResolveInfo;
// }
//
// public void setResolveInfo(PathEntryResolveInfo info){
// fResolveInfo = info;
// }
}
public static boolean isPathEntryData(CConfigurationData data){
return data instanceof CfgData;
}
@Override
public CConfigurationData applyConfiguration(ICConfigurationDescription cfgDescription,
ICConfigurationDescription baseCfgDescription, CConfigurationData baseData,
IProgressMonitor monitor) throws CoreException {
//TODO: check external/reference info here as well.
if (!fFactory.isModified(baseData)) {
return createData(cfgDescription, baseData, false, true);
}
IProject project = cfgDescription.getProjectDescription().getProject();
// ReferenceSettingsInfo refInfo = new ReferenceSettingsInfo(des);
IPathEntry entries[] = PathEntryTranslator.getPathEntries(project, baseCfgDescription, PathEntryTranslator.INCLUDE_USER);
CModelManager manager = CModelManager.getDefault();
ICProject cproject = manager.create(project);
IPathEntry[] curRawEntries = PathEntryManager.getDefault().getRawPathEntries(cproject);
List<IPathEntry> list = new ArrayList<IPathEntry>();
list.addAll(Arrays.asList(entries));
for(int i = 0; i < curRawEntries.length; i++){
if(curRawEntries[i].getEntryKind() == IPathEntry.CDT_CONTAINER){
list.add(curRawEntries[i]);
}
}
IPathEntry[] newEntries = list.toArray(new IPathEntry[list.size()]);
PathEntryManager.getDefault().setRawPathEntries(cproject, newEntries, new NullProgressMonitor());
return createData(cfgDescription, baseData, false, false);
}
private CConfigurationData createData(ICConfigurationDescription cfgDescription, CConfigurationData fallbackData, boolean modifiedFlag, boolean useCache) throws CoreException {
CConfigurationData dataToReturn;
try {
dataToReturn = createData(cfgDescription, useCache);
} catch (Exception e){
if(fallbackData != null)
dataToReturn = fallbackData;
else if (e instanceof CoreException)
throw (CoreException)e;
else
throw ExceptionFactory.createCoreException(e);
}
fFactory.setModified(dataToReturn, modifiedFlag);
return dataToReturn;
}
@Override
public CConfigurationData createConfiguration(ICConfigurationDescription cfgDescription,
ICConfigurationDescription baseCfgDescription, CConfigurationData baseData,
boolean clone, IProgressMonitor monitor) throws CoreException {
CfgData copy = new CfgData(cfgDescription.getId(), cfgDescription.getName(), baseData, clone);
copy.setModified(false);
return copy;
}
private CfgData createData(ICConfigurationDescription cfgDescription, boolean useCache) throws CoreException {
IProject project = cfgDescription.getProjectDescription().getProject();
CModelManager manager = CModelManager.getDefault();
ICProject cproject = manager.create(project);
PathEntryResolveInfo rInfo = PathEntryManager.getDefault().getResolveInfo(cproject, useCache);
CfgData data = new CfgData(cfgDescription.getId(), cfgDescription.getName());
data.initEmptyData();
CDataUtil.adjustConfig(data, getDataFactory());
//CProjectDescriptionManager.getInstance().adjustDefaultConfig(data);
// data.setResolveInfo(rInfo);
PathEntryTranslator tr = new PathEntryTranslator(project, data);
ReferenceSettingsInfo refInfo = tr.applyPathEntries(rInfo, PathEntryTranslator.OP_REPLACE);
ICExternalSetting extSettings[] = refInfo.getExternalSettings();
cfgDescription.removeExternalSettings();
if (extSettings.length != 0) {
ICExternalSetting setting;
for(int i = 0; i < extSettings.length; i++){
setting = extSettings[i];
cfgDescription.createExternalSetting(setting.getCompatibleLanguageIds(),
setting.getCompatibleContentTypeIds(),
setting.getCompatibleExtensions(),
setting.getEntries());
}
}
// IPath projPaths[] = refInfo.getReferencedProjectsPaths();
// if(projPaths.length != 0){
// Map map = new HashMap(projPaths.length);
// for(int i = 0; i < projPaths.length; i++){
// map.put(projPaths[i].segment(0), ""); //$NON-NLS-1$
// }
// des.setReferenceInfo(map);
// }
cproject.close();
String[] ids = getIds(cfgDescription.get(CCorePlugin.BINARY_PARSER_UNIQ_ID));
data.getTargetPlatformData().setBinaryParserIds(ids);
ids = getIds(cfgDescription.get(CCorePlugin.ERROR_PARSER_UNIQ_ID));
data.getBuildData().setErrorParserIDs(ids);
data.setModified(false);
return data;
}
private String[] getIds(ICConfigExtensionReference refs[]){
if(refs == null || refs.length == 0)
return new String[0];
String[] ids = new String[refs.length];
for(int i = 0; i < refs.length; i++){
ids[i] = refs[i].getID();
}
return ids;
}
@Override
public CConfigurationData loadConfiguration(ICConfigurationDescription cfgDescription, IProgressMonitor monitor) throws CoreException {
return createData(cfgDescription, null, false, true);
}
@Override
public void removeConfiguration(ICConfigurationDescription cfgDescription, CConfigurationData data, IProgressMonitor monitor) {
//do nothing for now
}
@Override
public void dataCached(ICConfigurationDescription cfgDescription, CConfigurationData data, IProgressMonitor monitor) {
fFactory.setModified(data, false);
}
}