/******************************************************************************* * Copyright (c) 2007, 2010 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.core; import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.Set; import java.util.Vector; import org.eclipse.cdt.core.CCProjectNature; import org.eclipse.cdt.core.CProjectNature; import org.eclipse.cdt.core.settings.model.ICSettingBase; import org.eclipse.cdt.core.settings.model.ICStorageElement; 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.util.CDataUtil; import org.eclipse.cdt.managedbuilder.buildproperties.IBuildProperty; import org.eclipse.cdt.managedbuilder.buildproperties.IBuildPropertyType; import org.eclipse.cdt.managedbuilder.core.BuildException; import org.eclipse.cdt.managedbuilder.core.IBuildObject; import org.eclipse.cdt.managedbuilder.core.IBuildObjectProperties; import org.eclipse.cdt.managedbuilder.core.IBuildPropertiesRestriction; import org.eclipse.cdt.managedbuilder.core.IConfiguration; import org.eclipse.cdt.managedbuilder.core.IFolderInfo; import org.eclipse.cdt.managedbuilder.core.IInputType; import org.eclipse.cdt.managedbuilder.core.IManagedConfigElement; import org.eclipse.cdt.managedbuilder.core.IManagedProject; import org.eclipse.cdt.managedbuilder.core.IModificationStatus; import org.eclipse.cdt.managedbuilder.core.IOption; import org.eclipse.cdt.managedbuilder.core.IOutputType; import org.eclipse.cdt.managedbuilder.core.IResourceInfo; import org.eclipse.cdt.managedbuilder.core.ITargetPlatform; import org.eclipse.cdt.managedbuilder.core.ITool; import org.eclipse.cdt.managedbuilder.core.IToolChain; import org.eclipse.cdt.managedbuilder.core.ManagedBuildManager; import org.eclipse.cdt.managedbuilder.internal.buildproperties.BuildPropertyManager; import org.eclipse.cdt.managedbuilder.internal.dataprovider.BuildFolderData; import org.eclipse.cdt.managedbuilder.internal.dataprovider.BuildLanguageData; import org.eclipse.cdt.managedbuilder.internal.dataprovider.ConfigurationDataProvider; import org.eclipse.core.resources.IProject; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IConfigurationElement; import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.Path; public class FolderInfo extends ResourceInfo implements IFolderInfo { private ToolChain toolChain; private boolean isExtensionElement; private boolean containsDiscoveredScannerInfo = true; public FolderInfo(FolderInfo folderInfo, String id, String resourceName, IPath path){ super(folderInfo, path, id, resourceName); isExtensionElement = folderInfo.isExtensionElement(); if(!isExtensionElement) setResourceData(new BuildFolderData(this)); if ( folderInfo.getParent() != null) setManagedBuildRevision(folderInfo.getParent().getManagedBuildRevision()); IToolChain parTc = folderInfo.getToolChain(); IToolChain extTc = ManagedBuildManager.getExtensionToolChain(parTc); if(extTc == null) extTc = parTc; String tcId = ManagedBuildManager.calculateChildId(extTc.getId(), null); createToolChain(extTc, tcId, parTc.getName(), false); toolChain.createOptions(parTc); toolChain.setUnusedChildren(parTc.getUnusedChildren()); ITool tools[] = parTc.getTools(); String subId = new String(); for (ITool tool : tools) { ITool extTool = ManagedBuildManager.getExtensionTool(tool); if(extTool == null) extTool = tool; subId = ManagedBuildManager.calculateChildId(extTool.getId(), null); toolChain.createTool(tool, subId, tool.getName(), false); } setDirty(true); setRebuildState(true); } public FolderInfo(IConfiguration parent, IManagedConfigElement element, String managedBuildRevision, boolean hasBody) { super(parent, element, hasBody); isExtensionElement = true; IManagedConfigElement tcEl = null; if(!hasBody){ setPath(Path.ROOT); setId(ManagedBuildManager.calculateChildId(parent.getId(), null)); setName("/"); //$NON-NLS-1$ tcEl = element; } else { IManagedConfigElement children[] = element.getChildren(IToolChain.TOOL_CHAIN_ELEMENT_NAME); if(children.length > 0) tcEl = children[0]; } if(tcEl != null) toolChain = new ToolChain(this, tcEl, managedBuildRevision); } public FolderInfo(IConfiguration parent, ICStorageElement element, String managedBuildRevision, boolean hasBody) { super(parent, element, hasBody); isExtensionElement = false; setResourceData(new BuildFolderData(this)); ICStorageElement tcEl = null; if(!hasBody){ setPath(Path.ROOT); setId(ManagedBuildManager.calculateChildId(parent.getId(), null)); setName("/"); //$NON-NLS-1$ tcEl = element; } else { ICStorageElement nodes[] = element.getChildren(); for (ICStorageElement node : nodes) { if(IToolChain.TOOL_CHAIN_ELEMENT_NAME.equals(node.getName())) tcEl = node; } } if(tcEl != null) toolChain = new ToolChain(this, tcEl, managedBuildRevision); } /*TODO public FolderInfo(FolderInfo base, IPath path, String id, String name) { super(base, path, id, name); } */ public FolderInfo(IConfiguration parent, IPath path, String id, String name, boolean isExtensionElement) { super(parent, path, id, name); this.isExtensionElement = isExtensionElement; if(!isExtensionElement) setResourceData(new BuildFolderData(this)); } public FolderInfo(IConfiguration cfg, FolderInfo cloneInfo, String id, Map<IPath, Map<String, String>> superIdMap, boolean cloneChildren) { super(cfg, cloneInfo, id); isExtensionElement = cfg.isExtensionElement(); if(!isExtensionElement) setResourceData(new BuildFolderData(this)); String subName; if(!cloneInfo.isExtensionElement) cloneChildren = true; boolean copyIds = cloneChildren && id.equals(cloneInfo.id); IToolChain cloneToolChain = cloneInfo.getToolChain(); IToolChain extToolChain = ManagedBuildManager.getExtensionToolChain(cloneToolChain); if (extToolChain==null) extToolChain = cloneToolChain; subName = cloneToolChain.getName(); if (cloneChildren) { String subId = copyIds ? cloneToolChain.getId() : ManagedBuildManager.calculateChildId(extToolChain.getId(), null); toolChain = new ToolChain(this, subId, subName, superIdMap, (ToolChain)cloneToolChain); } else { // Add a tool-chain element that specifies as its superClass the // tool-chain that is the child of the configuration. String subId = ManagedBuildManager.calculateChildId( extToolChain.getId(), null); IToolChain newChain = createToolChain(extToolChain, subId, extToolChain.getName(), false); // For each option/option category child of the tool-chain that is // the child of the selected configuration element, create an option/ // option category child of the cloned configuration's tool-chain element // that specifies the original tool element as its superClass. newChain.createOptions(extToolChain); // For each tool element child of the tool-chain that is the child of // the selected configuration element, create a tool element child of // the cloned configuration's tool-chain element that specifies the // original tool element as its superClass. ITool[] tools = extToolChain.getTools(); for (ITool tool : tools) { Tool toolChild = (Tool)tool; subId = ManagedBuildManager.calculateChildId(toolChild.getId(),null); newChain.createTool(toolChild, subId, toolChild.getName(), false); } ITargetPlatform tpBase = cloneInfo.getToolChain().getTargetPlatform(); ITargetPlatform extTp = tpBase; for(;extTp != null && !extTp.isExtensionElement();extTp = extTp.getSuperClass()) { // empty body, loop is to find extension element only } TargetPlatform tp; if(extTp != null){ int nnn = ManagedBuildManager.getRandomNumber(); subId = copyIds ? tpBase.getId() : extTp.getId() + "." + nnn; //$NON-NLS-1$ tp = new TargetPlatform(newChain, subId, tpBase.getName(), (TargetPlatform)tpBase); } else { subId = copyIds ? tpBase.getId() : ManagedBuildManager.calculateChildId(getId(), null); subName = tpBase != null ? tpBase.getName() : ""; //$NON-NLS-1$ tp = new TargetPlatform((ToolChain)newChain, null, subId, subName, false); } ((ToolChain)newChain).setTargetPlatform(tp); } if(isRoot()) containsDiscoveredScannerInfo = cloneInfo.containsDiscoveredScannerInfo; if(copyIds){ isDirty = cloneInfo.isDirty; needsRebuild = cloneInfo.needsRebuild; } else { setDirty(true); setRebuildState(true); } } private boolean conflictsWithRootTools(ITool tool){ IFolderInfo rf = getParent().getRootFolderInfo(); ITool[] rootTools = rf.getFilteredTools(); ITool tt = getParent().getTargetTool(); for (ITool rootTool : rootTools) { if(rootTool == tt || getMultipleOfType(rootTool) != null){ if(getConflictingInputExts(rootTool, tool).length != 0) return true; } } return false; } private IInputType getMultipleOfType(ITool tool){ IInputType[] types = tool.getInputTypes(); IInputType mType = null; boolean foundNonMultiplePrimary = false; for (IInputType type : types) { if(type.getMultipleOfType()){ if(type.getPrimaryInput() == true){ foundNonMultiplePrimary = false; mType = type; break; } else if (mType == null){ mType = type; } } else { if(type.getPrimaryInput() == true){ foundNonMultiplePrimary = true; } } } return foundNonMultiplePrimary ? null : mType; } public ITool[] filterTools(ITool localTools[], IManagedProject manProj) { if (manProj == null) { // If this is not associated with a project, then there is nothing to filter with return localTools; } IProject project = (IProject)manProj.getOwner(); Vector<Tool> tools = new Vector<Tool>(localTools.length); for (ITool t : localTools) { Tool tool = (Tool)t; if(!tool.isEnabled(this)) continue; if(!isRoot() && conflictsWithRootTools(tool)) continue; try { // Make sure the tool is right for the project switch (tool.getNatureFilter()) { case ITool.FILTER_C: if (project.hasNature(CProjectNature.C_NATURE_ID) && !project.hasNature(CCProjectNature.CC_NATURE_ID)) { tools.add(tool); } break; case ITool.FILTER_CC: if (project.hasNature(CCProjectNature.CC_NATURE_ID)) { tools.add(tool); } break; case ITool.FILTER_BOTH: tools.add(tool); break; default: break; } } catch (CoreException e) { continue; } } // Answer the filtered tools as an array return tools.toArray(new Tool[tools.size()]); } public ITool[] getFilteredTools() { if (toolChain == null) { return new ITool[0]; } ITool[] localTools = toolChain.getTools(); IManagedProject manProj = getParent().getManagedProject(); return filterTools(localTools, manProj); } public final int getKind() { return ICSettingBase.SETTING_FOLDER; } @Override public boolean isDirty() { if(super.isDirty()) return true; if (toolChain.isDirty()) return true; return false; } @Override public boolean needsRebuild() { if(super.needsRebuild() || toolChain.needsRebuild()) return true; else return false; } @Override public void setRebuildState(boolean rebuild) { super.setRebuildState(rebuild); if(!rebuild) toolChain.setRebuildState(false); } public IToolChain getToolChain() { return toolChain; } public ITool[] getTools() { return toolChain.getTools(); } public ITool getTool(String id) { return toolChain.getTool(id); } public ITool[] getToolsBySuperClassId(String id) { return toolChain.getToolsBySuperClassId(id); } ToolChain createToolChain(IToolChain superClass, String Id, String name, boolean isExtensionElement) { toolChain = new ToolChain(this, superClass, Id, name, isExtensionElement); setDirty(true); return toolChain; } @Override void serialize(ICStorageElement element){ super.serialize(element); ICStorageElement toolChainElement = element.createChild(IToolChain.TOOL_CHAIN_ELEMENT_NAME); toolChain.serialize(toolChainElement); } @Override void resolveReferences(){ if(toolChain != null) toolChain.resolveReferences(); } @Override public void updateManagedBuildRevision(String revision){ super.updateManagedBuildRevision(revision); if(toolChain != null) toolChain.updateManagedBuildRevision(revision); } @Override public boolean isExtensionElement(){ return isExtensionElement; } public String getErrorParserIds(){ if(toolChain != null) return toolChain.getErrorParserIds(getParent()); return null; } public CFolderData getFolderData(){ return (CFolderData)getResourceData(); } public CLanguageData[] getCLanguageDatas() { List<CLanguageData> list = new ArrayList<CLanguageData>(); for(ITool t : getFilteredTools()) for(CLanguageData d : t.getCLanguageDatas()) list.add(d); return list.toArray(new BuildLanguageData[list.size()]); } public ITool getToolFromOutputExtension(String extension) { // Treat a null argument as an empty string String ext = extension == null ? "" : extension; //$NON-NLS-1$ // Get all the tools for the current config ITool[] tools = getFilteredTools(); for (ITool tool : tools) { if (tool.producesFileType(ext)) { return tool; } } return null; } public ITool getToolFromInputExtension(String sourceExtension) { // Get all the tools for the current config ITool[] tools = getFilteredTools(); for (ITool tool : tools) { if (tool.buildsFileType(sourceExtension)) { return tool; } } return null; } @Override public void propertiesChanged() { if(isExtensionElement) return; toolChain.propertiesChanged(); super.propertiesChanged(); } @Override public void setDirty(boolean isDirty) { if (isExtensionElement && isDirty) return; super.setDirty(isDirty); // Propagate "false" to the children if (!isDirty) { if(toolChain != null) toolChain.setDirty(false); } } private Map<String, String> typeIdsToMap(String [] ids, IBuildObjectProperties props){ Map<String, String> map = new HashMap<String, String>(ids.length); for(String id : ids){ IBuildProperty prop = props.getProperty(id); map.put(id, prop.getValue().getId()); } return map; } private Map<String, String> propsToMap(IBuildProperty props[]){ Map<String, String> map = new HashMap<String, String>(props.length); for(IBuildProperty p : props) map.put(p.getPropertyType().getId(), p.getValue().getId()); return map; } private boolean checkPropertiesModificationCompatibility(IBuildPropertiesRestriction r, Map<String, String> unspecifiedRequiredProps, Map<String, String> unspecifiedProps, Set<String> undefinedSet){ IBuildObjectProperties props = null; IConfiguration cfg = getParent(); if(cfg != null){ props = cfg.getBuildProperties(); } unspecifiedProps.clear(); unspecifiedRequiredProps.clear(); if(props != null && props.getSupportedTypeIds().length != 0){ String[] requiredIds = props.getRequiredTypeIds(); IBuildPropertyType[] supportedTypes = props.getSupportedTypes(); if(supportedTypes.length != 0 || requiredIds.length != 0){ if(requiredIds.length == 0){ if(props.getProperty(ManagedBuildManager.BUILD_ARTEFACT_TYPE_PROPERTY_ID) != null){ requiredIds = new String[]{ManagedBuildManager.BUILD_ARTEFACT_TYPE_PROPERTY_ID}; } } Map<String, String> requiredMap = typeIdsToMap(requiredIds, props); getUnsupportedProperties(requiredMap, r, unspecifiedRequiredProps, undefinedSet); unspecifiedProps.putAll(unspecifiedRequiredProps); IBuildProperty[] ps = props.getProperties(); Map<String, String> propsMap = propsToMap(ps); getUnsupportedProperties(propsMap, r, unspecifiedProps, undefinedSet); } return unspecifiedRequiredProps.size() == 0; } return false; } private void getUnsupportedProperties(Map<String, String> props, IBuildPropertiesRestriction restriction, Map<String, String> unsupported, Set<String> inexistent){ BuildPropertyManager mngr = BuildPropertyManager.getInstance(); for(Map.Entry<String, String> entry : props.entrySet()){ String propId = entry.getKey(); String valueId = entry.getValue(); IBuildPropertyType type = mngr.getPropertyType(propId); if(type == null){ if(inexistent != null){ inexistent.add(propId); } } if(!restriction.supportsType(propId)){ unsupported.put(propId, null); } else if (!restriction.supportsValue(propId, valueId)){ unsupported.put(propId, valueId); } } } public void checkPropertiesModificationCompatibility(final ITool tools[], Map<String, String> unspecifiedRequiredProps, Map<String, String> unspecifiedProps, Set<String> undefinedSet){ final ToolChain tc = (ToolChain)getToolChain(); IBuildPropertiesRestriction r = new IBuildPropertiesRestriction(){ public boolean supportsType(String typeId) { if(tc.supportsType(typeId, false)) return true; for (ITool tool : tools) { if(((Tool)tool).supportsType(typeId)) return true; } return false; } public boolean supportsValue(String typeId, String valueId) { if(tc.supportsValue(typeId, valueId, false)) return true; for (ITool tool : tools) { if(((Tool)tool).supportsValue(typeId, valueId)) return true; } return false; } public String[] getRequiredTypeIds() { List<String> list = new ArrayList<String>(); list.addAll(Arrays.asList(tc.getRequiredTypeIds(false))); for (ITool tool : tools) { list.addAll(Arrays.asList(((Tool)tool).getRequiredTypeIds())); } return list.toArray(new String[list.size()]); } public String[] getSupportedTypeIds() { List<String> list = new ArrayList<String>(); list.addAll(Arrays.asList(tc.getSupportedTypeIds(false))); for (ITool tool : tools) { list.addAll(Arrays.asList(((Tool)tool).getSupportedTypeIds())); } return list.toArray(new String[list.size()]); } public String[] getSupportedValueIds(String typeId) { List<String> list = new ArrayList<String>(); list.addAll(Arrays.asList(tc.getSupportedValueIds(typeId, false))); for (ITool tool : tools) { list.addAll(Arrays.asList(((Tool)tool).getSupportedValueIds(typeId))); } return list.toArray(new String[list.size()]); } public boolean requiresType(String typeId) { if(tc.requiresType(typeId, false)) return true; for (ITool tool : tools) { if(((Tool)tool).requiresType(typeId)) return true; } return false; } }; checkPropertiesModificationCompatibility(r, unspecifiedRequiredProps, unspecifiedProps, undefinedSet); } public boolean checkPropertiesModificationCompatibility(IToolChain tc, Map<String, String> unspecifiedRequiredProps, Map<String, String> unspecifiedProps, Set<String> undefinedSet){ return checkPropertiesModificationCompatibility((IBuildPropertiesRestriction)tc, unspecifiedRequiredProps, unspecifiedProps, undefinedSet); } public boolean isPropertiesModificationCompatible(IToolChain tc){ Map<String, String> requiredMap = new HashMap<String, String>(); Map<String, String> unsupportedMap = new HashMap<String, String>(); Set<String> undefinedSet = new HashSet<String>(); if(!checkPropertiesModificationCompatibility(tc, requiredMap, unsupportedMap, undefinedSet)) return false; return true; } private Set<String> getRequiredUnspecifiedProperties(){ IBuildObjectProperties props = null; Set<String> set = new HashSet<String>(); IConfiguration cfg = getParent(); if(cfg != null) props = cfg.getBuildProperties(); if(props != null) for(String s : props.getRequiredTypeIds()) if(props.getProperty(s) == null) set.add(s); return set; } public boolean isToolChainCompatible(IToolChain tCh){ return isToolChainCompatible(toolChain, tCh); } public boolean isToolChainCompatible(ToolChain fromTc, IToolChain tCh){ boolean compatible = false; if(tCh == fromTc) return true; if(tCh == null){ tCh = ManagedBuildManager.getExtensionToolChain(ConfigurationDataProvider.PREF_TC_ID); } if(tCh == null) return false; IToolChain curReal = ManagedBuildManager.getRealToolChain(fromTc); IToolChain newReal = ManagedBuildManager.getRealToolChain(tCh); if(curReal == newReal) return true; if(getToolChainConverterInfo(fromTc, tCh) != null) compatible = true; if(!compatible) compatible = isPropertiesModificationCompatible(tCh); return compatible; } public IToolChain changeToolChain(IToolChain newSuperClass, String Id, String name) throws BuildException{ boolean usePrefTc = false; if(newSuperClass == null){ newSuperClass = ManagedBuildManager.getExtensionToolChain(ConfigurationDataProvider.PREF_TC_ID); usePrefTc = true; } if(newSuperClass == null) return toolChain; IToolChain curReal = ManagedBuildManager.getRealToolChain(toolChain); IToolChain newReal = ManagedBuildManager.getRealToolChain(newSuperClass); if(Id == null){ Id = ManagedBuildManager.calculateChildId(newSuperClass.getId(), null); } if(name == null){ name = newSuperClass.getName(); } if(newReal != curReal){ IToolChain extTc = ManagedBuildManager.getExtensionToolChain(newSuperClass); if(extTc != null) newSuperClass = extTc; ToolChain oldToolChain = toolChain; ConverterInfo cInfo = getToolChainConverterInfo(toolChain, newSuperClass); ITool oldTools[] = oldToolChain.getTools(); if(cInfo != null){ updateToolChainWithConverter(cInfo, Id, name); } else { updateToolChainWithProperties(usePrefTc ? null : newSuperClass, Id, name); } BuildSettingsUtil.disconnectDepentents(getParent(), oldTools); } return toolChain; } void updateToolChainWithProperties(IToolChain newSuperClass, String Id, String name) { ToolChain oldTc = (ToolChain)getToolChain(); if(newSuperClass != null) { createToolChain(newSuperClass, Id, name, false); // For each option/option category child of the tool-chain that is // the child of the selected configuration element, create an option/ // option category child of the cloned configuration's tool-chain element // that specifies the original tool element as its superClass. toolChain.createOptions(newSuperClass); // For each tool element child of the tool-chain that is the child of // the selected configuration element, create a tool element child of // the cloned configuration's tool-chain element that specifies the // original tool element as its superClass. String subId; ITool[] tools = newSuperClass.getTools(); for (ITool tool : tools) { Tool toolChild = (Tool)tool; subId = ManagedBuildManager.calculateChildId(toolChild.getId(),null); toolChain.createTool(toolChild, subId, toolChild.getName(), false); } } else { Configuration cfg = ConfigurationDataProvider.getClearPreference(null); ToolChain prefTch = (ToolChain)cfg.getRootFolderInfo().getToolChain(); toolChain = new ToolChain(this, ManagedBuildManager.calculateChildId(prefTch.getSuperClass().getId(), null), prefTch.getName(), new HashMap<IPath, Map<String, String>>(), prefTch); } if(isRoot()){ Builder oldBuilder = (Builder)oldTc.getBuilder(); Builder newBuilder = (Builder)getParent().getEditableBuilder(); newBuilder.copySettings(oldBuilder, false); } IManagedProject mProj = getParent().getManagedProject(); ITool[] filteredTools = getFilteredTools(); ITool[] oldFilteredTools = filterTools(oldTc.getTools(), mProj); copySettings(oldFilteredTools, filteredTools); toolChain.propertiesChanged(); } private void copySettings(ITool[] fromTools, ITool[] toTools){ ITool[][] matches = getBestMatches(fromTools, toTools); for (ITool[] match : matches) { BuildSettingsUtil.copyCommonSettings(match[0], match[1]); } } private ITool[][] getBestMatches(ITool[] tools1, ITool[] tools2){ HashSet<ITool> set = new HashSet<ITool>(Arrays.asList(tools2)); List<ITool[]> list = new ArrayList<ITool[]>(tools1.length); for(ITool tool1 : tools1){ ITool bestMatchTool = null; int num = 0; for(ITool tool2 : set){ int extsNum = getConflictingInputExts(tool1, tool2).length; if(extsNum > num){ bestMatchTool = tool2; num = extsNum; } } if(bestMatchTool != null){ list.add(new ITool[]{tool1, bestMatchTool}); set.remove(bestMatchTool); } } return list.toArray(new ITool[list.size()][]); } void updateToolChainWithConverter(ConverterInfo cInfo, String Id, String name) throws BuildException{ IBuildObject bo = cInfo.getConvertedFromObject(); ToolChain updatedToolChain = null; if(bo instanceof Configuration){ Configuration cfg = (Configuration)bo; if(cfg != getParent()){ IResourceInfo rcInfo = cfg.getResourceInfo(getPath(), true); if(rcInfo instanceof FolderInfo){ IToolChain tc = ((FolderInfo)rcInfo).getToolChain(); IToolChain realToToolChain = ManagedBuildManager.getRealToolChain((IToolChain)cInfo.getToObject()); if(ManagedBuildManager.getRealToolChain(tc) == realToToolChain){ updatedToolChain = (ToolChain)tc; } } if(updatedToolChain == null){ updatedToolChain = (ToolChain)cfg.getRootFolderInfo().getToolChain(); } } else { updatedToolChain = toolChain; } } else if(bo instanceof ToolChain){ updatedToolChain = (ToolChain)bo; } else { throw new BuildException(ManagedMakeMessages.getResourceString("FolderInfo.4")); //$NON-NLS-1$ } if(updatedToolChain != null && toolChain != updatedToolChain){ setUpdatedToolChain(updatedToolChain); } toolChain.setName(name); } void setUpdatedToolChain(ToolChain tch){ tch.copyNonoverriddenSettings(toolChain); toolChain = tch; tch.updateParentFolderInfo(this); } private ConverterInfo getToolChainConverterInfo(ToolChain fromTc, IToolChain toTc){ IConfigurationElement el = getToolChainConverterElement(fromTc, toTc); IToolChain foundToTc = toTc; if(el == null){ IToolChain[] tcs = ManagedBuildManager.findIdenticalToolChains(toTc); for (IToolChain tc : tcs) { foundToTc = tc; if(foundToTc == toTc) continue; el = getToolChainConverterElement(fromTc, foundToTc); if(el != null) break; } } if(el != null) return new ConverterInfo(this, getToolChain(), foundToTc, el); return null; } private IConfigurationElement getToolChainConverterElement(ToolChain fromTc, IToolChain tCh){ if(tCh == null) return null; if(fromTc != null) return fromTc.getConverterModificationElement(tCh); else return null; } @SuppressWarnings("unchecked") private ITool[][] checkDups(ITool[] removed, ITool[] added){ LinkedHashMap<Object, ITool> removedMap = createRealToExtToolMap(removed, false); LinkedHashMap<Object, ITool> addedMap = createRealToExtToolMap(added, true); LinkedHashMap<Object, ITool> rmCopy = (LinkedHashMap<Object, ITool>)removedMap.clone(); removedMap.keySet().removeAll(addedMap.keySet()); addedMap.keySet().removeAll(rmCopy.keySet()); if(removedMap.size() != 0){ LinkedHashMap<Object, ITool> curMap = createRealToExtToolMap(getTools(), false); for(Iterator<Map.Entry<Object, ITool>> iter = removedMap.entrySet().iterator(); iter.hasNext();){ Map.Entry<Object, ITool> entry = iter.next(); Object key = entry.getKey(); Object curTool = curMap.get(key); if(curTool != null) entry.setValue((ITool)curTool); else iter.remove(); } } ITool[][] result = new Tool[2][]; result[0] = removedMap.values().toArray(new Tool[removedMap.size()]); result[1] = addedMap.values().toArray(new Tool[addedMap.size()]); return result; } private LinkedHashMap<Object, ITool> createRealToExtToolMap(ITool[] tools, boolean extValues){ LinkedHashMap<Object, ITool> map = new LinkedHashMap<Object, ITool>(); for(ITool t : tools){ Tool realTool = (Tool)ManagedBuildManager.getRealTool(t); MatchKey<Tool> key = realTool.getMatchKey(); ITool toolValue = extValues ? ManagedBuildManager.getExtensionTool(t) : t; if(toolValue != null) map.put(key, toolValue); } return map; } public void modifyToolChain(ITool[] removed, ITool[] added){ ToolListModificationInfo info = ToolChainModificationHelper.getModificationInfo(this, getTools(), added, removed); info.apply(); return; // ITool[][] checked = checkDups(removed, added); // removed = checked[0]; // added = checked[1]; // if(added.length == 0 && removed.length == 0) // return; // // List<ITool> remainingRemoved = new ArrayList<ITool>(); // List<ITool> remainingAdded = new ArrayList<ITool>(); // Map<ITool, ConverterInfo> converterMap = // calculateConverterTools(removed, added, remainingRemoved, remainingAdded); // invokeConverters(converterMap); // List<Tool> newTools = new ArrayList<Tool>(added.length); // for(ConverterInfo info : converterMap.values()){ // if(info.getConvertedFromObject() instanceof Tool){ // Tool newTool = (Tool)info.getConvertedFromObject(); // newTool.updateParent(getToolChain()); // newTools.add(newTool); // } else { // remainingAdded.add((ITool)info.getToObject()); // } // } // // for(ITool t : remainingAdded){ // newTools.add( // new Tool( // toolChain, // t, // ManagedBuildManager.calculateChildId(t.getId(), null), // t.getName(), // false) // ); // } // // performToolChainModification(removed, newTools.toArray(new Tool[newTools.size()])); } // private void performToolChainModification(ITool removed[], ITool[] added){ // BuildSettingsUtil.disconnectDepentents(getParent(), removed); // // for (ITool tool : removed) { // toolChain.removeTool((Tool)tool); // } // // for (ITool tool : added) { // toolChain.addTool((Tool)tool); // } // // adjustTargetTools(removed, added); // // toolChain.propertiesChanged(); // } private void adjustTargetTools(ITool removed[], ITool added[]){ if(!isRoot()) return; Set<String> set = new HashSet<String>(); String [] ids = toolChain.getTargetToolList(); boolean targetToolsModified = false; set.addAll(Arrays.asList(ids)); for (ITool tool : removed) { Object[] tInfo = getTargetTool(tool); if(tInfo == null) continue; ITool target = (ITool)tInfo[0]; String tId = (String)tInfo[1]; if(BuildSettingsUtil.calcDependentTools(added, target, null).size() != 0) continue; ITool newTargetTool = findCompatibleTargetTool(target, added); if(newTargetTool == null) continue; newTargetTool = ManagedBuildManager.getExtensionTool(newTargetTool); if(newTargetTool == null) continue; set.remove(tId); set.add(newTargetTool.getId()); targetToolsModified = true; } if(targetToolsModified){ toolChain.setTargetToolIds(CDataUtil.arrayToString(set.toArray(new String[set.size()]), ";")); //$NON-NLS-1$ } } private ITool findCompatibleTargetTool(ITool tool, ITool allTools[]){ IProject project = getParent().getOwner().getProject(); String exts[] = ((Tool)tool).getAllOutputExtensions(project); Set<String> extsSet = new HashSet<String>(Arrays.asList(exts)); ITool compatibleTool = null; for (ITool t : allTools) { String otherExts[] = ((Tool)t).getAllOutputExtensions(project); for (String otherExt : otherExts) { if(extsSet.contains(otherExt)){ compatibleTool = t; break; } } if(compatibleTool != null) break; } if(compatibleTool == null){ //try to match build output variable Set<String> set = getToolOutputVars(tool); for (ITool t: allTools) { IOutputType types[] = t.getOutputTypes(); for (IOutputType type : types) { String var = type.getBuildVariable(); if(var != null && set.contains(var)){ compatibleTool = t; break; } } if(compatibleTool != null) break; } } return compatibleTool; } private Set<String> getToolOutputVars(ITool tool){ Set<String> set = new HashSet<String>(); IOutputType types[] = tool.getOutputTypes(); for (IOutputType type : types) { String var = type.getBuildVariable(); if(var != null) set.add(var); } return set; } private Object[] getTargetTool(ITool tool){ String [] ids = toolChain.getTargetToolList(); for (String id : ids) { ITool target = tool; for(; target != null; target = target.getSuperClass()){ if(id.equals(target.getId())) break; } if(target != null) return new Object[]{target, id}; } return null; } // private List<ConverterInfo> invokeConverters(Map<?, ConverterInfo> converterMap){ // List<ConverterInfo> failed = new ArrayList<ConverterInfo>(); // for(ConverterInfo info : converterMap.values()){ // IBuildObject converted = info.getConvertedFromObject(); // if(converted == null || // !converted.getClass().equals(info.getFromObject().getClass())){ // failed.add(info); // } // } // return failed; // } // private Map<ITool, ConverterInfo> calculateConverterTools(ITool[] removed, ITool[] added, List<ITool> remainingRemoved, List<ITool> remainingAdded){ // if(remainingAdded == null) // remainingAdded = new ArrayList<ITool>(added.length); // if(remainingRemoved == null) // remainingRemoved = new ArrayList<ITool>(removed.length); // // remainingAdded.clear(); // remainingRemoved.clear(); // // remainingAdded.addAll(Arrays.asList(added)); // remainingRemoved.addAll(Arrays.asList(removed)); // // Map<ITool, ConverterInfo> resultMap = new HashMap<ITool, ConverterInfo>(); // // for(Iterator<ITool> rIter = remainingRemoved.iterator(); rIter.hasNext();){ // ITool r = rIter.next(); // // if(r.getParentResourceInfo() != this) // continue; // // if(ManagedBuildManager.getConversionElements(r).size() == 0) // continue; // // for(Iterator<ITool> aIter = remainingAdded.iterator(); aIter.hasNext();){ // ITool a = aIter.next(); // // if(a.getParentResourceInfo() == this) // continue; // // IConfigurationElement el = getToolConverterElement(r, a); // if(el != null){ // resultMap.put(r, new ConverterInfo(this, r, a, el)); // rIter.remove(); // aIter.remove(); // break; // } // } // } // // return resultMap; // } private ITool[] calculateToolsArray(ITool[] removed, ITool[] added){ LinkedHashMap<Object, ITool> map = createRealToExtToolMap(getTools(), false); LinkedHashMap<Object, ITool> removedMap = createRealToExtToolMap(removed, false); map.keySet().removeAll(removedMap.keySet()); map.putAll(createRealToExtToolMap(added, true)); return map.values().toArray(new ITool[map.size()]); } @SuppressWarnings("unchecked") private ITool[][] calculateConflictingTools(ITool[] newTools){ HashSet<ITool> set = new HashSet<ITool>(); set.addAll(Arrays.asList(newTools)); List<ITool[]> result = new ArrayList<ITool[]>(); for(Iterator<ITool> iter = set.iterator(); iter.hasNext();){ ITool t = iter.next(); iter.remove(); HashSet<ITool> tmp = (HashSet<ITool>)set.clone(); List<ITool> list = new ArrayList<ITool>(); for(Iterator<ITool> tmpIt = tmp.iterator(); tmpIt.hasNext();){ ITool other = tmpIt.next(); String conflicts[] = getConflictingInputExts(t, other); if(conflicts.length != 0){ list.add(other); tmpIt.remove(); } } if(list.size() != 0){ list.add(t); result.add(list.toArray(new Tool[list.size()])); } set = tmp; iter = set.iterator(); } return result.toArray(new ITool[result.size()][]); } private String[] getConflictingInputExts(ITool tool1, ITool tool2){ IProject project = getParent().getOwner().getProject(); String ext1[] = ((Tool)tool1).getAllInputExtensions(project); String ext2[] = ((Tool)tool2).getAllInputExtensions(project); Set<String> set1 = new HashSet<String>(Arrays.asList(ext1)); Set<String> result = new HashSet<String>(); for(String e : ext2){ if(set1.remove(e)) result.add(e); } return result.toArray(new String[result.size()]); } public IModificationStatus getToolChainModificationStatus(ITool[] removed, ITool[] added){ ITool[][] checked = checkDups(removed, added); removed = checked[0]; added = checked[1]; ITool newTools[] = calculateToolsArray(removed, added); ITool[][] conflicting = calculateConflictingTools(filterTools(newTools, getParent().getManagedProject())); Map<String, String> unspecifiedRequiredProps = new HashMap<String, String>(); Map<String, String> unspecifiedProps = new HashMap<String, String>(); Set<String> undefinedSet = new HashSet<String>(); IConfiguration cfg = getParent(); ITool[] nonManagedTools = null; if(cfg.isManagedBuildOn() && cfg.supportsBuild(true)){ List<ITool> list = new ArrayList<ITool>(); for(ITool t : newTools) if(!t.supportsBuild(true)) list.add(t); if(list.size() != 0) nonManagedTools = list.toArray(new Tool[list.size()]); } return new ModificationStatus(unspecifiedRequiredProps, unspecifiedProps, undefinedSet, conflicting, nonManagedTools); } public boolean supportsBuild(boolean managed) { if(getRequiredUnspecifiedProperties().size() != 0) return false; ToolChain tCh = (ToolChain)getToolChain(); if(tCh == null || !tCh.getSupportsManagedBuildAttribute()) return !managed; ITool tools[] = getFilteredTools(); for(int i = 0; i < tools.length; i++){ if(!tools[i].supportsBuild(managed)) return false; } return true; } public boolean buildsFileType(String srcExt) { // Check to see if there is a rule to build a file with this extension ITool[] tools = getFilteredTools(); for (ITool tool : tools) { if (tool != null && tool.buildsFileType(srcExt)) { return true; } } return false; } public String getOutputExtension(String resourceExtension) { String outputExtension = null; ITool[] tools = getFilteredTools(); for (ITool tool : tools) { outputExtension = tool.getOutputExtension(resourceExtension); if (outputExtension != null) { return outputExtension; } } return null; } public boolean isHeaderFile(String ext) { // Check to see if there is a rule to build a file with this extension IManagedProject manProj = getParent().getManagedProject(); IProject project = null; if (manProj != null) { project = (IProject)manProj.getOwner(); } ITool[] tools = getFilteredTools(); for (ITool tool : tools) { try { if (project != null) { // Make sure the tool is right for the project switch (tool.getNatureFilter()) { case ITool.FILTER_C: if (project.hasNature(CProjectNature.C_NATURE_ID) && !project.hasNature(CCProjectNature.CC_NATURE_ID)) { return tool.isHeaderFile(ext); } break; case ITool.FILTER_CC: if (project.hasNature(CCProjectNature.CC_NATURE_ID)) { return tool.isHeaderFile(ext); } break; case ITool.FILTER_BOTH: return tool.isHeaderFile(ext); } } else { return tool.isHeaderFile(ext); } } catch (CoreException e) { continue; } } return false; } @Override public Set<String> contributeErrorParsers(Set<String> set){ if(toolChain != null) set = toolChain.contributeErrorParsers(this, set, true); return set; } @Override public void resetErrorParsers() { if(toolChain != null) toolChain.resetErrorParsers(this); } @Override void removeErrorParsers(Set<String> set) { if(toolChain != null) toolChain.removeErrorParsers(this, set); } @Override public ITool getToolById(String id) { if(toolChain != null) return toolChain.getTool(id); return null; } @Override void resolveProjectReferences(boolean onLoad){ if(toolChain != null) toolChain.resolveProjectReferences(onLoad); } public void resetOptionSettings() { // We just need to remove all Options ITool[] tools = getTools(); IToolChain toolChain = getToolChain(); IOption[] opts; // Send out the event to notify the options that they are about to be removed. // Do not do this for the child resource configurations as they are handled when // the configuration itself is destroyed. // ManagedBuildManager.performValueHandlerEvent(this, IManagedOptionValueHandler.EVENT_CLOSE, false); // Remove the configurations for (ITool tool : tools) { opts = tool.getOptions(); for (IOption opt : opts) { tool.removeOption(opt); } } opts = toolChain.getOptions(); for (IOption opt : opts) { toolChain.removeOption(opt); } // rebuildNeeded = true; } @Override public boolean hasCustomSettings(){ IFolderInfo parentFo = getParentFolderInfo(); if(parentFo == null) return true; return toolChain.hasCustomSettings((ToolChain)parentFo.getToolChain()); } public boolean containsDiscoveredScannerInfo(){ if(!isRoot()) return true; return containsDiscoveredScannerInfo; } public void setContainsDiscoveredScannerInfo(boolean contains){ containsDiscoveredScannerInfo = contains; } @Override public boolean isFolderInfo() { return true; } @Override void performPostModificationAdjustments(ToolListModificationInfo info) { adjustTargetTools(info.getRemovedTools(), info.getAddedTools(true)); super.performPostModificationAdjustments(info); } @Override void applyToolsInternal(ITool[] resultingTools, ToolListModificationInfo info) { ITool[] removedTools = info.getRemovedTools(); for (ITool tool : removedTools) { ITool extTool = ManagedBuildManager.getExtensionTool(tool); if(extTool.getParent() == toolChain.getSuperClass()) toolChain.addUnusedChild(extTool); } toolChain.setToolsInternal(resultingTools); adjustTargetTools(removedTools, info.getAddedTools(true)); setRebuildState(true); } public boolean isSupported(){ if(toolChain != null) return toolChain.isSupported(); return false; } // private IConfigurationElement getToolConverterElement(ITool fromTool, ITool toTool){ // ToolChain curTc = (ToolChain)getToolChain(); // if(curTc != null){ // return curTc.getConverterModificationElement(fromTool, toTool); // } // return null; // } }