/// <summary> /// Loads a contenxt document /// </summary> /// <param name="url"></param> /// <returns></returns> public virtual async Task <RemoteDocument> LoadDocumentAsync(string url) { var doc = new RemoteDocument(url, null); try { var resp = await HttpClient.GetAsync(url); // ensure we got some form of JSON as a response if (!resp.Content.Headers.ContentType.MediaType.Contains("json")) { throw new JsonLdError(JsonLdError.Error.LoadingDocumentFailed, url); } // check if the response contains JSON-LD var isJsonld = resp.Content.Headers.ContentType.MediaType == "application/ld+json"; // get link headers from response var linkHeaders = resp.Content.Headers.FirstOrDefault(kvp => kvp.Key == "Links").Value? .SelectMany(h1 => h1.Split(",".ToCharArray()).Select(h2 => h2.Trim())) .ToArray(); if (!isJsonld && linkHeaders != null) { // get headers for linked contexts (must only be 1) var linkedContexts = linkHeaders.Where(v => v.EndsWith("rel=\"http://www.w3.org/ns/json-ld#context\"", StringComparison.OrdinalIgnoreCase)) .ToList(); if (linkedContexts.Count > 1) { throw new JsonLdError(JsonLdError.Error.MultipleContextLinkHeaders); } // get the url for the linked context from the response headers var header = linkedContexts.First(); var linkedContextUrl = header.Substring(1, header.IndexOf(">", StringComparison.Ordinal) - 1); // load the remote doc var remoteContext = await LoadDocumentAsync(Url.Resolve(url, linkedContextUrl)); // set the context and its url doc.ContextUrl = remoteContext.DocumentUrl; doc.Context = remoteContext.Document; } doc.DocumentUrl = url; doc.Document = JsonUtils.FromInputStream(await resp.Content.ReadAsStreamAsync()); } catch (JsonLdError) { throw; } catch (Exception) { throw new JsonLdError(JsonLdError.Error.LoadingDocumentFailed, url); } return(doc); }
/// <exception cref="JsonLDNet.Core.JsonLdError"></exception> public virtual async Task <RemoteDocument> LoadDocumentAsync(string url) { RemoteDocument doc = new RemoteDocument(url, null); try { using (HttpResponseMessage response = await JsonLD.Util.LDHttpClient.FetchAsync(url).ConfigureAwait(false)) { var code = (int)response.StatusCode; if (code >= 400) { throw new JsonLdError(JsonLdError.Error.LoadingDocumentFailed, $"HTTP {code} {url}"); } var finalUrl = response.RequestMessage.RequestUri.ToString(); var contentType = GetJsonLDContentType(response.Content.Headers.ContentType.MediaType); if (contentType == JsonLDContentType.Other) { throw new JsonLdError(JsonLdError.Error.LoadingDocumentFailed, url); } // For plain JSON, see if there's a context document linked in the HTTP response headers. if (contentType == JsonLDContentType.PlainJson && response.Headers.TryGetValues("Link", out var linkHeaders)) { linkHeaders = linkHeaders.SelectMany((h) => h.Split(",".ToCharArray())) .Select(h => h.Trim()).ToArray(); IEnumerable <string> linkedContexts = linkHeaders.Where(v => v.EndsWith("rel=\"http://www.w3.org/ns/json-ld#context\"")); if (linkedContexts.Count() > 1) { throw new JsonLdError(JsonLdError.Error.MultipleContextLinkHeaders); } string header = linkedContexts.First(); string linkedUrl = header.Substring(1, header.IndexOf(">") - 1); string resolvedUrl = URL.Resolve(finalUrl, linkedUrl); var remoteContext = await this.LoadDocumentAsync(resolvedUrl).ConfigureAwait(false); doc.contextUrl = remoteContext.documentUrl; doc.context = remoteContext.document; } Stream stream = await response.Content.ReadAsStreamAsync().ConfigureAwait(false); doc.DocumentUrl = finalUrl; doc.Document = JSONUtils.FromInputStream(stream); } } catch (JsonLdError) { throw; } catch (Exception exception) { throw new JsonLdError(JsonLdError.Error.LoadingDocumentFailed, url, exception); } return(doc); }
/// <exception cref="JsonLDNet.Core.JsonLdError"></exception> public virtual RemoteDocument LoadDocument(string url) { #if !PORTABLE RemoteDocument doc = new RemoteDocument(url, null); try { HttpWebRequest req = (HttpWebRequest)HttpWebRequest.Create(url); req.Accept = AcceptHeader; WebResponse resp = req.GetResponse(); bool isJsonld = resp.Headers[HttpResponseHeader.ContentType] == "application/ld+json"; if (!resp.Headers[HttpResponseHeader.ContentType].Contains("json")) { throw new JsonLdError(JsonLdError.Error.LoadingDocumentFailed, url); } string[] linkHeaders = resp.Headers.GetValues("Link"); if (!isJsonld && linkHeaders != null) { linkHeaders = linkHeaders.SelectMany((h) => h.Split(",".ToCharArray())) .Select(h => h.Trim()).ToArray(); IEnumerable<string> linkedContexts = linkHeaders.Where(v => v.EndsWith("rel=\"http://www.w3.org/ns/json-ld#context\"")); if (linkedContexts.Count() > 1) { throw new JsonLdError(JsonLdError.Error.MultipleContextLinkHeaders); } string header = linkedContexts.First(); string linkedUrl = header.Substring(1, header.IndexOf(">") - 1); string resolvedUrl = URL.Resolve(url, linkedUrl); var remoteContext = this.LoadDocument(resolvedUrl); doc.contextUrl = remoteContext.documentUrl; doc.context = remoteContext.document; } Stream stream = resp.GetResponseStream(); doc.DocumentUrl = req.Address.ToString(); doc.Document = JSONUtils.FromInputStream(stream); } catch (JsonLdError) { throw; } catch (Exception) { throw new JsonLdError(JsonLdError.Error.LoadingDocumentFailed, url); } return doc; #else throw new NotImplementedException(); #endif }
/// <exception cref="JsonLDNet.Core.JsonLdError"></exception> public virtual RemoteDocument LoadDocument(string url) { #if !PORTABLE RemoteDocument doc = new RemoteDocument(url, null); try { HttpWebRequest req = (HttpWebRequest)HttpWebRequest.Create(url); req.Accept = AcceptHeader; WebResponse resp = req.GetResponse(); bool isJsonld = resp.Headers[HttpResponseHeader.ContentType] == "application/ld+json"; if (!resp.Headers[HttpResponseHeader.ContentType].Contains("json")) { throw new JsonLdError(JsonLdError.Error.LoadingDocumentFailed, url); } string[] linkHeaders = resp.Headers.GetValues("Link"); if (!isJsonld && linkHeaders != null) { linkHeaders = linkHeaders.SelectMany((h) => h.Split(",".ToCharArray())) .Select(h => h.Trim()).ToArray(); IEnumerable <string> linkedContexts = linkHeaders.Where(v => v.EndsWith("rel=\"http://www.w3.org/ns/json-ld#context\"")); if (linkedContexts.Count() > 1) { throw new JsonLdError(JsonLdError.Error.MultipleContextLinkHeaders); } string header = linkedContexts.First(); string linkedUrl = header.Substring(1, header.IndexOf(">") - 1); string resolvedUrl = URL.Resolve(url, linkedUrl); var remoteContext = this.LoadDocument(resolvedUrl); doc.contextUrl = remoteContext.documentUrl; doc.context = remoteContext.document; } Stream stream = resp.GetResponseStream(); doc.DocumentUrl = req.Address.ToString(); doc.Document = JSONUtils.FromInputStream(stream); } catch (JsonLdError) { throw; } catch (Exception) { throw new JsonLdError(JsonLdError.Error.LoadingDocumentFailed, url); } return(doc); #else throw new PlatformNotSupportedException(); #endif }
/// <exception cref="JsonLDNet.Core.JsonLdError"></exception> public virtual RemoteDocument LoadDocument(string url) { #if !PORTABLE && !IS_CORECLR RemoteDocument doc = new RemoteDocument(url, null); HttpWebResponse resp; try { HttpWebRequest req = (HttpWebRequest)HttpWebRequest.Create(url); req.Accept = AcceptHeader; resp = (HttpWebResponse)req.GetResponse(); bool isJsonld = resp.Headers[HttpResponseHeader.ContentType] == "application/ld+json"; if (!resp.Headers[HttpResponseHeader.ContentType].Contains("json")) { throw new JsonLdError(JsonLdError.Error.LoadingDocumentFailed, url); } string[] linkHeaders = resp.Headers.GetValues("Link"); if (!isJsonld && linkHeaders != null) { linkHeaders = linkHeaders.SelectMany((h) => h.Split(",".ToCharArray())) .Select(h => h.Trim()).ToArray(); IEnumerable <string> linkedContexts = linkHeaders.Where(v => v.EndsWith("rel=\"http://www.w3.org/ns/json-ld#context\"")); if (linkedContexts.Count() > 1) { throw new JsonLdError(JsonLdError.Error.MultipleContextLinkHeaders); } string header = linkedContexts.First(); string linkedUrl = header.Substring(1, header.IndexOf(">") - 1); string resolvedUrl = URL.Resolve(url, linkedUrl); var remoteContext = this.LoadDocument(resolvedUrl); doc.contextUrl = remoteContext.documentUrl; doc.context = remoteContext.document; } Stream stream = resp.GetResponseStream(); doc.DocumentUrl = req.Address.ToString(); doc.Document = JSONUtils.FromInputStream(stream); } catch (JsonLdError) { throw; } catch (WebException webException) { try { resp = (HttpWebResponse)webException.Response; int baseStatusCode = (int)(Math.Floor((double)resp.StatusCode / 100)) * 100; if (baseStatusCode == 300) { string location = resp.Headers[HttpResponseHeader.Location]; if (!string.IsNullOrWhiteSpace(location)) { // TODO: Add recursion break or simply switch to HttpClient so we don't have to recurse on HTTP redirects. return(LoadDocument(location)); } } } catch (Exception innerException) { throw new JsonLdError(JsonLdError.Error.LoadingDocumentFailed, url, innerException); } throw new JsonLdError(JsonLdError.Error.LoadingDocumentFailed, url, webException); } catch (Exception exception) { throw new JsonLdError(JsonLdError.Error.LoadingDocumentFailed, url, exception); } return(doc); #else throw new PlatformNotSupportedException(); #endif }
/// <exception cref="JsonLD.Core.JsonLdError"></exception> public static JArray Expand(JToken input, JsonLdOptions opts) { // 1) // TODO: look into java futures/promises // 2) verification of DOMString IRI bool isIriString = input.Type == JTokenType.String; if (isIriString) { bool hasColon = false; foreach (var c in ((string)input)) { if (c == ':') { hasColon = true; } if (!hasColon && (c == '{' || c == '[')) { isIriString = false; break; } } } if (isIriString) { try { RemoteDocument tmp = opts.documentLoader.LoadDocument((string)input); input = tmp.document; } catch (Exception e) { // TODO: figure out how to deal with remote context throw new JsonLdError(JsonLdError.Error.LoadingDocumentFailed, e.Message); } // if set the base in options should override the base iri in the // active context // thus only set this as the base iri if it's not already set in // options if (opts.GetBase() == null) { opts.SetBase((string)input); } } // 3) Context activeCtx = new Context(opts); // 4) if (opts.GetExpandContext() != null) { JObject exCtx = opts.GetExpandContext(); if (exCtx is JObject && ((IDictionary <string, JToken>)exCtx).ContainsKey("@context" )) { exCtx = (JObject)((IDictionary <string, JToken>)exCtx)["@context"]; } activeCtx = activeCtx.Parse(exCtx); } // 5) // TODO: add support for getting a context from HTTP when content-type // is set to a jsonld compatable format // 6) JToken expanded = new JsonLdApi(opts).Expand(activeCtx, input); // final step of Expansion Algorithm if (expanded is JObject && ((IDictionary <string, JToken>)expanded).ContainsKey("@graph") && ( (IDictionary <string, JToken>)expanded).Count == 1) { expanded = ((JObject)expanded)["@graph"]; } else { if (expanded.IsNull()) { expanded = new JArray(); } } // normalize to an array if (!(expanded is JArray)) { JArray tmp = new JArray(); tmp.Add(expanded); expanded = tmp; } return((JArray)expanded); }