<commit_before>﻿using System;
using System.Collections.Generic;
using System.Reflection;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;

namespace LtiLibrary.Core.Common
{
    /// <summary>
    /// Serialize a JsonLdObject to JSON representation.
    /// </summary>
    /// <remarks>
    /// Collects JsonLdObject Terms and writes them first as @context.
    /// Does not convert JSON to a JsonLdObject.
    /// </remarks>
    public class JsonLdObjectConverter : JsonConverter
    {
        private static readonly Type JsonLdObjectType = typeof(IJsonLdObject);
        private static readonly Type JsonLdObjectArrayType = typeof (IEnumerable<IJsonLdObject>);

        public override bool CanRead
        {
            get { return false; }
        }

        public override bool CanWrite
        {
            get { return true; }
        }

        /// <summary>
        /// Writes the JSON representation of the object.
        /// </summary>
        /// <param name="writer">The Newtonsoft.Json.JsonWriter to write to.</param>
        /// <param name="value">The value.</param>
        /// <param name="serializer">The calling serializer.</param>
        public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
        {
            // Collect the external contexts. Note that the last one wins.
            // See http://www.w3.org/TR/json-ld/#advanced-context-usage
            Uri externalContextId = null;
            if (JsonLdObjectType.IsInstanceOfType(value))
            {
                var obj = (IJsonLdObject) value;
                externalContextId = GetExternalContextId(obj);
            }

            // Collect the local terms
            IDictionary<string, string> terms = null;
            if (JsonLdObjectType.IsInstanceOfType(value))
            {
                var obj = (IJsonLdObject) value;
                terms = GetTerms(obj);
            }

            // Use a new contract resolver to parse the object so that this
            // version of WriteJson is not called recursively
            serializer.ContractResolver = new JsonLdObjectContractResolver(true);
            serializer.DateFormatHandling = DateFormatHandling.IsoDateFormat;
            serializer.NullValueHandling = NullValueHandling.Ignore;
            var o = JObject.FromObject(value, serializer);

            // Add the @context and write the JSON representation.
            // If there is only an external context, add a simple JProperty.
            if (externalContextId != null && (terms == null || terms.Count == 0))
            {
                JToken context;
                if (!o.TryGetValue("@context", StringComparison.InvariantCulture, out context))
                {
                    o.AddFirst(new JProperty("@context", externalContextId));
                }
                o["@context"] = externalContextId;
            }
            // If there are only terms, add a JObject with each term as a JProperty
            else if (externalContextId == null && terms != null && terms.Count > 0)
            {
                var termsObject = new JObject();
                foreach (var key in terms.Keys)
                {
                    termsObject.Add(new JProperty(key, terms[key]));
                }
                o.AddFirst(new JProperty("@context", termsObject));
            }<commit_msg>Add @context without scanning entire JObject.<commit_after>﻿using System;
using System.Collections.Generic;
using System.Reflection;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;

namespace LtiLibrary.Core.Common
{
    /// <summary>
    /// Serialize a JsonLdObject to JSON representation.
    /// </summary>
    /// <remarks>
    /// Collects JsonLdObject Terms and writes them first as @context.
    /// Does not convert JSON to a JsonLdObject.
    /// </remarks>
    public class JsonLdObjectConverter : JsonConverter
    {
        private static readonly Type JsonLdObjectType = typeof(IJsonLdObject);
        private static readonly Type JsonLdObjectArrayType = typeof (IEnumerable<IJsonLdObject>);

        public override bool CanRead
        {
            get { return false; }
        }

        public override bool CanWrite
        {
            get { return true; }
        }

        /// <summary>
        /// Writes the JSON representation of the object.
        /// </summary>
        /// <param name="writer">The Newtonsoft.Json.JsonWriter to write to.</param>
        /// <param name="value">The value.</param>
        /// <param name="serializer">The calling serializer.</param>
        public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
        {
            // Collect the external contexts. Note that the last one wins.
            // See http://www.w3.org/TR/json-ld/#advanced-context-usage
            Uri externalContextId = null;
            if (JsonLdObjectType.IsInstanceOfType(value))
            {
                var obj = (IJsonLdObject) value;
                externalContextId = GetExternalContextId(obj);
            }

            // Collect the local terms
            IDictionary<string, string> terms = null;
            if (JsonLdObjectType.IsInstanceOfType(value))
            {
                var obj = (IJsonLdObject) value;
                terms = GetTerms(obj);
            }

            // Use a new contract resolver to parse the object so that this
            // version of WriteJson is not called recursively
            serializer.ContractResolver = new JsonLdObjectContractResolver(true);
            serializer.DateFormatHandling = DateFormatHandling.IsoDateFormat;
            serializer.NullValueHandling = NullValueHandling.Ignore;
            var o = JObject.FromObject(value, serializer);

            // Add the @context and write the JSON representation.
            // If there is only an external context, add a simple JProperty.
            if (externalContextId != null && (terms == null || terms.Count == 0))
            {
                if (!o.HasValues || o.First.Type != JTokenType.Property || !((JProperty) o.First).Name.Equals("@context"))
                {
                    o.AddFirst(new JProperty("@context", externalContextId));
                }
                o["@context"] = externalContextId;
            }
            // If there are only terms, add a JObject with each term as a JProperty
            else if (externalContextId == null && terms != null && terms.Count > 0)
            {
                var termsObject = new JObject();
                foreach (var key in terms.Keys)
                {
                    termsObject.Add(new JProperty(key, terms[key]));
                }
                o.AddFirst(new JProperty("@context", termsObject));
            }
{'fraction_non_alphanumeric': 0.0952029520295203, 'fraction_numerical': 0.0008856088560885609, 'mean_word_length': 1.8470588235294119, 'pattern_counts': {'":': 0, '<': 31, '<?xml version=': 0, '>': 33, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '245834', 'n_tokens_mistral': 1714, 'n_tokens_neox': 1662, 'n_words': 492}