Пример #1
0
        private ISparqlPath TryParsePathSequence(SparqlQueryParserContext context, Queue <IToken> tokens)
        {
            ISparqlPath path = TryParsePathEltOrInverse(context, tokens);
            IToken      next;

            while (tokens.Count > 0)
            {
                next = tokens.Peek();
                switch (next.TokenType)
                {
                case Token.DIVIDE:
                    tokens.Dequeue();
                    path = new SequencePath(path, TryParsePathEltOrInverse(context, tokens));
                    break;

                case Token.HAT:
                    tokens.Dequeue();
                    path = new SequencePath(path, new InversePath(TryParsePathElt(context, tokens)));
                    break;

                default:
                    return(path);
                }
            }

            return(path);
        }
Пример #2
0
        private Property TryParsePathOneInPropertySet(SparqlQueryParserContext context, Queue <IToken> tokens, out bool inverse)
        {
            IToken next = tokens.Dequeue();

            inverse = false;
            switch (next.TokenType)
            {
            case Token.URI:
            case Token.QNAME:
                return(new Property(new UriNode(null, UriFactory.Create(Tools.ResolveUriOrQName(next, context.Query.NamespaceMap, context.Query.BaseUri)))));

            case Token.KEYWORDA:
                return(new Property(new UriNode(null, UriFactory.Create(RdfSpecsHelper.RdfType))));

            case Token.HAT:
                next    = tokens.Dequeue();
                inverse = true;
                switch (next.TokenType)
                {
                case Token.URI:
                case Token.QNAME:
                    return(new Property(new UriNode(null, UriFactory.Create(Tools.ResolveUriOrQName(next, context.Query.NamespaceMap, context.Query.BaseUri)))));

                case Token.KEYWORDA:
                    return(new Property(new UriNode(null, UriFactory.Create(RdfSpecsHelper.RdfType))));

                default:
                    throw new RdfParseException("Unexpected Token Type '" + next.GetType().Name + "' encountered, expected a QName/URI or the 'a' Keyword after an inverse operator in a negated property set", next);
                }

            default:
                throw new RdfParseException("Unexpected Token Type '" + next.GetType().Name + "' encountered, expected a QName/URI or the 'a' Keyword or the inverse operator '^' to define a path in a negated property set", next);
            }
        }
Пример #3
0
        private SparqlUpdateCommand TryParseDeleteDataCommand(SparqlUpdateParserContext context)
        {
            DeleteDataCommand cmd;

            SparqlQueryParserContext subContext = new SparqlQueryParserContext(context.Tokens);

            subContext.Query.BaseUri                        = context.BaseUri;
            subContext.Query.NamespaceMap                   = context.NamespaceMap;
            subContext.ExpressionParser.NamespaceMap        = context.NamespaceMap;
            subContext.ExpressionParser.ExpressionFactories = context.ExpressionFactories;
            subContext.ExpressionFactories                  = context.ExpressionFactories;
            subContext.ExpressionParser.QueryParser         = context.QueryParser;
            subContext.CheckBlankNodeScope                  = false;
            GraphPattern gp = context.QueryParser.TryParseGraphPattern(subContext, context.Tokens.LastTokenType != Token.LEFTCURLYBRACKET);

            // Validate that the Graph Pattern is simple
            // Check it doesn't contain anything other than Triple Patterns or if it does it just contains a single GRAPH Pattern
            if (gp.IsFiltered)
            {
                throw new RdfParseException("A FILTER Clause cannot occur in a DELETE DATA Command");
            }
            else if (gp.IsOptional)
            {
                throw new RdfParseException("An OPTIONAL Clause cannot occur in a DELETE DATA Command");
            }
            else if (gp.IsUnion)
            {
                throw new RdfParseException("A UNION Clause cannot occur in a DELETE DATA Command");
            }
            else if (gp.HasChildGraphPatterns)
            {
                if (!gp.ChildGraphPatterns.All(p => (p.IsGraph && p.GraphSpecifier.TokenType != Token.VARIABLE) || (!p.IsExists && !p.IsMinus && !p.IsNotExists && !p.IsOptional && !p.IsOptional && !p.IsService && !p.IsSubQuery && !p.IsUnion && !p.IsGraph)))
                {
                    throw new RdfParseException("A DELETE DATA Command may only contain a combination of Triple Patterns and GRAPH clauses, GRAPH clauses must specify a Graph URI");
                }
                else if (gp.ChildGraphPatterns.Any(p => p.HasChildGraphPatterns))
                {
                    throw new RdfParseException("A DELETE DATA Command may not contain nested Graph Patterns");
                }
                else if (gp.ChildGraphPatterns.Count == 1 && gp.ChildGraphPatterns[0].IsGraph && gp.TriplePatterns.Count == 0)
                {
                    cmd = new DeleteDataCommand(gp.ChildGraphPatterns[0]);
                }
                else if (gp.HasChildGraphPatterns)
                {
                    cmd = new DeleteDataCommand(gp);
                }
                else
                {
                    throw new RdfParseException("Nested Graph Patterns cannot occur in a DELETE DATA Command");
                }
            }
            else
            {
                // OK
                cmd = new DeleteDataCommand(gp);
            }

            return(cmd);
        }
Пример #4
0
        private ISparqlPath TryParsePathEltOrInverse(SparqlQueryParserContext context, Queue <IToken> tokens)
        {
            IToken next = tokens.Peek();

            if (next.TokenType == Token.HAT)
            {
                tokens.Dequeue();
                return(new InversePath(TryParsePathElt(context, tokens)));
            }
            else
            {
                return(TryParsePathElt(context, tokens));
            }
        }
Пример #5
0
        private GraphPattern TryParseModifyTemplate(SparqlUpdateParserContext context)
        {
            SparqlQueryParserContext subContext = new SparqlQueryParserContext(context.Tokens);

            subContext.Query.BaseUri                        = context.BaseUri;
            subContext.Query.NamespaceMap                   = context.NamespaceMap;
            subContext.ExpressionParser.NamespaceMap        = context.NamespaceMap;
            subContext.ExpressionParser.ExpressionFactories = context.ExpressionFactories;
            subContext.ExpressionFactories                  = context.ExpressionFactories;
            subContext.ExpressionParser.QueryParser         = context.QueryParser;
            GraphPattern gp = context.QueryParser.TryParseGraphPattern(subContext, context.Tokens.LastTokenType != Token.LEFTCURLYBRACKET);

            // Validate that the Graph Pattern is simple
            // Check it doesn't contain anything other than Triple Patterns or if it does it just contains a single GRAPH Pattern
            if (gp.IsFiltered)
            {
                throw new RdfParseException("A FILTER Clause cannot occur in a Modify Template");
            }
            else if (gp.IsOptional)
            {
                throw new RdfParseException("An OPTIONAL Clause cannot occur in a Modify Template");
            }
            else if (gp.IsUnion)
            {
                throw new RdfParseException("A UNION Clause cannot occur in a Modify Template");
            }
            else if (gp.HasChildGraphPatterns)
            {
                if (gp.ChildGraphPatterns.All(p => p.IsGraph && !p.IsFiltered && !p.IsOptional && !p.IsUnion && !p.HasChildGraphPatterns))
                {
                    return(gp);
                }
                else
                {
                    throw new RdfParseException("Nested Graph Patterns cannot occur in a Modify Template");
                }
            }
            else
            {
                return(gp);
            }
        }
Пример #6
0
        private ISparqlPath TryParsePathAlternative(SparqlQueryParserContext context, Queue <IToken> tokens)
        {
            ISparqlPath path = TryParsePathSequence(context, tokens);
            IToken      next;

            while (tokens.Count > 0)
            {
                next = tokens.Dequeue();
                if (next.TokenType == Token.BITWISEOR)
                {
                    path = new AlternativePath(path, TryParsePathSequence(context, tokens));
                }
                else
                {
                    throw new RdfParseException("Unexpected Token '" + next.GetType().ToString() + "' encountered, expected a valid path sequence/alternative token", next);
                }
            }

            return(path);
        }
