Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,7 @@
import fr.inria.corese.core.sparql.triple.parser.Expression;
import fr.inria.corese.core.sparql.triple.parser.Variable;

import java.util.ArrayList;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Objects;
import java.util.*;

/**
* Builds KGRAM {@code Exp} / {@code Query} structures from Corese-next query AST nodes.
Expand Down Expand Up @@ -59,14 +56,18 @@ public CoreseAstQueryBuilder() {
public Query toNextQuery(AskQueryAst askQueryAst) {
Objects.requireNonNull(askQueryAst, "askQueryAst");
rejectUnsupportedAskClauses(askQueryAst);

Query query = createQuery(
askQueryAst.whereClause(),
askQueryAst.datasetClause(),
askQueryAst.solutionModifier());
applyOrderBy(query, askQueryAst.solutionModifier());
query.setAsk(true);
return query;
SparqlAstToExpression.setPrefixes(buildPrefixMap(askQueryAst.prologue().prefixDeclarations()));
try {
Query query = createQuery(
askQueryAst.whereClause(),
askQueryAst.datasetClause(),
askQueryAst.solutionModifier());
applyOrderBy(query, askQueryAst.solutionModifier());
query.setAsk(true);
return query;
} finally {
SparqlAstToExpression.clearPrefixes();
}
}

/**
Expand All @@ -81,15 +82,19 @@ public Query toNextQuery(AskQueryAst askQueryAst) {
public Query toNextQuery(SelectQueryAst selectQueryAst) {
Objects.requireNonNull(selectQueryAst, "selectQueryAst");
rejectUnsupportedSelectClauses(selectQueryAst);

Query query = createQuery(
selectQueryAst.whereClause(),
selectQueryAst.datasetClause(),
selectQueryAst.solutionModifier());
applyProjection(query, selectQueryAst.projection());
query.setDistinct(selectQueryAst.solutionModifier().distinct());
applyOrderBy(query, selectQueryAst.solutionModifier());
return query;
SparqlAstToExpression.setPrefixes(buildPrefixMap(selectQueryAst.prologue().prefixDeclarations()));
try {
Query query = createQuery(
selectQueryAst.whereClause(),
selectQueryAst.datasetClause(),
selectQueryAst.solutionModifier());
applyProjection(query, selectQueryAst.projection());
query.setDistinct(selectQueryAst.solutionModifier().distinct());
applyOrderBy(query, selectQueryAst.solutionModifier());
return query;
} finally {
SparqlAstToExpression.clearPrefixes();
}
}

/**
Expand All @@ -105,15 +110,19 @@ public Query toNextQuery(SelectQueryAst selectQueryAst) {
public Query toNextQuery(DescribeQueryAst describeQueryAst) {
Objects.requireNonNull(describeQueryAst, "describeQueryAst");
rejectUnsupportedDescribeClauses(describeQueryAst);

Query query = createQuery(
describeQueryAst.whereClause(),
describeQueryAst.datasetClause(),
describeQueryAst.solutionModifier());
applyOrderBy(query, describeQueryAst.solutionModifier());
List<Node> describedNodes = describeNodes(query, describeQueryAst);
lowerDescribeToConstructQuery(query, describedNodes);
return query;
SparqlAstToExpression.setPrefixes(buildPrefixMap(describeQueryAst.prologue().prefixDeclarations()));
try {
Query query = createQuery(
describeQueryAst.whereClause(),
describeQueryAst.datasetClause(),
describeQueryAst.solutionModifier());
applyOrderBy(query, describeQueryAst.solutionModifier());
List<Node> describedNodes = describeNodes(query, describeQueryAst);
lowerDescribeToConstructQuery(query, describedNodes);
return query;
} finally {
SparqlAstToExpression.clearPrefixes();
}
}

/**
Expand All @@ -129,38 +138,23 @@ public Query toNextQuery(DescribeQueryAst describeQueryAst) {
public Query toNextQuery(ConstructQueryAst constructQueryAst) {
Objects.requireNonNull(constructQueryAst, "constructQueryAst");
rejectUnsupportedConstructClauses(constructQueryAst);

Query query = createQuery(
constructQueryAst.whereClause(),
constructQueryAst.datasetClause(),
constructQueryAst.solutionModifier());
applyOrderBy(query, constructQueryAst.solutionModifier());
Exp template = compileConstructTemplate(query, constructQueryAst.constructTemplate());
query.setConstruct(true);
query.setConstruct(template);
query.setConstructNodes(template.getNodes());
return query;
}

/**
* Converts a filter expression carried as {@link TermAst}: must be a {@link ConstraintAst}.
*/
public Filter toNextFilter(TermAst filterExpression) {
Objects.requireNonNull(filterExpression, "filterExpression");
if (!(filterExpression instanceof ConstraintAst constraint)) {
throw new IllegalArgumentException(
"FILTER expects a ConstraintAst, got: " + filterExpression.getClass().getName());
SparqlAstToExpression.setPrefixes(buildPrefixMap(constructQueryAst.prologue().prefixDeclarations()));
try {
Query query = createQuery(
constructQueryAst.whereClause(),
constructQueryAst.datasetClause(),
constructQueryAst.solutionModifier());
applyOrderBy(query, constructQueryAst.solutionModifier());
Exp template = compileConstructTemplate(query, constructQueryAst.constructTemplate());
query.setConstruct(true);
query.setConstruct(template);
query.setConstructNodes(template.getNodes());
return query;
} finally {
SparqlAstToExpression.clearPrefixes();
}
return toNextFilter(constraint);
}

/**
* Converts a constraint tree (boolean filter expression) into a KGRAM {@link Filter}.
*/
public Filter toNextFilter(ConstraintAst filterExpression) {
Objects.requireNonNull(filterExpression, "filterExpression");
return SparqlAstToExpression.toNextFilter(filterExpression, whereCompiler);
}

/**
* Converts a query term used as subject, predicate, object, or variable reference
Expand Down Expand Up @@ -188,6 +182,14 @@ static TermAst simplePredicate(PathAst path) {
+ path.getClass().getSimpleName());
}

private static Map<String, String> buildPrefixMap(List<PrefixDeclarationAst> decls) {
Map<String, String> map = new HashMap<>(decls.size() * 2);
for (PrefixDeclarationAst decl : decls) {
map.put(decl.prefix(), decl.namespace().raw());
}
return map;
}

private static void rejectUnsupportedAskClauses(AskQueryAst askQueryAst) {
if (!askQueryAst.valuesClause().mappings().isEmpty()) {
throw new UnsupportedQueryFeatureException(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;

Expand All @@ -22,6 +23,25 @@
*/
public final class SparqlAstToExpression {

/**
* Per-thread prefix map for the query currently being compiled.
* Set by {@link #setPrefixes}/{@link #clearPrefixes} in {@link CoreseAstQueryBuilder}.
*/
private static final ThreadLocal<Map<String, String>> QUERY_PREFIXES = new ThreadLocal<>();

/** Package-private: called by {@link CoreseAstQueryBuilder} before building each query. */
static void setPrefixes(Map<String, String> prefixes) {
QUERY_PREFIXES.set(prefixes);
}

/** Package-private: called by {@link CoreseAstQueryBuilder} after building each query. */
static void clearPrefixes() {
QUERY_PREFIXES.remove();
}

private static final String BLANK_NODE_VAR_PREFIX = "__bn_";


private SparqlAstToExpression() {
}

Expand All @@ -33,6 +53,8 @@ public static Expression convert(TermAst term) {
case VarAst(String name) -> Variable.create(name);
case LiteralAst(String lexical, String lang, String datatype) ->
literalToConstant(lexical, lang, datatype);
case IriAst(String raw) when raw.startsWith(IOConstants.BLANK_NODE_PREFIX) ->
Variable.create(BLANK_NODE_VAR_PREFIX + raw.substring(IOConstants.BLANK_NODE_PREFIX.length()));
case IriAst(String raw) -> iriToConstant(raw);
case ConstraintAst c -> constraintToExpression(c);
default -> throw new IllegalStateException("Unhandled TermAst: " + term.getClass());
Expand All @@ -54,8 +76,8 @@ public static Filter toNextFilter(FilterAst filterClause, WhereCompiler whereCom
* Filters containing {@code EXISTS} / {@code NOT EXISTS} require
* {@link #toNextFilter(TermAst, WhereCompiler)} so their graph pattern can be compiled.
*/
public static Filter toNextFilter(TermAst filterExpression) {
return toNextFilter(filterExpression, null);
public static void toNextFilter(TermAst filterExpression) {
toNextFilter(filterExpression, null);
}

/**
Expand Down Expand Up @@ -137,6 +159,16 @@ private static Constant iriToConstant(String rawIri) {
if (raw.startsWith(IOConstants.BLANK_NODE_PREFIX)) {
return Constant.createBlank(raw.substring(IOConstants.BLANK_NODE_PREFIX.length()));
}
Map<String, String> prefixes = QUERY_PREFIXES.get();
if (prefixes != null) {
int colonIdx = raw.indexOf(':');
if (colonIdx > 0) {
String ns = prefixes.get(raw.substring(0, colonIdx));
if (ns != null) {
raw = ns + raw.substring(colonIdx + 1);
}
}
}
return Constant.createResource(raw);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ void iriAstToExpression() {
assertNotNull(iriNode);
assertInstanceOf(Constant.class, iriNode);
assertTrue(iriNode.isURI());
assertEquals("http://ns.inria.fr/test/iri", ((Constant)iriNode).getLabel());
assertEquals("http://ns.inria.fr/test/iri", iriNode.getLabel());
}

@Test
Expand Down
Loading
Loading