// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT license.
using Microsoft.ClearScript.Util;
using System;
using System.IO;
using System.Threading.Tasks;
namespace Microsoft.ClearScript
{
///
/// Represents a document loader.
///
public abstract class DocumentLoader
{
// ReSharper disable EmptyConstructor
///
/// Initializes a new instance.
///
protected DocumentLoader()
{
// the help file builder (SHFB) insists on an empty constructor here
}
// ReSharper restore EmptyConstructor
///
/// Gets the default document loader.
///
public static DocumentLoader Default => DefaultImpl.Instance;
///
/// Gets or sets the maximum size of the document loader's cache.
///
///
/// This property specifies the maximum number of documents to be cached by the document
/// loader. For the default document loader, its initial value is 1024.
///
///
public virtual uint MaxCacheSize
{
get => 0;
set => throw new NotSupportedException("The document loader does not support caching");
}
///
/// Loads a document.
///
/// Document access settings for the operation.
/// An optional structure containing meta-information for the requesting document.
/// A string specifying the document to be loaded.
/// An optional category for the requested document.
/// An optional context callback for the requested document.
/// A instance that represents the loaded document.
///
/// A loaded document must have an absolute URI. Once a
/// load operation has completed successfully, subsequent requests that resolve to the same
/// URI are expected to return the same reference, although loaders
/// are not required to manage document caches of unlimited size.
///
public virtual Document LoadDocument(DocumentSettings settings, DocumentInfo? sourceInfo, string specifier, DocumentCategory category, DocumentContextCallback contextCallback)
{
MiscHelpers.VerifyNonBlankArgument(specifier, nameof(specifier), "Invalid document specifier");
try
{
return LoadDocumentAsync(settings, sourceInfo, specifier, category, contextCallback).Result;
}
catch (AggregateException exception)
{
exception = exception.Flatten();
if (exception.InnerExceptions.Count == 1)
{
throw new FileLoadException(null, specifier, exception.InnerExceptions[0]);
}
throw new FileLoadException(null, specifier, exception);
}
}
///
/// Loads a document asynchronously.
///
/// Document access settings for the operation.
/// An optional structure containing meta-information for the requesting document.
/// A string specifying the document to be loaded.
/// An optional category for the requested document.
/// An optional context callback for the requested document.
/// A task that represents the asynchronous operation. Upon completion, the task's result is a instance that represents the loaded document.
///
/// A loaded document must have an absolute URI. Once a
/// load operation has completed successfully, subsequent requests that resolve to the same
/// URI are expected to return the same reference, although loaders
/// are not required to manage document caches of unlimited size.
///
public abstract Task LoadDocumentAsync(DocumentSettings settings, DocumentInfo? sourceInfo, string specifier, DocumentCategory category, DocumentContextCallback contextCallback);
///
/// Searches for a cached document by URI.
///
/// The document URI for which to search.
/// The cached document if it was found, null otherwise.
public virtual Document GetCachedDocument(Uri uri)
{
return null;
}
///
/// Stores a document in the cache.
///
/// The document to store in the cache.
/// True to replace any existing document with the same URI, false otherwise.
/// The cached document, which may be different from if is false.
///
/// A cached document must have an absolute URI.
///
public virtual Document CacheDocument(Document document, bool replace)
{
throw new NotSupportedException("The document loader does not support caching");
}
///
/// Discards all cached documents.
///
public virtual void DiscardCachedDocuments()
{
}
#region Nested type: IStatistics
internal interface IStatistics
{
long FileCheckCount { get; }
long WebCheckCount { get; }
void ResetCheckCounts();
}
#endregion
#region Nested type: DefaultImpl
// IMPORTANT: Before its implementation was factored out and made public, some hosts used
// reflection to instantiate this class in order to maintain multiple document caches. It
// should therefore be treated and retained as part of the public API, as well as a
// placeholder for any future overrides of the default functionality.
private sealed class DefaultImpl : DefaultDocumentLoader
{
public static readonly DefaultImpl Instance = new();
private DefaultImpl()
{
}
}
#endregion
}
}