File: Model\TranslatableDocument.cs
Web Access
Project: Microsoft.DotNet.XliffTasks.csproj (Microsoft.DotNet.XliffTasks)
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;

namespace XliffTasks.Model;

/// <summary>
/// Represents a document that can be translated by applying substitutions to nodes.
/// </summary>
internal abstract class TranslatableDocument : Document
{
    /// <summary>
    /// The nodes of the document that can have substitutions.
    /// </summary>
    public IReadOnlyList<TranslatableNode> Nodes { get; private set; } = Array.Empty<TranslatableNode>();

    /// <summary>
    /// Indicates if content has been loaded in to the document.
    /// </summary>
    public override bool HasContent => _hasContent;
    private bool _hasContent;

    /// <summary>
    /// Loads (or reloads) the document content from the given reader.
    /// </summary>
    public sealed override void Load(TextReader reader)
    {
        LoadCore(reader);
        Nodes = GetTranslatableNodes().ToList().AsReadOnly();
        _hasContent = true;
    }

    /// <summary>
    /// Saves the document's content to the given file path.
    /// </summary>
    public sealed override void Save(TextWriter writer)
    {
        EnsureContent();
        SaveCore(writer);
    }

    /// <summary>
    /// Applies the given translations to the document. 
    /// Keys align with <see cref="TranslatableNode.Id"/>.
    /// Values indicate the text with which to replace <see cref="TranslatableNode.Source"/>.
    /// </summary>
    public void Translate(IReadOnlyDictionary<string, string> translations)
    {
        EnsureContent();

        foreach (TranslatableNode node in Nodes)
        {
            if (translations.TryGetValue(node.Id, out string translation))
            {
                node.Translate(translation);
            }
        }
   }

    // rewrite nodes that point to external files (used often for icons, etc.)
    // these will have relative paths adjusted to absolute path.
    public virtual void RewriteRelativePathsToAbsolute(string sourceFullPath)
    {
    }

    protected abstract void LoadCore(TextReader reader);

    protected abstract void SaveCore(TextWriter writer);

    protected abstract IEnumerable<TranslatableNode> GetTranslatableNodes();
}