package org.aksw.sparqlify.util;
import java.util.Map;
import org.aksw.jena_sparql_api.views.E_RdfTerm;
import org.aksw.jena_sparql_api.views.ExprEvaluator;
import org.aksw.sparqlify.algebra.sql.exprs2.ExprSqlBridge;
import org.aksw.sparqlify.algebra.sql.exprs2.SqlExpr;
import org.aksw.sparqlify.core.TypeToken;
import org.aksw.sparqlify.core.algorithms.ExprSqlRewrite;
import org.aksw.sparqlify.core.cast.ExprBindingSubstitutor;
import org.aksw.sparqlify.core.cast.TypedExprTransformer;
import org.aksw.sparqlify.core.interfaces.SqlTranslator;
import org.aksw.sparqlify.core.rewrite.expr.transform.RdfTermEliminator;
import org.apache.jena.sparql.core.Var;
import org.apache.jena.sparql.expr.Expr;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class SqlTranslatorImpl2
implements SqlTranslator
{
private static final Logger logger = LoggerFactory.getLogger(SqlTranslatorImpl2.class);
private ExprBindingSubstitutor exprBindingSubstitutor;
private RdfTermEliminator rdfTermEliminator;
private ExprEvaluator exprEvaluator;
private TypedExprTransformer typedExprTransformer;
public SqlTranslatorImpl2(ExprBindingSubstitutor exprBindingSubstitutor, RdfTermEliminator rdfTermEliminator, ExprEvaluator exprTransformer, TypedExprTransformer typedExprTransformer) {
this.exprBindingSubstitutor = exprBindingSubstitutor;
this.rdfTermEliminator = rdfTermEliminator;
this.exprEvaluator = exprTransformer;
this.typedExprTransformer = typedExprTransformer;
}
public RdfTermEliminator getRdfTermEliminator() {
return rdfTermEliminator;
}
public TypedExprTransformer getTypedExprTransformer() {
return typedExprTransformer;
}
/**
* TODO: There are two use cases:
* a) Rewrite an expression completely to SQL -> result is an SqlExpr object
* b) Partially rewrite an expression to SQL -> result is an SqlExprRewrite object
*
* I think the interface should return the SqlExprRewrite and
* a static helper function then extracts the SqlExpr from it
*
*/
@Override
public ExprSqlRewrite translate(Expr sparqlExpr, Map<Var, Expr> binding,
Map<String, TypeToken> typeMap) {
Expr e1;
// Obtain an 'integrated' expression by replacing variables in the sparqlExpr with corresponding expressions of the binding
if(binding != null) {
e1 = exprBindingSubstitutor.substitute(sparqlExpr, binding);
} else {
e1 = sparqlExpr;
}
E_RdfTerm e2 = rdfTermEliminator._transform(e1);
Expr e3 = exprEvaluator.transform(e2);
//System.out.println("[ExprRewrite Phase 2]: " + e2);
ExprSqlRewrite e4 = typedExprTransformer.rewrite(e3, typeMap);
//logger.debug("[ExprRewrite Phase 4]: " + e4);
return e4;
}
/**
* Assumes that the rewrite's root expression is of type E_RdfTerm.
* Returns the SQL expression (if exists) corresponding to its value component.
*
* @param rewrite
* @return
*/
public static SqlExpr asSqlExpr(ExprSqlRewrite rewrite) {
Expr tmp = rewrite.getExpr();
if(!(tmp instanceof E_RdfTerm)) {
throw new RuntimeException("Wrong expression type - hould not happen");
}
E_RdfTerm rdfTerm = (E_RdfTerm)tmp;
Expr et = rdfTerm.getLexicalValue();
if(et.isVariable()) {
String varName = et.getVarName();
SqlExpr result = rewrite.getProjection().getNameToExpr().get(varName);
return result;
} else {
throw new RuntimeException("Could not completely rewrite: " + rewrite + " --- stopped at: " + et);
}
}
public static SqlExpr asSqlExprOld(ExprSqlRewrite rewrite) {
Expr et = rewrite.getExpr();
if(et instanceof ExprSqlBridge) {
ExprSqlBridge bridge = (ExprSqlBridge)et;
SqlExpr result = bridge.getSqlExpr();
return result;
} else {
throw new RuntimeException("Could not completely rewrite: " + rewrite + " --- stopped at: " + et);
}
}
}