From c5190ae74ab8fe13609362efce88fa4b8cc24f34 Mon Sep 17 00:00:00 2001 From: Rob Mensching Date: Sat, 30 Dec 2017 17:09:15 -0800 Subject: Fix resolution of localizations that are embedded in intermediates --- .../Link/CollateLocalizationsCommand.cs | 71 ++++++++++++++++++++++ 1 file changed, 71 insertions(+) create mode 100644 src/WixToolset.Core/Link/CollateLocalizationsCommand.cs (limited to 'src/WixToolset.Core/Link') diff --git a/src/WixToolset.Core/Link/CollateLocalizationsCommand.cs b/src/WixToolset.Core/Link/CollateLocalizationsCommand.cs new file mode 100644 index 00000000..ffa66210 --- /dev/null +++ b/src/WixToolset.Core/Link/CollateLocalizationsCommand.cs @@ -0,0 +1,71 @@ +// 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. + +namespace WixToolset.Core.Link +{ + using System; + using System.Collections.Generic; + using System.Linq; + using WixToolset.Data; + using WixToolset.Extensibility.Services; + + internal class CollateLocalizationsCommand + { + public CollateLocalizationsCommand(IMessaging messaging, IEnumerable localizations) + { + this.Messaging = messaging; + this.Localizations = localizations; + } + + private IMessaging Messaging { get; } + + private IEnumerable Localizations { get; } + + public Dictionary Execute() + { + var localizationsByCulture = new Dictionary(StringComparer.OrdinalIgnoreCase); + + foreach (var localization in this.Localizations) + { + if (localizationsByCulture.TryGetValue(localization.Culture, out var existingCulture)) + { + var merged = this.Merge(existingCulture, localization); + localizationsByCulture[localization.Culture] = merged; + } + else + { + localizationsByCulture.Add(localization.Culture, localization); + } + } + + return localizationsByCulture; + } + + private Localization Merge(Localization existingLocalization, Localization localization) + { + var variables = existingLocalization.Variables.ToDictionary(v => v.Id); + var controls = existingLocalization.LocalizedControls.ToDictionary(kvp => kvp.Key, kvp => kvp.Value); + + foreach (var newVariable in localization.Variables) + { + if (!variables.TryGetValue(newVariable.Id, out var existingVariable) || (existingVariable.Overridable && !newVariable.Overridable)) + { + variables[newVariable.Id] = newVariable; + } + else if (!newVariable.Overridable) + { + this.Messaging.Write(ErrorMessages.DuplicateLocalizationIdentifier(newVariable.SourceLineNumbers, newVariable.Id)); + } + } + + foreach (var localizedControl in localization.LocalizedControls) + { + if (!controls.ContainsKey(localizedControl.Key)) + { + controls.Add(localizedControl.Key, localizedControl.Value); + } + } + + return new Localization(existingLocalization.Codepage, existingLocalization.Culture, variables, controls); + } + } +} -- cgit v1.2.3-55-g6feb