private void ProcessField() { if (!_parseRuleStack.Any()) { _parseRuleStack.Push(new DefaultExpressionTokens()); } var fieldName = _context.GetToken(new[] { Delimiters.DOLLAR }, new[] { Delimiters.WHITE_SPACE }).Item1; if (_supportedFields != null && _supportedFields.All(s => s != fieldName)) { var errorMessage = $"Unsupported Fields, Value : {fieldName}, SupportedFields : {string.Join(",", _supportedFields)}, ParserState : {_context.GetProcessedString()}"; SetState(new ErrorParserState { ErrorMessage = errorMessage }); return; } _availableFields.Add(fieldName); _currentExpressionToken = new ConditionExpressionToken { FieldName = fieldName }; SetState(new LogicalOperatorParserState()); }
private void PushToExpressionStack() { var token = _parseRuleStack.Peek(); _currentExpressionToken.PreviousToken = token.Tokens.LastOrDefault(); token.Tokens.Add(_currentExpressionToken); _currentExpressionToken = null; SetState(new BinaryOperatorParserState()); }
private ExpressionBuilder <K> BuildExpression(ConditionExpressionToken token, ExpressionBuilder <K> builder) { if (token.PreviousToken == null) { return(BuildLogicalExpression(builder, BinaryOperator.NONE, token)); } var prevBinaryToken = token.PreviousToken as BinaryExpressionToken; if (prevBinaryToken == null) { throw new Exception(); } switch (prevBinaryToken.Operator) { case BinaryOperatorType.AND: return(BuildLogicalExpression(builder, BinaryOperator.AND, token)); case BinaryOperatorType.OR: return(BuildLogicalExpression(builder, BinaryOperator.OR, token)); default: throw new ArgumentException($"Binary operator '{prevBinaryToken.Operator}' not supported"); } }
private void ProcessOperandArray() { if (new[] { LogicalOperatorType.IN, LogicalOperatorType.NI }.All(s => s != _currentExpressionToken.Operator)) { var errorMessage = $"Invalid Field Value for Logical Operator, Operator : {_currentExpressionToken.Operator}, " + $"ParserState : {_context.GetProcessedString()}"; SetState(new ErrorParserState { ErrorMessage = errorMessage }); return; } var token = _context.GetToken(new[] { Delimiters.OPEN_BRACE }, new[] { Delimiters.CLOSE_BRACE }).Item1; var subTokens = token.Split(new[] { ",", " " }, StringSplitOptions.RemoveEmptyEntries); if (!subTokens.Any()) { var errorMessage = $"Set cannot be Empty. It should contain atleast one Field Value, ParserState : {_context.GetProcessedString()}"; SetState(new ErrorParserState { ErrorMessage = errorMessage }); return; } if (!_parseRuleStack.Any()) { _parseRuleStack.Push(new DefaultExpressionTokens()); } var tExpressionTokens = new DefaultExpressionTokens(); for (int i = 0; i < subTokens.Length; i++) { var subToken = subTokens[i]; var tToken = new ConditionExpressionToken { FieldName = _currentExpressionToken.FieldName, Operator = _currentExpressionToken.Operator == LogicalOperatorType.IN ? LogicalOperatorType.EQ : LogicalOperatorType.NE, PreviousToken = tExpressionTokens.Tokens.LastOrDefault() }; if (subToken.StartsWith("'")) { tToken.Operand = subToken.Trim('\''); } else if (subToken.Equals("null", StringComparison.CurrentCultureIgnoreCase)) { tToken.Operand = null; } else { var errorMessage = $"Invalid Field Value, Value : {subToken}, ParserState : {_context.GetProcessedString()}"; SetState(new ErrorParserState { ErrorMessage = errorMessage }); return; } tExpressionTokens.Tokens.Add(tToken); if (i < subTokens.Length - 1) { tExpressionTokens.Tokens.Add(new BinaryExpressionToken { Operator = _currentExpressionToken.Operator == LogicalOperatorType.IN ? BinaryOperatorType.OR : BinaryOperatorType.AND, PreviousToken = tToken }); } } _currentExpressionToken = null; var previousToken = _parseRuleStack.Peek(); tExpressionTokens.PreviousToken = previousToken.Tokens.LastOrDefault(); previousToken.Tokens.Add(tExpressionTokens); SetState(new BinaryOperatorParserState()); }
private ExpressionBuilder <K> BuildLogicalExpression(ExpressionBuilder <K> builder, BinaryOperator binaryOperator, ConditionExpressionToken token) { if (_supportedFields != null && _supportedFields.All(s => s != token.FieldName)) { throw new ArgumentException($"Field not supported, FieldName : {token.FieldName}, SupportedFields : {string.Join(",", _supportedFields)}"); } var transformedFieldName = TransformFieldName(token.FieldName); var transformedFieldValue = token.Operand; if (transformedFieldValue != null) { transformedFieldValue = TransformFieldValue(token.FieldName, transformedFieldValue); } Func <string, string, Tuple <ExpressionBuilder <K>, string> > buildExpression = (fieldName, fieldValue) => { try { switch (token.Operator) { case LogicalOperatorType.EQ: return(builder.BuildEqualToExpression(binaryOperator, fieldName, fieldValue)); case LogicalOperatorType.GE: return(builder.BuildGreaterThanOrEqualToExpression(binaryOperator, fieldName, fieldValue)); case LogicalOperatorType.LE: return(builder.BuildLessThanOrEqualToExpression(binaryOperator, fieldName, fieldValue)); case LogicalOperatorType.GT: return(builder.BuildGreaterThanExpression(binaryOperator, fieldName, fieldValue)); case LogicalOperatorType.LT: return(builder.BuildLesserThanExpression(binaryOperator, fieldName, fieldValue)); case LogicalOperatorType.NE: return(builder.BuildNotEqualToExpression(binaryOperator, fieldName, fieldValue)); case LogicalOperatorType.CN: return(builder.BuildContainsExpression(binaryOperator, fieldName, fieldValue)); case LogicalOperatorType.SW: return(builder.BuildStartsWithExpression(binaryOperator, fieldName, fieldValue)); case LogicalOperatorType.EW: return(builder.BuildEndsWithExpression(binaryOperator, fieldName, fieldValue)); } } catch (Exception) { throw new ArgumentException($"Invalid field value, Operator : {token.Operator}, " + $"FieldName : {fieldName}, " + $"FieldValue : {fieldValue ?? string.Empty}"); } throw new ArgumentException($"Operator not supported, Operator : {token.Operator}"); }; var expression = buildExpression(transformedFieldName, transformedFieldValue); if (!string.IsNullOrEmpty(expression.Item2)) { throw new ArgumentException(expression.Item2); } return(expression.Item1); }