
com.weaverplatform.sp4rql.model.solution.SolutionFactory Maven / Gradle / Ivy
package com.weaverplatform.sp4rql.model.solution;
import com.weaverplatform.sp4rql.error.ParseException;
import com.weaverplatform.sp4rql.model.expression.ExpressionUnit;
import com.weaverplatform.sp4rql.model.restriction.Sp4rqlRestriction;
import com.weaverplatform.sp4rql.model.scope.ScopeQuery;
import com.weaverplatform.sp4rql.model.scope.Sp4rqlScope;
import com.weaverplatform.sp4rql.model.token.VariableToken;
public class SolutionFactory {
// When this function is called we can be sure all scopes and restrictions are instantiated and linked
public static void buildSolutions(Sp4rqlScope scope) {
scope.resetSolutions();
buildSubSolutions(scope);
updateResolvesTo(scope);
}
private static void buildSubSolutions(Sp4rqlScope scope) {
// Register all tokens from restrictions in this scope
for(Sp4rqlRestriction restriction : scope.getRestrictions()) {
for(VariableToken token : restriction.getExposedVariables()) {
Sp4rqlSolution solution = registerToken(token, scope);
solution.addRestriction(restriction);
}
}
// Register all tokens from select mappings
if(scope instanceof ScopeQuery) {
ScopeQuery scopeQuery = (ScopeQuery) scope;
for(VariableToken token : scopeQuery.getSelectVariables()) {
ExpressionUnit expression = scopeQuery.getSelectExpression(token);
// Variable expression is null for normal selects
if(expression != null) {
if(!expression.isAggregate()) {
throw new ParseException("Expected an expression with a aggregate function");
}
Sp4rqlSolution solution = registerToken(token, scope);
solution.setAggregationExpression(expression);
}
}
}
// Register all tokens from 'scoped expressions' (only exists and not exists) in this scope
for(Sp4rqlScope expressionScope : scope.getExpressionScopes()) {
for(VariableToken token : expressionScope.getExposedVariables()) {
Sp4rqlSolution solution = registerToken(token, scope);
solution.addRestriction(expressionScope);
}
}
// Analyse all scopes
for(Sp4rqlSolution solution : scope.getSolutions()) {
solution.analyseTypes();
}
// Visit all sub-scopes recursively
for(Sp4rqlRestriction restriction : scope.getRestrictions()) {
if(restriction instanceof Sp4rqlScope) {
buildSubSolutions((Sp4rqlScope) restriction);
}
}
for(Sp4rqlRestriction restriction : scope.getExpressionScopes()) {
if(restriction instanceof Sp4rqlScope) {
buildSubSolutions((Sp4rqlScope) restriction);
}
}
}
public static Sp4rqlSolution registerToken(VariableToken token, Sp4rqlScope scope) {
Sp4rqlSolution solution = scope.getSolution(token);
if(solution != null) {
return solution;
}
boolean escalate = false;
if(scope.inScope() != null) {
escalate |= scope.getExposedVariables().contains(token);
}
if(escalate) {
solution = registerToken(token, scope.inScope());
scope.setSolution(token, solution);
return solution;
} else {
solution = new Sp4rqlSolution(token);
solution.setScope(scope);
scope.setSolution(token, solution);
return solution;
}
}
private static void updateResolvesTo(Sp4rqlScope scope) {
// Update resolveTo values
for(Sp4rqlRestriction restriction : scope.getRestrictions()) {
if(restriction instanceof Sp4rqlScope) {
updateResolvesTo((Sp4rqlScope) restriction);
}
}
// Make sure all equalSolutions are attuned
for(Sp4rqlSolution solution : scope.getSolutions()) {
solution.tuneEqualSolutions();
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy