Ejemplo n.º 1
0
        /// <summary>
        /// Calculates the Numeric Value of the Aggregate as evaluated for the given Binding
        /// </summary>
        /// <param name="context">Evaluation Context</param>
        /// <param name="bindingID">Binding ID</param>
        /// <returns></returns>
        public override object NumericValue(SparqlEvaluationContext context, int bindingID)
        {
            INode aggValue;

            if (context.Binder.IsGroup(bindingID))
            {
                BindingGroup group = context.Binder.Group(bindingID);
                context.Binder.SetGroupContext(true);
                aggValue = this._aggregate.Apply(context, group.BindingIDs);
                context.Binder.SetGroupContext(false);
            }
            else
            {
                aggValue = this._aggregate.Apply(context);
            }

            if (aggValue.NodeType == NodeType.Literal)
            {
                ILiteralNode lit = (ILiteralNode)aggValue;
                if (!lit.Language.Equals(String.Empty))
                {
                    //If there's a Language Tag implied type is string so no numeric value
                    throw new RdfQueryException("Cannot calculate the Numeric Value of literal with a language specifier");
                }
                else if (lit.DataType == null)
                {
                    //Try and infer the Data Type
                    if (SparqlSpecsHelper.IsInteger(lit.Value))
                    {
                        return(Int64.Parse(lit.Value));
                    }
                    else if (SparqlSpecsHelper.IsDecimal(lit.Value))
                    {
                        return(Decimal.Parse(lit.Value));
                    }
                    else if (SparqlSpecsHelper.IsDouble(lit.Value))
                    {
                        return(Double.Parse(lit.Value));
                    }
                    else
                    {
                        throw new RdfQueryException("Cannot calculate the Numeric Value of a literal since it does not appear to be a valid Integer/Decimal/Double");
                    }
                }
                else
                {
                    switch (SparqlSpecsHelper.GetNumericTypeFromDataTypeUri(lit.DataType))
                    {
                    case SparqlNumericType.Decimal:
                        return(Decimal.Parse(lit.Value));

                    case SparqlNumericType.Double:
                        return(Double.Parse(lit.Value));

                    case SparqlNumericType.Float:
                        return(Single.Parse(lit.Value));

                    case SparqlNumericType.Integer:
                        return(Int64.Parse(lit.Value));

                    case SparqlNumericType.NaN:
                    default:
                        throw new RdfQueryException("Cannot calculate the Numeric Value of a literal since its Data Type URI does not correspond to a Data Type URI recognised as a Numeric Type in the SPARQL Specification");
                    }
                }
            }
            else
            {
                throw new RdfQueryException("Cannot calculate the Numeric Value of a non-Literal Node");
            }
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Determines the Effective Boolean Value of the expression for the given Binding in the given Context
        /// </summary>
        /// <param name="context">Evaluation Context</param>
        /// <param name="bindingID">Binding ID</param>
        /// <returns></returns>
        public override bool EffectiveBooleanValue(SparqlEvaluationContext context, int bindingID)
        {
            try
            {
                //While we could use NumericType or NumericValue for Numeric Expressions we can't guarantee that
                //this would work properly

                INode temp = this._expr.Value(context, bindingID);
                if (temp.NodeType == NodeType.Literal)
                {
                    ILiteralNode lit = (ILiteralNode)temp;

                    //No DatatType means not numeric
                    if (lit.DataType == null)
                    {
                        return(false);
                    }

                    //Get the Numeric Type from the DataType URI
                    SparqlNumericType type = SparqlSpecsHelper.GetNumericTypeFromDataTypeUri(lit.DataType);

                    //Now check the lexical value
                    switch (type)
                    {
                    case SparqlNumericType.Decimal:
                        //Decimal - just regex on lexical form
                        return(SparqlSpecsHelper.IsDecimal(lit.Value));

                    case SparqlNumericType.Double:
                    case SparqlNumericType.Float:
                        //Double/Float just regex on lexical form
                        return(SparqlSpecsHelper.IsDouble(lit.Value));

                    case SparqlNumericType.Integer:
                        //Integer Type so could be any of the supported types
                        switch (lit.DataType.ToString())
                        {
                        case XmlSpecsHelper.XmlSchemaDataTypeByte:
                            //Byte - have to try parsing it
                            SByte sb;
                            return(SByte.TryParse(lit.Value, out sb));

                        case XmlSpecsHelper.XmlSchemaDataTypeUnsignedByte:
                            //Unsigned Byte - have to try parsing it
                            Byte b;
                            return(Byte.TryParse(lit.Value, out b) && b >= 0);

                        case XmlSpecsHelper.XmlSchemaDataTypeInt:
                        case XmlSpecsHelper.XmlSchemaDataTypeInteger:
                        case XmlSpecsHelper.XmlSchemaDataTypeLong:
                        case XmlSpecsHelper.XmlSchemaDataTypeShort:
                            //Standard Integer - can just regex on its lexical form
                            return(SparqlSpecsHelper.IsInteger(lit.Value));

                        case XmlSpecsHelper.XmlSchemaDataTypeNegativeInteger:
                        case XmlSpecsHelper.XmlSchemaDataTypeNonPositiveInteger:
                            //Negative Integer - can just regex on its lexical form
                            //plus ensure that the value starts with a -
                            return(lit.Value.StartsWith("-") && SparqlSpecsHelper.IsInteger(lit.Value));

                        case XmlSpecsHelper.XmlSchemaDataTypeNonNegativeInteger:
                        case XmlSpecsHelper.XmlSchemaDataTypePositiveInteger:
                        case XmlSpecsHelper.XmlSchemaDataTypeUnsignedInt:
                        case XmlSpecsHelper.XmlSchemaDataTypeUnsignedLong:
                        case XmlSpecsHelper.XmlSchemaDataTypeUnsignedShort:
                            //Positive Integer - can just regex on its lexical form
                            //plus ensure that the value doesn't start with a -
                            return(!lit.Value.StartsWith("-") && SparqlSpecsHelper.IsInteger(lit.Value));

                        default:
                            //Otherwise not numeric
                            return(false);
                        }

                    default:
                        return(false);
                    }
                }
                else
                {
                    return(false);
                }
            }
            catch (RdfQueryException)
            {
                return(false);
            }
        }
Ejemplo n.º 3
0
        /// <summary>
        /// Creates a new Full Text Pattern
        /// </summary>
        /// <param name="origPatterns">Original Patterns</param>
        public FullTextPattern(IEnumerable <TriplePattern> origPatterns)
        {
            this._origPatterns.AddRange(origPatterns.OrderBy(tp => tp.Predicate.ToString()));
            PatternItem matchVar  = null;
            PatternItem searchVar = null;
            Dictionary <String, PatternItem> firsts = new Dictionary <string, PatternItem>();
            Dictionary <String, PatternItem> rests  = new Dictionary <string, PatternItem>();

            foreach (TriplePattern tp in this._origPatterns)
            {
                NodeMatchPattern predItem = tp.Predicate as NodeMatchPattern;
                if (predItem == null)
                {
                    continue;
                }
                IUriNode predUri = predItem.Node as IUriNode;
                if (predUri == null)
                {
                    continue;
                }

                switch (predUri.Uri.ToString())
                {
                case FullTextHelper.FullTextMatchPredicateUri:
                    //Extract the Search Term
                    if (searchVar != null)
                    {
                        throw new RdfQueryException("More than one pf:textMatch property specified");
                    }
                    if (tp.Object.VariableName == null)
                    {
                        this._searchTerm = tp.Object;
                    }
                    else
                    {
                        searchVar = tp.Object;
                    }

                    //Extract the Match Variable
                    if (matchVar != null)
                    {
                        throw new RdfQueryException("More than one pf:textMatch property specified");
                    }
                    if (tp.Subject.VariableName != null && !tp.Subject.VariableName.StartsWith("_:"))
                    {
                        this._matchVar = tp.Subject;
                        if (this._origPatterns.Count > 1 && searchVar == null)
                        {
                            throw new RdfQueryException("Too many patterns provided");
                        }
                    }
                    else
                    {
                        matchVar = tp.Subject;
                    }
                    break;

                case RdfSpecsHelper.RdfListFirst:
                    firsts.Add(tp.Subject.VariableName.ToString(), tp.Object);
                    break;

                case RdfSpecsHelper.RdfListRest:
                    rests.Add(tp.Subject.VariableName.ToString(), tp.Object);
                    break;

                default:
                    throw new RdfQueryException("Unexpected pattern");
                }
            }

            //Use the first and rest lists to determine Match and Score Variables if necessary
            if (this._matchVar == null)
            {
                firsts.TryGetValue(matchVar.VariableName, out this._matchVar);
                String restKey = rests[matchVar.VariableName].VariableName;
                firsts.TryGetValue(restKey, out this._scoreVar);
            }
            //Use the first and rest lists to determine search term, threshold and limit if necessary
            if (this._searchTerm == null)
            {
                firsts.TryGetValue(searchVar.VariableName, out this._searchTerm);
                String restKey = rests[searchVar.VariableName].VariableName;
                firsts.TryGetValue(restKey, out this._thresholdTerm);
                PatternItem last = rests[restKey];
                if (!last.ToString().Equals("<" + RdfSpecsHelper.RdfListNil + ">"))
                {
                    restKey = rests[restKey].VariableName;
                    firsts.TryGetValue(restKey, out this._limitTerm);
                }
                else
                {
                    //If there is only 2 arguments for the search term determine whether it should actually be a
                    //limit rather than a threshold
                    //Essentially if it is an integer assume that it was meant as a limit
                    INode temp = ((NodeMatchPattern)this._thresholdTerm).Node;
                    if (temp is ILiteralNode)
                    {
                        ILiteralNode lit = (ILiteralNode)temp;
                        if (lit.DataType != null)
                        {
                            if (SparqlSpecsHelper.GetNumericTypeFromDataTypeUri(lit.DataType) == VDS.RDF.Query.Expressions.SparqlNumericType.Integer)
                            {
                                //Is actually a limit
                                this._limitTerm     = this._thresholdTerm;
                                this._thresholdTerm = null;
                            }
                        }
                        else
                        {
                            if (SparqlSpecsHelper.IsDecimal(lit.Value) || SparqlSpecsHelper.IsDouble(lit.Value))
                            {
                                //Remains as a Threshold
                            }
                            else if (SparqlSpecsHelper.IsInteger(lit.Value))
                            {
                                //Is actually a limit
                                this._limitTerm     = this._thresholdTerm;
                                this._thresholdTerm = null;
                            }
                        }
                    }
                }
            }

            if (this._matchVar == null)
            {
                throw new RdfQueryException("Failed to specify match variable");
            }
            if (this._searchTerm == null)
            {
                this._searchTerm = searchVar;
            }
            if (this._searchTerm == null)
            {
                throw new RdfQueryException("Failed to specify search terms");
            }
        }