示例#1
0
        static ScimExpressionParser()
        {
            CaseInsensitiveString = from content in QuotedString
                                    select ScimExpression.String(content);


            IdentifierName = Parse.Identifier(Parse.Letter, Parse.LetterOrDigit);

            //compValue = false / null / true / number / string
            //; rules from JSON(RFC 7159)
            Literal = Parse.String("true").Return(ScimExpression.Constant(true))
                      .XOr(Parse.String("false").Return(ScimExpression.Constant(false)))
                      .XOr(Parse.String("null").Return(ScimExpression.Constant(null)));

            //ATTRNAME = ALPHA * (nameChar)
            //nameChar = "-" / "_" / DIGIT / ALPHA
            // TODO : check - and _
            AttrName = IdentifierName.Select(ScimExpression.Attribute);

            //valuePath = attrPath "[" valFilter "]"
            //    ; FILTER uses sub - attributes of a parent attrPath
            ValuePath = from open in Parse.Char('[')
                        from expr in Parse.Ref(() => Filter)
                        from close in Parse.Char(']')
                        select new Func <ScimExpression, ScimExpression>(r => ScimExpression.Binary("Where", r, expr));

            //subAttr = "." ATTRNAME
            //; a sub-attribute of a complex attribute
            SubAttr = Parse.Char('.')
                      .Then(_ => IdentifierName)
                      .Then(n => Parse.Return(new Func <ScimExpression, ScimExpression>(r => ScimExpression.SubAttribute(n, r))));

            //attrPath = [URI ":"] ATTRNAME * 1subAttr
            //     ; SCIM attribute name
            //     ; URI is SCIM "schema" URI
            AttrPath = AttrName
                       .SelectMany(root => SubAttr.XOr(ValuePath).XMany(), (name, path) => path.Aggregate(name, (o, f) => f(o)));

            Operand = (ExpressionInParentheses
                       .XOr(Literal.Or(AttrPath.Token()))
                       .XOr(CaseInsensitiveString)).Token();

            // compareOp = "eq" / "ne" / "co" /
            //        "sw" / "ew" /
            //        "gt" / "lt" /
            //        "ge" / "le"
            Comparison = Parse.XChainOperator(Le.Or(Lt).XOr(Ge.Or(Gt)).XOr(Eq.Or(Ne)).XOr(Sw.Or(Ew)).XOr(Co).XOr(Pr), Operand, ScimExpression.Binary);

            // attrPath SP "pr"
            Presence = Operand.SelectMany(operand => Pr, (operand, pr) => ScimExpression.Unary(pr, operand));

            // attrExp = (attrPath SP "pr") /
            //   (attrPath SP compareOp SP compValue)
            AttributeExpression = Presence.Or(Comparison);

            // logExp    = FILTER SP ("and" / "or") SP FILTER
            LogicalExpression = Parse.XChainOperator(Or.Or(And), AttributeExpression, ScimExpression.Binary);
            Filter            = LogicalExpression;
        }
        private Expression <Func <TResource, bool> > BuildExpression <TResource>(ScimExpression filter, IAttributeNameMapper mapper, string prefix)
        {
            var callExpression = filter as ScimCallExpression;

            if (callExpression != null && (callExpression.OperatorName == "And" || callExpression.OperatorName == "Or"))
            {
                return(this.BindLogicalExpression <TResource>(callExpression, mapper, prefix));
            }

            if (callExpression != null && (callExpression.OperatorName != "And" || callExpression.OperatorName != "Or"))
            {
                return(this.BindAttributeExpression <TResource>(callExpression, mapper));
            }

            throw new InvalidOperationException("Unknown node type");
        }
 public Expression <Func <TResource, bool> > Bind <TResource>(ScimExpression filter, string sortBy, bool ascending, IAttributeNameMapper mapper = null)
 {
     return(this.BuildExpression <TResource>(filter, mapper, null));
 }
 public static ScimExpression SubAttribute(string name, ScimExpression parent)
 {
     return(new ScimSubAttributeExpression(name, parent));
 }
 public static ScimExpression Unary(string opName, ScimExpression operand)
 {
     return(new ScimCallExpression(opName, operand));
 }
 public static ScimExpression Binary(string opName, ScimExpression leftOperand, ScimExpression rightOperand)
 {
     return(new ScimCallExpression(opName, leftOperand, rightOperand));
 }