Пример #7
0
        private ISparqlPath TryParseNegatedPropertySet(SparqlQueryParserContext context, Queue <IToken> tokens)
        {
            IToken   next = tokens.Peek();
            bool     inverse;
            Property p;

            switch (next.TokenType)
            {
            case Token.QNAME:
            case Token.URI:
            case Token.KEYWORDA:
            case Token.HAT:
                p = TryParsePathOneInPropertySet(context, tokens, out inverse);
                if (inverse)
                {
                    return(new NegatedSet(Enumerable.Empty <Property>(), p.AsEnumerable()));
                }
                else
                {
                    return(new NegatedSet(p.AsEnumerable(), Enumerable.Empty <Property>()));
                }

            case Token.LEFTBRACKET:
                List <Property> ps       = new List <Property>();
                List <Property> inverses = new List <Property>();

                tokens.Dequeue();
                next = tokens.Peek();
                while (next.TokenType != Token.RIGHTBRACKET)
                {
                    // Parse the next item in the set
                    p = TryParsePathOneInPropertySet(context, tokens, out inverse);
                    if (inverse)
                    {
                        inverses.Add(p);
                    }
                    else
                    {
                        ps.Add(p);
                    }

                    // Then there may be an optional | which we should discard
                    next = tokens.Peek();
                    if (next.TokenType == Token.BITWISEOR)
                    {
                        tokens.Dequeue();
                        next = tokens.Peek();
                        // If we see this we can't then see a ) immediately
                        if (next.TokenType == Token.RIGHTBRACKET)
                        {
                            throw new RdfParseException("Unexpected ) to end a negated property set encountered immediately after a | which should indicate that further items are in the set", next);
                        }
                    }
                }
                tokens.Dequeue();

                if (ps.Count == 0 && inverses.Count == 0)
                {
                    throw new RdfParseException("Unexpected empty negated property set encountered", next);
                }
                else
                {
                    return(new NegatedSet(ps, inverses));
                }

            default:
                throw new RdfParseException("Unexpected Token Type '" + next.GetType().Name + "' encountered, expected the first path in a negated property set", next);
            }
        }
