コード例 #1
0
        public void ExpressionTest_False()
        {
            var isExpression = ExpressionParserUtilities.IsExpression("~Sample Value", out string expression);

            Assert.False(isExpression);
            Assert.Equal("", expression);
        }
コード例 #2
0
        public void ExpressionTest_True()
        {
            var isExpression = ExpressionParserUtilities.IsExpression("~(func(\"Sample Value\"))", out string expression);

            Assert.True(isExpression);
            Assert.Equal("func(\"Sample Value\")", expression);
        }
コード例 #3
0
        public void ExpressionTest_EmptyExpression_True()
        {
            var isExpression = ExpressionParserUtilities.IsExpression("~()", out string expression);

            Assert.True(isExpression);
            Assert.Equal("", expression);
        }
コード例 #4
0
ファイル: JsonTransformer.cs プロジェクト: simplic/JUST.net
        private void RecursiveEvaluate(JToken parentToken, string inputJson, JArray parentArray, JToken currentArrayToken)
        {
            if (parentToken == null)
            {
                return;
            }

            JEnumerable <JToken> tokens = parentToken.Children();

            List <JToken> selectedTokens = null;
            Dictionary <string, JToken> tokensToReplace = null;
            List <JToken> tokensToDelete = null;

            List <string> loopProperties = null;
            JArray        arrayToForm    = null;
            List <JToken> tokenToForm    = null;
            List <JToken> tokensToAdd    = null;

            bool isLoop = false;

            foreach (JToken childToken in tokens)
            {
                if (childToken.Type == JTokenType.Array && (parentToken as JProperty).Name.Trim() != "#")
                {
                    JArray arrayToken = childToken as JArray;

                    List <object> itemsToAdd = new List <object>();

                    foreach (JToken arrEl in childToken.Children())
                    {
                        object itemToAdd = arrEl.Value <JToken>();

                        if (arrEl.Type == JTokenType.String && arrEl.ToString().Trim().StartsWith("#"))
                        {
                            object value = ParseFunction(arrEl.ToString(), inputJson, parentArray, currentArrayToken);
                            itemToAdd = value;
                        }

                        itemsToAdd.Add(itemToAdd);
                    }

                    arrayToken.RemoveAll();

                    foreach (object itemToAdd in itemsToAdd)
                    {
                        arrayToken.Add(itemToAdd);
                    }
                }

                if (childToken.Type == JTokenType.Property)
                {
                    JProperty property = childToken as JProperty;

                    if (property.Name != null && property.Name == "#" && property.Value.Type == JTokenType.Array)
                    {
                        JArray values = property.Value as JArray;

                        JEnumerable <JToken> arrayValues = values.Children();

                        foreach (JToken arrayValue in arrayValues)
                        {
                            if (arrayValue.Type == JTokenType.String && arrayValue.Value <string>().Trim().StartsWith("#copy"))
                            {
                                if (selectedTokens == null)
                                {
                                    selectedTokens = new List <JToken>();
                                }

                                selectedTokens.Add(Copy(arrayValue.Value <string>(), inputJson));
                            }

                            if (arrayValue.Type == JTokenType.String && arrayValue.Value <string>().Trim().StartsWith("#replace"))
                            {
                                if (tokensToReplace == null)
                                {
                                    tokensToReplace = new Dictionary <string, JToken>();
                                }
                                string value = arrayValue.Value <string>();

                                tokensToReplace.Add(GetTokenStringToReplace(value), Replace(value, inputJson));
                            }

                            if (arrayValue.Type == JTokenType.String && arrayValue.Value <string>().Trim().StartsWith("#delete"))
                            {
                                if (tokensToDelete == null)
                                {
                                    tokensToDelete = new List <JToken>();
                                }

                                tokensToDelete.Add(Delete(arrayValue.Value <string>()));
                            }
                        }
                    }

                    if (ExpressionParserUtilities.IsExpression(property.Value.ToString().Trim(), out string expression))
                    {
                        expressionInterpreter.SetContext(currentArrayToken, parentArray, expression);

                        try
                        {
                            var result = expressionInterpreter.Eval(expression);
                            property.Value = new JValue(result);
                        }
                        catch (PathNotFoundException ex)
                        {
                            throw;
                        }
                        catch (Exception ex)
                        {
                            throw new Exception($"Could not execute expression: {expression}. Property: {property}.", ex);
                        }
                    }

                    // TODO: Not required anymore
                    // if (property.Name != null && property.Value.ToString().Trim().StartsWith("#")
                    //     && !property.Name.Contains("#eval") && !property.Name.Contains("#ifgroup")
                    //     && !property.Name.Contains("#loop"))
                    // {
                    //     object newValue = ParseFunction(property.Value.ToString(), inputJson, parentArray, currentArrayToken);
                    //
                    //     if (newValue != null && newValue.ToString().Contains("\""))
                    //     {
                    //         try
                    //         {
                    //             JToken newToken = JToken.Parse(newValue.ToString());
                    //             property.Value = newToken;
                    //         }
                    //         catch
                    //         {
                    //             property.Value = new JValue(newValue);
                    //         }
                    //     }
                    //     else
                    //         property.Value = new JValue(newValue);
                    // }

                    /* For looping*/
                    isLoop = false;

                    if (property.Name != null && property.Name.Contains("#eval"))
                    {
                        int startIndex = property.Name.IndexOf("(");
                        int endIndex   = property.Name.LastIndexOf(")");

                        string functionString = property.Name.Substring(startIndex + 1, endIndex - startIndex - 1);

                        object functionResult = ParseFunction(functionString, inputJson, null, null);

                        JProperty clonedProperty = new JProperty(functionResult.ToString(), property.Value);

                        if (loopProperties == null)
                        {
                            loopProperties = new List <string>();
                        }

                        loopProperties.Add(property.Name);

                        if (tokensToAdd == null)
                        {
                            tokensToAdd = new List <JToken>
                            {
                                clonedProperty
                            };
                        }
                    }

                    if (property.Name != null && property.Name.Contains("#ifgroup"))
                    {
                        int startIndex = property.Name.IndexOf("(");
                        int endIndex   = property.Name.LastIndexOf(")");

                        string functionString = property.Name.Substring(startIndex + 1, endIndex - startIndex - 1);

                        object functionResult = ParseFunction(functionString, inputJson, null, null);
                        bool   result         = false;

                        try
                        {
                            result = Convert.ToBoolean(functionResult);
                        }
                        catch
                        {
                            result = false;
                        }



                        if (result == true)
                        {
                            if (loopProperties == null)
                            {
                                loopProperties = new List <string>();
                            }

                            loopProperties.Add(property.Name);

                            RecursiveEvaluate(childToken, inputJson, parentArray, currentArrayToken);

                            if (tokenToForm == null)
                            {
                                tokenToForm = new List <JToken>();
                            }

                            foreach (JToken grandChildToken in childToken.Children())
                            {
                                tokenToForm.Add(grandChildToken.DeepClone());
                            }
                        }
                        else
                        {
                            if (loopProperties == null)
                            {
                                loopProperties = new List <string>();
                            }

                            loopProperties.Add(property.Name);
                        }

                        isLoop = true;
                    }

                    if (property.Name != null && property.Name.Contains("#loop"))
                    {
                        string strArrayToken = property.Name.Substring(6, property.Name.Length - 7);

                        JsonReader reader = null;
                        if (currentArrayToken != null && property.Name.Contains("#loopwithincontext"))
                        {
                            strArrayToken = property.Name.Substring(19, property.Name.Length - 20);
                            reader        = new JsonTextReader(new StringReader(JsonConvert.SerializeObject(currentArrayToken)));
                        }
                        else
                        {
                            reader = new JsonTextReader(new StringReader(inputJson));
                        }
                        reader.DateParseHandling = DateParseHandling.None;
                        JToken token      = JObject.Load(reader);
                        JToken arrayToken = null;

                        if (strArrayToken.Contains("#") && !strArrayToken.Trim().StartsWith("#"))
                        {
                            int    sIndex = strArrayToken.IndexOf("#");
                            string sub1   = strArrayToken.Substring(0, sIndex);

                            int indexOfEndFunction = GetIndexOfFunctionEnd(strArrayToken);

                            if (indexOfEndFunction > sIndex && sIndex > 0)
                            {
                                string sub2 = strArrayToken.Substring(indexOfEndFunction + 1, strArrayToken.Length - indexOfEndFunction - 1);

                                string functionResult = ParseFunction(strArrayToken.Substring(sIndex, indexOfEndFunction - sIndex + 1), inputJson, parentArray, currentArrayToken).ToString();

                                strArrayToken = sub1 + functionResult + sub2;
                            }
                        }

                        if (strArrayToken.Trim().StartsWith("#"))
                        {
                            arrayToken = ParseFunction(strArrayToken, inputJson, parentArray, currentArrayToken) as JArray;
                        }

                        if (arrayToken == null)
                        {
                            try
                            {
                                arrayToken = token.SelectToken(strArrayToken);

                                if (arrayToken is JObject)
                                {
                                    arrayToken = new JArray(arrayToken);
                                }
                            }
                            catch
                            {
                                var multipleTokens = token.SelectTokens(strArrayToken);

                                arrayToken = new JArray(multipleTokens);
                            }
                        }

                        if (arrayToken == null)
                        {
                            arrayToForm = new JArray();
                        }
                        else
                        {
                            JArray array = (JArray)arrayToken;

                            IEnumerator <JToken> elements = array.GetEnumerator();



                            while (elements.MoveNext())
                            {
                                if (arrayToForm == null)
                                {
                                    arrayToForm = new JArray();
                                }

                                JToken clonedToken = childToken.DeepClone();

                                RecursiveEvaluate(clonedToken, inputJson, array, elements.Current);

                                foreach (JToken replacedProperty in clonedToken.Children())
                                {
                                    arrayToForm.Add(replacedProperty);
                                }
                            }
                        }
                        if (loopProperties == null)
                        {
                            loopProperties = new List <string>();
                        }

                        loopProperties.Add(property.Name);
                        isLoop = true;
                    }
                    /*End looping */
                }

                if (childToken.Type == JTokenType.String && childToken.Value <string>().Trim().StartsWith("#") &&
                    parentArray != null && currentArrayToken != null)
                {
                    object newValue = ParseFunction(childToken.Value <string>(), inputJson, parentArray, currentArrayToken);

                    if (newValue != null && newValue.ToString().Contains("\""))
                    {
                        try
                        {
                            JToken newToken = JToken.Parse(newValue.ToString());
                            childToken.Replace(new JValue(newValue));
                        }
                        catch
                        {
                        }
                    }
                    else
                    {
                        childToken.Replace(new JValue(newValue));
                    }
                }

                if (!isLoop)
                {
                    RecursiveEvaluate(childToken, inputJson, parentArray, currentArrayToken);
                }
            }


            if (selectedTokens != null)
            {
                foreach (JToken selectedToken in selectedTokens)
                {
                    if (selectedToken != null)
                    {
                        JEnumerable <JToken> copyChildren = selectedToken.Children();

                        foreach (JToken copyChild in copyChildren)
                        {
                            JProperty property = copyChild as JProperty;

                            (parentToken as JObject).Add(property.Name, property.Value);
                        }
                    }
                }
            }

            if (tokensToReplace != null)
            {
                foreach (KeyValuePair <string, JToken> tokenToReplace in tokensToReplace)
                {
                    JToken selectedToken = (parentToken as JObject).SelectToken(tokenToReplace.Key);

                    if (selectedToken != null && selectedToken is JObject)
                    {
                        JObject selectedObject = selectedToken as JObject;
                        selectedObject.RemoveAll();


                        JEnumerable <JToken> copyChildren = tokenToReplace.Value.Children();

                        foreach (JToken copyChild in copyChildren)
                        {
                            JProperty property = copyChild as JProperty;

                            selectedObject.Add(property.Name, property.Value);
                        }
                    }
                    if (selectedToken != null && selectedToken is JValue)
                    {
                        JValue selectedObject = selectedToken as JValue;

                        selectedObject.Value = tokenToReplace.Value.ToString();
                    }
                }
            }

            if (tokensToDelete != null)
            {
                foreach (string selectedToken in tokensToDelete)
                {
                    JToken tokenToRemove = parentToken.SelectToken(selectedToken);

                    if (tokenToRemove != null)
                    {
                        tokenToRemove.Ancestors().First().Remove();
                    }
                }
            }
            if (tokensToAdd != null)
            {
                foreach (JToken token in tokensToAdd)
                {
                    (parentToken as JObject).Add((token as JProperty).Name, (token as JProperty).Value);
                }
            }
            if (tokenToForm != null)
            {
                foreach (JToken token in tokenToForm)
                {
                    foreach (JProperty childToken in token.Children())
                    {
                        (parentToken as JObject).Add(childToken.Name, childToken.Value);
                    }
                }
            }
            if (parentToken is JObject)
            {
                (parentToken as JObject).Remove("#");
            }

            if (loopProperties != null)
            {
                foreach (string propertyToDelete in loopProperties)
                {
                    (parentToken as JObject).Remove(propertyToDelete);
                }
            }
            if (arrayToForm != null)
            {
                parentToken.Replace(arrayToForm);
            }
        }