/// <summary> /// Compares the given pattern members, throwing a "Type Error" whenever the comparison operator detects sematically incompatible members; /// </summary> internal static Int32 CompareRDFPatternMembers(RDFPatternMember left, RDFPatternMember right) { #region NULLS if (left == null) { if (right == null) { return(0); } return(-1); } if (right == null) { return(1); } #endregion #region RESOURCE/CONTEXT if (left is RDFResource || left is RDFContext) { //RESOURCE/CONTEXT VS RESOURCE/CONTEXT/PLAINLITERAL if (right is RDFResource || right is RDFContext || right is RDFPlainLiteral) { return(String.Compare(left.ToString(), right.ToString(), StringComparison.Ordinal)); } //RESOURCE/CONTEXT VS TYPEDLITERAL else { if (((RDFTypedLiteral)right).HasStringDatatype()) { return(String.Compare(left.ToString(), ((RDFTypedLiteral)right).Value, StringComparison.Ordinal)); } return(-99); //Type Error } } #endregion #region PLAINLITERAL else if (left is RDFPlainLiteral) { //PLAINLITERAL VS RESOURCE/CONTEXT/PLAINLITERAL if (right is RDFResource || right is RDFContext || right is RDFPlainLiteral) { return(String.Compare(left.ToString(), right.ToString(), StringComparison.Ordinal)); } //PLAINLITERAL VS TYPEDLITERAL else { if (((RDFTypedLiteral)right).HasStringDatatype()) { return(String.Compare(left.ToString(), ((RDFTypedLiteral)right).Value, StringComparison.Ordinal)); } return(-99); //Type Error } } #endregion #region TYPEDLITERAL else { //TYPEDLITERAL VS RESOURCE/CONTEXT/PLAINLITERAL if (right is RDFResource || right is RDFContext || right is RDFPlainLiteral) { if (((RDFTypedLiteral)left).HasStringDatatype()) { return(String.Compare(((RDFTypedLiteral)left).Value, right.ToString(), StringComparison.Ordinal)); } return(-99); //Type Error } //TYPEDLITERAL VS TYPEDLITERAL else { if (((RDFTypedLiteral)left).HasBooleanDatatype() && ((RDFTypedLiteral)right).HasBooleanDatatype()) { Boolean leftValueBoolean = Boolean.Parse(((RDFTypedLiteral)left).Value); Boolean rightValueBoolean = Boolean.Parse(((RDFTypedLiteral)right).Value); return(leftValueBoolean.CompareTo(rightValueBoolean)); } else if (((RDFTypedLiteral)left).HasDatetimeDatatype() && ((RDFTypedLiteral)right).HasDatetimeDatatype()) { DateTime leftValueDateTime = DateTime.Parse(((RDFTypedLiteral)left).Value, CultureInfo.InvariantCulture, DateTimeStyles.AdjustToUniversal); DateTime rightValueDateTime = DateTime.Parse(((RDFTypedLiteral)right).Value, CultureInfo.InvariantCulture, DateTimeStyles.AdjustToUniversal); return(leftValueDateTime.CompareTo(rightValueDateTime)); } else if (((RDFTypedLiteral)left).HasDecimalDatatype() && ((RDFTypedLiteral)right).HasDecimalDatatype()) { Decimal leftValueDecimal = Decimal.Parse(((RDFTypedLiteral)left).Value, CultureInfo.InvariantCulture); Decimal rightValueDecimal = Decimal.Parse(((RDFTypedLiteral)right).Value, CultureInfo.InvariantCulture); return(leftValueDecimal.CompareTo(rightValueDecimal)); } else if (((RDFTypedLiteral)left).HasStringDatatype() && ((RDFTypedLiteral)right).HasStringDatatype()) { String leftValueString = ((RDFTypedLiteral)left).Value; String rightValueString = ((RDFTypedLiteral)right).Value; return(leftValueString.CompareTo(rightValueString)); } else if (((RDFTypedLiteral)left).HasTimespanDatatype() && ((RDFTypedLiteral)right).HasTimespanDatatype()) { TimeSpan leftValueDuration = XmlConvert.ToTimeSpan(((RDFTypedLiteral)left).Value); TimeSpan rightValueDuration = XmlConvert.ToTimeSpan(((RDFTypedLiteral)right).Value); return(leftValueDuration.CompareTo(rightValueDuration)); } else { return(-99); //Type Error } } } #endregion }
/// <summary> /// Applies the filter on the column corresponding to the pattern in the given datarow /// </summary> internal override Boolean ApplyFilter(DataRow row, Boolean applyNegation) { Boolean keepRow = false; EnumerableRowCollection <DataRow> patternResultsEnumerable = this.PatternResults?.AsEnumerable(); if (patternResultsEnumerable?.Any() ?? false) { #region Disjoint Evaluation //In case of disjointess between the query and the filter's pattern, all solutions are compatible Boolean disjointSubject = this.Pattern.Subject is RDFVariable ? !row.Table.Columns.Contains(this.Pattern.Subject.ToString()) : true; Boolean disjointPredicate = this.Pattern.Predicate is RDFVariable ? !row.Table.Columns.Contains(this.Pattern.Predicate.ToString()) : true; Boolean disjointObject = this.Pattern.Object is RDFVariable ? !row.Table.Columns.Contains(this.Pattern.Object.ToString()) : true; if (disjointSubject && disjointPredicate && disjointObject) { keepRow = true; } #endregion #region Non-Disjoint Evaluation else { #region Subject Boolean subjectCompared = false; if (this.Pattern.Subject is RDFVariable && this.PatternResults.Columns.Contains(this.Pattern.Subject.ToString()) && row.Table.Columns.Contains(this.Pattern.Subject.ToString())) { //In case of emptiness the solution is compatible, otherwise proceed with comparison if (!row.IsNull(this.Pattern.Subject.ToString())) { //Get subject filter's value for the given row RDFPatternMember rowMember = RDFQueryUtilities.ParseRDFPatternMember(row[this.Pattern.Subject.ToString()].ToString()); //Apply subject filter on the pattern resultset patternResultsEnumerable = patternResultsEnumerable.Where(x => RDFQueryUtilities.ParseRDFPatternMember(x.Field <String>(this.Pattern.Subject.ToString())).Equals(rowMember)); } subjectCompared = true; } #endregion #region Predicate Boolean predicateCompared = false; if (this.Pattern.Predicate is RDFVariable && this.PatternResults.Columns.Contains(this.Pattern.Predicate.ToString()) && row.Table.Columns.Contains(this.Pattern.Predicate.ToString())) { //In case of emptiness the solution is compatible, otherwise proceed with comparison if (!row.IsNull(this.Pattern.Predicate.ToString())) { //Get predicate filter's value for the given row RDFPatternMember rowMember = RDFQueryUtilities.ParseRDFPatternMember(row[this.Pattern.Predicate.ToString()].ToString()); //Apply predicate filter on the pattern resultset patternResultsEnumerable = patternResultsEnumerable.Where(x => RDFQueryUtilities.ParseRDFPatternMember(x.Field <String>(this.Pattern.Predicate.ToString())).Equals(rowMember)); } predicateCompared = true; } #endregion #region Object Boolean objectCompared = false; if (this.Pattern.Object is RDFVariable && this.PatternResults.Columns.Contains(this.Pattern.Object.ToString()) && row.Table.Columns.Contains(this.Pattern.Object.ToString())) { //In case of emptiness the solution is compatible, otherwise proceed with comparison if (!row.IsNull(this.Pattern.Object.ToString())) { //Get object filter's value for the given row RDFPatternMember rowMember = RDFQueryUtilities.ParseRDFPatternMember(row[this.Pattern.Object.ToString()].ToString()); //Apply object filter on the pattern resultset patternResultsEnumerable = patternResultsEnumerable.Where(x => RDFQueryUtilities.ParseRDFPatternMember(x.Field <String>(this.Pattern.Object.ToString())).Equals(rowMember)); } objectCompared = true; } #endregion #region Decision //Verify filter's response on the pattern resultset if ((subjectCompared || predicateCompared || objectCompared) && patternResultsEnumerable.ToList().Any()) { keepRow = true; } #endregion } #endregion } //Apply the eventual negation if (applyNegation) { keepRow = !keepRow; } return(keepRow); }
/// <summary> /// Default-ctor to build a comparison filter of the given type on the given filters /// </summary> public RDFComparisonFilter(RDFQueryEnums.RDFComparisonFlavors comparisonFlavor, RDFPatternMember leftMember, RDFPatternMember rightMember) { if (leftMember != null) { if (rightMember != null) { this.ComparisonFlavor = comparisonFlavor; this.LeftMember = leftMember; this.RightMember = rightMember; } else { throw new RDFQueryException("Cannot create RDFComparisonFilter because given \"rightMember\" parameter is null."); } } else { throw new RDFQueryException("Cannot create RDFComparisonFilter because given \"leftMember\" parameter is null."); } }
/// <summary> /// Gets the list of patterns corresponding to the path /// </summary> internal List <RDFPattern> GetPatternList() { List <RDFPattern> patterns = new List <RDFPattern>(); #region Single Property if (this.Steps.Count == 1) { //InversePath (swap start/end) if (this.Steps[0].IsInverseStep) { patterns.Add(new RDFPattern(this.End, this.Steps[0].StepProperty, this.Start)); } //Path else { patterns.Add(new RDFPattern(this.Start, this.Steps[0].StepProperty, this.End)); } } #endregion #region Multiple Properties else { RDFPatternMember currStart = this.Start; RDFPatternMember currEnd = new RDFVariable("__PP0"); for (int i = 0; i < this.Steps.Count; i++) { #region Alternative if (this.Steps[i].StepFlavor == RDFQueryEnums.RDFPropertyPathStepFlavors.Alternative) { //Translate to union (item is not the last alternative) if (i < this.Steps.Count - 1 && this.Steps[i + 1].StepFlavor == RDFQueryEnums.RDFPropertyPathStepFlavors.Alternative) { //Adjust start/end if (!this.Steps.Any(p => p.StepFlavor == RDFQueryEnums.RDFPropertyPathStepFlavors.Sequence && p.StepOrdinal > i)) { currEnd = this.End; } //InversePath (swap start/end) if (this.Steps[i].IsInverseStep) { patterns.Add(new RDFPattern(currEnd, this.Steps[i].StepProperty, currStart).UnionWithNext()); } //Path else { patterns.Add(new RDFPattern(currStart, this.Steps[i].StepProperty, currEnd).UnionWithNext()); } } //Translate to pattern (item is the last alternative) else { //InversePath (swap start/end) if (this.Steps[i].IsInverseStep) { patterns.Add(new RDFPattern(currEnd, this.Steps[i].StepProperty, currStart)); } //Path else { patterns.Add(new RDFPattern(currStart, this.Steps[i].StepProperty, currEnd)); } //Adjust start/end if (i < this.Steps.Count - 1) { currStart = currEnd; if (i == this.Steps.Count - 2 || !this.Steps.Any(p => p.StepFlavor == RDFQueryEnums.RDFPropertyPathStepFlavors.Sequence && p.StepOrdinal > i)) { currEnd = this.End; } else { currEnd = new RDFVariable(string.Concat("__PP", (i + 1).ToString())); } } } } #endregion #region Sequence else { //InversePath (swap start/end) if (this.Steps[i].IsInverseStep) { patterns.Add(new RDFPattern(currEnd, this.Steps[i].StepProperty, currStart)); } //Path else { patterns.Add(new RDFPattern(currStart, this.Steps[i].StepProperty, currEnd)); } //Adjust start/end if (i < this.Steps.Count - 1) { currStart = currEnd; if (i == this.Steps.Count - 2) { currEnd = this.End; } else { currEnd = new RDFVariable(string.Concat("__PP", (i + 1).ToString())); } } } #endregion } } #endregion return(patterns); }
/// <summary> /// Default ctor for SPO pattern /// </summary> public RDFPattern(RDFPatternMember subject, RDFPatternMember predicate, RDFPatternMember objLit) { this.Variables = new List <RDFVariable>(); this.IsEvaluable = true; this.IsOptional = false; this.JoinAsUnion = false; //Subject if (subject != null) { if (subject is RDFResource || subject is RDFVariable) { this.Subject = subject; if (subject is RDFVariable) { if (!this.Variables.Any(v => v.Equals(subject))) { this.Variables.Add((RDFVariable)subject); } } } else { throw new RDFQueryException("Cannot create RDFPattern because given \"subject\" parameter (" + subject + ") is neither a resource or a variable"); } } else { throw new RDFQueryException("Cannot create RDFPattern because given \"subject\" parameter is null"); } //Predicate if (predicate != null) { if (predicate is RDFResource || predicate is RDFVariable) { if (predicate is RDFResource && ((RDFResource)predicate).IsBlank) { throw new RDFQueryException("Cannot create RDFPattern because given \"predicate\" parameter is a blank resource"); } this.Predicate = predicate; if (predicate is RDFVariable) { if (!this.Variables.Any(v => v.Equals(predicate))) { this.Variables.Add((RDFVariable)predicate); } } } else { throw new RDFQueryException("Cannot create RDFPattern because given \"predicate\" parameter (" + predicate + ") is neither a resource or a variable"); } } else { throw new RDFQueryException("Cannot create RDFPattern because given \"predicate\" parameter is null"); } //Object/Literal if (objLit != null) { if (objLit is RDFResource || objLit is RDFLiteral || objLit is RDFVariable) { this.Object = objLit; if (objLit is RDFVariable) { if (!this.Variables.Any(v => v.Equals(objLit))) { this.Variables.Add((RDFVariable)objLit); } } } else { throw new RDFQueryException("Cannot create RDFPattern because given \"objLit\" parameter (" + objLit + ") is neither a resource, or a literal or a variable"); } } else { throw new RDFQueryException("Cannot create RDFPattern because given \"objLit\" parameter is null"); } }
/// <summary> /// Default ctor for CSPO pattern /// </summary> public RDFPattern(RDFPatternMember context, RDFPatternMember subject, RDFPatternMember predicate, RDFPatternMember objLit) : this(subject, predicate, objLit) { //Context if (context != null) { if (context is RDFContext || context is RDFVariable) { this.Context = context; if (context is RDFVariable) { if (!this.Variables.Any(v => v.Equals(context))) { this.Variables.Add((RDFVariable)context); } } } else { throw new RDFQueryException("Cannot create RDFPattern because given \"context\" parameter (" + context + ") is neither a context or a variable"); } } else { throw new RDFQueryException("Cannot create RDFPattern because given \"context\" parameter is null"); } }
/// <summary> /// Writes the "SPARQL Query Results XML Format" stream corresponding to the SELECT query result /// </summary> public void ToSparqlXmlResult(Stream outputStream) { try { #region serialize using (XmlTextWriter sparqlWriter = new XmlTextWriter(outputStream, Encoding.UTF8)) { XmlDocument sparqlDoc = new XmlDocument(); sparqlWriter.Formatting = Formatting.Indented; #region xmlDecl XmlDeclaration sparqlDecl = sparqlDoc.CreateXmlDeclaration("1.0", "UTF-8", null); sparqlDoc.AppendChild(sparqlDecl); #endregion #region sparqlRoot XmlNode sparqlRoot = sparqlDoc.CreateNode(XmlNodeType.Element, "sparql", null); XmlAttribute sparqlRootNS = sparqlDoc.CreateAttribute("xmlns"); XmlText sparqlRootNSText = sparqlDoc.CreateTextNode("http://www.w3.org/2005/sparql-results#"); sparqlRootNS.AppendChild(sparqlRootNSText); sparqlRoot.Attributes.Append(sparqlRootNS); #region sparqlHead XmlNode sparqlHeadElement = sparqlDoc.CreateNode(XmlNodeType.Element, "head", null); IEnumerator resultColumns = this.SelectResults.Columns.GetEnumerator(); while (resultColumns.MoveNext()) { XmlNode variableElement = sparqlDoc.CreateNode(XmlNodeType.Element, "variable", null); XmlAttribute varElName = sparqlDoc.CreateAttribute("name"); XmlText varElNameText = sparqlDoc.CreateTextNode(resultColumns.Current.ToString()); varElName.AppendChild(varElNameText); variableElement.Attributes.Append(varElName); sparqlHeadElement.AppendChild(variableElement); } sparqlRoot.AppendChild(sparqlHeadElement); #endregion #region sparqlResults XmlNode sparqlResultsElement = sparqlDoc.CreateNode(XmlNodeType.Element, "results", null); IEnumerator resultRows = this.SelectResults.Rows.GetEnumerator(); while (resultRows.MoveNext()) { resultColumns.Reset(); XmlNode resultElement = sparqlDoc.CreateNode(XmlNodeType.Element, "result", null); while (resultColumns.MoveNext()) { if (!((DataRow)resultRows.Current).IsNull(resultColumns.Current.ToString())) { XmlNode bindingElement = sparqlDoc.CreateNode(XmlNodeType.Element, "binding", null); XmlAttribute bindElName = sparqlDoc.CreateAttribute("name"); XmlText bindElNameText = sparqlDoc.CreateTextNode(resultColumns.Current.ToString()); bindElName.AppendChild(bindElNameText); bindingElement.Attributes.Append(bindElName); #region RDFTerm RDFPatternMember rdfTerm = RDFQueryUtilities.ParseRDFPatternMember(((DataRow)resultRows.Current)[resultColumns.Current.ToString()].ToString()); if (rdfTerm is RDFResource) { if (rdfTerm.ToString().StartsWith("bnode:")) { XmlNode bnodeElement = sparqlDoc.CreateNode(XmlNodeType.Element, "bnode", null); XmlText bnodeElText = sparqlDoc.CreateTextNode(rdfTerm.ToString()); bnodeElement.AppendChild(bnodeElText); bindingElement.AppendChild(bnodeElement); } else { XmlNode uriElement = sparqlDoc.CreateNode(XmlNodeType.Element, "uri", null); XmlText uriElText = sparqlDoc.CreateTextNode(rdfTerm.ToString()); uriElement.AppendChild(uriElText); bindingElement.AppendChild(uriElement); } } else if (rdfTerm is RDFLiteral) { XmlNode litElement = sparqlDoc.CreateNode(XmlNodeType.Element, "literal", null); if (rdfTerm is RDFPlainLiteral) { if (((RDFPlainLiteral)rdfTerm).Language != String.Empty) { XmlAttribute xmlLang = sparqlDoc.CreateAttribute(RDFVocabulary.XML.PREFIX + ":lang", RDFVocabulary.XML.BASE_URI); XmlText xmlLangText = sparqlDoc.CreateTextNode(((RDFPlainLiteral)rdfTerm).Language); xmlLang.AppendChild(xmlLangText); litElement.Attributes.Append(xmlLang); } XmlText plainLiteralText = sparqlDoc.CreateTextNode(RDFModelUtilities.EscapeControlCharsForXML(HttpUtility.HtmlDecode(((RDFLiteral)rdfTerm).Value))); litElement.AppendChild(plainLiteralText); } else { XmlAttribute datatype = sparqlDoc.CreateAttribute("datatype"); XmlText datatypeText = sparqlDoc.CreateTextNode(RDFModelUtilities.GetDatatypeFromEnum(((RDFTypedLiteral)rdfTerm).Datatype)); datatype.AppendChild(datatypeText); litElement.Attributes.Append(datatype); XmlText typedLiteralText = sparqlDoc.CreateTextNode(RDFModelUtilities.EscapeControlCharsForXML(HttpUtility.HtmlDecode(((RDFLiteral)rdfTerm).Value))); litElement.AppendChild(typedLiteralText); } bindingElement.AppendChild(litElement); } #endregion resultElement.AppendChild(bindingElement); } } sparqlResultsElement.AppendChild(resultElement); } sparqlRoot.AppendChild(sparqlResultsElement); #endregion sparqlDoc.AppendChild(sparqlRoot); #endregion sparqlDoc.Save(sparqlWriter); } #endregion } catch (Exception ex) { throw new RDFQueryException("Cannot serialize SPARQL XML RESULT because: " + ex.Message, ex); } }
/// <summary> /// Prints the string representation of a pattern member /// </summary> internal static String PrintPatternMember(RDFPatternMember patternMember, List <RDFNamespace> prefixes) { if (patternMember != null) { #region Variable if (patternMember is RDFVariable) { return(patternMember.ToString()); } #endregion #region Resource/Context if (patternMember is RDFResource || patternMember is RDFContext) { #region Blank if (patternMember is RDFResource && ((RDFResource)patternMember).IsBlank) { return(patternMember.ToString().Replace("bnode:", "_:")); } #endregion #region NonBlank var abbreviatedPM = RDFQueryUtilities.AbbreviateRDFPatternMember(patternMember, prefixes); if (abbreviatedPM.Item1) { return(abbreviatedPM.Item2); } else { return("<" + abbreviatedPM.Item2 + ">"); } #endregion } #endregion #region Literal if (patternMember is RDFLiteral) { #region PlainLiteral if (patternMember is RDFPlainLiteral) { if (((RDFPlainLiteral)patternMember).Language != String.Empty) { return("\"" + ((RDFPlainLiteral)patternMember).Value + "\"@" + ((RDFPlainLiteral)patternMember).Language); } return("\"" + ((RDFPlainLiteral)patternMember).Value + "\""); } #endregion #region TypedLiteral else { var abbreviatedPM = RDFQueryUtilities.AbbreviateRDFPatternMember(RDFQueryUtilities.ParseRDFPatternMember(RDFModelUtilities.GetDatatypeFromEnum(((RDFTypedLiteral)patternMember).Datatype)), prefixes); if (abbreviatedPM.Item1) { return("\"" + ((RDFTypedLiteral)patternMember).Value + "\"^^" + abbreviatedPM.Item2); } else { return("\"" + ((RDFTypedLiteral)patternMember).Value + "\"^^<" + abbreviatedPM.Item2 + ">"); } } #endregion } #endregion } return(null); }