Пример #8
0
        public ISparqlPath Parse(SparqlQueryParserContext context, IToken first)
        {
            // Need to gather up all the Tokens which make up the path
            int              openBrackets = 0;
            Queue <IToken>   tokens       = new Queue <IToken>();
            IToken           next;
            LastPathItemType lastItem      = LastPathItemType.None;
            int              lastSequencer = -1;

            // Add the first token and set the initial last item type
            tokens.Enqueue(first);
            switch (first.TokenType)
            {
            case Token.LEFTBRACKET:
                openBrackets = 1;
                lastItem     = LastPathItemType.Predicate;
                break;

            case Token.QNAME:
            case Token.URI:
            case Token.KEYWORDA:
                lastItem = LastPathItemType.Predicate;
                break;

            case Token.HAT:
                lastItem = LastPathItemType.Sequencer;
                break;

            case Token.NEGATION:
                lastItem = LastPathItemType.Negation;
                break;

            default:
                throw new RdfParseException("Unexpected Token '" + first.GetType().ToString() + "' encountered, this is not valid as the start of a property path");
            }


            while (true)
            {
                next = context.Tokens.Peek();
                if (openBrackets > 0)
                {
                    context.Tokens.Dequeue();
                    tokens.Enqueue(next);

                    if (next.TokenType == Token.RIGHTBRACKET)
                    {
                        openBrackets--;
                        // Groups are considered predicates for purposes of last item
                        lastItem = LastPathItemType.Predicate;
                    }
                    else if (next.TokenType == Token.LEFTBRACKET)
                    {
                        openBrackets++;
                    }
                }
                else
                {
                    switch (next.TokenType)
                    {
                    case Token.LEFTBRACKET:
                        // Path Group

                        if (lastItem == LastPathItemType.Predicate || lastItem == LastPathItemType.Modifier)
                        {
                            // If it follows a Predicate/Modifier then this is likely a collection as the object of a
                            // Triple pattern so we stop
                            lastItem = LastPathItemType.End;
                        }
                        else if (lastItem == LastPathItemType.Sequencer || lastItem == LastPathItemType.Negation)
                        {
                            // This is a new Path Group if it follows a sequencer/negation
                            openBrackets++;
                            context.Tokens.Dequeue();
                            tokens.Enqueue(next);
                            lastItem = LastPathItemType.Predicate;
                        }
                        else
                        {
                            throw new RdfParseException("Path Groups can only follow path sequencing tokens", next);
                        }
                        break;

                    case Token.LEFTCURLYBRACKET:
                        // Explicit cardinality modifiers

                        if (context.SyntaxMode == SparqlQuerySyntax.Sparql_1_1)
                        {
                            throw new RdfParseException("The {} forms for property paths are not supported in SPARQL 1.1", next);
                        }
                        if (lastItem != LastPathItemType.Predicate)
                        {
                            throw new RdfParseException("Cardinality Modifiers can only follow Predicates/Path Groups", next);
                        }

                        // Add the opening { to the tokens
                        context.Tokens.Dequeue();
                        tokens.Enqueue(next);
                        next = context.Tokens.Peek();

                        // Grab everything up to the next }
                        while (next.TokenType != Token.RIGHTCURLYBRACKET)
                        {
                            // If we see another { this is an error
                            if (next.TokenType == Token.LEFTCURLYBRACKET)
                            {
                                throw new RdfParseException("Nested Cardinality Modifiers for Paths are not permitted", next);
                            }

                            context.Tokens.Dequeue();
                            tokens.Enqueue(next);
                            next = context.Tokens.Peek();
                        }
                        // Add the trailing } to the tokens
                        context.Tokens.Dequeue();
                        tokens.Enqueue(next);
                        lastItem = LastPathItemType.Modifier;
                        break;

                    case Token.PLUS:
                    case Token.QUESTION:
                    case Token.MULTIPLY:
                        // Other Cardinality modifiers are permitted

                        if (lastItem != LastPathItemType.Predicate)
                        {
                            throw new RdfParseException("Cardinality Modifiers can only follow Predicates/Path Groups");
                        }

                        context.Tokens.Dequeue();
                        tokens.Enqueue(next);
                        lastItem = LastPathItemType.Modifier;
                        break;

                    case Token.BITWISEOR:
                    case Token.DIVIDE:
                    case Token.HAT:
                        // Path sequencing

                        if (lastItem != LastPathItemType.Predicate && lastItem != LastPathItemType.Modifier)
                        {
                            if (lastItem == LastPathItemType.Sequencer && next.TokenType == Token.HAT && (lastSequencer == Token.DIVIDE || lastSequencer == Token.BITWISEOR))
                            {
                                // / ^ or | ^ is a valid sequencing
                            }
                            else
                            {
                                throw new RdfParseException("Path sequencing tokens can only follow Predicates/Path Groups", next);
                            }
                        }

                        context.Tokens.Dequeue();
                        tokens.Enqueue(next);
                        lastItem      = LastPathItemType.Sequencer;
                        lastSequencer = next.TokenType;
                        break;

                    case Token.QNAME:
                    case Token.URI:
                    case Token.KEYWORDA:
                        // Predicates

                        if (lastItem != LastPathItemType.None && lastItem != LastPathItemType.Sequencer && lastItem != LastPathItemType.Negation)
                        {
                            // This appears to be the end of the path since we've encountered something that could be
                            // an Object
                            lastItem = LastPathItemType.End;
                        }
                        else
                        {
                            context.Tokens.Dequeue();
                            tokens.Enqueue(next);
                            lastItem = LastPathItemType.Predicate;
                        }
                        break;

                    case Token.NEGATION:
                        if (lastItem == LastPathItemType.Sequencer)
                        {
                            context.Tokens.Dequeue();
                            tokens.Enqueue(next);
                            lastItem = LastPathItemType.Negation;
                        }
                        else
                        {
                            throw new RdfParseException("Negated Property Sets can only follow path sequencing tokens", next);
                        }
                        break;

                    default:
                        if (lastItem != LastPathItemType.None && lastItem != LastPathItemType.Sequencer)
                        {
                            // Appears to be the end of the path since we've encountered an unexpected token after seeing
                            // a Predicate
                            lastItem = LastPathItemType.End;
                        }
                        else
                        {
                            throw new RdfParseException("Unexpected Token '" + next.GetType().ToString() + "' encounted, this is not a valid token for a Path", next);
                        }
                        break;
                    }

                    if (lastItem == LastPathItemType.End)
                    {
                        break;
                    }
                }
            }

            ISparqlPath path = TryParsePath(context, tokens);

            return(path);
        }
