/// <summary> /// Prints the string representation of a SPARQL SELECT query /// </summary> internal static String PrintSelectQuery(RDFSelectQuery selectQuery, Double indentLevel, Boolean fromUnion) { StringBuilder sb = new StringBuilder(); if (selectQuery != null) { #region INDENT Int32 subqueryHeaderSpacesFunc(Double indLevel) { return(subqueryBodySpacesFunc(indentLevel) - 2 < 0 ? 0 : subqueryBodySpacesFunc(indentLevel) - 2); } Int32 subqueryBodySpacesFunc(Double indLevel) { return(Convert.ToInt32(4 * indentLevel)); } Int32 subqueryUnionSpacesFunc(Boolean union) { return(union ? 2 : 0); } String subquerySpaces = new String(' ', subqueryHeaderSpacesFunc(indentLevel) + subqueryUnionSpacesFunc(fromUnion)); String subqueryBodySpaces = new String(' ', subqueryBodySpacesFunc(indentLevel) + subqueryUnionSpacesFunc(fromUnion)); #endregion #region PREFIX if (!selectQuery.IsSubQuery) { if (selectQuery.Prefixes.Any()) { selectQuery.Prefixes.ForEach(pf => { sb.Append("PREFIX " + pf.NamespacePrefix + ": <" + pf.NamespaceUri + ">\n"); }); sb.Append("\n"); } } #endregion #region HEADER #region BEGINSELECT if (selectQuery.IsSubQuery) { if (selectQuery.IsOptional && !fromUnion) { sb.Append(subquerySpaces + "OPTIONAL {\n"); } else { sb.Append(subquerySpaces + "{\n"); } } sb.Append(subqueryBodySpaces + "SELECT"); #endregion #region DISTINCT selectQuery.GetModifiers() .Where(mod => mod is RDFDistinctModifier) .ToList() .ForEach(dm => sb.Append(" " + dm)); #endregion #region VARIABLES if (selectQuery.ProjectionVars.Any()) { selectQuery.ProjectionVars.OrderBy(x => x.Value) .ToList() .ForEach(v => sb.Append(" " + v.Key)); } else { sb.Append(" *"); } sb.Append("\n"); #endregion #endregion #region BODY sb.Append(subqueryBodySpaces + "WHERE {\n"); #region MEMBERS Boolean printingUnion = false; List <RDFQueryMember> evaluableQueryMembers = selectQuery.GetEvaluableQueryMembers().ToList(); RDFQueryMember lastQueryMbr = evaluableQueryMembers.LastOrDefault(); foreach (var queryMember in evaluableQueryMembers) { #region PATTERNGROUPS if (queryMember is RDFPatternGroup) { //Current pattern group is set as UNION with the next one if (((RDFPatternGroup)queryMember).JoinAsUnion) { //Current pattern group IS NOT the last of the query //(so UNION keyword must be appended at last) if (!queryMember.Equals(lastQueryMbr)) { //Begin a new Union block if (!printingUnion) { printingUnion = true; sb.Append(subqueryBodySpaces + " {\n"); } sb.Append(PrintPatternGroup((RDFPatternGroup)queryMember, subqueryBodySpaces.Length + 2, true, selectQuery.Prefixes)); sb.Append(subqueryBodySpaces + " UNION\n"); } //Current pattern group IS the last of the query //(so UNION keyword must not be appended at last) else { //End the Union block if (printingUnion) { printingUnion = false; sb.Append(PrintPatternGroup((RDFPatternGroup)queryMember, subqueryBodySpaces.Length + 2, true, selectQuery.Prefixes)); sb.Append(subqueryBodySpaces + " }\n"); } else { sb.Append(PrintPatternGroup((RDFPatternGroup)queryMember, subqueryBodySpaces.Length, false, selectQuery.Prefixes)); } } } //Current pattern group is set as INTERSECT with the next one else { //End the Union block if (printingUnion) { printingUnion = false; sb.Append(PrintPatternGroup((RDFPatternGroup)queryMember, subqueryBodySpaces.Length + 2, true, selectQuery.Prefixes)); sb.Append(subqueryBodySpaces + " }\n"); } else { sb.Append(PrintPatternGroup((RDFPatternGroup)queryMember, subqueryBodySpaces.Length, false, selectQuery.Prefixes)); } } } #endregion #region SUBQUERY else if (queryMember is RDFQuery) { //Merge main query prefixes selectQuery.Prefixes.ForEach(pf1 => { if (!((RDFSelectQuery)queryMember).Prefixes.Any(pf2 => pf2.Equals(pf1))) { ((RDFSelectQuery)queryMember).AddPrefix(pf1); } }); //Current subquery is set as UNION with the next one if (((RDFSelectQuery)queryMember).JoinAsUnion) { //Current subquery IS NOT the last of the query //(so UNION keyword must be appended at last) if (!queryMember.Equals(lastQueryMbr)) { //Begin a new Union block if (!printingUnion) { printingUnion = true; sb.Append(subqueryBodySpaces + " {\n"); } sb.Append(PrintSelectQuery((RDFSelectQuery)queryMember, indentLevel + 1 + (fromUnion ? 0.5 : 0), true)); sb.Append(subqueryBodySpaces + " UNION\n"); } //Current query IS the last of the query //(so UNION keyword must not be appended at last) else { //End the Union block if (printingUnion) { printingUnion = false; sb.Append(PrintSelectQuery((RDFSelectQuery)queryMember, indentLevel + 1 + (fromUnion ? 0.5 : 0), true)); sb.Append(subqueryBodySpaces + " }\n"); } else { sb.Append(PrintSelectQuery((RDFSelectQuery)queryMember, indentLevel + 1 + (fromUnion ? 0.5 : 0), false)); } } } //Current query is set as INTERSECT with the next one else { //End the Union block if (printingUnion) { printingUnion = false; sb.Append(PrintSelectQuery((RDFSelectQuery)queryMember, indentLevel + 1 + (fromUnion ? 0.5 : 0), true)); sb.Append(subqueryBodySpaces + " }\n"); } else { sb.Append(PrintSelectQuery((RDFSelectQuery)queryMember, indentLevel + 1 + (fromUnion ? 0.5 : 0), false)); } } } #endregion } #endregion sb.Append(subqueryBodySpaces + "}"); #endregion #region FOOTER #region MODIFIERS List <RDFModifier> modifiers = selectQuery.GetModifiers().ToList(); // ORDER BY if (modifiers.Any(mod => mod is RDFOrderByModifier)) { sb.Append("\n"); sb.Append(subqueryBodySpaces + "ORDER BY"); modifiers.Where(mod => mod is RDFOrderByModifier) .ToList() .ForEach(om => sb.Append(" " + om)); } // LIMIT/OFFSET if (modifiers.Any(mod => mod is RDFLimitModifier || mod is RDFOffsetModifier)) { modifiers.Where(mod => mod is RDFLimitModifier) .ToList() .ForEach(lim => { sb.Append("\n"); sb.Append(subqueryBodySpaces + lim); }); modifiers.Where(mod => mod is RDFOffsetModifier) .ToList() .ForEach(off => { sb.Append("\n"); sb.Append(subqueryBodySpaces + off); }); } #endregion #region ENDSELECT sb.Append("\n"); if (selectQuery.IsSubQuery) { sb.Append(subquerySpaces + "}\n"); } #endregion #endregion } return(sb.ToString()); }