/*******************************************************************************
* Copyright (c) 2005, 2011 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.managedbuilder.internal.dataprovider;
import org.eclipse.cdt.core.cdtvariables.ICdtVariable;
import org.eclipse.cdt.core.cdtvariables.ICdtVariableManager;
import org.eclipse.cdt.core.settings.model.ICConfigurationDescription;
import org.eclipse.cdt.managedbuilder.core.IBuilder;
import org.eclipse.cdt.managedbuilder.core.IConfiguration;
import org.eclipse.cdt.managedbuilder.core.IManagedProject;
import org.eclipse.cdt.managedbuilder.internal.macros.BuildMacroProvider;
import org.eclipse.cdt.managedbuilder.internal.macros.DefaultMacroContextInfo;
import org.eclipse.cdt.managedbuilder.internal.macros.IMacroContextInfo;
import org.eclipse.cdt.managedbuilder.macros.IBuildMacro;
import org.eclipse.cdt.managedbuilder.macros.IBuildMacroProvider;
import org.eclipse.cdt.managedbuilder.macros.IConfigurationBuildMacroSupplier;
import org.eclipse.cdt.managedbuilder.macros.IProjectBuildMacroSupplier;
import org.eclipse.cdt.utils.cdtvariables.ICdtVariableSupplier;
import org.eclipse.cdt.utils.cdtvariables.IVariableContextInfo;
import org.eclipse.cdt.utils.cdtvariables.SupplierBasedCdtVariableManager;
import org.eclipse.cdt.utils.envvar.EnvVarOperationProcessor;
/**
* This supplier is used to suply macros provided by the tool-integrator
*
* @since 3.0
*/
public class ExternalExtensionMacroSupplier implements ICdtVariableSupplier{
private static final String fNonOverloadableMacros[] = new String[]{
//tool-integrators not allowed currently to override the "CWD" and "PWD" macros
"CWD", //$NON-NLS-1$
"PWD" //$NON-NLS-1$
};
private ICdtVariableManager fMngr;
private ICConfigurationDescription fCfgDes;
// private static ExternalExtensionMacroSupplier fInstance;
private class ExtensionMacroProvider extends BuildMacroProvider{
private IMacroContextInfo fStartInfo;
private int fContextType;
private Object fContextData;
private boolean fStartInitialized;
public ExtensionMacroProvider(int contextType, Object contextData){
fContextType = contextType;
fContextData = contextData;
}
/* (non-Javadoc)
* @see org.eclipse.cdt.managedbuilder.envvar.IEnvironmentVariableProvider#getVariable(java.lang.String, java.lang.Object, boolean)
*/
@Override
public ICdtVariable getVariable(String macroName,
int contextType,
Object contextData,
boolean includeParent) {
if(getValidName(macroName) == null)
return null;
return fMngr.getVariable(macroName, fCfgDes);
// return super.getMacro(macroName,contextType,contextData,includeParent);
}
/* (non-Javadoc)
* @see org.eclipse.cdt.managedbuilder.macros.IBuildMacroProvider#getMacros(int, java.lang.Object, boolean)
*/
@Override
public ICdtVariable[] getVariables(int contextType,Object contextData, boolean includeParent) {
// return filterVariables(super.getMacros(contextType, contextData, includeParent));
return filterVariables(fMngr.getVariables(fCfgDes));
}
/* (non-Javadoc)
* @see org.eclipse.cdt.managedbuilder.internal.envvar.EnvironmentVariableProvider#getContextInfo(java.lang.Object)
*/
@Override
public IMacroContextInfo getMacroContextInfo(int contextType,Object contextData){
IMacroContextInfo startInfo = getStartInfo();
if(contextType == fContextType &&
contextData == fContextData)
return startInfo;
IMacroContextInfo info = super.getMacroContextInfo(contextType, contextData);
if(info == null)
return null;
if(SupplierBasedCdtVariableManager.checkParentContextRelation(startInfo,info))
return info;
return null;
}
protected IMacroContextInfo getStartInfo(){
if(fStartInfo == null && !fStartInitialized){
IMacroContextInfo info = super.getMacroContextInfo(fContextType,fContextData);
if(info != null){
ICdtVariableSupplier suppliers[] = info.getSuppliers();
suppliers = filterValidSuppliers(suppliers);
if(suppliers != null)
fStartInfo = new DefaultMacroContextInfo(fContextType,fContextData,suppliers);
else
fStartInfo = (IMacroContextInfo)info.getNext();
fStartInitialized = true;
}
fStartInitialized = true;
}
return fStartInfo;
}
}
public ExternalExtensionMacroSupplier(ICdtVariableManager mngr, ICConfigurationDescription cfgDes){
fMngr = mngr;
fCfgDes = cfgDes;
}
/* (non-Javadoc)
* @see org.eclipse.cdt.managedbuilder.macros.IBuildMacroSupplier#getMacro(java.lang.String, int, java.lang.Object)
*/
@Override
public ICdtVariable getVariable(String macroName, IVariableContextInfo context) {
if((macroName = getValidName(macroName)) == null)
return null;
IMacroContextInfo info = (IMacroContextInfo)context;
int contextType = info.getContextType();
Object contextData = info.getContextData();
switch(contextType){
case IBuildMacroProvider.CONTEXT_CONFIGURATION:
IConfiguration cfg = null;
IBuilder builder = null;
if(contextData instanceof IBuilder){
builder = (IBuilder)contextData;
cfg = builder.getParent().getParent();
} else if(contextData instanceof IConfiguration){
cfg = (IConfiguration)contextData;
builder = cfg.getBuilder();
}
if(cfg != null){
IConfigurationBuildMacroSupplier supplier = cfg.getBuildMacroSupplier();
if(supplier == null)
return null;
return supplier.getMacro(macroName,cfg,new ExtensionMacroProvider(contextType, contextData));
}
case IBuildMacroProvider.CONTEXT_PROJECT:
if (contextData instanceof IManagedProject) {
IManagedProject project = (IManagedProject)contextData;
IProjectBuildMacroSupplier supplier = project.getProjectType() != null ? project.getProjectType().getBuildMacroSupplier() : null;
if(supplier == null)
return null;
return supplier.getMacro(macroName,project,new ExtensionMacroProvider(contextType, contextData));
}
}
return null;
}
/* (non-Javadoc)
* @see org.eclipse.cdt.managedbuilder.macros.IBuildMacroSupplier#getMacros(int, java.lang.Object)
*/
@Override
public ICdtVariable[] getVariables(IVariableContextInfo context) {
IBuildMacro macros[] = null;
IMacroContextInfo info = (IMacroContextInfo)context;
int contextType = info.getContextType();
Object contextData = info.getContextData();
switch(contextType){
case IBuildMacroProvider.CONTEXT_CONFIGURATION:
IConfiguration cfg = null;
IBuilder builder = null;
if(contextData instanceof IBuilder){
builder = (IBuilder)contextData;
cfg = builder.getParent().getParent();
}else if(contextData instanceof IConfiguration){
cfg = (IConfiguration)contextData;
builder = cfg.getBuilder();
}
if(cfg != null){
IConfigurationBuildMacroSupplier supplier = cfg.getBuildMacroSupplier();
if(supplier != null)
macros = supplier.getMacros(cfg,new ExtensionMacroProvider(contextType, contextData));
}
break;
case IBuildMacroProvider.CONTEXT_PROJECT:
if (contextData instanceof IManagedProject) {
IManagedProject project = (IManagedProject)contextData;
IProjectBuildMacroSupplier supplier = project.getProjectType() != null ? project.getProjectType().getBuildMacroSupplier() : null;
if(supplier != null)
macros = supplier.getMacros(project,new ExtensionMacroProvider(contextType, contextData));
}
}
return filterVariables(macros);
}
protected String getValidName(String name){
if(name == null || (name = name.trim()).length() == 0)
return null;
if(fNonOverloadableMacros != null){
for(int i = 0; i < fNonOverloadableMacros.length; i++){
if(fNonOverloadableMacros[i].equals(EnvVarOperationProcessor.normalizeName(name)))
return null;
}
}
return name;
}
protected ICdtVariable[] filterVariables(ICdtVariable macros[]){
return filterVariables(macros,fNonOverloadableMacros);
}
private ICdtVariable[] filterVariables(ICdtVariable macros[], String remove[]){
if(macros == null || macros.length == 0)
return macros;
ICdtVariable filtered[] = new ICdtVariable[macros.length];
int filteredNum = 0;
for(int i = 0; i < macros.length; i++){
ICdtVariable var = macros[i];
String name = null;
if(var != null && (name = var.getName().trim()).length() != 0){
boolean skip = false;
if(remove != null && remove.length > 0){
for(int j = 0; j < remove.length; j++){
if(remove[j] != null && remove[j].equals(name)){
skip = true;
break;
}
}
}
if(!skip)
filtered[filteredNum++] = var;
}
}
if(filteredNum != filtered.length){
ICdtVariable m[] = new ICdtVariable[filteredNum];
for(int i = 0; i < filteredNum; i++)
m[i] = filtered[i];
filtered = m;
}
return filtered;
}
protected ICdtVariableSupplier[] filterValidSuppliers(ICdtVariableSupplier suppliers[]){
if(suppliers == null)
return null;
int i = 0, j = 0;
for(i = 0; i < suppliers.length; i++){
if(suppliers[i] == this)
break;
}
if(i >= suppliers.length)
return null;
int startNum = i + 1;
ICdtVariableSupplier validSuppliers[] =
new ICdtVariableSupplier[suppliers.length - startNum];
for(i = startNum, j = 0; i < suppliers.length; i++, j++)
validSuppliers[j] = suppliers[i];
return validSuppliers;
}
}