Пример #1
0
        /// <summary>
        /// Adds a system document with the specified category and context callback to the configuration.
        /// </summary>
        /// <param name="identifier">An identifier for the document.</param>
        /// <param name="category">An optional category for the document.</param>
        /// <param name="contents">A string containing the document's contents.</param>
        /// <param name="contextCallback">An optional context callback for the document.</param>
        /// <remarks>
        /// System documents take precedence over loaded documents. Once this method is invoked,
        /// document access using this configuration will always map the combination of
        /// <paramref name="identifier"/> and <paramref name="category"/> to the specified
        /// document, bypassing the configuration's document loader.
        /// </remarks>
        public void AddSystemDocument(string identifier, DocumentCategory category, string contents, DocumentContextCallback contextCallback)
        {
            MiscHelpers.VerifyNonBlankArgument(identifier, "specifier", "Invalid document specifier");
            var info = new DocumentInfo(Path.GetFileName(identifier))
            {
                Category = category, ContextCallback = contextCallback
            };

            AddSystemDocument(identifier, new StringDocument(info, contents));
        }
Пример #2
0
        internal Document LoadDocument(DocumentInfo?sourceInfo, string specifier, DocumentCategory category, DocumentContextCallback contextCallback)
        {
            var document = FindSystemDocument(specifier, category);

            if (document != null)
            {
                return(document);
            }

            document = Loader.LoadDocument(this, sourceInfo, specifier, category, contextCallback);
            if (document.Info.Category != (category ?? DocumentCategory.Script))
            {
                throw new FileLoadException("Loaded document category mismatch", "specifier");
            }

            return(document);
        }
Пример #3
0
 public override Task <Document> LoadDocumentAsync(DocumentSettings settings, DocumentInfo?sourceInfo, string specifier, DocumentCategory category, DocumentContextCallback contextCallback)
 {
     return(Default.LoadDocumentAsync(settings, sourceInfo, specifier, category, contextCallback ?? CreateDocumentContext));
 }
Пример #4
0
            public override async Task <Document> LoadDocumentAsync(DocumentSettings settings, DocumentInfo?sourceInfo, string specifier, DocumentCategory category, DocumentContextCallback contextCallback)
            {
                MiscHelpers.VerifyNonNullArgument(settings, nameof(settings));
                MiscHelpers.VerifyNonBlankArgument(specifier, nameof(specifier), "Invalid document specifier");

                if ((settings.AccessFlags & DocumentAccessFlags.EnableAllLoading) == DocumentAccessFlags.None)
                {
                    throw new UnauthorizedAccessException("The script engine is not configured for loading documents");
                }

                if (category == null)
                {
                    category = sourceInfo.HasValue ? sourceInfo.Value.Category : DocumentCategory.Script;
                }

                List <Uri> candidateUris;

                if (Uri.TryCreate(specifier, UriKind.RelativeOrAbsolute, out var uri) && uri.IsAbsoluteUri)
                {
                    candidateUris = await GetCandidateUrisAsync(settings, sourceInfo, uri).ConfigureAwait(false);
                }
                else
                {
                    candidateUris = await GetCandidateUrisAsync(settings, sourceInfo, specifier).ConfigureAwait(false);
                }

                if (candidateUris.Count < 1)
                {
                    throw new FileNotFoundException(null, specifier);
                }

                if (candidateUris.Count == 1)
                {
                    return(await LoadDocumentAsync(settings, candidateUris[0], category, contextCallback).ConfigureAwait(false));
                }

                var exceptions = new List <Exception>(candidateUris.Count);

                foreach (var candidateUri in candidateUris)
                {
                    var task = LoadDocumentAsync(settings, candidateUri, category, contextCallback);
                    try
                    {
                        return(await task.ConfigureAwait(false));
                    }
                    catch (Exception exception)
                    {
                        if ((task.Exception != null) && task.Exception.InnerExceptions.Count == 1)
                        {
                            Debug.Assert(ReferenceEquals(task.Exception.InnerExceptions[0], exception));
                            exceptions.Add(exception);
                        }
                        else
                        {
                            exceptions.Add(task.Exception);
                        }
                    }
                }

                if (exceptions.Count < 1)
                {
                    MiscHelpers.AssertUnreachable();
                    throw new FileNotFoundException(null, specifier);
                }

                if (exceptions.Count == 1)
                {
                    MiscHelpers.AssertUnreachable();
                    throw new FileLoadException(exceptions[0].Message, specifier, exceptions[0]);
                }

                throw new AggregateException(exceptions).Flatten();
            }
