From 11b35857bf35d20a72eae2537dadbf7ddc26c83c Mon Sep 17 00:00:00 2001 From: Mikhail Sennikovsky Date: Thu, 31 May 2007 12:46:56 +0000 Subject: [PATCH] 1. Fix for [Bug 188963] New builder need to tell build system to manual build 2. Fix for [Bug 189302] Build command for make target should default to the project one 3. Small bug-fixes --- .../core/ManagedBuildManager.java | 2 + .../managedbuilder/internal/core/Builder.java | 134 +++++++++++++++++- .../internal/core/BuilderFactory.java | 61 +++++++- .../ConfigurationDataProvider.java | 42 ++++++ .../settings/model/IModificationContext.java | 26 ++++ .../extension/CConfigurationDataProvider.java | 46 +++++- .../model/CConfigurationDescriptionCache.java | 5 +- .../settings/model/CProjectDescription.java | 5 +- .../model/CProjectDescriptionManager.java | 59 ++++---- .../SetCProjectDescriptionOperation.java | 26 ++-- .../core/settings/model/SettingsContext.java | 92 ++++++++++++ 11 files changed, 442 insertions(+), 56 deletions(-) create mode 100644 core/org.eclipse.cdt.core/model/org/eclipse/cdt/core/settings/model/IModificationContext.java create mode 100644 core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/settings/model/SettingsContext.java diff --git a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/core/ManagedBuildManager.java b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/core/ManagedBuildManager.java index 1abe6f418b2..fd9b03ef389 100644 --- a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/core/ManagedBuildManager.java +++ b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/core/ManagedBuildManager.java @@ -3882,6 +3882,8 @@ public class ManagedBuildManager extends AbstractCExtension implements IScannerI } private static ICConfigurationDescription getDescriptionForConfiguration(IConfiguration cfg, boolean checkConsistance){ + if(cfg.isExtensionElement()) + return null; ICConfigurationDescription des = ((Configuration)cfg).getConfigurationDescription(); if(des == null){ if(checkConsistance) diff --git a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/Builder.java b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/Builder.java index cf409be9a5b..c5ea71915c9 100644 --- a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/Builder.java +++ b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/Builder.java @@ -835,6 +835,87 @@ public class Builder extends BuildObject implements IBuilder, IMatchKeyProvider isDirty = false; } } + + public void serializeRawData(ICStorageElement element) { + if (superClass != null) + element.setAttribute(IProjectType.SUPERCLASS, superClass.getId()); + + element.setAttribute(IBuildObject.ID, id); + + if (getName() != null) { + element.setAttribute(IBuildObject.NAME, getName()); + } + + if (unusedChildren != null) { + element.setAttribute(IProjectType.UNUSED_CHILDREN, unusedChildren); + } + + if (isAbstract != null) { + element.setAttribute(IProjectType.IS_ABSTRACT, isAbstract.toString()); + } + + // versionsSupported + if (versionsSupported != null) { + element.setAttribute(VERSIONS_SUPPORTED, versionsSupported); + } + + // convertToId + if (convertToId != null) { + element.setAttribute(CONVERT_TO_ID, convertToId); + } + + if (getErrorParserIds() != null) { + element.setAttribute(IToolChain.ERROR_PARSERS, getErrorParserIds()); + } + + if (getCommand() != null) { + element.setAttribute(IBuilder.COMMAND, getCommand()); + } + + if (getArgumentsAttribute() != null) { + element.setAttribute(IBuilder.ARGUMENTS, getArgumentsAttribute()); + } + + if(getAutoBuildTargetAttribute() != null) + element.setAttribute(ATTRIBUTE_TARGET_AUTO, getAutoBuildTargetAttribute()); + element.setAttribute(ATTRIBUTE_AUTO_ENABLED, Boolean.valueOf(isAutoBuildEnable()).toString()); + if(getIncrementalBuildTargetAttribute() != null) + element.setAttribute(ATTRIBUTE_TARGET_INCREMENTAL, getIncrementalBuildTargetAttribute()); + element.setAttribute(ATTRIBUTE_INCREMENTAL_ENABLED, Boolean.valueOf(isIncrementalBuildEnabled()).toString()); + if(getCleanBuildTargetAttribute() != null) + element.setAttribute(ATTRIBUTE_TARGET_CLEAN, getCleanBuildTargetAttribute()); + element.setAttribute(ATTRIBUTE_CLEAN_ENABLED, Boolean.valueOf(isCleanBuildEnabled()).toString()); + element.setAttribute(ATTRIBUTE_MANAGED_BUILD_ON, Boolean.valueOf(isManagedBuildOn()).toString()); + element.setAttribute(ATTRIBUTE_KEEP_ENV, Boolean.valueOf(keepEnvironmentVariablesInBuildfile()).toString()); + element.setAttribute(ATTRIBUTE_SUPORTS_MANAGED_BUILD, Boolean.valueOf(supportsBuild(true)).toString()); + if(customizedErrorParserIds != null) + element.setAttribute(ATTRIBUTE_CUSTOMIZED_ERROR_PARSERS, CDataUtil.arrayToString(customizedErrorParserIds, ";")); //$NON-NLS-1$ + if(customizedEnvironment != null) + element.setAttribute(ATTRIBUTE_ENVIRONMENT, MapStorageElement.encodeMap(customizedEnvironment)); + element.setAttribute(ATTRIBUTE_APPEND_ENVIRONMENT, Boolean.valueOf(appendEnvironment()).toString()); + if(getBuildPathAttribute() != null) + element.setAttribute(ATTRIBUTE_BUILD_PATH, getBuildPathAttribute()); + if(customBuildProperties != null) + element.setAttribute(ATTRIBUTE_CUSTOM_PROPS, MapStorageElement.encodeMap(customBuildProperties)); + + if(getIgnoreErrCmdAttribute() != null) + element.setAttribute(ATTRIBUTE_IGNORE_ERR_CMD, getIgnoreErrCmdAttribute()); + element.setAttribute(ATTRIBUTE_STOP_ON_ERR, Boolean.valueOf(isStopOnError()).toString()); + if(getParrallelBuildCmd() != null) + element.setAttribute(ATTRIBUTE_PARALLEL_BUILD_CMD, getParrallelBuildCmd()); + element.setAttribute(ATTRIBUTE_PARALLELIZATION_NUMBER, new Integer(getParallelizationNumAttribute()).toString()); + element.setAttribute(ATTRIBUTE_PARALLEL_BUILD_ON, Boolean.valueOf(isParallelBuildOn()).toString()); + // Note: build file generator cannot be specified in a project file because + // an IConfigurationElement is needed to load it! + if (buildFileGeneratorElement != null) { + // TODO: issue warning? + } + + if(outputEntries != null){ + ICStorageElement outEl = element.createChild(OUTPUT_ENTRIES); + LanguageSettingEntriesSerializer.serializeEntries(outputEntries, outEl); + } + } /* * P A R E N T A N D C H I L D H A N D L I N G @@ -1101,6 +1182,14 @@ public class Builder extends BuildObject implements IBuilder, IMatchKeyProvider public void setArguments(String newArgs) { if(getArguments().equals(newArgs)) return; + + if(newArgs != null){ + String stopOnErrCmd = getStopOnErrCmd(isStopOnError()); + String parallelBuildCmd = isParallelBuildOn() ? getParallelizationCmd(getParallelizationNum()) : EMPTY_STRING; + + newArgs = removeCmd(newArgs, stopOnErrCmd); + newArgs = removeCmd(newArgs, parallelBuildCmd); + } setArgumentsAttribute(newArgs); } @@ -1810,7 +1899,7 @@ public class Builder extends BuildObject implements IBuilder, IMatchKeyProvider if(autoBuildEnabled == null){ if(superClass != null) return superClass.isAutoBuildEnable(); - return true; + return false; } return autoBuildEnabled.booleanValue(); } @@ -1969,6 +2058,49 @@ public class Builder extends BuildObject implements IBuilder, IMatchKeyProvider return new String[0]; } + public static String toBuilderAttribute(String name) { + + if(BUILD_TARGET_INCREMENTAL.equals(name) + || BuilderFactory.BUILD_TARGET_INCREMENTAL.equals(name) + || BUILD_TARGET_FULL.equals(name) + || BuilderFactory.BUILD_TARGET_FULL.equals(name)){ + return ATTRIBUTE_TARGET_INCREMENTAL; + } else if (BUILD_TARGET_AUTO.equals(name) + || BuilderFactory.BUILD_TARGET_AUTO.equals(name)) { + return ATTRIBUTE_TARGET_AUTO; + } else if (BUILD_TARGET_CLEAN.equals(name) + || BuilderFactory.BUILD_TARGET_CLEAN.equals(name)) { + return ATTRIBUTE_TARGET_CLEAN; + } else if (BUILD_LOCATION.equals(name) + || BuilderFactory.BUILD_LOCATION.equals(name)) { + return ATTRIBUTE_BUILD_PATH; + } else if (BUILD_COMMAND.equals(name) + || BuilderFactory.BUILD_COMMAND.equals(name)) { + return COMMAND; + } else if (BUILD_ARGUMENTS.equals(name) + || BuilderFactory.BUILD_ARGUMENTS.equals(name)) { + return ARGUMENTS; + } else if (BuilderFactory.STOP_ON_ERROR.equals(name)) { + return ATTRIBUTE_STOP_ON_ERR; + } //TODO else if(BuilderFactory.USE_DEFAULT_BUILD_CMD.equals(name)){ + // return getCommand(); + //} + else if (BuilderFactory.BUILD_INCREMENTAL_ENABLED.equals(name) + || BuilderFactory.BUILD_FULL_ENABLED.equals(name)) { + return ATTRIBUTE_INCREMENTAL_ENABLED; + } else if (BuilderFactory.BUILD_CLEAN_ENABLED.equals(name)){ + return ATTRIBUTE_CLEAN_ENABLED; + } else if (BuilderFactory.BUILD_AUTO_ENABLED.equals(name)) { + return ATTRIBUTE_AUTO_ENABLED; + } else if (BuilderFactory.ENVIRONMENT.equals(name)) { + return ATTRIBUTE_ENVIRONMENT; + } else if (BuilderFactory.BUILD_APPEND_ENVIRONMENT.equals(name)){ + return ATTRIBUTE_APPEND_ENVIRONMENT; + } else if (ErrorParserManager.PREF_ERROR_PARSER.equals(name)) { + return ATTRIBUTE_CUSTOMIZED_ERROR_PARSERS; + } + return null; + } public Map getEnvironment() { diff --git a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/BuilderFactory.java b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/BuilderFactory.java index 67b1da75445..b3aeaa699ea 100644 --- a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/BuilderFactory.java +++ b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/BuilderFactory.java @@ -18,7 +18,6 @@ import java.util.Map; import org.eclipse.cdt.core.ErrorParserManager; import org.eclipse.cdt.make.core.IMakeCommonBuildInfo; -import org.eclipse.cdt.make.internal.core.BuildInfoFactory; import org.eclipse.cdt.managedbuilder.core.IBuilder; import org.eclipse.cdt.managedbuilder.core.IConfiguration; import org.eclipse.cdt.managedbuilder.core.IManagedBuildInfo; @@ -26,9 +25,11 @@ import org.eclipse.cdt.managedbuilder.core.IManagedProject; import org.eclipse.cdt.managedbuilder.core.IToolChain; import org.eclipse.cdt.managedbuilder.core.ManagedBuildManager; import org.eclipse.cdt.managedbuilder.core.ManagedBuilderCorePlugin; +import org.eclipse.cdt.managedbuilder.core.ManagedCProjectNature; import org.eclipse.core.resources.ICommand; import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IProjectDescription; +import org.eclipse.core.resources.IncrementalProjectBuilder; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Status; @@ -36,7 +37,7 @@ import org.eclipse.core.runtime.Status; public class BuilderFactory { private static final String PREFIX = "org.eclipse.cdt.make.core"; //$NON-NLS-1$ - private static final String PREFIX_WITH_DOT = PREFIX + '.'; //$NON-NLS-1$ +// private static final String PREFIX_WITH_DOT = PREFIX + '.'; //$NON-NLS-1$ static final String BUILD_COMMAND = PREFIX + ".buildCommand"; //$NON-NLS-1$ static final String BUILD_LOCATION = PREFIX + ".buildLocation"; //$NON-NLS-1$ @@ -95,6 +96,17 @@ public class BuilderFactory { // return super.getMapKey(name); // } + public void setAttribute(String name, String value) { + String[] names = Builder.toBuildAttributes(name); + String attrName = names.length != 0 ? names[names.length - 1] : null; + + if(attrName == null && BuilderFactory.USE_DEFAULT_BUILD_CMD.equals(name)) + attrName = BuilderFactory.USE_DEFAULT_BUILD_CMD; + + if(attrName != null) + super.setAttribute(attrName, value); + } + protected MapStorageElement createChildElement(Map childMap) { return new BuildArgsStorageElement(childMap, this); } @@ -208,6 +220,16 @@ public class BuilderFactory { return el.toStringMap(); } + private static Map builderBuildArgsMap(IBuilder builder){ + MapStorageElement el = new BuildArgsStorageElement("", null); //$NON-NLS-1$ + ((Builder)builder).serializeRawData(el); + + Boolean d = Boolean.valueOf(builder.isDefaultBuildCmd()); + el.setAttribute(BuilderFactory.USE_DEFAULT_BUILD_CMD, d.toString()); + + return el.toStringMap(); + } + public static IBuilder createCustomBuilder(IConfiguration cfg, String builderId) throws CoreException{ IBuilder builder = cfg.getBuilder(); if(!builderId.equals(builder.getId())){ @@ -374,4 +396,39 @@ public class BuilderFactory { return builders; return EMPTY_BUILDERS_ARRAY; } + + public static int applyBuilder(IProjectDescription eDes, IBuilder builder){ + return applyBuilder(eDes, CommonBuilder.BUILDER_ID, builder); + } + + public static final int CMD_UNDEFINED = -1; + public static final int NO_CHANGES = 0; + public static final int CMD_CHANGED = 1; + + public static int applyBuilder(IProjectDescription eDes, String eBuilderId, IBuilder builder){ + ICommand cmd = ManagedCProjectNature.getBuildSpec(eDes, eBuilderId); + if(cmd == null) + return CMD_UNDEFINED; + + if(applyBuilder(cmd, builder)){ + ManagedCProjectNature.setBuildSpec(eDes, cmd); + return CMD_CHANGED; + } + return NO_CHANGES; + } + public static boolean applyBuilder(ICommand cmd, IBuilder builder) { + Map oldMap = cmd.getArguments(); + Map map = builderBuildArgsMap(builder); + + if(oldMap.equals(map)) + return false; + + cmd.setArguments(map); + + cmd.setBuilding(IncrementalProjectBuilder.AUTO_BUILD, builder.isAutoBuildEnable()); + cmd.setBuilding(IncrementalProjectBuilder.FULL_BUILD, builder.isFullBuildEnabled()); + cmd.setBuilding(IncrementalProjectBuilder.INCREMENTAL_BUILD, builder.isIncrementalBuildEnabled()); + cmd.setBuilding(IncrementalProjectBuilder.CLEAN_BUILD, builder.isCleanBuildEnabled()); + return true; + } } diff --git a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/dataprovider/ConfigurationDataProvider.java b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/dataprovider/ConfigurationDataProvider.java index 3d27bb30e45..dc9187c5b8c 100644 --- a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/dataprovider/ConfigurationDataProvider.java +++ b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/dataprovider/ConfigurationDataProvider.java @@ -24,9 +24,11 @@ import org.eclipse.cdt.core.model.LanguageManager; import org.eclipse.cdt.core.settings.model.ICConfigurationDescription; import org.eclipse.cdt.core.settings.model.ICProjectDescription; import org.eclipse.cdt.core.settings.model.ICStorageElement; +import org.eclipse.cdt.core.settings.model.IModificationContext; import org.eclipse.cdt.core.settings.model.extension.CConfigurationData; import org.eclipse.cdt.core.settings.model.extension.CConfigurationDataProvider; import org.eclipse.cdt.managedbuilder.core.BuildException; +import org.eclipse.cdt.managedbuilder.core.IBuilder; import org.eclipse.cdt.managedbuilder.core.IConfiguration; import org.eclipse.cdt.managedbuilder.core.IFolderInfo; import org.eclipse.cdt.managedbuilder.core.IInputType; @@ -39,6 +41,7 @@ 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.core.ManagedBuilderCorePlugin; +import org.eclipse.cdt.managedbuilder.internal.core.BuilderFactory; import org.eclipse.cdt.managedbuilder.internal.core.Configuration; import org.eclipse.cdt.managedbuilder.internal.core.ISettingsChangeListener; import org.eclipse.cdt.managedbuilder.internal.core.InputType; @@ -49,6 +52,7 @@ import org.eclipse.cdt.managedbuilder.internal.core.SettingsChangeEvent; import org.eclipse.cdt.managedbuilder.internal.core.Tool; import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IProjectDescription; +import org.eclipse.core.resources.IWorkspaceRunnable; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.QualifiedName; @@ -73,6 +77,27 @@ public class ConfigurationDataProvider extends CConfigurationDataProvider implem } } + private static class DesApplyRunnable implements IWorkspaceRunnable { + IBuilder fBuilder; + IProject fProject; + + DesApplyRunnable(IProject project, IBuilder builder){ + fProject = project; + fBuilder = builder; + } + + public void run(IProgressMonitor monitor) throws CoreException { + try { + IProjectDescription eDes = fProject.getDescription(); + if(BuilderFactory.applyBuilder(eDes, fBuilder) == BuilderFactory.CMD_CHANGED) { + fProject.setDescription(eDes, monitor); + } + } catch (Exception e){ + ManagedBuilderCorePlugin.log(e); + } + } + + } static BuildConfigurationData writeConfiguration(ICConfigurationDescription des, CConfigurationData base) throws CoreException { BuildConfigurationData appliedCfg = (BuildConfigurationData)base; @@ -107,6 +132,7 @@ public class ConfigurationDataProvider extends CConfigurationDataProvider implem ICConfigurationDescription des, ICConfigurationDescription baseDescription, CConfigurationData base, + IModificationContext context, IProgressMonitor monitor) throws CoreException { if(des.isPreferenceConfiguration()) @@ -128,6 +154,22 @@ public class ConfigurationDataProvider extends CConfigurationDataProvider implem setPersistedFlag(des); cacheNaturesIdsUsedOnCache(des); + if(des.isActive()){ + IConfiguration cfg = appliedCfg.getConfiguration(); + IBuilder builder = cfg.getEditableBuilder(); + IProject project = context.getProject(); + IProjectDescription eDes = context.getEclipseProjectDescription(); + switch(BuilderFactory.applyBuilder(eDes, builder)){ + case BuilderFactory.CMD_UNDEFINED: + IWorkspaceRunnable applyR = new DesApplyRunnable(project, builder); + context.addWorkspaceRunnable(applyR); + break; + case BuilderFactory.CMD_CHANGED: + context.setEclipseProjectDescription(eDes); + break; + } + } + return appliedCfg; } diff --git a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/core/settings/model/IModificationContext.java b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/core/settings/model/IModificationContext.java new file mode 100644 index 00000000000..c3831fefc8c --- /dev/null +++ b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/core/settings/model/IModificationContext.java @@ -0,0 +1,26 @@ +/******************************************************************************* + * Copyright (c) 2007 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.core.settings.model; + +import org.eclipse.core.resources.IProject; +import org.eclipse.core.resources.IProjectDescription; +import org.eclipse.core.resources.IWorkspaceRunnable; +import org.eclipse.core.runtime.CoreException; + +public interface IModificationContext { + IProject getProject(); + + IProjectDescription getEclipseProjectDescription() throws CoreException; + + void setEclipseProjectDescription(IProjectDescription eDes) throws CoreException; + + void addWorkspaceRunnable(IWorkspaceRunnable runnable); +} diff --git a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/core/settings/model/extension/CConfigurationDataProvider.java b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/core/settings/model/extension/CConfigurationDataProvider.java index 278af6889cc..1465ab2d682 100644 --- a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/core/settings/model/extension/CConfigurationDataProvider.java +++ b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/core/settings/model/extension/CConfigurationDataProvider.java @@ -11,6 +11,7 @@ package org.eclipse.cdt.core.settings.model.extension; import org.eclipse.cdt.core.settings.model.ICConfigurationDescription; +import org.eclipse.cdt.core.settings.model.IModificationContext; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IProgressMonitor; @@ -55,20 +56,53 @@ public abstract class CConfigurationDataProvider { public abstract void removeConfiguration(ICConfigurationDescription des, CConfigurationData data, IProgressMonitor monitor); /** - * called during the setProjectDescription operation to notify the provider that the configuration data - * is being applied. - * Provider would typically store all the necessary data configuration during this call. + * the method is called in case the implementer does NOT override + * the {@link #applyConfiguration(ICConfigurationDescription, ICConfigurationDescription, CConfigurationData, IModificationContext, IProgressMonitor)} + * method. See {@link #applyConfiguration(ICConfigurationDescription, ICConfigurationDescription, CConfigurationData, IModificationContext, IProgressMonitor)} + * for detail * * @param des * @param base * @return * @throws CoreException + * + * @see {@link #applyConfiguration(ICConfigurationDescription, ICConfigurationDescription, CConfigurationData, IModificationContext, IProgressMonitor)} */ - public abstract CConfigurationData applyConfiguration(ICConfigurationDescription des, + public CConfigurationData applyConfiguration(ICConfigurationDescription des, ICConfigurationDescription baseDescription, CConfigurationData baseData, - IProgressMonitor monitor) throws CoreException; - + IProgressMonitor monitor) throws CoreException{ + return baseData; + } + + /** + * called during the setProjectDescription operation to notify the provider that the configuration data + * is being applied. + * Provider would typically store all the necessary data configuration during this call. + * + * @param des + * @param baseDescription + * @param baseData + * @param context the {@link IModificationContext} allows registering workspace runnables to be run + * as a single batch workspace operation. + * If possible the runnables will be run directly in the apply context(thread) after all + * configuration datas get applied. Otherwise runnables will be run as a separate job. + * This allows to perform all workspace modifications registered by different configurations + * to be run as a single batch peration together with the workspace modifications performed by the + * ICProjectDesacription framework + * @param monitor + * + * @return + * @throws CoreException + */ + public CConfigurationData applyConfiguration(ICConfigurationDescription des, + ICConfigurationDescription baseDescription, + CConfigurationData baseData, + IModificationContext context, + IProgressMonitor monitor) throws CoreException{ + return applyConfiguration(des, baseDescription, baseData, monitor); + } + /** * called to notify that the configuration data was cached * implementors can do any necessary cleaning, etc. diff --git a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/settings/model/CConfigurationDescriptionCache.java b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/settings/model/CConfigurationDescriptionCache.java index a044e459ec7..f29cafe12b5 100644 --- a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/settings/model/CConfigurationDescriptionCache.java +++ b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/settings/model/CConfigurationDescriptionCache.java @@ -32,6 +32,7 @@ import org.eclipse.cdt.core.settings.model.ICSettingObject; import org.eclipse.cdt.core.settings.model.ICSourceEntry; import org.eclipse.cdt.core.settings.model.ICStorageElement; import org.eclipse.cdt.core.settings.model.ICTargetPlatformSetting; +import org.eclipse.cdt.core.settings.model.IModificationContext; import org.eclipse.cdt.core.settings.model.WriteAccessException; import org.eclipse.cdt.core.settings.model.extension.CBuildData; import org.eclipse.cdt.core.settings.model.extension.CConfigurationData; @@ -132,11 +133,11 @@ public class CConfigurationDescriptionCache extends CDefaultConfigurationData // fInitializing = false; } - void applyData(CSettingEntryFactory factory) throws CoreException{ + void applyData(CSettingEntryFactory factory, IModificationContext context) throws CoreException{ if(fBaseDescription == null) return; - fData = CProjectDescriptionManager.getInstance().applyData(this, fBaseDescription, fData, null); + fData = CProjectDescriptionManager.getInstance().applyData(this, fBaseDescription, fData, context, null); fDataLoadded = true; fName = fData.getName(); fId = fData.getId(); diff --git a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/settings/model/CProjectDescription.java b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/settings/model/CProjectDescription.java index c97f47d588d..65dd1a4b716 100644 --- a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/settings/model/CProjectDescription.java +++ b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/settings/model/CProjectDescription.java @@ -23,6 +23,7 @@ import org.eclipse.cdt.core.settings.model.ICSettingContainer; import org.eclipse.cdt.core.settings.model.ICSettingObject; import org.eclipse.cdt.core.settings.model.ICSettingsStorage; import org.eclipse.cdt.core.settings.model.ICStorageElement; +import org.eclipse.cdt.core.settings.model.IModificationContext; import org.eclipse.cdt.core.settings.model.WriteAccessException; import org.eclipse.cdt.core.settings.model.extension.CConfigurationData; import org.eclipse.cdt.core.settings.model.util.CSettingEntryFactory; @@ -205,7 +206,7 @@ public class CProjectDescription implements ICProjectDescription, ICDataProxyCon // fIsLoadding = false; } - void applyDatas(){ + void applyDatas(IModificationContext context){ if(!fIsReadOnly || !fIsApplying) return; @@ -213,7 +214,7 @@ public class CProjectDescription implements ICProjectDescription, ICDataProxyCon for(Iterator iter = fCfgMap.values().iterator(); iter.hasNext();){ CConfigurationDescriptionCache cache = (CConfigurationDescriptionCache)iter.next(); try { - cache.applyData(factory); + cache.applyData(factory, context); } catch (CoreException e) { CCorePlugin.log(e); e.printStackTrace(); diff --git a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/settings/model/CProjectDescriptionManager.java b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/settings/model/CProjectDescriptionManager.java index 599aaa86433..7c2ba9155ad 100644 --- a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/settings/model/CProjectDescriptionManager.java +++ b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/settings/model/CProjectDescriptionManager.java @@ -68,6 +68,7 @@ import org.eclipse.cdt.core.settings.model.ICSettingsStorage; import org.eclipse.cdt.core.settings.model.ICSourceEntry; import org.eclipse.cdt.core.settings.model.ICStorageElement; import org.eclipse.cdt.core.settings.model.ICTargetPlatformSetting; +import org.eclipse.cdt.core.settings.model.IModificationContext; 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; @@ -435,10 +436,10 @@ public class CProjectDescriptionManager implements ICProjectDescriptionManager { public ICProjectDescription getProjectDescription(IProject project, int flags){ ICProjectDescription des = null; - IProjectDescription eDes = null; boolean write = checkFlags(flags, GET_WRITABLE); boolean load = !checkFlags(flags, GET_IF_LOADDED); boolean ignoreClose = checkFlags(flags, INTERNAL_GET_IGNORE_CLOSE); + SettingsContext context = null; des = getDescriptionApplying(project); @@ -457,8 +458,8 @@ public class CProjectDescriptionManager implements ICProjectDescriptionManager { if(des == null){ //TODO: check if conversion needed try { - eDes = project.getDescription(); - des = getConvertedDescription(project, eDes); + context = new SettingsContext(project); + des = getConvertedDescription(project, context); } catch (CoreException e) { CCorePlugin.log(e); } @@ -467,8 +468,8 @@ public class CProjectDescriptionManager implements ICProjectDescriptionManager { if(des != null){ if(setLoaddedDescriptionOnLoad(project, des)){ - if(eDes != null) - saveConversion(project, eDes, (CProjectDescription)des, new NullProgressMonitor()); + if(context != null) + saveConversion(project, context, (CProjectDescription)des, new NullProgressMonitor()); CProjectDescriptionEvent event = createLoaddedEvent(des); notifyListeners(event); @@ -567,7 +568,7 @@ public class CProjectDescriptionManager implements ICProjectDescriptionManager { return null; } - private ICProjectDescription getConvertedDescription(IProject project, IProjectDescription eDes) throws CoreException{ + private ICProjectDescription getConvertedDescription(IProject project, SettingsContext context) throws CoreException{ Object info[] = loadProjectDescriptionFromOldstyleStorage(project); CProjectDescription des = null; String ownerId; @@ -582,8 +583,11 @@ public class CProjectDescriptionManager implements ICProjectDescriptionManager { des = null; } + IProjectDescription eDes = context.getEclipseProjectDescription(); + ICProjectConverter converter = getConverter(project, ownerId, des); if(converter != null){ + CProjectDescription convertedDes = (CProjectDescription)converter.convertProject(project, eDes, ownerId, des); if(convertedDes != null){ /// ICConfigurationDescription activeCfg = convertedDes.getActiveConfiguration(); @@ -602,6 +606,8 @@ public class CProjectDescriptionManager implements ICProjectDescriptionManager { if(des != null && des.isValid()){ //TODO: should be set via the CModel operation? InternalXmlStorageElement el = null; + context.setEclipseProjectDescription(eDes); + try { el = copyElement((InternalXmlStorageElement)des.getRootStorageElement(), false); } catch (CoreException e2) { @@ -610,7 +616,7 @@ public class CProjectDescriptionManager implements ICProjectDescriptionManager { des = new CProjectDescription(des, true, el, des.isCdtProjectCreating()); try { setDescriptionApplying(project, des); - des.applyDatas(); + des.applyDatas(context); des.doneApplying(); } finally { clearDescriptionApplying(project); @@ -632,30 +638,20 @@ public class CProjectDescriptionManager implements ICProjectDescriptionManager { } private void saveConversion(final IProject proj, - final IProjectDescription eDes, + final SettingsContext context, CProjectDescription des, IProgressMonitor monitor) { - CompositeWorkspaceRunnable r = new CompositeWorkspaceRunnable(null); - r.add(new IWorkspaceRunnable(){ - - public void run(IProgressMonitor monitor) throws CoreException { - try { - proj.setDescription(eDes, monitor); - } catch (CoreException e){ - CCorePlugin.log(e); - } - - } - }); try { - r.add(createDesSerializationRunnable(des)); + context.addWorkspaceRunnable(createDesSerializationRunnable(des)); } catch (CoreException e1) { CCorePlugin.log(e1); } - - runWspModification(r, monitor); + + IWorkspaceRunnable toRun = context.createOperationRunnable(); + if(toRun != null) + runWspModification(toRun, monitor); } public Job runWspModification(final IWorkspaceRunnable runnable, IProgressMonitor monitor){ @@ -1565,12 +1561,12 @@ public class CProjectDescriptionManager implements ICProjectDescriptionManager { return provider.loadConfiguration(des, monitor); } - CConfigurationData applyData(ICConfigurationDescription des, ICConfigurationDescription baseDescription, CConfigurationData base, IProgressMonitor monitor) throws CoreException { + CConfigurationData applyData(ICConfigurationDescription des, ICConfigurationDescription baseDescription, CConfigurationData base, IModificationContext context, IProgressMonitor monitor) throws CoreException { if(monitor == null) monitor = new NullProgressMonitor(); CConfigurationDataProvider provider = getProvider(des); - return provider.applyConfiguration(des, baseDescription, base, monitor); + return provider.applyConfiguration(des, baseDescription, base, context, monitor); } void notifyCached(ICConfigurationDescription des, CConfigurationData data, IProgressMonitor monitor) { @@ -2904,6 +2900,15 @@ public class CProjectDescriptionManager implements ICProjectDescriptionManager { return getPreferenceConfiguration(buildSystemId, true); } + private void runContextOperations(SettingsContext context, IProgressMonitor monitor){ + IWorkspaceRunnable toRun = context.createOperationRunnable(); + if(toRun != null){ + runWspModification(toRun, monitor); + } else if (monitor != null){ + monitor.done(); + } + } + public ICConfigurationDescription getPreferenceConfiguration(String buildSystemId, boolean write) throws CoreException { ICConfigurationDescription des = getLoaddedPreference(buildSystemId); if(des == null){ @@ -2984,9 +2989,11 @@ public class CProjectDescriptionManager implements ICProjectDescriptionManager { rootEl = rootParent.importChild(baseRootEl); CConfigurationDescriptionCache cache = new CConfigurationDescriptionCache(des, baseData, cfgDes.getSpecSettings(), null, rootEl); CSettingEntryFactory factory = new CSettingEntryFactory(); - cache.applyData(factory); + SettingsContext context = new SettingsContext(null); + cache.applyData(factory, context); cache.doneInitialization(); factory.clear(); + runContextOperations(context, null); return cache; } diff --git a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/settings/model/SetCProjectDescriptionOperation.java b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/settings/model/SetCProjectDescriptionOperation.java index 747273c9459..68a56d6687b 100644 --- a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/settings/model/SetCProjectDescriptionOperation.java +++ b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/settings/model/SetCProjectDescriptionOperation.java @@ -18,12 +18,10 @@ import org.eclipse.cdt.core.settings.model.CProjectDescriptionEvent; import org.eclipse.cdt.core.settings.model.ICDescriptionDelta; import org.eclipse.cdt.core.settings.model.ICProjectDescriptionManager; import org.eclipse.cdt.internal.core.model.CModelOperation; -import org.eclipse.cdt.internal.core.settings.model.CProjectDescriptionManager.CompositeWorkspaceRunnable; import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IProjectDescription; import org.eclipse.core.resources.IWorkspaceRunnable; import org.eclipse.core.runtime.CoreException; -import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.NullProgressMonitor; public class SetCProjectDescriptionOperation extends CModelOperation { @@ -60,9 +58,10 @@ public class SetCProjectDescriptionOperation extends CModelOperation { throw new CModelException(ExceptionFactory.createCoreException(SettingsModelMessages.getString("CProjectDescriptionManager.17") + project.getName())); //$NON-NLS-1$ CProjectDescription fNewDescriptionCache = new CProjectDescription(fSetDescription, true, el, creating); + SettingsContext context = new SettingsContext(project); try { mngr.setDescriptionApplying(project, fNewDescriptionCache); - fNewDescriptionCache.applyDatas(); + fNewDescriptionCache.applyDatas(context); } finally { mngr.clearDescriptionApplying(project); } @@ -84,19 +83,10 @@ public class SetCProjectDescriptionOperation extends CModelOperation { fSetDescription.switchToCachedAppliedData(fNewDescriptionCache); - CompositeWorkspaceRunnable runnable = new CompositeWorkspaceRunnable(SettingsModelMessages.getString("SetCProjectDescriptionOperation.0")); //$NON-NLS-1$ - try { - final IProjectDescription eDes = project.getDescription(); + final IProjectDescription eDes = context.getEclipseProjectDescription(); if(mngr.checkHandleActiveCfgChange(fNewDescriptionCache, fOldDescriptionCache, eDes, new NullProgressMonitor())){ - runnable.add(new IWorkspaceRunnable(){ - - public void run(IProgressMonitor monitor) - throws CoreException { - project.setDescription(eDes, monitor); - } - - }); + context.setEclipseProjectDescription(eDes); } } catch (CoreException e2) { CCorePlugin.log(e2); @@ -121,9 +111,11 @@ public class SetCProjectDescriptionOperation extends CModelOperation { try { if(!CProjectDescriptionManager.checkFlags(fFlags, ICProjectDescriptionManager.SET_NO_SERIALIZE)) - runnable.add(mngr.createDesSerializationRunnable(fNewDescriptionCache)); - if(!runnable.isEmpty()) - mngr.runWspModification(runnable, new NullProgressMonitor()); + context.addWorkspaceRunnable(mngr.createDesSerializationRunnable(fNewDescriptionCache)); + IWorkspaceRunnable toRun = context.createOperationRunnable(); + + if(toRun != null) + mngr.runWspModification(toRun, new NullProgressMonitor()); } catch (CoreException e) { throw new CModelException(e); } diff --git a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/settings/model/SettingsContext.java b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/settings/model/SettingsContext.java new file mode 100644 index 00000000000..e5aabc2161a --- /dev/null +++ b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/settings/model/SettingsContext.java @@ -0,0 +1,92 @@ +/******************************************************************************* + * Copyright (c) 2007 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 org.eclipse.cdt.core.settings.model.IModificationContext; +import org.eclipse.cdt.internal.core.settings.model.CProjectDescriptionManager.CompositeWorkspaceRunnable; +import org.eclipse.core.resources.IProject; +import org.eclipse.core.resources.IProjectDescription; +import org.eclipse.core.resources.IWorkspaceRunnable; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IProgressMonitor; + +public final class SettingsContext implements IModificationContext{ + private IProjectDescription fEDes; + private IProject fProject; + private CompositeWorkspaceRunnable fRunnable; + + SettingsContext(IProject project){ + fProject = project; + } + + public IProject getProject(){ + return fProject; + } + + IProjectDescription getEclipseProjectDescription(boolean create) throws CoreException{ + IProjectDescription eDes = fEDes; + if(eDes == null && create){ + if(fProject == null) + throw ExceptionFactory.createCoreException("no project associated with the context"); + + eDes = fProject.getDescription(); + } + return eDes; + } + + public IProjectDescription getEclipseProjectDescription() throws CoreException{ + return getEclipseProjectDescription(true); + } + + public void setEclipseProjectDescription(IProjectDescription des) + throws CoreException { + if(fEDes == null) + fEDes = des; + else if(fEDes != des) + throw ExceptionFactory.createCoreException("can not accept the not-context project description"); + } + + CompositeWorkspaceRunnable getCompositeWorkspaceRunnable(boolean create){ + if(fRunnable == null && create) + fRunnable = new CompositeWorkspaceRunnable(null); + return fRunnable; + } + + public void addWorkspaceRunnable(IWorkspaceRunnable runnable){ + getCompositeWorkspaceRunnable(true).add(runnable); + } + + IWorkspaceRunnable createOperationRunnable() { + CompositeWorkspaceRunnable result = new CompositeWorkspaceRunnable(null); + + IWorkspaceRunnable r = getSetEclipseProjectDescriptionRunnable(); + if(r != null) + result.add(r); + r = getCompositeWorkspaceRunnable(false); + if(r != null) + result.add(r); + + return result.isEmpty() ? null : result; + } + + private IWorkspaceRunnable getSetEclipseProjectDescriptionRunnable(){ + if(fEDes != null){ + return new IWorkspaceRunnable(){ + + public void run(IProgressMonitor monitor) + throws CoreException { + fProject.setDescription(fEDes, monitor); + } + }; + } + return null; + } +}