aboutsummaryrefslogtreecommitdiff
path: root/src/WixToolset.Core
diff options
context:
space:
mode:
authorSean Hall <r.sean.hall@gmail.com>2020-06-19 13:52:20 +1000
committerSean Hall <r.sean.hall@gmail.com>2020-06-19 14:07:03 +1000
commitabff61df823505abc01776cec7b207501c671bf2 (patch)
treedf1358638c44accce92d8a1a2da9e5795d8d231d /src/WixToolset.Core
parent40d7700f0c5f6464f9491bf60d9d8604a81b7466 (diff)
downloadwix-abff61df823505abc01776cec7b207501c671bf2.tar.gz
wix-abff61df823505abc01776cec7b207501c671bf2.tar.bz2
wix-abff61df823505abc01776cec7b207501c671bf2.zip
Implement BundleCustomData. Remove Unreal from CustomTable.
Diffstat (limited to 'src/WixToolset.Core')
-rw-r--r--src/WixToolset.Core/Compiler.cs566
-rw-r--r--src/WixToolset.Core/Compiler_Bundle.cs244
2 files changed, 537 insertions, 273 deletions
diff --git a/src/WixToolset.Core/Compiler.cs b/src/WixToolset.Core/Compiler.cs
index da0806fb..bbd6b292 100644
--- a/src/WixToolset.Core/Compiler.cs
+++ b/src/WixToolset.Core/Compiler.cs
@@ -3668,7 +3668,6 @@ namespace WixToolset.Core
3668 { 3668 {
3669 var sourceLineNumbers = Preprocessor.GetSourceLineNumbers(node); 3669 var sourceLineNumbers = Preprocessor.GetSourceLineNumbers(node);
3670 string tableId = null; 3670 string tableId = null;
3671 var unreal = false;
3672 var columns = new List<WixCustomTableColumnTuple>(); 3671 var columns = new List<WixCustomTableColumnTuple>();
3673 3672
3674 foreach (var attrib in node.Attributes()) 3673 foreach (var attrib in node.Attributes())
@@ -3680,9 +3679,6 @@ namespace WixToolset.Core
3680 case "Id": 3679 case "Id":
3681 tableId = this.Core.GetAttributeIdentifierValue(sourceLineNumbers, attrib); 3680 tableId = this.Core.GetAttributeIdentifierValue(sourceLineNumbers, attrib);
3682 break; 3681 break;
3683 case "Unreal":
3684 unreal = YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib);
3685 break;
3686 default: 3682 default:
3687 this.Core.UnexpectedAttribute(node, attrib); 3683 this.Core.UnexpectedAttribute(node, attrib);
3688 break; 3684 break;
@@ -3710,315 +3706,336 @@ namespace WixToolset.Core
3710 var childSourceLineNumbers = Preprocessor.GetSourceLineNumbers(child); 3706 var childSourceLineNumbers = Preprocessor.GetSourceLineNumbers(child);
3711 switch (child.Name.LocalName) 3707 switch (child.Name.LocalName)
3712 { 3708 {
3713 case "Column": 3709 case "Column":
3714 string columnName = null; 3710 var column = this.ParseColumnElement(child, childSourceLineNumbers, tableId);
3715 IntermediateFieldType? columnType = null; 3711 if (column != 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)
3733 { 3712 {
3734 case "Id": 3713 columns.Add(column);
3735 columnName = this.Core.GetAttributeIdentifierValue(childSourceLineNumbers, childAttrib); 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;
3736 break; 3786 break;
3737 case "Category": 3787 case "upperCase":
3738 var categoryValue = this.Core.GetAttributeValue(childSourceLineNumbers, childAttrib); 3788 category = WixCustomTableColumnCategoryType.UpperCase;
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 }
3829 break; 3789 break;
3830 case "Description": 3790 case "lowerCase":
3831 description = this.Core.GetAttributeValue(childSourceLineNumbers, childAttrib); 3791 category = WixCustomTableColumnCategoryType.LowerCase;
3832 break; 3792 break;
3833 case "KeyColumn": 3793 case "integer":
3834 keyColumn = this.Core.GetAttributeIntegerValue(childSourceLineNumbers, childAttrib, 1, 32); 3794 category = WixCustomTableColumnCategoryType.Integer;
3835 break; 3795 break;
3836 case "KeyTable": 3796 case "doubleInteger":
3837 keyTable = this.Core.GetAttributeValue(childSourceLineNumbers, childAttrib); 3797 category = WixCustomTableColumnCategoryType.DoubleInteger;
3838 break; 3798 break;
3839 case "Localizable": 3799 case "timeDate":
3840 localizable = YesNoType.Yes == this.Core.GetAttributeYesNoValue(childSourceLineNumbers, childAttrib); 3800 category = WixCustomTableColumnCategoryType.TimeDate;
3841 break; 3801 break;
3842 case "MaxValue": 3802 case "identifier":
3843 maxValue = this.Core.GetAttributeLongValue(childSourceLineNumbers, childAttrib, Int32.MinValue + 1, Int32.MaxValue); 3803 category = WixCustomTableColumnCategoryType.Identifier;
3844 break; 3804 break;
3845 case "MinValue": 3805 case "property":
3846 minValue = this.Core.GetAttributeLongValue(childSourceLineNumbers, childAttrib, Int32.MinValue + 1, Int32.MaxValue); 3806 category = WixCustomTableColumnCategoryType.Property;
3847 break; 3807 break;
3848 case "Modularize": 3808 case "filename":
3849 var modularizeValue = this.Core.GetAttributeValue(childSourceLineNumbers, childAttrib); 3809 category = WixCustomTableColumnCategoryType.Filename;
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 }
3886 break; 3810 break;
3887 case "Nullable": 3811 case "wildCardFilename":
3888 nullable = YesNoType.Yes == this.Core.GetAttributeYesNoValue(childSourceLineNumbers, childAttrib); 3812 category = WixCustomTableColumnCategoryType.WildCardFilename;
3889 break; 3813 break;
3890 case "PrimaryKey": 3814 case "path":
3891 primaryKey = YesNoType.Yes == this.Core.GetAttributeYesNoValue(childSourceLineNumbers, childAttrib); 3815 category = WixCustomTableColumnCategoryType.Path;
3892 break; 3816 break;
3893 case "Set": 3817 case "paths":
3894 setValues = this.Core.GetAttributeValue(childSourceLineNumbers, childAttrib); 3818 category = WixCustomTableColumnCategoryType.Paths;
3895 break; 3819 break;
3896 case "Type": 3820 case "anyPath":
3897 var typeValue = this.Core.GetAttributeValue(childSourceLineNumbers, childAttrib); 3821 category = WixCustomTableColumnCategoryType.AnyPath;
3898 switch (typeValue) 3822 break;
3899 { 3823 case "defaultDir":
3900 case "binary": 3824 category = WixCustomTableColumnCategoryType.DefaultDir;
3901 columnType = IntermediateFieldType.Path; 3825 break;
3902 break; 3826 case "regPath":
3903 case "int": 3827 category = WixCustomTableColumnCategoryType.RegPath;
3904 columnType = IntermediateFieldType.Number; 3828 break;
3905 break; 3829 case "formatted":
3906 case "string": 3830 category = WixCustomTableColumnCategoryType.Formatted;
3907 columnType = IntermediateFieldType.String; 3831 break;
3908 break; 3832 case "formattedSddl":
3909 case "": 3833 category = WixCustomTableColumnCategoryType.FormattedSddl;
3910 break; 3834 break;
3911 default: 3835 case "template":
3912 this.Core.Write(ErrorMessages.IllegalAttributeValue(childSourceLineNumbers, child.Name.LocalName, "Type", typeValue, "binary", "int", "string")); 3836 category = WixCustomTableColumnCategoryType.Template;
3913 columnType = IntermediateFieldType.String; // set a value to prevent expected attribute error below. 3837 break;
3914 break; 3838 case "condition":
3915 } 3839 category = WixCustomTableColumnCategoryType.Condition;
3840 break;
3841 case "guid":
3842 category = WixCustomTableColumnCategoryType.Guid;
3916 break; 3843 break;
3917 case "Width": 3844 case "version":
3918 width = this.Core.GetAttributeIntegerValue(childSourceLineNumbers, childAttrib, 0, Int32.MaxValue); 3845 category = WixCustomTableColumnCategoryType.Version;
3919 break; 3846 break;
3920 case "Unreal": 3847 case "language":
3921 columnUnreal = YesNoType.Yes == this.Core.GetAttributeYesNoValue(childSourceLineNumbers, childAttrib); 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 "":
3922 break; 3863 break;
3923 default: 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.
3925 break; 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"));
3937 } 3871 }
3938 else if (columnType == IntermediateFieldType.Number) 3872 break;
3939 { 3873 case "Description":
3940 if (2 != width && 4 != width) 3874 description = this.Core.GetAttributeValue(childSourceLineNumbers, childAttrib);
3941 { 3875 break;
3942 this.Core.Write(ErrorMessages.CustomTableIllegalColumnWidth(childSourceLineNumbers, child.Name.LocalName, "Width", width)); 3876 case "KeyColumn":
3943 } 3877 keyColumn = this.Core.GetAttributeIntegerValue(childSourceLineNumbers, childAttrib, 1, 32);
3944 } 3878 break;
3945 else if (columnType == IntermediateFieldType.Path) 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)
3946 { 3894 {
3947 if (!category.HasValue) 3895 case "column":
3948 { 3896 modularization = WixCustomTableColumnModularizeType.Column;
3949 category = WixCustomTableColumnCategoryType.Binary; 3897 break;
3950 } 3898 case "companionFile":
3951 else if (category != WixCustomTableColumnCategoryType.Binary) 3899 modularization = WixCustomTableColumnModularizeType.CompanionFile;
3952 { 3900 break;
3953 this.Core.Write(ErrorMessages.ExpectedBinaryCategory(childSourceLineNumbers)); 3901 case "condition":
3954 } 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;
3955 } 3928 }
3956 3929 break;
3957 this.Core.ParseForExtensionElements(child); 3930 case "Nullable":
3958 3931 nullable = YesNoType.Yes == this.Core.GetAttributeYesNoValue(childSourceLineNumbers, childAttrib);
3959 if (!this.Core.EncounteredError) 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)
3960 { 3942 {
3961 var attributes = primaryKey ? WixCustomTableColumnTupleAttributes.PrimaryKey : WixCustomTableColumnTupleAttributes.None; 3943 case "binary":
3962 attributes |= localizable ? WixCustomTableColumnTupleAttributes.Localizable : WixCustomTableColumnTupleAttributes.None; 3944 columnType = IntermediateFieldType.Path;
3963 attributes |= nullable ? WixCustomTableColumnTupleAttributes.Nullable : WixCustomTableColumnTupleAttributes.None; 3945 break;
3964 attributes |= columnUnreal ? WixCustomTableColumnTupleAttributes.Unreal : WixCustomTableColumnTupleAttributes.None; 3946 case "int":
3965 3947 columnType = IntermediateFieldType.Number;
3966 var column = this.Core.AddTuple(new WixCustomTableColumnTuple(childSourceLineNumbers, new Identifier(AccessModifier.Private, tableId, columnName)) 3948 break;
3967 { 3949 case "string":
3968 TableRef = tableId, 3950 columnType = IntermediateFieldType.String;
3969 Name = columnName, 3951 break;
3970 Type = columnType.Value, 3952 case "":
3971 Attributes = attributes, 3953 break;
3972 Width = width, 3954 default:
3973 Category = category, 3955 this.Core.Write(ErrorMessages.IllegalAttributeValue(childSourceLineNumbers, child.Name.LocalName, "Type", typeValue, "binary", "int", "string"));
3974 Description = description, 3956 columnType = IntermediateFieldType.String; // set a value to prevent expected attribute error below.
3975 KeyColumn = keyColumn, 3957 break;
3976 KeyTable = keyTable,
3977 MaxValue = maxValue,
3978 MinValue = minValue,
3979 Modularize = modularization,
3980 Set = setValues,
3981 });
3982 columns.Add(column);
3983 } 3958 }
3984 break; 3959 break;
3985 case "Row": 3960 case "Width":
3986 this.ParseRow(child, tableId); 3961 width = this.Core.GetAttributeIntegerValue(childSourceLineNumbers, childAttrib, 0, Int32.MaxValue);
3962 break;
3963 case "Unreal":
3964 columnUnreal = YesNoType.Yes == this.Core.GetAttributeYesNoValue(childSourceLineNumbers, childAttrib);
3987 break; 3965 break;
3988 default: 3966 default:
3989 this.Core.UnexpectedElement(node, child); 3967 this.Core.UnexpectedAttribute(child, childAttrib);
3990 break; 3968 break;
3991 }
3992 } 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)
3994 { 3984 {
3995 this.Core.ParseExtensionElement(node, child); 3985 this.Core.Write(ErrorMessages.CustomTableIllegalColumnWidth(childSourceLineNumbers, child.Name.LocalName, "Width", width));
3996 } 3986 }
3997 } 3987 }
3998 3988 else if (columnType == IntermediateFieldType.Path)
3999 if (columns.Count > 0)
4000 { 3989 {
4001 if (!columns.Where(c => c.PrimaryKey).Any()) 3990 if (!category.HasValue)
4002 { 3991 {
4003 this.Core.Write(ErrorMessages.CustomTableMissingPrimaryKey(sourceLineNumbers)); 3992 category = WixCustomTableColumnCategoryType.Binary;
4004 } 3993 }
4005 3994 else if (category != WixCustomTableColumnCategoryType.Binary)
4006 if (!this.Core.EncounteredError)
4007 { 3995 {
4008 var columnNames = String.Join(new string(WixCustomTableTuple.ColumnNamesSeparator, 1), columns.Select(c => c.Name)); 3996 this.Core.Write(ErrorMessages.ExpectedBinaryCategory(childSourceLineNumbers));
4009
4010 this.Core.AddTuple(new WixCustomTableTuple(sourceLineNumbers, new Identifier(AccessModifier.Public, tableId))
4011 {
4012 ColumnNames = columnNames,
4013 Unreal = unreal,
4014 });
4015 } 3997 }
4016 } 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;
4017 } 4029 }
4018 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)
4020 { 4038 {
4021 var sourceLineNumbers = Preprocessor.GetSourceLineNumbers(node);
4022 var rowId = Guid.NewGuid().ToString("N").ToUpperInvariant(); 4039 var rowId = Guid.NewGuid().ToString("N").ToUpperInvariant();
4023 4040
4024 foreach (var attrib in node.Attributes()) 4041 foreach (var attrib in node.Attributes())
@@ -6204,6 +6221,9 @@ namespace WixToolset.Core
6204 case "BootstrapperApplicationRef": 6221 case "BootstrapperApplicationRef":
6205 this.ParseBootstrapperApplicationRefElement(child); 6222 this.ParseBootstrapperApplicationRefElement(child);
6206 break; 6223 break;
6224 case "BundleCustomData":
6225 this.ParseBundleCustomDataElement(child);
6226 break;
6207 case "BundleExtension": 6227 case "BundleExtension":
6208 this.ParseBundleExtensionElement(child); 6228 this.ParseBundleExtensionElement(child);
6209 break; 6229 break;
diff --git a/src/WixToolset.Core/Compiler_Bundle.cs b/src/WixToolset.Core/Compiler_Bundle.cs
index 31896a42..5154a72f 100644
--- a/src/WixToolset.Core/Compiler_Bundle.cs
+++ b/src/WixToolset.Core/Compiler_Bundle.cs
@@ -7,6 +7,7 @@ namespace WixToolset.Core
7 using System.Diagnostics; 7 using System.Diagnostics;
8 using System.Globalization; 8 using System.Globalization;
9 using System.IO; 9 using System.IO;
10 using System.Linq;
10 using System.Xml.Linq; 11 using System.Xml.Linq;
11 using WixToolset.Data; 12 using WixToolset.Data;
12 using WixToolset.Data.Burn; 13 using WixToolset.Data.Burn;
@@ -276,6 +277,9 @@ namespace WixToolset.Core
276 case "BootstrapperApplicationRef": 277 case "BootstrapperApplicationRef":
277 this.ParseBootstrapperApplicationRefElement(child); 278 this.ParseBootstrapperApplicationRefElement(child);
278 break; 279 break;
280 case "BundleCustomData":
281 this.ParseBundleCustomDataElement(child);
282 break;
279 case "BundleExtension": 283 case "BundleExtension":
280 this.ParseBundleExtensionElement(child); 284 this.ParseBundleExtensionElement(child);
281 break; 285 break;
@@ -767,6 +771,246 @@ namespace WixToolset.Core
767 } 771 }
768 } 772 }
769 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
770 /// <summary> 1014 /// <summary>
771 /// Parse the BundleExtension element. 1015 /// Parse the BundleExtension element.
772 /// </summary> 1016 /// </summary>