Пример #9
0
        private ISparqlPath TryParsePathMod(SparqlQueryParserContext context, Queue <IToken> tokens, ISparqlPath path)
        {
            IToken next = tokens.Dequeue();

            switch (next.TokenType)
            {
            case Token.MULTIPLY:
                return(new ZeroOrMore(path));

            case Token.QUESTION:
                return(new ZeroOrOne(path));

            case Token.PLUS:
                return(new OneOrMore(path));

            case Token.LEFTCURLYBRACKET:
                next = tokens.Dequeue();
                int min, max;
                if (next.TokenType == Token.PLAINLITERAL)
                {
                    if (Int32.TryParse(next.Value, out min))
                    {
                        if (min < 0)
                        {
                            throw new RdfParseException("Cannot specify the minimum cardinality of a path as less than zero", next);
                        }
                        next = tokens.Dequeue();
                        if (next.TokenType == Token.COMMA)
                        {
                            next = tokens.Dequeue();
                            if (next.TokenType == Token.PLAINLITERAL)
                            {
                                if (Int32.TryParse(next.Value, out max))
                                {
                                    if (max < min)
                                    {
                                        throw new RdfParseException("Cannot specify the maximum cardinality of a path as less than the minimum", next);
                                    }
                                    next = tokens.Dequeue();
                                    if (next.TokenType != Token.RIGHTCURLYBRACKET)
                                    {
                                        throw new RdfParseException("Unexpected Token '" + next.GetType().ToString() + "' encountered, expected a } to terminate a Path Cardinality modifier", next);
                                    }
                                    if (min == max)
                                    {
                                        return(new FixedCardinality(path, min));
                                    }
                                    else
                                    {
                                        return(new NToM(path, min, max));
                                    }
                                }
                                else
                                {
                                    throw new RdfParseException("The value '" + next.Value + "' is not valid for use as a Path Cardinality modifier", next);
                                }
                            }
                            else if (next.TokenType == Token.RIGHTCURLYBRACKET)
                            {
                                if (min == 0)
                                {
                                    return(new ZeroOrMore(path));
                                }
                                else if (min == 1)
                                {
                                    return(new OneOrMore(path));
                                }
                                else
                                {
                                    return(new NOrMore(path, min));
                                }
                            }
                            else
                            {
                                throw new RdfParseException("Unexpected Token '" + next.GetType().ToString() + "' encountered, expected an Integer Plain Literal as part of a Path Cardinality modifier", next);
                            }
                        }
                        else if (next.TokenType == Token.RIGHTCURLYBRACKET)
                        {
                            return(new FixedCardinality(path, min));
                        }
                        else
                        {
                            throw new RdfParseException("Unexpected Token '" + next.GetType().ToString() + "' encountered, expected a valid token to continue the Path Cardinality modifier", next);
                        }
                    }
                    else
                    {
                        throw new RdfParseException("The value '" + next.Value + "' is not valid for use as a Path Cardinality modifier", next);
                    }
                }
                else if (next.TokenType == Token.COMMA)
                {
                    next = tokens.Dequeue();
                    if (next.TokenType == Token.PLAINLITERAL)
                    {
                        if (Int32.TryParse(next.Value, out max))
                        {
                            if (max <= 0)
                            {
                                throw new RdfParseException("Cannot specify the maximum cardinality for a path as being less than the minimum", next);
                            }
                            next = tokens.Dequeue();
                            if (next.TokenType != Token.RIGHTCURLYBRACKET)
                            {
                                throw new RdfParseException("Unexpected Token '" + next.GetType().ToString() + "' encountered, expected a } to terminate a Path Cardinality modifier", next);
                            }
                            if (max == 1)
                            {
                                return(new ZeroOrOne(path));
                            }
                            else
                            {
                                return(new ZeroToN(path, max));
                            }
                        }
                        else
                        {
                            throw new RdfParseException("The value '" + next.Value + "' is not valid for use as a Path Cardinality modifier", next);
                        }
                    }
                    else
                    {
                        throw new RdfParseException("Unexpected Token '" + next.GetType().ToString() + "' encountered, expected an Integer Plain Literal as part of a Path Cardinality modifier", next);
                    }
                }
                else
                {
                    throw new RdfParseException("Unexpected Token '" + next.GetType().ToString() + "' encountered, expected an Integer Plain Literal/Comma as part of a Path Cardinality modifier", next);
                }

            default:
                throw new RdfParseException("Unexpected Token '" + next.GetType().ToString() + "' encountered, expected a token which is valid as a Path Cardinality modifier", next);
            }
        }
