aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRob Mensching <rob@firegiant.com>2017-12-30 01:31:32 -0800
committerRob Mensching <rob@firegiant.com>2017-12-30 01:31:32 -0800
commit7b013ac66a36e0f73d480ef28771a65f64b57e19 (patch)
tree4a2996a1a539337ae27f3b9dfc692cf6052b897c
parentbcfae2a06a3a6c7e778b615e765b5a9efe847c0c (diff)
downloadwix-7b013ac66a36e0f73d480ef28771a65f64b57e19.tar.gz
wix-7b013ac66a36e0f73d480ef28771a65f64b57e19.tar.bz2
wix-7b013ac66a36e0f73d480ef28771a65f64b57e19.zip
Support serializing localization information in Intermediates
-rw-r--r--src/WixToolset.Data/Bind/BindVariable.cs33
-rw-r--r--src/WixToolset.Data/Intermediate.cs34
-rw-r--r--src/WixToolset.Data/Json/JsonObjectExtensions.cs45
-rw-r--r--src/WixToolset.Data/Localization.cs72
-rw-r--r--src/WixToolset.Data/LocalizedControl.cs33
-rw-r--r--src/test/WixToolsetTest.Data/SerializeFixture.cs56
6 files changed, 253 insertions, 20 deletions
diff --git a/src/WixToolset.Data/Bind/BindVariable.cs b/src/WixToolset.Data/Bind/BindVariable.cs
index 06c004e1..276dae38 100644
--- a/src/WixToolset.Data/Bind/BindVariable.cs
+++ b/src/WixToolset.Data/Bind/BindVariable.cs
@@ -1,9 +1,11 @@
1// Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. 1// Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information.
2 2
3namespace WixToolset.Data.Rows 3namespace WixToolset.Data.Bind
4{ 4{
5 using SimpleJson;
6
5 /// <summary> 7 /// <summary>
6 /// Specialization of a row for the WixVariable table. 8 /// Bind variable.
7 /// </summary> 9 /// </summary>
8 public sealed class BindVariable 10 public sealed class BindVariable
9 { 11 {
@@ -29,5 +31,32 @@ namespace WixToolset.Data.Rows
29 /// </summary> 31 /// </summary>
30 /// <value>Whether this variable is overridable.</value> 32 /// <value>Whether this variable is overridable.</value>
31 public bool Overridable { get; set; } 33 public bool Overridable { get; set; }
34
35 internal JsonObject Serialize()
36 {
37 var jsonObject = new JsonObject
38 {
39 { "name", this.Id },
40 };
41
42 jsonObject.AddIsNotNullOrEmpty("value", this.Value);
43 jsonObject.AddNonDefaultValue("overridable", this.Overridable, false);
44 jsonObject.AddNonDefaultValue("ln", this.SourceLineNumbers?.Serialize());
45
46 return jsonObject;
47 }
48
49 internal static BindVariable Deserialize(JsonObject jsonObject)
50 {
51 var variable = new BindVariable()
52 {
53 Id = jsonObject.GetValueOrDefault<string>("name"),
54 Value = jsonObject.GetValueOrDefault<string>("value"),
55 Overridable = jsonObject.GetValueOrDefault("overridable", false),
56 SourceLineNumbers = jsonObject.GetValueOrDefault<SourceLineNumber>("ln")
57 };
58
59 return variable;
60 }
32 } 61 }
33} 62}
diff --git a/src/WixToolset.Data/Intermediate.cs b/src/WixToolset.Data/Intermediate.cs
index a23cc091..ae507058 100644
--- a/src/WixToolset.Data/Intermediate.cs
+++ b/src/WixToolset.Data/Intermediate.cs
@@ -198,17 +198,17 @@ namespace WixToolset.Data
198 jsonObject.Add("definitions", customDefinitionsJson); 198 jsonObject.Add("definitions", customDefinitionsJson);
199 } 199 }
200 200
201 //if (this.Localizations.Any()) 201 if (this.Localizations.Any())
202 //{ 202 {
203 // var localizationsJson = new JsonArray(); 203 var localizationsJson = new JsonArray();
204 // foreach (var localization in this.Localizations) 204 foreach (var localization in this.Localizations)
205 // { 205 {
206 // var localizationJson = localization.Serialize(); 206 var localizationJson = localization.Serialize();
207 // localizationsJson.Add(localizationJson); 207 localizationsJson.Add(localizationJson);
208 // } 208 }
209 209
210 // jsonObject.Add("localizations", localizationsJson); 210 jsonObject.Add("localizations", localizationsJson);
211 //} 211 }
212 212
213 var json = SimpleJson.SerializeObject(jsonObject); 213 var json = SimpleJson.SerializeObject(jsonObject);
214 writer.Write(json); 214 writer.Write(json);
@@ -272,12 +272,12 @@ namespace WixToolset.Data
272 272
273 var localizations = new Dictionary<string, Localization>(StringComparer.OrdinalIgnoreCase); 273 var localizations = new Dictionary<string, Localization>(StringComparer.OrdinalIgnoreCase);
274 274
275 //var localizationsJson = jsonObject.GetValueOrDefault<JsonArray>("localizations") ?? new JsonArray(); 275 var localizationsJson = jsonObject.GetValueOrDefault<JsonArray>("localizations") ?? new JsonArray();
276 //foreach (JsonObject localizationJson in localizationsJson) 276 foreach (JsonObject localizationJson in localizationsJson)
277 //{ 277 {
278 // var localization = Localization.Deserialize(localizationJson); 278 var localization = Localization.Deserialize(localizationJson);
279 // localizations.Add(localization.Culture, localization); 279 localizations.Add(localization.Culture, localization);
280 //} 280 }
281 281
282 return new Intermediate(id, sections, localizations, null); 282 return new Intermediate(id, sections, localizations, null);
283 } 283 }
diff --git a/src/WixToolset.Data/Json/JsonObjectExtensions.cs b/src/WixToolset.Data/Json/JsonObjectExtensions.cs
index 296a7ab6..e9e170ee 100644
--- a/src/WixToolset.Data/Json/JsonObjectExtensions.cs
+++ b/src/WixToolset.Data/Json/JsonObjectExtensions.cs
@@ -7,6 +7,51 @@ namespace WixToolset.Data
7 7
8 internal static class JsonObjectExtensions 8 internal static class JsonObjectExtensions
9 { 9 {
10 public static JsonObject AddNonDefaultValue(this JsonObject jsonObject, string key, bool value, bool defaultValue = default(bool))
11 {
12 if (value != defaultValue)
13 {
14 jsonObject.Add(key, value);
15 }
16
17 return jsonObject;
18 }
19
20 public static JsonObject AddNonDefaultValue(this JsonObject jsonObject, string key, int value, int defaultValue = default(int))
21 {
22 if (value != defaultValue)
23 {
24 jsonObject.Add(key, value);
25 }
26
27 return jsonObject;
28 }
29
30 public static JsonObject AddNonDefaultValue(this JsonObject jsonObject, string key, object value, object defaultValue = null)
31 {
32 if (value != defaultValue)
33 {
34 jsonObject.Add(key, value);
35 }
36
37 return jsonObject;
38 }
39
40 public static JsonObject AddIsNotNullOrEmpty(this JsonObject jsonObject, string key, string value)
41 {
42 if (!String.IsNullOrEmpty(value))
43 {
44 jsonObject.Add(key, value);
45 }
46
47 return jsonObject;
48 }
49
50 public static bool GetValueOrDefault(this JsonObject jsonObject, string key, bool defaultValue)
51 {
52 return jsonObject.TryGetValue(key, out var value) ? Convert.ToBoolean(value) : defaultValue;
53 }
54
10 public static int GetValueOrDefault(this JsonObject jsonObject, string key, int defaultValue) 55 public static int GetValueOrDefault(this JsonObject jsonObject, string key, int defaultValue)
11 { 56 {
12 return jsonObject.TryGetValue(key, out var value) ? Convert.ToInt32(value) : defaultValue; 57 return jsonObject.TryGetValue(key, out var value) ? Convert.ToInt32(value) : defaultValue;
diff --git a/src/WixToolset.Data/Localization.cs b/src/WixToolset.Data/Localization.cs
index 10eff2e1..4ddef77b 100644
--- a/src/WixToolset.Data/Localization.cs
+++ b/src/WixToolset.Data/Localization.cs
@@ -7,8 +7,9 @@ namespace WixToolset.Data
7 using System.Diagnostics; 7 using System.Diagnostics;
8 using System.Globalization; 8 using System.Globalization;
9 using System.Xml; 9 using System.Xml;
10 using SimpleJson;
10 using WixToolset.Data.Msi; 11 using WixToolset.Data.Msi;
11 using WixToolset.Data.Rows; 12 using WixToolset.Data.Bind;
12 13
13 /// <summary> 14 /// <summary>
14 /// Object that represents a localization file. 15 /// Object that represents a localization file.
@@ -74,6 +75,75 @@ namespace WixToolset.Data
74 } 75 }
75 } 76 }
76 77
78 internal JsonObject Serialize()
79 {
80 var jsonObject = new JsonObject
81 {
82 { "codepage", this.Codepage },
83 };
84
85 jsonObject.AddIsNotNullOrEmpty("culture", this.Culture);
86
87 // Serialize bind variables.
88 if (this.Variables.Count > 0)
89 {
90 var variablesJson = new JsonArray(this.Variables.Count);
91
92 foreach (var variable in this.Variables)
93 {
94 var variableJson = variable.Serialize();
95
96 variablesJson.Add(variableJson);
97 }
98
99 jsonObject.Add("variables", variablesJson);
100 }
101
102 // Serialize localized control.
103 if (this.LocalizedControls.Count > 0)
104 {
105 var controlsJson = new JsonObject();
106
107 foreach (var controlWithKey in this.LocalizedControls)
108 {
109 var controlJson = controlWithKey.Value.Serialize();
110
111 controlsJson.Add(controlWithKey.Key, controlJson);
112 }
113
114 jsonObject.Add("controls", controlsJson);
115 }
116
117 return jsonObject;
118 }
119
120 internal static Localization Deserialize(JsonObject jsonObject)
121 {
122 var codepage = jsonObject.GetValueOrDefault("codepage", 0);
123 var culture = jsonObject.GetValueOrDefault<string>("culture");
124
125 var variables = new Dictionary<string, BindVariable>();
126 var variablesJson = jsonObject.GetValueOrDefault("variables", new JsonArray());
127 foreach (JsonObject variableJson in variablesJson)
128 {
129 var bindPath = BindVariable.Deserialize(variableJson);
130 variables.Add(bindPath.Id, bindPath);
131 }
132
133 var controls = new Dictionary<string, LocalizedControl>();
134 var controlsJson = jsonObject.GetValueOrDefault<JsonObject>("controls");
135 if (controlsJson != null)
136 {
137 foreach (var controlJsonWithKey in controlsJson)
138 {
139 var control = LocalizedControl.Deserialize((JsonObject)controlJsonWithKey.Value);
140 controls.Add(controlJsonWithKey.Key, control);
141 }
142 }
143
144 return new Localization(codepage, culture, variables, controls);
145 }
146
77 /// <summary> 147 /// <summary>
78 /// Loads a localization file from a stream. 148 /// Loads a localization file from a stream.
79 /// </summary> 149 /// </summary>
diff --git a/src/WixToolset.Data/LocalizedControl.cs b/src/WixToolset.Data/LocalizedControl.cs
index 979f9fde..cb60b7ba 100644
--- a/src/WixToolset.Data/LocalizedControl.cs
+++ b/src/WixToolset.Data/LocalizedControl.cs
@@ -3,6 +3,7 @@
3namespace WixToolset.Data 3namespace WixToolset.Data
4{ 4{
5 using System; 5 using System;
6 using SimpleJson;
6 7
7 public class LocalizedControl 8 public class LocalizedControl
8 { 9 {
@@ -47,5 +48,37 @@ namespace WixToolset.Data
47 /// <param name="control">The id of the control.</param> 48 /// <param name="control">The id of the control.</param>
48 /// <returns>The localized control id.</returns> 49 /// <returns>The localized control id.</returns>
49 public static string GetKey(string dialog, string control) => String.Concat(dialog, "/", control); 50 public static string GetKey(string dialog, string control) => String.Concat(dialog, "/", control);
51
52 internal JsonObject Serialize()
53 {
54 var jsonObject = new JsonObject
55 {
56 { "dialog", this.Dialog },
57 };
58
59 jsonObject.AddIsNotNullOrEmpty("control", this.Control);
60 jsonObject.AddNonDefaultValue("x", this.X, 0);
61 jsonObject.AddNonDefaultValue("y", this.Y, 0);
62 jsonObject.AddNonDefaultValue("width", this.Width, 0);
63 jsonObject.AddNonDefaultValue("height", this.Height, 0);
64 jsonObject.AddNonDefaultValue("attribs", this.Attributes, 0);
65 jsonObject.AddIsNotNullOrEmpty("text", this.Text);
66
67 return jsonObject;
68 }
69
70 internal static LocalizedControl Deserialize(JsonObject jsonObject)
71 {
72 var dialog = jsonObject.GetValueOrDefault<string>("dialog");
73 var control = jsonObject.GetValueOrDefault<string>("control");
74 var x = jsonObject.GetValueOrDefault("x", 0);
75 var y = jsonObject.GetValueOrDefault("y", 0);
76 var width = jsonObject.GetValueOrDefault("width", 0);
77 var height = jsonObject.GetValueOrDefault("height", 0);
78 var attribs = jsonObject.GetValueOrDefault("attribs", 0);
79 var text = jsonObject.GetValueOrDefault<string>("text");
80
81 return new LocalizedControl(dialog, control, x, y, width, height, attribs, text);
82 }
50 } 83 }
51} 84}
diff --git a/src/test/WixToolsetTest.Data/SerializeFixture.cs b/src/test/WixToolsetTest.Data/SerializeFixture.cs
index 9883053f..1e03481d 100644
--- a/src/test/WixToolsetTest.Data/SerializeFixture.cs
+++ b/src/test/WixToolsetTest.Data/SerializeFixture.cs
@@ -6,6 +6,7 @@ namespace WixToolsetTest.Data
6 using System.IO; 6 using System.IO;
7 using System.Linq; 7 using System.Linq;
8 using WixToolset.Data; 8 using WixToolset.Data;
9 using WixToolset.Data.Bind;
9 using WixToolset.Data.Tuples; 10 using WixToolset.Data.Tuples;
10 using Xunit; 11 using Xunit;
11 12
@@ -39,5 +40,60 @@ namespace WixToolsetTest.Data
39 Assert.Equal("TestFolder", tuple.Directory_); 40 Assert.Equal("TestFolder", tuple.Directory_);
40 Assert.Equal(2, tuple.Attributes); 41 Assert.Equal(2, tuple.Attributes);
41 } 42 }
43
44 [Fact]
45 public void CanSaveAndLoadIntermediateWithLocalization()
46 {
47 var sln = new SourceLineNumber("test.wxs", 10);
48
49 var bindVariables = new[]
50 {
51 new BindVariable { Id = "TestVar1", Value = "TestValue1", SourceLineNumbers = sln },
52 new BindVariable { Id = "TestVar2", Value = "TestValue2", Overridable = true, SourceLineNumbers = sln },
53 };
54
55 var controls = new[]
56 {
57 new LocalizedControl("TestDlg1", "TestControl1", 10, 10, 100, 100, 0, null),
58 new LocalizedControl("TestDlg1", "TestControl2", 100, 90, 50, 70, 0, "localized"),
59 };
60
61 var localizations = new[]
62 {
63 new Localization(65001, null, bindVariables.ToDictionary(b => b.Id), controls.ToDictionary(c => c.GetKey()))
64 };
65
66 var section = new IntermediateSection("test", SectionType.Product, 65001);
67
68 section.Tuples.Add(new ComponentTuple(sln, new Identifier("TestComponent", AccessModifier.Public))
69 {
70 ComponentId = new Guid(1, 0, 0, new byte[8]).ToString("B"),
71 Directory_ = "TestFolder",
72 Attributes = 2,
73 });
74
75 var intermediate = new Intermediate("TestIntermediate", new[] { section }, localizations.ToDictionary(l => l.Culture), null);
76
77 var path = Path.GetTempFileName();
78 try
79 {
80 intermediate.Save(path);
81
82 var loaded = Intermediate.Load(path);
83
84 var loc = loaded.Localizations.Single();
85 Assert.Equal(65001, loc.Codepage);
86 Assert.Empty(loc.Culture);
87 Assert.Equal(new[]
88 {
89 "TestVar1/TestValue1/False",
90 "TestVar2/TestValue2/True",
91 }, loc.Variables.Select(v => String.Join("/", v.Id, v.Value, v.Overridable)).ToArray());
92 }
93 finally
94 {
95 File.Delete(path);
96 }
97 }
42 } 98 }
43} 99}