/// <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)); }
private Document FindSystemDocument(string identifier, DocumentCategory category) { try { return(systemDocumentMap[Tuple.Create(identifier, category ?? DocumentCategory.Script)]); } catch (KeyNotFoundException) { return(null); } }
private Document FindSystemDocument(string identifier, DocumentCategory category) { Document document; if (systemDocumentMap.TryGetValue(Tuple.Create(identifier, category ?? DocumentCategory.Script), out document)) { return(document); } return(null); }
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); }
/// <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);
/// <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); } }
public override async Task <Document> LoadDocumentAsync(DocumentSettings settings, DocumentInfo?sourceInfo, string specifier, DocumentCategory category, DocumentContextCallback contextCallback) { MiscHelpers.VerifyNonNullArgument(settings, "settings"); MiscHelpers.VerifyNonBlankArgument(specifier, "specifier", "Invalid document specifier"); if ((settings.AccessFlags & DocumentAccessFlags.EnableAllLoading) == DocumentAccessFlags.None) { throw new UnauthorizedAccessException("This script engine is not configured for loading documents"); } if (category == null) { category = sourceInfo.HasValue ? sourceInfo.Value.Category : DocumentCategory.Script; } List <Uri> candidateUris; Uri uri; if (Uri.TryCreate(specifier, UriKind.RelativeOrAbsolute, out 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(); }
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("This 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("This 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; if (callback != null) { callback(ref documentInfo); } return(CacheDocument(new StringDocument(documentInfo, contents))); }
/// <summary> /// Adds a system document with the specified category 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> /// <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) { AddSystemDocument(identifier, category, contents, null); }