Пример #10
0
        private ISparqlPath TryParsePathPrimary(SparqlQueryParserContext context, Queue <IToken> tokens)
        {
            IToken      next = tokens.Dequeue();
            ISparqlPath path;

            switch (next.TokenType)
            {
            case Token.URI:
            case Token.QNAME:
                path = new Property(new UriNode(null, UriFactory.Create(Tools.ResolveUriOrQName(next, context.Query.NamespaceMap, context.Query.BaseUri))));
                break;

            case Token.KEYWORDA:
                path = new Property(new UriNode(null, UriFactory.Create(RdfSpecsHelper.RdfType)));
                break;

            case Token.LEFTBRACKET:
                Queue <IToken> subtokens    = new Queue <IToken>();
                int            openBrackets = 1;
                do
                {
                    next = tokens.Dequeue();
                    if (next.TokenType == Token.LEFTBRACKET)
                    {
                        openBrackets++;
                    }
                    else if (next.TokenType == Token.RIGHTBRACKET)
                    {
                        openBrackets--;
                    }

                    if (openBrackets > 0)
                    {
                        subtokens.Enqueue(next);
                    }
                } while (openBrackets > 0);

                path = TryParsePath(context, subtokens);
                break;

            case Token.NEGATION:
                path = TryParseNegatedPropertySet(context, tokens);
                break;

            default:
                throw new RdfParseException("Unexpected Token '" + next.GetType().ToString() + "' encountered, expected a URI/QName, the 'a' keyword or the start of a group path expression", next);
            }

            // See if there's a Path Modifier
            if (tokens.Count > 0)
            {
                next = tokens.Peek();
                switch (next.TokenType)
                {
                case Token.MULTIPLY:
                case Token.PLUS:
                case Token.QUESTION:
                case Token.LEFTCURLYBRACKET:
                    path = TryParsePathMod(context, tokens, path);
                    break;
                }
            }

            return(path);
        }
Пример #11
0
 private ISparqlPath TryParsePathElt(SparqlQueryParserContext context, Queue <IToken> tokens)
 {
     return(TryParsePathPrimary(context, tokens));
 }
Пример #12
0
 private ISparqlPath TryParsePath(SparqlQueryParserContext context, Queue <IToken> tokens)
 {
     return(TryParsePathAlternative(context, tokens));
 }
