// 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
{
using System;
using System.Collections.Generic;
using System.Linq;
using WixToolset.Core.Bind;
using WixToolset.Data;
using WixToolset.Data.Tuples;
using WixToolset.Extensibility;
using WixToolset.Extensibility.Services;
///
/// Resolver for the WiX toolset.
///
public sealed class Resolver
{
public Resolver(IServiceProvider serviceProvider)
{
this.ServiceProvider = serviceProvider;
}
private IServiceProvider ServiceProvider { get; set; }
public IEnumerable BindPaths { get; set; }
public Intermediate IntermediateRepresentation { get; set; }
public string IntermediateFolder { get; set; }
public IEnumerable Localizations { get; set; }
private IMessaging Messaging { get; set; }
public ResolveResult Execute()
{
this.Messaging = this.ServiceProvider.GetService();
var localizer = new Localizer(this.Messaging, this.Localizations);
var variableResolver = new WixVariableResolver(this.Messaging, localizer);
this.PopulateVariableResolver(variableResolver);
var context = this.ServiceProvider.GetService();
context.Messaging = this.Messaging;
context.BindPaths = this.BindPaths;
context.Extensions = this.ServiceProvider.GetService().Create();
context.IntermediateFolder = this.IntermediateFolder;
context.IntermediateRepresentation = this.IntermediateRepresentation;
context.WixVariableResolver = variableResolver;
// Preresolve.
//
foreach (IResolverExtension extension in context.Extensions)
{
extension.PreResolve(context);
}
// Resolve.
//
this.LocalizeUI(context);
var resolveResult = this.Resolve(localizer.Codepage, context);
if (resolveResult != null)
{
// Postresolve.
//
foreach (IResolverExtension extension in context.Extensions)
{
extension.PostResolve(resolveResult);
}
}
return resolveResult;
}
private ResolveResult Resolve(int codepage, IResolveContext context)
{
var buildingPatch = context.IntermediateRepresentation.Sections.Any(s => s.Type == SectionType.Patch);
var filesWithEmbeddedFiles = new ExtractEmbeddedFiles();
IEnumerable delayedFields;
{
var command = new ResolveFieldsCommand();
command.Messaging = context.Messaging;
command.BuildingPatch = buildingPatch;
command.BindVariableResolver = context.WixVariableResolver;
command.BindPaths = context.BindPaths;
command.Extensions = context.Extensions;
command.FilesWithEmbeddedFiles = filesWithEmbeddedFiles;
command.IntermediateFolder = context.IntermediateFolder;
command.Intermediate = context.IntermediateRepresentation;
command.SupportDelayedResolution = true;
command.Execute();
delayedFields = command.DelayedFields;
}
#if REVISIT_FOR_PATCHING
if (context.IntermediateRepresentation.SubStorages != null)
{
foreach (SubStorage transform in context.IntermediateRepresentation.SubStorages)
{
var command = new ResolveFieldsCommand();
command.BuildingPatch = buildingPatch;
command.BindVariableResolver = context.WixVariableResolver;
command.BindPaths = context.BindPaths;
command.Extensions = context.Extensions;
command.FilesWithEmbeddedFiles = filesWithEmbeddedFiles;
command.IntermediateFolder = context.IntermediateFolder;
command.Intermediate = context.IntermediateRepresentation;
command.SupportDelayedResolution = false;
command.Execute();
}
}
#endif
var expectedEmbeddedFiles = filesWithEmbeddedFiles.GetExpectedEmbeddedFiles();
return new ResolveResult
{
Codepage = codepage,
ExpectedEmbeddedFiles = expectedEmbeddedFiles,
DelayedFields = delayedFields,
IntermediateRepresentation = context.IntermediateRepresentation
};
}
///
/// Localize dialogs and controls.
///
private void LocalizeUI(IResolveContext context)
{
foreach (var section in context.IntermediateRepresentation.Sections)
{
foreach (var row in section.Tuples.OfType())
{
string dialog = row.Dialog;
if (context.WixVariableResolver.TryGetLocalizedControl(dialog, null, out LocalizedControl localizedControl))
{
if (CompilerConstants.IntegerNotSet != localizedControl.X)
{
row.HCentering = localizedControl.X;
}
if (CompilerConstants.IntegerNotSet != localizedControl.Y)
{
row.VCentering = localizedControl.Y;
}
if (CompilerConstants.IntegerNotSet != localizedControl.Width)
{
row.Width = localizedControl.Width;
}
if (CompilerConstants.IntegerNotSet != localizedControl.Height)
{
row.Height = localizedControl.Height;
}
row.Attributes = row.Attributes | localizedControl.Attributes;
if (!String.IsNullOrEmpty(localizedControl.Text))
{
row.Title = localizedControl.Text;
}
}
}
foreach (var row in section.Tuples.OfType())
{
string dialog = row.Dialog_;
string control = row.Control;
if (context.WixVariableResolver.TryGetLocalizedControl(dialog, control, out LocalizedControl localizedControl))
{
if (CompilerConstants.IntegerNotSet != localizedControl.X)
{
row.X = localizedControl.X;
}
if (CompilerConstants.IntegerNotSet != localizedControl.Y)
{
row.Y = localizedControl.Y;
}
if (CompilerConstants.IntegerNotSet != localizedControl.Width)
{
row.Width = localizedControl.Width;
}
if (CompilerConstants.IntegerNotSet != localizedControl.Height)
{
row.Height = localizedControl.Height;
}
row.Attributes = row.Attributes | localizedControl.Attributes;
if (!String.IsNullOrEmpty(localizedControl.Text))
{
row.Text = localizedControl.Text;
}
}
}
}
}
private void PopulateVariableResolver(WixVariableResolver resolver)
{
// Gather all the wix variables.
var wixVariableTuples = this.IntermediateRepresentation.Sections.SelectMany(s => s.Tuples).OfType();
foreach (var tuple in wixVariableTuples)
{
try
{
resolver.AddVariable(tuple.WixVariable, tuple.Value, tuple.Overridable);
}
catch (ArgumentException)
{
this.Messaging.Write(ErrorMessages.WixVariableCollision(tuple.SourceLineNumbers, tuple.WixVariable));
}
}
}
}
}