/// <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
        }
Exemple #5
0
        /// <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
        }
Exemple #6
0
        /// <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);
        }