Пример #5
0
            private async Task <Document> LoadDocumentAsync(DocumentSettings settings, Uri uri, DocumentCategory category, DocumentContextCallback contextCallback)
            {
                var cachedDocument = GetCachedDocument(uri);

                if (cachedDocument != null)
                {
                    return(cachedDocument);
                }

                string contents;
                var    flags = settings.AccessFlags;

                if (uri.IsFile)
                {
                    if (!flags.HasFlag(DocumentAccessFlags.EnableFileLoading))
                    {
                        throw new UnauthorizedAccessException("The script engine is not configured for loading documents from the file system");
                    }

                    using (var reader = new StreamReader(uri.LocalPath))
                    {
                        contents = await reader.ReadToEndAsync().ConfigureAwait(false);
                    }
                }
                else
                {
                    if (!flags.HasFlag(DocumentAccessFlags.EnableWebLoading))
                    {
                        throw new UnauthorizedAccessException("The script engine is not configured for downloading documents from the Web");
                    }

                    using (var client = new WebClient())
                    {
                        contents = await client.DownloadStringTaskAsync(uri).ConfigureAwait(false);
                    }
                }

                var documentInfo = new DocumentInfo(uri)
                {
                    Category = category, ContextCallback = contextCallback
                };

                var callback = settings.LoadCallback;

                callback?.Invoke(ref documentInfo);

                return(CacheDocument(new StringDocument(documentInfo, contents)));
            }
Пример #6
0
 /// <summary>
 /// Loads a document asynchronously.
 /// </summary>
 /// <param name="settings">Document access settings for the operation.</param>
 /// <param name="sourceInfo">An optional structure containing meta-information for the requesting document.</param>
 /// <param name="specifier">A string specifying the document to be loaded.</param>
 /// <param name="category">An optional category for the requested document.</param>
 /// <param name="contextCallback">An optional context callback for the requested document.</param>
 /// <returns>A task that represents the asynchronous operation. Upon completion, the task's result is a <see cref="Document"/> instance that represents the loaded document.</returns>
 /// <remarks>
 /// A loaded document must have an absolute <see cref="DocumentInfo.Uri">URI</see>. Once a
 /// load operation has completed successfully, subsequent requests that resolve to the same
 /// URI are expected to return the same <see cref="Document"/> reference, although loaders
 /// are not required to manage document caches of unlimited size.
 /// </remarks>
 public abstract Task <Document> LoadDocumentAsync(DocumentSettings settings, DocumentInfo?sourceInfo, string specifier, DocumentCategory category, DocumentContextCallback contextCallback);
Пример #7
0
        /// <summary>
        /// Loads a document.
        /// </summary>
        /// <param name="settings">Document access settings for the operation.</param>
        /// <param name="sourceInfo">An optional structure containing meta-information for the requesting document.</param>
        /// <param name="specifier">A string specifying the document to be loaded.</param>
        /// <param name="category">An optional category for the requested document.</param>
        /// <param name="contextCallback">An optional context callback for the requested document.</param>
        /// <returns>A <see cref="Document"/> instance that represents the loaded document.</returns>
        /// <remarks>
        /// A loaded document must have an absolute <see cref="DocumentInfo.Uri">URI</see>. Once a
        /// load operation has completed successfully, subsequent requests that resolve to the same
        /// URI are expected to return the same <see cref="Document"/> reference, although loaders
        /// are not required to manage document caches of unlimited size.
        /// </remarks>
        public virtual Document LoadDocument(DocumentSettings settings, DocumentInfo?sourceInfo, string specifier, DocumentCategory category, DocumentContextCallback contextCallback)
        {
            MiscHelpers.VerifyNonBlankArgument(specifier, "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);
            }
        }