/******************************************************************************* * Copyright (c) 2007, 2009 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 java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.Map; import org.eclipse.cdt.core.settings.model.ICLanguageSettingEntry; import org.eclipse.cdt.core.settings.model.extension.CLanguageData; import org.eclipse.cdt.core.settings.model.util.CDataUtil; import org.eclipse.cdt.core.settings.model.util.IKindBasedInfo; import org.eclipse.cdt.core.settings.model.util.KindBasedStore; import org.eclipse.cdt.managedbuilder.core.BuildException; import org.eclipse.cdt.managedbuilder.core.IBuildObject; import org.eclipse.cdt.managedbuilder.core.IConfiguration; import org.eclipse.cdt.managedbuilder.core.IInputType; import org.eclipse.cdt.managedbuilder.core.IOption; import org.eclipse.cdt.managedbuilder.core.IResourceInfo; 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.core.FolderInfo; import org.eclipse.cdt.managedbuilder.internal.core.InputType; import org.eclipse.cdt.managedbuilder.internal.core.ResourceConfiguration; /** * This class holds the language data for managed build tool * * It current holds both the main kind => BuildEntryStorage * mapping as well as mappings on the currently undef'd kinds * (e.g. a language setting entry defined by scanner discovery * but later re-defined by a build system setting ) */ public class BuildLanguageData extends CLanguageData { private static final IOption[] EMPTY_OPTION_ARRAY = new IOption[0]; private final String fId; private ITool fTool; private IInputType fInputType; /** The main kind => BuildEntryStorage store * The BuildEntryStorage calls back to this BuildLanguageData * to work out which entries are actually (un)defined. */ private KindBasedStore<BuildEntryStorage> fKindToEntryStore = new KindBasedStore<BuildEntryStorage>(); /** Indicates that the option array stores have been inited */ private volatile boolean fOptionStoreInited; private KindBasedStore<IOption[]> fKindToOptionArrayStore = new KindBasedStore<IOption[]>(); private KindBasedStore<IOption[]> fKindToUndefOptionArrayStore = new KindBasedStore<IOption[]>(); // private Map fKindToEntryArrayMap = new HashMap(); // private ProfileInfoProvider fDiscoveredInfo; public BuildLanguageData(ITool tool, IInputType inType){ fTool = tool; if(inType != null){ // inType = tool.getEdtableInputType(inType); fInputType = inType; if(inType.getParent() != tool) throw new IllegalArgumentException(); // IInputType extType = inType; // for(;extType != null && !extType.isExtensionElement(); extType = extType.getSuperClass()); // String typeId; // if(extType != null) // typeId = extType.getId(); // else // typeId = inType.getId(); fId = inType.getId();//new StringBuffer(fTool.getId()).append(".").append(typeId).toString(); } else { fInputType = null; fId = new StringBuffer(fTool.getId()).append(".").append("languagedata").toString(); //$NON-NLS-1$ //$NON-NLS-2$ } // fDiscoveredInfo = new ProfileInfoProvider(this); } private void obtainEditableInputType(){ if(fInputType != null){ // IInputType old = fInputType; fInputType = fTool.getEditableInputType(fInputType); // if(old != fInputType){ // fDiscoveredInfo.checkUpdateInputType(fInputType); // } } } @Override public void setEntries(int kind, ICLanguageSettingEntry entries[]) { BuildEntryStorage storage = getEntryStorage(kind); if(storage != null) storage.setEntries(entries); } private BuildEntryStorage getEntryStorage(int kind){ if(getOptionsForKind(kind).length == 0 && isToolChainDiscoveryProfile()) return null; BuildEntryStorage storage = fKindToEntryStore.get(kind); if(storage == null){ storage = new BuildEntryStorage(kind, this); fKindToEntryStore.put(kind, storage); } return storage; } private void notifyOptionsChangeForKind(int kind){ fOptionStoreInited = false; BuildEntryStorage storage = getEntryStorage(kind); if(storage != null) storage.optionsChanged(); } public void optionsChanged(int type){ int kind = ManagedBuildManager.optionTypeToEntryKind(type); if(kind == 0) kind = ManagedBuildManager.optionUndefTypeToEntryKind(type); if(kind != 0) notifyOptionsChangeForKind(kind); } // private ProfileInfoProvider getDiscoveredInfoProvider(){ // return fDiscoveredInfo; // } /* private String getOptionValueFromEntry(ICLanguageSettingEntry entry){ String optValue = entry.getName(); if(entry.getKind() == ICLanguageSettingEntry.MACRO){ String macroValue = entry.getValue(); StringBuffer buf = new StringBuffer(optValue).append('=').append(macroValue); optValue = buf.toString(); } return optValue; } */ @Override public String getLanguageId() { return fInputType != null ? fInputType.getLanguageId(fTool) : null; } @Override public ICLanguageSettingEntry[] getEntries(int kinds) { List<ICLanguageSettingEntry> list = new ArrayList<ICLanguageSettingEntry>(); if((kinds & ICLanguageSettingEntry.INCLUDE_PATH) != 0) { BuildEntryStorage storage = getEntryStorage(ICLanguageSettingEntry.INCLUDE_PATH); if(storage != null) storage.getEntries(list); } else if((kinds & ICLanguageSettingEntry.INCLUDE_FILE) != 0) { BuildEntryStorage storage = getEntryStorage(ICLanguageSettingEntry.INCLUDE_FILE); if(storage != null) storage.getEntries(list); } else if((kinds & ICLanguageSettingEntry.MACRO) != 0) { BuildEntryStorage storage = getEntryStorage(ICLanguageSettingEntry.MACRO); if(storage != null) storage.getEntries(list); } else if((kinds & ICLanguageSettingEntry.MACRO_FILE) != 0) { BuildEntryStorage storage = getEntryStorage(ICLanguageSettingEntry.MACRO_FILE); if(storage != null) storage.getEntries(list); } else if((kinds & ICLanguageSettingEntry.LIBRARY_PATH) != 0) { BuildEntryStorage storage = getEntryStorage(ICLanguageSettingEntry.LIBRARY_PATH); if(storage != null) storage.getEntries(list); } else if((kinds & ICLanguageSettingEntry.LIBRARY_FILE) != 0) { BuildEntryStorage storage = getEntryStorage(ICLanguageSettingEntry.LIBRARY_FILE); if(storage != null) storage.getEntries(list); } return list.toArray(new ICLanguageSettingEntry[list.size()]); } public void updateInputType(IInputType type){ fInputType = type; } @Override public String[] getSourceContentTypeIds() { if(fInputType != null){ return fInputType.getSourceContentTypeIds(); } return null; } @Override public String[] getSourceExtensions() { return fInputType != null ? fInputType.getSourceExtensions(fTool) : fTool.getPrimaryInputExtensions(); } @Override public int getSupportedEntryKinds() { KindBasedStore<IOption[]> store = getKindToOptionArrayStore(); IKindBasedInfo<IOption[]>[] infos = store.getContents(); int kinds = 0; for(int i = 0; i < infos.length; i++){ if(infos[i].getInfo().length > 0) kinds |= infos[i].getKind(); } return kinds; } private KindBasedStore<IOption[]> getKindToOptionArrayStore(){ initOptionStores(); return fKindToOptionArrayStore; } private void initOptionStores() { if(!fOptionStoreInited) { synchronized (this) { if(!fOptionStoreInited) { calculateKindToOptionArrayStore(); calculateKindToUndefOptionArrayStore(); fOptionStoreInited = true; } } } } private KindBasedStore<IOption[]> getKindToUndefOptionArrayStore(){ initOptionStores(); return fKindToUndefOptionArrayStore; } private void calculateKindToOptionArrayStore(){ fKindToOptionArrayStore.clear(); Map<Integer, List<IOption>> kindToOptionList = new HashMap<Integer, List<IOption>>(); IOption options[] = fTool.getOptions(); for (final IOption option : options) { try { Integer entryKind = ManagedBuildManager.optionTypeToEntryKind(option.getValueType()); if(entryKind != 0){ if (!kindToOptionList.containsKey(entryKind)) kindToOptionList.put(entryKind, new ArrayList<IOption>(3){{add(option);}}); else kindToOptionList.get(entryKind).add(option); } } catch (BuildException e) { } } IKindBasedInfo<IOption[]>[] infos = fKindToOptionArrayStore.getContents(); for (IKindBasedInfo<IOption[]> info : infos) { List<IOption> list = kindToOptionList.get(info.getKind()); if(list != null){ IOption[] opts = list.toArray(new IOption[list.size()]); info.setInfo(opts); } else { info.setInfo(EMPTY_OPTION_ARRAY); } } } private void calculateKindToUndefOptionArrayStore(){ fKindToUndefOptionArrayStore.clear(); Map<Integer, List<IOption>> kindToOptionList = new HashMap<Integer, List<IOption>>(); IOption options[] = fTool.getOptions(); for (final IOption option : options) { try { Integer entryKind = ManagedBuildManager.optionUndefTypeToEntryKind(option.getValueType()); if(entryKind != 0){ if (!kindToOptionList.containsKey(entryKind)) kindToOptionList.put(entryKind, new ArrayList<IOption>(3){{add(option);}}); else kindToOptionList.get(entryKind).add(option); } } catch (BuildException e) { } } IKindBasedInfo<IOption[]>[] infos = fKindToUndefOptionArrayStore.getContents(); for (IKindBasedInfo<IOption[]> info : infos) { List<IOption> list = kindToOptionList.get(info.getKind()); if(list != null){ IOption[] opts = list.toArray(new IOption[list.size()]); info.setInfo(opts); } else { info.setInfo(EMPTY_OPTION_ARRAY); } } } IOption[] getUndefOptionsForKind(int entryKind){ KindBasedStore<IOption[]> store = getKindToUndefOptionArrayStore(); return store.get(entryKind); } IOption[] getOptionsForKind(int entryKind){ KindBasedStore<IOption[]> store = getKindToOptionArrayStore(); return store.get(entryKind); } /* private IOption[] getOptionsForType(int type){ Map map = getTypeToOptionArrayMap(); return (IOption[])map.get(new Integer(type)); } */ @Override public void setLanguageId(String id) { if(CDataUtil.objectsEqual(id, fInputType.getLanguageId(fTool))){ // fInputType = fTool.getEdtableInputType(fInputType); obtainEditableInputType(); fInputType.setLanguageIdAttribute(id); } } @Override public String getId() { return fId; } @Override public String getName() { String name; if(fInputType == null){ name = fTool.getName(); if(name == null){ String[] exts = getSourceExtensions(); if(exts.length != 0){ name = CDataUtil.arrayToString(exts, ","); //$NON-NLS-1$ } else { name = fTool.getId(); } } } else { name = fInputType.getLanguageName(fTool); } return name; } @Override public boolean isValid() { // TODO Auto-generated method stub return true; } public void setName(String name) { // TODO Auto-generated method stub } public ITool getTool(){ return fTool; } public IInputType getInputType() { return fInputType; } boolean isToolChainDiscoveryProfile(){ return fInputType != null ? ((InputType)fInputType).getDiscoveryProfileIdAttribute() == null : true; } String getDiscoveryProfileId(){ if(fInputType != null) return fInputType.getDiscoveryProfileId(fTool); IBuildObject bo = fTool.getParent(); if(bo instanceof IToolChain) return ((IToolChain)bo).getScannerConfigDiscoveryProfileId(); else if(bo instanceof IResourceInfo){ IToolChain tCh = ((ResourceConfiguration)bo).getBaseToolChain(); if(tCh != null) return tCh.getScannerConfigDiscoveryProfileId(); } return null; } public IConfiguration getConfiguration(){ return fTool.getParentResourceInfo().getParent(); } @Override public void setSourceContentTypeIds(String[] ids) { String[] headerIds = fInputType.getHeaderContentTypeIds(); List<String> newSrc = new ArrayList<String>(ids.length); List<String> newHeaders = new ArrayList<String>(ids.length); for(int i = 0; i < ids.length; i++){ String id = ids[i]; int j = 0; for(; j < headerIds.length; j++){ if(id.equals(headerIds[j])){ newHeaders.add(id); break; } } if(j == headerIds.length){ newSrc.add(id); } } String newSrcIds[] = newSrc.toArray(new String[newSrc.size()]); String newHeaderIds[] = newHeaders.toArray(new String[newHeaders.size()]); if(!Arrays.equals(newSrcIds, fInputType.getSourceContentTypeIds())){ // fInputType = fTool.getEdtableInputType(fInputType); obtainEditableInputType(); fInputType.setSourceContentTypeIds(newSrcIds); } if(!Arrays.equals(newHeaderIds, fInputType.getHeaderContentTypeIds())){ // fInputType = fTool.getEdtableInputType(fInputType); obtainEditableInputType(); fInputType.setHeaderContentTypeIds(newHeaderIds); } } @Override public void setSourceExtensions(String[] exts) { // TODO Auto-generated method stub } void clearCachedData(){ fKindToEntryStore.clear(); } @Override public boolean containsDiscoveredScannerInfo() { IResourceInfo rcInfo = fTool.getParentResourceInfo(); if(rcInfo instanceof FolderInfo){ return ((FolderInfo)rcInfo).containsDiscoveredScannerInfo(); } return true; } }