@joebigelow / wix / commits / abff61df

Implement BundleCustomData. Remove Unreal from CustomTable.

Sean Hall committed Jun 19, 2020 at 13:52 UTC abff61df823505abc01776cec7b207501c671bf2
9 files changed +680 -379
src/WixToolset.Core.Burn/Bind/GenerateManifestDataFromIRCommand.cs
+59 -39
@@ -2,6 +2,7 @@
2
3 namespace WixToolset.Core.Burn.Bind
4 {
5 + using System;
6 using System.Collections.Generic;
7 using System.Linq;
8 using System.Text;
@@ -37,8 +38,8 @@ namespace WixToolset.Core.Burn.Bind
38 public void Execute()
39 {
40 var tuples = this.Section.Tuples.ToList();
40 - var cellsByTableAndRowId = new Dictionary<string, List<WixCustomTableCellTuple>>();
41 - var customTablesById = new Dictionary<string, WixCustomTableTuple>();
41 + var cellsByCustomDataAndElementId = new Dictionary<string, List<WixBundleCustomDataCellTuple>>();
42 + var customDataById = new Dictionary<string, WixBundleCustomDataTuple>();
43
44 foreach (var kvp in this.ExtensionSearchTuplesById)
45 {
@@ -63,6 +64,7 @@ namespace WixToolset.Core.Burn.Bind
64 case TupleDefinitionType.WixBundle:
65 case TupleDefinitionType.WixBundleCatalog:
66 case TupleDefinitionType.WixBundleContainer:
67 + case TupleDefinitionType.WixBundleCustomDataAttribute:
68 case TupleDefinitionType.WixBundleExePackage:
69 case TupleDefinitionType.WixBundleExtension:
70 case TupleDefinitionType.WixBundleMsiFeature:
@@ -82,7 +84,6 @@ namespace WixToolset.Core.Burn.Bind
84 case TupleDefinitionType.WixBundleVariable:
85 case TupleDefinitionType.WixChain:
86 case TupleDefinitionType.WixComponentSearch:
85 - case TupleDefinitionType.WixCustomTableColumn:
87 case TupleDefinitionType.WixDependencyProvider:
88 case TupleDefinitionType.WixFileSearch:
89 case TupleDefinitionType.WixGroup:
@@ -95,12 +96,12 @@ namespace WixToolset.Core.Burn.Bind
96 case TupleDefinitionType.WixUpdateRegistration:
97 break;
98
98 - case TupleDefinitionType.WixCustomTable:
99 - unknownTuple = !this.IndexCustomTableTuple((WixCustomTableTuple)tuple, customTablesById);
99 + case TupleDefinitionType.WixBundleCustomData:
100 + unknownTuple = !this.IndexBundleCustomDataTuple((WixBundleCustomDataTuple)tuple, customDataById);
101 break;
102
102 - case TupleDefinitionType.WixCustomTableCell:
103 - this.IndexCustomTableCellTuple((WixCustomTableCellTuple)tuple, cellsByTableAndRowId);
103 + case TupleDefinitionType.WixBundleCustomDataCell:
104 + this.IndexBundleCustomDataCellTuple((WixBundleCustomDataCellTuple)tuple, cellsByCustomDataAndElementId);
105 break;
106
107 case TupleDefinitionType.MustBeFromAnExtension:
@@ -118,68 +119,87 @@ namespace WixToolset.Core.Burn.Bind
119 }
120 }
121
121 - this.AddIndexedCellTuples(customTablesById, cellsByTableAndRowId);
122 + this.AddIndexedCellTuples(customDataById, cellsByCustomDataAndElementId);
123 }
124
124 - private bool IndexCustomTableTuple(WixCustomTableTuple wixCustomTableTuple, Dictionary<string, WixCustomTableTuple> customTablesById)
125 + private bool IndexBundleCustomDataTuple(WixBundleCustomDataTuple wixBundleCustomDataTuple, Dictionary<string, WixBundleCustomDataTuple> customDataById)
126 {
126 - if (!wixCustomTableTuple.Unreal)
127 + switch (wixBundleCustomDataTuple.Type)
128 {
128 - return false;
129 + case WixBundleCustomDataType.BootstrapperApplication:
130 + case WixBundleCustomDataType.BundleExtension:
131 + break;
132 + default:
133 + return false;
134 }
135
131 - var tableId = wixCustomTableTuple.Id.Id;
132 - customTablesById.Add(tableId, wixCustomTableTuple);
136 + var customDataId = wixBundleCustomDataTuple.Id.Id;
137 + customDataById.Add(customDataId, wixBundleCustomDataTuple);
138 return true;
139 }
140
136 - private void IndexCustomTableCellTuple(WixCustomTableCellTuple wixCustomTableCellTuple, Dictionary<string, List<WixCustomTableCellTuple>> cellsByTableAndRowId)
141 + private void IndexBundleCustomDataCellTuple(WixBundleCustomDataCellTuple wixBundleCustomDataCellTuple, Dictionary<string, List<WixBundleCustomDataCellTuple>> cellsByCustomDataAndElementId)
142 {
138 - var tableAndRowId = wixCustomTableCellTuple.TableRef + "/" + wixCustomTableCellTuple.RowId;
139 - if (!cellsByTableAndRowId.TryGetValue(tableAndRowId, out var cells))
143 + var tableAndRowId = wixBundleCustomDataCellTuple.CustomDataRef + "/" + wixBundleCustomDataCellTuple.ElementId;
144 + if (!cellsByCustomDataAndElementId.TryGetValue(tableAndRowId, out var cells))
145 {
141 - cells = new List<WixCustomTableCellTuple>();
142 - cellsByTableAndRowId.Add(tableAndRowId, cells);
146 + cells = new List<WixBundleCustomDataCellTuple>();
147 + cellsByCustomDataAndElementId.Add(tableAndRowId, cells);
148 }
149
145 - cells.Add(wixCustomTableCellTuple);
150 + cells.Add(wixBundleCustomDataCellTuple);
151 }
152
148 - private void AddIndexedCellTuples(Dictionary<string, WixCustomTableTuple> customTablesById, Dictionary<string, List<WixCustomTableCellTuple>> cellsByTableAndRowId)
153 + private void AddIndexedCellTuples(Dictionary<string, WixBundleCustomDataTuple> customDataById, Dictionary<string, List<WixBundleCustomDataCellTuple>> cellsByCustomDataAndElementId)
154 {
150 - var sb = new StringBuilder();
151 - using (var writer = XmlWriter.Create(sb, BurnBackendHelper.WriterSettings))
155 + foreach (var elementValues in cellsByCustomDataAndElementId.Values)
156 {
153 - foreach (var rowOfCells in cellsByTableAndRowId.Values)
154 - {
155 - var tableId = rowOfCells[0].TableRef;
156 - var tableTuple = customTablesById[tableId];
157 -
158 - if (!tableTuple.Unreal)
159 - {
160 - return;
161 - }
157 + var elementName = elementValues[0].CustomDataRef;
158 + var customDataTuple = customDataById[elementName];
159
163 - var columnNames = tableTuple.ColumnNamesSeparated;
160 + var attributeNames = customDataTuple.AttributeNamesSeparated;
161
165 - var rowDataByColumn = rowOfCells.ToDictionary(t => t.ColumnRef, t => t.Data);
162 + var elementValuesByAttribute = elementValues.ToDictionary(t => t.AttributeRef, t => t.Value);
163
167 - writer.WriteStartElement(tableId, BurnCommon.BADataNamespace);
164 + var sb = new StringBuilder();
165 + using (var writer = XmlWriter.Create(sb, BurnBackendHelper.WriterSettings))
166 + {
167 + switch (customDataTuple.Type)
168 + {
169 + case WixBundleCustomDataType.BootstrapperApplication:
170 + writer.WriteStartElement(elementName, BurnCommon.BADataNamespace);
171 + break;
172 + case WixBundleCustomDataType.BundleExtension:
173 + writer.WriteStartElement(elementName, BurnCommon.BundleExtensionDataNamespace);
174 + break;
175 + default:
176 + throw new NotImplementedException();
177 + }
178
179 // Write all row data as attributes in table column order.
170 - foreach (var column in columnNames)
180 + foreach (var attributeName in attributeNames)
181 {
172 - if (rowDataByColumn.TryGetValue(column, out var data))
182 + if (elementValuesByAttribute.TryGetValue(attributeName, out var value))
183 {
174 - writer.WriteAttributeString(column, data);
184 + writer.WriteAttributeString(attributeName, value);
185 }
186 }
187
188 writer.WriteEndElement();
189 }
180 - }
190
182 - this.BackendHelper.AddBootstrapperApplicationData(sb.ToString());
191 + switch (customDataTuple.Type)
192 + {
193 + case WixBundleCustomDataType.BootstrapperApplication:
194 + this.BackendHelper.AddBootstrapperApplicationData(sb.ToString());
195 + break;
196 + case WixBundleCustomDataType.BundleExtension:
197 + this.BackendHelper.AddBundleExtensionData(customDataTuple.BundleExtensionRef, sb.ToString());
198 + break;
199 + default:
200 + throw new NotImplementedException();
201 + }
202 + }
203 }
204
205 private bool AddTupleFromExtension(IntermediateTuple tuple)
src/WixToolset.Core.WindowsInstaller/Bind/CreateOutputFromIRCommand.cs
+3 -1
@@ -4,6 +4,7 @@ namespace WixToolset.Core.WindowsInstaller.Bind
4 {
5 using System;
6 using System.Collections.Generic;
7 + using System.Diagnostics;
8 using System.Globalization;
9 using System.Linq;
10 using WixToolset.Data;
@@ -978,7 +979,8 @@ namespace WixToolset.Core.WindowsInstaller.Bind
979
980 if (customTableDefinition.Unreal)
981 {
981 - return;
982 + Debug.Assert(false, "CustomTableDefinition should never be unreal.");
983 + continue;
984 }
985
986 var customRow = this.CreateRow(firstCellTuple, customTableDefinition);
src/WixToolset.Core.WindowsInstaller/Bind/LoadTableDefinitionsCommand.cs
+1 -1
@@ -208,7 +208,7 @@ namespace WixToolset.Core.WindowsInstaller.Bind
208 columns.Add(columnDefinition);
209 }
210
211 - var customTable = new TableDefinition(tuple.Id.Id, null, columns, tuple.Unreal);
211 + var customTable = new TableDefinition(tuple.Id.Id, null, columns);
212 return customTable;
213 }
214 }
src/WixToolset.Core/Compiler.cs
+293 -273
@@ -3668,7 +3668,6 @@ namespace WixToolset.Core
3668 {
3669 var sourceLineNumbers = Preprocessor.GetSourceLineNumbers(node);
3670 string tableId = null;
3671 - var unreal = false;
3671 var columns = new List<WixCustomTableColumnTuple>();
3672
3673 foreach (var attrib in node.Attributes())
@@ -3680,9 +3679,6 @@ namespace WixToolset.Core
3679 case "Id":
3680 tableId = this.Core.GetAttributeIdentifierValue(sourceLineNumbers, attrib);
3681 break;
3683 - case "Unreal":
3684 - unreal = YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib);
3685 - break;
3682 default:
3683 this.Core.UnexpectedAttribute(node, attrib);
3684 break;
@@ -3710,315 +3706,336 @@ namespace WixToolset.Core
3706 var childSourceLineNumbers = Preprocessor.GetSourceLineNumbers(child);
3707 switch (child.Name.LocalName)
3708 {
3713 - case "Column":
3714 - string columnName = null;
3715 - IntermediateFieldType? columnType = null;
3716 - var description = String.Empty;
3717 - int? keyColumn = null;
3718 - var keyTable = String.Empty;
3719 - var localizable = false;
3720 - long? maxValue = null;
3721 - long? minValue = null;
3722 - WixCustomTableColumnCategoryType? category = null;
3723 - var modularization = WixCustomTableColumnModularizeType.None;
3724 - var nullable = false;
3725 - var primaryKey = false;
3726 - var setValues = String.Empty;
3727 - var columnUnreal = false;
3728 - var width = 0;
3729 -
3730 - foreach (var childAttrib in child.Attributes())
3731 - {
3732 - switch (childAttrib.Name.LocalName)
3709 + case "Column":
3710 + var column = this.ParseColumnElement(child, childSourceLineNumbers, tableId);
3711 + if (column != null)
3712 {
3734 - case "Id":
3735 - columnName = this.Core.GetAttributeIdentifierValue(childSourceLineNumbers, childAttrib);
3713 + columns.Add(column);
3714 + }
3715 + break;
3716 + case "Row":
3717 + this.ParseRowElement(child, childSourceLineNumbers, tableId);
3718 + break;
3719 + default:
3720 + this.Core.UnexpectedElement(node, child);
3721 + break;
3722 + }
3723 + }
3724 + else
3725 + {
3726 + this.Core.ParseExtensionElement(node, child);
3727 + }
3728 + }
3729 +
3730 + if (columns.Count > 0)
3731 + {
3732 + if (!columns.Where(c => c.PrimaryKey).Any())
3733 + {
3734 + this.Core.Write(ErrorMessages.CustomTableMissingPrimaryKey(sourceLineNumbers));
3735 + }
3736 +
3737 + if (!this.Core.EncounteredError)
3738 + {
3739 + var columnNames = String.Join(new string(WixCustomTableTuple.ColumnNamesSeparator, 1), columns.Select(c => c.Name));
3740 +
3741 + this.Core.AddTuple(new WixCustomTableTuple(sourceLineNumbers, new Identifier(AccessModifier.Public, tableId))
3742 + {
3743 + ColumnNames = columnNames,
3744 + });
3745 + }
3746 + }
3747 + }
3748 +
3749 + /// <summary>
3750 + /// Parses a Column element.
3751 + /// </summary>
3752 + /// <param name="child">Element to parse.</param>
3753 + /// <param name="childSourceLineNumbers">Element's SourceLineNumbers.</param>
3754 + /// <param name="tableId">Table Id.</param>
3755 + private WixCustomTableColumnTuple ParseColumnElement(XElement child, SourceLineNumber childSourceLineNumbers, string tableId)
3756 + {
3757 + string columnName = null;
3758 + IntermediateFieldType? columnType = null;
3759 + var description = String.Empty;
3760 + int? keyColumn = null;
3761 + var keyTable = String.Empty;
3762 + var localizable = false;
3763 + long? maxValue = null;
3764 + long? minValue = null;
3765 + WixCustomTableColumnCategoryType? category = null;
3766 + var modularization = WixCustomTableColumnModularizeType.None;
3767 + var nullable = false;
3768 + var primaryKey = false;
3769 + var setValues = String.Empty;
3770 + var columnUnreal = false;
3771 + var width = 0;
3772 +
3773 + foreach (var childAttrib in child.Attributes())
3774 + {
3775 + switch (childAttrib.Name.LocalName)
3776 + {
3777 + case "Id":
3778 + columnName = this.Core.GetAttributeIdentifierValue(childSourceLineNumbers, childAttrib);
3779 + break;
3780 + case "Category":
3781 + var categoryValue = this.Core.GetAttributeValue(childSourceLineNumbers, childAttrib);
3782 + switch (categoryValue)
3783 + {
3784 + case "text":
3785 + category = WixCustomTableColumnCategoryType.Text;
3786 break;
3737 - case "Category":
3738 - var categoryValue = this.Core.GetAttributeValue(childSourceLineNumbers, childAttrib);
3739 - switch (categoryValue)
3740 - {
3741 - case "text":
3742 - category = WixCustomTableColumnCategoryType.Text;
3743 - break;
3744 - case "upperCase":
3745 - category = WixCustomTableColumnCategoryType.UpperCase;
3746 - break;
3747 - case "lowerCase":
3748 - category = WixCustomTableColumnCategoryType.LowerCase;
3749 - break;
3750 - case "integer":
3751 - category = WixCustomTableColumnCategoryType.Integer;
3752 - break;
3753 - case "doubleInteger":
3754 - category = WixCustomTableColumnCategoryType.DoubleInteger;
3755 - break;
3756 - case "timeDate":
3757 - category = WixCustomTableColumnCategoryType.TimeDate;
3758 - break;
3759 - case "identifier":
3760 - category = WixCustomTableColumnCategoryType.Identifier;
3761 - break;
3762 - case "property":
3763 - category = WixCustomTableColumnCategoryType.Property;
3764 - break;
3765 - case "filename":
3766 - category = WixCustomTableColumnCategoryType.Filename;
3767 - break;
3768 - case "wildCardFilename":
3769 - category = WixCustomTableColumnCategoryType.WildCardFilename;
3770 - break;
3771 - case "path":
3772 - category = WixCustomTableColumnCategoryType.Path;
3773 - break;
3774 - case "paths":
3775 - category = WixCustomTableColumnCategoryType.Paths;
3776 - break;
3777 - case "anyPath":
3778 - category = WixCustomTableColumnCategoryType.AnyPath;
3779 - break;
3780 - case "defaultDir":
3781 - category = WixCustomTableColumnCategoryType.DefaultDir;
3782 - break;
3783 - case "regPath":
3784 - category = WixCustomTableColumnCategoryType.RegPath;
3785 - break;
3786 - case "formatted":
3787 - category = WixCustomTableColumnCategoryType.Formatted;
3788 - break;
3789 - case "formattedSddl":
3790 - category = WixCustomTableColumnCategoryType.FormattedSddl;
3791 - break;
3792 - case "template":
3793 - category = WixCustomTableColumnCategoryType.Template;
3794 - break;
3795 - case "condition":
3796 - category = WixCustomTableColumnCategoryType.Condition;
3797 - break;
3798 - case "guid":
3799 - category = WixCustomTableColumnCategoryType.Guid;
3800 - break;
3801 - case "version":
3802 - category = WixCustomTableColumnCategoryType.Version;
3803 - break;
3804 - case "language":
3805 - category = WixCustomTableColumnCategoryType.Language;
3806 - break;
3807 - case "binary":
3808 - category = WixCustomTableColumnCategoryType.Binary;
3809 - break;
3810 - case "customSource":
3811 - category = WixCustomTableColumnCategoryType.CustomSource;
3812 - break;
3813 - case "cabinet":
3814 - category = WixCustomTableColumnCategoryType.Cabinet;
3815 - break;
3816 - case "shortcut":
3817 - category = WixCustomTableColumnCategoryType.Shortcut;
3818 - break;
3819 - case "":
3820 - break;
3821 - default:
3822 - this.Core.Write(ErrorMessages.IllegalAttributeValue(childSourceLineNumbers, child.Name.LocalName, "Category", categoryValue,
3823 - "text", "upperCase", "lowerCase", "integer", "doubleInteger", "timeDate", "identifier", "property", "filename",
3824 - "wildCardFilename", "path", "paths", "anyPath", "defaultDir", "regPath", "formatted", "formattedSddl", "template",
3825 - "condition", "guid", "version", "language", "binary", "customSource", "cabinet", "shortcut"));
3826 - columnType = IntermediateFieldType.String; // set a value to prevent expected attribute error below.
3827 - break;
3828 - }
3787 + case "upperCase":
3788 + category = WixCustomTableColumnCategoryType.UpperCase;
3789 break;
3830 - case "Description":
3831 - description = this.Core.GetAttributeValue(childSourceLineNumbers, childAttrib);
3790 + case "lowerCase":
3791 + category = WixCustomTableColumnCategoryType.LowerCase;
3792 break;
3833 - case "KeyColumn":
3834 - keyColumn = this.Core.GetAttributeIntegerValue(childSourceLineNumbers, childAttrib, 1, 32);
3793 + case "integer":
3794 + category = WixCustomTableColumnCategoryType.Integer;
3795 break;
3836 - case "KeyTable":
3837 - keyTable = this.Core.GetAttributeValue(childSourceLineNumbers, childAttrib);
3796 + case "doubleInteger":
3797 + category = WixCustomTableColumnCategoryType.DoubleInteger;
3798 break;
3839 - case "Localizable":
3840 - localizable = YesNoType.Yes == this.Core.GetAttributeYesNoValue(childSourceLineNumbers, childAttrib);
3799 + case "timeDate":
3800 + category = WixCustomTableColumnCategoryType.TimeDate;
3801 break;
3842 - case "MaxValue":
3843 - maxValue = this.Core.GetAttributeLongValue(childSourceLineNumbers, childAttrib, Int32.MinValue + 1, Int32.MaxValue);
3802 + case "identifier":
3803 + category = WixCustomTableColumnCategoryType.Identifier;
3804 break;
3845 - case "MinValue":
3846 - minValue = this.Core.GetAttributeLongValue(childSourceLineNumbers, childAttrib, Int32.MinValue + 1, Int32.MaxValue);
3805 + case "property":
3806 + category = WixCustomTableColumnCategoryType.Property;
3807 break;
3848 - case "Modularize":
3849 - var modularizeValue = this.Core.GetAttributeValue(childSourceLineNumbers, childAttrib);
3850 - switch (modularizeValue)
3851 - {
3852 - case "column":
3853 - modularization = WixCustomTableColumnModularizeType.Column;
3854 - break;
3855 - case "companionFile":
3856 - modularization = WixCustomTableColumnModularizeType.CompanionFile;
3857 - break;
3858 - case "condition":
3859 - modularization = WixCustomTableColumnModularizeType.Condition;
3860 - break;
3861 - case "controlEventArgument":
3862 - modularization = WixCustomTableColumnModularizeType.ControlEventArgument;
3863 - break;
3864 - case "controlText":
3865 - modularization = WixCustomTableColumnModularizeType.ControlText;
3866 - break;
3867 - case "icon":
3868 - modularization = WixCustomTableColumnModularizeType.Icon;
3869 - break;
3870 - case "none":
3871 - modularization = WixCustomTableColumnModularizeType.None;
3872 - break;
3873 - case "property":
3874 - modularization = WixCustomTableColumnModularizeType.Property;
3875 - break;
3876 - case "semicolonDelimited":
3877 - modularization = WixCustomTableColumnModularizeType.SemicolonDelimited;
3878 - break;
3879 - case "":
3880 - break;
3881 - default:
3882 - this.Core.Write(ErrorMessages.IllegalAttributeValue(childSourceLineNumbers, child.Name.LocalName, "Modularize", modularizeValue, "column", "companionFile", "condition", "controlEventArgument", "controlText", "icon", "property", "semicolonDelimited"));
3883 - columnType = IntermediateFieldType.String; // set a value to prevent expected attribute error below.
3884 - break;
3885 - }
3808 + case "filename":
3809 + category = WixCustomTableColumnCategoryType.Filename;
3810 break;
3887 - case "Nullable":
3888 - nullable = YesNoType.Yes == this.Core.GetAttributeYesNoValue(childSourceLineNumbers, childAttrib);
3811 + case "wildCardFilename":
3812 + category = WixCustomTableColumnCategoryType.WildCardFilename;
3813 break;
3890 - case "PrimaryKey":
3891 - primaryKey = YesNoType.Yes == this.Core.GetAttributeYesNoValue(childSourceLineNumbers, childAttrib);
3814 + case "path":
3815 + category = WixCustomTableColumnCategoryType.Path;
3816 break;
3893 - case "Set":
3894 - setValues = this.Core.GetAttributeValue(childSourceLineNumbers, childAttrib);
3817 + case "paths":
3818 + category = WixCustomTableColumnCategoryType.Paths;
3819 break;
3896 - case "Type":
3897 - var typeValue = this.Core.GetAttributeValue(childSourceLineNumbers, childAttrib);
3898 - switch (typeValue)
3899 - {
3900 - case "binary":
3901 - columnType = IntermediateFieldType.Path;
3902 - break;
3903 - case "int":
3904 - columnType = IntermediateFieldType.Number;
3905 - break;
3906 - case "string":
3907 - columnType = IntermediateFieldType.String;
3908 - break;
3909 - case "":
3910 - break;
3911 - default:
3912 - this.Core.Write(ErrorMessages.IllegalAttributeValue(childSourceLineNumbers, child.Name.LocalName, "Type", typeValue, "binary", "int", "string"));
3913 - columnType = IntermediateFieldType.String; // set a value to prevent expected attribute error below.
3914 - break;
3915 - }
3820 + case "anyPath":
3821 + category = WixCustomTableColumnCategoryType.AnyPath;
3822 + break;
3823 + case "defaultDir":
3824 + category = WixCustomTableColumnCategoryType.DefaultDir;
3825 + break;
3826 + case "regPath":
3827 + category = WixCustomTableColumnCategoryType.RegPath;
3828 + break;
3829 + case "formatted":
3830 + category = WixCustomTableColumnCategoryType.Formatted;
3831 + break;
3832 + case "formattedSddl":
3833 + category = WixCustomTableColumnCategoryType.FormattedSddl;
3834 + break;
3835 + case "template":
3836 + category = WixCustomTableColumnCategoryType.Template;
3837 + break;
3838 + case "condition":
3839 + category = WixCustomTableColumnCategoryType.Condition;
3840 + break;
3841 + case "guid":
3842 + category = WixCustomTableColumnCategoryType.Guid;
3843 break;
3917 - case "Width":
3918 - width = this.Core.GetAttributeIntegerValue(childSourceLineNumbers, childAttrib, 0, Int32.MaxValue);
3844 + case "version":
3845 + category = WixCustomTableColumnCategoryType.Version;
3846 break;
3920 - case "Unreal":
3921 - columnUnreal = YesNoType.Yes == this.Core.GetAttributeYesNoValue(childSourceLineNumbers, childAttrib);
3847 + case "language":
3848 + category = WixCustomTableColumnCategoryType.Language;
3849 + break;
3850 + case "binary":
3851 + category = WixCustomTableColumnCategoryType.Binary;
3852 + break;
3853 + case "customSource":
3854 + category = WixCustomTableColumnCategoryType.CustomSource;
3855 + break;
3856 + case "cabinet":
3857 + category = WixCustomTableColumnCategoryType.Cabinet;
3858 + break;
3859 + case "shortcut":
3860 + category = WixCustomTableColumnCategoryType.Shortcut;
3861 + break;
3862 + case "":
3863 break;
3864 default:
3924 - this.Core.UnexpectedAttribute(child, childAttrib);
3865 + this.Core.Write(ErrorMessages.IllegalAttributeValue(childSourceLineNumbers, child.Name.LocalName, "Category", categoryValue,
3866 + "text", "upperCase", "lowerCase", "integer", "doubleInteger", "timeDate", "identifier", "property", "filename",
3867 + "wildCardFilename", "path", "paths", "anyPath", "defaultDir", "regPath", "formatted", "formattedSddl", "template",
3868 + "condition", "guid", "version", "language", "binary", "customSource", "cabinet", "shortcut"));
3869 + columnType = IntermediateFieldType.String; // set a value to prevent expected attribute error below.
3870 break;
3926 - }
3927 - }
3928 -
3929 - if (null == columnName)
3930 - {
3931 - this.Core.Write(ErrorMessages.ExpectedAttribute(childSourceLineNumbers, child.Name.LocalName, "Id"));
3932 - }
3933 -
3934 - if (!columnType.HasValue)
3935 - {
3936 - this.Core.Write(ErrorMessages.ExpectedAttribute(childSourceLineNumbers, child.Name.LocalName, "Type"));
3871 }
3938 - else if (columnType == IntermediateFieldType.Number)
3939 - {
3940 - if (2 != width && 4 != width)
3941 - {
3942 - this.Core.Write(ErrorMessages.CustomTableIllegalColumnWidth(childSourceLineNumbers, child.Name.LocalName, "Width", width));
3943 - }
3944 - }
3945 - else if (columnType == IntermediateFieldType.Path)
3872 + break;
3873 + case "Description":
3874 + description = this.Core.GetAttributeValue(childSourceLineNumbers, childAttrib);
3875 + break;
3876 + case "KeyColumn":
3877 + keyColumn = this.Core.GetAttributeIntegerValue(childSourceLineNumbers, childAttrib, 1, 32);
3878 + break;
3879 + case "KeyTable":
3880 + keyTable = this.Core.GetAttributeValue(childSourceLineNumbers, childAttrib);
3881 + break;
3882 + case "Localizable":
3883 + localizable = YesNoType.Yes == this.Core.GetAttributeYesNoValue(childSourceLineNumbers, childAttrib);
3884 + break;
3885 + case "MaxValue":
3886 + maxValue = this.Core.GetAttributeLongValue(childSourceLineNumbers, childAttrib, Int32.MinValue + 1, Int32.MaxValue);
3887 + break;
3888 + case "MinValue":
3889 + minValue = this.Core.GetAttributeLongValue(childSourceLineNumbers, childAttrib, Int32.MinValue + 1, Int32.MaxValue);
3890 + break;
3891 + case "Modularize":
3892 + var modularizeValue = this.Core.GetAttributeValue(childSourceLineNumbers, childAttrib);
3893 + switch (modularizeValue)
3894 {
3947 - if (!category.HasValue)
3948 - {
3949 - category = WixCustomTableColumnCategoryType.Binary;
3950 - }
3951 - else if (category != WixCustomTableColumnCategoryType.Binary)
3952 - {
3953 - this.Core.Write(ErrorMessages.ExpectedBinaryCategory(childSourceLineNumbers));
3954 - }
3895 + case "column":
3896 + modularization = WixCustomTableColumnModularizeType.Column;
3897 + break;
3898 + case "companionFile":
3899 + modularization = WixCustomTableColumnModularizeType.CompanionFile;
3900 + break;
3901 + case "condition":
3902 + modularization = WixCustomTableColumnModularizeType.Condition;
3903 + break;
3904 + case "controlEventArgument":
3905 + modularization = WixCustomTableColumnModularizeType.ControlEventArgument;
3906 + break;
3907 + case "controlText":
3908 + modularization = WixCustomTableColumnModularizeType.ControlText;
3909 + break;
3910 + case "icon":
3911 + modularization = WixCustomTableColumnModularizeType.Icon;
3912 + break;
3913 + case "none":
3914 + modularization = WixCustomTableColumnModularizeType.None;
3915 + break;
3916 + case "property":
3917 + modularization = WixCustomTableColumnModularizeType.Property;
3918 + break;
3919 + case "semicolonDelimited":
3920 + modularization = WixCustomTableColumnModularizeType.SemicolonDelimited;
3921 + break;
3922 + case "":
3923 + break;
3924 + default:
3925 + this.Core.Write(ErrorMessages.IllegalAttributeValue(childSourceLineNumbers, child.Name.LocalName, "Modularize", modularizeValue, "column", "companionFile", "condition", "controlEventArgument", "controlText", "icon", "property", "semicolonDelimited"));
3926 + columnType = IntermediateFieldType.String; // set a value to prevent expected attribute error below.
3927 + break;
3928 }
3956 -
3957 - this.Core.ParseForExtensionElements(child);
3958 -
3959 - if (!this.Core.EncounteredError)
3929 + break;
3930 + case "Nullable":
3931 + nullable = YesNoType.Yes == this.Core.GetAttributeYesNoValue(childSourceLineNumbers, childAttrib);
3932 + break;
3933 + case "PrimaryKey":
3934 + primaryKey = YesNoType.Yes == this.Core.GetAttributeYesNoValue(childSourceLineNumbers, childAttrib);
3935 + break;
3936 + case "Set":
3937 + setValues = this.Core.GetAttributeValue(childSourceLineNumbers, childAttrib);
3938 + break;
3939 + case "Type":
3940 + var typeValue = this.Core.GetAttributeValue(childSourceLineNumbers, childAttrib);
3941 + switch (typeValue)
3942 {
3961 - var attributes = primaryKey ? WixCustomTableColumnTupleAttributes.PrimaryKey : WixCustomTableColumnTupleAttributes.None;
3962 - attributes |= localizable ? WixCustomTableColumnTupleAttributes.Localizable : WixCustomTableColumnTupleAttributes.None;
3963 - attributes |= nullable ? WixCustomTableColumnTupleAttributes.Nullable : WixCustomTableColumnTupleAttributes.None;
3964 - attributes |= columnUnreal ? WixCustomTableColumnTupleAttributes.Unreal : WixCustomTableColumnTupleAttributes.None;
3965 -
3966 - var column = this.Core.AddTuple(new WixCustomTableColumnTuple(childSourceLineNumbers, new Identifier(AccessModifier.Private, tableId, columnName))
3967 - {
3968 - TableRef = tableId,
3969 - Name = columnName,
3970 - Type = columnType.Value,
3971 - Attributes = attributes,
3972 - Width = width,
3973 - Category = category,
3974 - Description = description,
3975 - KeyColumn = keyColumn,
3976 - KeyTable = keyTable,
3977 - MaxValue = maxValue,
3978 - MinValue = minValue,
3979 - Modularize = modularization,
3980 - Set = setValues,
3981 - });
3982 - columns.Add(column);
3943 + case "binary":
3944 + columnType = IntermediateFieldType.Path;
3945 + break;
3946 + case "int":
3947 + columnType = IntermediateFieldType.Number;
3948 + break;
3949 + case "string":
3950 + columnType = IntermediateFieldType.String;
3951 + break;
3952 + case "":
3953 + break;
3954 + default:
3955 + this.Core.Write(ErrorMessages.IllegalAttributeValue(childSourceLineNumbers, child.Name.LocalName, "Type", typeValue, "binary", "int", "string"));
3956 + columnType = IntermediateFieldType.String; // set a value to prevent expected attribute error below.
3957 + break;
3958 }
3959 break;
3985 - case "Row":
3986 - this.ParseRow(child, tableId);
3960 + case "Width":
3961 + width = this.Core.GetAttributeIntegerValue(childSourceLineNumbers, childAttrib, 0, Int32.MaxValue);
3962 + break;
3963 + case "Unreal":
3964 + columnUnreal = YesNoType.Yes == this.Core.GetAttributeYesNoValue(childSourceLineNumbers, childAttrib);
3965 break;
3966 default:
3989 - this.Core.UnexpectedElement(node, child);
3967 + this.Core.UnexpectedAttribute(child, childAttrib);
3968 break;
3991 - }
3969 }
3993 - else
3970 + }
3971 +
3972 + if (null == columnName)
3973 + {
3974 + this.Core.Write(ErrorMessages.ExpectedAttribute(childSourceLineNumbers, child.Name.LocalName, "Id"));
3975 + }
3976 +
3977 + if (!columnType.HasValue)
3978 + {
3979 + this.Core.Write(ErrorMessages.ExpectedAttribute(childSourceLineNumbers, child.Name.LocalName, "Type"));
3980 + }
3981 + else if (columnType == IntermediateFieldType.Number)
3982 + {
3983 + if (2 != width && 4 != width)
3984 {
3995 - this.Core.ParseExtensionElement(node, child);
3985 + this.Core.Write(ErrorMessages.CustomTableIllegalColumnWidth(childSourceLineNumbers, child.Name.LocalName, "Width", width));
3986 }
3987 }
3998 -
3999 - if (columns.Count > 0)
3988 + else if (columnType == IntermediateFieldType.Path)
3989 {
4001 - if (!columns.Where(c => c.PrimaryKey).Any())
3990 + if (!category.HasValue)
3991 {
4003 - this.Core.Write(ErrorMessages.CustomTableMissingPrimaryKey(sourceLineNumbers));
3992 + category = WixCustomTableColumnCategoryType.Binary;
3993 }
4005 -
4006 - if (!this.Core.EncounteredError)
3994 + else if (category != WixCustomTableColumnCategoryType.Binary)
3995 {
4008 - var columnNames = String.Join(new string(WixCustomTableTuple.ColumnNamesSeparator, 1), columns.Select(c => c.Name));
4009 -
4010 - this.Core.AddTuple(new WixCustomTableTuple(sourceLineNumbers, new Identifier(AccessModifier.Public, tableId))
4011 - {
4012 - ColumnNames = columnNames,
4013 - Unreal = unreal,
4014 - });
3996 + this.Core.Write(ErrorMessages.ExpectedBinaryCategory(childSourceLineNumbers));
3997 }
3998 }
3999 +
4000 + this.Core.ParseForExtensionElements(child);
4001 +
4002 + if (this.Core.EncounteredError)
4003 + {
4004 + return null;
4005 + }
4006 +
4007 + var attributes = primaryKey ? WixCustomTableColumnTupleAttributes.PrimaryKey : WixCustomTableColumnTupleAttributes.None;
4008 + attributes |= localizable ? WixCustomTableColumnTupleAttributes.Localizable : WixCustomTableColumnTupleAttributes.None;
4009 + attributes |= nullable ? WixCustomTableColumnTupleAttributes.Nullable : WixCustomTableColumnTupleAttributes.None;
4010 + attributes |= columnUnreal ? WixCustomTableColumnTupleAttributes.Unreal : WixCustomTableColumnTupleAttributes.None;
4011 +
4012 + var column = this.Core.AddTuple(new WixCustomTableColumnTuple(childSourceLineNumbers, new Identifier(AccessModifier.Private, tableId, columnName))
4013 + {
4014 + TableRef = tableId,
4015 + Name = columnName,
4016 + Type = columnType.Value,
4017 + Attributes = attributes,
4018 + Width = width,
4019 + Category = category,
4020 + Description = description,
4021 + KeyColumn = keyColumn,
4022 + KeyTable = keyTable,
4023 + MaxValue = maxValue,
4024 + MinValue = minValue,
4025 + Modularize = modularization,
4026 + Set = setValues,
4027 + });
4028 + return column;
4029 }
4030
4019 - private void ParseRow(XElement node, string tableId)
4031 + /// <summary>
4032 + /// Parses a Row element.
4033 + /// </summary>
4034 + /// <param name="node">Element to parse.</param>
4035 + /// <param name="sourceLineNumbers">Element's SourceLineNumbers.</param>
4036 + /// <param name="tableId">Table Id.</param>
4037 + private void ParseRowElement(XElement node, SourceLineNumber sourceLineNumbers, string tableId)
4038 {
4021 - var sourceLineNumbers = Preprocessor.GetSourceLineNumbers(node);
4039 var rowId = Guid.NewGuid().ToString("N").ToUpperInvariant();
4040
4041 foreach (var attrib in node.Attributes())
@@ -6204,6 +6221,9 @@ namespace WixToolset.Core
6221 case "BootstrapperApplicationRef":
6222 this.ParseBootstrapperApplicationRefElement(child);
6223 break;
6224 + case "BundleCustomData":
6225 + this.ParseBundleCustomDataElement(child);
6226 + break;
6227 case "BundleExtension":
6228 this.ParseBundleExtensionElement(child);
6229 break;
src/WixToolset.Core/Compiler_Bundle.cs
+244
@@ -7,6 +7,7 @@ namespace WixToolset.Core
7 using System.Diagnostics;
8 using System.Globalization;
9 using System.IO;
10 + using System.Linq;
11 using System.Xml.Linq;
12 using WixToolset.Data;
13 using WixToolset.Data.Burn;
@@ -276,6 +277,9 @@ namespace WixToolset.Core
277 case "BootstrapperApplicationRef":
278 this.ParseBootstrapperApplicationRefElement(child);
279 break;
280 + case "BundleCustomData":
281 + this.ParseBundleCustomDataElement(child);
282 + break;
283 case "BundleExtension":
284 this.ParseBundleExtensionElement(child);
285 break;
@@ -767,6 +771,246 @@ namespace WixToolset.Core
771 }
772 }
773
774 +
775 +
776 + /// <summary>
777 + /// Parses a BundleCustomData element.
778 + /// </summary>
779 + /// <param name="node">Element to parse.</param>
780 + private void ParseBundleCustomDataElement(XElement node)
781 + {
782 + var sourceLineNumbers = Preprocessor.GetSourceLineNumbers(node);
783 + string customDataId = null;
784 + WixBundleCustomDataType? customDataType = null;
785 + string extensionId = null;
786 + var attributeDefinitions = new List<WixBundleCustomDataAttributeTuple>();
787 +
788 + foreach (var attrib in node.Attributes())
789 + {
790 + if (String.IsNullOrEmpty(attrib.Name.NamespaceName) || CompilerCore.WixNamespace == attrib.Name.Namespace)
791 + {
792 + switch (attrib.Name.LocalName)
793 + {
794 + case "Id":
795 + customDataId = this.Core.GetAttributeIdentifierValue(sourceLineNumbers, attrib);
796 + break;
797 + case "Type":
798 + var typeValue = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
799 + switch (typeValue)
800 + {
801 + case "bootstrapperApplication":
802 + customDataType = WixBundleCustomDataType.BootstrapperApplication;
803 + break;
804 + case "bundleExtension":
805 + customDataType = WixBundleCustomDataType.BundleExtension;
806 + break;
807 + default:
808 + this.Core.Write(ErrorMessages.IllegalAttributeValue(sourceLineNumbers, node.Name.LocalName, "Type", typeValue, "bootstrapperApplication", "bundleExtension"));
809 + customDataType = WixBundleCustomDataType.Unknown; // set a value to prevent expected attribute error below.
810 + break;
811 + }
812 + break;
813 + case "ExtensionId":
814 + extensionId = this.Core.GetAttributeIdentifierValue(sourceLineNumbers, attrib);
815 + this.Core.CreateSimpleReference(sourceLineNumbers, TupleDefinitions.WixBundleExtension, extensionId);
816 + break;
817 + default:
818 + this.Core.UnexpectedAttribute(node, attrib);
819 + break;
820 + }
821 + }
822 + else
823 + {
824 + this.Core.ParseExtensionAttribute(node, attrib);
825 + }
826 + }
827 +
828 + if (null == customDataId)
829 + {
830 + this.Core.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Id"));
831 + }
832 +
833 + var hasExtensionId = null != extensionId;
834 + if (hasExtensionId && !customDataType.HasValue)
835 + {
836 + customDataType = WixBundleCustomDataType.BundleExtension;
837 + }
838 +
839 + if (!customDataType.HasValue)
840 + {
841 + this.Core.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Type"));
842 + }
843 + else if (hasExtensionId)
844 + {
845 + if (customDataType.Value == WixBundleCustomDataType.BootstrapperApplication)
846 + {
847 + this.Core.Write(ErrorMessages.IllegalAttributeWithOtherAttribute(sourceLineNumbers, node.Name.LocalName, "ExtensonId", "Type", "bootstrapperApplication"));
848 + }
849 + }
850 + else if (customDataType.Value == WixBundleCustomDataType.BundleExtension)
851 + {
852 + this.Core.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "ExtensionId", "Type", "bundleExtension"));
853 + }
854 +
855 + foreach (var child in node.Elements())
856 + {
857 + if (CompilerCore.WixNamespace == child.Name.Namespace)
858 + {
859 + var childSourceLineNumbers = Preprocessor.GetSourceLineNumbers(child);
860 + switch (child.Name.LocalName)
861 + {
862 + case "BundleAttributeDefinition":
863 + var attributeDefinition = this.ParseBundleAttributeDefinitionElement(child, childSourceLineNumbers, customDataId);
864 + if (attributeDefinition != null)
865 + {
866 + attributeDefinitions.Add(attributeDefinition);
867 + }
868 + break;
869 + case "BundleElement":
870 + this.ParseBundleElementElement(child, childSourceLineNumbers, customDataId);
871 + break;
872 + default:
873 + this.Core.UnexpectedElement(node, child);
874 + break;
875 + }
876 + }
877 + else
878 + {
879 + this.Core.ParseExtensionElement(node, child);
880 + }
881 + }
882 +
883 + if (attributeDefinitions.Count > 0)
884 + {
885 + if (!this.Core.EncounteredError)
886 + {
887 + var attributeNames = String.Join(new string(WixBundleCustomDataTuple.AttributeNamesSeparator, 1), attributeDefinitions.Select(c => c.Name));
888 +
889 + this.Core.AddTuple(new WixBundleCustomDataTuple(sourceLineNumbers, new Identifier(AccessModifier.Public, customDataId))
890 + {
891 + AttributeNames = attributeNames,
892 + Type = customDataType.Value,
893 + BundleExtensionRef = extensionId,
894 + });
895 + }
896 + }
897 + }
898 +
899 + /// <summary>
900 + /// Parses a BundleAttributeDefinition element.
901 + /// </summary>
902 + /// <param name="node">Element to parse.</param>
903 + /// <param name="sourceLineNumbers">Element's SourceLineNumbers.</param>
904 + /// <param name="customDataId">BundleCustomData Id.</param>
905 + private WixBundleCustomDataAttributeTuple ParseBundleAttributeDefinitionElement(XElement node, SourceLineNumber sourceLineNumbers, string customDataId)
906 + {
907 + string attributeName = null;
908 +
909 + foreach (var attrib in node.Attributes())
910 + {
911 + switch (attrib.Name.LocalName)
912 + {
913 + case "Id":
914 + attributeName = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
915 + break;
916 + default:
917 + this.Core.UnexpectedAttribute(node, attrib);
918 + break;
919 + }
920 + }
921 +
922 + if (null == attributeName)
923 + {
924 + this.Core.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Id"));
925 + }
926 +
927 + this.Core.ParseForExtensionElements(node);
928 +
929 + if (this.Core.EncounteredError)
930 + {
931 + return null;
932 + }
933 +
934 + var customDataAttribute = this.Core.AddTuple(new WixBundleCustomDataAttributeTuple(sourceLineNumbers, new Identifier(AccessModifier.Private, customDataId, attributeName))
935 + {
936 + CustomDataRef = customDataId,
937 + Name = attributeName,
938 + });
939 + return customDataAttribute;
940 + }
941 +
942 + /// <summary>
943 + /// Parses a BundleElement element.
944 + /// </summary>
945 + /// <param name="node">Element to parse.</param>
946 + /// <param name="sourceLineNumbers">Element's SourceLineNumbers.</param>
947 + /// <param name="customDataId">BundleCustomData Id.</param>
948 + private void ParseBundleElementElement(XElement node, SourceLineNumber sourceLineNumbers, string customDataId)
949 + {
950 + var elementId = Guid.NewGuid().ToString("N").ToUpperInvariant();
951 +
952 + foreach (var attrib in node.Attributes())
953 + {
954 + this.Core.ParseExtensionAttribute(node, attrib);
955 + }
956 +
957 + foreach (var child in node.Elements())
958 + {
959 + var childSourceLineNumbers = Preprocessor.GetSourceLineNumbers(child);
960 + switch (child.Name.LocalName)
961 + {
962 + case "BundleAttribute":
963 + string attributeName = null;
964 + string value = null;
965 + foreach (var attrib in child.Attributes())
966 + {
967 + switch (attrib.Name.LocalName)
968 + {
969 + case "Id":
970 + attributeName = this.Core.GetAttributeValue(childSourceLineNumbers, attrib);
971 + break;
972 + case "Value":
973 + value = this.Core.GetAttributeValue(childSourceLineNumbers, attrib);
974 + break;
975 + default:
976 + this.Core.ParseExtensionAttribute(child, attrib);
977 + break;
978 + }
979 + }
980 +
981 + if (null == attributeName)
982 + {
983 + this.Core.Write(ErrorMessages.ExpectedAttribute(childSourceLineNumbers, child.Name.LocalName, "Id"));
984 + }
985 +
986 + if (String.IsNullOrEmpty(value))
987 + {
988 + value = Common.GetInnerText(child);
989 + }
990 +
991 + if (!this.Core.EncounteredError)
992 + {
993 + this.Core.AddTuple(new WixBundleCustomDataCellTuple(childSourceLineNumbers, new Identifier(AccessModifier.Private, customDataId, elementId, attributeName))
994 + {
995 + ElementId = elementId,
996 + AttributeRef = attributeName,
997 + CustomDataRef = customDataId,
998 + Value = value,
999 + });
1000 + }
1001 + break;
1002 + default:
1003 + this.Core.UnexpectedElement(node, child);
1004 + break;
1005 + }
1006 + }
1007 +
1008 + if (!this.Core.EncounteredError)
1009 + {
1010 + this.Core.CreateSimpleReference(sourceLineNumbers, TupleDefinitions.WixBundleCustomData, customDataId);
1011 + }
1012 + }
1013 +
1014 /// <summary>
1015 /// Parse the BundleExtension element.
1016 /// </summary>
src/test/WixToolsetTest.CoreIntegration/BundleManifestFixture.cs
+44 -5
@@ -13,7 +13,7 @@ namespace WixToolsetTest.CoreIntegration
13 public class BundleManifestFixture
14 {
15 [Fact]
16 - public void PopulatesBAManifestWithUnrealCustomTable()
16 + public void PopulatesBAManifestWithBootstrapperApplicationBundleCustomData()
17 {
18 var folder = TestData.Get(@"TestData");
19
@@ -43,11 +43,50 @@ namespace WixToolsetTest.CoreIntegration
43 var extractResult = BundleExtractor.ExtractBAContainer(null, bundlePath, baFolderPath, extractFolderPath);
44 extractResult.AssertSuccess();
45
46 - var customElements = extractResult.SelectBADataNodes("/ba:BootstrapperApplicationData/ba:BundleCustomTable");
46 + var customElements = extractResult.SelectBADataNodes("/ba:BootstrapperApplicationData/ba:BundleCustomTableBA");
47 Assert.Equal(3, customElements.Count);
48 - Assert.Equal("<BundleCustomTable Id='one' Column2='two' />", customElements[0].GetTestXml());
49 - Assert.Equal("<BundleCustomTable Id='&gt;' Column2='&lt;' />", customElements[1].GetTestXml());
50 - Assert.Equal("<BundleCustomTable Id='1' Column2='2' />", customElements[2].GetTestXml());
48 + Assert.Equal("<BundleCustomTableBA Id='one' Column2='two' />", customElements[0].GetTestXml());
49 + Assert.Equal("<BundleCustomTableBA Id='&gt;' Column2='&lt;' />", customElements[1].GetTestXml());
50 + Assert.Equal("<BundleCustomTableBA Id='1' Column2='2' />", customElements[2].GetTestXml());
51 + }
52 + }
53 +
54 + [Fact]
55 + public void PopulatesBEManifestWithBundleExtensionBundleCustomData()
56 + {
57 + var folder = TestData.Get(@"TestData");
58 +
59 + using (var fs = new DisposableFileSystem())
60 + {
61 + var baseFolder = fs.GetFolder();
62 + var intermediateFolder = Path.Combine(baseFolder, "obj");
63 + var bundlePath = Path.Combine(baseFolder, @"bin\test.exe");
64 + var baFolderPath = Path.Combine(baseFolder, "ba");
65 + var extractFolderPath = Path.Combine(baseFolder, "extract");
66 +
67 + var result = WixRunner.Execute(new[]
68 + {
69 + "build",
70 + Path.Combine(folder, "BundleCustomTable", "BundleCustomTable.wxs"),
71 + Path.Combine(folder, "BundleWithPackageGroupRef", "MinimalPackageGroup.wxs"),
72 + Path.Combine(folder, "BundleWithPackageGroupRef", "Bundle.wxs"),
73 + "-bindpath", Path.Combine(folder, "SimpleBundle", "data"),
74 + "-intermediateFolder", intermediateFolder,
75 + "-o", bundlePath
76 + });
77 +
78 + result.AssertSuccess();
79 +
80 + Assert.True(File.Exists(bundlePath));
81 +
82 + var extractResult = BundleExtractor.ExtractBAContainer(null, bundlePath, baFolderPath, extractFolderPath);
83 + extractResult.AssertSuccess();
84 +
85 + var customElements = extractResult.SelectBundleExtensionDataNodes("/be:BundleExtensionData/be:BundleExtension[@Id='CustomTableExtension']/be:BundleCustomTableBE");
86 + Assert.Equal(3, customElements.Count);
87 + Assert.Equal("<BundleCustomTableBE Id='one' Column2='two' />", customElements[0].GetTestXml());
88 + Assert.Equal("<BundleCustomTableBE Id='&gt;' Column2='&lt;' />", customElements[1].GetTestXml());
89 + Assert.Equal("<BundleCustomTableBE Id='1' Column2='2' />", customElements[2].GetTestXml());
90 }
91 }
92
src/test/WixToolsetTest.CoreIntegration/CustomTableFixture.cs
-31
@@ -3,7 +3,6 @@
3 namespace WixToolsetTest.CoreIntegration
4 {
5 using System.IO;
6 - using Microsoft.Build.Tasks;
6 using WixBuildTools.TestSupport;
7 using WixToolset.Core.TestPackage;
8 using Xunit;
@@ -159,36 +158,6 @@ namespace WixToolsetTest.CoreIntegration
158 }
159 }
160
162 - [Fact]
163 - public void UnrealCustomTableIsNotPresentInMsi()
164 - {
165 - var folder = TestData.Get(@"TestData");
166 -
167 - using (var fs = new DisposableFileSystem())
168 - {
169 - var baseFolder = fs.GetFolder();
170 - var intermediateFolder = Path.Combine(baseFolder, "obj");
171 - var msiPath = Path.Combine(baseFolder, @"bin\test.msi");
172 -
173 - var result = WixRunner.Execute(new[]
174 - {
175 - "build",
176 - Path.Combine(folder, "CustomTable", "CustomTable.wxs"),
177 - Path.Combine(folder, "ProductWithComponentGroupRef", "MinimalComponentGroup.wxs"),
178 - Path.Combine(folder, "ProductWithComponentGroupRef", "Product.wxs"),
179 - "-bindpath", Path.Combine(folder, "SingleFile", "data"),
180 - "-intermediateFolder", intermediateFolder,
181 - "-o", msiPath
182 - });
183 -
184 - result.AssertSuccess();
185 -
186 - Assert.True(File.Exists(msiPath));
187 - var results = Query.QueryDatabase(msiPath, new[] { "CustomTable2" });
188 - Assert.Empty(results);
189 - }
190 - }
191 -
161 [Fact]
162 public void CanCompileAndDecompile()
163 {
src/test/WixToolsetTest.CoreIntegration/TestData/BundleCustomTable/BundleCustomTable.wxs
+36 -16
@@ -5,22 +5,42 @@
5 <PackageGroupRef Id="MinimalPackageGroup" />
6 </PackageGroup>
7
8 - <CustomTable Id="BundleCustomTable" Unreal="yes">
9 - <Column Id="Id" Type="string" PrimaryKey="yes" />
10 - <Column Id="Column2" Type="string" PrimaryKey="yes" />
8 + <BundleCustomData Id="BundleCustomTableBA" Type="bootstrapperApplication">
9 + <BundleAttributeDefinition Id="Id" />
10 + <BundleAttributeDefinition Id="Column2" />
11
12 - <Row>
13 - <Data Column="Id">one</Data>
14 - <Data Column="Column2">two</Data>
15 - </Row>
16 - <Row>
17 - <Data Column="Column2">&lt;</Data>
18 - <Data Column="Id">&gt;</Data>
19 - </Row>
20 - <Row>
21 - <Data Column="Id">1</Data>
22 - <Data Column="Column2">2</Data>
23 - </Row>
24 - </CustomTable>
12 + <BundleElement>
13 + <BundleAttribute Id="Id">one</BundleAttribute>
14 + <BundleAttribute Id="Column2">two</BundleAttribute>
15 + </BundleElement>
16 + <BundleElement>
17 + <BundleAttribute Id="Column2">&lt;</BundleAttribute>
18 + <BundleAttribute Id="Id">&gt;</BundleAttribute>
19 + </BundleElement>
20 + <BundleElement>
21 + <BundleAttribute Id="Id">1</BundleAttribute>
22 + <BundleAttribute Id="Column2">2</BundleAttribute>
23 + </BundleElement>
24 + </BundleCustomData>
25 +
26 + <BundleCustomData Id="BundleCustomTableBE" Type="bundleExtension" ExtensionId="CustomTableExtension">
27 + <BundleAttributeDefinition Id="Id" />
28 + <BundleAttributeDefinition Id="Column2" />
29 +
30 + <BundleElement>
31 + <BundleAttribute Id="Id">one</BundleAttribute>
32 + <BundleAttribute Id="Column2">two</BundleAttribute>
33 + </BundleElement>
34 + <BundleElement>
35 + <BundleAttribute Id="Column2">&lt;</BundleAttribute>
36 + <BundleAttribute Id="Id">&gt;</BundleAttribute>
37 + </BundleElement>
38 + <BundleElement>
39 + <BundleAttribute Id="Id">1</BundleAttribute>
40 + <BundleAttribute Id="Column2">2</BundleAttribute>
41 + </BundleElement>
42 + </BundleCustomData>
43 +
44 + <BundleExtension Id="CustomTableExtension" SourceFile="fakeba.dll" />
45 </Fragment>
46 </Wix>
src/test/WixToolsetTest.CoreIntegration/TestData/CustomTable/CustomTable.wxs
-13
@@ -17,18 +17,5 @@
17 <Data Column="Component_">test.txt</Data>
18 </Row>
19 </CustomTable>
20 -
21 - <CustomTable Id="CustomTable2" Unreal="yes">
22 - <Column Id="ColumnA" Type="string" PrimaryKey="yes" />
23 - <Column Id="Component_" Type="string" Width="72" KeyTable="Component" KeyColumn="1" />
24 - <Row>
25 - <Data Column="ColumnA">RowA</Data>
26 - <Data Column="Component_">test.txt</Data>
27 - </Row>
28 - <Row>
29 - <Data Column="ColumnA">RowB</Data>
30 - <Data Column="Component_">test.txt</Data>
31 - </Row>
32 - </CustomTable>
20 </Fragment>
21 </Wix>