Пример #13
0
        private SparqlUpdateCommand TryParseInsertDataCommand(SparqlUpdateParserContext context)
        {
            InsertDataCommand cmd;

            SparqlQueryParserContext subContext = new SparqlQueryParserContext(context.Tokens);

            subContext.Query.BaseUri                        = context.BaseUri;
            subContext.Query.NamespaceMap                   = context.NamespaceMap;
            subContext.ExpressionParser.NamespaceMap        = context.NamespaceMap;
            subContext.ExpressionParser.ExpressionFactories = context.ExpressionFactories;
            subContext.ExpressionFactories                  = context.ExpressionFactories;
            subContext.CheckBlankNodeScope                  = false;
            GraphPattern gp = context.QueryParser.TryParseGraphPattern(subContext, context.Tokens.LastTokenType != Token.LEFTCURLYBRACKET);

            //Validate use of Blank Nodes in INSERT DATA, same BNode MAY be used within different graph patterns in a single command
            //though each represents a fresh blank node
            //The same BNode MAY NOT be used across separate commands
            if (context.DataBNodes.Count == 0)
            {
                //First INSERT DATA so simply register all the BNodes
                foreach (String var in gp.Variables.Where(v => v.StartsWith("_:")))
                {
                    context.DataBNodes.Add(var);
                }
            }
            else
            {
                //Some INSERT DATA commands have already occurred, validate that newly introduced variables are not already present
                foreach (String var in gp.Variables.Where(v => v.StartsWith("_:")).Distinct())
                {
                    if (context.DataBNodes.Contains(var))
                    {
                        throw new RdfParseException("An INSERT DATA command used the BNode " + var + " which has been used in previous INSERT DATA commands and is not permitted per Section 19.6 of the specification");
                    }
                    else
                    {
                        context.DataBNodes.Add(var);
                    }
                }
            }

            //Validate that the Graph Pattern is simple
            //Check it doesn't contain anything other than Triple Patterns or if it does it just contains a single GRAPH Pattern
            if (gp.IsFiltered)
            {
                throw new RdfParseException("A FILTER Clause cannot occur in a INSERT DATA Command");
            }
            else if (gp.IsOptional)
            {
                throw new RdfParseException("An OPTIONAL Clause cannot occur in a INSERT DATA Command");
            }
            else if (gp.IsUnion)
            {
                throw new RdfParseException("A UNION Clause cannot occur in a INSERT DATA Command");
            }
            else if (gp.HasChildGraphPatterns)
            {
                if (!gp.ChildGraphPatterns.All(p => (p.IsGraph && p.GraphSpecifier.TokenType != Token.VARIABLE) || (!p.IsExists && !p.IsMinus && !p.IsNotExists && !p.IsOptional && !p.IsOptional && !p.IsService && !p.IsSubQuery && !p.IsUnion && !p.IsGraph)))
                {
                    throw new RdfParseException("An INSERT DATA Command may only contain a combination of Triple Patterns and GRAPH clauses, GRAPH clauses must specify a Graph URI");
                }
                else if (gp.ChildGraphPatterns.Any(p => p.HasChildGraphPatterns))
                {
                    throw new RdfParseException("An INSERT DATA Command may not contain nested Graph Patterns");
                }
                else if (gp.ChildGraphPatterns.Count == 1 && gp.ChildGraphPatterns[0].IsGraph && gp.TriplePatterns.Count == 0)
                {
                    cmd = new InsertDataCommand(gp.ChildGraphPatterns[0]);
                }
                else if (gp.HasChildGraphPatterns)
                {
                    cmd = new InsertDataCommand(gp);
                }
                else
                {
                    throw new RdfParseException("Nested Graph Patterns cannot occur in a INSERT DATA Command");
                }
            }
            else
            {
                //OK
                cmd = new InsertDataCommand(gp);
            }

            return(cmd);
        }
Пример #14
0
        private SparqlUpdateCommand TryParseInsertCommand(SparqlUpdateParserContext context, bool allowData)
        {
            List <Uri> usings     = new List <Uri>();
            List <Uri> usingNamed = new List <Uri>();
            IToken     next       = context.Tokens.Dequeue();

            if (allowData)
            {
                //We are allowed to have an INSERT DATA command here so check for it
                if (next.TokenType == Token.DATA)
                {
                    return(this.TryParseInsertDataCommand(context));
                }
            }
            else
            {
                if (next.TokenType == Token.DATA)
                {
                    throw ParserHelper.Error("The DATA keyword is not permitted here as this INSERT command forms part of a modification command", next);
                }
            }

            //Get the Modification Template
            GraphPattern insertions = this.TryParseModifyTemplate(context);

            //Then we expect a WHERE keyword
            next = context.Tokens.Dequeue();
            if (next.TokenType == Token.USING)
            {
                foreach (KeyValuePair <Uri, bool> kvp in this.TryParseUsingStatements(context))
                {
                    if (kvp.Value)
                    {
                        usingNamed.Add(kvp.Key);
                    }
                    else
                    {
                        usings.Add(kvp.Key);
                    }
                }
                next = context.Tokens.Dequeue();
            }
            if (next.TokenType != Token.WHERE)
            {
                throw ParserHelper.Error("Unexpected Token '" + next.GetType().ToString() + "' encountered, expected a WHERE keyword as part of a INSERT command", next);
            }

            //Now parse the WHERE pattern
            SparqlQueryParserContext subContext = new SparqlQueryParserContext(context.Tokens);

            subContext.Query.BaseUri                        = context.BaseUri;
            subContext.Query.NamespaceMap                   = context.NamespaceMap;
            subContext.ExpressionParser.NamespaceMap        = context.NamespaceMap;
            subContext.ExpressionParser.ExpressionFactories = context.ExpressionFactories;
            subContext.ExpressionFactories                  = context.ExpressionFactories;
            GraphPattern where = context.QueryParser.TryParseGraphPattern(subContext, context.Tokens.LastTokenType != Token.LEFTCURLYBRACKET);

            //And finally return the command
            InsertCommand cmd = new InsertCommand(insertions, where);

            usings.ForEach(u => cmd.AddUsingUri(u));
            usingNamed.ForEach(u => cmd.AddUsingNamedUri(u));
            return(cmd);
        }
