From c00c0bb52ae3c1ef8d17d8576f9bc9adaffeaddd Mon Sep 17 00:00:00 2001 From: Jeff Johnston Date: Fri, 20 Jul 2012 14:44:36 -0400 Subject: [PATCH] New interfaces to allow reading and updating of Autotool configuration options for a given build configuration. Change-Id: I54d866abb4251fe7e5f7df47493b280b5ac2cd33 Reviewed-on: https://git.eclipse.org/r/6942 Reviewed-by: Jeff Johnston IP-Clean: Jeff Johnston Tested-by: Jeff Johnston --- .../org.eclipse.cdt.autotools.core/ChangeLog | 13 ++ .../META-INF/MANIFEST.MF | 2 +- .../cdt/autotools/core/AutotoolsPlugin.java | 32 +++ .../cdt/autotools/core/IAutotoolsOption.java | 22 ++ .../AutotoolsConfigurationManager.java | 193 ++++++++++++++++-- .../configure/ConfigureMessages.properties | 6 +- 6 files changed, 244 insertions(+), 24 deletions(-) create mode 100644 build/org.eclipse.cdt.autotools.core/src/org/eclipse/cdt/autotools/core/IAutotoolsOption.java diff --git a/build/org.eclipse.cdt.autotools.core/ChangeLog b/build/org.eclipse.cdt.autotools.core/ChangeLog index 4db2797dc08..2007aa9556f 100644 --- a/build/org.eclipse.cdt.autotools.core/ChangeLog +++ b/build/org.eclipse.cdt.autotools.core/ChangeLog @@ -1,3 +1,16 @@ +2012-07-20 Jeff Johnston + + * src/org/eclipse/cdt/autotools/core/AutotoolsPlugin.java (getAutotoolCfgOptions): New publicly accessible + method for retrieving Autotool configuration options for a given build configuration. + (updateAutotoolCfgOptions): New publicly accessible method for updating Autotool configuration options for + a given build configuration. + * src/org/eclipse/cdt/internal/autotools/core/configure/ConfigureMessages.properties: Add new messages for + errors caused by user reading and updating configuration options. + * src/org/eclipse/cdt/internal/autotools/core/configure/AutotoolsConfigurationManager.java: Add synchronization to + all public methods. + (updateAutotoolCfgOptions): New method to allow external users to update configuration options. + (getAutotoolsCfgOptions): New method to get configuration options for a given configuration id. + 2012-04-20 Jeff Johnston * META-INF/MANIFEST.MF: Bump up version to 1.1.0. diff --git a/build/org.eclipse.cdt.autotools.core/META-INF/MANIFEST.MF b/build/org.eclipse.cdt.autotools.core/META-INF/MANIFEST.MF index 2cb9762176a..df33f30ac5f 100644 --- a/build/org.eclipse.cdt.autotools.core/META-INF/MANIFEST.MF +++ b/build/org.eclipse.cdt.autotools.core/META-INF/MANIFEST.MF @@ -2,7 +2,7 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: %Bundle-Name.0 Bundle-SymbolicName: org.eclipse.cdt.autotools.core;singleton:=true -Bundle-Version: 1.1.0.qualifier +Bundle-Version: 1.2.0.qualifier Bundle-Activator: org.eclipse.cdt.autotools.core.AutotoolsPlugin Bundle-Localization: plugin Require-Bundle: org.eclipse.ui;bundle-version="3.4.0", diff --git a/build/org.eclipse.cdt.autotools.core/src/org/eclipse/cdt/autotools/core/AutotoolsPlugin.java b/build/org.eclipse.cdt.autotools.core/src/org/eclipse/cdt/autotools/core/AutotoolsPlugin.java index 9793b03959b..862d445f278 100644 --- a/build/org.eclipse.cdt.autotools.core/src/org/eclipse/cdt/autotools/core/AutotoolsPlugin.java +++ b/build/org.eclipse.cdt.autotools.core/src/org/eclipse/cdt/autotools/core/AutotoolsPlugin.java @@ -12,9 +12,11 @@ package org.eclipse.cdt.autotools.core; import java.lang.reflect.InvocationTargetException; import java.text.MessageFormat; +import java.util.Map; import java.util.MissingResourceException; import java.util.ResourceBundle; +import org.eclipse.cdt.internal.autotools.core.configure.AutotoolsConfigurationManager; import org.eclipse.cdt.managedbuilder.core.IManagedBuildInfo; import org.eclipse.cdt.managedbuilder.core.IManagedProject; import org.eclipse.cdt.managedbuilder.core.ManagedBuildManager; @@ -290,4 +292,34 @@ public class AutotoolsPlugin extends AbstractUIPlugin { } return null; } + + /** + * Return set of Autotool configuration options for a given build configuration id. + * + * @param project existing autotools project + * @param cfgId configuration id + * @return a copy of Autotools configurations for the given configuration id + * @throws CoreException if project is not valid Autotools project or cfgId does not exist + * @since 1.2 + */ + public Map getAutotoolCfgOptions(IProject project, + String cfgId) throws CoreException { + return AutotoolsConfigurationManager.getInstance().getAutotoolsCfgOptions(project, cfgId); + } + + /** + * Update Autotool configuration options for a specified build configuration + * + * @param project existing autotools project + * @param cfgId configuation id + * @param options set of updated Autotool configuration options + * @throws CoreException if project is not valid Autotools project or cfgId does not exist + * + * @since 1.2 + */ + public void updateAutotoolCfgOptions(IProject project, String cfgId, + Map options) throws CoreException { + AutotoolsConfigurationManager.getInstance().updateAutotoolCfgOptions(project, cfgId, options); + + } } diff --git a/build/org.eclipse.cdt.autotools.core/src/org/eclipse/cdt/autotools/core/IAutotoolsOption.java b/build/org.eclipse.cdt.autotools.core/src/org/eclipse/cdt/autotools/core/IAutotoolsOption.java new file mode 100644 index 00000000000..18788775fb1 --- /dev/null +++ b/build/org.eclipse.cdt.autotools.core/src/org/eclipse/cdt/autotools/core/IAutotoolsOption.java @@ -0,0 +1,22 @@ +package org.eclipse.cdt.autotools.core; + +import org.eclipse.core.runtime.CoreException; + + +/** + * @since 1.2 + */ +public interface IAutotoolsOption { + public final static int CATEGORY = 0; + public final static int BIN = 1; + public final static int STRING = 2; + public final static int INTERNAL = 3; + public final static int MULTIARG = 4; + public final static int TOOL = 5; + public final static int FLAG = 6; + public final static int FLAGVALUE = 7; + public int getType(); + public boolean canUpdate(); + public void setValue(String value) throws CoreException; + public String getValue(); +} diff --git a/build/org.eclipse.cdt.autotools.core/src/org/eclipse/cdt/internal/autotools/core/configure/AutotoolsConfigurationManager.java b/build/org.eclipse.cdt.autotools.core/src/org/eclipse/cdt/internal/autotools/core/configure/AutotoolsConfigurationManager.java index 2eac3af257a..1c1e526b787 100644 --- a/build/org.eclipse.cdt.autotools.core/src/org/eclipse/cdt/internal/autotools/core/configure/AutotoolsConfigurationManager.java +++ b/build/org.eclipse.cdt.autotools.core/src/org/eclipse/cdt/internal/autotools/core/configure/AutotoolsConfigurationManager.java @@ -20,12 +20,16 @@ import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; import java.util.Map; +import java.util.Map.Entry; +import java.util.Random; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.ParserConfigurationException; +import org.eclipse.cdt.autotools.core.AutotoolsNewProjectNature; import org.eclipse.cdt.autotools.core.AutotoolsPlugin; +import org.eclipse.cdt.autotools.core.IAutotoolsOption; import org.eclipse.cdt.core.model.CoreModel; import org.eclipse.cdt.core.settings.model.ICConfigurationDescription; import org.eclipse.cdt.core.settings.model.ICProjectDescription; @@ -45,7 +49,10 @@ import org.eclipse.core.resources.IResourceChangeListener; import org.eclipse.core.resources.IResourceDelta; import org.eclipse.core.resources.IWorkspaceRoot; import org.eclipse.core.resources.ResourcesPlugin; +import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IPath; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.NamedNodeMap; @@ -58,8 +65,18 @@ public class AutotoolsConfigurationManager implements IResourceChangeListener { public final static String CFG_FILE_NAME = ".autotools"; //$NON-NLS-1$ private final static String CFG_CANT_SAVE = "Configure.Error.NoProjectToSave"; //$NON-NLS-1$ - + /** + * @since 1.2 + */ + public static final String INVALID_AUTOTOOLS_PROJECT = "CfgOptions.Invalid.Project"; //$NON-NLS-1$ + /** + * @since 1.2 + */ + + public static final String INVALID_AUTOTOOLS_CONFIG_ID = "CfgOptions.Invalid.Config"; //$NON-NLS-1$ + private static AutotoolsConfigurationManager instance; + private static Random rand = new Random(); private boolean isSyncing; @@ -79,21 +96,21 @@ public class AutotoolsConfigurationManager implements IResourceChangeListener { return instance; } - public IAConfiguration createDefaultConfiguration(IProject project, String id) { + public synchronized IAConfiguration createDefaultConfiguration(IProject project, String id) { IAConfiguration cfg = new AutotoolsConfiguration(id); return cfg; } - public IAConfiguration findCfg(IProject p, String id) { + public synchronized IAConfiguration findCfg(IProject p, String id) { Map cfgs = getConfigurations(p); return cfgs.get(id); } - public IAConfiguration getConfiguration(IProject p, String cfgId) { + public synchronized IAConfiguration getConfiguration(IProject p, String cfgId) { return getConfiguration(p, cfgId, true); } - public IAConfiguration getConfiguration(IProject p, String cfgId, boolean persist) { + public synchronized IAConfiguration getConfiguration(IProject p, String cfgId, boolean persist) { IAConfiguration cfg = findCfg(p, cfgId); if (cfg == null) { cfg = createDefaultConfiguration(p, cfgId); @@ -109,14 +126,14 @@ public class AutotoolsConfigurationManager implements IResourceChangeListener { } - public boolean isConfigurationAlreadySaved(IProject project, ICConfigurationDescription cfgd) { + public synchronized boolean isConfigurationAlreadySaved(IProject project, ICConfigurationDescription cfgd) { Map cfgs = getSavedConfigs(project); if (cfgs != null) return cfgs.get(cfgd.getId()) != null; return false; } - public void addConfiguration(IProject project, IAConfiguration cfg) { + public synchronized void addConfiguration(IProject project, IAConfiguration cfg) { String projectName = project.getName(); Map cfgs = getSavedConfigs(project); if (cfgs == null) { @@ -127,11 +144,11 @@ public class AutotoolsConfigurationManager implements IResourceChangeListener { saveConfigs(project); } - public boolean isSyncing() { + public synchronized boolean isSyncing() { return isSyncing; } - private void setSyncing(boolean value) { + private synchronized void setSyncing(boolean value) { isSyncing = value; } @@ -144,7 +161,7 @@ public class AutotoolsConfigurationManager implements IResourceChangeListener { * @param project to synchronize configurations for * */ - public void syncConfigurations(IProject project) { + public synchronized void syncConfigurations(IProject project) { setSyncing(true); clearTmpConfigurations(project); ICProjectDescription pd = CoreModel.getDefault().getProjectDescription(project); @@ -160,13 +177,13 @@ public class AutotoolsConfigurationManager implements IResourceChangeListener { replaceProjectConfigurations(project, newCfgList); } - public void replaceProjectConfigurations(IProject project, Map cfgs) { + public synchronized void replaceProjectConfigurations(IProject project, Map cfgs) { String projectName = project.getName(); configs.put(projectName, cfgs); saveConfigs(project); } - public void replaceProjectConfigurations(IProject project, Map cfgs, ICConfigurationDescription[] cfgds) { + public synchronized void replaceProjectConfigurations(IProject project, Map cfgs, ICConfigurationDescription[] cfgds) { String projectName = project.getName(); configs.put(projectName, cfgs); saveConfigs(project, cfgds); @@ -201,7 +218,7 @@ public class AutotoolsConfigurationManager implements IResourceChangeListener { else if (nameNode != null) { String cfgName = nameNode.getNodeValue(); ICConfigurationDescription cfgd = - CoreModel.getDefault().getProjectDescription(project).getConfigurationByName(cfgName); + CoreModel.getDefault().getProjectDescription(project).getConfigurationByName(cfgName); if (cfgd != null) cfgId = cfgd.getId(); else @@ -258,7 +275,7 @@ public class AutotoolsConfigurationManager implements IResourceChangeListener { return list; } - public IAConfiguration getTmpConfiguration(IProject p, ICConfigurationDescription cfgd) { + public synchronized IAConfiguration getTmpConfiguration(IProject p, ICConfigurationDescription cfgd) { Map list = getTmpConfigs(p); IAConfiguration acfg = list.get(cfgd.getId()); if (acfg != null) { @@ -278,7 +295,7 @@ public class AutotoolsConfigurationManager implements IResourceChangeListener { * @param cfgd the configuration descriptor for the clone * @return true if the configuration is already saved, false otherwise */ - public boolean cloneCfg(IProject p, String oldId, ICConfigurationDescription cfgd) { + public synchronized boolean cloneCfg(IProject p, String oldId, ICConfigurationDescription cfgd) { if (isConfigurationAlreadySaved(p, cfgd)) return true; Map tmpList = getTmpConfigs(p); @@ -316,13 +333,15 @@ public class AutotoolsConfigurationManager implements IResourceChangeListener { return tmpList; } - public void clearTmpConfigurations(IProject p) { + public synchronized void clearTmpConfigurations(IProject p) { tmpConfigs.remove(p.getName()); } - public void saveConfigs(IProject project) { - ICConfigurationDescription[] cfgds = CoreModel.getDefault().getProjectDescription(project).getConfigurations(); - saveConfigs(project, cfgds); + public synchronized void saveConfigs(IProject project) { + synchronized (project) { + ICConfigurationDescription[] cfgds = CoreModel.getDefault().getProjectDescription(project).getConfigurations(); + saveConfigs(project, cfgds); + } } private void syncNameField(ICConfigurationDescription cfgd) { @@ -417,7 +436,7 @@ public class AutotoolsConfigurationManager implements IResourceChangeListener { // with any changes currently that have been made to them. If a configuration has been renamed, but this // has not yet been confirmed by the end-user, then only the changes to the configuration are made. The // name currently remains the same in the output file. - public void applyConfigs(String projectName, ICConfigurationDescription[] cfgds) { + public synchronized void applyConfigs(String projectName, ICConfigurationDescription[] cfgds) { try { IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot(); IResource res = (IProject)root.findMember(projectName, false); @@ -489,7 +508,7 @@ public class AutotoolsConfigurationManager implements IResourceChangeListener { } } - public Map getConfigurations(IProject project) { + public synchronized Map getConfigurations(IProject project) { Map list = getSavedConfigs(project); if (list == null) { list = new HashMap(); @@ -498,7 +517,7 @@ public class AutotoolsConfigurationManager implements IResourceChangeListener { return list; } - public void resourceChanged(IResourceChangeEvent event) { + public synchronized void resourceChanged(IResourceChangeEvent event) { IResource res = event.getResource(); if (!(res instanceof IProject)) return; @@ -527,4 +546,134 @@ public class AutotoolsConfigurationManager implements IResourceChangeListener { } } + private class AutotoolsOption implements IAutotoolsOption { + + private IConfigureOption option; + private final static String UNMODIFIABLE_CONFIG_OPTION = "CfgOptions.Unmodifiable.Option"; //$NON-NLS-1$ + + + public AutotoolsOption(IConfigureOption option) { + this.option = option; + } + + @Override + public int getType() { + return option.getType(); + } + + @Override + public boolean canUpdate() { + int type = getType(); + switch (type) { + case STRING: + case BIN: + case TOOL: + case FLAGVALUE: + case MULTIARG: + case INTERNAL: + return true; + } + return false; + } + + @Override + public void setValue(String value) throws CoreException { + if (!canUpdate()) { + throw new CoreException(new Status(IStatus.ERROR, AutotoolsPlugin.PLUGIN_ID, + ConfigureMessages.getString(UNMODIFIABLE_CONFIG_OPTION))); + } + synchronized (option) { + option.setValue(value); + } + } + + @Override + public String getValue() { + synchronized (option) { + return option.getValue(); + } + } + + } + + private String createDummyId() { + for (;;) { + String id = "TEMP_" + rand.nextInt(); + if (tmpConfigs.get(id) == null) + return id; + } + } + + /** + * @since 1.2 + */ + public synchronized Map getAutotoolsCfgOptions(IProject project, + String cfgId) throws CoreException { + + // Verify project is valid Autotools project + if (project == null || !project.hasNature(AutotoolsNewProjectNature.AUTOTOOLS_NATURE_ID)) { + throw new CoreException(new Status(IStatus.ERROR, AutotoolsPlugin.PLUGIN_ID, + ConfigureMessages.getString(INVALID_AUTOTOOLS_PROJECT))); + } + + // Verify configuration id is valid + ICConfigurationDescription cfgd = + CoreModel.getDefault().getProjectDescription(project).getConfigurationById(cfgId); + IConfiguration icfg = ManagedBuildManager.getConfigurationForDescription(cfgd); + if (icfg == null) { + throw new CoreException(new Status(IStatus.ERROR, AutotoolsPlugin.PLUGIN_ID, + ConfigureMessages.getString(INVALID_AUTOTOOLS_CONFIG_ID))); + } + + IAConfiguration cfg = getConfiguration(project, cfgId); + HashMap options = new HashMap(); + + // Get set of configuration options and convert to set of IAutotoolOptions + Map cfgOptions = cfg.getOptions(); + IAConfiguration dummyCfg = createDefaultConfiguration(project, createDummyId()); + for (Iterator> i = cfgOptions.entrySet().iterator(); i.hasNext();) { + Map.Entry entry = (Entry) i.next(); + String name = entry.getKey(); + IAutotoolsOption configOption = + new AutotoolsOption(entry.getValue().copy((AutotoolsConfiguration)dummyCfg)); + options.put(name, configOption); + } + + return options; + } + + /** + * @since 1.2 + */ + public synchronized void updateAutotoolCfgOptions(IProject project, String cfgId, + Map options) throws CoreException { + + // Verify project is valid Autotools project + if (project == null || !project.hasNature(AutotoolsNewProjectNature.AUTOTOOLS_NATURE_ID)) { + throw new CoreException(new Status(IStatus.ERROR, AutotoolsPlugin.PLUGIN_ID, + ConfigureMessages.getString(INVALID_AUTOTOOLS_PROJECT))); + } + + // Verify configuration id is valid + IAConfiguration cfg = findCfg(project, cfgId); + if (cfg == null) { + throw new CoreException(new Status(IStatus.ERROR, AutotoolsPlugin.PLUGIN_ID, + ConfigureMessages.getString(INVALID_AUTOTOOLS_CONFIG_ID))); + } + + // Get set of configuration options and convert to set of IAutotoolOptions + for (Iterator> i = options.entrySet().iterator(); i.hasNext();) { + Map.Entry entry = (Entry) i.next(); + String name = entry.getKey(); + IAutotoolsOption option = entry.getValue(); + IConfigureOption cfgOption = cfg.getOption(name); + if (cfgOption != null) { + cfgOption.setValue(option.getValue()); + } + } + + // Save changes + saveConfigs(project); + } + } diff --git a/build/org.eclipse.cdt.autotools.core/src/org/eclipse/cdt/internal/autotools/core/configure/ConfigureMessages.properties b/build/org.eclipse.cdt.autotools.core/src/org/eclipse/cdt/internal/autotools/core/configure/ConfigureMessages.properties index 0823b6ca45a..c317733fc4d 100644 --- a/build/org.eclipse.cdt.autotools.core/src/org/eclipse/cdt/internal/autotools/core/configure/ConfigureMessages.properties +++ b/build/org.eclipse.cdt.autotools.core/src/org/eclipse/cdt/internal/autotools/core/configure/ConfigureMessages.properties @@ -98,4 +98,8 @@ Tool.command=Command Tool.allopts=All Options Configure.Error.AlreadyExists="A configuration named {0} already exists" -Configure.Error.NoProjectToSave="Project: {0} does not exist at time of saving configuration" \ No newline at end of file +Configure.Error.NoProjectToSave="Project: {0} does not exist at time of saving configuration" + +CfgOptions.Invalid.Project=Specified project is not a valid existing Autotools project +CfgOptions.Invalid.Config=Specified configuration id does not correspond to an existing configuration +CfgOptions.Unmodifiable.Option=Attempting to modify an unmodifiable Autotools configure option