package org.xenei.jdbc4sparql.sparql.parser.jsqlparser;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import java.io.StringReader;
import java.lang.reflect.InvocationTargetException;
import java.sql.SQLDataException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.IdentityHashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import net.sf.jsqlparser.JSQLParserException;
import net.sf.jsqlparser.parser.CCJSqlParserManager;
import net.sf.jsqlparser.statement.Statement;
import org.apache.log4j.Level;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.xenei.jdbc4sparql.LoggingConfig;
import org.xenei.jdbc4sparql.iface.Catalog;
import org.xenei.jdbc4sparql.iface.name.TableName;
import org.xenei.jdbc4sparql.impl.rdf.RdfCatalog;
import org.xenei.jdbc4sparql.impl.rdf.RdfSchema;
import org.xenei.jdbc4sparql.impl.rdf.RdfTable;
import org.xenei.jdbc4sparql.impl.rdf.RdfTableDef;
import org.xenei.jdbc4sparql.impl.virtual.VirtualCatalog;
import org.xenei.jdbc4sparql.meta.MetaCatalogBuilder;
import org.xenei.jdbc4sparql.sparql.ForceTypeF;
import org.xenei.jdbc4sparql.sparql.parser.SparqlParser;
import org.xenei.jdbc4sparql.sparql.parser.jsqlparser.proxies.ExprInfo;
import org.xenei.jdbc4sparql.utils.ElementExtractor;
import com.hp.hpl.jena.graph.Node;
import com.hp.hpl.jena.query.Query;
import com.hp.hpl.jena.rdf.model.Model;
import com.hp.hpl.jena.rdf.model.ModelFactory;
import com.hp.hpl.jena.sparql.core.TriplePath;
import com.hp.hpl.jena.sparql.core.Var;
import com.hp.hpl.jena.sparql.expr.E_Function;
import com.hp.hpl.jena.sparql.expr.Expr;
import com.hp.hpl.jena.sparql.syntax.Element;
import com.hp.hpl.jena.sparql.syntax.ElementBind;
import com.hp.hpl.jena.sparql.syntax.ElementFilter;
import com.hp.hpl.jena.sparql.syntax.ElementOptional;
import com.hp.hpl.jena.sparql.syntax.ElementPathBlock;
/**
*
*
*/
abstract public class AbstractSparqlParserTest {
protected Model model;
protected SparqlParser parser;
protected Map<String, Catalog> catalogs;
protected RdfCatalog catalog;
protected RdfSchema schema;
protected final CCJSqlParserManager parserManager = new CCJSqlParserManager();
protected Query query;
protected Map<Class<? extends Element>, Integer> tests;
protected Map<Class<? extends Element>, Wrapper> results;
protected TableName fooTableName;
protected TableName barTableName;
protected List<String> vars;
protected static String RQD = "IntCol";
protected static String OPT = "NullableStringCol";
protected static String RQD_TEST = "StringCol";
protected static String OPT_TEST = "NullableIntCol";
@Before
public void setup() {
catalogs = new HashMap<String, Catalog>();
catalogs.put(VirtualCatalog.NAME, new VirtualCatalog());
LoggingConfig.setConsole(Level.DEBUG);
LoggingConfig.setRootLogger(Level.INFO);
LoggingConfig.setLogger("com.hp.hpl.jena.", Level.INFO);
LoggingConfig.setLogger("org.xenei.jdbc4sparql", Level.DEBUG);
model = ModelFactory.createDefaultModel();
final Model localModel = ModelFactory.createDefaultModel();
catalog = new RdfCatalog.Builder().setLocalModel(localModel)
.setName("testCatalog").build(model);
catalogs.put(catalog.getShortName(), catalog);
schema = new RdfSchema.Builder().setCatalog(catalog)
.setName("testSchema").build(model);
// create the foo table
final RdfTableDef tableDef = new RdfTableDef.Builder()
.addColumnDef(
MetaCatalogBuilder.getNonNullStringBuilder().build(
model))
.addColumnDef(
MetaCatalogBuilder.getNullStringBuilder().build(model))
.addColumnDef(
MetaCatalogBuilder.getNonNullIntBuilder().build(model))
.addColumnDef(
MetaCatalogBuilder.getNullIntBuilder().build(model))
.build(model);
RdfTable.Builder bldr = new RdfTable.Builder().setTableDef(tableDef)
.setColumn(0, "StringCol").setColumn(1, "NullableStringCol")
.setColumn(2, "IntCol").setColumn(3, "NullableIntCol")
.setName("foo").setSchema(schema)
.addQuerySegment("%1$s a <http://example.com/foo> . ");
bldr.getColumn(0).addQuerySegment(
"%1$s <http://example.com/zero> %2$s .");
bldr.getColumn(1).addQuerySegment(
"%1$s <http://example.com/one> %2$s . ");
bldr.getColumn(2).addQuerySegment(
"%1$s <http://example.com/two> %2$s . ");
bldr.getColumn(3).addQuerySegment(
"%1$s <http://example.com/three> %2$s .");
fooTableName = bldr.getName();
bldr.build(model);
bldr = new RdfTable.Builder().setTableDef(tableDef)
.setColumn(0, "BarStringCol")
.setColumn(1, "BarNullableStringCol")
.setColumn(2, "BarIntCol")
// must be NullableIntCol for inner join test
.setColumn(3, "NullableIntCol").setName("bar")
.setSchema(schema)
.addQuerySegment("%1$s a <http://example.com/bar> . ");
bldr.getColumn(0).addQuerySegment(
"%1$s <http://example.com/zero> %2$s . ");
bldr.getColumn(1).addQuerySegment(
"%1$s <http://example.com/one> %2$s . ");
bldr.getColumn(2).addQuerySegment(
"%1$s <http://example.com/two> %2$s . ");
bldr.getColumn(3).addQuerySegment(
"%1$s <http://example.com/three> %2$s . ");
barTableName = bldr.getName();
bldr.build(model);
parser = new SparqlParserImpl();
tests = new HashMap<Class<? extends Element>, Integer>();
}
@Test
public void testGetSupportedNumericFunctions() {
assertNotNull(parser.getSupportedNumericFunctions());
}
@Test
public void testGetSupportedStringFunctions() {
assertNotNull(parser.getSupportedStringFunctions());
}
@Test
public void testGetSupportedSystemFunctions() {
assertNotNull(parser.getSupportedSystemFunctions());
}
// /**
// * Parse the SQL string and then deparse it back into SQL to provide the
// SQL
// * string native to the parser. This is used in support of nativeSQL() in
// * the Driver.
// *
// * @param sqlQuery
// * the original SQL string
// * @return the native SQL string
// * @throws SQLException
// * on error.
// */
// String nativeSQL(String sqlQuery) throws SQLException;
protected Query getQuery(final String sql) throws SQLDataException,
JSQLParserException {
final Statement stmt = parserManager.parse(new StringReader(sql));
final SparqlVisitor sparqlVisitor = new SparqlVisitor(catalogs, parser,
catalog, schema);
stmt.accept(sparqlVisitor);
return sparqlVisitor.getBuilder().build();
}
protected class Wrapper {
List<Element> lst;
Integer i;
}
protected Map<Class<? extends Element>, Wrapper> validate(final Query query,
final Map<Class<? extends Element>, Integer> tests)
throws IllegalAccessException, IllegalArgumentException,
InvocationTargetException {
return validate( query.getQueryPattern(), tests );
}
protected Map<Class<? extends Element>, Wrapper> validate(final Element query,
final Map<Class<? extends Element>, Integer> tests)
throws IllegalAccessException, IllegalArgumentException,
InvocationTargetException {
final Map<Class<? extends Element>, Wrapper> retval = new IdentityHashMap<Class<? extends Element>, Wrapper>();
final ElementExtractor extractor = new ElementExtractor();
for (final Map.Entry<Class<? extends Element>, Integer> test : tests
.entrySet()) {
query.visit(
extractor.setMatchType(test.getKey()).reset());
if (test.getValue() != null)
{
assertEquals("Wrong number of " + test.getKey(), test.getValue(),
Integer.valueOf(extractor.getExtracted().size()));
}
final Wrapper wrapper = new Wrapper();
wrapper.lst = extractor.getExtracted();
wrapper.i = extractor.getExtracted().size();
retval.put(test.getKey(), wrapper);
}
return retval;
}
protected void verifyVars(final List<Var> vars, final String[] names) {
assertEquals(names.length, vars.size());
for (int i = 0; i < names.length; i++) {
assertEquals(names[i], vars.get(i).getName());
}
}
protected List<String> verifyTable(final Wrapper w, final String name) {
final List<String> retval = new ArrayList<String>();
for (final Element el : w.lst) {
final ElementPathBlock epb = (ElementPathBlock) el;
final Iterator<TriplePath> iter = epb.patternElts();
while (iter.hasNext()) {
final TriplePath t = iter.next();
Assert.assertTrue(t.getSubject().isVariable());
Assert.assertEquals(name, t.getSubject().getName());
final Node n = t.getObject();
if (n.isVariable()) {
retval.add(t.getObject().getName());
}
}
}
return retval;
}
protected void verifyBinds(final Wrapper w, final List<String> cols) {
for (final Element el : w.lst) {
final ElementBind bind = (ElementBind) el;
final Expr expr = bind.getExpr();
assertTrue("Not an E_Function", expr instanceof E_Function);
assertEquals(ForceTypeF.IRI, ((E_Function) expr).getFunctionIRI());
final String name = ((E_Function) expr).getArg(1).getVarName();
assertTrue("Missing " + name, cols.contains(name));
}
}
}