/// <summary> /// Internal helper for calculating 3D Cartesian Distance /// </summary> /// <param name="context">Evaluation Context</param> /// <param name="bindingID">Binding ID</param> /// <returns></returns> private IValuedNode CartesianDistance3D(SparqlEvaluationContext context, int bindingID) { IValuedNode x1 = _x1.Evaluate(context, bindingID); if (x1 == null) { throw new RdfQueryException("Cannot calculate cartesian distance when a argument is null"); } IValuedNode y1 = _y1.Evaluate(context, bindingID); if (y1 == null) { throw new RdfQueryException("Cannot calculate cartesian distance when a argument is null"); } IValuedNode z1 = _z1.Evaluate(context, bindingID); if (z1 == null) { throw new RdfQueryException("Cannot calculate cartesian distance when a argument is null"); } IValuedNode x2 = _x2.Evaluate(context, bindingID); if (x2 == null) { throw new RdfQueryException("Cannot calculate cartesian distance when a argument is null"); } IValuedNode y2 = _y2.Evaluate(context, bindingID); if (y2 == null) { throw new RdfQueryException("Cannot calculate cartesian distance when a argument is null"); } IValuedNode z2 = _z2.Evaluate(context, bindingID); if (z2 == null) { throw new RdfQueryException("Cannot calculate cartesian distance when a argument is null"); } double dX = x2.AsDouble() - x1.AsDouble(); double dY = y2.AsDouble() - y1.AsDouble(); double dZ = z2.AsDouble() - z1.AsDouble(); return(new DoubleNode(null, Math.Sqrt(Math.Pow(dX, 2) + Math.Pow(dY, 2) + Math.Pow(dZ, 2)))); }
/// <summary> /// Gets the value of the aggregate for the given binding /// </summary> /// <param name="context">Evaluation Context</param> /// <param name="bindingID">Binding ID</param> /// <returns></returns> protected override string ValueInternal(SparqlEvaluationContext context, int bindingID) { IValuedNode temp = this._expr.Evaluate(context, bindingID); if (temp == null) { throw new RdfQueryException("Cannot do an XPath string-join on a null"); } switch (temp.NodeType) { case NodeType.Literal: case NodeType.Uri: return(temp.AsString()); default: throw new RdfQueryException("Cannot do an XPath string-join on a non-Literal Node"); } }
/// <summary> /// Gets the value of the function in the given Evaluation Context for the given Binding ID. /// </summary> /// <param name="context">Evaluation Context.</param> /// <param name="bindingID">Binding ID.</param> /// <returns> /// Returns a constant Literal Node which is a Date Time typed Literal. /// </returns> public IValuedNode Evaluate(SparqlEvaluationContext context, int bindingID) { if (_currQuery == null) { _currQuery = context.Query; } if (_node == null || !ReferenceEquals(_currQuery, context.Query)) { lock (this) { if (_node == null || !ReferenceEquals(_currQuery, context.Query)) { _node = new DateTimeNode(null, DateTime.Now); } } } return(_node); }
/// <summary> /// Evaluates the expression /// </summary> /// <param name="context">Evaluation Context</param> /// <param name="bindingID">Binding ID</param> /// <returns></returns> public override IValuedNode Evaluate(SparqlEvaluationContext context, int bindingID) { IValuedNode result = this._expr.Evaluate(context, bindingID); if (result != null) { if (this._expressions.Count == 0) { return(new BooleanNode(null, false)); } //Have to use SPARQL Value Equality here //If any expressions error and nothing in the set matches then an error is thrown bool errors = false; foreach (ISparqlExpression expr in this._expressions) { try { IValuedNode temp = expr.Evaluate(context, bindingID); if (SparqlSpecsHelper.Equality(result, temp)) { return(new BooleanNode(null, true)); } } catch { errors = true; } } if (errors) { throw new RdfQueryException("One/more expressions in a Set function failed to evaluate"); } else { return(new BooleanNode(null, false)); } } else { return(new BooleanNode(null, false)); } }
/// <summary> /// Returns the value of the Expression as evaluated for a given Binding as a Literal Node /// </summary> /// <param name="context">Evaluation Context</param> /// <param name="bindingID">Binding ID</param> /// <returns></returns> public override IValuedNode Evaluate(SparqlEvaluationContext context, int bindingID) { IValuedNode result = this._expr.Evaluate(context, bindingID); if (result == null) { throw new RdfQueryException("Cannot create an IRI from a null"); } else { switch (result.NodeType) { case NodeType.Literal: ILiteralNode lit = (ILiteralNode)result; string baseUri = string.Empty; if (context.Query != null) baseUri = context.Query.BaseUri.ToSafeString(); string uri; if (lit.DataType == null) { uri = Tools.ResolveUri(lit.Value, baseUri); return new UriNode(null, UriFactory.Create(uri)); } else { string dt = lit.DataType.AbsoluteUri; if (dt.Equals(XmlSpecsHelper.XmlSchemaDataTypeString, StringComparison.Ordinal)) { uri = Tools.ResolveUri(lit.Value, baseUri); return new UriNode(null, UriFactory.Create(uri)); } else { throw new RdfQueryException("Cannot create an IRI from a non-string typed literal"); } } case NodeType.Uri: //Already a URI so nothing to do return result; default: throw new RdfQueryException("Cannot create an IRI from a non-URI/String literal"); } } }
private static object GetPrimitiveValue(IValuedNode valuedNode, IEdmPrimitiveType targetType, bool asNullable) { // TODO: Some sort of cast to nullable when necessary switch (targetType.PrimitiveKind) { case EdmPrimitiveTypeKind.Boolean: return(valuedNode.AsBoolean()); case EdmPrimitiveTypeKind.Byte: return((byte)valuedNode.AsInteger()); case EdmPrimitiveTypeKind.DateTime: return(valuedNode.AsDateTime()); case EdmPrimitiveTypeKind.Decimal: return(valuedNode.AsDecimal()); case EdmPrimitiveTypeKind.Double: return(valuedNode.AsDouble()); case EdmPrimitiveTypeKind.Int16: return((Int16)valuedNode.AsInteger()); case EdmPrimitiveTypeKind.Int32: return((Int32)valuedNode.AsInteger()); case EdmPrimitiveTypeKind.Int64: return(valuedNode.AsInteger()); case EdmPrimitiveTypeKind.String: return(valuedNode.AsString()); case EdmPrimitiveTypeKind.DateTimeOffset: return(valuedNode.AsDateTime()); default: throw new NotSupportedException( String.Format("Support for primitive type {0} has not been implemented yet", targetType.PrimitiveKind)); } }
/// <summary> /// Calculates the Numeric Value of this Expression as evaluated for a given Binding /// </summary> /// <param name="context">Evaluation Context</param> /// <param name="bindingID">Binding ID</param> /// <returns></returns> public override IValuedNode Evaluate(SparqlEvaluationContext context, int bindingID) { IValuedNode a = this._leftExpr.Evaluate(context, bindingID); IValuedNode b = this._rightExpr.Evaluate(context, bindingID); if (a == null || b == null) { throw new RdfQueryException("Cannot apply division when one/both arguments are null"); } SparqlNumericType type = (SparqlNumericType)Math.Max((int)a.NumericType, (int)b.NumericType); try { switch (type) { case SparqlNumericType.Integer: case SparqlNumericType.Decimal: //For Division Integers are treated as decimals decimal d = a.AsDecimal() / b.AsDecimal(); if (Decimal.Floor(d).Equals(d) && d >= Int64.MinValue && d <= Int64.MaxValue) { return(new LongNode(null, Convert.ToInt64(d))); } return(new DecimalNode(null, d)); case SparqlNumericType.Float: return(new FloatNode(null, a.AsFloat() / b.AsFloat())); case SparqlNumericType.Double: return(new DoubleNode(null, a.AsDouble() / b.AsDouble())); default: throw new RdfQueryException("Cannot evalute an Arithmetic Expression when the Numeric Type of the expression cannot be determined"); } } catch (DivideByZeroException) { throw new RdfQueryException("Cannot evaluate a Division Expression where the divisor is Zero"); } }
private IValuedNode CheckArgument(ISparqlExpression expr, SparqlEvaluationContext context, int bindingID, Func <Uri, bool> argumentTypeValidator) { IValuedNode temp = expr.Evaluate(context, bindingID); if (temp != null) { if (temp.NodeType == NodeType.Literal) { ILiteralNode lit = (ILiteralNode)temp; if (lit.DataType != null) { if (argumentTypeValidator(lit.DataType)) { // Appropriately typed literals are fine return(temp); } else { throw new RdfQueryException("Unable to evaluate an XPath substring as one of the argument expressions returned a typed literal with an invalid type"); } } else if (argumentTypeValidator(UriFactory.Create(XmlSpecsHelper.XmlSchemaDataTypeString))) { // Untyped Literals are treated as Strings and may be returned when the argument allows strings return(temp); } else { throw new RdfQueryException("Unable to evalaute an XPath substring as one of the argument expressions returned an untyped literal"); } } else { throw new RdfQueryException("Unable to evaluate an XPath substring as one of the argument expressions returned a non-literal"); } } else { throw new RdfQueryException("Unable to evaluate an XPath substring as one of the argument expressions evaluated to null"); } }
/// <summary> /// Returns the value of the Expression as evaluated for a given Binding as a Literal Node /// </summary> /// <param name="context">Evaluation Context</param> /// <param name="bindingID">Binding ID</param> /// <returns></returns> public override IValuedNode Evaluate(SparqlEvaluationContext context, int bindingID) { IValuedNode result = _expr.Evaluate(context, bindingID); if (result == null) { throw new RdfQueryException("Cannot return the lexical value of an NULL"); } else { switch (result.NodeType) { case NodeType.Literal: case NodeType.Uri: return(new StringNode(null, result.AsString())); default: throw new RdfQueryException("Cannot return the lexical value of Nodes which are not Literal/URI Nodes"); } } }
/// <summary> /// Creates a new ARQ String Join function /// </summary> /// <param name="sepExpr">Separator Expression</param> /// <param name="expressions">Expressions to concatentate</param> public StringJoinFunction(ISparqlExpression sepExpr, IEnumerable <ISparqlExpression> expressions) { if (sepExpr is ConstantTerm) { IValuedNode temp = sepExpr.Evaluate(null, 0); if (temp.NodeType == NodeType.Literal) { _separator = temp.AsString(); _fixedSeparator = true; } else { _sep = sepExpr; } } else { _sep = sepExpr; } _exprs.AddRange(expressions); }
/// <summary> /// Gets the date based on the stored value using the default value if there was no stored value /// </summary> /// <param name="t">Triple whose object is the stored value</param> /// <param name="defaultValue">Default value</param> /// <returns>Date</returns> private static DateTimeOffset?GetDate(Triple t, DateTimeOffset?defaultValue) { if (t == null) { return(defaultValue); } INode n = t.Object; if (n.NodeType == NodeType.Literal) { IValuedNode value = n.AsValuedNode(); try { return(value.AsDateTimeOffset()); } catch (RdfQueryException) { return(defaultValue); } } return(defaultValue); }
/// <summary> /// Evaluates the expression. /// </summary> /// <param name="context">Evaluation Context.</param> /// <param name="bindingID">Binding ID.</param> /// <returns></returns> public override IValuedNode Evaluate(SparqlEvaluationContext context, int bindingID) { IValuedNode x = _leftExpr.Evaluate(context, bindingID); if (x == null) { throw new RdfQueryException("Cannot calculate distance of a null"); } IValuedNode y = _rightExpr.Evaluate(context, bindingID); if (y == null) { throw new RdfQueryException("Cannot calculate distance of a null"); } if (x.NumericType == SparqlNumericType.NaN || y.NumericType == SparqlNumericType.NaN) { throw new RdfQueryException("Cannot calculate distance when one/both arguments are non-numeric"); } return(new DoubleNode(null, Math.Sqrt(Math.Pow(x.AsDouble(), 2) + Math.Pow(y.AsDouble(), 2)))); }
/// <summary> /// Evaluates the expression. /// </summary> /// <param name="context">Evaluation Context.</param> /// <param name="bindingID">Binding ID.</param> /// <returns></returns> public override IValuedNode Evaluate(SparqlEvaluationContext context, int bindingID) { IValuedNode arg = _leftExpr.Evaluate(context, bindingID); if (arg == null) { throw new RdfQueryException("Cannot raise a null to a power"); } IValuedNode pow = _rightExpr.Evaluate(context, bindingID); if (pow == null) { throw new RdfQueryException("Cannot raise to a null power"); } if (arg.NumericType == SparqlNumericType.NaN || pow.NumericType == SparqlNumericType.NaN) { throw new RdfQueryException("Cannot raise to a power when one/both arguments are non-numeric"); } return(new DoubleNode(null, Math.Pow(arg.AsDouble(), pow.AsDouble()))); }
/// <summary> /// Evaluates the expression /// </summary> /// <param name="context">Evaluation Context</param> /// <param name="bindingID">Binding ID</param> /// <returns></returns> public override IValuedNode Evaluate(SparqlEvaluationContext context, int bindingID) { IValuedNode arg = this._leftExpr.Evaluate(context, bindingID); if (arg == null) { throw new RdfQueryException("Cannot root a null"); } IValuedNode root = this._rightExpr.Evaluate(context, bindingID); if (root == null) { throw new RdfQueryException("Cannot root to a null root"); } if (arg.NumericType == SparqlNumericType.NaN || root.NumericType == SparqlNumericType.NaN) { throw new RdfQueryException("Cannot root when one/both arguments are non-numeric"); } return(new DoubleNode(null, Math.Pow(arg.AsDouble(), (1d / root.AsDouble())))); }
/// <summary> /// Evaluates the expression. /// </summary> /// <param name="context">Evaluation Context.</param> /// <param name="bindingID">Binding ID.</param> /// <returns></returns> public override IValuedNode Evaluate(SparqlEvaluationContext context, int bindingID) { IValuedNode arg = _leftExpr.Evaluate(context, bindingID); if (arg == null) { throw new RdfQueryException("Cannot log a null"); } IValuedNode logBase = _rightExpr.Evaluate(context, bindingID); if (logBase == null) { throw new RdfQueryException("Cannot log to a null base"); } if (arg.NumericType == SparqlNumericType.NaN || logBase.NumericType == SparqlNumericType.NaN) { throw new RdfQueryException("Cannot log when one/both arguments are non-numeric"); } return(new DoubleNode(null, Math.Log(arg.AsDouble(), logBase.AsDouble()))); }
/// <summary> /// Gets the Numeric Value of the function as evaluated in the given Context for the given Binding ID. /// </summary> /// <param name="context">Evaluation Context.</param> /// <param name="bindingID">Binding ID.</param> /// <returns></returns> public override IValuedNode Evaluate(SparqlEvaluationContext context, int bindingID) { IValuedNode a = _expr.Evaluate(context, bindingID); if (a == null) { throw new RdfQueryException("Cannot calculate an arithmetic expression on a null"); } switch (a.NumericType) { case SparqlNumericType.Integer: // Rounding an Integer has no effect return(a); case SparqlNumericType.Decimal: return(new DecimalNode(null, Math.Round(a.AsDecimal(), MidpointRounding.AwayFromZero))); case SparqlNumericType.Float: try { return(new FloatNode(null, Convert.ToSingle(Math.Round(a.AsDouble(), MidpointRounding.AwayFromZero), CultureInfo.InvariantCulture))); } catch (RdfQueryException) { throw; } catch (Exception ex) { throw new RdfQueryException("Unable to cast the float value of a round to a float", ex); } case SparqlNumericType.Double: return(new DoubleNode(null, Math.Round(a.AsDouble(), MidpointRounding.AwayFromZero))); default: throw new RdfQueryException("Cannot evalute an Arithmetic Expression when the Numeric Type of the expression cannot be determined"); } }
/// <summary> /// Evaluates the expression /// </summary> /// <param name="context">Evaluation Context</param> /// <param name="bindingID">Binding ID</param> /// <returns></returns> public override IValuedNode Evaluate(SparqlEvaluationContext context, int bindingID) { IValuedNode temp = this._expr.Evaluate(context, bindingID); if (temp == null) { throw new RdfQueryException("Cannot square root a null"); } switch (temp.NumericType) { case SparqlNumericType.Integer: case SparqlNumericType.Decimal: case SparqlNumericType.Float: case SparqlNumericType.Double: return(new DoubleNode(null, Math.Log(temp.AsDouble(), Math.E))); case SparqlNumericType.NaN: default: throw new RdfQueryException("Cannot square a non-numeric argument"); } }
/// <summary> /// Gets the Numeric Value of the function as evaluated in the given Context for the given Binding ID. /// </summary> /// <param name="context">Evaluation Context.</param> /// <param name="bindingID">Binding ID.</param> /// <returns></returns> public override IValuedNode Evaluate(SparqlEvaluationContext context, int bindingID) { IValuedNode a = _expr.Evaluate(context, bindingID); if (a == null) { throw new RdfQueryException("Cannot calculate an arithmetic expression on a null"); } switch (a.NumericType) { case SparqlNumericType.Integer: return(new LongNode(null, Math.Abs(a.AsInteger()))); case SparqlNumericType.Decimal: return(new DecimalNode(null, Math.Abs(a.AsDecimal()))); case SparqlNumericType.Float: try { return(new FloatNode(null, Convert.ToSingle(Math.Abs(a.AsDouble())))); } catch (RdfQueryException) { throw; } catch (Exception ex) { throw new RdfQueryException("Unable to cast absolute value of float to a float", ex); } case SparqlNumericType.Double: return(new DoubleNode(null, Math.Abs(a.AsDouble()))); default: throw new RdfQueryException("Cannot evalute an Arithmetic Expression when the Numeric Type of the expression cannot be determined"); } }
/// <summary> /// Applies the SAMPLE Aggregate. /// </summary> /// <param name="context">Evaluation Context.</param> /// <param name="bindingIDs">Binding IDs.</param> /// <returns></returns> public override IValuedNode Apply(SparqlEvaluationContext context, IEnumerable <int> bindingIDs) { // Try the expression with each member of the Group until we find a non-null foreach (int id in bindingIDs) { try { // First non-null result we find is returned IValuedNode temp = _expr.Evaluate(context, id); if (temp != null) { return(temp); } } catch (RdfQueryException) { // Ignore errors - we'll loop round and try the next } } // If the Group is Empty of the Expression fails to evaluate for the entire Group then the result is null return(null); }
/// <summary> /// Compares two Date Times for Date Time ordering /// </summary> /// <param name="x">Node</param> /// <param name="y">Node</param> /// <returns></returns> protected int DateTimeCompare(IValuedNode x, IValuedNode y) { if (x == null || y == null) { throw new RdfQueryException("Cannot evaluate date time equality when one or both arguments are Null"); } try { DateTimeOffset a = x.AsDateTime(); DateTimeOffset b = y.AsDateTime(); if (!a.Offset.Equals(b.Offset)) { throw new RdfQueryException("Cannot order Dates which are from different time zones"); } return(a.CompareTo(b)); } catch (FormatException) { throw new RdfQueryException("Cannot evaluate date time equality since one of the arguments does not have a valid lexical value for a Date Time"); } }
/// <summary> /// Gets the Timezone of the Argument Expression as evaluated 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 IValuedNode Evaluate(SparqlEvaluationContext context, int bindingID) { IValuedNode temp = this._expr.Evaluate(context, bindingID); if (temp != null) { DateTimeOffset dt = temp.AsDateTime(); //Regex based check to see if the value has a Timezone component //If not then the result is a null if (!Regex.IsMatch(temp.AsString(), "(Z|[+-]\\d{2}:\\d{2})$")) { return(new StringNode(null, string.Empty)); } //Now we have a DateTime we can try and return the Timezone if (dt.Offset.Equals(TimeSpan.Zero)) { //If Zero it was specified as Z (which means UTC so zero offset) return(new StringNode(null, "Z")); } else { //If the Offset is outside the range -14 to 14 this is considered invalid if (dt.Offset.Hours < -14 || dt.Offset.Hours > 14) { return(null); } //Otherwise it has an offset which is a given number of hours (and minutes) return(new StringNode(null, dt.Offset.Hours.ToString("00") + ":" + dt.Offset.Minutes.ToString("00"))); } } else { throw new RdfQueryException("Unable to evaluate a Date Time function on a null argument"); } }
/// <summary> /// Evaluates the expression /// </summary> /// <param name="context">Evaluation Context</param> /// <param name="bindingID">Binding ID</param> /// <returns></returns> public override IValuedNode Evaluate(SparqlEvaluationContext context, int bindingID) { IValuedNode temp = this._expr.Evaluate(context, bindingID); if (temp == null) throw new RdfQueryException("Cannot evaluate factorial of a null"); long l = temp.AsInteger(); if (l == 0) return new LongNode(null, 0); long fac = 1; if (l > 0) { for (long i = l; i > 1; i--) { fac = fac * i; } } else { for (long i = l; i < -1; i++) { fac = fac * i; } } return new LongNode(null, fac); }
public void SparqlParsingLiteralsInExpressions() { Queue <IToken> tokens = new Queue <IToken>(); tokens.Enqueue(new LiteralToken("value", 0, 0, 0)); tokens.Enqueue(new HatHatToken(0, 0)); tokens.Enqueue(new DataTypeToken("<http://example/type>", 0, 0, 0)); SparqlExpressionParser parser = new SparqlExpressionParser(); ISparqlExpression expr = parser.Parse(tokens); Assert.IsInstanceOf(typeof(ConstantTerm), expr); ConstantTerm constant = expr as ConstantTerm; Assert.IsNotNull(constant); IValuedNode n = constant.Node; Assert.IsInstanceOf(typeof(ILiteralNode), n); ILiteralNode lit = (ILiteralNode)n; Assert.AreEqual(String.Empty, lit.Language); Assert.IsTrue(EqualityHelper.AreUrisEqual(lit.DataType, new Uri("http://example/type"))); }
/// <summary> /// Gets the Value of the function as evaluated in the given Context for the given Binding ID /// </summary> /// <param name="context">Context</param> /// <param name="bindingID">Binding ID</param> /// <returns></returns> public IValuedNode Evaluate(SparqlEvaluationContext context, int bindingID) { StringBuilder output = new StringBuilder(); foreach (ISparqlExpression expr in this._exprs) { IValuedNode temp = expr.Evaluate(context, bindingID); if (temp == null) { throw new RdfQueryException("Cannot evaluate the XPath concat() function when an argument evaluates to a Null"); } switch (temp.NodeType) { case NodeType.Literal: output.Append(temp.AsString()); break; default: throw new RdfQueryException("Cannot evaluate the XPath concat() function when an argument is not a Literal Node"); } } return(new StringNode(null, output.ToString(), UriFactory.Create(XmlSpecsHelper.XmlSchemaDataTypeString))); }
/// <summary> /// Evaluates the expression /// </summary> /// <param name="context">Evaluation Context</param> /// <param name="bindingID">Binding ID</param> /// <returns></returns> public IValuedNode Evaluate(SparqlEvaluationContext context, int bindingID) { // Configure Options if (this._optionExpr != null && !this._fixedOptions) { this.ConfigureOptions(this._optionExpr.Evaluate(context, bindingID), true); } // Compile the Regex if necessary if (!this._fixedPattern) { // Regex is not pre-compiled if (this._patternExpr != null) { IValuedNode p = this._patternExpr.Evaluate(context, bindingID); if (p != null) { if (p.NodeType == NodeType.Literal) { this._pattern = p.AsString(); } else { throw new RdfQueryException("Cannot parse a Pattern String from a non-Literal Node"); } } else { throw new RdfQueryException("Not a valid Pattern Expression"); } } else { throw new RdfQueryException("Not a valid Pattern Expression or the fixed Pattern String was invalid"); } } // Execute the Regular Expression IValuedNode textNode = this._textExpr.Evaluate(context, bindingID); if (textNode == null) { throw new RdfQueryException("Cannot evaluate a Regular Expression against a NULL"); } if (textNode.NodeType == NodeType.Literal) { // Execute string text = textNode.AsString(); if (this._regex != null) { return(new BooleanNode(null, this._regex.IsMatch(text))); } else { return(new BooleanNode(null, Regex.IsMatch(text, this._pattern, this._options))); } } else { throw new RdfQueryException("Cannot evaluate a Regular Expression against a non-Literal Node"); } }
/// <summary> /// Creates a new ARQ Pi function /// </summary> public PiFunction() { this._node = new DoubleNode(null, Math.PI); }
/// <summary> /// Creates a new Constant /// </summary> /// <param name="n">Valued Node</param> public ConstantTerm(IValuedNode n) { this._node = n; }
/// <summary> /// Returns the value of the Expression as evaluated for a given Binding as a Literal Node. /// </summary> /// <param name="context">Evaluation Context.</param> /// <param name="bindingID">Binding ID.</param> /// <returns></returns> public IValuedNode Evaluate(SparqlEvaluationContext context, int bindingID) { // Configure Options if (_optionExpr != null) { ConfigureOptions(_optionExpr.Evaluate(context, bindingID), true); } // Compile the Regex if necessary if (!_fixedPattern) { // Regex is not pre-compiled if (_findExpr != null) { IValuedNode p = _findExpr.Evaluate(context, bindingID); if (p != null) { if (p.NodeType == NodeType.Literal) { _find = p.AsString(); } else { throw new RdfQueryException("Cannot parse a Pattern String from a non-Literal Node"); } } else { throw new RdfQueryException("Not a valid Pattern Expression"); } } else { throw new RdfQueryException("Not a valid Pattern Expression or the fixed Pattern String was invalid"); } } // Compute the Replace if necessary if (!_fixedReplace) { if (_replaceExpr != null) { IValuedNode r = _replaceExpr.Evaluate(context, bindingID); if (r != null) { if (r.NodeType == NodeType.Literal) { _replace = r.AsString(); } else { throw new RdfQueryException("Cannot parse a Replace String from a non-Literal Node"); } } else { throw new RdfQueryException("Not a valid Replace Expression"); } } else { throw new RdfQueryException("Not a valid Replace Expression"); } } // Execute the Regular Expression IValuedNode textNode = _textExpr.Evaluate(context, bindingID); if (textNode == null) { throw new RdfQueryException("Cannot evaluate a Regular Expression against a NULL"); } if (textNode.NodeType == NodeType.Literal) { // Execute ILiteralNode lit = (ILiteralNode)textNode; if (lit.DataType != null && !lit.DataType.AbsoluteUri.Equals(XmlSpecsHelper.XmlSchemaDataTypeString)) { throw new RdfQueryException("Text Argument to Replace must be of type xsd:string if a datatype is specified"); } string text = lit.Value; string output = Regex.Replace(text, _find, _replace, _options); if (lit.DataType != null) { return(new StringNode(null, output, lit.DataType)); } else if (!lit.Language.Equals(string.Empty)) { return(new StringNode(null, output, lit.Language)); } else { return(new StringNode(null, output)); } } else { throw new RdfQueryException("Cannot evaluate a Regular Expression against a non-Literal Node"); } }
/// <summary> /// Applies the Median Aggregate function to the results. /// </summary> /// <param name="context">Evaluation Context.</param> /// <param name="bindingIDs">Binding IDs over which the Aggregate applies.</param> /// <returns></returns> public override IValuedNode Apply(SparqlEvaluationContext context, IEnumerable <int> bindingIDs) { if (_varname != null) { // Ensured the MEDIANed variable is in the Variables of the Results if (!context.Binder.Variables.Contains(_varname)) { throw new RdfQueryException("Cannot use the Variable " + _expr.ToString() + " in a MEDIAN Aggregate since the Variable does not occur in a Graph Pattern"); } } List <IValuedNode> values = new List <IValuedNode>(); HashSet <IValuedNode> distinctValues = new HashSet <IValuedNode>(); bool nullSeen = false; foreach (int id in bindingIDs) { try { IValuedNode temp = _expr.Evaluate(context, id); if (_distinct) { if (temp != null) { if (distinctValues.Contains(temp)) { continue; } else { distinctValues.Add(temp); } } else if (!nullSeen) { nullSeen = false; } else { continue; } } values.Add(temp); } catch { // Ignore errors } } if (values.Count == 0) { return(null); } // Find the middle value and return values.Sort(); int skip = values.Count / 2; return(values.Skip(skip).First()); }
/// <summary> /// Returns the value of the Expression as evaluated for a given Binding as a Literal Node /// </summary> /// <param name="context">Evaluation Context</param> /// <param name="bindingID">Binding ID</param> /// <returns></returns> public IValuedNode Evaluate(SparqlEvaluationContext context, int bindingID) { ILiteralNode input = (ILiteralNode)CheckArgument(_expr, context, bindingID); IValuedNode start = CheckArgument(_start, context, bindingID, XPathFunctionFactory.AcceptNumericArguments); if (_length != null) { IValuedNode length = CheckArgument(_length, context, bindingID, XPathFunctionFactory.AcceptNumericArguments); if (input.Value.Equals(string.Empty)) { return(new StringNode(null, string.Empty, UriFactory.Create(XmlSpecsHelper.XmlSchemaDataTypeString))); } int s = Convert.ToInt32(start.AsInteger()); int l = Convert.ToInt32(length.AsInteger()); if (s < 1) { s = 1; } if (l < 1) { // If no/negative characters are being selected the empty string is returned return(new StringNode(null, string.Empty, UriFactory.Create(XmlSpecsHelper.XmlSchemaDataTypeString))); } else if ((s - 1) > input.Value.Length) { // If the start is after the end of the string the empty string is returned return(new StringNode(null, string.Empty, UriFactory.Create(XmlSpecsHelper.XmlSchemaDataTypeString))); } else { if (((s - 1) + l) > input.Value.Length) { // If the start plus the length is greater than the length of the string the string from the starts onwards is returned return(new StringNode(null, input.Value.Substring(s - 1), UriFactory.Create(XmlSpecsHelper.XmlSchemaDataTypeString))); } else { // Otherwise do normal substring return(new StringNode(null, input.Value.Substring(s - 1, l), UriFactory.Create(XmlSpecsHelper.XmlSchemaDataTypeString))); } } } else { if (input.Value.Equals(string.Empty)) { return(new StringNode(null, string.Empty, UriFactory.Create(XmlSpecsHelper.XmlSchemaDataTypeString))); } int s = Convert.ToInt32(start.AsInteger()); if (s < 1) { s = 1; } return(new StringNode(null, input.Value.Substring(s - 1), UriFactory.Create(XmlSpecsHelper.XmlSchemaDataTypeString))); } }
private static object GetPrimitiveValue(IValuedNode valuedNode, IEdmPrimitiveType targetType, bool asNullable) { // TODO: Some sort of cast to nullable when necessary switch (targetType.PrimitiveKind) { case EdmPrimitiveTypeKind.Boolean: return valuedNode.AsBoolean(); case EdmPrimitiveTypeKind.Byte: return (byte) valuedNode.AsInteger(); case EdmPrimitiveTypeKind.DateTime: return valuedNode.AsDateTime(); case EdmPrimitiveTypeKind.Decimal: return valuedNode.AsDecimal(); case EdmPrimitiveTypeKind.Double: return valuedNode.AsDouble(); case EdmPrimitiveTypeKind.Int16: return (Int16) valuedNode.AsInteger(); case EdmPrimitiveTypeKind.Int32: return (Int32) valuedNode.AsInteger(); case EdmPrimitiveTypeKind.Int64: return valuedNode.AsInteger(); case EdmPrimitiveTypeKind.String: return valuedNode.AsString(); case EdmPrimitiveTypeKind.DateTimeOffset: return valuedNode.AsDateTime(); default: throw new NotSupportedException( String.Format("Support for primitive type {0} has not been implemented yet", targetType.PrimitiveKind)); } }
/// <summary> /// Gets the value of the function in the given Evaluation Context for the given Binding ID /// </summary> /// <param name="context">Evaluation Context</param> /// <param name="bindingID">Binding ID</param> /// <returns> /// Returns a constant Literal Node which is a Date Time typed Literal /// </returns> public IValuedNode Evaluate(SparqlEvaluationContext context, int bindingID) { if (this._currQuery == null) { this._currQuery = context.Query; } if (this._node == null || !ReferenceEquals(this._currQuery, context.Query)) { this._node = new DateTimeNode(null, DateTime.Now); } return this._node; }
/// <summary> /// Casts the Value of the inner Expression to a Decimal. /// </summary> /// <param name="context">Evaluation Context.</param> /// <param name="bindingID">Binding ID.</param> /// <returns></returns> public override IValuedNode Evaluate(SparqlEvaluationContext context, int bindingID) { IValuedNode n = _expr.Evaluate(context, bindingID);//.CoerceToDecimal(); if (n == null) { throw new RdfQueryException("Cannot cast a Null to a xsd:decimal"); } // New method should be much faster // if (n is DecimalNode) return n; // return new DecimalNode(null, n.AsDecimal()); switch (n.NodeType) { case NodeType.Blank: case NodeType.GraphLiteral: case NodeType.Uri: throw new RdfQueryException("Cannot cast a Blank/URI/Graph Literal Node to a xsd:decimal"); case NodeType.Literal: if (n is DecimalNode) { return(n); } // See if the value can be cast ILiteralNode lit = (ILiteralNode)n; if (lit.DataType != null) { string dt = lit.DataType.ToString(); if (SparqlSpecsHelper.IntegerDataTypes.Contains(dt)) { // Already an integer type so valid as a xsd:decimal decimal d; if (Decimal.TryParse(lit.Value, NumberStyles.Any ^ NumberStyles.AllowExponent, CultureInfo.InvariantCulture, out d)) { // Parsed OK return(new DecimalNode(lit.Graph, d)); } else { throw new RdfQueryException("Invalid lexical form for xsd:decimal"); } } else if (dt.Equals(XmlSpecsHelper.XmlSchemaDataTypeDateTime)) { // DateTime cast forbidden throw new RdfQueryException("Cannot cast a xsd:dateTime to a xsd:decimal"); } else { decimal d; if (Decimal.TryParse(lit.Value, NumberStyles.Any ^ NumberStyles.AllowExponent, CultureInfo.InvariantCulture, out d)) { // Parsed OK return(new DecimalNode(lit.Graph, d)); } else { throw new RdfQueryException("Cannot cast the value '" + lit.Value + "' to a xsd:decimal"); } } } else { decimal d; if (Decimal.TryParse(lit.Value, NumberStyles.Any ^ NumberStyles.AllowExponent, CultureInfo.InvariantCulture, out d)) { // Parsed OK return(new DecimalNode(lit.Graph, d)); } else { throw new RdfQueryException("Cannot cast the value '" + lit.Value + "' to a xsd:decimal"); } } default: throw new RdfQueryException("Cannot cast an Unknown Node to a xsd:decimal"); } }
/// <summary> /// Configures the Options for the Regular Expression /// </summary> /// <param name="n">Node detailing the Options</param> /// <param name="throwErrors">Whether errors should be thrown or suppressed</param> private void ConfigureOptions(IValuedNode n, bool throwErrors) { //Start by resetting to no options this._options = RegexOptions.None; if (n == null) { if (throwErrors) { throw new RdfQueryException("REGEX Options Expression does not produce an Options string"); } } else { if (n.NodeType == NodeType.Literal) { string ops = n.AsString(); foreach (char c in ops.ToCharArray()) { switch (c) { case 'i': this._options |= RegexOptions.IgnoreCase; break; case 'm': this._options |= RegexOptions.Multiline; break; case 's': this._options |= RegexOptions.Singleline; break; case 'x': this._options |= RegexOptions.IgnorePatternWhitespace; break; default: if (throwErrors) { throw new RdfQueryException("Invalid flag character '" + c + "' in Options string"); } break; } } } else { if (throwErrors) { throw new RdfQueryException("REGEX Options Expression does not produce an Options string"); } } } }