Пример #15
0
        private SparqlUpdateCommand TryParseDeleteCommand(SparqlUpdateParserContext context, bool allowData)
        {
            IToken     next       = context.Tokens.Dequeue();
            List <Uri> usings     = new List <Uri>();
            List <Uri> usingNamed = new List <Uri>();

            if (allowData)
            {
                // We are allowed to have an DELETE DATA command here so check for it
                if (next.TokenType == Token.DATA)
                {
                    return(TryParseDeleteDataCommand(context));
                }
            }
            else
            {
                if (next.TokenType == Token.DATA)
                {
                    throw ParserHelper.Error("The DATA keyword is not permitted here as this INSERT command forms part of a modification command", next);
                }
            }

            if (next.TokenType == Token.WHERE)
            {
                // Parse the WHERE pattern which serves as both the selection and deletion pattern in this case
                context.Tokens.Dequeue();
                GraphPattern where = TryParseModifyTemplate(context);

                // Then return the command
                return(new DeleteCommand(where, where));
            }
            // Get the Modification Template
            GraphPattern deletions = TryParseModifyTemplate(context);

            // Then we expect a WHERE keyword
            next = context.Tokens.Dequeue();
            if (next.TokenType == Token.USING)
            {
                foreach (KeyValuePair <Uri, bool> kvp in TryParseUsingStatements(context))
                {
                    if (kvp.Value)
                    {
                        usingNamed.Add(kvp.Key);
                    }
                    else
                    {
                        usings.Add(kvp.Key);
                    }
                }
                next = context.Tokens.Dequeue();
            }
            if (next.TokenType == Token.WHERE)
            {
                // Now parse the WHERE pattern
                SparqlQueryParserContext subContext = new SparqlQueryParserContext(context.Tokens);
                subContext.Query.BaseUri                        = context.BaseUri;
                subContext.Query.NamespaceMap                   = context.NamespaceMap;
                subContext.ExpressionParser.NamespaceMap        = context.NamespaceMap;
                subContext.ExpressionParser.ExpressionFactories = context.ExpressionFactories;
                subContext.ExpressionFactories                  = context.ExpressionFactories;
                subContext.ExpressionParser.QueryParser         = context.QueryParser;
                GraphPattern where = context.QueryParser.TryParseGraphPattern(subContext, context.Tokens.LastTokenType != Token.LEFTCURLYBRACKET);

                // And finally return the command
                DeleteCommand cmd = new DeleteCommand(deletions, @where);
                usings.ForEach(u => cmd.AddUsingUri(u));
                usingNamed.ForEach(u => cmd.AddUsingNamedUri(u));
                return(cmd);
            }
            if (next.TokenType == Token.INSERT)
            {
                InsertCommand insertCmd = (InsertCommand)TryParseInsertCommand(context, false);
                ModifyCommand cmd       = new ModifyCommand(deletions, insertCmd.InsertPattern, insertCmd.WherePattern);
                insertCmd.UsingUris.ToList().ForEach(u => cmd.AddUsingUri(u));
                insertCmd.UsingNamedUris.ToList().ForEach(u => cmd.AddUsingNamedUri(u));
                return(cmd);
            }
            throw ParserHelper.Error("Unexpected Token '" + next.GetType().ToString() + "' encountered, expected a WHERE keyword as part of a DELETE command", next);
        }