diff --git a/build/org.eclipse.cdt.managedbuilder.core.tests/plugin.xml b/build/org.eclipse.cdt.managedbuilder.core.tests/plugin.xml index 67494d80a53..dfaafb86cec 100644 --- a/build/org.eclipse.cdt.managedbuilder.core.tests/plugin.xml +++ b/build/org.eclipse.cdt.managedbuilder.core.tests/plugin.xml @@ -9311,4 +9311,66 @@ name="Test Plugin GCC BOP Patterns Highlighter"> + + + + + + + + + diff --git a/build/org.eclipse.cdt.managedbuilder.core.tests/tests/org/eclipse/cdt/managedbuilder/core/tests/ManagedBuildCoreTests.java b/build/org.eclipse.cdt.managedbuilder.core.tests/tests/org/eclipse/cdt/managedbuilder/core/tests/ManagedBuildCoreTests.java index 68e2a10bb90..e1bf503c10a 100644 --- a/build/org.eclipse.cdt.managedbuilder.core.tests/tests/org/eclipse/cdt/managedbuilder/core/tests/ManagedBuildCoreTests.java +++ b/build/org.eclipse.cdt.managedbuilder.core.tests/tests/org/eclipse/cdt/managedbuilder/core/tests/ManagedBuildCoreTests.java @@ -22,6 +22,9 @@ 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.IOption; +import org.eclipse.cdt.managedbuilder.core.IOption.ITreeOption; +import org.eclipse.cdt.managedbuilder.core.IOption.ITreeRoot; +import org.eclipse.cdt.managedbuilder.core.IOptionApplicability; import org.eclipse.cdt.managedbuilder.core.IOptionCategory; import org.eclipse.cdt.managedbuilder.core.IProjectType; import org.eclipse.cdt.managedbuilder.core.ITargetPlatform; @@ -30,6 +33,7 @@ import org.eclipse.cdt.managedbuilder.core.IToolChain; import org.eclipse.cdt.managedbuilder.core.ManagedBuildManager; import org.eclipse.cdt.managedbuilder.internal.core.Builder; import org.eclipse.core.runtime.IConfigurationElement; +import org.junit.Assert; public class ManagedBuildCoreTests extends TestCase { @@ -44,6 +48,7 @@ public class ManagedBuildCoreTests extends TestCase { public static Test suite() { TestSuite suite = new TestSuite(ManagedBuildCoreTests.class.getName()); suite.addTest(new ManagedBuildCoreTests("testLoadManifest")); + suite.addTest(new ManagedBuildCoreTests("testTreeOptions")); return suite; } @@ -598,5 +603,64 @@ public class ManagedBuildCoreTests extends TestCase { } // end for } // end routine + + /** + * Tests Options of type tree as implemented in bug 365718 + * @throws Exception + */ + public void testTreeOptions() throws Exception { + IOption treeOption = ManagedBuildManager.getExtensionOption("cdt.managedbuild.tool.gnu.c.linker.test.tree.option"); + assertNotNull(treeOption); + + // standard options + assertEquals(IOption.TREE, treeOption.getValueType()); + assertEquals("grandChild_1_1_1", treeOption.getValue()); + assertEquals("grandChild_1_1_1", treeOption.getDefaultValue()); + assertEquals("cdt.managedbuild.tool.gnu.c.linker.test.tree.option", treeOption.getId()); + assertEquals("-dummy", treeOption.getCommand()); + assertEquals("-dummy122", treeOption.getCommand("grandChild_1_2_2")); + + String[] applicableValues = treeOption.getApplicableValues(); + String[] expected = new String[18]; + int index = 0; + for (int i = 1; i < 4; i++) { + for (int j = 1; j < 3; j++) { + for (int k = 1; k < 4; k++) { + expected[index++] = "Grand Child " + i + ' ' + j + ' ' + k; + } + } + } + Assert.assertArrayEquals(expected, applicableValues); + + ITreeRoot treeRoot = treeOption.getTreeRoot(); + assertNotNull(treeRoot); + + // test some tree option attributes + ITreeOption[] children = treeRoot.getChildren(); + assertNotNull(children); + assertEquals(0, children[2].getOrder()); + assertEquals("Parent 2", children[1].getName()); + assertTrue(children[0].isContainer()); + + ITreeOption findNode = treeRoot.findNode("grandChild_2_1_3"); + assertNotNull(findNode); + + int size = children.length; + treeRoot.addChild("newID", "New Name"); + assertEquals(size+1, treeRoot.getChildren().length); + assertEquals("newID", treeRoot.getChild("New Name").getID()); + + // check tree only methods + IOption nonTreeOption = ManagedBuildManager.getExtensionOption("testgnu.c.compiler.exe.debug.option.debugging.level"); + assertFalse(IOption.TREE == nonTreeOption.getValueType()); + boolean exception = false; + try { + nonTreeOption.getTreeRoot(); + } catch (Exception e) { + exception = true; + } + assertTrue(exception); + + } } // end class diff --git a/build/org.eclipse.cdt.managedbuilder.core/schema/buildDefinitions.exsd b/build/org.eclipse.cdt.managedbuilder.core/schema/buildDefinitions.exsd index e8a56781bf9..6e8e0e32854 100644 --- a/build/org.eclipse.cdt.managedbuilder.core/schema/buildDefinitions.exsd +++ b/build/org.eclipse.cdt.managedbuilder.core/schema/buildDefinitions.exsd @@ -1178,6 +1178,7 @@ Options can also be associated with a toolchain. However in such a case the opti + @@ -1289,6 +1290,8 @@ Additional special types exist to flag options of special relevance to the build + + @@ -1512,6 +1515,118 @@ A custom field-editor needs to be registered, under the same ID, through the < + + + + + + + + + The id should be the value used for determining which treeOption is selected, it has to be unique within the tree. + + + + + + + Display name for the option + + + + + + + + + + Description of the option to be presented to the user + + + + + + + + + + The command that the tree value translates to on the command line. + + + + + + + Flags this tree value as the default to apply to the option if the user has not changed the setting. + + + + + + + An icon to be used for this node in the tree representation. Should use full path for the icon: e.g., platform:/plugin/org.eclipse.cdt/icons/wizard.png + + + + + + + + + + An integer representing the order of this option within its peers in the tree. The order is a relative number, were smaller numbers appear on top of larger numbers. +If no order is defined a default order is assumed, see "org.eclipse.cdt.managedbuilder.core.IOption.ITreeOption.DEFAULT_ORDER" for more details. + + + + + + + + + + Represents the root of a tree of options. Note that the root is never shown to the user and can't be selected. It is a place holder for settings affecting the options tree behavior + + + + + + + + + + + + + + + + + + + + + + + + The tree root icon can be used in branding the UI representation of the tree. Should use full path for the icon: e.g., platform:/plugin/org.eclipse.cdt/icons/wizard.png + + + + + + + + + + Determines whether this tree allows selecting categories as well as leaf nodes, or leaf nodes only. +Default is true (leaf nodes only). + + + + + + diff --git a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/core/IOption.java b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/core/IOption.java index 2196fd19fe8..85ac319e5f5 100644 --- a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/core/IOption.java +++ b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/core/IOption.java @@ -55,6 +55,12 @@ public interface IOption extends IBuildObject { public static final int LIBRARY_FILES = 10; public static final int MACRO_FILES = 11; + /** + * Tree of items to select one from. + * @since 8.1 + */ + public static final int TREE = 12; + public static final int UNDEF_INCLUDE_PATH = -INCLUDE_PATH; public static final int UNDEF_PREPROCESSOR_SYMBOLS = -PREPROCESSOR_SYMBOLS; public static final int UNDEF_INCLUDE_FILES = -INCLUDE_FILES; @@ -84,6 +90,14 @@ public interface IOption extends IBuildObject { /** @since 7.0 */ public static final String BROWSE_FILTER_EXTENSIONS = "browseFilterExtensions"; //$NON-NLS-1$ public static final String CATEGORY = "category"; //$NON-NLS-1$ + /** + * @since 8.1 + */ + public static final String ICON = "icon"; //$NON-NLS-1$ + /** + * @since 8.1 + */ + public static final String ORDER = "order"; //$NON-NLS-1$ public static final String COMMAND = "command"; //$NON-NLS-1$ public static final String COMMAND_FALSE = "commandFalse"; //$NON-NLS-1$ /** @since 8.0 */ @@ -92,6 +106,22 @@ public interface IOption extends IBuildObject { public static final String CONTEXT_ID = "contextId"; //$NON-NLS-1$ public static final String DEFAULT_VALUE = "defaultValue"; //$NON-NLS-1$ public static final String ENUM_VALUE = "enumeratedOptionValue"; //$NON-NLS-1$ + /** + * @since 8.1 + */ + public static final String TREE_ROOT = "treeOptionRoot"; //$NON-NLS-1$ + /** + * @since 8.1 + */ + public static final String SELECT_LEAF_ONLY = "selectLeafOnly"; //$NON-NLS-1$ + /** + * @since 8.1 + */ + public static final String TREE_VALUE = "treeOption"; //$NON-NLS-1$ + /** + * @since 8.1 + */ + public static final String DESCRIPTION = "description"; //$NON-NLS-1$ public static final String IS_DEFAULT = "isDefault"; //$NON-NLS-1$ public static final String LIST_VALUE = "listOptionValue"; //$NON-NLS-1$ public static final String RESOURCE_FILTER = "resourceFilter"; //$NON-NLS-1$ @@ -114,6 +144,10 @@ public interface IOption extends IBuildObject { public static final String TYPE_UNDEF_LIB_FILES = "undefLibFiles"; //$NON-NLS-1$ public static final String TYPE_UNDEF_INC_FILES = "undefIncludeFiles"; //$NON-NLS-1$ public static final String TYPE_UNDEF_SYMBOL_FILES = "undefSymbolFiles"; //$NON-NLS-1$ + /** + * @since 8.1 + */ + public static final String TYPE_TREE = "tree"; //$NON-NLS-1$ public static final String VALUE = "value"; //$NON-NLS-1$ public static final String VALUE_TYPE = "valueType"; //$NON-NLS-1$ @@ -325,18 +359,59 @@ public interface IOption extends IBuildObject { */ public String getEnumCommand (String id) throws BuildException; + /** + * Returns the command associated with the child of this option + * with the given id. Applies to options of types that has children + * for example {@link #TREE} or {@link #ENUMERATED} + * + * @param id - child id + * @return the command associated with the child id. For + * example, if the child id was gnu.debug.level.default + * for the debug level option of the Gnu compiler, and the plugin + * manifest defined that as -g, then the return value would be the + * String "-g" + * + * @throws BuildException + * @since 8.1 + */ + public String getCommand (String id) throws BuildException; + /** * @param id - enumeration id * @return the "name" associated with the enumeration id. */ public String getEnumName (String id) throws BuildException; + /** + * Returns the name associated with the child of this option + * with the given id. Applies to options of types that has children + * for example {@link #TREE} or {@link #ENUMERATED} + * + * @param id The id to look for + * @return Name of the child with the passed id or null if not found. + * @throws BuildException if any issue happened while searching. + * @since 8.1 + */ + public abstract String getName(String id) throws BuildException; + /** * @param name - a "name" associated with enumeration id * @return enumeration id */ public String getEnumeratedId(String name) throws BuildException; + /** + * Returns the id associated with the child of this option + * with the given name. Applies to options of types that has children + * for example {@link #TREE} or {@link #ENUMERATED} + * + * @param name the name of the child to look for. + * @return The id of the found child or null if not found. + * @throws BuildException if any error happened while searching + * @since 8.1 + */ + public abstract String getId(String name) throws BuildException; + /** * @return an array of String containing the includes paths * defined in the build model. @@ -514,6 +589,7 @@ public interface IOption extends IBuildObject { *
  • {@link IOption#BOOLEAN} *
  • {@link IOption#STRING} *
  • {@link IOption#ENUMERATED} + *
  • {@link IOption#TREE} *
  • {@link IOption#STRING_LIST} - corresponds to * {@link IOption#INCLUDE_PATH}, {@link IOption#PREPROCESSOR_SYMBOLS}, {@link IOption#LIBRARIES}, * {@link IOption#OBJECTS}, {@link IOption#INCLUDE_FILES}, {@link IOption#LIBRARY_PATHS}, @@ -528,4 +604,101 @@ public interface IOption extends IBuildObject { String[] getBasicStringListValue() throws BuildException; public OptionStringValue[] getBasicStringListValueElements() throws BuildException; + + /** + * Returns the tree root of this option if it is of type {@link #TREE} + * @return tree root of this option or null if not found. + * @throws BuildException if this option is not of type {@link #TREE} + * @since 8.1 + */ + public ITreeRoot getTreeRoot() throws BuildException; + + /** + * Represents the root of the tree of values in options of + * type {@link IOption#TREE} + * @author mhussein + * @since 8.1 + * + */ + public interface ITreeRoot extends ITreeOption { + /** + * Determines whether this tree allows selecting leaf nodes + * only or any nodes. + * @return true if only leaf nodes are allowed. + * false if all child nodes could be selected. + * @see ITreeOption#isContainer() + */ + boolean isSelectLeafsOnly(); + + /** + * Locates the node with the given id anywhere in the tree. + * @param id the id to search for + * @return the found child or null if not found. + */ + ITreeOption findNode(String id); + + /** + * Adds a new node to the tree. + * @param id The id of the new child. + * @param name The name of the new child. + * @param category The category of the new child.category is a '.' + * separated string representing hierarchical path + * of the child from the root of the tree. + * can cause other nodes to be created to construct the + * full path to the new child. + * @param order The order of the newly created node among its peers. + * see {@link ITreeOption#getOrder()} for more information. + * Note: this order will apply to any parents auto-created + * according to the passed category. + * if null the {@link ITreeOption#DEFAULT_ORDER} + * will be used. + * @return the newly added node. + */ + ITreeOption addNode(String id, String name, String category, Integer order); + } + + /** + * Represents a one of the possible values for options of type + * {@link IOption#TREE} + * @author mhussein + * @since 8.1 + * + */ + public interface ITreeOption { + /** + * The default order for tree nodes without order specified. + * Tree options with Orders smaller than this should appear above + * tree options with no order specified and vice versa. + */ + public static final int DEFAULT_ORDER = 1000; + + String getName(); + String getID(); + String getDescription(); + /** + * The order that determines UI appearance of the tree node, + * not necessarily its position in {@link #getChildren()} + * @return The order of this tree option relative to its peers. + * Smaller number means it should appear above peers. + * @see #DEFAULT_ORDER + */ + int getOrder(); + void setOrder(int order); + + ITreeOption[] getChildren(); + ITreeOption getParent(); + boolean isContainer(); + String getCommand(); + ITreeOption getChild(String name); + + /** + * Adds a new child directly under this node. + * @param id + * @param name + * @return + */ + ITreeOption addChild(String id, String name); + void remove(); + String getIcon(); + } } diff --git a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/core/ManagedOptionValueHandler.java b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/core/ManagedOptionValueHandler.java index cf081b242f5..0304e015273 100644 --- a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/core/ManagedOptionValueHandler.java +++ b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/core/ManagedOptionValueHandler.java @@ -120,6 +120,7 @@ public class ManagedOptionValueHandler implements } break; case IOption.ENUMERATED: + case IOption.TREE: if (option.getValue().toString().equals(defaultValue.toString())) { return true; } diff --git a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/buildmodel/BuildStep.java b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/buildmodel/BuildStep.java index 0142f707db9..62b8143297b 100644 --- a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/buildmodel/BuildStep.java +++ b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/buildmodel/BuildStep.java @@ -657,7 +657,7 @@ public class BuildStep implements IBuildStep { } else { ManagedBuildManager.setOption(cfg, fTool, assignToOption, false); } - } else if (optType == IOption.ENUMERATED) { + } else if (optType == IOption.ENUMERATED || optType == IOption.TREE) { if (bRcs.length > 0) { ManagedBuildManager.setOption(cfg, fTool, assignToOption, BuildDescriptionManager.getRelPath(cwd, bRcs[0].getLocation()).toOSString()); } diff --git a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/ConfigurationV2.java b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/ConfigurationV2.java index f65adbc4e37..f3d8fb9e16b 100644 --- a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/ConfigurationV2.java +++ b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/ConfigurationV2.java @@ -132,6 +132,7 @@ public class ConfigurationV2 extends BuildObject implements IConfigurationV2 { new OptionReference(newRef, opt).setValue(optRef.getBooleanValue()); break; case IOption.STRING: + case IOption.TREE: new OptionReference(newRef, opt).setValue(optRef.getStringValue()); break; case IOption.ENUMERATED: diff --git a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/Option.java b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/Option.java index 711e3c60c3e..07d69fe1a73 100644 --- a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/Option.java +++ b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/Option.java @@ -39,6 +39,7 @@ import org.eclipse.cdt.managedbuilder.core.ManagedBuildManager; import org.eclipse.cdt.managedbuilder.core.ManagedBuilderCorePlugin; import org.eclipse.cdt.managedbuilder.core.ManagedOptionValueHandler; import org.eclipse.cdt.managedbuilder.core.OptionStringValue; +import org.eclipse.cdt.managedbuilder.core.IOption.ITreeOption; import org.eclipse.cdt.managedbuilder.internal.enablement.OptionEnablementExpression; import org.eclipse.cdt.managedbuilder.internal.macros.OptionContextData; import org.eclipse.cdt.managedbuilder.macros.IOptionContextData; @@ -71,9 +72,9 @@ public class Option extends BuildObject implements IOption, IBuildPropertiesRest private String commandFalse; private String tip; private String contextId; - private List enumList; - private Map enumCommands; - private Map enumNames; + private List applicableValuesList; + private Map commandsMap; + private Map namesMap; private Object value; private Object defaultValue; private Integer valueType; @@ -87,6 +88,7 @@ public class Option extends BuildObject implements IOption, IBuildPropertiesRest private IConfigurationElement applicabilityCalculatorElement = null; private IOptionApplicability applicabilityCalculator = null; private BooleanExpressionApplicabilityCalculator booleanExpressionCalculator = null; + private ITreeRoot treeRoot; // Miscellaneous private boolean isExtensionOption = false; private boolean isDirty = false; @@ -222,10 +224,13 @@ public class Option extends BuildObject implements IOption, IBuildPropertiesRest if (option.resourceFilter != null) { resourceFilter = new Integer(option.resourceFilter.intValue()); } - if (option.enumList != null) { - enumList = new ArrayList(option.enumList); - enumCommands = new HashMap(option.enumCommands); - enumNames = new HashMap(option.enumNames); + if (option.applicableValuesList != null) { + applicableValuesList = new ArrayList(option.applicableValuesList); + commandsMap = new HashMap(option.commandsMap); + namesMap = new HashMap(option.namesMap); + } + if (option.treeRoot != null) { + treeRoot = new TreeRoot((TreeRoot) option.treeRoot); } if (option.valueType != null) { @@ -245,6 +250,7 @@ public class Option extends BuildObject implements IOption, IBuildPropertiesRest break; case STRING: case ENUMERATED: + case TREE: if (option.value != null) { value = new String((String)option.value); } @@ -549,18 +555,18 @@ public class Option extends BuildObject implements IOption, IBuildPropertiesRest ICStorageElement configElement = configNode; String optId = SafeStringInterner.safeIntern(configElement.getAttribute(ID)); if (i == 0) { - enumList = new ArrayList(); + applicableValuesList = new ArrayList(); if (defaultValue == null) { defaultValue = optId; // Default value to be overridden is default is specified } } - enumList.add(optId); + applicableValuesList.add(optId); if (configElement.getAttribute(COMMAND) != null) { - getEnumCommandMap().put(optId, SafeStringInterner.safeIntern(configElement.getAttribute(COMMAND))); + getCommandMap().put(optId, SafeStringInterner.safeIntern(configElement.getAttribute(COMMAND))); } else { - getEnumCommandMap().put(optId, EMPTY_STRING); + getCommandMap().put(optId, EMPTY_STRING); } - getEnumNameMap().put(optId, SafeStringInterner.safeIntern(configElement.getAttribute(NAME))); + getNameMap().put(optId, SafeStringInterner.safeIntern(configElement.getAttribute(NAME))); if (configElement.getAttribute(IS_DEFAULT) != null) { Boolean isDefault = new Boolean(configElement.getAttribute(IS_DEFAULT)); if (isDefault.booleanValue()) { @@ -570,6 +576,14 @@ public class Option extends BuildObject implements IOption, IBuildPropertiesRest } } break; + case TREE: + if (element.getAttribute(VALUE) != null) { + value = element.getAttribute(VALUE); + } + if (element.getAttribute(DEFAULT_VALUE) != null) { + defaultValue = element.getAttribute(DEFAULT_VALUE); + } + break; case STRING_LIST: case INCLUDE_PATH: case PREPROCESSOR_SYMBOLS: @@ -727,6 +741,8 @@ public class Option extends BuildObject implements IOption, IBuildPropertiesRest return UNDEF_INCLUDE_FILES; else if (valueTypeStr.equals(TYPE_UNDEF_SYMBOL_FILES)) return UNDEF_MACRO_FILES; + else if (valueTypeStr.equals(TYPE_TREE)) + return TREE; else { // TODO: This was the CDT 2.0 default - should we keep it? return PREPROCESSOR_SYMBOLS; @@ -789,6 +805,7 @@ public class Option extends BuildObject implements IOption, IBuildPropertiesRest break; case STRING: case ENUMERATED: + case TREE: element.setAttribute(VALUE, (String)value); break; case STRING_LIST: @@ -834,6 +851,7 @@ public class Option extends BuildObject implements IOption, IBuildPropertiesRest break; case STRING: case ENUMERATED: + case TREE: element.setAttribute(DEFAULT_VALUE, (String)defaultValue); break; default: @@ -898,6 +916,9 @@ public class Option extends BuildObject implements IOption, IBuildPropertiesRest case UNDEF_MACRO_FILES: str = TYPE_UNDEF_SYMBOL_FILES; break; + case TREE: + str = TYPE_TREE; + break; default: // TODO; is this a problem... str = EMPTY_STRING; @@ -1039,7 +1060,7 @@ public class Option extends BuildObject implements IOption, IBuildPropertiesRest @Override public String[] getApplicableValues() { // Does this option instance have the list of values? - if (enumList == null) { + if (applicableValuesList == null) { if (superClass != null) { return superClass.getApplicableValues(); } else { @@ -1047,13 +1068,13 @@ public class Option extends BuildObject implements IOption, IBuildPropertiesRest } } // Get all of the enumerated names from the option - if (enumList.size() == 0) { + if (applicableValuesList.size() == 0) { return EMPTY_STRING_ARRAY; } else { // Return the elements in the order they are specified in the manifest - String[] enumNames = new String[enumList.size()]; - for (int index = 0; index < enumList.size(); ++ index) { - enumNames[index] = getEnumNameMap().get(enumList.get(index)); + String[] enumNames = new String[applicableValuesList.size()]; + for (int index = 0; index < applicableValuesList.size(); ++ index) { + enumNames[index] = getNameMap().get(applicableValuesList.get(index)); } return enumNames; } @@ -1311,35 +1332,35 @@ public class Option extends BuildObject implements IOption, IBuildPropertiesRest } /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.IOption#getEnumCommand(java.lang.String) + * @see org.eclipse.cdt.managedbuilder.core.IOption#getCommand(java.lang.String) */ @Override - public String getEnumCommand(String id) throws BuildException { + public String getCommand(String id) throws BuildException { // Sanity if (id == null) return EMPTY_STRING; // Does this option instance have the list of values? - if (enumList == null) { + if (applicableValuesList == null) { if (superClass != null) { - return superClass.getEnumCommand(id); + return superClass.getCommand(id); } else { return EMPTY_STRING; } } - if (getValueType() != ENUMERATED) { + if (getValueType() != ENUMERATED && getValueType() != TREE) { throw new BuildException(ManagedMakeMessages.getResourceString("Option.error.bad_value_type")); //$NON-NLS-1$ } // First check for the command in ID->command map - String cmd = getEnumCommandMap().get(id); + String cmd = getCommandMap().get(id); if (cmd == null) { // This may be a 1.2 project or plugin manifest. If so, the argument is the human readable // name of the enumeration. Search for the ID that maps to the name and use that to find the // command. - for (String realID : enumList) { - String name = getEnumNameMap().get(realID); + for (String realID : applicableValuesList) { + String name = getNameMap().get(realID); if (id.equals(name)) { - cmd = getEnumCommandMap().get(realID); + cmd = getCommandMap().get(realID); break; } } @@ -1347,18 +1368,31 @@ public class Option extends BuildObject implements IOption, IBuildPropertiesRest return cmd == null ? EMPTY_STRING : cmd; } + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.IOption#getEnumCommand(java.lang.String) + */ + @Override + public String getEnumCommand(String id) throws BuildException { + return getCommand(id); + } + /* (non-Javadoc) * @see org.eclipse.cdt.managedbuilder.core.IOption#getEnumName(java.lang.String) */ @Override public String getEnumName(String id) throws BuildException { + return getName(id); + } + + @Override + public String getName(String id) throws BuildException { // Sanity if (id == null) return EMPTY_STRING; // Does this option instance have the list of values? - if (enumList == null) { + if (applicableValuesList == null) { if (superClass != null) { - return superClass.getEnumName(id); + return superClass.getName(id); } else { return EMPTY_STRING; } @@ -1368,7 +1402,7 @@ public class Option extends BuildObject implements IOption, IBuildPropertiesRest } // First check for the command in ID->name map - String name = getEnumNameMap().get(id); + String name = getNameMap().get(id); if (name == null) { // This may be a 1.2 project or plugin manifest. If so, the argument is the human readable // name of the enumeration. @@ -1384,11 +1418,11 @@ public class Option extends BuildObject implements IOption, IBuildPropertiesRest * @return a Map of enumerated option value IDs to actual commands that are passed * to a tool on the command line. */ - private Map getEnumCommandMap() { - if (enumCommands == null) { - enumCommands = new HashMap(); + private Map getCommandMap() { + if (commandsMap == null) { + commandsMap = new HashMap(); } - return enumCommands; + return commandsMap; } /* (non-Javadoc) @@ -1396,23 +1430,28 @@ public class Option extends BuildObject implements IOption, IBuildPropertiesRest */ @Override public String getEnumeratedId(String name) throws BuildException { + return getId(name); + } + + @Override + public String getId(String name) throws BuildException { if (name == null) return null; // Does this option instance have the list of values? - if (enumList == null) { + if (applicableValuesList == null) { if (superClass != null) { - return superClass.getEnumeratedId(name); + return superClass.getId(name); } else { return EMPTY_STRING; } } - if (getValueType() != ENUMERATED) { + if (getValueType() != ENUMERATED && getValueType() != TREE) { throw new BuildException(ManagedMakeMessages.getResourceString("Option.error.bad_value_type")); //$NON-NLS-1$ } - Set idSet = getEnumNameMap().keySet(); + Set idSet = getNameMap().keySet(); for (String id : idSet) { - String enumName = getEnumNameMap().get(id); + String enumName = getNameMap().get(id); if (name.equals(enumName)) { return id; } @@ -1424,11 +1463,11 @@ public class Option extends BuildObject implements IOption, IBuildPropertiesRest * * @return a Map of enumerated option value IDs to the selection displayed to the user. */ - private Map getEnumNameMap() { - if (enumNames == null) { - enumNames = new HashMap(); + private Map getNameMap() { + if (namesMap == null) { + namesMap = new HashMap(); } - return enumNames; + return namesMap; } /* (non-Javadoc) @@ -1537,7 +1576,7 @@ public class Option extends BuildObject implements IOption, IBuildPropertiesRest */ @Override public String getStringValue() throws BuildException { - if (getValueType() != STRING && getValueType() != ENUMERATED) { + if (getValueType() != STRING && getValueType() != ENUMERATED && getValueType() != TREE) { throw new BuildException(ManagedMakeMessages.getResourceString("Option.error.bad_value_type")); //$NON-NLS-1$ } return getValue() == null ? EMPTY_STRING : (String)getValue(); @@ -1609,6 +1648,7 @@ public class Option extends BuildObject implements IOption, IBuildPropertiesRest val = new Boolean(false); break; case STRING: + case TREE: val = EMPTY_STRING; break; case ENUMERATED: @@ -1669,6 +1709,7 @@ public class Option extends BuildObject implements IOption, IBuildPropertiesRest val = new Boolean(false); break; case STRING: + case TREE: val = EMPTY_STRING; break; case ENUMERATED: @@ -1949,7 +1990,7 @@ public class Option extends BuildObject implements IOption, IBuildPropertiesRest @Override public void setValue(String value) throws BuildException { // Note that we can still set the human-readable value here - if (/*!isExtensionElement() && */(getValueType() == STRING || getValueType() == ENUMERATED)) { + if (/*!isExtensionElement() && */(getValueType() == STRING || getValueType() == ENUMERATED || getValueType() == TREE)) { this.value = value; } else { throw new BuildException(ManagedMakeMessages.getResourceString("Option.error.bad_value_type")); //$NON-NLS-1$ @@ -2281,19 +2322,43 @@ public class Option extends BuildObject implements IOption, IBuildPropertiesRest for (int i = 0; i < enumElements.length; ++i) { String optId = SafeStringInterner.safeIntern(enumElements[i].getAttribute(ID)); if (i == 0) { - enumList = new ArrayList(); + applicableValuesList = new ArrayList(); if (defaultValue == null) { defaultValue = optId; // Default value to be overridden if default is specified } } - enumList.add(optId); - getEnumCommandMap().put(optId, SafeStringInterner.safeIntern(enumElements[i].getAttribute(COMMAND))); - getEnumNameMap().put(optId, SafeStringInterner.safeIntern(enumElements[i].getAttribute(NAME))); + applicableValuesList.add(optId); + getCommandMap().put(optId, SafeStringInterner.safeIntern(enumElements[i].getAttribute(COMMAND))); + getNameMap().put(optId, SafeStringInterner.safeIntern(enumElements[i].getAttribute(NAME))); Boolean isDefault = new Boolean(enumElements[i].getAttribute(IS_DEFAULT)); if (isDefault.booleanValue()) { defaultValue = optId; } } + break; + case TREE: + value = element.getAttribute(VALUE); + defaultValue = element.getAttribute(DEFAULT_VALUE); + + IManagedConfigElement[] treeRootConfigs = element.getChildren(TREE_ROOT); + if (treeRootConfigs != null && treeRootConfigs.length == 1) { + IManagedConfigElement treeRootConfig = treeRootConfigs[0]; + treeRoot = new TreeRoot(treeRootConfig, element, getParent() instanceof IToolChain); + applicableValuesList = new ArrayList(); + iterateOnTree(treeRoot, new ITreeNodeIterator() { + + @Override + public void iterateOnNode(ITreeOption node) {} + + @Override + public void iterateOnLeaf(ITreeOption leafNode) { + applicableValuesList.add(leafNode.getID()); + getCommandMap().put(leafNode.getID(), leafNode.getCommand()); + getNameMap().put(leafNode.getID(), leafNode.getName()); + } + }); + } + break; case STRING_LIST: case INCLUDE_PATH: @@ -2613,6 +2678,8 @@ public class Option extends BuildObject implements IOption, IBuildPropertiesRest return IOption.STRING; case IOption.ENUMERATED: return IOption.ENUMERATED; + case IOption.TREE: + return IOption.TREE; default: return IOption.STRING_LIST; } @@ -2658,4 +2725,267 @@ public class Option extends BuildObject implements IOption, IBuildPropertiesRest } return 0; } + + public static class TreeRoot extends TreeOption implements ITreeRoot { + private boolean selectLeafOnly = true; + TreeRoot(IManagedConfigElement element, IManagedConfigElement buildOption, boolean readTool) { + super(element, null, readTool); + String leaf = element.getAttribute(SELECT_LEAF_ONLY); + if (leaf != null) { + selectLeafOnly = Boolean.valueOf(leaf); + } + String toolTip = buildOption.getAttribute(TOOL_TIP); + if (description == null && toolTip != null) { + description = toolTip; + } + } + + public TreeRoot() { + super("", "", null); //$NON-NLS-1$ //$NON-NLS-2$ + } + + public TreeRoot(TreeRoot clone) { + super(clone, null); + selectLeafOnly = clone.selectLeafOnly; + } + + @Override + public boolean isSelectLeafsOnly() { + return selectLeafOnly; + } + + @Override + public ITreeOption findNode(String id) { + if(id == null) return null; + return find(id, children); + } + + private ITreeOption find(String id, List children) { + ITreeOption found = null; + if (children != null) { + for (ITreeOption child : children) { + if (id.equals(child.getID())) { + found = child; + break; + } + found = find(id, ((TreeOption)child).children); + if (found != null) break; + } + } + return found; + } + + @Override + public ITreeOption addNode(String id, String name, String category, Integer order) { + ITreeOption parent = this; + if (category != null && category.length() > 0) { + ITreeOption tempParent; + String tempCategory = ""; + String[] categories = category.split("\\."); //$NON-NLS-1$ + for (String cat : categories) { + tempCategory += cat; + tempParent = parent.getChild(cat); + if (tempParent == null) { + tempParent = parent.addChild(cat, cat); + if (order != null) { + tempParent.setOrder(order); + } + } + parent = tempParent; + tempCategory += '.'; + } + } + + ITreeOption child = parent.addChild(id, name); + if (order != null) { + child.setOrder(order); + } + return child; + } + + } + + private static class TreeOption implements ITreeOption { + private String treeNodeId; + private String treeNodeName; + protected String description; + protected String icon; + protected String command; + protected List children = null; + private int order = DEFAULT_ORDER; + private ITreeOption parent; + + TreeOption(IManagedConfigElement element, ITreeOption parent, boolean readTool) { + treeNodeId = element.getAttribute(ID); + treeNodeName = element.getAttribute(NAME); + description = element.getAttribute(DESCRIPTION); + command = element.getAttribute(COMMAND); + icon = element.getAttribute(ICON); + + String orderStr = element.getAttribute(ORDER); + if (orderStr != null && orderStr.trim().length() > 0) { + try { + order = Integer.parseInt(orderStr); + } catch (NumberFormatException e) { + // Do nothing, default value is used. + } + } + this.parent = parent; + + IManagedConfigElement[] treeChildren = element.getChildren(TREE_VALUE); + if (treeChildren != null && treeChildren.length > 0) { + children = new ArrayList(); + for (IManagedConfigElement configElement : treeChildren) { + children.add(new TreeOption(configElement, this, readTool)); + } + } + } + + TreeOption(TreeOption clone, ITreeOption parent) { + treeNodeId = clone.treeNodeId; + treeNodeName = clone.treeNodeName; + description = clone.description; + command = clone.command; + icon = clone.icon; + order = clone.order; + this.parent = parent; + + if (clone.children != null) { + children = new ArrayList(); + for (ITreeOption cloneChild : clone.children) { + children.add(new TreeOption((TreeOption) cloneChild, this)); + } + } + } + + private TreeOption(String id, String name, ITreeOption parent) { + this.treeNodeId = id; + this.treeNodeName = name; + this.parent = parent; + } + + @Override + public ITreeOption addChild(String id, String name) { + ITreeOption option = new TreeOption(id, name, this); + if (children == null) { + children = new ArrayList(); + } + children.add(0, option); + return option; + } + + @Override + public boolean isContainer() { + return children != null && !children.isEmpty(); // TODO do we need explicit marking as container for empty ones + } + + @Override + public String getName() { + return treeNodeName; + } + + @Override + public String getID() { + return treeNodeId; + } + + @Override + public String getDescription() { + return description; + } + + @Override + public String getCommand() { + return command; + } + + @Override + public String getIcon() { + return icon; + } + + @Override + public ITreeOption[] getChildren() { + if (children == null) return null; + return children.toArray(new ITreeOption[children.size()]); + } + + @Override + public ITreeOption getChild(String name) { + if (children == null || name == null) return null; + for (ITreeOption child : children) { + if (name.equals(child.getName())) { + return child; + } + } + return null; + } + + @Override + public ITreeOption getParent() { + return parent; + } + + @Override + public int getOrder() { + return order; + } + + @Override + public void setOrder(int order) { + this.order = order; + } + + @Override + public void remove() { + ((TreeOption)parent).children.remove(this); + + } + + @Override + public String toString() { + return getName(); + } + } + + /** + * Calls the iterator (visitor) on the passed parent as well as all nodes in its subtree. + * @param it + * @param parent + */ + public static void iterateOnTree(ITreeOption parent, ITreeNodeIterator it) { + + it.iterateOnNode(parent); + if (!parent.isContainer()) { + it.iterateOnLeaf(parent); + } + + ITreeOption[] children = parent.getChildren(); + if (children != null) { + for (ITreeOption option : children) { + iterateOnTree(option, it); + } + } + } + + public interface ITreeNodeIterator { + void iterateOnNode(ITreeOption node); + void iterateOnLeaf(ITreeOption leafNode); + } + + @Override + public ITreeRoot getTreeRoot() throws BuildException { + if (treeRoot == null) { + if (superClass != null) { + return superClass.getTreeRoot(); + } else { + return null; + } + } + if (getValueType() != TREE) { + throw new BuildException(ManagedMakeMessages.getResourceString("Option.error.bad_value_type")); //$NON-NLS-1$ + } + + return treeRoot; + } } diff --git a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/OptionReference.java b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/OptionReference.java index e26d2cf9e20..f6d544f18ac 100644 --- a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/OptionReference.java +++ b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/OptionReference.java @@ -117,6 +117,7 @@ public class OptionReference implements IOption { value = new Boolean(element.getAttribute(DEFAULT_VALUE)); break; case STRING: + case TREE: case ENUMERATED: // Pre-2.0 the value was the string for the UI // Post-2.0 it is the ID of the enumerated option @@ -189,6 +190,7 @@ public class OptionReference implements IOption { case STRING: value = element.getAttribute(DEFAULT_VALUE); break; + case TREE: case ENUMERATED: String temp = element.getAttribute(DEFAULT_VALUE); if (temp != null) { @@ -248,6 +250,7 @@ public class OptionReference implements IOption { element.setAttribute(DEFAULT_VALUE, ((Boolean)value).toString()); break; case STRING: + case TREE: case ENUMERATED: element.setAttribute(DEFAULT_VALUE, (String)value); break; @@ -384,6 +387,19 @@ public class OptionReference implements IOption { return new String(); } + public String getCommand(String id) throws BuildException { + if (!resolved) { + resolveReferences(); + } + if (option != null) { + try { + String command = option.getCommand(id); + return command; + } catch (BuildException e) {} + } + return new String(); + } + /* (non-Javadoc) * @see org.eclipse.cdt.core.build.managed.IOption#getEnumName(java.lang.String) */ @@ -401,6 +417,19 @@ public class OptionReference implements IOption { return new String(); } + public String getName(String id) throws BuildException { + if (!resolved) { + resolveReferences(); + } + if (option != null) { + try { + String name = option.getName(id); + return name; + } catch (BuildException e) {} + } + return new String(); + } + /* (non-Javadoc) * @see org.eclipse.cdt.managedbuilder.core.IOption#getEnumeratedId(java.lang.String) */ @@ -418,6 +447,19 @@ public class OptionReference implements IOption { return new String(); } + public String getId(String name) throws BuildException { + if (!resolved) { + resolveReferences(); + } + if (option != null) { + try { + String id = option.getId(name); + return id; + } catch (BuildException e) {} + } + return new String(); + } + /* (non-Javadoc) * @see org.eclipse.cdt.core.build.managed.IBuildObject#getId() */ @@ -730,7 +772,7 @@ public class OptionReference implements IOption { @Override public void setValue(String value) throws BuildException { // Note that we can still set the human-readable value here - if (getValueType() == STRING || getValueType() == ENUMERATED) { + if (getValueType() == STRING || getValueType() == ENUMERATED || getValueType() == TREE) { this.value = value; } else { throw new BuildException(ManagedMakeMessages.getResourceString("Option.error.bad_value_type")); //$NON-NLS-1$ @@ -1024,6 +1066,8 @@ public class OptionReference implements IOption { return IOption.STRING; case IOption.ENUMERATED: return IOption.ENUMERATED; + case IOption.TREE: + return IOption.TREE; default: return IOption.STRING_LIST; } @@ -1039,4 +1083,17 @@ public class OptionReference implements IOption { } return ve; } + public ITreeRoot getTreeRoot() { + if (!resolved) { + resolveReferences(); + } + if (option != null) { + try { + return option.getTreeRoot(); + } catch (BuildException e) { + } + } + return null; + } + } diff --git a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/Tool.java b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/Tool.java index d1f67bc82b3..d1189ad7c74 100644 --- a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/Tool.java +++ b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/Tool.java @@ -2625,6 +2625,13 @@ public class Tool extends HoldsOptions implements ITool, IOptionCategory, IMatch } break; + case IOption.TREE : + String treeVal = option.getCommand(option.getStringValue()); + if (treeVal.length() > 0) { + sb.append(treeVal); + } + break; + case IOption.STRING :{ String strCmd = option.getCommand(); String val = option.getStringValue(); diff --git a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/ToolReference.java b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/ToolReference.java index a983b1cf11d..701d6cab4e3 100644 --- a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/ToolReference.java +++ b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/ToolReference.java @@ -201,7 +201,9 @@ public class ToolReference implements IToolReference { clone.setValue(parent.getBooleanValue()); break; case IOption.STRING: + case IOption.TREE: clone.setValue(parent.getStringValue()); + break; case IOption.ENUMERATED: clone.setValue(parent.getSelectedEnum()); break; @@ -518,6 +520,13 @@ public class ToolReference implements IToolReference { } break; + case IOption.TREE : + String treeVal = option.getCommand(option.getStringValue()); + if (treeVal.length() > 0) { + buf.append(treeVal + WHITE_SPACE); + } + break; + case IOption.STRING : String strCmd = option.getCommand(); String val = option.getStringValue(); diff --git a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/enablement/CheckOptionExpression.java b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/enablement/CheckOptionExpression.java index 9a4a12c84b3..5ebcf95b941 100644 --- a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/enablement/CheckOptionExpression.java +++ b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/enablement/CheckOptionExpression.java @@ -112,6 +112,7 @@ public class CheckOptionExpression implements IBooleanExpression { switch(option.getValueType()){ case IOption.STRING: + case IOption.TREE: case IOption.ENUMERATED:{ String stringValue = option.getStringValue(); stringValue = provider.resolveValue(stringValue, inexVal, delimiter, @@ -177,6 +178,7 @@ public class CheckOptionExpression implements IBooleanExpression { switch(option.getValueType()){ case IOption.STRING: + case IOption.TREE: case IOption.ENUMERATED:{ String stringValue = option.getStringValue(); stringValue = provider.resolveValue(stringValue, inexVal, delimiter, diff --git a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/enablement/OptionEnablementExpression.java b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/enablement/OptionEnablementExpression.java index 1974450ec9d..57bb78ee8bd 100644 --- a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/enablement/OptionEnablementExpression.java +++ b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/enablement/OptionEnablementExpression.java @@ -298,6 +298,7 @@ public class OptionEnablementExpression extends AndExpression{ } break; case IOption.ENUMERATED: + case IOption.TREE: case IOption.STRING: if(extensionAdjustment) setOption.setValue(value); diff --git a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/macros/MbsMacroSupplier.java b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/macros/MbsMacroSupplier.java index 6336160fc62..f61fb6e36cc 100644 --- a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/macros/MbsMacroSupplier.java +++ b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/macros/MbsMacroSupplier.java @@ -913,6 +913,8 @@ public class MbsMacroSupplier extends BuildCdtVariablesSupplierBase { break; case IOption.ENUMERATED: break; + case IOption.TREE: + break; case IOption.STRING_LIST: fType = IBuildMacro.VALUE_TEXT_LIST; fStringListValue = option.getStringListValue(); @@ -1138,6 +1140,8 @@ public class MbsMacroSupplier extends BuildCdtVariablesSupplierBase { break; case IOption.ENUMERATED: break; + case IOption.TREE: + break; case IOption.STRING_LIST: can = true; break; diff --git a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/makegen/gnu/GnuMakefileGenerator.java b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/makegen/gnu/GnuMakefileGenerator.java index e23dbd5d9f2..22aa3e8f072 100644 --- a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/makegen/gnu/GnuMakefileGenerator.java +++ b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/makegen/gnu/GnuMakefileGenerator.java @@ -3044,7 +3044,7 @@ public class GnuMakefileGenerator implements IManagedBuilderMakefileGenerator2 { boolean b = false; if (allRes.size() > 0) b = true; ManagedBuildManager.setOption(rcInfo, tool, assignToOption, b); - } else if (optType == IOption.ENUMERATED) { + } else if (optType == IOption.ENUMERATED || optType == IOption.TREE) { if (allRes.size() > 0) { String s = allRes.get(0).toString(); ManagedBuildManager.setOption(rcInfo, tool, assignToOption, s); diff --git a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/makegen/gnu/ManagedBuildGnuToolInfo.java b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/makegen/gnu/ManagedBuildGnuToolInfo.java index 3ede50863ac..d96ce0bebde 100644 --- a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/makegen/gnu/ManagedBuildGnuToolInfo.java +++ b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/makegen/gnu/ManagedBuildGnuToolInfo.java @@ -422,7 +422,7 @@ public class ManagedBuildGnuToolInfo implements IManagedBuildGnuToolInfo { } else { ManagedBuildManager.setOption(config, tool, assignToOption, false); } - } else if (optType == IOption.ENUMERATED) { + } else if (optType == IOption.ENUMERATED || optType == IOption.TREE) { if (itCommandInputs.size() > 0) { ManagedBuildManager.setOption(config, tool, assignToOption, itCommandInputs.firstElement()); } diff --git a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/projectconverter/UpdateManagedProject12.java b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/projectconverter/UpdateManagedProject12.java index de7cefba7ec..79c113f6446 100644 --- a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/projectconverter/UpdateManagedProject12.java +++ b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/projectconverter/UpdateManagedProject12.java @@ -397,6 +397,19 @@ class UpdateManagedProject12 { } configuration.setOption(tool, newOpt, idValue != null ? idValue : name); break; + case IOption.TREE: + // This is going to be the human readable form of the tree value + name = optRef.getAttribute(IOption.DEFAULT_VALUE); + // Convert it to the ID + idValue = newOpt.getId(name); + if (idValue == null) { + // If the name does not match one of the enumerations values, probably because + // the list of enumerands has changed, set the name to be the name used for the + // enumeration's default value + name = (String)newOpt.getDefaultValue(); + } + configuration.setOption(tool, newOpt, idValue != null ? idValue : name); + break; case IOption.STRING_LIST: case IOption.INCLUDE_PATH: case IOption.PREPROCESSOR_SYMBOLS: diff --git a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/projectconverter/UpdateManagedProject20.java b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/projectconverter/UpdateManagedProject20.java index 69360b49dc2..0b0448d5ae3 100644 --- a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/projectconverter/UpdateManagedProject20.java +++ b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/projectconverter/UpdateManagedProject20.java @@ -427,6 +427,7 @@ class UpdateManagedProject20 { break; } case IOption.ENUMERATED: + case IOption.TREE: case IOption.STRING:{ if(optRef.hasAttribute(IOption.DEFAULT_VALUE)) configuration.setOption(tool,option,optRef.getAttribute(IOption.DEFAULT_VALUE)); diff --git a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/templateengine/processes/SetMBSStringOptionValue.java b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/templateengine/processes/SetMBSStringOptionValue.java index fbb5c76a58a..754f4920da6 100644 --- a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/templateengine/processes/SetMBSStringOptionValue.java +++ b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/templateengine/processes/SetMBSStringOptionValue.java @@ -118,7 +118,7 @@ public class SetMBSStringOptionValue extends ProcessRunner { for (IOption option : options) { if (option.getBaseId().toLowerCase().matches(lowerId)) { int optionType = option.getValueType(); - if ((optionType == IOption.STRING) || (optionType == IOption.ENUMERATED)) { + if ((optionType == IOption.STRING) || (optionType == IOption.ENUMERATED) || (optionType == IOption.TREE)) { ManagedBuildManager.setOption(resourceConfig, optionHolder, option, value); modified = true; } @@ -133,7 +133,7 @@ public class SetMBSStringOptionValue extends ProcessRunner { for (IOption option : options) { if (option.getBaseId().toLowerCase().matches(lowerId)) { int optionType = option.getValueType(); - if ((optionType == IOption.STRING) || (optionType == IOption.ENUMERATED)) { + if ((optionType == IOption.STRING) || (optionType == IOption.ENUMERATED) || (optionType == IOption.TREE)) { ManagedBuildManager.setOption(config, optionHolder, option, value); modified = true; } diff --git a/build/org.eclipse.cdt.managedbuilder.ui/src/org/eclipse/cdt/managedbuilder/ui/properties/BuildOptionSettingsUI.java b/build/org.eclipse.cdt.managedbuilder.ui/src/org/eclipse/cdt/managedbuilder/ui/properties/BuildOptionSettingsUI.java index b940a747ef7..d082e0c696e 100644 --- a/build/org.eclipse.cdt.managedbuilder.ui/src/org/eclipse/cdt/managedbuilder/ui/properties/BuildOptionSettingsUI.java +++ b/build/org.eclipse.cdt.managedbuilder.ui/src/org/eclipse/cdt/managedbuilder/ui/properties/BuildOptionSettingsUI.java @@ -14,8 +14,12 @@ package org.eclipse.cdt.managedbuilder.ui.properties; import java.io.File; +import java.net.URL; import java.util.ArrayList; +import java.util.Arrays; import java.util.Collection; +import java.util.Collections; +import java.util.Comparator; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -28,6 +32,8 @@ import org.eclipse.cdt.managedbuilder.core.IConfiguration; import org.eclipse.cdt.managedbuilder.core.IHoldsOptions; import org.eclipse.cdt.managedbuilder.core.IManagedOptionValueHandler; import org.eclipse.cdt.managedbuilder.core.IOption; +import org.eclipse.cdt.managedbuilder.core.IOption.ITreeOption; +import org.eclipse.cdt.managedbuilder.core.IOption.ITreeRoot; import org.eclipse.cdt.managedbuilder.core.IOptionApplicability; import org.eclipse.cdt.managedbuilder.core.IOptionCategory; import org.eclipse.cdt.managedbuilder.core.IResourceInfo; @@ -42,18 +48,37 @@ import org.eclipse.cdt.ui.newui.AbstractPage; import org.eclipse.core.runtime.IConfigurationElement; import org.eclipse.core.runtime.IExtension; import org.eclipse.core.runtime.IExtensionPoint; +import org.eclipse.core.runtime.FileLocator; +import org.eclipse.jface.dialogs.IDialogConstants; +import org.eclipse.jface.dialogs.TitleAreaDialog; import org.eclipse.core.runtime.Platform; import org.eclipse.jface.preference.BooleanFieldEditor; import org.eclipse.jface.preference.DirectoryFieldEditor; import org.eclipse.jface.preference.FieldEditor; import org.eclipse.jface.preference.FileFieldEditor; +import org.eclipse.jface.preference.StringButtonFieldEditor; import org.eclipse.jface.preference.StringFieldEditor; +import org.eclipse.jface.resource.ImageDescriptor; import org.eclipse.jface.util.PropertyChangeEvent; +import org.eclipse.jface.viewers.DoubleClickEvent; +import org.eclipse.jface.viewers.IDoubleClickListener; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.ISelectionChangedListener; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.jface.viewers.ITreeContentProvider; +import org.eclipse.jface.viewers.LabelProvider; +import org.eclipse.jface.viewers.SelectionChangedEvent; +import org.eclipse.jface.viewers.TreeViewer; +import org.eclipse.jface.viewers.Viewer; +import org.eclipse.jface.window.Window; import org.eclipse.osgi.util.TextProcessor; import org.eclipse.swt.SWT; import org.eclipse.swt.events.ModifyEvent; import org.eclipse.swt.events.ModifyListener; +import org.eclipse.swt.graphics.Image; import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; import org.eclipse.swt.widgets.Button; import org.eclipse.swt.widgets.Combo; import org.eclipse.swt.widgets.Composite; @@ -61,10 +86,13 @@ import org.eclipse.swt.widgets.Control; import org.eclipse.swt.widgets.Event; import org.eclipse.swt.widgets.Label; import org.eclipse.swt.widgets.Listener; +import org.eclipse.swt.widgets.Shell; import org.eclipse.swt.widgets.Text; import org.eclipse.ui.PlatformUI; import org.osgi.framework.Bundle; +import org.eclipse.ui.dialogs.FilteredTree; +import org.eclipse.ui.dialogs.PatternFilter; /** * Option settings page in project properties Build Settings under Tool Settings tab. @@ -87,6 +115,35 @@ public class BuildOptionSettingsUI extends AbstractToolSettingUI { ** currently set to Enter rather than Hover since the former seems more responsive **/ private final static int selectAction = SWT.MouseEnter; + private final class TreeBrowseFieldEditor extends StringButtonFieldEditor { + private final String nameStr; + private final IOption option; + private String contextId; + + private TreeBrowseFieldEditor(String name, String labelText, Composite parent, String nameStr, + IOption option, String contextId) { + super(name, labelText, parent); + this.nameStr = nameStr; + this.option = option; + this.contextId = contextId; + } + + @Override + protected String changePressed() { + ITreeRoot treeRoot; + try { + treeRoot = option.getTreeRoot(); + TreeSelectionDialog dlg = new TreeSelectionDialog(getShell(), treeRoot, nameStr, contextId); + if (dlg.open() == Window.OK) { + ITreeOption selected = dlg.getSelection(); + return selected.getName(); + } + } catch (BuildException e) { + } + return null; + } + } + private class TipInfo { private String name; private String tip; @@ -212,7 +269,7 @@ public class BuildOptionSettingsUI extends AbstractToolSettingUI { if (applicabilityCalculator == null || applicabilityCalculator.isOptionVisible(config, holder, opt)) { String optId = getToolSettingsPrefStore().getOptionId(opt); - String nameStr = TextProcessor.process(opt.getName()); + final String nameStr = TextProcessor.process(opt.getName()); String tipStr = TextProcessor.process(opt.getToolTip()); String contextId = opt.getContextId(); @@ -374,6 +431,20 @@ public class BuildOptionSettingsUI extends AbstractToolSettingUI { } } break; + case IOption.TREE: + fieldEditor = new TreeBrowseFieldEditor(optId, nameStr, fieldEditorParent, nameStr, opt, contextId); + ((StringButtonFieldEditor)fieldEditor).setChangeButtonText("..."); //$NON-NLS-1$ + + if (pageHasToolTipBox) { + Text text = ((StringButtonFieldEditor)fieldEditor).getTextControl(fieldEditorParent); + Label label = fieldEditor.getLabelControl(fieldEditorParent); + text.setData(new TipInfo(nameStr,tipStr)); + text.addListener(selectAction, tipSetListener); + label.setData(new TipInfo(nameStr,tipStr)); + label.addListener(selectAction, tipSetListener); + } + break; + case IOption.INCLUDE_PATH: case IOption.STRING_LIST: case IOption.PREPROCESSOR_SYMBOLS: @@ -563,8 +634,9 @@ public class BuildOptionSettingsUI extends AbstractToolSettingUI { // } break; case IOption.ENUMERATED : + case IOption.TREE : String enumVal = clonedOption.getStringValue(); - String enumId = clonedOption.getEnumeratedId(enumVal); + String enumId = clonedOption.getId(enumVal); setOption = ManagedBuildManager.setOption(realCfg, realHolder, realOption, (enumId != null && enumId.length() > 0) ? enumId : enumVal); // Reset the preference store since the Id may have changed @@ -755,6 +827,15 @@ public class BuildOptionSettingsUI extends AbstractToolSettingUI { ManagedBuildManager.setOption(fInfo,changedHolder,changedOption, (enumId != null && enumId.length() > 0) ? enumId : name); + } + break; + case IOption.TREE: + if(fe instanceof TreeBrowseFieldEditor){ + String name = ((TreeBrowseFieldEditor)fe).getStringValue(); + String treeId = changedOption.getId(name); + ManagedBuildManager.setOption(fInfo,changedHolder,changedOption, + (treeId != null && treeId.length() > 0) ? treeId : name); + } break; case IOption.INCLUDE_PATH: @@ -1004,5 +1085,237 @@ public class BuildOptionSettingsUI extends AbstractToolSettingUI { } } + /** + * @since 8.1 + */ + public static class TreeSelectionDialog extends TitleAreaDialog { + private final ITreeRoot treeRoot; + private ITreeOption selected; + private final String name; + private String contextId; + private String baseMessage = ""; //$NON-NLS-1$ + public TreeSelectionDialog(Shell parentShell, ITreeRoot root, String name, String contextId) { + super(parentShell); + treeRoot = root; + setShellStyle(getShellStyle() | SWT.RESIZE); + if (root.getIcon() != null) { + Image img = createImage(root.getIcon()); + if (img != null) { + setTitleImage(img); + } + } + this.name = name; + this.contextId = contextId; + if (contextId != null && contextId.length() > 0) { + setHelpAvailable(true); + } + } + + @Override + protected Control createDialogArea(Composite parent) { + if (contextId != null && contextId.length() > 0) { + PlatformUI.getWorkbench().getHelpSystem().setHelp(parent, contextId); + } + + Composite control = new Composite(parent, SWT.NULL); + GridData gd= new GridData(GridData.FILL_BOTH); + GridLayout topLayout = new GridLayout(); + topLayout.numColumns = 1; + control.setLayout(topLayout); + control.setLayoutData(gd); + + PatternFilter filter = new PatternFilter(); + filter.setIncludeLeadingWildcard(true); + FilteredTree tree = new FilteredTree(control, + SWT.SINGLE | SWT.H_SCROLL | SWT.V_SCROLL | SWT.BORDER, + filter, true); + final TreeViewer viewer = tree.getViewer(); + viewer.setContentProvider(new ITreeContentProvider() { + + @Override + public void dispose() { + } + + @Override + public void inputChanged(Viewer viewer, Object oldInput, Object newInput) { + } + + @Override + public Object[] getElements(Object inputElement) { + return getChildren(inputElement); + } + + @Override + public Object[] getChildren(Object parentElement) { + if (parentElement instanceof ITreeOption) { + ITreeOption[] children = ((ITreeOption)parentElement).getChildren(); + + // Not entirely sure whether this method is allowed to return null, + // but let's play safe. + if (children == null) + return null; + + List childrenList = new ArrayList(Arrays.asList(children)); + + // Check if any of the children has empty name + List toRemove = null; + for (ITreeOption child : children) { + if (child.getName() == null || child.getName().trim().length() == 0) { + if (toRemove == null) { + toRemove = new ArrayList(); + } + toRemove.add(child); + } + } + if (toRemove != null) { + childrenList.removeAll(toRemove); + } + + // Sort the children. + Collections.sort(childrenList, new Comparator() { + @Override + public int compare(ITreeOption arg0, ITreeOption arg1) { + if (arg0.getOrder() == arg1.getOrder()) { + return arg0.getName().compareToIgnoreCase(arg1.getName()); + } else { + return arg0.getOrder() - arg1.getOrder(); + } + } + }); + + return childrenList.toArray(new ITreeOption[0]); + } + return null; + } + + @Override + public Object getParent(Object element) { + if (element instanceof ITreeOption) { + return ((ITreeOption)element).getParent(); + } + return null; + } + + @Override + public boolean hasChildren(Object element) { + Object[] children = getChildren(element); + return children != null && children.length > 0; + } + + }); + + viewer.setLabelProvider(new LabelProvider() { + + @Override + public String getText(Object element) { + if (element instanceof ITreeOption) { + return ((ITreeOption)element).getName(); + } + return super.getText(element); + } + + @Override + public Image getImage(Object element) { + if (element instanceof ITreeOption) { + String icon = ((ITreeOption)element).getIcon(); + return createImage(icon); + } + return super.getImage(element); + } + }); + + viewer.addSelectionChangedListener(new ISelectionChangedListener() { + + @Override + public void selectionChanged(SelectionChangedEvent event) { + ISelection selection = event.getSelection(); + if (selection instanceof IStructuredSelection) { + Object selectedObj = ((IStructuredSelection)selection).getFirstElement(); + if (selectedObj instanceof ITreeOption) { + selected = (ITreeOption) selectedObj; + + updateOKButton(selected); + + // Adjust Message + String description = selected.getDescription(); + if (description == null) { + ITreeOption node = selected; + description = ""; //$NON-NLS-1$ + String sep = ": "; //$NON-NLS-1$ + while (node != null && node.getParent() != null) { // ignore root + description = sep + node.getName() + description; + node = node.getParent(); + } + description = description.substring(sep.length()); // remove the first separator. + } + setMessage(baseMessage + description); + } + } + } + }); + + viewer.addDoubleClickListener(new IDoubleClickListener() { + + @Override + public void doubleClick(DoubleClickEvent event) { + ISelection selection = event.getSelection(); + if (!selection.isEmpty() && selection instanceof IStructuredSelection && ((IStructuredSelection)selection).size() == 1) { + Object selectedNode = ((IStructuredSelection)selection).getFirstElement(); + if (selectedNode instanceof ITreeOption) { + if (updateOKButton((ITreeOption)selectedNode)) { + TreeSelectionDialog.this.okPressed(); + } else { // if doubleclick is not on selectable item, expand/collapse + viewer.setExpandedState(selectedNode,!viewer.getExpandedState(selectedNode)); + } + } + } + } + }); + + viewer.setInput(treeRoot); + + String msg = "Select " + name; //$NON-NLS-1$ + getShell().setText(msg); + setTitle(msg); + if (treeRoot.getDescription() != null) { + baseMessage = treeRoot.getDescription(); + setMessage(baseMessage); + baseMessage += "\nCurrent Selection: "; //$NON-NLS-1$ + } else { + setMessage(msg); + } + + return control; + } + + public ITreeOption getSelection() { + return selected; + } + + private Image createImage(String icon) { + if (icon != null) { + URL url = null; + try { + url = FileLocator.find(new URL(icon)); + } catch (Exception e) { + } + if (url != null) { + ImageDescriptor desc = ImageDescriptor.createFromURL(url); + return desc.createImage(); + } + } + return null; + } + + private boolean updateOKButton(ITreeOption selection) { + // Check if Valid selection (only allow selecting leaf nodes) + if (treeRoot.isSelectLeafsOnly()) { + boolean enableOK = !selection.isContainer(); + getButton(IDialogConstants.OK_ID).setEnabled(enableOK); + return enableOK; + } + return false; + } + } } diff --git a/build/org.eclipse.cdt.managedbuilder.ui/src/org/eclipse/cdt/managedbuilder/ui/properties/BuildToolSettingUI.java b/build/org.eclipse.cdt.managedbuilder.ui/src/org/eclipse/cdt/managedbuilder/ui/properties/BuildToolSettingUI.java index 685cf46fee0..547d4d61f83 100644 --- a/build/org.eclipse.cdt.managedbuilder.ui/src/org/eclipse/cdt/managedbuilder/ui/properties/BuildToolSettingUI.java +++ b/build/org.eclipse.cdt.managedbuilder.ui/src/org/eclipse/cdt/managedbuilder/ui/properties/BuildToolSettingUI.java @@ -20,6 +20,7 @@ import java.util.Vector; import org.eclipse.cdt.managedbuilder.core.BuildException; import org.eclipse.cdt.managedbuilder.core.IOption; +import org.eclipse.cdt.managedbuilder.core.IOption.ITreeRoot; import org.eclipse.cdt.managedbuilder.core.IResourceInfo; import org.eclipse.cdt.managedbuilder.core.ITool; import org.eclipse.cdt.managedbuilder.internal.core.MultiResourceInfo; @@ -316,6 +317,20 @@ public class BuildToolSettingUI extends AbstractToolSettingUI { if (!enumeration.equals("")) //$NON-NLS-1$ setOption(opt, enumeration); break; + case IOption.TREE : + String selectedID = ""; //$NON-NLS-1$ + ITreeRoot treeRoot = opt.getTreeRoot(); + String[] treeValues = opt.getApplicableValues(); + for (int i = 0; i < treeValues.length; i++) { + if (opt.getCommand(treeValues[i]).equals( + optionValue)) { + selectedID = treeValues[i]; + optionValueExist = true; + } + } + if (!selectedID.equals("")) //$NON-NLS-1$ + setOption(opt, selectedID); + break; case IOption.STRING_LIST : case IOption.INCLUDE_PATH : case IOption.PREPROCESSOR_SYMBOLS : diff --git a/build/org.eclipse.cdt.managedbuilder.ui/src/org/eclipse/cdt/managedbuilder/ui/properties/ToolSettingsPrefStore.java b/build/org.eclipse.cdt.managedbuilder.ui/src/org/eclipse/cdt/managedbuilder/ui/properties/ToolSettingsPrefStore.java index f1f0ec3eaee..dd5c356a013 100644 --- a/build/org.eclipse.cdt.managedbuilder.ui/src/org/eclipse/cdt/managedbuilder/ui/properties/ToolSettingsPrefStore.java +++ b/build/org.eclipse.cdt.managedbuilder.ui/src/org/eclipse/cdt/managedbuilder/ui/properties/ToolSettingsPrefStore.java @@ -205,8 +205,8 @@ public class ToolSettingsPrefStore implements IPreferenceStore { try { IOption opt = (IOption)option[1]; Object val = opt.getValue(); - if(opt.getValueType() == IOption.ENUMERATED && val instanceof String) - val = opt.getEnumName((String)val); + if((opt.getValueType() == IOption.ENUMERATED || opt.getValueType() == IOption.TREE) && val instanceof String) + val = opt.getName((String)val); return val; } catch (BuildException e) { } @@ -313,9 +313,10 @@ public class ToolSettingsPrefStore implements IPreferenceStore { } break; case IOption.ENUMERATED: + case IOption.TREE: if(value instanceof String){ String val = (String)value; - String enumId = option.getEnumeratedId(val); + String enumId = option.getId(val); newOption = rcInfo.setOption(holder, option, (enumId != null && enumId.length() > 0) ? enumId : val); } diff --git a/build/org.eclipse.cdt.managedbuilder.ui/src/org/eclipse/cdt/managedbuilder/ui/properties/ToolSettingsTab.java b/build/org.eclipse.cdt.managedbuilder.ui/src/org/eclipse/cdt/managedbuilder/ui/properties/ToolSettingsTab.java index db5056087ea..a6e7dabb923 100644 --- a/build/org.eclipse.cdt.managedbuilder.ui/src/org/eclipse/cdt/managedbuilder/ui/properties/ToolSettingsTab.java +++ b/build/org.eclipse.cdt.managedbuilder.ui/src/org/eclipse/cdt/managedbuilder/ui/properties/ToolSettingsTab.java @@ -568,8 +568,9 @@ public class ToolSettingsTab extends AbstractCBuildPropertyTab implements IPrefe ManagedBuildManager.setOption(res, dst, op2, boolVal); break; case IOption.ENUMERATED : + case IOption.TREE : String enumVal = op1.getStringValue(); - String enumId = op1.getEnumeratedId(enumVal); + String enumId = op1.getId(enumVal); String out = (enumId != null && enumId.length() > 0) ? enumId : enumVal; ManagedBuildManager.setOption(res, dst, op2, out); break;