private static void CollectLanguageLocalizations(string language, JArray routes, string parentPath)
        {
            localizations.TryGetValue(language, out var locs);
            normalizations.TryGetValue(language, out var norms);
            components.TryGetValue(language, out var comps);

            foreach (JObject route in routes.Children())
            {
                var path = JsonHelper.GetTokenValue <string>(route, "path");
                if (!string.IsNullOrEmpty(path))
                {
                    var fullPath = StringHelper.AddToString(parentPath, "/", path);

                    var component = JsonHelper.GetTokenValue <string>(route, "component");
                    if (!string.IsNullOrEmpty(component))
                    {
                        comps[fullPath] = component;
                    }

                    var localize  = JsonHelper.GetTokenValue <JObject>(route, "_localize") ?? new JObject();
                    var localized = JsonHelper.GetTokenValue <string>(localize, language) ?? path;
                    AddLocalizations(locs, path, localized);
                    AddLocalizations(norms, localized, path);
                    var children = route["children"] as JArray;
                    if (children != null)
                    {
                        CollectLanguageLocalizations(language, children, fullPath);
                    }
                }
            }
        }
        protected object AddByKey(JObject translations, string key, out JToken parent, out string parentKey, out string subKey)
        {
            var    ks = key.Split(keyPartDelimiterSplitter).ToList();
            object o  = null;

            parent    = translations;
            parentKey = string.Empty;
            subKey    = key;

            while (o == null && parent != null && ks.Count > 1)
            {
                var k = ks[0];
                parentKey = StringHelper.AddToString(parentKey, keyPartDelimiter, k);
                ks.RemoveAt(0);
                var node = JsonHelper.GetTokenValue <JObject>(parent, k, true);
                if (node == null)
                {
                    node = new JObject();
                    (parent as JObject).Add(k.ToLowerCamelCase(), node);
                }

                parent = node;
                subKey = string.Join(keyPartDelimiter, ks);
                o      = parent != null?JsonHelper.GetTokenValue <object>(parent, subKey, true) : null;
            }

            if (o == null)
            {
                parentKey = string.Empty;
            }

            return(o);
        }
        protected object FindByKey(JObject translations, string key, out JToken parent, out string parentKey, out string subKey)
        {
            var    ks = key.Split(keyPartDelimiterSplitter).ToList();
            object o  = null;

            parent    = translations;
            parentKey = string.Empty;
            subKey    = key;

            // search in common
            if (ks.Count == 1)
            {
                // search in common
                o      = JsonHelper.GetTokenValue <object>(translations[commonKey], ks[0], true);
                parent = translations[commonKey];
                subKey = ks[0];
            }

            // search by name space
            while (o == null && parent != null && ks.Count > 0)
            {
                var k = ks[0];
                parentKey = StringHelper.AddToString(parentKey, keyPartDelimiter, k);
                ks.RemoveAt(0);
                parent = JsonHelper.GetTokenValue <JToken>(parent, k, true);
                subKey = string.Join(keyPartDelimiter, ks);
                o      = parent != null?JsonHelper.GetTokenValue <object>(parent, subKey, true) : null;
            }

            if (o == null)
            {
                parentKey = string.Empty;
            }

            // search by full (multi-part) key
            if (o == null && key.Contains(keyPartDelimiter))
            {
                o      = JsonHelper.GetTokenValue <object>(translations, key, true);
                parent = translations;
                subKey = key;
            }

            return(o);
        }
        private bool ExistsKey(JObject translations, string key)
        {
            var    ks        = key.Split(keyPartDelimiterSplitter).ToList();
            object o         = null;
            JToken parent    = translations;
            var    parentKey = string.Empty;

            while (o == null && parent != null && ks.Count > 0)
            {
                var k = ks[0];
                parentKey = StringHelper.AddToString(parentKey, keyPartDelimiter, k);
                ks.RemoveAt(0);
                parent = JsonHelper.GetTokenValue <JToken>(parent, k, true);
                var subKey = string.Join(keyPartDelimiter, ks);
                o = parent != null?JsonHelper.GetTokenValue <object>(parent, subKey, true) : null;
            }

            return(o != null);
        }
 public static R GetTokenValue <R>(this JToken parent, string key, bool ignoreCase = false)
 {
     return(JsonHelper.GetTokenValue <R>(parent, key, ignoreCase));
 }