├── .gitignore ├── .settings ├── org.eclipse.m2e.core.prefs └── org.eclipse.jdt.core.prefs ├── src ├── main │ ├── resources │ │ └── META-INF │ │ │ └── services │ │ │ ├── org.xenei.jdbc4sparql.sparql.builders.SchemaBuilder │ │ │ └── org.xenei.jdbc4sparql.sparql.parser.SparqlParser │ └── java │ │ └── org │ │ └── xenei │ │ └── jdbc4sparql │ │ ├── sparql │ │ ├── items │ │ │ ├── NamedObject.java │ │ │ ├── NamedObjectGUIDFilter.java │ │ │ ├── NamedObjectFilter.java │ │ │ ├── QueryItemInfo.java │ │ │ └── QueryColumnInfo.java │ │ ├── parser │ │ │ └── jsqlparser │ │ │ │ ├── proxies │ │ │ │ ├── ExprInfo.java │ │ │ │ ├── ExprInfoFactory.java │ │ │ │ └── ExprInfoHandler.java │ │ │ │ ├── StandardFunctionHandler.java │ │ │ │ ├── SparqlItemsListVisitor.java │ │ │ │ ├── functions │ │ │ │ ├── FunctionColumn.java │ │ │ │ ├── SystemFunctionHandler.java │ │ │ │ └── FunctionColumnDef.java │ │ │ │ ├── SparqlFromVisitor.java │ │ │ │ ├── RegexNodeValue.java │ │ │ │ ├── SparqlVisitor.java │ │ │ │ └── SparqlParserImpl.java │ │ ├── ForceTypeF.java │ │ ├── SparqlResultSet.java │ │ └── builders │ │ │ └── SimpleNullableBuilder.java │ │ ├── iface │ │ ├── ModelFactory.java │ │ ├── name │ │ │ ├── GUIDObject.java │ │ │ ├── SearchName.java │ │ │ ├── CatalogName.java │ │ │ ├── FQName.java │ │ │ ├── SchemaName.java │ │ │ └── FQNameImpl.java │ │ ├── Schema.java │ │ ├── NamespacedObject.java │ │ ├── TableDef.java │ │ ├── KeySegment.java │ │ ├── Key.java │ │ ├── Catalog.java │ │ ├── ColumnDef.java │ │ ├── Column.java │ │ ├── NameFilter.java │ │ └── Table.java │ │ ├── utils │ │ ├── SQLNameUtil.java │ │ ├── NoCloseZipInputStream.java │ │ └── ExpressionExtractor.java │ │ ├── J4SPropertyNames.java │ │ ├── impl │ │ ├── rdf │ │ │ ├── RdfNamespacedObject.java │ │ │ ├── ResourceBuilder.java │ │ │ ├── AbstractChangeListener.java │ │ │ └── RdfKeySegment.java │ │ ├── NameUtils.java │ │ ├── ListResultSet.java │ │ ├── virtual │ │ │ ├── VirtualSchema.java │ │ │ ├── VirtualCatalog.java │ │ │ └── VirtualTable.java │ │ ├── NamespaceImpl.java │ │ ├── AbstractTable.java │ │ ├── NavigableSetResultSet.java │ │ ├── SortedBag.java │ │ └── IteratorResultSet.java │ │ └── config │ │ └── MemDatasetProducer.java ├── test │ ├── resources │ │ ├── org │ │ │ └── xenei │ │ │ │ └── jdbc4sparql │ │ │ │ ├── J4SStatementTest.zip │ │ │ │ ├── J4SStatementTestTDB.zip │ │ │ │ ├── J4SDriverTest.ttl │ │ │ │ ├── J4SNumberFunctionTest.ttl │ │ │ │ ├── J4SStatementTest.ttl │ │ │ │ └── J4SStatementOuterJoinTest.ttl │ │ └── J4SNumberFunctionTest.ttl │ └── java │ │ ├── org │ │ └── xenei │ │ │ └── jdbc4sparql │ │ │ ├── config │ │ │ ├── MemConfigTest.java │ │ │ └── TDBConfigTest.java │ │ │ ├── iface │ │ │ └── name │ │ │ │ ├── CatalogNameConstructorTests.java │ │ │ │ ├── SchemaNameConstructorTests.java │ │ │ │ ├── NameSegmentTest.java │ │ │ │ ├── TableNameConstructorTests.java │ │ │ │ ├── BaseNameImplTest.java │ │ │ │ └── CatalogNameTests.java │ │ │ ├── J4SStatementMemTestFromConfig.java │ │ │ ├── J4SStatementTDBTestFromConfig.java │ │ │ ├── AbstractJ4SSetup.java │ │ │ ├── J4SStatementTDBTest.java │ │ │ ├── impl │ │ │ └── rdf │ │ │ │ ├── KeySegmentBuilderTests.java │ │ │ │ ├── KeyBuilderTests.java │ │ │ │ ├── ColumnBuilderTests.java │ │ │ │ ├── TableBuilderTest.java │ │ │ │ ├── SchemaBuilderTest.java │ │ │ │ └── CatalogBuilderTest.java │ │ │ ├── LoggingConfig.java │ │ │ ├── SystemFunctionTests.java │ │ │ ├── sparql │ │ │ ├── builders │ │ │ │ └── RDFSBuilderTest.java │ │ │ ├── parser │ │ │ │ └── SparqlParserUtilTest.java │ │ │ └── items │ │ │ │ └── QueryColumnInfoTest.java │ │ │ └── J4SStatementOuterJoinTest.java │ │ ├── SparqlDisplay.java │ │ ├── TestConnection.java │ │ ├── ConfigSave.java │ │ ├── QueryTester.java │ │ └── SQLDisplay.java └── example │ └── org │ └── xenei │ └── jdbc4sparql │ └── example │ ├── ConfigSave.java │ └── SQLClient.java ├── NOTICE.txt ├── .project ├── .classpath └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | /target 2 | -------------------------------------------------------------------------------- /.settings/org.eclipse.m2e.core.prefs: -------------------------------------------------------------------------------- 1 | activeProfiles= 2 | eclipse.preferences.version=1 3 | resolveWorkspaceProjects=true 4 | version=1 5 | -------------------------------------------------------------------------------- /src/main/resources/META-INF/services/org.xenei.jdbc4sparql.sparql.builders.SchemaBuilder: -------------------------------------------------------------------------------- 1 | org.xenei.jdbc4sparql.sparql.builders.SimpleBuilder 2 | 3 | -------------------------------------------------------------------------------- /src/main/resources/META-INF/services/org.xenei.jdbc4sparql.sparql.parser.SparqlParser: -------------------------------------------------------------------------------- 1 | org.xenei.jdbc4sparql.sparql.parser.jsqlparser.SparqlParserImpl 2 | 3 | -------------------------------------------------------------------------------- /src/test/resources/org/xenei/jdbc4sparql/J4SStatementTest.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Claudenw/jdbc4sparql/HEAD/src/test/resources/org/xenei/jdbc4sparql/J4SStatementTest.zip -------------------------------------------------------------------------------- /src/test/resources/org/xenei/jdbc4sparql/J4SStatementTestTDB.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Claudenw/jdbc4sparql/HEAD/src/test/resources/org/xenei/jdbc4sparql/J4SStatementTestTDB.zip -------------------------------------------------------------------------------- /src/main/java/org/xenei/jdbc4sparql/sparql/items/NamedObject.java: -------------------------------------------------------------------------------- 1 | package org.xenei.jdbc4sparql.sparql.items; 2 | 3 | import org.xenei.jdbc4sparql.iface.name.ItemName; 4 | 5 | public interface NamedObject { 6 | public T getName(); 7 | } 8 | -------------------------------------------------------------------------------- /src/main/java/org/xenei/jdbc4sparql/iface/ModelFactory.java: -------------------------------------------------------------------------------- 1 | package org.xenei.jdbc4sparql.iface; 2 | 3 | import java.util.Properties; 4 | 5 | import com.hp.hpl.jena.rdf.model.Model; 6 | 7 | public interface ModelFactory { 8 | Model createModel(final Properties properties); 9 | 10 | } 11 | -------------------------------------------------------------------------------- /src/test/java/org/xenei/jdbc4sparql/config/MemConfigTest.java: -------------------------------------------------------------------------------- 1 | // package org.xenei.jdbc4sparql.config; 2 | // 3 | // public class MemConfigTest extends AbstractConfigTest 4 | // { 5 | // 6 | // public MemConfigTest() 7 | // { 8 | // super(MemDatasetProducer.class); 9 | // } 10 | // 11 | // } 12 | -------------------------------------------------------------------------------- /src/test/java/org/xenei/jdbc4sparql/config/TDBConfigTest.java: -------------------------------------------------------------------------------- 1 | // package org.xenei.jdbc4sparql.config; 2 | // 3 | // public class TDBConfigTest extends AbstractConfigTest 4 | // { 5 | // 6 | // public TDBConfigTest() 7 | // { 8 | // super(TDBDatasetProducer.class); 9 | // } 10 | // 11 | // } 12 | -------------------------------------------------------------------------------- /src/main/java/org/xenei/jdbc4sparql/iface/name/GUIDObject.java: -------------------------------------------------------------------------------- 1 | package org.xenei.jdbc4sparql.iface.name; 2 | 3 | /** 4 | * Identifies an object with a GUID. 5 | * 6 | */ 7 | public interface GUIDObject { 8 | /** 9 | * Return the GUID as a string. 10 | * 11 | * @return the GUID string. 12 | */ 13 | public String getGUID(); 14 | } 15 | -------------------------------------------------------------------------------- /NOTICE.txt: -------------------------------------------------------------------------------- 1 | 2 | JDBC 4 SPARQL is licensed under Apache License V2. However, there is one component that is Licensed under the GNU LGPL V3.0 3 | this means that if you want to use this product in an environment that is not permitted under GNU LGPL V3.0 you will need to 4 | find another implementation of the SparqlParser interface. How to do this is covered in the README.md document. 5 | -------------------------------------------------------------------------------- /src/main/java/org/xenei/jdbc4sparql/utils/SQLNameUtil.java: -------------------------------------------------------------------------------- 1 | package org.xenei.jdbc4sparql.utils; 2 | 3 | public class SQLNameUtil { 4 | 5 | /** 6 | * Clean up a name to only include A-Z, a-z, 0-9 and _ 7 | * 8 | * @param name 9 | * @return 10 | */ 11 | public static String clean(final String name) { 12 | return name.replaceAll("[^A-Za-z0-9]+", "_"); 13 | } 14 | 15 | private SQLNameUtil() { 16 | 17 | } 18 | 19 | } 20 | -------------------------------------------------------------------------------- /src/main/java/org/xenei/jdbc4sparql/sparql/parser/jsqlparser/proxies/ExprInfo.java: -------------------------------------------------------------------------------- 1 | package org.xenei.jdbc4sparql.sparql.parser.jsqlparser.proxies; 2 | 3 | import java.util.Set; 4 | 5 | import org.xenei.jdbc4sparql.iface.name.ColumnName; 6 | import org.xenei.jdbc4sparql.sparql.items.NamedObject; 7 | import org.xenei.jdbc4sparql.sparql.parser.jsqlparser.SparqlExprVisitor.ExprColumn; 8 | 9 | import com.hp.hpl.jena.sparql.expr.Expr; 10 | 11 | public interface ExprInfo extends NamedObject, Expr { 12 | public Set getColumns(); 13 | 14 | public Expr getExpr(); 15 | } 16 | -------------------------------------------------------------------------------- /src/test/java/org/xenei/jdbc4sparql/iface/name/CatalogNameConstructorTests.java: -------------------------------------------------------------------------------- 1 | package org.xenei.jdbc4sparql.iface.name; 2 | 3 | import static org.junit.Assert.assertEquals; 4 | import static org.junit.Assert.fail; 5 | 6 | import org.junit.Test; 7 | 8 | public class CatalogNameConstructorTests { 9 | 10 | @Test 11 | public void testNullCatalog() { 12 | try { 13 | new CatalogName((String) null); 14 | fail("Should have thrown IllegalArgumentException"); 15 | } catch (final IllegalArgumentException e) { 16 | assertEquals("Segment catalog may not be null", e.getMessage()); 17 | } 18 | 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/main/java/org/xenei/jdbc4sparql/J4SPropertyNames.java: -------------------------------------------------------------------------------- 1 | package org.xenei.jdbc4sparql; 2 | 3 | public interface J4SPropertyNames { 4 | public static final String BUILDER_PROPERTY = "builder"; 5 | public static final String CATALOG_PROPERTY = "catalog"; 6 | public static final String PARSER_PROPERTY = "parser"; 7 | public static final String TYPE_PROPERTY = "type"; 8 | public static final String DATASET_PRODUCER = "datasetProducer"; 9 | public static final String SCHEMA_PROPERTY = "schema"; 10 | public static final String USER_PROPERTY = "user"; 11 | public static final String PASSWORD_PROPERTY = "password"; 12 | 13 | } 14 | -------------------------------------------------------------------------------- /.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | jdbc4sparql 4 | 5 | 6 | 7 | 8 | 9 | org.eclipse.jdt.core.javabuilder 10 | 11 | 12 | 13 | 14 | org.eclipse.m2e.core.maven2Builder 15 | 16 | 17 | 18 | 19 | 20 | org.eclipse.m2e.core.maven2Nature 21 | org.eclipse.jdt.core.javanature 22 | 23 | 24 | -------------------------------------------------------------------------------- /src/test/java/SparqlDisplay.java: -------------------------------------------------------------------------------- 1 | import com.hp.hpl.jena.query.Query; 2 | import com.hp.hpl.jena.query.QueryFactory; 3 | 4 | public class SparqlDisplay { 5 | 6 | /** 7 | * @param args 8 | */ 9 | public static void main(final String[] args) { 10 | final Query q = QueryFactory 11 | .create("SELECT (MAX(?tstamp) as ?maxts) (MAX(?state) as ?x) WHERE {" 12 | + " ?state a ." 13 | + " ?state ?tstamp ." 14 | + " }"); 15 | q.toString(); 16 | } 17 | 18 | public SparqlDisplay() { 19 | // TODO Auto-generated constructor stub 20 | } 21 | 22 | } 23 | -------------------------------------------------------------------------------- /src/main/java/org/xenei/jdbc4sparql/impl/rdf/RdfNamespacedObject.java: -------------------------------------------------------------------------------- 1 | package org.xenei.jdbc4sparql.impl.rdf; 2 | 3 | import org.xenei.jdbc4sparql.iface.NamespacedObject; 4 | import org.xenei.jena.entities.ResourceWrapper; 5 | 6 | public abstract class RdfNamespacedObject implements NamespacedObject, 7 | ResourceWrapper { 8 | 9 | @Override 10 | public final String getFQName() { 11 | return this.getResource().getURI(); 12 | } 13 | 14 | @Override 15 | public final String getLocalName() { 16 | return this.getResource().asNode().getLocalName(); 17 | } 18 | 19 | @Override 20 | public final String getNamespace() { 21 | return this.getResource().asNode().getNameSpace(); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /.settings/org.eclipse.jdt.core.prefs: -------------------------------------------------------------------------------- 1 | eclipse.preferences.version=1 2 | org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled 3 | org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.7 4 | org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve 5 | org.eclipse.jdt.core.compiler.compliance=1.7 6 | org.eclipse.jdt.core.compiler.debug.lineNumber=generate 7 | org.eclipse.jdt.core.compiler.debug.localVariable=generate 8 | org.eclipse.jdt.core.compiler.debug.sourceFile=generate 9 | org.eclipse.jdt.core.compiler.problem.assertIdentifier=error 10 | org.eclipse.jdt.core.compiler.problem.enumIdentifier=error 11 | org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning 12 | org.eclipse.jdt.core.compiler.source=1.7 13 | -------------------------------------------------------------------------------- /src/test/resources/org/xenei/jdbc4sparql/J4SDriverTest.ttl: -------------------------------------------------------------------------------- 1 | 2 | a . 3 | 4 | [] a ; 5 | 6 | "5" ; 7 | 8 | "Foo2String" . 9 | 10 | [] a ; 11 | 12 | "5" ; 13 | 14 | "6" ; 15 | 16 | "FooNullableFooString" ; 17 | 18 | "FooString" . 19 | -------------------------------------------------------------------------------- /src/test/resources/J4SNumberFunctionTest.ttl: -------------------------------------------------------------------------------- 1 | # 2 | # The foo table 3 | # 4 | 5 | 6 | a . 7 | 8 | [] a ; 9 | 10 | "5" ; 11 | 12 | "1.5" . 13 | 14 | [] a ; 15 | 16 | "-3" ; 17 | 18 | "-1.3" . 19 | 20 | [] a ; 21 | 22 | "7" ; 23 | 24 | "1.7" . 25 | -------------------------------------------------------------------------------- /src/test/resources/org/xenei/jdbc4sparql/J4SNumberFunctionTest.ttl: -------------------------------------------------------------------------------- 1 | # 2 | # The foo table 3 | # 4 | 5 | 6 | a . 7 | 8 | [] a ; 9 | 10 | "5" ; 11 | 12 | "1.5" . 13 | 14 | [] a ; 15 | 16 | "-3" ; 17 | 18 | "-1.3" . 19 | 20 | [] a ; 21 | 22 | "7" ; 23 | 24 | "1.7" . 25 | -------------------------------------------------------------------------------- /src/test/java/org/xenei/jdbc4sparql/J4SStatementMemTestFromConfig.java: -------------------------------------------------------------------------------- 1 | package org.xenei.jdbc4sparql; 2 | 3 | import java.net.URL; 4 | import java.sql.SQLException; 5 | import java.util.Properties; 6 | 7 | import org.junit.After; 8 | import org.junit.Before; 9 | 10 | public class J4SStatementMemTestFromConfig extends AbstractJ4SStatementTest { 11 | @Before 12 | public void setup() throws Exception { 13 | Class.forName("org.xenei.jdbc4sparql.J4SDriver"); 14 | 15 | final URL fUrl = J4SDriverTest.class 16 | .getResource("./J4SStatementTest.zip"); 17 | 18 | final J4SDriver driver = new J4SDriver(); 19 | final J4SUrl url = new J4SUrl("jdbc:J4S:" + fUrl.toExternalForm()); 20 | conn = new J4SConnection(driver, url, new Properties()); 21 | stmt = conn.createStatement(); 22 | } 23 | 24 | @After 25 | public void teardown() throws SQLException { 26 | stmt.close(); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/test/java/org/xenei/jdbc4sparql/J4SStatementTDBTestFromConfig.java: -------------------------------------------------------------------------------- 1 | package org.xenei.jdbc4sparql; 2 | 3 | import java.net.URL; 4 | import java.sql.SQLException; 5 | import java.util.Properties; 6 | 7 | import org.junit.After; 8 | import org.junit.Before; 9 | 10 | public class J4SStatementTDBTestFromConfig extends AbstractJ4SStatementTest { 11 | 12 | @Before 13 | public void setup() throws Exception { 14 | Class.forName("org.xenei.jdbc4sparql.J4SDriver"); 15 | 16 | final URL fUrl = J4SDriverTest.class 17 | .getResource("./J4SStatementTestTDB.zip"); 18 | 19 | final J4SDriver driver = new J4SDriver(); 20 | final J4SUrl url = new J4SUrl("jdbc:J4S:" + fUrl.toExternalForm()); 21 | conn = new J4SConnection(driver, url, new Properties()); 22 | stmt = conn.createStatement(); 23 | } 24 | 25 | @After 26 | public void teardown() throws SQLException { 27 | stmt.close(); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/main/java/org/xenei/jdbc4sparql/sparql/parser/jsqlparser/proxies/ExprInfoFactory.java: -------------------------------------------------------------------------------- 1 | package org.xenei.jdbc4sparql.sparql.parser.jsqlparser.proxies; 2 | 3 | import java.util.Collection; 4 | import java.util.Collections; 5 | 6 | import net.sf.cglib.proxy.Enhancer; 7 | 8 | import org.xenei.jdbc4sparql.iface.name.ColumnName; 9 | import org.xenei.jdbc4sparql.sparql.parser.jsqlparser.SparqlExprVisitor.ExprColumn; 10 | 11 | import com.hp.hpl.jena.sparql.expr.Expr; 12 | 13 | public class ExprInfoFactory { 14 | 15 | public static Expr getInstance(final Expr expr, final ColumnName name) { 16 | return getInstance(expr, Collections. emptyList(), name); 17 | } 18 | 19 | public static Expr getInstance(final Expr expr, 20 | final Collection columns, final ColumnName name) { 21 | 22 | final Class[] clazz = new Class[1]; 23 | clazz[0] = ExprInfo.class; 24 | 25 | final Enhancer e = new Enhancer(); 26 | e.setInterfaces(clazz); 27 | e.setCallback(new ExprInfoHandler(expr, columns, name)); 28 | return (Expr) e.create(); 29 | 30 | } 31 | 32 | } 33 | -------------------------------------------------------------------------------- /src/main/java/org/xenei/jdbc4sparql/sparql/items/NamedObjectGUIDFilter.java: -------------------------------------------------------------------------------- 1 | package org.xenei.jdbc4sparql.sparql.items; 2 | 3 | import java.util.Collection; 4 | import java.util.HashSet; 5 | import java.util.Set; 6 | 7 | import org.xenei.jdbc4sparql.iface.name.GUIDObject; 8 | 9 | import com.hp.hpl.jena.util.iterator.Filter; 10 | 11 | public class NamedObjectGUIDFilter extends Filter { 12 | 13 | private final Set others; 14 | 15 | public NamedObjectGUIDFilter(final String other) { 16 | this.others = new HashSet(); 17 | this.others.add(other); 18 | } 19 | 20 | public NamedObjectGUIDFilter(final GUIDObject other) { 21 | this.others = new HashSet(); 22 | this.others.add(other.getGUID()); 23 | } 24 | 25 | public NamedObjectGUIDFilter(final Collection others) { 26 | this.others = new HashSet(); 27 | for (final GUIDObject obj : others) { 28 | this.others.add(obj.getGUID()); 29 | } 30 | } 31 | 32 | @Override 33 | public boolean accept(final T item) { 34 | return others.contains(item.getGUID()); 35 | } 36 | 37 | } 38 | -------------------------------------------------------------------------------- /src/main/java/org/xenei/jdbc4sparql/sparql/items/NamedObjectFilter.java: -------------------------------------------------------------------------------- 1 | package org.xenei.jdbc4sparql.sparql.items; 2 | 3 | import java.util.ArrayList; 4 | import java.util.Collection; 5 | 6 | import com.hp.hpl.jena.util.iterator.Filter; 7 | 8 | public class NamedObjectFilter> extends Filter { 9 | 10 | protected Collection> others; 11 | 12 | public NamedObjectFilter(final NamedObject other) { 13 | this.others = new ArrayList>(); 14 | this.others.add(other); 15 | } 16 | 17 | public NamedObjectFilter(final Collection others) { 18 | this.others = new ArrayList>(); 19 | for (final Object t : others) { 20 | if (t instanceof NamedObject) { 21 | this.others.add((NamedObject) t); 22 | } 23 | else { 24 | throw new IllegalArgumentException(String.format( 25 | "%s is not an instance of ItemName or NamedObject", 26 | t.getClass())); 27 | } 28 | } 29 | } 30 | 31 | @Override 32 | public boolean accept(final T item) { 33 | for (final NamedObject other : others) { 34 | if (other.equals(item)) { 35 | return true; 36 | } 37 | } 38 | return false; 39 | } 40 | 41 | } 42 | -------------------------------------------------------------------------------- /src/test/java/org/xenei/jdbc4sparql/iface/name/SchemaNameConstructorTests.java: -------------------------------------------------------------------------------- 1 | package org.xenei.jdbc4sparql.iface.name; 2 | 3 | import static org.junit.Assert.assertEquals; 4 | import static org.junit.Assert.fail; 5 | 6 | import org.junit.Test; 7 | 8 | public class SchemaNameConstructorTests { 9 | 10 | private final String catalog = "catalog"; 11 | private final String schema = "schema"; 12 | 13 | @Test 14 | public void testNullSchema() { 15 | try { 16 | new SchemaName(catalog, null); 17 | fail("Should have thrown IllegalArgumentException"); 18 | } catch (final IllegalArgumentException e) { 19 | assertEquals("Segment schema may not be null", e.getMessage()); 20 | } 21 | 22 | } 23 | 24 | @Test 25 | public void testNullCatalog() { 26 | try { 27 | new SchemaName(null, schema); 28 | fail("Should have thrown IllegalArgumentException"); 29 | } catch (final IllegalArgumentException e) { 30 | assertEquals("Segment catalog may not be null", e.getMessage()); 31 | } 32 | 33 | try { 34 | new SchemaName((String) null, null); 35 | fail("Should have thrown IllegalArgumentException"); 36 | } catch (final IllegalArgumentException e) { 37 | assertEquals("Segment catalog may not be null", e.getMessage()); 38 | } 39 | 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/main/java/org/xenei/jdbc4sparql/impl/NameUtils.java: -------------------------------------------------------------------------------- 1 | package org.xenei.jdbc4sparql.impl; 2 | 3 | import java.util.UUID; 4 | 5 | import org.xenei.jdbc4sparql.iface.Table; 6 | import org.xenei.jdbc4sparql.iface.name.TableName; 7 | import org.xenei.jdbc4sparql.sparql.items.NamedObject; 8 | 9 | import com.hp.hpl.jena.sparql.core.Var; 10 | 11 | public class NameUtils { 12 | 13 | public static String createUUIDName() { 14 | return ("v_" + UUID.randomUUID().toString()).replace("-", "_"); 15 | } 16 | 17 | public static String getCursorName(final Table t) { 18 | return NameUtils.getCursorName(t.getName()); 19 | } 20 | 21 | public static String getCursorName(final TableName name) { 22 | return "CURSOR_" + name.createName("_"); 23 | } 24 | 25 | public static String getDBName(final NamedObject namedObject) { 26 | return namedObject.getName().getDBName(); 27 | } 28 | 29 | public static String getDBName(final Var var) { 30 | return var.getName().replace(NameUtils.SPARQL_DOT, NameUtils.DB_DOT); 31 | } 32 | 33 | public static String getSPARQLName(final NamedObject namedObject) { 34 | return namedObject.getName().getSPARQLName(); 35 | } 36 | 37 | public static final String DB_DOT = "."; 38 | 39 | public static final String SPARQL_DOT = "\u00B7"; 40 | 41 | public static final String[] DOT_LIST = { 42 | DB_DOT, SPARQL_DOT 43 | }; 44 | 45 | } 46 | -------------------------------------------------------------------------------- /.classpath: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /src/main/java/org/xenei/jdbc4sparql/iface/Schema.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one 3 | * or more contributor license agreements. See the NOTICE file 4 | * distributed with this work for additional information 5 | * regarding copyright ownership. The ASF licenses this file 6 | * to you under the Apache License, Version 2.0 (the 7 | * "License"); you may not use this file except in compliance 8 | * with the License. You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | package org.xenei.jdbc4sparql.iface; 19 | 20 | import java.util.Set; 21 | 22 | import org.xenei.jdbc4sparql.iface.name.SchemaName; 23 | import org.xenei.jdbc4sparql.sparql.items.NamedObject; 24 | 25 | public interface Schema extends NamedObject { 26 | 27 | NameFilter findTables(String tableNamePattern); 28 | 29 | /** 30 | * The catalog this schema is in. 31 | * 32 | * @return Catalog 33 | */ 34 | 35 | Catalog getCatalog(); 36 | 37 | Table getTable(String tableName); 38 | 39 | Set
getTables(); 40 | 41 | } 42 | -------------------------------------------------------------------------------- /src/main/java/org/xenei/jdbc4sparql/impl/ListResultSet.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one 3 | * or more contributor license agreements. See the NOTICE file 4 | * distributed with this work for additional information 5 | * regarding copyright ownership. The ASF licenses this file 6 | * to you under the Apache License, Version 2.0 (the 7 | * "License"); you may not use this file except in compliance 8 | * with the License. You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | package org.xenei.jdbc4sparql.impl; 19 | 20 | import java.sql.SQLException; 21 | import java.util.List; 22 | 23 | import org.xenei.jdbc4sparql.iface.Table; 24 | 25 | public abstract class ListResultSet extends AbstractCollectionResultSet { 26 | public ListResultSet(final List rows, final Table table) 27 | throws SQLException { 28 | super(rows, table); 29 | } 30 | 31 | @Override 32 | protected Object getRowObject() throws SQLException { 33 | checkPosition(); 34 | return ((List) getDataCollection()).get(getPosition()); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/main/java/org/xenei/jdbc4sparql/sparql/parser/jsqlparser/proxies/ExprInfoHandler.java: -------------------------------------------------------------------------------- 1 | package org.xenei.jdbc4sparql.sparql.parser.jsqlparser.proxies; 2 | 3 | import java.lang.reflect.Method; 4 | import java.util.Collection; 5 | import java.util.HashSet; 6 | import java.util.Set; 7 | 8 | import net.sf.cglib.proxy.MethodInterceptor; 9 | import net.sf.cglib.proxy.MethodProxy; 10 | 11 | import org.xenei.jdbc4sparql.iface.name.ColumnName; 12 | import org.xenei.jdbc4sparql.sparql.parser.jsqlparser.SparqlExprVisitor.ExprColumn; 13 | 14 | import com.hp.hpl.jena.sparql.expr.Expr; 15 | 16 | public class ExprInfoHandler implements MethodInterceptor { 17 | private final Expr base; 18 | private final Set columns; 19 | private final ColumnName name; 20 | 21 | public ExprInfoHandler(final Expr base, 22 | final Collection columns, final ColumnName name) { 23 | this.base = base; 24 | this.columns = new HashSet(); 25 | this.columns.addAll(columns); 26 | this.name = name; 27 | } 28 | 29 | @Override 30 | public Object intercept(final Object obj, final Method method, 31 | final Object[] args, final MethodProxy proxy) throws Throwable { 32 | if (method.getName().equals("getColumns")) { 33 | return columns; 34 | } 35 | 36 | if (method.getName().equals("getName")) { 37 | return name; 38 | } 39 | 40 | if (method.getName().equals("getExpr")) { 41 | return base; 42 | } 43 | return method.invoke(base, args); 44 | } 45 | 46 | } 47 | -------------------------------------------------------------------------------- /src/test/java/org/xenei/jdbc4sparql/AbstractJ4SSetup.java: -------------------------------------------------------------------------------- 1 | package org.xenei.jdbc4sparql; 2 | 3 | import java.sql.Connection; 4 | import java.sql.ResultSet; 5 | import java.sql.SQLException; 6 | import java.sql.Statement; 7 | import java.util.ArrayList; 8 | import java.util.List; 9 | 10 | import org.junit.After; 11 | import org.slf4j.Logger; 12 | import org.slf4j.LoggerFactory; 13 | 14 | public abstract class AbstractJ4SSetup { 15 | 16 | // JDBC Connection 17 | protected Connection conn; 18 | 19 | protected Statement stmt; 20 | 21 | static private Logger LOG = LoggerFactory.getLogger(AbstractJ4SSetup.class); 22 | 23 | protected List getColumnNames(final String table) 24 | throws SQLException { 25 | final ResultSet rs = conn.getMetaData().getColumns(conn.getCatalog(), 26 | conn.getSchema(), table, null); 27 | final List colNames = new ArrayList(); 28 | while (rs.next()) { 29 | if (LOG.isDebugEnabled()) { 30 | AbstractJ4SSetup.LOG.debug(String.format("%s %s %s %s", 31 | rs.getString(1), rs.getString(2), rs.getString(3), 32 | rs.getString(4))); 33 | } 34 | colNames.add(rs.getString(4)); 35 | } 36 | return colNames; 37 | } 38 | 39 | @After 40 | public void tearDown() { 41 | try { 42 | if (stmt != null) { 43 | stmt.close(); 44 | } 45 | } catch (final SQLException ignore) { 46 | } 47 | try { 48 | if (conn != null) { 49 | conn.close(); 50 | } 51 | } catch (final SQLException ignore) { 52 | } 53 | } 54 | 55 | } 56 | -------------------------------------------------------------------------------- /src/test/java/org/xenei/jdbc4sparql/J4SStatementTDBTest.java: -------------------------------------------------------------------------------- 1 | package org.xenei.jdbc4sparql; 2 | 3 | import java.net.URL; 4 | import java.sql.DriverManager; 5 | import java.sql.SQLException; 6 | import java.util.Properties; 7 | 8 | import org.junit.After; 9 | import org.junit.Before; 10 | 11 | public class J4SStatementTDBTest extends AbstractJ4SStatementTest { 12 | // file URL 13 | private URL fUrl; 14 | 15 | // J4SUrl 16 | private String url; 17 | 18 | @Before 19 | public void setup() throws Exception { 20 | Class.forName("org.xenei.jdbc4sparql.J4SDriver"); 21 | 22 | fUrl = J4SDriverTest.class.getResource("./J4SStatementTest.ttl"); 23 | 24 | url = "jdbc:j4s?catalog=test&type=turtle&builder=org.xenei.jdbc4sparql.sparql.builders.SimpleNullableBuilder:" 25 | + fUrl.toString(); 26 | 27 | final Properties prop = new Properties(); 28 | prop.setProperty(J4SPropertyNames.USER_PROPERTY, "myschema"); 29 | prop.setProperty(J4SPropertyNames.PASSWORD_PROPERTY, "mypassw"); 30 | prop.setProperty(J4SPropertyNames.DATASET_PRODUCER, 31 | "org.xenei.jdbc4sparql.config.TDBDatasetProducer"); 32 | conn = DriverManager.getConnection(url, prop); 33 | conn.setAutoCommit(false); 34 | stmt = conn.createStatement(); 35 | // This is here to generate the zip file for reading config 36 | // ((J4SConnection)conn).saveConfig( new 37 | // java.io.File("/tmp/J4SStatementTestTDB.zip" )); 38 | } 39 | 40 | @After 41 | public void teardown() throws SQLException { 42 | stmt.close(); 43 | } 44 | 45 | } 46 | -------------------------------------------------------------------------------- /src/test/java/TestConnection.java: -------------------------------------------------------------------------------- 1 | import java.sql.ResultSet; 2 | import java.util.Properties; 3 | 4 | import org.xenei.jdbc4sparql.J4SConnection; 5 | import org.xenei.jdbc4sparql.J4SConnectionTest; 6 | import org.xenei.jdbc4sparql.J4SDriver; 7 | import org.xenei.jdbc4sparql.J4SUrl; 8 | 9 | import com.hp.hpl.jena.sparql.lang.sparql_11.ParseException; 10 | 11 | public class TestConnection { 12 | 13 | /** 14 | * arg[0] is the j4s URL. If not provided defaults to 15 | * jdbc:j4s?builder=org.xenei.jdbc4sparql.sparql.builders. 16 | * SimpleNullableBuilder&type=turtle:file:./J4SStatementTest.ttl 17 | * 18 | * arg[1] is the output file name. If not provided defaults to config.zip in 19 | * the system temp directory. 20 | * 21 | * @param args 22 | * @throws ParseException 23 | */ 24 | public static void main(final String[] args) throws Exception { 25 | final J4SDriver driver = new J4SDriver(); 26 | String urlStr = null; 27 | if (args.length > 0) { 28 | urlStr = args[0]; 29 | } 30 | else { 31 | J4SConnectionTest.class.getResource("./J4SStatementTest.ttl"); 32 | urlStr = "jdbc:j4s:file:/tmp/configBuilder.zip"; 33 | } 34 | final J4SUrl url = new J4SUrl(urlStr); 35 | final Properties properties = new Properties(); 36 | final J4SConnection connection = new J4SConnection(driver, url, 37 | properties); 38 | 39 | final ResultSet rs = connection.getMetaData().getCatalogs(); 40 | while (rs.next()) { 41 | System.out.println(rs.getString(1)); 42 | } 43 | 44 | connection.close(); 45 | } 46 | 47 | } 48 | -------------------------------------------------------------------------------- /src/main/java/org/xenei/jdbc4sparql/iface/NamespacedObject.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one 3 | * or more contributor license agreements. See the NOTICE file 4 | * distributed with this work for additional information 5 | * regarding copyright ownership. The ASF licenses this file 6 | * to you under the Apache License, Version 2.0 (the 7 | * "License"); you may not use this file except in compliance 8 | * with the License. You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | package org.xenei.jdbc4sparql.iface; 19 | 20 | public interface NamespacedObject { 21 | public static class Utils { 22 | 23 | public static boolean equals(final NamespacedObject o1, final Object o2) { 24 | return (o2 instanceof NamespacedObject) ? o1.getFQName().equals( 25 | ((NamespacedObject) o2).getFQName()) : false; 26 | } 27 | 28 | public static String getFQName(final NamespacedObject o) { 29 | return o.getNamespace() + o.getLocalName(); 30 | } 31 | 32 | public static int hashCode(final NamespacedObject o) { 33 | return o.getFQName().hashCode(); 34 | } 35 | 36 | } 37 | 38 | String getFQName(); 39 | 40 | String getLocalName(); 41 | 42 | String getNamespace(); 43 | } 44 | -------------------------------------------------------------------------------- /src/main/java/org/xenei/jdbc4sparql/iface/TableDef.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one 3 | * or more contributor license agreements. See the NOTICE file 4 | * distributed with this work for additional information 5 | * regarding copyright ownership. The ASF licenses this file 6 | * to you under the Apache License, Version 2.0 (the 7 | * "License"); you may not use this file except in compliance 8 | * with the License. You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | package org.xenei.jdbc4sparql.iface; 19 | 20 | import java.util.List; 21 | 22 | public interface TableDef { 23 | 24 | public int getColumnCount(); 25 | 26 | public ColumnDef getColumnDef(int idx); 27 | 28 | /** 29 | * Get the list of columns in the table 30 | * 31 | * @return 32 | */ 33 | public List getColumnDefs(); 34 | 35 | public int getColumnIndex(ColumnDef column); 36 | 37 | /** 38 | * get the primary key for the table 39 | * 40 | * @return 41 | */ 42 | 43 | public Key getPrimaryKey(); 44 | 45 | /** 46 | * Get the table sort order key. returns null if the table is not sorted. 47 | * 48 | * @return 49 | */ 50 | 51 | public Key getSortKey(); 52 | 53 | public TableDef getSuperTableDef(); 54 | 55 | } 56 | -------------------------------------------------------------------------------- /src/main/java/org/xenei/jdbc4sparql/iface/name/SearchName.java: -------------------------------------------------------------------------------- 1 | package org.xenei.jdbc4sparql.iface.name; 2 | 3 | /** 4 | * An ItemName implementation that is used for searching lists of ItemNames. 5 | * 6 | */ 7 | public class SearchName extends ItemName { 8 | 9 | public SearchName(final String catalog, final String schema, 10 | final String table, final String column) { 11 | this(catalog, schema, table, column, NameSegments.getInstance( 12 | catalog != null, schema != null, table != null, column != null)); 13 | } 14 | 15 | public SearchName(final String catalog, final String schema, 16 | final String table, final String col, final NameSegments segs) { 17 | super(catalog, schema, table, col, segs); 18 | } 19 | 20 | public SearchName(final ItemName name, final NameSegments segments) { 21 | super(name, segments); 22 | } 23 | 24 | public SearchName(final FQName name, final NameSegments segments) { 25 | super(name, segments); 26 | } 27 | 28 | @Override 29 | protected String createName(final String separator) { 30 | return String.format("%s%s%s%s%s%s%s", getCatalog(), separator, 31 | getSchema(), separator, getTable(), separator, getColumn()); 32 | } 33 | 34 | @Override 35 | public String getShortName() { 36 | final NameSegments ns = getUsedSegments(); 37 | if (ns.isColumn()) { 38 | return getColumn(); 39 | } 40 | if (ns.isTable()) { 41 | return getTable(); 42 | } 43 | if (ns.isSchema()) { 44 | return getSchema(); 45 | } 46 | if (ns.isCatalog()) { 47 | return getCatalog(); 48 | } 49 | return ""; 50 | } 51 | 52 | @Override 53 | public ItemName clone(final NameSegments segs) { 54 | return new SearchName(this, segs); 55 | } 56 | 57 | } 58 | -------------------------------------------------------------------------------- /src/main/java/org/xenei/jdbc4sparql/sparql/parser/jsqlparser/StandardFunctionHandler.java: -------------------------------------------------------------------------------- 1 | package org.xenei.jdbc4sparql.sparql.parser.jsqlparser; 2 | 3 | import java.sql.SQLException; 4 | import java.util.ArrayList; 5 | import java.util.List; 6 | 7 | import net.sf.jsqlparser.expression.Function; 8 | 9 | import org.xenei.jdbc4sparql.sparql.SparqlQueryBuilder; 10 | import org.xenei.jdbc4sparql.sparql.parser.jsqlparser.SparqlExprVisitor.AliasInfo; 11 | import org.xenei.jdbc4sparql.sparql.parser.jsqlparser.functions.AbstractFunctionHandler; 12 | import org.xenei.jdbc4sparql.sparql.parser.jsqlparser.functions.NumericFunctionHandler; 13 | import org.xenei.jdbc4sparql.sparql.parser.jsqlparser.functions.StringFunctionHandler; 14 | import org.xenei.jdbc4sparql.sparql.parser.jsqlparser.functions.SystemFunctionHandler; 15 | 16 | import com.hp.hpl.jena.sparql.expr.Expr; 17 | 18 | public class StandardFunctionHandler { 19 | 20 | private final List handlers; 21 | 22 | public StandardFunctionHandler(final SparqlQueryBuilder builder) { 23 | handlers = new ArrayList(); 24 | handlers.add(new NumericFunctionHandler(builder)); 25 | handlers.add(new StringFunctionHandler(builder)); 26 | handlers.add(new SystemFunctionHandler(builder)); 27 | } 28 | 29 | public Expr handle(final Function func, final AliasInfo alias) 30 | throws SQLException { 31 | for (final AbstractFunctionHandler handler : handlers) { 32 | final Expr exprInfo = handler.handle(func, alias); 33 | if (exprInfo != null) { 34 | return exprInfo; 35 | } 36 | } 37 | throw new IllegalArgumentException(String.format( 38 | "Function %s is not supported", func.getName())); 39 | } 40 | 41 | } 42 | -------------------------------------------------------------------------------- /src/main/java/org/xenei/jdbc4sparql/impl/virtual/VirtualSchema.java: -------------------------------------------------------------------------------- 1 | package org.xenei.jdbc4sparql.impl.virtual; 2 | 3 | import java.util.HashMap; 4 | import java.util.HashSet; 5 | import java.util.Map; 6 | import java.util.Set; 7 | 8 | import org.xenei.jdbc4sparql.iface.Catalog; 9 | import org.xenei.jdbc4sparql.iface.NameFilter; 10 | import org.xenei.jdbc4sparql.iface.Schema; 11 | import org.xenei.jdbc4sparql.iface.Table; 12 | import org.xenei.jdbc4sparql.iface.name.SchemaName; 13 | 14 | public class VirtualSchema implements Schema { 15 | public static final String NAME = ""; 16 | private final Catalog catalog; 17 | private final Map tables; 18 | private final SchemaName schemaName; 19 | 20 | public VirtualSchema(final Catalog catalog) { 21 | this(catalog, NAME); 22 | } 23 | 24 | public VirtualSchema(final Catalog catalog, final String name) { 25 | this.catalog = catalog; 26 | this.schemaName = catalog.getName().getSchemaName(name); 27 | tables = new HashMap(); 28 | tables.put(VirtualTable.NAME, new VirtualTable(this)); 29 | tables.put(VirtualTable.SYSTEM_TABLE, new VirtualTable(this, 30 | VirtualTable.SYSTEM_TABLE)); 31 | } 32 | 33 | @Override 34 | public NameFilter
findTables(final String tableNamePattern) { 35 | return new NameFilter
(tableNamePattern, tables.values()); 36 | } 37 | 38 | @Override 39 | public Catalog getCatalog() { 40 | return catalog; 41 | } 42 | 43 | @Override 44 | public SchemaName getName() { 45 | return schemaName; 46 | } 47 | 48 | @Override 49 | public Table getTable(final String tableName) { 50 | return tables.get(tableName); 51 | } 52 | 53 | @Override 54 | public Set
getTables() { 55 | return new HashSet
(tables.values()); 56 | } 57 | 58 | } 59 | -------------------------------------------------------------------------------- /src/test/java/org/xenei/jdbc4sparql/impl/rdf/KeySegmentBuilderTests.java: -------------------------------------------------------------------------------- 1 | package org.xenei.jdbc4sparql.impl.rdf; 2 | 3 | import org.junit.After; 4 | import org.junit.Assert; 5 | import org.junit.Before; 6 | import org.junit.Test; 7 | import org.xenei.jdbc4sparql.iface.KeySegment; 8 | 9 | import com.hp.hpl.jena.rdf.model.Model; 10 | import com.hp.hpl.jena.rdf.model.ModelFactory; 11 | 12 | public class KeySegmentBuilderTests { 13 | private Model model; 14 | 15 | @Before 16 | public void setUp() throws Exception { 17 | model = ModelFactory.createDefaultModel(); 18 | } 19 | 20 | @After 21 | public void tearDown() throws Exception { 22 | model.close(); 23 | } 24 | 25 | @Test 26 | public void testDefault() { 27 | final RdfKeySegment.Builder builder = new RdfKeySegment.Builder(); 28 | final KeySegment seg = builder.build(model); 29 | 30 | Assert.assertEquals(0, seg.getIdx()); 31 | Assert.assertEquals(true, seg.isAscending()); 32 | 33 | } 34 | 35 | @Test 36 | public void testInvalid() { 37 | final RdfKeySegment.Builder builder = new RdfKeySegment.Builder(); 38 | try { 39 | builder.setIdx(-1); 40 | Assert.fail("should have thrown IllegalArgumentException"); 41 | } catch (final IllegalArgumentException expected) { 42 | // expected 43 | } 44 | 45 | try { 46 | builder.setIdx(Short.MAX_VALUE + 1); 47 | 48 | Assert.fail("should have thrown IllegalArgumentException"); 49 | } catch (final IllegalArgumentException expected) { 50 | // expected 51 | } 52 | } 53 | 54 | @Test 55 | public void testSetValues() { 56 | final RdfKeySegment.Builder builder = new RdfKeySegment.Builder() 57 | .setIdx(5).setAscending(false); 58 | final KeySegment seg = builder.build(model); 59 | 60 | Assert.assertEquals(5, seg.getIdx()); 61 | Assert.assertEquals(false, seg.isAscending()); 62 | 63 | } 64 | 65 | } 66 | -------------------------------------------------------------------------------- /src/main/java/org/xenei/jdbc4sparql/iface/KeySegment.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one 3 | * or more contributor license agreements. See the NOTICE file 4 | * distributed with this work for additional information 5 | * regarding copyright ownership. The ASF licenses this file 6 | * to you under the Apache License, Version 2.0 (the 7 | * "License"); you may not use this file except in compliance 8 | * with the License. You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | package org.xenei.jdbc4sparql.iface; 19 | 20 | import java.util.Comparator; 21 | 22 | public interface KeySegment extends Comparator[]> { 23 | 24 | public String getId(); 25 | 26 | public short getIdx(); 27 | 28 | public boolean isAscending(); 29 | 30 | public static class Utils { 31 | 32 | public static final int compare(final int idx, 33 | final boolean isAscending, final Comparable[] data1, 34 | final Object[] data2) { 35 | final Object o1 = data1[idx]; 36 | final Object o2 = data2[idx]; 37 | int retval; 38 | if (o1 == null) { 39 | retval = o2 == null ? 0 : -1; 40 | } 41 | else if (o2 == null) { 42 | retval = 1; 43 | } 44 | else { 45 | return data1[idx].compareTo(data2[idx]); 46 | // retval = Comparable.class.cast(data1[idx]) 47 | // .compareTo(data2[idx]); 48 | } 49 | return isAscending ? retval : -1 * retval; 50 | } 51 | 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /src/test/java/ConfigSave.java: -------------------------------------------------------------------------------- 1 | import java.io.File; 2 | import java.io.FileOutputStream; 3 | import java.net.URL; 4 | import java.util.Properties; 5 | 6 | import org.xenei.jdbc4sparql.J4SConnection; 7 | import org.xenei.jdbc4sparql.J4SConnectionTest; 8 | import org.xenei.jdbc4sparql.J4SDriver; 9 | import org.xenei.jdbc4sparql.J4SUrl; 10 | 11 | import com.hp.hpl.jena.sparql.lang.sparql_11.ParseException; 12 | 13 | public class ConfigSave { 14 | 15 | /** 16 | * arg[0] is the j4s URL. If not provided defaults to 17 | * jdbc:j4s?builder=org.xenei.jdbc4sparql.sparql.builders. 18 | * SimpleNullableBuilder&type=turtle:file:./J4SStatementTest.ttl 19 | * 20 | * arg[1] is the output file name. If not provided defaults to config.zip in 21 | * the system temp directory. 22 | * 23 | * @param args 24 | * @throws ParseException 25 | */ 26 | public static void main(final String[] args) throws Exception { 27 | final J4SDriver driver = new J4SDriver(); 28 | String urlStr = null; 29 | if (args.length > 0) { 30 | urlStr = args[0]; 31 | } 32 | else { 33 | final URL fUrl = J4SConnectionTest.class 34 | .getResource("./J4SStatementTest.ttl"); 35 | urlStr = "jdbc:j4s?builder=org.xenei.jdbc4sparql.sparql.builders.SimpleNullableBuilder&type=turtle:" 36 | + fUrl.toExternalForm(); 37 | } 38 | final J4SUrl url = new J4SUrl(urlStr); 39 | final Properties properties = new Properties(); 40 | final J4SConnection connection = new J4SConnection(driver, url, 41 | properties); 42 | 43 | File f = null; 44 | if (args.length == 2) { 45 | f = new File(args[1]); 46 | } 47 | else { 48 | f = new File(new File(System.getProperty("java.io.tmpdir")), 49 | "config.zip"); 50 | } 51 | final FileOutputStream fos = new FileOutputStream(f); 52 | connection.saveConfig(fos); 53 | fos.close(); 54 | connection.close(); 55 | } 56 | 57 | } 58 | -------------------------------------------------------------------------------- /src/main/java/org/xenei/jdbc4sparql/sparql/parser/jsqlparser/SparqlItemsListVisitor.java: -------------------------------------------------------------------------------- 1 | package org.xenei.jdbc4sparql.sparql.parser.jsqlparser; 2 | 3 | import java.util.List; 4 | 5 | import net.sf.jsqlparser.expression.Expression; 6 | import net.sf.jsqlparser.expression.operators.relational.ExpressionList; 7 | import net.sf.jsqlparser.expression.operators.relational.ItemsListVisitor; 8 | import net.sf.jsqlparser.statement.select.SubSelect; 9 | 10 | import org.slf4j.Logger; 11 | import org.slf4j.LoggerFactory; 12 | import org.xenei.jdbc4sparql.sparql.SparqlQueryBuilder; 13 | 14 | import com.hp.hpl.jena.sparql.expr.ExprList; 15 | 16 | public class SparqlItemsListVisitor implements ItemsListVisitor { 17 | private static Logger LOG = LoggerFactory 18 | .getLogger(SparqlItemsListVisitor.class); 19 | private final SparqlExprVisitor exprVisitor; 20 | private ExprList result; 21 | 22 | SparqlItemsListVisitor(final SparqlQueryBuilder builder) { 23 | exprVisitor = new SparqlExprVisitor(builder, 24 | SparqlQueryBuilder.OPTIONAL, false); 25 | } 26 | 27 | public ExprList getResult() { 28 | return result; 29 | } 30 | 31 | @Override 32 | public void visit(final ExpressionList expressionList) { 33 | if (LOG.isDebugEnabled()) { 34 | SparqlItemsListVisitor.LOG.debug("visit ExpressionList: {}", 35 | expressionList); 36 | } 37 | @SuppressWarnings("unchecked") 38 | final List l = expressionList.getExpressions(); 39 | result = new ExprList(); 40 | // accept them in reverse order 41 | for (final Expression e : l) { 42 | e.accept(exprVisitor); 43 | result.add(exprVisitor.getResult()); 44 | } 45 | } 46 | 47 | @Override 48 | public void visit(final SubSelect subSelect) { 49 | if (LOG.isDebugEnabled()) { 50 | SparqlItemsListVisitor.LOG.debug("visit SubSelect: {}", subSelect); 51 | } 52 | subSelect.accept(exprVisitor); 53 | } 54 | 55 | } 56 | -------------------------------------------------------------------------------- /src/main/java/org/xenei/jdbc4sparql/sparql/parser/jsqlparser/functions/FunctionColumn.java: -------------------------------------------------------------------------------- 1 | package org.xenei.jdbc4sparql.sparql.parser.jsqlparser.functions; 2 | 3 | import org.xenei.jdbc4sparql.iface.Catalog; 4 | import org.xenei.jdbc4sparql.iface.Column; 5 | import org.xenei.jdbc4sparql.iface.ColumnDef; 6 | import org.xenei.jdbc4sparql.iface.Schema; 7 | import org.xenei.jdbc4sparql.iface.Table; 8 | import org.xenei.jdbc4sparql.iface.name.ColumnName; 9 | import org.xenei.jdbc4sparql.impl.NameUtils; 10 | 11 | public class FunctionColumn implements Column { 12 | private final Table table; 13 | private final ColumnName name; 14 | private final ColumnDef cd; 15 | 16 | public FunctionColumn(final Table table, final String name, final int type) { 17 | this.table = table; 18 | this.name = table.getName().getColumnName(name); 19 | this.cd = new FunctionColumnDef(type); 20 | } 21 | 22 | @Override 23 | public Catalog getCatalog() { 24 | return table.getCatalog(); 25 | } 26 | 27 | @Override 28 | public ColumnDef getColumnDef() { 29 | return cd; 30 | } 31 | 32 | @Override 33 | public ColumnName getName() { 34 | return name; 35 | } 36 | 37 | @Override 38 | public String getQuerySegmentFmt() { 39 | return null; 40 | } 41 | 42 | @Override 43 | public String getRemarks() { 44 | return "Function Column"; 45 | } 46 | 47 | @Override 48 | public Schema getSchema() { 49 | return table.getSchema(); 50 | } 51 | 52 | @Override 53 | public String getSPARQLName() { 54 | return NameUtils.getSPARQLName(this); 55 | } 56 | 57 | @Override 58 | public String getSQLName() { 59 | return NameUtils.getDBName(this); 60 | } 61 | 62 | @Override 63 | public Table getTable() { 64 | return table; 65 | } 66 | 67 | @Override 68 | public boolean hasQuerySegments() { 69 | return false; 70 | } 71 | 72 | @Override 73 | public boolean isOptional() { 74 | return false; 75 | } 76 | } -------------------------------------------------------------------------------- /src/main/java/org/xenei/jdbc4sparql/iface/Key.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one 3 | * or more contributor license agreements. See the NOTICE file 4 | * distributed with this work for additional information 5 | * regarding copyright ownership. The ASF licenses this file 6 | * to you under the Apache License, Version 2.0 (the 7 | * "License"); you may not use this file except in compliance 8 | * with the License. You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | package org.xenei.jdbc4sparql.iface; 19 | 20 | import java.util.Comparator; 21 | import java.util.List; 22 | 23 | import org.xenei.jena.entities.annotations.Subject; 24 | 25 | @Subject(namespace = "http://org.xenei.jdbc4sparql/entity/Key#") 26 | public interface Key extends 27 | Comparator[]> { 28 | 29 | public String getId(); 30 | 31 | /** 32 | * Get the key name (may be null) 33 | * 34 | * @return the key name. 35 | */ 36 | public String getKeyName(); 37 | 38 | public List getSegments(); 39 | 40 | public boolean isUnique(); 41 | 42 | public static class Utils { 43 | 44 | public final static int compare( 45 | final List segments, 46 | final Comparable[] data1, 47 | final Comparable[] data2) { 48 | for (final KeySegment segment : segments) { 49 | final int retval = segment.compare(data1, data2); 50 | if (retval != 0) { 51 | return retval; 52 | } 53 | } 54 | return 0; 55 | } 56 | 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /src/main/java/org/xenei/jdbc4sparql/impl/virtual/VirtualCatalog.java: -------------------------------------------------------------------------------- 1 | package org.xenei.jdbc4sparql.impl.virtual; 2 | 3 | import java.util.HashMap; 4 | import java.util.HashSet; 5 | import java.util.List; 6 | import java.util.Map; 7 | import java.util.Set; 8 | 9 | import org.xenei.jdbc4sparql.iface.Catalog; 10 | import org.xenei.jdbc4sparql.iface.NameFilter; 11 | import org.xenei.jdbc4sparql.iface.Schema; 12 | import org.xenei.jdbc4sparql.iface.name.CatalogName; 13 | 14 | import com.hp.hpl.jena.graph.Node; 15 | import com.hp.hpl.jena.query.Query; 16 | import com.hp.hpl.jena.query.QuerySolution; 17 | 18 | public class VirtualCatalog implements Catalog { 19 | public static final String NAME = ""; 20 | private final CatalogName name = new CatalogName(NAME); 21 | private Map schemas; 22 | 23 | public VirtualCatalog() { 24 | schemas = new HashMap(); 25 | schemas.put(VirtualSchema.NAME, new VirtualSchema(this)); 26 | } 27 | 28 | @Override 29 | public void close() { 30 | schemas = null; 31 | } 32 | 33 | @Override 34 | public List executeLocalQuery(final Query query) { 35 | return null; 36 | } 37 | 38 | @Override 39 | public NameFilter findSchemas(final String schemaNamePattern) { 40 | return new NameFilter(schemaNamePattern, schemas.values()); 41 | } 42 | 43 | @Override 44 | public CatalogName getName() { 45 | return name; 46 | } 47 | 48 | @Override 49 | public Schema getSchema(final String schemaName) { 50 | return schemas.get(schemaName); 51 | } 52 | 53 | @Override 54 | public Set getSchemas() { 55 | return new HashSet(schemas.values()); 56 | } 57 | 58 | @Override 59 | public boolean isService() { 60 | return false; 61 | } 62 | 63 | @Override 64 | public Node getServiceNode() { 65 | return null; 66 | } 67 | 68 | @Override 69 | public String getShortName() { 70 | return getName().getCatalog(); 71 | } 72 | 73 | } 74 | -------------------------------------------------------------------------------- /src/example/org/xenei/jdbc4sparql/example/ConfigSave.java: -------------------------------------------------------------------------------- 1 | package org.xenei.jdbc4sparql.example; 2 | 3 | import java.io.File; 4 | import java.io.FileOutputStream; 5 | import java.net.URL; 6 | import java.util.Properties; 7 | 8 | import org.xenei.jdbc4sparql.J4SConnection; 9 | import org.xenei.jdbc4sparql.J4SDriver; 10 | import org.xenei.jdbc4sparql.J4SUrl; 11 | 12 | import com.hp.hpl.jena.sparql.lang.sparql_11.ParseException; 13 | 14 | public class ConfigSave { 15 | 16 | /** 17 | * arg[0] is the j4s URL. If not provided defaults to 18 | * jdbc:j4s?builder=org.xenei.jdbc4sparql.sparql.builders. 19 | * SimpleNullableBuilder&type=turtle:file:./J4SStatementTest.ttl 20 | * 21 | * arg[1] is the output file name. If not provided defaults to config.zip in 22 | * the system temp directory. 23 | * 24 | * @param args 25 | * @throws ParseException 26 | */ 27 | public static void main(final String[] args) throws Exception { 28 | final J4SDriver driver = new J4SDriver(); 29 | String urlStr = null; 30 | if (args.length > 0) { 31 | urlStr = args[0]; 32 | } 33 | else { 34 | final URL fUrl = new URL( 35 | "file:/home/claude/XeneiWorkspace/jdbc4sparql/target/test-classes/org/xenei/jdbc4sparql/J4SStatementTest.ttl"); 36 | urlStr = "jdbc:j4s?builder=org.xenei.jdbc4sparql.sparql.builders.SimpleNullableBuilder&type=turtle:" 37 | + fUrl.toExternalForm(); 38 | } 39 | final J4SUrl url = new J4SUrl(urlStr); 40 | final Properties properties = new Properties(); 41 | final J4SConnection connection = new J4SConnection(driver, url, 42 | properties); 43 | 44 | File f = null; 45 | if (args.length == 2) { 46 | f = new File(args[1]); 47 | } 48 | else { 49 | f = new File(new File(System.getProperty("java.io.tmpdir")), 50 | "config.zip"); 51 | } 52 | final FileOutputStream fos = new FileOutputStream(f); 53 | connection.saveConfig(fos); 54 | fos.close(); 55 | connection.close(); 56 | } 57 | 58 | } 59 | -------------------------------------------------------------------------------- /src/main/java/org/xenei/jdbc4sparql/impl/virtual/VirtualTable.java: -------------------------------------------------------------------------------- 1 | package org.xenei.jdbc4sparql.impl.virtual; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | import org.xenei.jdbc4sparql.iface.Column; 7 | import org.xenei.jdbc4sparql.iface.Schema; 8 | import org.xenei.jdbc4sparql.iface.Table; 9 | import org.xenei.jdbc4sparql.iface.TableDef; 10 | import org.xenei.jdbc4sparql.iface.name.TableName; 11 | import org.xenei.jdbc4sparql.impl.AbstractTable; 12 | 13 | public class VirtualTable extends AbstractTable { 14 | public static final String SYSTEM_TABLE = "system"; 15 | public static final String NAME = ""; 16 | private final Schema schema; 17 | private final TableName tableName; 18 | private final List columns; 19 | private TableDef tableDef; 20 | 21 | public VirtualTable(final Schema schema) { 22 | this(schema, SYSTEM_TABLE); 23 | } 24 | 25 | public VirtualTable(final Schema schema, final String name) { 26 | this.tableName = schema.getName().getTableName(name); 27 | this.columns = new ArrayList(); 28 | this.schema = schema; 29 | } 30 | 31 | @Override 32 | public void delete() { 33 | // does nothing 34 | } 35 | 36 | @Override 37 | public List getColumnList() { 38 | return columns; 39 | } 40 | 41 | @Override 42 | public TableName getName() { 43 | return tableName; 44 | } 45 | 46 | @Override 47 | public String getQuerySegmentFmt() { 48 | return null; 49 | } 50 | 51 | @Override 52 | public String getRemarks() { 53 | return ""; 54 | } 55 | 56 | @Override 57 | public Schema getSchema() { 58 | return schema; 59 | } 60 | 61 | @Override 62 | public Table getSuperTable() { 63 | return null; 64 | } 65 | 66 | @Override 67 | public TableDef getTableDef() { 68 | return tableDef; 69 | } 70 | 71 | @Override 72 | public String getType() { 73 | return "Virtual"; 74 | } 75 | 76 | @Override 77 | public boolean hasQuerySegments() { 78 | return false; 79 | } 80 | 81 | } 82 | -------------------------------------------------------------------------------- /src/main/java/org/xenei/jdbc4sparql/impl/NamespaceImpl.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one 3 | * or more contributor license agreements. See the NOTICE file 4 | * distributed with this work for additional information 5 | * regarding copyright ownership. The ASF licenses this file 6 | * to you under the Apache License, Version 2.0 (the 7 | * "License"); you may not use this file except in compliance 8 | * with the License. You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | package org.xenei.jdbc4sparql.impl; 19 | 20 | import org.xenei.jdbc4sparql.iface.NamespacedObject; 21 | 22 | public class NamespaceImpl implements NamespacedObject { 23 | private final String namespace; 24 | private final String localName; 25 | private final int hashCode; 26 | 27 | protected NamespaceImpl(String namespace, final String localName) { 28 | this.namespace = namespace; 29 | this.localName = localName; 30 | if (!(namespace.endsWith("#") || namespace.endsWith("/"))) { 31 | namespace += namespace.contains("#") ? "/" : "#"; 32 | } 33 | hashCode = NamespacedObject.Utils.hashCode(this); 34 | } 35 | 36 | @Override 37 | public boolean equals(final Object o) { 38 | return NamespacedObject.Utils.equals(this, o); 39 | } 40 | 41 | @Override 42 | public String getFQName() { 43 | return namespace + localName; 44 | } 45 | 46 | @Override 47 | public String getLocalName() { 48 | return localName; 49 | } 50 | 51 | @Override 52 | public String getNamespace() { 53 | return namespace; 54 | } 55 | 56 | @Override 57 | public int hashCode() { 58 | return hashCode; 59 | } 60 | 61 | } 62 | -------------------------------------------------------------------------------- /src/main/java/org/xenei/jdbc4sparql/utils/NoCloseZipInputStream.java: -------------------------------------------------------------------------------- 1 | package org.xenei.jdbc4sparql.utils; 2 | 3 | import java.io.IOException; 4 | import java.io.InputStream; 5 | import java.util.zip.ZipInputStream; 6 | 7 | /** 8 | * A zip input stream that does not close when "close" is called. Instead it 9 | * calls closeEntry. To close the stream call close on the original input 10 | * stream. 11 | */ 12 | public class NoCloseZipInputStream extends InputStream { 13 | ZipInputStream wrapped; 14 | 15 | public NoCloseZipInputStream(final ZipInputStream is) { 16 | wrapped = is; 17 | } 18 | 19 | @Override 20 | public int available() throws IOException { 21 | return wrapped.available(); 22 | } 23 | 24 | /** 25 | * A close implementation that calls closeEntry() instead. To really close 26 | * the stream call close on the inputstream that was used in the 27 | * constructor. 28 | */ 29 | @Override 30 | public void close() throws IOException { 31 | wrapped.closeEntry(); 32 | } 33 | 34 | @Override 35 | public boolean equals(final Object obj) { 36 | return wrapped.equals(obj); 37 | } 38 | 39 | @Override 40 | public int hashCode() { 41 | return wrapped.hashCode(); 42 | } 43 | 44 | @Override 45 | public void mark(final int readlimit) { 46 | wrapped.mark(readlimit); 47 | } 48 | 49 | @Override 50 | public boolean markSupported() { 51 | return wrapped.markSupported(); 52 | } 53 | 54 | @Override 55 | public int read() throws IOException { 56 | return wrapped.read(); 57 | } 58 | 59 | @Override 60 | public int read(final byte[] b) throws IOException { 61 | return wrapped.read(b); 62 | } 63 | 64 | @Override 65 | public int read(final byte[] b, final int off, final int len) 66 | throws IOException { 67 | return wrapped.read(b, off, len); 68 | } 69 | 70 | @Override 71 | public void reset() throws IOException { 72 | wrapped.reset(); 73 | } 74 | 75 | @Override 76 | public long skip(final long n) throws IOException { 77 | return wrapped.skip(n); 78 | } 79 | 80 | @Override 81 | public String toString() { 82 | return wrapped.toString(); 83 | } 84 | 85 | } -------------------------------------------------------------------------------- /src/main/java/org/xenei/jdbc4sparql/sparql/ForceTypeF.java: -------------------------------------------------------------------------------- 1 | package org.xenei.jdbc4sparql.sparql; 2 | 3 | import org.slf4j.Logger; 4 | import org.slf4j.LoggerFactory; 5 | import org.xenei.jdbc4sparql.iface.TypeConverter; 6 | import org.xenei.jdbc4sparql.sparql.items.QueryColumnInfo; 7 | 8 | import com.hp.hpl.jena.sparql.engine.binding.Binding; 9 | import com.hp.hpl.jena.sparql.expr.E_Function; 10 | import com.hp.hpl.jena.sparql.expr.ExprEvalException; 11 | import com.hp.hpl.jena.sparql.expr.ExprList; 12 | import com.hp.hpl.jena.sparql.expr.ExprVar; 13 | import com.hp.hpl.jena.sparql.expr.NodeValue; 14 | import com.hp.hpl.jena.sparql.expr.nodevalue.NodeValueBoolean; 15 | import com.hp.hpl.jena.sparql.function.FunctionEnv; 16 | import com.hp.hpl.jena.sparql.syntax.ElementBind; 17 | 18 | /** 19 | * A local filter that removes any values that are null and not allowed to be 20 | * null or that can not be converted to the expected column value type. 21 | */ 22 | public class ForceTypeF extends CheckTypeF { 23 | private static final Logger LOG = LoggerFactory.getLogger(ForceTypeF.class); 24 | public static final String IRI = "java:" 25 | + ForceTypeF.class.getCanonicalName(); 26 | 27 | public static E_Function getFunction(final QueryColumnInfo columnInfo) { 28 | return new E_Function(IRI, getExprList(columnInfo)); 29 | } 30 | 31 | public static ElementBind getBinding(final QueryColumnInfo columnInfo) { 32 | return new ElementBind(columnInfo.getVar(), getFunction(columnInfo)); 33 | } 34 | 35 | @Override 36 | public NodeValue exec(final Binding binding, final ExprList args, 37 | final String uri, final FunctionEnv env) { 38 | if (((NodeValueBoolean) super.exec(binding, args, uri, env)) 39 | .getBoolean()) { 40 | final NodeValue retval = TypeConverter.getNodeValue(super 41 | .getValue()); 42 | if (LOG.isDebugEnabled()) { 43 | LOG.debug("ForceTypeF( {} ) is {} ({})", args.get(0), retval, binding.get( ((ExprVar) args.get(0)).asVar())); 44 | } 45 | return retval; 46 | } 47 | throw new ExprEvalException( 48 | "CheckTypeF for ForceTypeF did not return true."); 49 | 50 | } 51 | 52 | } -------------------------------------------------------------------------------- /src/main/java/org/xenei/jdbc4sparql/sparql/parser/jsqlparser/functions/SystemFunctionHandler.java: -------------------------------------------------------------------------------- 1 | package org.xenei.jdbc4sparql.sparql.parser.jsqlparser.functions; 2 | 3 | import java.sql.SQLException; 4 | import java.util.Arrays; 5 | 6 | import net.sf.jsqlparser.expression.Function; 7 | 8 | import org.xenei.jdbc4sparql.J4SDriver; 9 | import org.xenei.jdbc4sparql.iface.name.ColumnName; 10 | import org.xenei.jdbc4sparql.sparql.SparqlQueryBuilder; 11 | import org.xenei.jdbc4sparql.sparql.parser.jsqlparser.SparqlExprVisitor.AliasInfo; 12 | import org.xenei.jdbc4sparql.sparql.parser.jsqlparser.proxies.ExprInfoFactory; 13 | 14 | import com.hp.hpl.jena.sparql.expr.Expr; 15 | import com.hp.hpl.jena.sparql.expr.nodevalue.NodeValueString; 16 | 17 | public class SystemFunctionHandler extends AbstractFunctionHandler { 18 | public static final String[] SYSTEM_FUNCTIONS = { 19 | "CATALOG", "VERSION" 20 | }; 21 | private static final int CATALOG = 0; 22 | private static final int VERSION = 1; 23 | 24 | public SystemFunctionHandler(final SparqlQueryBuilder builder) { 25 | super(builder); 26 | } 27 | 28 | @Override 29 | public Expr handle(final Function func, final AliasInfo alias) 30 | throws SQLException { 31 | 32 | final int i = Arrays.asList(SystemFunctionHandler.SYSTEM_FUNCTIONS) 33 | .indexOf(func.getName().toUpperCase()); 34 | ColumnName colName; 35 | NodeValueString str; 36 | switch (i) { 37 | case CATALOG: 38 | str = new NodeValueString(builder.getCatalog().getName() 39 | .getShortName()); 40 | // colName = tblName.getColumnName(func.getName()); 41 | colName = tblName.getColumnName(alias.getAlias()); 42 | builder.registerFunction(colName, java.sql.Types.VARCHAR); 43 | return ExprInfoFactory.getInstance(str, colName); 44 | 45 | case VERSION: 46 | str = new NodeValueString(J4SDriver.getVersion()); 47 | // colName = tblName.getColumnName(func.getName()); 48 | colName = tblName.getColumnName(alias.getAlias()); 49 | builder.registerFunction(colName, java.sql.Types.VARCHAR); 50 | return ExprInfoFactory.getInstance(str, colName); 51 | default: 52 | return null; 53 | } 54 | 55 | } 56 | 57 | } 58 | -------------------------------------------------------------------------------- /src/test/java/org/xenei/jdbc4sparql/impl/rdf/KeyBuilderTests.java: -------------------------------------------------------------------------------- 1 | package org.xenei.jdbc4sparql.impl.rdf; 2 | 3 | import org.junit.After; 4 | import org.junit.Assert; 5 | import org.junit.Before; 6 | import org.junit.Test; 7 | import org.xenei.jdbc4sparql.iface.Key; 8 | 9 | import com.hp.hpl.jena.rdf.model.Model; 10 | import com.hp.hpl.jena.rdf.model.ModelFactory; 11 | 12 | public class KeyBuilderTests { 13 | private Model model; 14 | 15 | @Before 16 | public void setUp() throws Exception { 17 | model = ModelFactory.createDefaultModel(); 18 | } 19 | 20 | @After 21 | public void tearDown() throws Exception { 22 | model.close(); 23 | } 24 | 25 | @Test 26 | public void testDefault() { 27 | final RdfKeySegment.Builder segBuilder = new RdfKeySegment.Builder(); 28 | 29 | final RdfKey.Builder builder = new RdfKey.Builder() 30 | .addSegment(segBuilder.build(model)); 31 | 32 | final Key key = builder.build(model); 33 | 34 | Assert.assertEquals(false, key.isUnique()); 35 | Assert.assertEquals(1, key.getSegments().size()); 36 | Assert.assertEquals(segBuilder.build(model), key.getSegments().get(0)); 37 | 38 | } 39 | 40 | @Test 41 | public void testMultipleSegments() { 42 | final RdfKeySegment.Builder segBuilder = new RdfKeySegment.Builder(); 43 | 44 | final RdfKey.Builder builder = new RdfKey.Builder().addSegment( 45 | segBuilder.build(model)).addSegment( 46 | segBuilder.setAscending(false).setIdx(1).build(model)); 47 | 48 | final Key key = builder.build(model); 49 | 50 | Assert.assertEquals(false, key.isUnique()); 51 | Assert.assertEquals(2, key.getSegments().size()); 52 | Assert.assertEquals(segBuilder.build(model), key.getSegments().get(1)); 53 | } 54 | 55 | @Test 56 | public void testUnique() { 57 | final RdfKeySegment.Builder segBuilder = new RdfKeySegment.Builder(); 58 | 59 | final RdfKey.Builder builder = new RdfKey.Builder().addSegment( 60 | segBuilder.build(model)).setUnique(true); 61 | 62 | final Key key = builder.build(model); 63 | 64 | Assert.assertEquals(true, key.isUnique()); 65 | Assert.assertEquals(1, key.getSegments().size()); 66 | Assert.assertEquals(segBuilder.build(model), key.getSegments().get(0)); 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /src/test/resources/org/xenei/jdbc4sparql/J4SStatementTest.ttl: -------------------------------------------------------------------------------- 1 | # 2 | # The foo table 3 | # 4 | 5 | 6 | a . 7 | 8 | [] a ; 9 | 10 | "4" ; 11 | 12 | "Foo2String" . 13 | 14 | [] a ; 15 | 16 | "5" ; 17 | 18 | "6" ; 19 | 20 | "FooNullableFooString" ; 21 | 22 | "FooString" . 23 | 24 | # data for bad parsing test 25 | [] a ; 26 | 27 | "notanint" ; 28 | 29 | "Foo3String" . 30 | 31 | # 32 | # The bar table 33 | # 34 | 35 | 36 | a . 37 | 38 | [] a ; 39 | 40 | "15" ; 41 | 42 | "16" ; 43 | 44 | "BarNullableFooString" ; 45 | 46 | "FooString" . 47 | 48 | # data for bad parsing text 49 | [] a ; 50 | 51 | "25" ; 52 | 53 | "26" ; 54 | 55 | "BarNullableFoo3String" ; 56 | 57 | "Foo3String" . -------------------------------------------------------------------------------- /src/test/java/org/xenei/jdbc4sparql/LoggingConfig.java: -------------------------------------------------------------------------------- 1 | package org.xenei.jdbc4sparql; 2 | 3 | import org.apache.log4j.ConsoleAppender; 4 | import org.apache.log4j.FileAppender; 5 | import org.apache.log4j.Level; 6 | import org.apache.log4j.Logger; 7 | import org.apache.log4j.PatternLayout; 8 | 9 | public class LoggingConfig { 10 | public static ConsoleAppender getConsole() { 11 | if (LoggingConfig.console == null) { 12 | LoggingConfig.console = new ConsoleAppender(); // create appender 13 | // configure the appender 14 | final String PATTERN = "%d [%p|%c|%C{1}] %m%n"; 15 | LoggingConfig.console.setLayout(new PatternLayout(PATTERN)); 16 | LoggingConfig.console.setThreshold(Level.INFO); 17 | LoggingConfig.console.activateOptions(); 18 | // add appender to any Logger (here is root) 19 | Logger.getRootLogger().addAppender(LoggingConfig.console); 20 | } 21 | return LoggingConfig.console; 22 | } 23 | 24 | public static FileAppender getLog() { 25 | if (LoggingConfig.log == null) { 26 | LoggingConfig.log = new FileAppender(); 27 | LoggingConfig.log.setName("FileLogger"); 28 | LoggingConfig.log.setFile("/tmp/loggingConfig.log"); 29 | LoggingConfig.log.setLayout(new PatternLayout( 30 | "%d %-5p [%c{1}] %m%n")); 31 | LoggingConfig.log.setThreshold(Level.DEBUG); 32 | LoggingConfig.log.setAppend(true); 33 | LoggingConfig.log.activateOptions(); 34 | Logger.getRootLogger().addAppender(LoggingConfig.log); 35 | } 36 | return LoggingConfig.log; 37 | } 38 | 39 | public static void setConsole(final Level level) { 40 | LoggingConfig.getConsole().setThreshold(level); 41 | } 42 | 43 | public static void setLog(final Level level) { 44 | LoggingConfig.getLog().setThreshold(level); 45 | } 46 | 47 | public static void setLogger(final Class clazz, final Level level) { 48 | Logger.getLogger(clazz).setLevel(level); 49 | } 50 | 51 | public static void setLogger(final String name, final Level level) { 52 | Logger.getLogger(name).setLevel(level); 53 | } 54 | 55 | public static void setRootLogger(final Level level) { 56 | Logger.getRootLogger().setLevel(level); 57 | } 58 | 59 | private static ConsoleAppender console; 60 | 61 | private static FileAppender log; 62 | } 63 | -------------------------------------------------------------------------------- /src/main/java/org/xenei/jdbc4sparql/sparql/SparqlResultSet.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one 3 | * or more contributor license agreements. See the NOTICE file 4 | * distributed with this work for additional information 5 | * regarding copyright ownership. The ASF licenses this file 6 | * to you under the Apache License, Version 2.0 (the 7 | * "License"); you may not use this file except in compliance 8 | * with the License. You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | package org.xenei.jdbc4sparql.sparql; 19 | 20 | import java.sql.SQLException; 21 | 22 | import org.xenei.jdbc4sparql.iface.Table; 23 | import org.xenei.jdbc4sparql.iface.TypeConverter; 24 | import org.xenei.jdbc4sparql.impl.ListResultSet; 25 | 26 | import com.hp.hpl.jena.query.Query; 27 | import com.hp.hpl.jena.query.QuerySolution; 28 | import com.hp.hpl.jena.rdf.model.RDFNode; 29 | 30 | public class SparqlResultSet extends ListResultSet { 31 | private final Query query; 32 | 33 | public SparqlResultSet(final Table table, final Query query) 34 | throws SQLException { 35 | super(table.getCatalog().executeLocalQuery(query), table); 36 | this.query = query; 37 | } 38 | 39 | @Override 40 | protected Table getTable() { 41 | return super.getTable(); 42 | } 43 | 44 | @Override 45 | protected Object readObject(final int columnOrdinal) throws SQLException { 46 | checkPosition(); 47 | checkColumn(columnOrdinal); 48 | final QuerySolution soln = (QuerySolution) getRowObject(); 49 | final String colName = query.getProjectVars().get(columnOrdinal - 1) 50 | .getName(); 51 | final RDFNode node = soln.get(colName); 52 | 53 | if (node == null) { 54 | return null; 55 | } 56 | if (node.isLiteral()) { 57 | return TypeConverter.getJavaValue(node.asLiteral()); 58 | } 59 | return node.toString(); 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /src/test/java/org/xenei/jdbc4sparql/iface/name/NameSegmentTest.java: -------------------------------------------------------------------------------- 1 | package org.xenei.jdbc4sparql.iface.name; 2 | 3 | import static org.junit.Assert.assertEquals; 4 | 5 | import java.util.ArrayList; 6 | import java.util.Collection; 7 | import java.util.List; 8 | 9 | import org.junit.Test; 10 | import org.junit.runner.RunWith; 11 | import org.junit.runners.Parameterized; 12 | import org.junit.runners.Parameterized.Parameters; 13 | 14 | @RunWith(Parameterized.class) 15 | public class NameSegmentTest { 16 | private final FQName baseName; 17 | private final NameSegments segments; 18 | private final boolean catalog; 19 | private final boolean schema; 20 | private final boolean table; 21 | private final boolean column; 22 | 23 | public NameSegmentTest(final Boolean catalog, final Boolean schema, 24 | final Boolean table, final Boolean column) { 25 | segments = NameSegments.getInstance(catalog, schema, table, column); 26 | baseName = new FQNameImpl("catalog", "schema", "table", "column"); 27 | this.catalog = catalog; 28 | this.schema = schema; 29 | this.table = table; 30 | this.column = column; 31 | } 32 | 33 | @Parameters(name = "catalog:{0} schema:{1} table:{2} col:{3}") 34 | public static Collection data() { 35 | final Boolean vals[] = new Boolean[] { 36 | Boolean.TRUE, Boolean.FALSE 37 | }; 38 | final List lst = new ArrayList(); 39 | for (final Boolean catalog : vals) { 40 | for (final Boolean schema : vals) { 41 | for (final Boolean table : vals) { 42 | for (final Boolean column : vals) { 43 | lst.add(new Boolean[] { 44 | catalog, schema, table, column 45 | }); 46 | } 47 | } 48 | } 49 | } 50 | return lst; 51 | } 52 | 53 | @Test 54 | public void testGetCatalog() { 55 | assertEquals(catalog ? "catalog" : null, segments.getCatalog(baseName)); 56 | } 57 | 58 | @Test 59 | public void testGetSchema() { 60 | assertEquals(schema ? "schema" : null, segments.getSchema(baseName)); 61 | } 62 | 63 | @Test 64 | public void testGetTable() { 65 | assertEquals(table ? "table" : null, segments.getTable(baseName)); 66 | } 67 | 68 | @Test 69 | public void testGetColumn() { 70 | assertEquals(column ? "column" : null, segments.getColumn(baseName)); 71 | } 72 | 73 | } 74 | -------------------------------------------------------------------------------- /src/main/java/org/xenei/jdbc4sparql/impl/AbstractTable.java: -------------------------------------------------------------------------------- 1 | package org.xenei.jdbc4sparql.impl; 2 | 3 | import java.util.Iterator; 4 | import java.util.List; 5 | 6 | import org.xenei.jdbc4sparql.iface.Catalog; 7 | import org.xenei.jdbc4sparql.iface.Column; 8 | import org.xenei.jdbc4sparql.iface.NameFilter; 9 | import org.xenei.jdbc4sparql.iface.Table; 10 | 11 | public abstract class AbstractTable implements Table { 12 | 13 | public AbstractTable() { 14 | 15 | } 16 | 17 | @Override 18 | public NameFilter findColumns(final String columnNamePattern) { 19 | return new NameFilter(columnNamePattern, getColumns()); 20 | } 21 | 22 | @Override 23 | public Catalog getCatalog() { 24 | return getSchema().getCatalog(); 25 | } 26 | 27 | @Override 28 | public Column getColumn(final int idx) { 29 | return getColumnList().get(idx); 30 | } 31 | 32 | @Override 33 | public Column getColumn(final String name) { 34 | for (final Column col : getColumnList()) { 35 | if (col.getName().equals(name)) { 36 | return col; 37 | } 38 | } 39 | return null; 40 | } 41 | 42 | @Override 43 | public int getColumnCount() { 44 | return getColumnList().size(); 45 | } 46 | 47 | @Override 48 | public int getColumnIndex(final Column column) { 49 | return getColumnList().indexOf(column); 50 | } 51 | 52 | /** 53 | * Returns the column index for hte name or -1 if not found 54 | * 55 | * @param columnName 56 | * The name to search for 57 | * @return the column index (0 based) or -1 if not found. 58 | */ 59 | @Override 60 | public int getColumnIndex(final String columnName) { 61 | final List cols = getColumnList(); 62 | for (int i = 0; i < cols.size(); i++) { 63 | if (cols.get(i).getName().equals(columnName)) { 64 | return i; 65 | } 66 | } 67 | return -1; 68 | } 69 | 70 | @Override 71 | public Iterator getColumns() { 72 | return getColumnList().iterator(); 73 | } 74 | 75 | @Override 76 | public String getSPARQLName() { 77 | return NameUtils.getSPARQLName(this); 78 | } 79 | 80 | @Override 81 | public String getSQLName() { 82 | return NameUtils.getDBName(this); 83 | } 84 | 85 | @Override 86 | public String toString() { 87 | return String.format("Table[ %s.%s ]", getCatalog().getName(), 88 | getSQLName()); 89 | } 90 | } 91 | -------------------------------------------------------------------------------- /src/example/org/xenei/jdbc4sparql/example/SQLClient.java: -------------------------------------------------------------------------------- 1 | package org.xenei.jdbc4sparql.example; 2 | 3 | import java.io.IOException; 4 | import java.net.URISyntaxException; 5 | import java.sql.Connection; 6 | import java.sql.DatabaseMetaData; 7 | import java.sql.ResultSet; 8 | import java.sql.ResultSetMetaData; 9 | import java.sql.SQLException; 10 | import java.sql.Statement; 11 | import java.util.Properties; 12 | 13 | import org.xenei.jdbc4sparql.J4SConnection; 14 | import org.xenei.jdbc4sparql.J4SDriver; 15 | import org.xenei.jdbc4sparql.J4SUrl; 16 | import org.xenei.jena.entities.MissingAnnotation; 17 | 18 | public class SQLClient { 19 | 20 | private static void doIO(final Connection connection, final String queryStr) 21 | throws SQLException { 22 | final DatabaseMetaData md = connection.getMetaData(); 23 | ResultSet rs = md.getTables(null, null, null, null); 24 | while (rs.next()) { 25 | System.out.println(String.format("%s.%s.%s", 26 | rs.getString("TABLE_CAT"), rs.getString("TABLE_SCHEM"), 27 | rs.getString("TABLE_NAME"))); 28 | } 29 | rs.close(); 30 | final Statement stmt = connection.createStatement(); 31 | stmt.execute("SELECT * FROM Agent_data"); 32 | rs = stmt.getResultSet(); 33 | final ResultSetMetaData rsmd = rs.getMetaData(); 34 | while (rs.next()) { 35 | for (int i = 0; i < rsmd.getColumnCount(); i++) { 36 | System.out.print(String.format("[%s]%s ", 37 | rsmd.getColumnName(i + 1), rs.getString(i + 1))); 38 | } 39 | System.out.println(); 40 | } 41 | rs.close(); 42 | stmt.close(); 43 | } 44 | 45 | public static void main(final String[] args) throws URISyntaxException, 46 | IOException, SQLException, ClassNotFoundException, 47 | InstantiationException, IllegalAccessException, MissingAnnotation { 48 | // final File outFile = ConfigBuilder.gatherSchema(Arrays.asList(args) 49 | // .subList(1, args.length)); 50 | 51 | final J4SDriver driver = new J4SDriver(); 52 | 53 | final String urlStr = String.format("jdbc:j4s:file:%s", 54 | "/tmp/configBuilder.zip"); 55 | final J4SUrl url = new J4SUrl(urlStr); 56 | System.out.println("Opening " + url); 57 | final Properties properties = new Properties(); 58 | 59 | final J4SConnection connection = new J4SConnection(driver, url, 60 | properties); 61 | SQLClient.doIO(connection, ""); 62 | 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /src/test/resources/org/xenei/jdbc4sparql/J4SStatementOuterJoinTest.ttl: -------------------------------------------------------------------------------- 1 | # 2 | # The foo table 3 | # 4 | 5 | 6 | a . 7 | 8 | [] a ; 9 | 10 | "5" ; 11 | 12 | "Foo5String" . 13 | 14 | [] a ; 15 | 16 | "6" ; 17 | 18 | "6" ; 19 | 20 | "FooNullableFooString" ; 21 | 22 | "Foo6tring" . 23 | 24 | 25 | [] a ; 26 | 27 | "7" ; 28 | 29 | "Foo7String" . 30 | 31 | # 32 | # The bar table 33 | # 34 | 35 | 36 | a . 37 | 38 | [] a ; 39 | 40 | "15" ; 41 | 42 | "16" ; 43 | 44 | "BarNullableFooString" ; 45 | 46 | "Bar15String" . 47 | 48 | 49 | [] a ; 50 | 51 | "5" ; 52 | 53 | "26" ; 54 | 55 | "BarNullableFoo3String" ; 56 | 57 | "Bar5String" . 58 | 59 | [] a ; 60 | 61 | "7" ; 62 | 63 | "Bar7String" . 64 | -------------------------------------------------------------------------------- /src/test/java/org/xenei/jdbc4sparql/SystemFunctionTests.java: -------------------------------------------------------------------------------- 1 | package org.xenei.jdbc4sparql; 2 | 3 | import java.net.URL; 4 | import java.sql.DriverManager; 5 | import java.sql.ResultSet; 6 | import java.sql.ResultSetMetaData; 7 | import java.util.Properties; 8 | 9 | import org.apache.log4j.Level; 10 | import org.junit.Assert; 11 | import org.junit.Before; 12 | import org.junit.Test; 13 | 14 | public class SystemFunctionTests extends AbstractJ4SSetup { 15 | // file URL 16 | private URL fUrl; 17 | 18 | // J4SUrl 19 | private String url; 20 | 21 | @Before 22 | public void setup() throws Exception { 23 | LoggingConfig.setConsole(Level.DEBUG); 24 | LoggingConfig.setRootLogger(Level.INFO); 25 | LoggingConfig.setLogger("com.hp.hpl.jena.", Level.INFO); 26 | LoggingConfig.setLogger("org.xenei.jdbc4sparql", Level.DEBUG); 27 | Class.forName("org.xenei.jdbc4sparql.J4SDriver"); 28 | 29 | fUrl = J4SDriverTest.class.getResource("./J4SStatementTest.ttl"); 30 | 31 | url = "jdbc:j4s?catalog=test&type=turtle&builder=org.xenei.jdbc4sparql.sparql.builders.SimpleNullableBuilder:" 32 | + fUrl.toString(); 33 | 34 | final Properties prop = new Properties(); 35 | prop.setProperty(J4SPropertyNames.USER_PROPERTY, "myschema"); 36 | prop.setProperty(J4SPropertyNames.PASSWORD_PROPERTY, "mypassw"); 37 | conn = DriverManager.getConnection(url, prop); 38 | conn.setAutoCommit(false); 39 | stmt = conn.createStatement(); 40 | // TODO remove this 41 | // ((J4SConnection)conn).saveConfig( new 42 | // java.io.File("/tmp/J4SStatementTest.zip")); 43 | } 44 | 45 | @Test 46 | public void testCatalogFunction() throws Exception { 47 | 48 | // count all the rows 49 | final ResultSet rset = stmt 50 | .executeQuery("select catalog() from fooTable"); 51 | final ResultSetMetaData rsm = rset.getMetaData(); 52 | Assert.assertEquals(1, rsm.getColumnCount()); 53 | rset.next(); 54 | Assert.assertEquals("test", rset.getString(1)); 55 | rset.close(); 56 | 57 | } 58 | 59 | @Test 60 | public void testVersionFunction() throws Exception { 61 | 62 | final ResultSet rset = stmt 63 | .executeQuery("select version() From fooTable"); 64 | final ResultSetMetaData rsm = rset.getMetaData(); 65 | Assert.assertEquals(1, rsm.getColumnCount()); 66 | rset.next(); 67 | Assert.assertEquals(J4SDriver.getVersion(), rset.getString(1)); 68 | rset.close(); 69 | } 70 | 71 | } 72 | -------------------------------------------------------------------------------- /src/test/java/org/xenei/jdbc4sparql/iface/name/TableNameConstructorTests.java: -------------------------------------------------------------------------------- 1 | package org.xenei.jdbc4sparql.iface.name; 2 | 3 | import static org.junit.Assert.assertEquals; 4 | import static org.junit.Assert.fail; 5 | 6 | import org.junit.Test; 7 | 8 | public class TableNameConstructorTests { 9 | 10 | private final String catalog = "catalog"; 11 | private final String schema = "schema"; 12 | private final String table = "table"; 13 | 14 | @Test 15 | public void testNullTable() { 16 | try { 17 | new TableName(catalog, schema, null); 18 | fail("Should have thrown IllegalArgumentException"); 19 | } catch (final IllegalArgumentException e) { 20 | assertEquals("Segment table may not be null", e.getMessage()); 21 | } 22 | 23 | } 24 | 25 | @Test 26 | public void testNullSchema() { 27 | try { 28 | new TableName(catalog, null, table); 29 | fail("Should have thrown IllegalArgumentException"); 30 | } catch (final IllegalArgumentException e) { 31 | assertEquals("Segment schema may not be null", e.getMessage()); 32 | } 33 | 34 | try { 35 | new TableName(catalog, null, null); 36 | fail("Should have thrown IllegalArgumentException"); 37 | } catch (final IllegalArgumentException e) { 38 | assertEquals("Segment schema may not be null", e.getMessage()); 39 | } 40 | 41 | } 42 | 43 | @Test 44 | public void testNullCatalog() { 45 | try { 46 | new TableName(null, schema, table); 47 | fail("Should have thrown IllegalArgumentException"); 48 | } catch (final IllegalArgumentException e) { 49 | assertEquals("Segment catalog may not be null", e.getMessage()); 50 | } 51 | 52 | try { 53 | new TableName(null, schema, null); 54 | fail("Should have thrown IllegalArgumentException"); 55 | } catch (final IllegalArgumentException e) { 56 | assertEquals("Segment catalog may not be null", e.getMessage()); 57 | } 58 | 59 | try { 60 | new TableName(null, null, table); 61 | fail("Should have thrown IllegalArgumentException"); 62 | } catch (final IllegalArgumentException e) { 63 | assertEquals("Segment catalog may not be null", e.getMessage()); 64 | } 65 | 66 | try { 67 | new TableName(null, null, null); 68 | fail("Should have thrown IllegalArgumentException"); 69 | } catch (final IllegalArgumentException e) { 70 | assertEquals("Segment catalog may not be null", e.getMessage()); 71 | } 72 | 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /src/test/java/org/xenei/jdbc4sparql/impl/rdf/ColumnBuilderTests.java: -------------------------------------------------------------------------------- 1 | package org.xenei.jdbc4sparql.impl.rdf; 2 | 3 | import static org.mockito.Mockito.mock; 4 | import static org.mockito.Mockito.when; 5 | 6 | import org.junit.After; 7 | import org.junit.Assert; 8 | import org.junit.Before; 9 | import org.junit.Test; 10 | import org.xenei.jdbc4sparql.iface.Column; 11 | import org.xenei.jdbc4sparql.iface.ColumnDef; 12 | import org.xenei.jdbc4sparql.iface.name.TableName; 13 | 14 | import com.hp.hpl.jena.rdf.model.Model; 15 | import com.hp.hpl.jena.rdf.model.ModelFactory; 16 | 17 | public class ColumnBuilderTests { 18 | private Model model; 19 | private ColumnDef columnDef; 20 | private RdfTable mockTable; 21 | 22 | @Before 23 | public void setUp() throws Exception { 24 | model = ModelFactory.createDefaultModel(); 25 | columnDef = RdfColumnDef.Builder.getStringBuilder().build(model); 26 | mockTable = mock(RdfTable.class); 27 | when(mockTable.getResource()).thenReturn( 28 | model.createResource("http://example.com/mockTable")); 29 | when(mockTable.getName()).thenReturn( 30 | new TableName("catalog", "schema", "table")); 31 | } 32 | 33 | @After 34 | public void tearDown() throws Exception { 35 | model.close(); 36 | } 37 | 38 | @Test 39 | public void testStandardCreation() { 40 | final RdfColumn.Builder builder = new RdfColumn.Builder() 41 | .setColumnDef(columnDef).setName("test").setTable(mockTable); 42 | final Column cd = builder.build(model); 43 | Assert.assertEquals("test", cd.getName().getShortName()); 44 | Assert.assertEquals(false, cd.getColumnDef().isAutoIncrement()); 45 | Assert.assertEquals(false, cd.getColumnDef().isCaseSensitive()); 46 | Assert.assertEquals("", cd.getColumnDef().getColumnClassName()); 47 | Assert.assertEquals(false, cd.getColumnDef().isCurrency()); 48 | Assert.assertEquals(false, cd.getColumnDef().isDefinitelyWritable()); 49 | Assert.assertEquals(0, cd.getColumnDef().getDisplaySize()); 50 | Assert.assertEquals(0, cd.getColumnDef().getNullable()); 51 | Assert.assertEquals(0, cd.getColumnDef().getPrecision()); 52 | Assert.assertEquals(false, cd.getColumnDef().isReadOnly()); 53 | Assert.assertEquals(0, cd.getColumnDef().getScale()); 54 | Assert.assertEquals(false, cd.getColumnDef().isSearchable()); 55 | Assert.assertEquals(false, cd.getColumnDef().isSigned()); 56 | Assert.assertEquals("String", cd.getColumnDef().getTypeName()); 57 | Assert.assertEquals(false, cd.getColumnDef().isWritable()); 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /src/main/java/org/xenei/jdbc4sparql/iface/name/CatalogName.java: -------------------------------------------------------------------------------- 1 | package org.xenei.jdbc4sparql.iface.name; 2 | 3 | import org.apache.commons.lang.StringUtils; 4 | 5 | /** 6 | * Catalog ItemName implementation. 7 | */ 8 | public class CatalogName extends ItemName { 9 | /** 10 | * Check the catalog name. Checks that the itemName catalog name segment is 11 | * not null. 12 | * 13 | * @param name 14 | * The ItemName to check. 15 | * @return the ItemName 16 | * @Throws IllegalArgumentException 17 | */ 18 | static ItemName checkItemName(final ItemName name) 19 | throws IllegalArgumentException { 20 | if (name == null) { 21 | throw new IllegalArgumentException("name may not be null"); 22 | } 23 | checkNotNull(name.getFQName().getCatalog(), "catalog"); 24 | return name; 25 | } 26 | 27 | /** 28 | * Create a CatalogName from an ItemName. 29 | * 30 | * @param name 31 | * the ItemName, must not be null. 32 | * @Throws IllegalArgumentException is name is null. 33 | */ 34 | public CatalogName(final ItemName name) throws IllegalArgumentException { 35 | super(checkItemName(name), NameSegments.CATALOG); 36 | } 37 | 38 | /** 39 | * Create a CatalogName from a catalog name string. Uses the default 40 | * namesegments for a catalog. 41 | * 42 | * @param catalog 43 | * the catalog name string. 44 | * @throws IllegalArgumentException 45 | * if the catalog name string is null. 46 | */ 47 | public CatalogName(final String catalog) throws IllegalArgumentException { 48 | super( 49 | new FQNameImpl(checkNotNull(catalog, "catalog"), null, null, 50 | null), NameSegments.CATALOG); 51 | } 52 | 53 | /** 54 | * Create a schemas name in this catalog. 55 | * 56 | * @param column 57 | * the columnName string 58 | * @return the ColumnName 59 | * @throws IllegalArgumentException 60 | */ 61 | public SchemaName getSchemaName(final String name) { 62 | return new SchemaName(getFQName().getCatalog(), name); 63 | } 64 | 65 | @Override 66 | protected String createName(final String separator) { 67 | return StringUtils.defaultString(getCatalog(), ""); 68 | } 69 | 70 | @Override 71 | public String getShortName() { 72 | return getCatalog(); 73 | } 74 | 75 | @Override 76 | public String toString() { 77 | return getCatalog(); 78 | } 79 | 80 | /** 81 | * Clone this catalog name with different segments. 82 | */ 83 | @Override 84 | public CatalogName clone(final NameSegments segs) { 85 | return new CatalogName(this); 86 | } 87 | } -------------------------------------------------------------------------------- /src/test/java/org/xenei/jdbc4sparql/iface/name/BaseNameImplTest.java: -------------------------------------------------------------------------------- 1 | package org.xenei.jdbc4sparql.iface.name; 2 | 3 | import static org.junit.Assert.assertEquals; 4 | import static org.junit.Assert.assertNotEquals; 5 | 6 | import org.junit.Before; 7 | import org.junit.Test; 8 | 9 | public class BaseNameImplTest { 10 | 11 | public static final String CATALOG = "catalog"; 12 | public static final String SCHEMA = "schema"; 13 | public static final String TABLE = "table"; 14 | public static final String COLUMN = "column"; 15 | 16 | protected FQNameImpl baseName; 17 | 18 | @Before 19 | public void setup() { 20 | baseName = new FQNameImpl(CATALOG, SCHEMA, TABLE, COLUMN); 21 | } 22 | 23 | @Test 24 | public void testGetCatalog() { 25 | assertEquals(CATALOG, baseName.getCatalog()); 26 | } 27 | 28 | @Test 29 | public void testGetSchema() { 30 | assertEquals(SCHEMA, baseName.getSchema()); 31 | } 32 | 33 | @Test 34 | public void testGetTable() { 35 | assertEquals(TABLE, baseName.getTable()); 36 | } 37 | 38 | @Test 39 | public void testGetColumn() { 40 | assertEquals(COLUMN, baseName.getColumn()); 41 | } 42 | 43 | @Test 44 | public void testEquality() { 45 | final FQName bn2 = new FQNameImpl(CATALOG, SCHEMA, TABLE, COLUMN); 46 | assertEquals(baseName, bn2); 47 | assertEquals(bn2, baseName); 48 | assertEquals(baseName.hashCode(), bn2.hashCode()); 49 | } 50 | 51 | @Test 52 | public void testInEquality() { 53 | FQName bn2 = new FQNameImpl(CATALOG, SCHEMA, TABLE, COLUMN + "1"); 54 | assertNotEquals(baseName, bn2); 55 | assertNotEquals(bn2, baseName); 56 | 57 | bn2 = new FQNameImpl(CATALOG, SCHEMA, TABLE + "1", COLUMN); 58 | assertNotEquals(baseName, bn2); 59 | assertNotEquals(bn2, baseName); 60 | 61 | bn2 = new FQNameImpl(CATALOG, SCHEMA + "1", TABLE, COLUMN); 62 | assertNotEquals(baseName, bn2); 63 | assertNotEquals(bn2, baseName); 64 | 65 | bn2 = new FQNameImpl(CATALOG + "1", SCHEMA, TABLE, COLUMN); 66 | assertNotEquals(baseName, bn2); 67 | assertNotEquals(bn2, baseName); 68 | 69 | bn2 = new FQNameImpl(CATALOG, SCHEMA, TABLE, null); 70 | assertNotEquals(baseName, bn2); 71 | assertNotEquals(bn2, baseName); 72 | 73 | bn2 = new FQNameImpl(CATALOG, SCHEMA, null, COLUMN); 74 | assertNotEquals(baseName, bn2); 75 | assertNotEquals(bn2, baseName); 76 | 77 | bn2 = new FQNameImpl(CATALOG, null, TABLE, COLUMN); 78 | assertNotEquals(baseName, bn2); 79 | assertNotEquals(bn2, baseName); 80 | 81 | bn2 = new FQNameImpl(null, SCHEMA, TABLE, COLUMN); 82 | assertNotEquals(baseName, bn2); 83 | assertNotEquals(bn2, baseName); 84 | } 85 | 86 | } 87 | -------------------------------------------------------------------------------- /src/main/java/org/xenei/jdbc4sparql/iface/Catalog.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one 3 | * or more contributor license agreements. See the NOTICE file 4 | * distributed with this work for additional information 5 | * regarding copyright ownership. The ASF licenses this file 6 | * to you under the Apache License, Version 2.0 (the 7 | * "License"); you may not use this file except in compliance 8 | * with the License. You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | package org.xenei.jdbc4sparql.iface; 19 | 20 | import java.util.List; 21 | import java.util.Set; 22 | 23 | import org.xenei.jdbc4sparql.iface.name.CatalogName; 24 | import org.xenei.jdbc4sparql.sparql.items.NamedObject; 25 | 26 | import com.hp.hpl.jena.graph.Node; 27 | import com.hp.hpl.jena.query.Query; 28 | import com.hp.hpl.jena.query.QuerySolution; 29 | 30 | public interface Catalog extends NamedObject { 31 | /** 32 | * Close release all associated resources. 33 | */ 34 | public void close(); 35 | 36 | /** 37 | * Execute the query against the local Model. 38 | * 39 | * This is used to execute queries built by the query builder. 40 | * 41 | * @param query 42 | * @return The list of QuerySolutions. 43 | */ 44 | public List executeLocalQuery(final Query query); 45 | 46 | /** 47 | * Return the list of schemas that have names matching the pattern if name 48 | * pattern == null return all the schemas if name pattern == "" return only 49 | * unamed schemas. if name is anything else match the string. 50 | * 51 | * @param schemaNamePattern 52 | * @return 53 | */ 54 | NameFilter findSchemas(String schemaNamePattern); 55 | 56 | /** 57 | * Get the schema 58 | * 59 | * @param schema 60 | * @return 61 | */ 62 | Schema getSchema(String schemaName); 63 | 64 | /** 65 | * 66 | * @param schemaPattern 67 | * a schema name pattern; must match the schema name as it is 68 | * stored in the database; "" retrieves those without a schema; 69 | * null means that all schemas should be returned 70 | * @return 71 | */ 72 | Set getSchemas(); 73 | 74 | String getShortName(); 75 | 76 | boolean isService(); 77 | 78 | Node getServiceNode(); 79 | 80 | } 81 | -------------------------------------------------------------------------------- /src/main/java/org/xenei/jdbc4sparql/impl/rdf/ResourceBuilder.java: -------------------------------------------------------------------------------- 1 | package org.xenei.jdbc4sparql.impl.rdf; 2 | 3 | import org.xenei.jdbc4sparql.iface.NamespacedObject; 4 | import org.xenei.jena.entities.EntityManager; 5 | import org.xenei.jena.entities.EntityManagerFactory; 6 | import org.xenei.jena.entities.annotations.Subject; 7 | 8 | import com.hp.hpl.jena.rdf.model.Model; 9 | import com.hp.hpl.jena.rdf.model.Property; 10 | import com.hp.hpl.jena.rdf.model.Resource; 11 | import com.hp.hpl.jena.vocabulary.RDF; 12 | 13 | public class ResourceBuilder { 14 | public static String getFQName(final Class nsClass) { 15 | final String s = ResourceBuilder.getNamespace(nsClass); 16 | 17 | return s.substring(0, s.length() - 1); 18 | } 19 | 20 | public static String getNamespace(final Class nsClass) { 21 | final EntityManager em = EntityManagerFactory.getEntityManager(); 22 | final Subject subject = em.getSubject(nsClass); 23 | if (subject == null) { 24 | throw new IllegalArgumentException(String.format( 25 | "%s is does not have a subject annotation", nsClass)); 26 | } 27 | return subject.namespace(); 28 | } 29 | 30 | private final Model model; 31 | 32 | public ResourceBuilder(final Model model) { 33 | if (model == null) { 34 | throw new IllegalArgumentException("Model may not be null"); 35 | } 36 | this.model = model; 37 | } 38 | 39 | public Property getProperty(final Class typeClass, final String localName) { 40 | return model.createProperty(ResourceBuilder.getNamespace(typeClass), 41 | localName); 42 | } 43 | 44 | /** 45 | * Get the resource from the model or create if if it does not exist. 46 | * 47 | * @return 48 | */ 49 | public Resource getResource(final String fqName, final Class typeClass) { 50 | final Resource type = model.createResource(ResourceBuilder 51 | .getFQName(typeClass)); 52 | 53 | Resource retval; 54 | if (hasResource(fqName)) { 55 | retval = model.getResource(fqName); 56 | if (!retval.hasProperty(RDF.type, type)) { 57 | throw new IllegalStateException(String.format( 58 | "Object %s is of type %s not %s", retval.getURI(), 59 | retval.getRequiredProperty(RDF.type).getResource() 60 | .getURI(), type.getURI())); 61 | } 62 | } 63 | else { 64 | retval = model.createResource(fqName, type); 65 | } 66 | return retval; 67 | } 68 | 69 | /** 70 | * Determine if the resource is in the model. 71 | * 72 | * @param obj 73 | * @return 74 | */ 75 | public boolean hasResource(final NamespacedObject obj) { 76 | return hasResource(obj.getFQName()); 77 | } 78 | 79 | public boolean hasResource(final String fqName) { 80 | return model.contains(model.createResource(fqName), null); 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /src/test/java/org/xenei/jdbc4sparql/impl/rdf/TableBuilderTest.java: -------------------------------------------------------------------------------- 1 | package org.xenei.jdbc4sparql.impl.rdf; 2 | 3 | import java.util.List; 4 | 5 | import org.junit.After; 6 | import org.junit.Assert; 7 | import org.junit.Before; 8 | import org.junit.Test; 9 | import org.mockito.Mockito; 10 | import org.xenei.jdbc4sparql.iface.Column; 11 | import org.xenei.jdbc4sparql.iface.NameFilter; 12 | import org.xenei.jdbc4sparql.iface.name.SchemaName; 13 | import org.xenei.jena.entities.EntityManagerFactory; 14 | 15 | import com.hp.hpl.jena.rdf.model.Model; 16 | import com.hp.hpl.jena.rdf.model.ModelFactory; 17 | import com.hp.hpl.jena.rdf.model.Property; 18 | import com.hp.hpl.jena.rdf.model.RDFList; 19 | import com.hp.hpl.jena.rdf.model.RDFNode; 20 | 21 | public class TableBuilderTest { 22 | 23 | private Model model; 24 | private RdfTableDef tableDef; 25 | private RdfSchema mockSchema; 26 | 27 | @Before 28 | public void setUp() throws Exception { 29 | model = ModelFactory.createDefaultModel(); 30 | final RdfTableDef.Builder builder = new RdfTableDef.Builder() 31 | .addColumnDef( 32 | RdfColumnDef.Builder.getStringBuilder().build(model)) 33 | .addColumnDef( 34 | RdfColumnDef.Builder.getIntegerBuilder().build(model)); 35 | tableDef = builder.build(model); 36 | mockSchema = Mockito.mock(RdfSchema.class); 37 | Mockito.when(mockSchema.getResource()).thenReturn( 38 | model.createResource("http://example.com/mockSchema")); 39 | Mockito.when(mockSchema.getName()).thenReturn( 40 | new SchemaName("catalog", "schema")); 41 | } 42 | 43 | @After 44 | public void tearDown() throws Exception { 45 | model.close(); 46 | } 47 | 48 | @Test 49 | public void testDefaultBuilder() throws Exception { 50 | final RdfTable.Builder builder = new RdfTable.Builder() 51 | .setTableDef(tableDef).setName("table") 52 | .setColumn(0, "StringCol").setColumn(1, "IntCol") 53 | .setSchema(mockSchema).setType("testing Table"); 54 | final RdfTable table = builder.build(model); 55 | 56 | Assert.assertEquals(2, table.getColumnCount()); 57 | Assert.assertEquals("table", table.getName().getShortName()); 58 | final NameFilter nf = table.findColumns("StringCol"); 59 | Assert.assertTrue(nf.hasNext()); 60 | final Column c = nf.next(); 61 | Assert.assertEquals("StringCol", c.getName().getShortName()); 62 | Assert.assertFalse(nf.hasNext()); 63 | 64 | EntityManagerFactory.getEntityManager(); 65 | 66 | final Property p = model.createProperty( 67 | ResourceBuilder.getNamespace(RdfTable.class), "column"); 68 | 69 | final List columns = table.getResource() 70 | .getRequiredProperty(p).getResource().as(RDFList.class) 71 | .asJavaList(); 72 | 73 | Assert.assertEquals(2, columns.size()); 74 | 75 | } 76 | 77 | } 78 | -------------------------------------------------------------------------------- /src/main/java/org/xenei/jdbc4sparql/iface/ColumnDef.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one 3 | * or more contributor license agreements. See the NOTICE file 4 | * distributed with this work for additional information 5 | * regarding copyright ownership. The ASF licenses this file 6 | * to you under the Apache License, Version 2.0 (the 7 | * "License"); you may not use this file except in compliance 8 | * with the License. You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | package org.xenei.jdbc4sparql.iface; 19 | 20 | import java.security.NoSuchAlgorithmException; 21 | import java.util.UUID; 22 | 23 | public interface ColumnDef { 24 | static class Util { 25 | /** 26 | * Create a unique ID for a column def. 27 | * 28 | * @param def 29 | * The column def to create the ID for. 30 | * @return a type 3 UUID for the column. 31 | * @throws NoSuchAlgorithmException 32 | */ 33 | public static UUID createID(final ColumnDef def) { 34 | final StringBuilder sb = new StringBuilder() 35 | .append(def.getColumnClassName()) 36 | .append(def.getDisplaySize()).append(def.getNullable()) 37 | .append(def.getPrecision()).append(def.getScale()) 38 | .append(def.getType()).append(def.getTypeName()) 39 | .append(def.isAutoIncrement()) 40 | .append(def.isCaseSensitive()).append(def.isCurrency()) 41 | .append(def.isDefinitelyWritable()) 42 | .append(def.isReadOnly()).append(def.isSearchable()) 43 | .append(def.isSigned()).append(def.isWritable()); 44 | return UUID.nameUUIDFromBytes(sb.toString().getBytes()); 45 | } 46 | } 47 | 48 | String getColumnClassName(); 49 | 50 | int getDisplaySize(); 51 | 52 | /** 53 | * Indicates the nullability of values in the designated column. Possible 54 | * return values are ResultSetMetaData.columnNullable, 55 | * ResultSetMetaData.columnNoNulls, ResultSetMetaData.columnNullableUnknown 56 | * 57 | * @return the nullability status of the given column. 58 | */ 59 | int getNullable(); 60 | 61 | int getPrecision(); 62 | 63 | int getScale(); 64 | 65 | int getType(); 66 | 67 | String getTypeName(); 68 | 69 | boolean isAutoIncrement(); 70 | 71 | boolean isCaseSensitive(); 72 | 73 | boolean isCurrency(); 74 | 75 | boolean isDefinitelyWritable(); 76 | 77 | boolean isReadOnly(); 78 | 79 | boolean isSearchable(); 80 | 81 | boolean isSigned(); 82 | 83 | boolean isWritable(); 84 | } 85 | -------------------------------------------------------------------------------- /src/main/java/org/xenei/jdbc4sparql/impl/NavigableSetResultSet.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one 3 | * or more contributor license agreements. See the NOTICE file 4 | * distributed with this work for additional information 5 | * regarding copyright ownership. The ASF licenses this file 6 | * to you under the Apache License, Version 2.0 (the 7 | * "License"); you may not use this file except in compliance 8 | * with the License. You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | package org.xenei.jdbc4sparql.impl; 19 | 20 | import java.sql.SQLException; 21 | import java.util.NavigableSet; 22 | 23 | import org.xenei.jdbc4sparql.iface.Table; 24 | 25 | public abstract class NavigableSetResultSet extends AbstractCollectionResultSet { 26 | private Object currentObject; 27 | private Integer lastPosition; 28 | 29 | public NavigableSetResultSet(final NavigableSet rows, 30 | final Table table) throws SQLException { 31 | super(rows, table); 32 | } 33 | 34 | @Override 35 | protected void fixupPosition() throws SQLException { 36 | super.fixupPosition(); 37 | if (isBeforeFirst() || isAfterLast()) { 38 | lastPosition = getPosition(); 39 | currentObject = null; 40 | return; 41 | } 42 | if (isFirst()) { 43 | lastPosition = getPosition(); 44 | currentObject = getDataCollection().first(); 45 | return; 46 | } 47 | if (isLast()) { 48 | lastPosition = getPosition(); 49 | currentObject = getDataCollection().last(); 50 | return; 51 | } 52 | if (lastPosition == null) { 53 | if ((getDataCollection().size() / 2) > getPosition()) { 54 | lastPosition = 0; 55 | currentObject = getDataCollection().first(); 56 | } 57 | else { 58 | lastPosition = getDataCollection().size() - 1; 59 | currentObject = getDataCollection().last(); 60 | } 61 | } 62 | while (lastPosition > getPosition()) { 63 | currentObject = getDataCollection().lower(currentObject); 64 | lastPosition--; 65 | } 66 | while (lastPosition < getPosition()) { 67 | currentObject = getDataCollection().higher(currentObject); 68 | lastPosition++; 69 | } 70 | } 71 | 72 | @Override 73 | public NavigableSet getDataCollection() { 74 | return (NavigableSet) super.getDataCollection(); 75 | } 76 | 77 | @Override 78 | protected Object getRowObject() throws SQLException { 79 | if (currentObject == null) { 80 | throw new SQLException("Result set has not been positioned"); 81 | } 82 | return currentObject; 83 | } 84 | 85 | } 86 | -------------------------------------------------------------------------------- /src/test/java/org/xenei/jdbc4sparql/impl/rdf/SchemaBuilderTest.java: -------------------------------------------------------------------------------- 1 | package org.xenei.jdbc4sparql.impl.rdf; 2 | 3 | import static org.mockito.Mockito.mock; 4 | import static org.mockito.Mockito.when; 5 | 6 | import org.junit.After; 7 | import org.junit.Assert; 8 | import org.junit.Before; 9 | import org.junit.Test; 10 | import org.xenei.jdbc4sparql.iface.Schema; 11 | 12 | import com.hp.hpl.jena.rdf.model.Model; 13 | import com.hp.hpl.jena.rdf.model.ModelFactory; 14 | 15 | public class SchemaBuilderTest { 16 | 17 | private Model model; 18 | private RdfTable.Builder tableBldr; 19 | private RdfCatalog mockCatalog; 20 | 21 | @Before 22 | public void setUp() throws Exception { 23 | model = ModelFactory.createDefaultModel(); 24 | final RdfTableDef.Builder builder = new RdfTableDef.Builder() 25 | .addColumnDef( 26 | RdfColumnDef.Builder.getStringBuilder().build(model)) 27 | .addColumnDef( 28 | RdfColumnDef.Builder.getIntegerBuilder().build(model)); 29 | tableBldr = new RdfTable.Builder().setName("testTable") 30 | .setTableDef(builder.build(model)).setColumn(0, "StringCol") 31 | .setColumn(1, "IntCol"); 32 | mockCatalog = mock(RdfCatalog.class); 33 | when(mockCatalog.getResource()).thenReturn( 34 | model.createResource("http://example.com/mockCatalog")); 35 | when(mockCatalog.getShortName()).thenReturn("mockCatalog"); 36 | } 37 | 38 | @After 39 | public void tearDown() throws Exception { 40 | model.close(); 41 | } 42 | 43 | @Test 44 | public void testAddTable() throws Exception { 45 | final RdfSchema.Builder builder = new RdfSchema.Builder().setName( 46 | "schema").setCatalog(mockCatalog); 47 | 48 | final RdfSchema schema = builder.build(model); 49 | 50 | tableBldr.setSchema(schema).setType("test table").build(model); 51 | 52 | schema.getTables(); 53 | 54 | Assert.assertEquals("schema", schema.getName().getShortName()); 55 | Assert.assertNotNull(schema.getTables()); 56 | Assert.assertEquals(1, schema.getTables().size()); 57 | } 58 | 59 | @Test 60 | public void testAddTableTableRead() { 61 | final RdfSchema.Builder builder = new RdfSchema.Builder().setName( 62 | "schema").setCatalog(mockCatalog); 63 | 64 | final RdfSchema schema = builder.build(model); 65 | Assert.assertEquals(0, schema.getTables().size()); 66 | 67 | tableBldr.setSchema(schema).setType("Test table").build(model); 68 | 69 | Assert.assertEquals("schema", schema.getName().getShortName()); 70 | Assert.assertNotNull(schema.getTables()); 71 | Assert.assertEquals(1, schema.getTables().size()); 72 | } 73 | 74 | @Test 75 | public void testDefault() { 76 | final RdfSchema.Builder builder = new RdfSchema.Builder().setName( 77 | "schema").setCatalog(mockCatalog); 78 | 79 | final Schema schema = builder.build(model); 80 | schema.getTables(); 81 | Assert.assertEquals("schema", schema.getName().getShortName()); 82 | Assert.assertNotNull(schema.getTables()); 83 | Assert.assertEquals(0, schema.getTables().size()); 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /src/main/java/org/xenei/jdbc4sparql/iface/Column.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one 3 | * or more contributor license agreements. See the NOTICE file 4 | * distributed with this work for additional information 5 | * regarding copyright ownership. The ASF licenses this file 6 | * to you under the Apache License, Version 2.0 (the 7 | * "License"); you may not use this file except in compliance 8 | * with the License. You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | package org.xenei.jdbc4sparql.iface; 19 | 20 | import org.xenei.jdbc4sparql.iface.name.ColumnName; 21 | import org.xenei.jdbc4sparql.sparql.items.NamedObject; 22 | 23 | public interface Column extends NamedObject { 24 | /** 25 | * Get teh catalog this table is in. 26 | * 27 | * @return the Catalog this table is in. 28 | */ 29 | public Catalog getCatalog(); 30 | 31 | /** 32 | * Get the column definition for this column. 33 | * 34 | * @return the ColumnDef 35 | */ 36 | public ColumnDef getColumnDef(); 37 | 38 | /** 39 | * A string used to format the column name with respect to the table so that 40 | * the SPARQL query will retrieve the proper data. For example 41 | * "%1$s %2$s" 42 | * 43 | * %1$s is the table name %2$s is the column name 44 | * 45 | * @return Format string for query segments in SPARQL query 46 | */ 47 | public String getQuerySegmentFmt(); 48 | 49 | /** 50 | * Get the remarks for the column. 51 | * 52 | * @return the remarks 53 | */ 54 | public String getRemarks(); 55 | 56 | /** 57 | * Get the Schema for this column. 58 | * 59 | * @return The schema this table is in 60 | */ 61 | public Schema getSchema(); 62 | 63 | /** 64 | * Get the SPARQL name for this column. 65 | * 66 | * @return The name formatted for SPARQL 67 | */ 68 | public String getSPARQLName(); 69 | 70 | /** 71 | * get the SQL name for this column. 72 | * 73 | * @return the name formatted for SQL 74 | */ 75 | public String getSQLName(); 76 | 77 | /** 78 | * Get the table this column is in. 79 | * 80 | * @return The table this column is in. 81 | */ 82 | public Table getTable(); 83 | 84 | /** 85 | * Return true if this column has querySegments. Most columns do, however, 86 | * some function columns do not. 87 | * 88 | * @return 89 | */ 90 | public boolean hasQuerySegments(); 91 | 92 | /** 93 | * True if this column is optional 94 | * 95 | * @return 96 | */ 97 | public boolean isOptional(); 98 | 99 | } 100 | -------------------------------------------------------------------------------- /src/main/java/org/xenei/jdbc4sparql/sparql/parser/jsqlparser/functions/FunctionColumnDef.java: -------------------------------------------------------------------------------- 1 | package org.xenei.jdbc4sparql.sparql.parser.jsqlparser.functions; 2 | 3 | import java.sql.ResultSetMetaData; 4 | 5 | import org.xenei.jdbc4sparql.iface.ColumnDef; 6 | 7 | public class FunctionColumnDef implements ColumnDef { 8 | private int displaySize = 0; 9 | private int nullable = ResultSetMetaData.columnNoNulls; 10 | private int precision = 0; 11 | private int scale = 0; 12 | private final int type; 13 | private boolean autoIncrement = false; 14 | private boolean caseSensitive = false; 15 | private boolean currency = false; 16 | private boolean signed = false; 17 | 18 | public FunctionColumnDef(final int type) { 19 | this.type = type; 20 | } 21 | 22 | @Override 23 | public String getColumnClassName() { 24 | return null; 25 | } 26 | 27 | @Override 28 | public int getDisplaySize() { 29 | return displaySize; 30 | } 31 | 32 | @Override 33 | public int getNullable() { 34 | return nullable; 35 | } 36 | 37 | @Override 38 | public int getPrecision() { 39 | return precision; 40 | } 41 | 42 | @Override 43 | public int getScale() { 44 | return scale; 45 | } 46 | 47 | @Override 48 | public int getType() { 49 | return type; 50 | } 51 | 52 | @Override 53 | public String getTypeName() { 54 | // TODO Auto-generated method stub 55 | return null; 56 | } 57 | 58 | @Override 59 | public boolean isAutoIncrement() { 60 | return autoIncrement; 61 | } 62 | 63 | @Override 64 | public boolean isCaseSensitive() { 65 | return caseSensitive; 66 | } 67 | 68 | @Override 69 | public boolean isCurrency() { 70 | return currency; 71 | } 72 | 73 | @Override 74 | public boolean isDefinitelyWritable() { 75 | return false; 76 | } 77 | 78 | @Override 79 | public boolean isReadOnly() { 80 | return true; 81 | } 82 | 83 | @Override 84 | public boolean isSearchable() { 85 | return false; 86 | } 87 | 88 | @Override 89 | public boolean isSigned() { 90 | return signed; 91 | } 92 | 93 | @Override 94 | public boolean isWritable() { 95 | return false; 96 | } 97 | 98 | public void setAutoIncrement(final boolean autoIncrement) { 99 | this.autoIncrement = autoIncrement; 100 | } 101 | 102 | public void setCaseSensitive(final boolean caseSensitive) { 103 | this.caseSensitive = caseSensitive; 104 | } 105 | 106 | public void setCurrency(final boolean currency) { 107 | this.currency = currency; 108 | } 109 | 110 | public void setDisplaySize(final int displaySize) { 111 | this.displaySize = displaySize; 112 | } 113 | 114 | public void setNullable(final int nullable) { 115 | this.nullable = nullable; 116 | } 117 | 118 | public void setPrecision(final int precision) { 119 | this.precision = precision; 120 | } 121 | 122 | public void setScale(final int scale) { 123 | this.scale = scale; 124 | } 125 | 126 | public void setSigned(final boolean signed) { 127 | this.signed = signed; 128 | } 129 | 130 | } 131 | -------------------------------------------------------------------------------- /src/test/java/org/xenei/jdbc4sparql/sparql/builders/RDFSBuilderTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one 3 | * or more contributor license agreements. See the NOTICE file 4 | * distributed with this work for additional information 5 | * regarding copyright ownership. The ASF licenses this file 6 | * to you under the Apache License, Version 2.0 (the 7 | * "License"); you may not use this file except in compliance 8 | * with the License. You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | package org.xenei.jdbc4sparql.sparql.builders; 19 | 20 | import java.net.URL; 21 | import java.sql.SQLException; 22 | import java.util.Arrays; 23 | import java.util.List; 24 | import java.util.Set; 25 | 26 | import org.junit.Assert; 27 | import org.junit.Before; 28 | import org.junit.Test; 29 | import org.xenei.jdbc4sparql.impl.rdf.RdfCatalog; 30 | import org.xenei.jdbc4sparql.impl.rdf.RdfSchema; 31 | import org.xenei.jdbc4sparql.impl.rdf.RdfTable; 32 | 33 | import com.hp.hpl.jena.rdf.model.Model; 34 | import com.hp.hpl.jena.rdf.model.ModelFactory; 35 | 36 | public class RDFSBuilderTest { 37 | private RdfCatalog catalog; 38 | private RdfSchema schema; 39 | // data model 40 | private Model model; 41 | // schema model 42 | private Model schemaModel; 43 | 44 | private SchemaBuilder builder; 45 | 46 | private final String[] tableNames = { 47 | "Project", "Version", "Repository", "Agent", "Document", "Group", 48 | "Image", "Online_Account", "Person", "Spatial_Thing", "Concept", 49 | "Thing" 50 | }; 51 | 52 | @Test 53 | public void buildRdfTableTest() throws SQLException { 54 | final Set tables = builder.getTables(schema); 55 | final List tblNames = Arrays.asList(tableNames); 56 | for (final RdfTable tbl : tables) { 57 | Assert.assertTrue(tbl.getName() + " missing from table list", 58 | tblNames.contains(tbl.getName().getShortName())); 59 | } 60 | } 61 | 62 | @Before 63 | public void setup() { 64 | model = ModelFactory.createDefaultModel(); 65 | schemaModel = ModelFactory.createDefaultModel(); 66 | URL url = RDFSBuilderTest.class.getResource("./foaf.rdf"); 67 | model.read(url.toExternalForm()); 68 | url = RDFSBuilderTest.class.getResource("./jena.rdf"); 69 | model.read(url.toExternalForm()); 70 | url = RDFSBuilderTest.class.getResource("./doap.rdf"); 71 | model.read(url.toExternalForm()); 72 | model = ModelFactory.createRDFSModel(model); 73 | catalog = new RdfCatalog.Builder().setLocalModel(model) 74 | .setName("SimpleSparql").build(schemaModel); 75 | 76 | schema = new RdfSchema.Builder().setCatalog(catalog) 77 | .setName("builderTest").build(schemaModel); 78 | 79 | builder = new RDFSBuilder(); 80 | 81 | } 82 | 83 | } 84 | -------------------------------------------------------------------------------- /src/main/java/org/xenei/jdbc4sparql/sparql/parser/jsqlparser/SparqlFromVisitor.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of jdbc4sparql jsqlparser implementation. 3 | * 4 | * jdbc4sparql jsqlparser implementation is free software: you can redistribute 5 | * it and/or modify 6 | * it under the terms of the GNU Lesser General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * jdbc4sparql jsqlparser implementation is distributed in the hope that it will 11 | * be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public License 17 | * along with jdbc4sparql jsqlparser implementation. If not, see 18 | * . 19 | */ 20 | package org.xenei.jdbc4sparql.sparql.parser.jsqlparser; 21 | 22 | import java.sql.SQLException; 23 | 24 | import net.sf.jsqlparser.schema.Table; 25 | import net.sf.jsqlparser.statement.select.FromItemVisitor; 26 | import net.sf.jsqlparser.statement.select.SubJoin; 27 | import net.sf.jsqlparser.statement.select.SubSelect; 28 | 29 | import org.apache.commons.lang3.StringUtils; 30 | import org.slf4j.Logger; 31 | import org.slf4j.LoggerFactory; 32 | import org.xenei.jdbc4sparql.iface.name.TableName; 33 | import org.xenei.jdbc4sparql.sparql.SparqlQueryBuilder; 34 | 35 | class SparqlFromVisitor implements FromItemVisitor { 36 | 37 | private final SparqlQueryBuilder builder; 38 | private final boolean optional; 39 | private TableName name; 40 | private static Logger LOG = LoggerFactory 41 | .getLogger(SparqlFromVisitor.class); 42 | 43 | SparqlFromVisitor(final SparqlQueryBuilder builder) { 44 | this(builder, SparqlQueryBuilder.REQUIRED); 45 | } 46 | 47 | SparqlFromVisitor(final SparqlQueryBuilder builder, final boolean optional) { 48 | this.builder = builder; 49 | this.optional = optional; 50 | } 51 | 52 | public TableName getName() { 53 | return name; 54 | } 55 | 56 | @Override 57 | public void visit(final SubJoin subjoin) { 58 | throw new UnsupportedOperationException("FROM subjoin is not supported"); 59 | } 60 | 61 | @Override 62 | public void visit(final SubSelect subSelect) { 63 | throw new UnsupportedOperationException( 64 | "FROM subselect is not supported"); 65 | } 66 | 67 | @Override 68 | public void visit(final Table table) { 69 | if (LOG.isDebugEnabled()) { 70 | SparqlFromVisitor.LOG.debug("visit table: {}", table); 71 | } 72 | try { 73 | final String defaultCatalog = builder.getCatalogName(); 74 | final String defaultSchema = builder.getDefaultSchemaName(); 75 | final TableName tName = new TableName(defaultCatalog, 76 | StringUtils.defaultString(table.getSchemaName(), 77 | defaultSchema), table.getName()); 78 | name = (table.getAlias() != null) ? TableName.getNameInstance( 79 | defaultCatalog, defaultSchema, table.getAlias()) : tName; 80 | builder.addTable(tName, name, optional); 81 | 82 | } catch (final SQLException e) { 83 | throw new RuntimeException(e); 84 | } 85 | } 86 | } -------------------------------------------------------------------------------- /src/main/java/org/xenei/jdbc4sparql/sparql/items/QueryItemInfo.java: -------------------------------------------------------------------------------- 1 | package org.xenei.jdbc4sparql.sparql.items; 2 | 3 | import org.xenei.jdbc4sparql.iface.name.GUIDObject; 4 | import org.xenei.jdbc4sparql.iface.name.ItemName; 5 | import org.xenei.jdbc4sparql.iface.name.NameSegments; 6 | 7 | import com.hp.hpl.jena.sparql.core.Var; 8 | 9 | /** 10 | * The base class for the Query items. 11 | * 12 | * @param 13 | * The type of the name for query item. 14 | */ 15 | public class QueryItemInfo, N extends ItemName> 16 | implements NamedObject, GUIDObject { 17 | private final T baseObject; 18 | private final N name; 19 | private final Var guidVar; 20 | private boolean optional; 21 | 22 | protected QueryItemInfo(final T baseObject, final N name, 23 | final boolean optional) { 24 | if (baseObject == null) { 25 | throw new IllegalArgumentException("baseObject may not be null"); 26 | } 27 | if (name == null) { 28 | throw new IllegalArgumentException("name may not be null"); 29 | } 30 | this.baseObject = baseObject; 31 | this.name = name; 32 | this.guidVar = Var.alloc(this.name.getGUID()); 33 | this.optional = optional; 34 | 35 | } 36 | 37 | @Override 38 | public boolean equals(final Object o) { 39 | if (o instanceof QueryItemInfo) { 40 | final QueryItemInfo other = (QueryItemInfo) o; 41 | return this.getName().equals(other.getName()); 42 | // && this.isOptional() == other.isOptional(); 43 | } 44 | return false; 45 | } 46 | 47 | protected T getBaseObject() { 48 | return baseObject; 49 | } 50 | 51 | @Override 52 | public String getGUID() { 53 | return baseObject.getName().getGUID(); 54 | } 55 | 56 | /** 57 | * Get the GUID variable based on the name of this column. 58 | * 59 | * @return The var for is column. 60 | */ 61 | public Var getGUIDVar() { 62 | return guidVar; 63 | } 64 | 65 | /** 66 | * Get the name for the query item. 67 | * 68 | * @return the item name. 69 | */ 70 | @Override 71 | public N getName() { 72 | return name; 73 | } 74 | 75 | public NameSegments getSegments() { 76 | return this.name.getUsedSegments(); 77 | } 78 | 79 | /** 80 | * Get the variable for the query item. 81 | * 82 | * @return The variable based on the column name. 83 | */ 84 | public Var getVar() { 85 | return Var.alloc(this.name.getSPARQLName()); 86 | } 87 | 88 | @Override 89 | public int hashCode() { 90 | return getName().hashCode(); 91 | } 92 | 93 | /** 94 | * returns the optional flag. 95 | * 96 | * @return True if this item is optional. 97 | */ 98 | public boolean isOptional() { 99 | return optional; 100 | } 101 | 102 | /** 103 | * Set the optional flag 104 | * 105 | * @param optional 106 | * The value of the optional flag. 107 | */ 108 | protected void setOptional(final boolean optional) { 109 | this.optional = optional; 110 | } 111 | 112 | protected void setSegments(final NameSegments usedSegments) { 113 | this.name.setUsedSegments(usedSegments); 114 | } 115 | 116 | @Override 117 | public String toString() { 118 | return getName().toString(); 119 | } 120 | 121 | } 122 | -------------------------------------------------------------------------------- /src/main/java/org/xenei/jdbc4sparql/sparql/parser/jsqlparser/RegexNodeValue.java: -------------------------------------------------------------------------------- 1 | package org.xenei.jdbc4sparql.sparql.parser.jsqlparser; 2 | 3 | import java.util.HashMap; 4 | import java.util.Map; 5 | import java.util.StringTokenizer; 6 | 7 | import com.hp.hpl.jena.sparql.expr.nodevalue.NodeValueString; 8 | 9 | class RegexNodeValue extends NodeValueString { 10 | private final boolean wildcard; 11 | 12 | private RegexNodeValue(final String str, final boolean wildcard) { 13 | super(str); 14 | this.wildcard = wildcard; 15 | } 16 | 17 | public boolean isWildcard() { 18 | return wildcard; 19 | } 20 | 21 | private final static String SLASH = "\\"; 22 | private final static String PATTERN = "[]^.?*+{}()|$_%" + SLASH; 23 | private final static Map CONVERSION = new HashMap(); 24 | 25 | static { 26 | for (int i = 0; i < PATTERN.length(); i++) { 27 | final String s = PATTERN.substring(i, i + 1); 28 | CONVERSION.put(s, SLASH + s); 29 | } 30 | CONVERSION.put("_", "."); 31 | CONVERSION.put("%", "(.+)"); 32 | } 33 | 34 | public static RegexNodeValue create(final String part) { 35 | final StringTokenizer tokenizer = new StringTokenizer(part, PATTERN, 36 | true); 37 | final StringBuilder sb = new StringBuilder().append("^"); 38 | final StringBuilder plainSb = new StringBuilder(); 39 | final StringBuilder workingToken = new StringBuilder(); 40 | int backslashCount = 0; 41 | int wildcard = 0; 42 | int escaping = 0; 43 | while (tokenizer.hasMoreTokens()) { 44 | final String candidate = tokenizer.nextToken(); 45 | plainSb.append(candidate); 46 | if ((candidate.length() == 1) 47 | && CONVERSION.keySet().contains(candidate)) { 48 | // token 49 | 50 | // an even number of backslashes means that we are just creating 51 | // backslashes. 52 | if ((backslashCount > 0) && ((backslashCount % 2) != 0)) { 53 | if (candidate.equals("%") || candidate.equals("_")) { 54 | sb.setCharAt(sb.length() - 2, candidate.charAt(0)); 55 | sb.setLength(sb.length() - 1); 56 | plainSb.setCharAt(sb.length() - 2, candidate.charAt(0)); 57 | plainSb.setLength(sb.length() - 1); 58 | escaping--; 59 | } 60 | else if (candidate.equals(SLASH)) { 61 | sb.append(CONVERSION.get(candidate)); 62 | escaping++; 63 | } 64 | else { 65 | sb.append(candidate); 66 | } 67 | } 68 | else { 69 | sb.append( 70 | workingToken.length() > 0 ? workingToken.toString() 71 | : "").append(CONVERSION.get(candidate)); 72 | escaping++; 73 | if (candidate.equals("%") || candidate.equals("_")) { 74 | wildcard++; 75 | } 76 | 77 | } 78 | if (candidate.equals(SLASH)) { 79 | backslashCount++; 80 | } 81 | else { 82 | backslashCount = 0; 83 | } 84 | workingToken.setLength(0); 85 | 86 | } 87 | else { 88 | workingToken.append(candidate); 89 | backslashCount = 0; 90 | } 91 | } 92 | // end of while 93 | if (workingToken.length() > 0) { 94 | sb.append(workingToken.toString()); 95 | } 96 | sb.append("$"); 97 | 98 | return new RegexNodeValue( 99 | (escaping > 0) && (wildcard > 0) ? sb.toString() 100 | : plainSb.toString(), wildcard > 0); 101 | } 102 | 103 | } -------------------------------------------------------------------------------- /src/test/java/QueryTester.java: -------------------------------------------------------------------------------- 1 | import java.net.URL; 2 | import java.util.List; 3 | 4 | import org.xenei.jdbc4sparql.J4SConnectionTest; 5 | 6 | import com.hp.hpl.jena.query.Query; 7 | import com.hp.hpl.jena.query.QueryExecution; 8 | import com.hp.hpl.jena.query.QueryExecutionFactory; 9 | import com.hp.hpl.jena.query.QueryFactory; 10 | import com.hp.hpl.jena.query.QuerySolution; 11 | import com.hp.hpl.jena.rdf.model.Model; 12 | import com.hp.hpl.jena.rdf.model.ModelFactory; 13 | import com.hp.hpl.jena.util.iterator.WrappedIterator; 14 | 15 | public class QueryTester { 16 | 17 | public static void main(final String[] args) throws Exception { 18 | // String qry = 19 | // "PREFIX xsd: SELECT (sum(?x) as ?y) WHERE { [] ?x1 . bind( xsd:integer(?x1) as ?x) }"; 20 | final Model m = ModelFactory.createDefaultModel(); 21 | m.read(fUrl.openStream(), "http://example.com/", "TURTLE"); 22 | // Property d = m.createProperty( "http://example.com/double"); 23 | // Property i = m.createProperty( "http://example.com/int"); 24 | // m.add( m.createResource("http://example.com/A"), d, 25 | // m.createTypedLiteral(-1.3) ); 26 | // m.add( m.createResource("http://example.com/A"), i, 27 | // m.createTypedLiteral(-3) ); 28 | // m.add( m.createResource("http://example.com/B"), d, 29 | // m.createTypedLiteral(1.5) ); 30 | // m.add( m.createResource("http://example.com/B"), i, 31 | // m.createTypedLiteral(5) ); 32 | // m.add( m.createResource("http://example.com/C"), d, 33 | // m.createTypedLiteral(1.7) ); 34 | // m.add( m.createResource("http://example.com/C"), i, "7" ); 35 | final Query q = QueryFactory.create(qry); 36 | final QueryExecution qexec = QueryExecutionFactory.create(q, m); 37 | final List retval = WrappedIterator.create( 38 | qexec.execSelect()).toList(); 39 | for (final QuerySolution qs : retval) { 40 | System.out.println(qs); 41 | } 42 | } 43 | 44 | static URL fUrl = J4SConnectionTest.class 45 | .getResource("./J4SStatementTest.ttl"); 46 | 47 | static String qry = "SELECT * " 48 | + " WHERE" 49 | + " { { { { ?fooTable ." 50 | + " ?fooTable ?v_b3f2fd82_c102_3c4d_baed_5958c464a424 ." 51 | + " ?fooTable ?v_599dcce2_998a_3b40_b1e3_8e8c6006cb0a ." 52 | + " ?fooTable ?v_f20fd591_2dfa_3a09_b81b_7c6f31cc3159" 53 | + " }" 54 | + " OPTIONAL" 55 | + " { ?fooTable ?v_2ca911d9_9e97_3d80_aaae_d6347f341e4e}" 56 | + " OPTIONAL" 57 | + " { ?fooTable ?v_ce84b044_b71d_37a4_bc63_462bd432993c}" 58 | + " }" 59 | + " BIND((?v_b3f2fd82_c102_3c4d_baed_5958c464a424) AS ?IntCol)" 60 | + " BIND((?v_ce84b044_b71d_37a4_bc63_462bd432993c) AS ?NullableIntCol)" 61 | + " BIND((?v_599dcce2_998a_3b40_b1e3_8e8c6006cb0a) AS ?type)" 62 | + " BIND((?v_f20fd591_2dfa_3a09_b81b_7c6f31cc3159) AS ?StringCol)" 63 | + " BIND((?v_2ca911d9_9e97_3d80_aaae_d6347f341e4e) AS ?NullableStringCol)" 64 | + " }" + " }"; 65 | } 66 | -------------------------------------------------------------------------------- /src/test/java/org/xenei/jdbc4sparql/impl/rdf/CatalogBuilderTest.java: -------------------------------------------------------------------------------- 1 | package org.xenei.jdbc4sparql.impl.rdf; 2 | 3 | import java.util.Set; 4 | 5 | import org.junit.After; 6 | import org.junit.Assert; 7 | import org.junit.Before; 8 | import org.junit.Test; 9 | import org.xenei.jdbc4sparql.iface.Catalog; 10 | import org.xenei.jdbc4sparql.iface.Schema; 11 | import org.xenei.jdbc4sparql.meta.MetaCatalogBuilder; 12 | 13 | import com.hp.hpl.jena.rdf.model.Model; 14 | import com.hp.hpl.jena.rdf.model.ModelFactory; 15 | 16 | public class CatalogBuilderTest { 17 | 18 | private Model model; 19 | private RdfSchema.Builder schemaBldr; 20 | 21 | @Before 22 | public void setUp() throws Exception { 23 | model = ModelFactory.createDefaultModel(); 24 | 25 | schemaBldr = new RdfSchema.Builder().setName("testSchema"); 26 | } 27 | 28 | @After 29 | public void tearDown() throws Exception { 30 | model.close(); 31 | } 32 | 33 | @Test 34 | public void testAddSchema() { 35 | final RdfCatalog.Builder builder = new RdfCatalog.Builder() 36 | .setName("catalog"); 37 | 38 | final RdfCatalog catalog = builder.build(model); 39 | Assert.assertEquals("catalog", catalog.getName().getShortName()); 40 | Assert.assertNotNull(catalog.getSchemas()); 41 | Assert.assertEquals(0, catalog.getSchemas().size()); 42 | schemaBldr.setCatalog(catalog); 43 | 44 | schemaBldr.build(model); 45 | 46 | Assert.assertNotNull(catalog.getSchemas()); 47 | Assert.assertEquals(1, catalog.getSchemas().size()); 48 | } 49 | 50 | @Test 51 | public void testDefault() { 52 | final RdfCatalog.Builder builder = new RdfCatalog.Builder() 53 | .setName("catalog"); 54 | 55 | final Catalog catalog = builder.build(model); 56 | 57 | Assert.assertEquals("catalog", catalog.getName().getShortName()); 58 | Assert.assertNotNull(catalog.getSchemas()); 59 | Assert.assertEquals(0, catalog.getSchemas().size()); 60 | Assert.assertNull(catalog.getSchema(MetaCatalogBuilder.SCHEMA_NAME)); 61 | } 62 | 63 | @Test 64 | public void testFindSchema() { 65 | final RdfCatalog.Builder builder = new RdfCatalog.Builder() 66 | .setName("catalog"); 67 | 68 | final RdfCatalog catalog = builder.build(model); 69 | 70 | schemaBldr.setCatalog(catalog).build(model); 71 | 72 | Assert.assertNotNull(catalog.findSchemas("testSchema")); 73 | 74 | Assert.assertNotNull(catalog.findSchemas(null)); 75 | } 76 | 77 | @Test 78 | public void testGetSchema() throws Exception { 79 | final RdfCatalog.Builder builder = new RdfCatalog.Builder() 80 | .setName("catalog"); 81 | 82 | final RdfCatalog catalog = builder.build(model); 83 | 84 | schemaBldr.setCatalog(catalog).build(model); 85 | 86 | Assert.assertNotNull(catalog.getSchema("testSchema")); 87 | 88 | } 89 | 90 | @Test 91 | public void testGetSchemas() { 92 | final RdfCatalog.Builder builder = new RdfCatalog.Builder() 93 | .setName("catalog"); 94 | 95 | final RdfCatalog catalog = builder.build(model); 96 | 97 | Set schemas = catalog.getSchemas(); 98 | Assert.assertNotNull(schemas); 99 | Assert.assertEquals(0, schemas.size()); 100 | Assert.assertNull(catalog.getSchema(MetaCatalogBuilder.SCHEMA_NAME)); 101 | 102 | schemaBldr.setCatalog(catalog); 103 | 104 | schemaBldr.build(model); 105 | 106 | schemas = catalog.getSchemas(); 107 | Assert.assertNotNull(schemas); 108 | Assert.assertEquals(1, schemas.size()); 109 | 110 | } 111 | } 112 | -------------------------------------------------------------------------------- /src/main/java/org/xenei/jdbc4sparql/sparql/builders/SimpleNullableBuilder.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one 3 | * or more contributor license agreements. See the NOTICE file 4 | * distributed with this work for additional information 5 | * regarding copyright ownership. The ASF licenses this file 6 | * to you under the Apache License, Version 2.0 (the 7 | * "License"); you may not use this file except in compliance 8 | * with the License. You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | package org.xenei.jdbc4sparql.sparql.builders; 19 | 20 | import java.sql.DatabaseMetaData; 21 | import java.sql.Types; 22 | import java.util.LinkedHashMap; 23 | import java.util.List; 24 | import java.util.Map; 25 | 26 | import org.xenei.jdbc4sparql.impl.rdf.RdfCatalog; 27 | import org.xenei.jdbc4sparql.impl.rdf.RdfColumnDef; 28 | import org.xenei.jdbc4sparql.impl.rdf.RdfTableDef; 29 | 30 | import com.hp.hpl.jena.query.QuerySolution; 31 | import com.hp.hpl.jena.rdf.model.Model; 32 | import com.hp.hpl.jena.rdf.model.Resource; 33 | 34 | /** 35 | * A simple example builder that looks for the phrase "nullable" in column name 36 | * to determine if they are nullable or not. if Nullable is not found 37 | * columnNoNulls is set. if the name contains int the colum type will be set to 38 | * "integer" otherwise it is string. 39 | */ 40 | public class SimpleNullableBuilder extends SimpleBuilder { 41 | public static final String BUILDER_NAME = "Simple_nullable_Builder"; 42 | public static final String DESCRIPTION = "A simple schema builder extends Simple_Builder by addint nullable columns for columns that have 'nullable' in their names"; 43 | 44 | public SimpleNullableBuilder() { 45 | } 46 | 47 | @Override 48 | protected Map addColumnDefs(final RdfCatalog catalog, 49 | final RdfTableDef.Builder tableDefBuilder, final Resource tName, 50 | final String tableQuerySegment) { 51 | final Model model = catalog.getResource().getModel(); 52 | final Map colNames = new LinkedHashMap(); 53 | final List solns = catalog.executeQuery(String.format( 54 | SimpleBuilder.COLUMN_QUERY, tName)); 55 | 56 | for (final QuerySolution soln : solns) { 57 | final RdfColumnDef.Builder builder = new RdfColumnDef.Builder(); 58 | final Resource cName = soln.getResource("cName"); 59 | int type = Types.VARCHAR; 60 | if (cName.getLocalName().contains("Int")) { 61 | type = Types.INTEGER; 62 | } 63 | if (cName.getLocalName().contains("Double")) { 64 | type = Types.DOUBLE; 65 | } 66 | if (cName.getLocalName().toLowerCase().contains("nullable")) { 67 | builder.setNullable(DatabaseMetaData.columnNullable); 68 | } 69 | else { 70 | builder.setNullable(DatabaseMetaData.columnNoNulls); 71 | } 72 | final String columnQuerySegment = String.format( 73 | SimpleBuilder.COLUMN_SEGMENT, "%1$s", "%2$s", 74 | cName.getURI()); 75 | colNames.put(cName.getLocalName(), columnQuerySegment); 76 | final int scale = calculateSize(catalog, tableQuerySegment, 77 | columnQuerySegment); 78 | builder.setType(type).setScale(scale).setReadOnly(true); 79 | tableDefBuilder.addColumnDef(builder.build(model)); 80 | } 81 | return colNames; 82 | } 83 | 84 | } 85 | -------------------------------------------------------------------------------- /src/main/java/org/xenei/jdbc4sparql/iface/name/FQName.java: -------------------------------------------------------------------------------- 1 | package org.xenei.jdbc4sparql.iface.name; 2 | 3 | import java.util.UUID; 4 | 5 | import org.apache.commons.lang3.StringUtils; 6 | import org.apache.commons.lang3.builder.CompareToBuilder; 7 | 8 | /** 9 | * A class that represents the Fully qualified name of a JDBC object. 10 | * 11 | * No segment of the FQName may be null. 12 | * 13 | * This is the name that included the Catalog, Schema, Table, and Column name 14 | * segments. 15 | * 16 | */ 17 | public interface FQName extends GUIDObject { 18 | 19 | /** 20 | * A helper class for comparing FQNames. Provides implementations of 21 | * compare(), equals() and hashCode(). 22 | * 23 | */ 24 | public static class Comparator implements java.util.Comparator { 25 | @Override 26 | public int compare(final FQName fqName1, final FQName fqName2) { 27 | return new CompareToBuilder() 28 | .append(fqName1.getCatalog(), fqName2.getCatalog()) 29 | .append(fqName1.getSchema(), fqName2.getSchema()) 30 | .append(fqName1.getTable(), fqName2.getTable()) 31 | .append(fqName1.getColumn(), fqName2.getColumn()) 32 | .toComparison(); 33 | } 34 | 35 | /** 36 | * Determines if 2 FQNames are equal. A FQName is equal if all the name 37 | * segments are equal. 38 | * 39 | * @param fqName1 40 | * the first FQName 41 | * @param fqName2 42 | * the second FQName 43 | * @return true if equal, false if not 44 | */ 45 | public static boolean equals(final Object fqName1, final Object fqName2) { 46 | if ((fqName1 instanceof FQName) && (fqName2 instanceof FQName)) { 47 | return ((FQName) fqName1).getGUID().equals( 48 | ((FQName) fqName2).getGUID()); 49 | // FQName bn1 = (FQName) fqName1; 50 | // FQName bn2 = (FQName) fqName2; 51 | // return new EqualsBuilder() 52 | // .append(bn1.getCatalog(), bn2.getCatalog()) 53 | // .append(bn1.getSchema(), bn2.getSchema()) 54 | // .append(bn1.getTable(), bn2.getTable()) 55 | // .append(bn1.getColumn(), bn2.getColumn()).isEquals(); 56 | } 57 | return false; 58 | } 59 | 60 | /** 61 | * Generates a common hash code for the FQName based on all the name 62 | * segments. 63 | * 64 | * @param fqName 65 | * @return 66 | */ 67 | public static int hashCode(final FQName fqName) { 68 | return fqName.getGUID().hashCode(); 69 | // return new HashCodeBuilder().append(fqName.getCatalog()) 70 | // .append(fqName.getSchema()).append(fqName.getTable()) 71 | // .append(fqName.getColumn()).toHashCode(); 72 | 73 | } 74 | 75 | public static String makeGUID(final String catalog, 76 | final String schema, final String table, final String column) { 77 | final String t = StringUtils.defaultString(catalog) 78 | + StringUtils.defaultString(schema) 79 | + StringUtils.defaultString(table) 80 | + StringUtils.defaultString(column); 81 | return "v_" 82 | + (UUID.nameUUIDFromBytes(t.getBytes()).toString().replace( 83 | "-", "_")); 84 | } 85 | } 86 | 87 | /** 88 | * Get the catalog name segment. 89 | * 90 | * @return The catalog name string. 91 | */ 92 | public String getCatalog(); 93 | 94 | /** 95 | * Get the column name segment. 96 | * 97 | * @return the column name string 98 | */ 99 | public String getColumn(); 100 | 101 | /** 102 | * Get the schema name segment. 103 | * 104 | * @return schema name string. 105 | */ 106 | public String getSchema(); 107 | 108 | /** 109 | * Get the table name segment. 110 | * 111 | * @return the talbe name string. 112 | */ 113 | public String getTable(); 114 | 115 | } 116 | -------------------------------------------------------------------------------- /src/main/java/org/xenei/jdbc4sparql/iface/NameFilter.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one 3 | * or more contributor license agreements. See the NOTICE file 4 | * distributed with this work for additional information 5 | * regarding copyright ownership. The ASF licenses this file 6 | * to you under the Apache License, Version 2.0 (the 7 | * "License"); you may not use this file except in compliance 8 | * with the License. You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | package org.xenei.jdbc4sparql.iface; 19 | 20 | import java.util.Collection; 21 | import java.util.Iterator; 22 | import java.util.List; 23 | import java.util.Set; 24 | 25 | import org.xenei.jdbc4sparql.sparql.items.NamedObject; 26 | 27 | import com.hp.hpl.jena.util.iterator.WrappedIterator; 28 | 29 | /** 30 | * Filters a namespacedObject by name. 31 | * 32 | * @param 33 | * a NamespacedObject 34 | */ 35 | public class NameFilter> implements Iterator, 36 | Iterable { 37 | // the name pattern to match 38 | private String namePattern; 39 | // the iterator of the original collection. 40 | private Iterator iter; 41 | // our next object. 42 | private T next; 43 | 44 | /** 45 | * Construct a NameFilter from a pattern and a collection. 46 | * 47 | * If namePattern is null match all names. 48 | * 49 | * @param namePattern 50 | * The pattern to match or null. 51 | * @param objs 52 | * The collection of objects to filter. 53 | */ 54 | public NameFilter(final String namePattern, final Collection objs) { 55 | this(namePattern, objs.iterator()); 56 | } 57 | 58 | /** 59 | * Construct a NameFilter from a pattern and an iterator. 60 | * 61 | * If namePattern is null match all names. 62 | * 63 | * @param namePattern 64 | * The pattern to match or null. 65 | * @param iter 66 | * the iterator of objects to filter. 67 | */ 68 | public NameFilter(final String namePattern, final Iterator iter) { 69 | this.namePattern = namePattern; 70 | this.iter = iter; 71 | next = null; 72 | } 73 | 74 | @Override 75 | public boolean hasNext() { 76 | if (namePattern == null) { 77 | return iter.hasNext(); 78 | } 79 | 80 | while ((next == null) && iter.hasNext()) { 81 | next = iter.next(); 82 | if (!next.getName().getShortName().equals(namePattern)) { 83 | next = null; 84 | } 85 | } 86 | return next != null; 87 | } 88 | 89 | @Override 90 | public Iterator iterator() { 91 | return this; 92 | } 93 | 94 | @Override 95 | public T next() { 96 | if (namePattern == null) { 97 | return iter.next(); 98 | } 99 | else { 100 | final T retval = next; 101 | next = null; 102 | return retval; 103 | } 104 | } 105 | 106 | @Override 107 | public void remove() { 108 | throw new UnsupportedOperationException(); 109 | } 110 | 111 | /** 112 | * Return the data as a list. 113 | * 114 | * @return 115 | */ 116 | public List toList() { 117 | return WrappedIterator.create(this).toList(); 118 | } 119 | 120 | /** 121 | * Return the data as a list. 122 | * 123 | * @return 124 | */ 125 | public Set toSet() { 126 | return WrappedIterator.create(this).toSet(); 127 | } 128 | } 129 | -------------------------------------------------------------------------------- /src/test/java/org/xenei/jdbc4sparql/iface/name/CatalogNameTests.java: -------------------------------------------------------------------------------- 1 | package org.xenei.jdbc4sparql.iface.name; 2 | 3 | import static org.junit.Assert.assertEquals; 4 | import static org.junit.Assert.assertNull; 5 | import static org.junit.Assert.fail; 6 | 7 | import org.junit.Test; 8 | import org.xenei.jdbc4sparql.impl.NameUtils; 9 | 10 | public class CatalogNameTests { 11 | private CatalogName catalogName; 12 | 13 | public CatalogNameTests() { 14 | } 15 | 16 | @Test 17 | public void testCatalog() { 18 | catalogName = new CatalogName("catalog"); 19 | assertEquals("catalog", catalogName.getCatalog()); 20 | assertNull(catalogName.getSchema()); 21 | assertNull(catalogName.getColumn()); 22 | assertNull(catalogName.getTable()); 23 | assertEquals("catalog", catalogName.getDBName()); 24 | assertEquals("catalog", catalogName.getSPARQLName()); 25 | assertEquals("catalog", catalogName.getShortName()); 26 | } 27 | 28 | @Test 29 | public void testCatalogFromCatalog() { 30 | catalogName = new CatalogName(new CatalogName("catalog")); 31 | assertEquals("catalog", catalogName.getCatalog()); 32 | assertNull(catalogName.getSchema()); 33 | assertNull(catalogName.getColumn()); 34 | assertNull(catalogName.getTable()); 35 | assertEquals("catalog", catalogName.getDBName()); 36 | assertEquals("catalog", catalogName.getSPARQLName()); 37 | assertEquals("catalog", catalogName.getShortName()); 38 | } 39 | 40 | @Test 41 | public void testCatalogFromOtherItemName() { 42 | final ItemName itemName = new SearchName("catalog", "schema", "table", 43 | "column"); 44 | catalogName = new CatalogName(itemName); 45 | assertEquals("catalog", catalogName.getCatalog()); 46 | assertNull(catalogName.getSchema()); 47 | assertNull(catalogName.getColumn()); 48 | assertNull(catalogName.getTable()); 49 | assertEquals("catalog", catalogName.getDBName()); 50 | assertEquals("catalog", catalogName.getSPARQLName()); 51 | assertEquals("catalog", catalogName.getShortName()); 52 | 53 | } 54 | 55 | @Test 56 | public void testCatalogWithDBDot() { 57 | try { 58 | catalogName = new CatalogName("cata" + NameUtils.DB_DOT + "log"); 59 | fail("Should have thrown IllegalArgumentException"); 60 | } catch (final IllegalArgumentException expected) { 61 | assertEquals("Catalog name may not contain '.'", 62 | expected.getMessage()); 63 | } 64 | 65 | } 66 | 67 | @Test 68 | public void testCatalogWithSPARQLDot() { 69 | try { 70 | catalogName = new CatalogName("cata" + NameUtils.SPARQL_DOT + "log"); 71 | fail("Should have thrown IllegalArgumentException"); 72 | } catch (final IllegalArgumentException expected) { 73 | assertEquals("Catalog name may not contain '" 74 | + NameUtils.SPARQL_DOT + "'", expected.getMessage()); 75 | } 76 | } 77 | 78 | @Test 79 | public void testEmptyCatalog() { 80 | catalogName = new CatalogName(""); 81 | assertEquals("", catalogName.getCatalog()); 82 | assertNull(catalogName.getSchema()); 83 | assertNull(catalogName.getColumn()); 84 | assertNull(catalogName.getTable()); 85 | assertEquals("", catalogName.getDBName()); 86 | assertEquals("", catalogName.getSPARQLName()); 87 | assertEquals("", catalogName.getShortName()); 88 | } 89 | 90 | @Test 91 | public void testEmptyCatalogFromCatalog() { 92 | catalogName = new CatalogName(new CatalogName("")); 93 | assertEquals("", catalogName.getCatalog()); 94 | assertNull(catalogName.getSchema()); 95 | assertNull(catalogName.getColumn()); 96 | assertNull(catalogName.getTable()); 97 | assertEquals("", catalogName.getDBName()); 98 | assertEquals("", catalogName.getSPARQLName()); 99 | assertEquals("", catalogName.getShortName()); 100 | } 101 | 102 | } 103 | -------------------------------------------------------------------------------- /src/main/java/org/xenei/jdbc4sparql/sparql/parser/jsqlparser/SparqlVisitor.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of jdbc4sparql jsqlparser implementation. 3 | * 4 | * jdbc4sparql jsqlparser implementation is free software: you can redistribute 5 | * it and/or modify 6 | * it under the terms of the GNU Lesser General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * jdbc4sparql jsqlparser implementation is distributed in the hope that it will 11 | * be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public License 17 | * along with jdbc4sparql jsqlparser implementation. If not, see 18 | * . 19 | */ 20 | package org.xenei.jdbc4sparql.sparql.parser.jsqlparser; 21 | 22 | import java.util.Map; 23 | 24 | import net.sf.jsqlparser.statement.StatementVisitor; 25 | import net.sf.jsqlparser.statement.create.table.CreateTable; 26 | import net.sf.jsqlparser.statement.delete.Delete; 27 | import net.sf.jsqlparser.statement.drop.Drop; 28 | import net.sf.jsqlparser.statement.insert.Insert; 29 | import net.sf.jsqlparser.statement.replace.Replace; 30 | import net.sf.jsqlparser.statement.select.Select; 31 | import net.sf.jsqlparser.statement.truncate.Truncate; 32 | import net.sf.jsqlparser.statement.update.Update; 33 | 34 | import org.slf4j.Logger; 35 | import org.slf4j.LoggerFactory; 36 | import org.xenei.jdbc4sparql.iface.Catalog; 37 | import org.xenei.jdbc4sparql.iface.Schema; 38 | import org.xenei.jdbc4sparql.impl.rdf.RdfCatalog; 39 | import org.xenei.jdbc4sparql.sparql.SparqlQueryBuilder; 40 | import org.xenei.jdbc4sparql.sparql.parser.SparqlParser; 41 | 42 | public class SparqlVisitor implements StatementVisitor { 43 | private final SparqlQueryBuilder sparqlQueryBuilder; 44 | private static Logger LOG = LoggerFactory.getLogger(SparqlVisitor.class); 45 | 46 | public SparqlVisitor(final Map catalogs, 47 | final SparqlParser parser, final RdfCatalog catalog, 48 | final Schema schema) { 49 | sparqlQueryBuilder = new SparqlQueryBuilder(catalogs, parser, catalog, 50 | schema); 51 | } 52 | 53 | public SparqlQueryBuilder getBuilder() { 54 | return sparqlQueryBuilder; 55 | } 56 | 57 | @Override 58 | public void visit(final CreateTable createTable) { 59 | throw new UnsupportedOperationException("CREATE TABLE"); 60 | } 61 | 62 | @Override 63 | public void visit(final Delete delete) { 64 | throw new UnsupportedOperationException("DELETE"); 65 | } 66 | 67 | @Override 68 | public void visit(final Drop drop) { 69 | throw new UnsupportedOperationException("DROP"); 70 | } 71 | 72 | @Override 73 | public void visit(final Insert insert) { 74 | throw new UnsupportedOperationException("INSERT"); 75 | } 76 | 77 | @Override 78 | public void visit(final Replace replace) { 79 | throw new UnsupportedOperationException("REPLACE"); 80 | } 81 | 82 | @Override 83 | public void visit(final Select select) { 84 | if (LOG.isDebugEnabled()) { 85 | SparqlVisitor.LOG.debug("visit: {}", select); 86 | } 87 | final SparqlSelectVisitor v = new SparqlSelectVisitor( 88 | sparqlQueryBuilder); 89 | select.getSelectBody().accept(v); 90 | } 91 | 92 | @Override 93 | public void visit(final Truncate truncate) { 94 | throw new UnsupportedOperationException("TRUNCATE"); 95 | } 96 | 97 | @Override 98 | public void visit(final Update update) { 99 | throw new UnsupportedOperationException("UPDATE"); 100 | } 101 | } 102 | -------------------------------------------------------------------------------- /src/main/java/org/xenei/jdbc4sparql/sparql/items/QueryColumnInfo.java: -------------------------------------------------------------------------------- 1 | package org.xenei.jdbc4sparql.sparql.items; 2 | 3 | import org.xenei.jdbc4sparql.iface.Column; 4 | import org.xenei.jdbc4sparql.iface.name.ColumnName; 5 | import org.xenei.jdbc4sparql.iface.name.NameSegments; 6 | 7 | import com.hp.hpl.jena.sparql.core.Var; 8 | 9 | /** 10 | * A column in a table in the query. This class maps the column to an alias 11 | * name. This may be a column in a base table or a function. 12 | */ 13 | public class QueryColumnInfo extends QueryItemInfo { 14 | 15 | private QueryColumnInfo aliasFor; 16 | 17 | private static Column checkColumn(final Column column) { 18 | if (column == null) { 19 | throw new IllegalArgumentException("Column may not be null"); 20 | } 21 | return column; 22 | } 23 | 24 | public static NameSegments createSegments(final NameSegments segments) { 25 | return NameSegments.getInstance(segments.isCatalog(), 26 | segments.isSchema(), segments.isSchema() || segments.isTable(), 27 | true); 28 | } 29 | 30 | public QueryColumnInfo(final Column column) { 31 | this(column, column.isOptional()); 32 | } 33 | 34 | /** 35 | * Create a QueryColumnInfo not associated with a QueryInfoSet 36 | * 37 | * @param tableInfo 38 | * @param column 39 | * @param alias 40 | * @param optional 41 | */ 42 | public QueryColumnInfo(final Column column, final boolean optional) { 43 | super(column, checkColumn(column).getName(), optional); 44 | aliasFor = null; 45 | } 46 | 47 | public QueryColumnInfo(final Column column, final ColumnName alias) { 48 | this(column, alias, column.isOptional()); 49 | } 50 | 51 | public QueryColumnInfo(final Column column, final ColumnName alias, 52 | final boolean optional) { 53 | super(column, alias, optional); 54 | aliasFor = null; 55 | } 56 | 57 | public QueryColumnInfo createAlias(final ColumnName alias) { 58 | final QueryColumnInfo retval = new QueryColumnInfo(this.getColumn(), 59 | alias); 60 | retval.aliasFor = this; 61 | return retval; 62 | } 63 | 64 | /** 65 | * Returns true if this ItemInfo is an alias for another ItemInfo 66 | * 67 | * @return true if alias, false otherwise. 68 | */ 69 | public boolean isAlias() { 70 | return aliasFor != null; 71 | } 72 | 73 | // public QueryColumnInfo getAliasFor() { 74 | // return aliasFor; 75 | // } 76 | 77 | public QueryColumnInfo getBaseColumnInfo() { 78 | return aliasFor != null? aliasFor.getBaseColumnInfo() : this; 79 | } 80 | 81 | /** 82 | * Get the GUID variable based on the name of this column. 83 | * 84 | * If this column is an alias for another column returns the GUIDVar for 85 | * that column. 86 | * 87 | * @return The var for is column. 88 | */ 89 | @Override 90 | public Var getGUIDVar() { 91 | return aliasFor != null ? aliasFor.getGUIDVar() : super.getGUIDVar(); 92 | } 93 | 94 | @Override 95 | public boolean equals(final Object o) { 96 | if ((o != null) && (o instanceof QueryColumnInfo)) { 97 | final QueryColumnInfo colInfo = (QueryColumnInfo) o; 98 | return getName().equals(colInfo.getName()) 99 | && getColumn().equals(colInfo.getColumn()); 100 | } 101 | return false; 102 | } 103 | 104 | public Column getColumn() { 105 | return getBaseObject(); 106 | } 107 | 108 | @Override 109 | public int hashCode() { 110 | return getName().hashCode(); 111 | } 112 | 113 | @Override 114 | public void setOptional(final boolean optional) { 115 | super.setOptional(optional); 116 | } 117 | 118 | @Override 119 | public void setSegments(final NameSegments segments) { 120 | super.setSegments(createSegments(segments)); 121 | } 122 | 123 | @Override 124 | public String toString() { 125 | return String.format("QueryColumnInfo[%s(%s)]", getColumn() 126 | .getSQLName(), getName()); 127 | } 128 | 129 | } 130 | -------------------------------------------------------------------------------- /src/main/java/org/xenei/jdbc4sparql/iface/name/SchemaName.java: -------------------------------------------------------------------------------- 1 | package org.xenei.jdbc4sparql.iface.name; 2 | 3 | import org.apache.commons.lang.StringUtils; 4 | 5 | /** 6 | * Schema Name implementation. 7 | */ 8 | public class SchemaName extends ItemName { 9 | /** 10 | * Check the schema name. Checks that the itemName schema and catalog name 11 | * segments are not null. 12 | * 13 | * @param name 14 | * The ItemName to check. 15 | * @return the ItemName 16 | * @Throws IllegalArgumentException 17 | */ 18 | static ItemName checkItemName(final ItemName name) 19 | throws IllegalArgumentException { 20 | if (name == null) { 21 | throw new IllegalArgumentException("name may not be null"); 22 | } 23 | CatalogName.checkItemName(name); 24 | checkNotNull(name.getFQName().getSchema(), "schema"); 25 | return name; 26 | } 27 | 28 | /** 29 | * Ensure that the schema segment is on, and the table and column segments 30 | * are off. 31 | * 32 | * @param segments 33 | * The segments to adjust 34 | * @return the adjusted segments. 35 | * @Throws IllegalArgumentException if segments is null. 36 | */ 37 | private static NameSegments adjustSegments(final NameSegments segments) 38 | throws IllegalArgumentException { 39 | if (segments == null) { 40 | throw new IllegalArgumentException("Segments may not be null"); 41 | } 42 | if (segments.isSchema() && !segments.isTable() && !segments.isColumn()) { 43 | return segments; 44 | } 45 | return NameSegments.getInstance(segments.isCatalog(), true, false, 46 | false); 47 | } 48 | 49 | /** 50 | * Create a SchmeaName from an ItemName. 51 | * 52 | * @param name 53 | * the ItemName, must not be null. 54 | * @Throws IllegalArgumentException is name is null. 55 | */ 56 | public SchemaName(final ItemName name) throws IllegalArgumentException { 57 | this(checkItemName(name), name.getUsedSegments()); 58 | } 59 | 60 | /** 61 | * Create a SchmeaName from an ItemName with specific name segments. 62 | * 63 | * @param name 64 | * the ItemName, must not be null. 65 | * @param segments 66 | * the name segments to use. 67 | * @Throws IllegalArgumentException is name or segments are null. 68 | */ 69 | public SchemaName(final ItemName name, final NameSegments segments) 70 | throws IllegalArgumentException { 71 | super(checkItemName(name), adjustSegments(segments)); 72 | } 73 | 74 | /** 75 | * Create a SchemaNamefrom a catalog name string and a schema name string. 76 | * Uses the default namesegments for a schema. 77 | * 78 | * @param catalog 79 | * the catalog name string. 80 | * @param schema 81 | * the schema name string. 82 | * @throws IllegalArgumentException 83 | * if either string is null. 84 | */ 85 | public SchemaName(final String catalog, final String schema) 86 | throws IllegalArgumentException { 87 | super(new FQNameImpl(checkNotNull(catalog, "catalog"), checkNotNull( 88 | schema, "schema"), null, null), NameSegments.SCHEMA); 89 | } 90 | 91 | /** 92 | * Create a table name in this schema. 93 | * 94 | * @param tblName 95 | * the table name string. 96 | * @return the Table Name 97 | * @throws IllegalArgumentException 98 | * if either name is null. 99 | */ 100 | public TableName getTableName(final String tblName) 101 | throws IllegalArgumentException { 102 | final FQName baseName = getFQName(); 103 | return new TableName(baseName.getCatalog(), baseName.getSchema(), 104 | tblName); 105 | } 106 | 107 | @Override 108 | protected String createName(final String separator) { 109 | return StringUtils.defaultString(getSchema()); 110 | } 111 | 112 | /** 113 | * Returns the schema name. 114 | */ 115 | @Override 116 | public String getShortName() { 117 | return getSchema(); 118 | } 119 | 120 | @Override 121 | public SchemaName clone(final NameSegments segs) { 122 | return new SchemaName(this, segs); 123 | } 124 | } -------------------------------------------------------------------------------- /src/test/java/org/xenei/jdbc4sparql/J4SStatementOuterJoinTest.java: -------------------------------------------------------------------------------- 1 | package org.xenei.jdbc4sparql; 2 | 3 | import java.net.URL; 4 | import java.sql.Connection; 5 | import java.sql.DriverManager; 6 | import java.sql.ResultSet; 7 | import java.sql.SQLException; 8 | import java.sql.Statement; 9 | 10 | import org.apache.log4j.Level; 11 | import org.junit.After; 12 | import org.junit.Assert; 13 | import org.junit.Before; 14 | import org.junit.Ignore; 15 | import org.junit.Test; 16 | 17 | public class J4SStatementOuterJoinTest { 18 | // file URL 19 | private URL fUrl; 20 | 21 | // J4SUrl 22 | private String url; 23 | 24 | // JDBC Connection 25 | private Connection conn; 26 | 27 | private Statement stmt; 28 | 29 | @Before 30 | public void setup() throws Exception { 31 | LoggingConfig.setConsole(Level.DEBUG); 32 | LoggingConfig.setRootLogger(Level.INFO); 33 | LoggingConfig.setLogger("com.hp.hpl.jena.", Level.INFO); 34 | LoggingConfig.setLogger("org.xenei.jdbc4sparql", Level.DEBUG); 35 | 36 | Class.forName("org.xenei.jdbc4sparql.J4SDriver"); 37 | 38 | fUrl = J4SDriverTest.class 39 | .getResource("./J4SStatementOuterJoinTest.ttl"); // /org/xenei/jdbc4sparql/J4SDriverTest.ttl"); 40 | 41 | url = "jdbc:j4s?catalog=test&type=turtle&builder=org.xenei.jdbc4sparql.sparql.builders.SimpleNullableBuilder:" 42 | + fUrl.toString(); 43 | 44 | conn = DriverManager.getConnection(url, "myschema", "mypassw"); 45 | conn.setAutoCommit(false); 46 | stmt = conn.createStatement(); 47 | } 48 | 49 | @After 50 | public void tearDown() { 51 | try { 52 | stmt.close(); 53 | } catch (final SQLException ignore) { 54 | } 55 | try { 56 | conn.close(); 57 | } catch (final SQLException ignore) { 58 | } 59 | } 60 | 61 | @Test 62 | @Ignore("Full Outer Join not suported.") 63 | public void testFullOuterJoin() throws ClassNotFoundException, SQLException { 64 | final ResultSet rset = stmt 65 | .executeQuery("select fooTable.IntCol, barTable.IntCol from fooTable full outer join barTable on fooTable.IntCol=barTable.IntCol"); 66 | try { 67 | boolean foundNull = false; 68 | while (rset.next()) { 69 | rset.getString(2); 70 | foundNull |= rset.wasNull(); 71 | } 72 | Assert.assertTrue("did not find null", foundNull); 73 | } finally { 74 | rset.close(); 75 | } 76 | } 77 | 78 | @Test 79 | public void testLeftOuterJoin() throws ClassNotFoundException, SQLException { 80 | final ResultSet rset = stmt 81 | .executeQuery("select fooTable.IntCol, barTable.IntCol from fooTable left outer join barTable on fooTable.IntCol=barTable.IntCol"); 82 | try { 83 | boolean foundNull = false; 84 | while (rset.next()) { 85 | rset.getString(2); 86 | foundNull |= rset.wasNull(); 87 | } 88 | Assert.assertTrue("did not find null", foundNull); 89 | } finally { 90 | rset.close(); 91 | } 92 | } 93 | 94 | @Test 95 | public void testOuterJoin() throws ClassNotFoundException, SQLException { 96 | final ResultSet rset = stmt 97 | .executeQuery("select fooTable.IntCol, barTable.IntCol from fooTable outer join barTable on fooTable.IntCol=barTable.IntCol"); 98 | try { 99 | boolean foundNull = false; 100 | while (rset.next()) { 101 | rset.getString(2); 102 | foundNull |= rset.wasNull(); 103 | } 104 | Assert.assertTrue("did not find null", foundNull); 105 | } finally { 106 | rset.close(); 107 | } 108 | } 109 | 110 | @Test 111 | @Ignore("Right Outer Join not suported.") 112 | public void testRightOuterJoin() throws ClassNotFoundException, 113 | SQLException { 114 | final ResultSet rset = stmt 115 | .executeQuery("select fooTable.IntCol, barTable.IntCol from fooTable right outer join barTable on fooTable.IntCol=barTable.IntCol"); 116 | try { 117 | boolean foundNull = false; 118 | while (rset.next()) { 119 | rset.getString(2); 120 | foundNull |= rset.wasNull(); 121 | } 122 | Assert.assertTrue("did not find null", foundNull); 123 | } finally { 124 | rset.close(); 125 | } 126 | } 127 | 128 | } 129 | -------------------------------------------------------------------------------- /src/main/java/org/xenei/jdbc4sparql/impl/SortedBag.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one 3 | * or more contributor license agreements. See the NOTICE file 4 | * distributed with this work for additional information 5 | * regarding copyright ownership. The ASF licenses this file 6 | * to you under the Apache License, Version 2.0 (the 7 | * "License"); you may not use this file except in compliance 8 | * with the License. You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | package org.xenei.jdbc4sparql.impl; 19 | 20 | import java.util.ArrayList; 21 | import java.util.Collection; 22 | import java.util.Comparator; 23 | import java.util.Iterator; 24 | import java.util.List; 25 | import java.util.TreeMap; 26 | 27 | import com.hp.hpl.jena.util.iterator.ExtendedIterator; 28 | import com.hp.hpl.jena.util.iterator.NiceIterator; 29 | 30 | /** 31 | * A bag that is sorted by key. 32 | * 33 | * @param 34 | */ 35 | public class SortedBag implements Collection { 36 | private final TreeMap> map; 37 | 38 | public SortedBag(final Comparator comparator) { 39 | map = new TreeMap>(comparator); 40 | } 41 | 42 | @Override 43 | public boolean add(final T e) { 44 | final List lst = (map.containsKey(e)) ? map.get(e) 45 | : new ArrayList(); 46 | final boolean retval = lst.add(e); 47 | map.put(e, lst); 48 | return retval; 49 | } 50 | 51 | @Override 52 | public boolean addAll(final Collection c) { 53 | boolean retval = false; 54 | for (final T t : c) { 55 | retval |= add(t); 56 | } 57 | return retval; 58 | } 59 | 60 | @Override 61 | public void clear() { 62 | map.clear(); 63 | } 64 | 65 | @Override 66 | public boolean contains(final Object o) { 67 | return map.containsKey(o); 68 | } 69 | 70 | @Override 71 | public boolean containsAll(final Collection c) { 72 | for (final Object o : c) { 73 | if (!contains(o)) { 74 | return false; 75 | } 76 | } 77 | return true; 78 | } 79 | 80 | @Override 81 | public boolean isEmpty() { 82 | return map.isEmpty(); 83 | } 84 | 85 | @Override 86 | public Iterator iterator() { 87 | ExtendedIterator iter = NiceIterator.emptyIterator(); 88 | for (final List lst : map.values()) { 89 | iter = iter.andThen(lst.iterator()); 90 | } 91 | return iter; 92 | 93 | } 94 | 95 | @SuppressWarnings("unchecked") 96 | @Override 97 | public boolean remove(final Object o) { 98 | boolean retval = false; 99 | final List lst = map.get(o); 100 | if (lst != null) { 101 | retval = lst.contains(o); 102 | lst.remove(o); 103 | if (lst.size() == 0) { 104 | map.remove(o); 105 | } 106 | else { 107 | map.put((T) o, lst); 108 | } 109 | } 110 | return retval; 111 | } 112 | 113 | @Override 114 | public boolean removeAll(final Collection c) { 115 | boolean retval = false; 116 | for (final Object o : c) { 117 | retval |= remove(o); 118 | } 119 | return retval; 120 | } 121 | 122 | @Override 123 | public boolean retainAll(final Collection c) { 124 | throw new UnsupportedOperationException(); 125 | } 126 | 127 | @Override 128 | public int size() { 129 | int size = 0; 130 | for (final List l : map.values()) { 131 | size += l.size(); 132 | } 133 | return size; 134 | } 135 | 136 | @Override 137 | public Object[] toArray() { 138 | return ((ExtendedIterator) iterator()).toList().toArray(); 139 | } 140 | 141 | @SuppressWarnings("unchecked") 142 | @Override 143 | public T[] toArray(final T[] a) { 144 | return ((ExtendedIterator) iterator()).toList().toArray(a); 145 | } 146 | } 147 | -------------------------------------------------------------------------------- /src/main/java/org/xenei/jdbc4sparql/utils/ExpressionExtractor.java: -------------------------------------------------------------------------------- 1 | package org.xenei.jdbc4sparql.utils; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | import com.hp.hpl.jena.sparql.expr.Expr; 7 | import com.hp.hpl.jena.sparql.expr.ExprAggregator; 8 | import com.hp.hpl.jena.sparql.expr.ExprFunction0; 9 | import com.hp.hpl.jena.sparql.expr.ExprFunction1; 10 | import com.hp.hpl.jena.sparql.expr.ExprFunction2; 11 | import com.hp.hpl.jena.sparql.expr.ExprFunction3; 12 | import com.hp.hpl.jena.sparql.expr.ExprFunctionN; 13 | import com.hp.hpl.jena.sparql.expr.ExprFunctionOp; 14 | import com.hp.hpl.jena.sparql.expr.ExprVar; 15 | import com.hp.hpl.jena.sparql.expr.ExprVisitor; 16 | import com.hp.hpl.jena.sparql.expr.NodeValue; 17 | import com.hp.hpl.jena.sparql.expr.aggregate.Aggregator; 18 | 19 | /** 20 | * Class for test classes to extract element types from query. 21 | */ 22 | public class ExpressionExtractor implements ExprVisitor { 23 | private final List extracted = new ArrayList(); 24 | private Class matchType; 25 | 26 | /** 27 | * Set the type to match 28 | * 29 | * @param clazz 30 | * The class type to match 31 | * @return this ElementExtractor for chaining 32 | */ 33 | public ExpressionExtractor setMatchType(final Class clazz) { 34 | matchType = clazz; 35 | return this; 36 | } 37 | 38 | /** 39 | * Reset the results. 40 | * 41 | * @return this ElementExtractor for chaining 42 | */ 43 | public ExpressionExtractor reset() { 44 | extracted.clear(); 45 | return this; 46 | } 47 | 48 | public List getExtracted() { 49 | return extracted; 50 | } 51 | 52 | public ExpressionExtractor(final Class clazz) { 53 | setMatchType(clazz); 54 | } 55 | 56 | @Override 57 | public void startVisit() { 58 | } 59 | 60 | @Override 61 | public void visit(final ExprFunction0 func) { 62 | if (matchType.isAssignableFrom(func.getClass())) { 63 | extracted.add(func); 64 | } 65 | for (final Expr e : func.getArgs()) { 66 | e.visit(this); 67 | } 68 | } 69 | 70 | @Override 71 | public void visit(final ExprFunction1 func) { 72 | if (matchType.isAssignableFrom(func.getClass())) { 73 | extracted.add(func); 74 | } 75 | for (final Expr e : func.getArgs()) { 76 | e.visit(this); 77 | } 78 | } 79 | 80 | @Override 81 | public void visit(final ExprFunction2 func) { 82 | if (matchType.isAssignableFrom(func.getClass())) { 83 | extracted.add(func); 84 | } 85 | for (final Expr e : func.getArgs()) { 86 | e.visit(this); 87 | } 88 | 89 | } 90 | 91 | @Override 92 | public void visit(final ExprFunction3 func) { 93 | if (matchType.isAssignableFrom(func.getClass())) { 94 | extracted.add(func); 95 | } 96 | for (final Expr e : func.getArgs()) { 97 | e.visit(this); 98 | } 99 | } 100 | 101 | @Override 102 | public void visit(final ExprFunctionN func) { 103 | if (matchType.isAssignableFrom(func.getClass())) { 104 | extracted.add(func); 105 | } 106 | for (final Expr e : func.getArgs()) { 107 | e.visit(this); 108 | } 109 | } 110 | 111 | @Override 112 | public void visit(final ExprFunctionOp funcOp) { 113 | if (matchType.isAssignableFrom(funcOp.getClass())) { 114 | extracted.add(funcOp); 115 | } 116 | for (final Expr e : funcOp.getArgs()) { 117 | e.visit(this); 118 | } 119 | } 120 | 121 | @Override 122 | public void visit(final NodeValue nv) { 123 | if (matchType.isAssignableFrom(nv.getClass())) { 124 | extracted.add(nv); 125 | } 126 | } 127 | 128 | @Override 129 | public void visit(final ExprVar nv) { 130 | if (matchType.isAssignableFrom(nv.getClass())) { 131 | extracted.add(nv); 132 | } 133 | } 134 | 135 | @Override 136 | public void visit(final ExprAggregator eAgg) { 137 | if (matchType.isAssignableFrom(eAgg.getClass())) { 138 | extracted.add(eAgg); 139 | } 140 | eAgg.getAggVar().visit(this); 141 | final Aggregator agg = eAgg.getAggregator(); 142 | if (agg.getExpr() != null) { 143 | agg.getExpr().visit(this); 144 | } 145 | } 146 | 147 | @Override 148 | public void finishVisit() { 149 | } 150 | 151 | } 152 | -------------------------------------------------------------------------------- /src/test/java/org/xenei/jdbc4sparql/sparql/parser/SparqlParserUtilTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one 3 | * or more contributor license agreements. See the NOTICE file 4 | * distributed with this work for additional information 5 | * regarding copyright ownership. The ASF licenses this file 6 | * to you under the Apache License, Version 2.0 (the 7 | * "License"); you may not use this file except in compliance 8 | * with the License. You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | package org.xenei.jdbc4sparql.sparql.parser; 19 | 20 | import java.util.List; 21 | 22 | import org.junit.Assert; 23 | import org.junit.Test; 24 | 25 | import com.hp.hpl.jena.graph.Node; 26 | import com.hp.hpl.jena.graph.NodeFactory; 27 | import com.hp.hpl.jena.sparql.core.TriplePath; 28 | import com.hp.hpl.jena.sparql.core.Var; 29 | import com.hp.hpl.jena.sparql.path.P_Link; 30 | import com.hp.hpl.jena.sparql.path.Path; 31 | import com.hp.hpl.jena.sparql.syntax.Element; 32 | import com.hp.hpl.jena.sparql.syntax.ElementGroup; 33 | import com.hp.hpl.jena.sparql.syntax.ElementPathBlock; 34 | 35 | public class SparqlParserUtilTest { 36 | private final Var vIs = Var.alloc("is"); 37 | private final Var vWas = Var.alloc("was"); 38 | private final Node nWho = NodeFactory.createURI("who"); 39 | private final Node nWhat = NodeFactory.createURI("what"); 40 | private final Path pWho = new P_Link(nWho); 41 | private final Path pWhat = new P_Link(nWhat); 42 | private final Node nThis = NodeFactory.createLiteral("this"); 43 | private final Node nThat = NodeFactory.createLiteral("that"); 44 | 45 | @Test 46 | public void parseDisjointQuerySegmentTest() throws Exception { 47 | final Element parsed = SparqlParser.Util.parse("{ ?is 'this' ." 48 | + "?was 'that' }"); 49 | Assert.assertTrue(parsed instanceof ElementGroup); 50 | List lst = ((ElementGroup) parsed).getElements(); 51 | Assert.assertEquals(1, lst.size()); 52 | Assert.assertTrue(parsed instanceof ElementGroup); 53 | lst = ((ElementGroup) parsed).getElements(); 54 | final Element e = lst.get(0); 55 | Assert.assertTrue(e instanceof ElementPathBlock); 56 | final ElementPathBlock epb = (ElementPathBlock) e; 57 | final List l = epb.getPattern().getList(); 58 | Assert.assertEquals(2, l.size()); 59 | Assert.assertEquals(new TriplePath(vIs, pWho, nThis), l.get(0)); 60 | Assert.assertEquals(new TriplePath(vWas, pWhat, nThat), l.get(1)); 61 | } 62 | 63 | @Test 64 | public void parseLinkedQuerySegmentTest() throws Exception { 65 | final Element parsed = SparqlParser.Util.parse("{ ?is 'this' ;" 66 | + " 'that' }"); 67 | Assert.assertTrue(parsed instanceof ElementGroup); 68 | final List lst = ((ElementGroup) parsed).getElements(); 69 | final Element e = lst.get(0); 70 | Assert.assertTrue(e instanceof ElementPathBlock); 71 | final ElementPathBlock epb = (ElementPathBlock) e; 72 | final List l = epb.getPattern().getList(); 73 | Assert.assertEquals(2, l.size()); 74 | Assert.assertEquals(new TriplePath(vIs, pWho, nThis), l.get(0)); 75 | Assert.assertEquals(new TriplePath(vIs, pWhat, nThat), l.get(1)); 76 | } 77 | 78 | @Test 79 | public void parseSingleQuerySegmentTest() throws Exception { 80 | final Element parsed = SparqlParser.Util.parse("{ ?is 'that' }"); 81 | 82 | Assert.assertTrue(parsed instanceof ElementGroup); 83 | final List lst = ((ElementGroup) parsed).getElements(); 84 | Assert.assertEquals(1, lst.size()); 85 | final Element e = lst.get(0); 86 | Assert.assertTrue(e instanceof ElementPathBlock); 87 | final ElementPathBlock epb = (ElementPathBlock) e; 88 | final List l = epb.getPattern().getList(); 89 | Assert.assertEquals(1, l.size()); 90 | Assert.assertEquals(new TriplePath(vIs, pWho, nThat), l.get(0)); 91 | } 92 | 93 | } 94 | -------------------------------------------------------------------------------- /src/main/java/org/xenei/jdbc4sparql/iface/name/FQNameImpl.java: -------------------------------------------------------------------------------- 1 | package org.xenei.jdbc4sparql.iface.name; 2 | 3 | import java.util.Map; 4 | 5 | import org.xenei.jdbc4sparql.impl.NameUtils; 6 | 7 | /** 8 | * An implementation of FQName. 9 | * 10 | */ 11 | public class FQNameImpl implements FQName { 12 | /** 13 | * A method to verify that a segment is not null and does not contain the 14 | * JDBC or SPARQL "dot" characters. Used in constructors to verify values. 15 | * 16 | * @param segment 17 | * The name of the segment. 18 | * @param value 19 | * the value of the segment. 20 | * @return the value. 21 | * @throws IllegalArgumentException 22 | * if the value is null. 23 | */ 24 | protected static String verifyOK(final String segment, final String value) 25 | throws IllegalArgumentException { 26 | if (value != null) { 27 | for (final String badChar : NameUtils.DOT_LIST) { 28 | if (value.contains(badChar)) { 29 | throw new IllegalArgumentException(String.format( 30 | "%s name may not contain '%s'", segment, badChar)); 31 | } 32 | } 33 | } 34 | return value; 35 | } 36 | 37 | static final String FOUND_IN_MULTIPLE_ = "%s was found in multiple %s"; 38 | 39 | private final String catalog; 40 | 41 | private final String schema; 42 | 43 | private final String table; 44 | 45 | private final String col; 46 | 47 | private final String guid; 48 | 49 | private transient Integer _hashCode; 50 | 51 | /** 52 | * Constructor. No argument may be null. 53 | * 54 | * @param catalog 55 | * catalog name. 56 | * @param schema 57 | * schema name. 58 | * @param table 59 | * table name. 60 | * @param col 61 | * column name. 62 | * @throws IllegalArgumentException 63 | * if any segment is null. 64 | */ 65 | protected FQNameImpl(final String catalog, final String schema, 66 | final String table, final String col) 67 | throws IllegalArgumentException { 68 | this.catalog = verifyOK("Catalog", catalog); 69 | this.schema = verifyOK("Schema", schema); 70 | this.table = verifyOK("Table", table); 71 | this.col = verifyOK("Column", col); 72 | guid = FQName.Comparator.makeGUID(catalog, schema, table, col); 73 | } 74 | 75 | /** 76 | * Find the object matching the key in the map. Uses matches() method to 77 | * determine match. 78 | * 79 | * @param map 80 | * The map to find the object in. 81 | * @return The Object (T) or null if not found 82 | * @throws IllegalArgumentException 83 | * if more than one object matches. 84 | */ 85 | public T findGUID(final Map map) { 86 | 87 | for (final GUIDObject name : map.keySet()) { 88 | if (name.getGUID().equals(this.getGUID())) { 89 | return map.get(name); 90 | } 91 | } 92 | return null; 93 | } 94 | 95 | @Override 96 | public String getCatalog() { 97 | return catalog; 98 | } 99 | 100 | /** 101 | * Get the column name string 102 | * 103 | * @return 104 | */ 105 | @Override 106 | public String getColumn() { 107 | return col; 108 | } 109 | 110 | /** 111 | * Get the schema segment of the name. 112 | * 113 | * @return 114 | */ 115 | @Override 116 | public String getSchema() { 117 | return schema; 118 | } 119 | 120 | /** 121 | * Get the name as a UUID based on the real name. 122 | * 123 | * @return the UUID based name 124 | */ 125 | @Override 126 | public String getGUID() { 127 | return guid; 128 | } 129 | 130 | /** 131 | * Get the table portion of the complete name. 132 | * 133 | * @return 134 | */ 135 | @Override 136 | public String getTable() { 137 | return table; 138 | } 139 | 140 | @Override 141 | public int hashCode() { 142 | if (_hashCode == null) { 143 | _hashCode = FQName.Comparator.hashCode(this); 144 | } 145 | return _hashCode; 146 | } 147 | 148 | @Override 149 | public boolean equals(final Object o) { 150 | return FQName.Comparator.equals(this, o); 151 | } 152 | 153 | @Override 154 | public String toString() { 155 | return String.format("%s.%s.%s.%s", catalog, schema, table, col); 156 | } 157 | 158 | } -------------------------------------------------------------------------------- /src/main/java/org/xenei/jdbc4sparql/iface/Table.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one 3 | * or more contributor license agreements. See the NOTICE file 4 | * distributed with this work for additional information 5 | * regarding copyright ownership. The ASF licenses this file 6 | * to you under the Apache License, Version 2.0 (the 7 | * "License"); you may not use this file except in compliance 8 | * with the License. You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | package org.xenei.jdbc4sparql.iface; 19 | 20 | import java.util.Iterator; 21 | import java.util.List; 22 | 23 | import org.xenei.jdbc4sparql.iface.name.TableName; 24 | import org.xenei.jdbc4sparql.sparql.items.NamedObject; 25 | 26 | public interface Table extends NamedObject { 27 | 28 | /** 29 | * delete the table. Removes the table from the schema. 30 | */ 31 | void delete(); 32 | 33 | /** 34 | * Find all columns with the columnNamePattern. 35 | * 36 | * If columnNamePattern is null all columns are matched. 37 | * 38 | * @param columnNamePattern 39 | * The pattern to match or null. 40 | * @return 41 | */ 42 | NameFilter findColumns(String columnNamePattern); 43 | 44 | /** 45 | * 46 | * @return Get the catalog this table is in. 47 | */ 48 | Catalog getCatalog(); 49 | 50 | /** 51 | * Get the column by index. 52 | * 53 | * @param idx 54 | * The index of the column to retrieve. 55 | * @return the column. 56 | * @thows IndexOutOfBoundsException 57 | */ 58 | Column getColumn(int idx); 59 | 60 | /** 61 | * Get the column by name 62 | * 63 | * @param name 64 | * the name of the column to retrieve 65 | * @return the column or null if name not found. 66 | */ 67 | Column getColumn(String name); 68 | 69 | int getColumnCount(); 70 | 71 | public int getColumnIndex(Column column); 72 | 73 | /** 74 | * Get the index (zero based) for the column name. 75 | * 76 | * @param columnName 77 | * The column name to search for 78 | * @return index for column name or -1 if not found. 79 | */ 80 | public int getColumnIndex(String columnName); 81 | 82 | List getColumnList(); 83 | 84 | /** 85 | * Get an iterator over all the columns in order. 86 | * 87 | * @return The column iterator. 88 | */ 89 | Iterator getColumns(); 90 | 91 | /** 92 | * A string used to format the column name with respect to the table so that 93 | * the SPARQL query will retrieve the proper data. For example 94 | * "%1$s %2$s" 95 | * 96 | * %1$s is the table name %2$s is the column name 97 | * 98 | * @return Format string for query segments in SPARQL query 99 | */ 100 | public String getQuerySegmentFmt(); 101 | 102 | String getRemarks(); 103 | 104 | /** 105 | * @return The schema the table belongs in. 106 | */ 107 | Schema getSchema(); 108 | 109 | /** 110 | * 111 | * @return the SPARQL formatted table name. 112 | */ 113 | String getSPARQLName(); 114 | 115 | /** 116 | * @return the SQL formatted table name 117 | */ 118 | String getSQLName(); 119 | 120 | /** 121 | * Get the supertable for this table. 122 | * 123 | * @return The super table or null. 124 | */ 125 | Table getSuperTable(); 126 | 127 | public TableDef getTableDef(); 128 | 129 | /** 130 | * Get the type of table. Typical types are "TABLE", "VIEW", "SYSTEM TABLE", 131 | * "GLOBAL TEMPORARY", "LOCAL TEMPORARY", "ALIAS", "SYNONYM". 132 | * 133 | * @return The table type 134 | */ 135 | String getType(); 136 | 137 | /** 138 | * Return true if this column has querySegments. Most columns do, however, 139 | * some function columns do not. 140 | * 141 | * @return 142 | */ 143 | public boolean hasQuerySegments(); 144 | 145 | } 146 | -------------------------------------------------------------------------------- /src/main/java/org/xenei/jdbc4sparql/impl/rdf/AbstractChangeListener.java: -------------------------------------------------------------------------------- 1 | package org.xenei.jdbc4sparql.impl.rdf; 2 | 3 | import java.util.List; 4 | 5 | import org.xenei.jena.entities.EntityManager; 6 | import org.xenei.jena.entities.EntityManagerFactory; 7 | import org.xenei.jena.entities.MissingAnnotation; 8 | 9 | import com.hp.hpl.jena.rdf.model.Model; 10 | import com.hp.hpl.jena.rdf.model.ModelChangedListener; 11 | import com.hp.hpl.jena.rdf.model.Property; 12 | import com.hp.hpl.jena.rdf.model.RDFNode; 13 | import com.hp.hpl.jena.rdf.model.Resource; 14 | import com.hp.hpl.jena.rdf.model.Statement; 15 | import com.hp.hpl.jena.rdf.model.StmtIterator; 16 | import com.hp.hpl.jena.vocabulary.RDF; 17 | 18 | public abstract class AbstractChangeListener implements 19 | ModelChangedListener { 20 | 21 | private final ResourceBuilder rb; 22 | private final Resource s; 23 | private final Property p; 24 | private final EntityManager entityManager = EntityManagerFactory 25 | .getEntityManager(); 26 | private final Class oClass; 27 | 28 | protected AbstractChangeListener(final Resource resource, 29 | final Class resourceClass, final String propertyName, 30 | final Class class1) { 31 | rb = new ResourceBuilder(resource.getModel()); 32 | s = resource; 33 | p = rb.getProperty(resourceClass, propertyName); 34 | this.oClass = class1; 35 | } 36 | 37 | @Override 38 | public void addedStatement(final Statement stmt) { 39 | if (isListening()) { 40 | final T t = readObject(stmt); 41 | if (t != null) { 42 | addObject(t); 43 | } 44 | } 45 | } 46 | 47 | @Override 48 | public void addedStatements(final List statements) { 49 | if (isListening()) { 50 | for (final Statement s : statements) { 51 | addedStatement(s); 52 | } 53 | } 54 | } 55 | 56 | @Override 57 | public void addedStatements(final Model m) { 58 | if (isListening()) { 59 | 60 | addedStatements(m.listStatements(s, p, (RDFNode) null)); 61 | } 62 | } 63 | 64 | @Override 65 | public void addedStatements(final Statement[] statements) { 66 | if (isListening()) { 67 | for (final Statement s : statements) { 68 | addedStatement(s); 69 | } 70 | } 71 | } 72 | 73 | @Override 74 | public void addedStatements(final StmtIterator statements) { 75 | if (isListening()) { 76 | while (statements.hasNext()) { 77 | addedStatement(statements.next()); 78 | } 79 | } 80 | } 81 | 82 | protected abstract void addObject(T t); 83 | 84 | protected abstract void clearObjects(); 85 | 86 | protected abstract boolean isListening(); 87 | 88 | @Override 89 | public void notifyEvent(final Model m, final Object event) { 90 | // do nothing 91 | } 92 | 93 | private T readObject(final Statement stmt) { 94 | T t = null; 95 | if (stmt.getSubject().equals(s) && stmt.getPredicate().equals(p)) { 96 | try { 97 | t = entityManager.read(stmt.getObject(), oClass); 98 | } catch (final MissingAnnotation e) { 99 | throw new RuntimeException(e); 100 | } 101 | } 102 | return t; 103 | } 104 | 105 | @Override 106 | public void removedStatement(final Statement stmt) { 107 | if (isListening()) { 108 | final T t = readObject(stmt); 109 | if (t != null) { 110 | removeObject(t); 111 | } 112 | } 113 | 114 | if (stmt.getSubject().equals(s) && stmt.getPredicate().equals(RDF.type)) { 115 | // deleting this 116 | s.getModel().unregister(this); 117 | clearObjects(); 118 | } 119 | } 120 | 121 | @Override 122 | public void removedStatements(final List statements) { 123 | if (isListening()) { 124 | for (final Statement s : statements) { 125 | removedStatement(s); 126 | } 127 | } 128 | } 129 | 130 | @Override 131 | public void removedStatements(final Model m) { 132 | if (isListening()) { 133 | removedStatements(m.listStatements(s, p, (RDFNode) null)); 134 | } 135 | } 136 | 137 | @Override 138 | public void removedStatements(final Statement[] statements) { 139 | if (isListening()) { 140 | for (final Statement s : statements) { 141 | removedStatement(s); 142 | } 143 | } 144 | } 145 | 146 | @Override 147 | public void removedStatements(final StmtIterator statements) { 148 | if (isListening()) { 149 | while (statements.hasNext()) { 150 | removedStatement(statements.next()); 151 | } 152 | } 153 | } 154 | 155 | protected abstract void removeObject(T t); 156 | 157 | } 158 | -------------------------------------------------------------------------------- /src/main/java/org/xenei/jdbc4sparql/sparql/parser/jsqlparser/SparqlParserImpl.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of jdbc4sparql jsqlparser implementation. 3 | * 4 | * jdbc4sparql jsqlparser implementation is free software: you can redistribute 5 | * it and/or modify 6 | * it under the terms of the GNU Lesser General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * jdbc4sparql jsqlparser implementation is distributed in the hope that it will 11 | * be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public License 17 | * along with jdbc4sparql jsqlparser implementation. If not, see 18 | * . 19 | */ 20 | package org.xenei.jdbc4sparql.sparql.parser.jsqlparser; 21 | 22 | import java.io.StringReader; 23 | import java.sql.SQLException; 24 | import java.util.Arrays; 25 | import java.util.List; 26 | import java.util.Map; 27 | 28 | import net.sf.jsqlparser.JSQLParserException; 29 | import net.sf.jsqlparser.parser.CCJSqlParserManager; 30 | import net.sf.jsqlparser.statement.Statement; 31 | import net.sf.jsqlparser.util.deparser.StatementDeParser; 32 | 33 | import org.slf4j.Logger; 34 | import org.slf4j.LoggerFactory; 35 | import org.xenei.jdbc4sparql.iface.Catalog; 36 | import org.xenei.jdbc4sparql.iface.Schema; 37 | import org.xenei.jdbc4sparql.impl.rdf.RdfCatalog; 38 | import org.xenei.jdbc4sparql.sparql.SparqlQueryBuilder; 39 | import org.xenei.jdbc4sparql.sparql.parser.SparqlParser; 40 | import org.xenei.jdbc4sparql.sparql.parser.jsqlparser.functions.NumericFunctionHandler; 41 | import org.xenei.jdbc4sparql.sparql.parser.jsqlparser.functions.StringFunctionHandler; 42 | import org.xenei.jdbc4sparql.sparql.parser.jsqlparser.functions.SystemFunctionHandler; 43 | 44 | public class SparqlParserImpl implements SparqlParser { 45 | public static final String PARSER_NAME = "JSqlParser"; 46 | public static final String DESCRIPTION = "Parser based on JSqlParser (http://jsqlparser.sourceforge.net/). Under LGPL V2 license"; 47 | private final CCJSqlParserManager parserManager = new CCJSqlParserManager(); 48 | private static Logger LOG = LoggerFactory.getLogger(SparqlParserImpl.class); 49 | 50 | public SparqlParserImpl() { 51 | } 52 | 53 | @Override 54 | public List getSupportedNumericFunctions() { 55 | return Arrays.asList(NumericFunctionHandler.NUMERIC_FUNCTIONS); 56 | } 57 | 58 | @Override 59 | public List getSupportedStringFunctions() { 60 | return Arrays.asList(StringFunctionHandler.STRING_FUNCTIONS); 61 | } 62 | 63 | @Override 64 | public List getSupportedSystemFunctions() { 65 | return Arrays.asList(SystemFunctionHandler.SYSTEM_FUNCTIONS); 66 | } 67 | 68 | @Override 69 | public String nativeSQL(final String sqlQuery) throws SQLException { 70 | if (LOG.isDebugEnabled()) { 71 | SparqlParserImpl.LOG.debug("nativeSQL: {}", sqlQuery); 72 | } 73 | try { 74 | final Statement stmt = parserManager.parse(new StringReader( 75 | sqlQuery)); 76 | final StringBuffer sb = new StringBuffer(); 77 | final StatementDeParser dp = new StatementDeParser(sb); 78 | stmt.accept(dp); 79 | return sb.toString(); 80 | } catch (final JSQLParserException e) { 81 | throw new SQLException(e); 82 | } 83 | } 84 | 85 | @Override 86 | public SparqlQueryBuilder parse(final Map catalogs, 87 | final Catalog catalog, final Schema schema, final String sqlQuery) 88 | throws SQLException { 89 | if (LOG.isDebugEnabled()) { 90 | SparqlParserImpl.LOG.debug("catalog: '{}' parsing SQL: {}", 91 | catalog.getName(), sqlQuery); 92 | } 93 | try { 94 | final Statement stmt = parserManager.parse(new StringReader( 95 | sqlQuery)); 96 | final SparqlVisitor sv = new SparqlVisitor(catalogs, this, 97 | (RdfCatalog) catalog, schema); 98 | stmt.accept(sv); 99 | if (SparqlParserImpl.LOG.isDebugEnabled()) { 100 | SparqlParserImpl.LOG.debug("Parsed as {}", sv.getBuilder()); 101 | } 102 | return sv.getBuilder(); 103 | } catch (final JSQLParserException e) { 104 | SparqlParserImpl.LOG.error("Error parsing: " + e.getMessage(), e); 105 | throw new SQLException(e); 106 | } 107 | } 108 | } 109 | -------------------------------------------------------------------------------- /src/main/java/org/xenei/jdbc4sparql/config/MemDatasetProducer.java: -------------------------------------------------------------------------------- 1 | package org.xenei.jdbc4sparql.config; 2 | 3 | import java.io.IOException; 4 | import java.util.Iterator; 5 | import java.util.Properties; 6 | import java.util.zip.ZipInputStream; 7 | 8 | import org.xenei.jdbc4sparql.impl.AbstractDatasetProducer; 9 | 10 | import com.hp.hpl.jena.graph.compose.MultiUnion; 11 | import com.hp.hpl.jena.query.Dataset; 12 | import com.hp.hpl.jena.query.DatasetFactory; 13 | import com.hp.hpl.jena.query.LabelExistsException; 14 | import com.hp.hpl.jena.query.ReadWrite; 15 | import com.hp.hpl.jena.rdf.model.Model; 16 | import com.hp.hpl.jena.rdf.model.ModelFactory; 17 | import com.hp.hpl.jena.shared.Lock; 18 | import com.hp.hpl.jena.sparql.core.DatasetGraph; 19 | import com.hp.hpl.jena.sparql.util.Context; 20 | 21 | public class MemDatasetProducer extends AbstractDatasetProducer { 22 | private static class MetaDS implements Dataset { 23 | Dataset ds; 24 | MultiUnion g; 25 | Model m; 26 | 27 | public MetaDS(final Dataset ds) { 28 | this.ds = ds; 29 | rescan(); 30 | } 31 | 32 | @Override 33 | public void abort() { 34 | ds.abort(); 35 | } 36 | 37 | @Override 38 | public void addNamedModel(final String uri, final Model model) 39 | throws LabelExistsException { 40 | ds.addNamedModel(uri, model); 41 | g.addGraph(ds.getNamedModel(uri).getGraph()); 42 | } 43 | 44 | @Override 45 | public DatasetGraph asDatasetGraph() { 46 | return ds.asDatasetGraph(); 47 | } 48 | 49 | @Override 50 | public void begin(final ReadWrite readWrite) { 51 | ds.begin(readWrite); 52 | } 53 | 54 | @Override 55 | public void close() { 56 | ds.close(); 57 | } 58 | 59 | @Override 60 | public void commit() { 61 | ds.commit(); 62 | } 63 | 64 | @Override 65 | public boolean containsNamedModel(final String uri) { 66 | return "urn:x-arq:UnionGraph".equals(uri) ? true : ds 67 | .containsNamedModel(uri); 68 | } 69 | 70 | @Override 71 | public void end() { 72 | ds.end(); 73 | } 74 | 75 | @Override 76 | public Context getContext() { 77 | return ds.getContext(); 78 | } 79 | 80 | @Override 81 | public Model getDefaultModel() { 82 | return ds.getDefaultModel(); 83 | } 84 | 85 | @Override 86 | public Lock getLock() { 87 | return ds.getLock(); 88 | } 89 | 90 | @Override 91 | public Model getNamedModel(final String uri) { 92 | if ("urn:x-arq:UnionGraph".equals(uri)) { 93 | return m; 94 | } 95 | final boolean hasModel = ds.containsNamedModel(uri); 96 | 97 | final Model model = ds.getNamedModel(uri); 98 | if (!hasModel) { 99 | g.addGraph(model.getGraph()); 100 | } 101 | return model; 102 | } 103 | 104 | @Override 105 | public boolean isInTransaction() { 106 | return ds.isInTransaction(); 107 | } 108 | 109 | @Override 110 | public Iterator listNames() { 111 | return ds.listNames(); 112 | } 113 | 114 | @Override 115 | public void removeNamedModel(final String uri) { 116 | g.removeGraph(ds.getNamedModel(uri).getGraph()); 117 | ds.removeNamedModel(uri); 118 | } 119 | 120 | @Override 121 | public void replaceNamedModel(final String uri, final Model model) { 122 | g.removeGraph(ds.getNamedModel(uri).getGraph()); 123 | ds.replaceNamedModel(uri, model); 124 | g.addGraph(ds.getNamedModel(uri).getGraph()); 125 | } 126 | 127 | public void rescan() { 128 | g = new MultiUnion(); 129 | final Iterator iter = ds.listNames(); 130 | while (iter.hasNext()) { 131 | g.addGraph(ds.getNamedModel(iter.next()).getGraph()); 132 | } 133 | m = ModelFactory.createModelForGraph(g); 134 | } 135 | 136 | @Override 137 | public void setDefaultModel(final Model model) { 138 | ds.setDefaultModel(model); 139 | } 140 | 141 | @Override 142 | public boolean supportsTransactions() { 143 | return ds.supportsTransactions(); 144 | } 145 | 146 | } 147 | 148 | public MemDatasetProducer() { 149 | this(new Properties()); 150 | } 151 | 152 | public MemDatasetProducer(final Properties props) { 153 | super(props, new MetaDS(DatasetFactory.createMem()), DatasetFactory 154 | .createMem()); 155 | } 156 | 157 | public MemDatasetProducer(final Properties props, final ZipInputStream zis) 158 | throws IOException { 159 | super(props, new MetaDS(DatasetFactory.createMem()), DatasetFactory 160 | .createMem()); 161 | load(zis); 162 | ((MetaDS) getMetaDataset()).rescan(); 163 | } 164 | } -------------------------------------------------------------------------------- /src/main/java/org/xenei/jdbc4sparql/impl/IteratorResultSet.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one 3 | * or more contributor license agreements. See the NOTICE file 4 | * distributed with this work for additional information 5 | * regarding copyright ownership. The ASF licenses this file 6 | * to you under the Apache License, Version 2.0 (the 7 | * "License"); you may not use this file except in compliance 8 | * with the License. You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | package org.xenei.jdbc4sparql.impl; 19 | 20 | import java.sql.ResultSet; 21 | import java.sql.SQLException; 22 | import java.sql.SQLFeatureNotSupportedException; 23 | import java.util.Iterator; 24 | 25 | import org.xenei.jdbc4sparql.iface.Table; 26 | 27 | public abstract class IteratorResultSet extends AbstractResultSet { 28 | Iterator rows; 29 | Object row = null; 30 | int position = 0; 31 | 32 | @SuppressWarnings("unchecked") 33 | public IteratorResultSet(final Iterator rows, final Table table) 34 | throws SQLException { 35 | super(table); 36 | this.rows = (Iterator) rows; 37 | } 38 | 39 | @Override 40 | public boolean absolute(final int arg0) throws SQLException { 41 | throw new SQLFeatureNotSupportedException(); 42 | } 43 | 44 | @Override 45 | public void afterLast() throws SQLException { 46 | throw new SQLFeatureNotSupportedException(); 47 | } 48 | 49 | @Override 50 | public void beforeFirst() throws SQLException { 51 | throw new SQLFeatureNotSupportedException(); 52 | } 53 | 54 | @Override 55 | public void cancelRowUpdates() throws SQLException { 56 | throw new SQLFeatureNotSupportedException(); 57 | } 58 | 59 | @Override 60 | public void clearWarnings() throws SQLException { 61 | // TODO Auto-generated method stub 62 | 63 | } 64 | 65 | @Override 66 | public void close() throws SQLException { 67 | rows = null; 68 | } 69 | 70 | @Override 71 | public void deleteRow() throws SQLException { 72 | throw new SQLFeatureNotSupportedException(); 73 | } 74 | 75 | @Override 76 | public boolean first() throws SQLException { 77 | throw new SQLFeatureNotSupportedException(); 78 | } 79 | 80 | @Override 81 | public int getRow() throws SQLException { 82 | return position; 83 | } 84 | 85 | protected Object getRowObject() throws SQLException { 86 | if (row == null) { 87 | throw new SQLException("Cursor not positioned on a result"); 88 | } 89 | return row; 90 | } 91 | 92 | @Override 93 | public int getType() throws SQLException { 94 | return ResultSet.TYPE_FORWARD_ONLY; 95 | } 96 | 97 | @Override 98 | public boolean isAfterLast() throws SQLException { 99 | throw new SQLFeatureNotSupportedException(); 100 | } 101 | 102 | @Override 103 | public boolean isBeforeFirst() throws SQLException { 104 | throw new SQLFeatureNotSupportedException(); 105 | } 106 | 107 | @Override 108 | public boolean isClosed() throws SQLException { 109 | return rows == null; 110 | } 111 | 112 | @Override 113 | public boolean isFirst() throws SQLException { 114 | throw new SQLFeatureNotSupportedException(); 115 | } 116 | 117 | @Override 118 | public boolean isLast() throws SQLException { 119 | throw new SQLFeatureNotSupportedException(); 120 | } 121 | 122 | @Override 123 | public boolean last() throws SQLException { 124 | throw new SQLFeatureNotSupportedException(); 125 | } 126 | 127 | @Override 128 | public void moveToCurrentRow() throws SQLException { 129 | throw new SQLFeatureNotSupportedException(); 130 | } 131 | 132 | @Override 133 | public boolean next() throws SQLException { 134 | if (rows.hasNext()) { 135 | position++; 136 | row = rows.next(); 137 | return true; 138 | } 139 | row = null; 140 | return false; 141 | } 142 | 143 | @Override 144 | public boolean previous() throws SQLException { 145 | throw new SQLFeatureNotSupportedException(); 146 | } 147 | 148 | @Override 149 | public boolean relative(final int arg0) throws SQLException { 150 | throw new SQLFeatureNotSupportedException(); 151 | } 152 | } 153 | -------------------------------------------------------------------------------- /src/test/java/SQLDisplay.java: -------------------------------------------------------------------------------- 1 | import java.sql.Connection; 2 | import java.sql.DatabaseMetaData; 3 | import java.sql.DriverManager; 4 | import java.sql.ResultSet; 5 | import java.sql.ResultSetMetaData; 6 | import java.sql.SQLException; 7 | 8 | import net.sf.jsqlparser.JSQLParserException; 9 | 10 | public class SQLDisplay { 11 | 12 | public static void listFunctions() throws ClassNotFoundException, 13 | SQLException { 14 | 15 | Class.forName(SQLDisplay.DRIVER); 16 | final Connection connection = DriverManager.getConnection( 17 | SQLDisplay.URL, SQLDisplay.USERNAME, SQLDisplay.PASSWORD); 18 | final DatabaseMetaData metadata = connection.getMetaData(); 19 | 20 | final ResultSet rs = metadata.getFunctions(null, null, null); 21 | SQLDisplay.printRS("Functions", rs); 22 | } 23 | 24 | public static void listNumericFunctions() throws ClassNotFoundException, 25 | SQLException { 26 | 27 | Class.forName(SQLDisplay.DRIVER); 28 | final Connection connection = DriverManager.getConnection( 29 | SQLDisplay.URL, SQLDisplay.USERNAME, SQLDisplay.PASSWORD); 30 | final DatabaseMetaData metadata = connection.getMetaData(); 31 | 32 | final String[] functions = metadata.getNumericFunctions() 33 | .split(",\\s*"); 34 | 35 | for (final String function : functions) { 36 | System.out.println("Numeric Function = " + function); 37 | } 38 | } 39 | 40 | public static void listSQLKeywords() throws ClassNotFoundException, 41 | SQLException { 42 | 43 | Class.forName(SQLDisplay.DRIVER); 44 | final Connection connection = DriverManager.getConnection( 45 | SQLDisplay.URL, SQLDisplay.USERNAME, SQLDisplay.PASSWORD); 46 | final DatabaseMetaData metadata = connection.getMetaData(); 47 | 48 | final String[] functions = metadata.getSQLKeywords().split(",\\s*"); 49 | 50 | for (final String function : functions) { 51 | System.out.println("SQL keyword = " + function); 52 | } 53 | } 54 | 55 | public static void listStringFunctions() throws ClassNotFoundException, 56 | SQLException { 57 | 58 | Class.forName(SQLDisplay.DRIVER); 59 | final Connection connection = DriverManager.getConnection( 60 | SQLDisplay.URL, SQLDisplay.USERNAME, SQLDisplay.PASSWORD); 61 | final DatabaseMetaData metadata = connection.getMetaData(); 62 | 63 | final String[] functions = metadata.getStringFunctions().split(",\\s*"); 64 | 65 | for (final String function : functions) { 66 | System.out.println("String Function = " + function); 67 | } 68 | } 69 | 70 | public static void listSystemFunctions() throws ClassNotFoundException, 71 | SQLException { 72 | 73 | Class.forName(SQLDisplay.DRIVER); 74 | final Connection connection = DriverManager.getConnection( 75 | SQLDisplay.URL, SQLDisplay.USERNAME, SQLDisplay.PASSWORD); 76 | final DatabaseMetaData metadata = connection.getMetaData(); 77 | 78 | final String[] functions = metadata.getSystemFunctions().split(",\\s*"); 79 | 80 | for (final String function : functions) { 81 | System.out.println("System Function = " + function); 82 | } 83 | } 84 | 85 | /** 86 | * @param args 87 | * @throws JSQLParserException 88 | */ 89 | public static void main(final String[] args) throws Exception { 90 | // String sqlQuery = "Select MAX(foo) as junk from tbl"; 91 | // CCJSqlParserManager parserManager = new CCJSqlParserManager(); 92 | // final Statement stmt = parserManager.parse(new StringReader( 93 | // sqlQuery)); 94 | // System.out.println( stmt.toString() ); 95 | SQLDisplay.listSystemFunctions(); 96 | SQLDisplay.listStringFunctions(); 97 | SQLDisplay.listNumericFunctions(); 98 | SQLDisplay.listSQLKeywords(); 99 | SQLDisplay.listFunctions(); 100 | } 101 | 102 | private static void printRS(final String name, final ResultSet rs) 103 | throws SQLException { 104 | final ResultSetMetaData meta = rs.getMetaData(); 105 | System.out.println(String.format("%s", name)); 106 | while (rs.next()) { 107 | for (int i = 1; i <= meta.getColumnCount(); i++) { 108 | System.out.println(String.format("%s=%s", 109 | meta.getColumnName(i), rs.getObject(i))); 110 | } 111 | } 112 | } 113 | 114 | private static final String DRIVER = "com.mysql.jdbc.Driver"; 115 | 116 | private static final String URL = "jdbc:mysql://127.0.0.1/test"; 117 | 118 | private static final String USERNAME = "claude"; 119 | 120 | private static final String PASSWORD = ""; 121 | 122 | public SQLDisplay() { 123 | // TODO Auto-generated constructor stub 124 | } 125 | 126 | } 127 | -------------------------------------------------------------------------------- /src/main/java/org/xenei/jdbc4sparql/impl/rdf/RdfKeySegment.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one 3 | * or more contributor license agreements. See the NOTICE file 4 | * distributed with this work for additional information 5 | * regarding copyright ownership. The ASF licenses this file 6 | * to you under the Apache License, Version 2.0 (the 7 | * "License"); you may not use this file except in compliance 8 | * with the License. You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | package org.xenei.jdbc4sparql.impl.rdf; 19 | 20 | import org.xenei.jdbc4sparql.iface.KeySegment; 21 | import org.xenei.jena.entities.EntityManager; 22 | import org.xenei.jena.entities.EntityManagerFactory; 23 | import org.xenei.jena.entities.EntityManagerRequiredException; 24 | import org.xenei.jena.entities.MissingAnnotation; 25 | import org.xenei.jena.entities.ResourceWrapper; 26 | import org.xenei.jena.entities.annotations.Predicate; 27 | import org.xenei.jena.entities.annotations.Subject; 28 | 29 | import com.hp.hpl.jena.rdf.model.Model; 30 | import com.hp.hpl.jena.rdf.model.Resource; 31 | 32 | @Subject(namespace = "http://org.xenei.jdbc4sparql/entity/KeySegment#") 33 | public class RdfKeySegment implements KeySegment, ResourceWrapper { 34 | 35 | public static class Builder implements KeySegment { 36 | private short idx; 37 | private boolean ascending = true; 38 | 39 | public RdfKeySegment build(final Model model) { 40 | 41 | final Class typeClass = RdfKeySegment.class; 42 | final String fqName = String.format("%s/instance/%s", 43 | ResourceBuilder.getFQName(typeClass), getId()); 44 | final ResourceBuilder builder = new ResourceBuilder(model); 45 | Resource keySegment = null; 46 | if (builder.hasResource(fqName)) { 47 | keySegment = builder.getResource(fqName, typeClass); 48 | } 49 | else { 50 | keySegment = builder.getResource(fqName, typeClass); 51 | 52 | keySegment.addLiteral(builder.getProperty(typeClass, "idx"), 53 | idx); 54 | keySegment.addLiteral( 55 | builder.getProperty(typeClass, "ascending"), ascending); 56 | 57 | } 58 | 59 | final EntityManager entityManager = EntityManagerFactory 60 | .getEntityManager(); 61 | try { 62 | return entityManager.read(keySegment, RdfKeySegment.class); 63 | } catch (final MissingAnnotation e) { 64 | throw new RuntimeException(e); 65 | } 66 | } 67 | 68 | @Override 69 | public int compare(final Comparable[] data1, 70 | final Comparable[] data2) { 71 | return Utils.compare(getIdx(), isAscending(), data1, data2); 72 | } 73 | 74 | @Override 75 | public String getId() { 76 | return (isAscending() ? "A" : "D") + getIdx(); 77 | } 78 | 79 | @Override 80 | public short getIdx() { 81 | return idx; 82 | } 83 | 84 | @Override 85 | public boolean isAscending() { 86 | return ascending; 87 | } 88 | 89 | public Builder setAscending(final boolean ascending) { 90 | this.ascending = ascending; 91 | return this; 92 | } 93 | 94 | public Builder setIdx(final int idx) { 95 | if ((idx < 0) || (idx > Short.MAX_VALUE)) { 96 | throw new IllegalArgumentException( 97 | "index must be in the range 0 - " + Short.MAX_VALUE); 98 | } 99 | this.idx = (short) idx; 100 | return this; 101 | } 102 | } 103 | 104 | @Override 105 | public final int compare(final Comparable[] data1, 106 | final Comparable[] data2) { 107 | return Utils.compare(getIdx(), isAscending(), data1, data2); 108 | } 109 | 110 | @Override 111 | public final String getId() { 112 | return (isAscending() ? "A" : "D") + getIdx(); 113 | } 114 | 115 | @Override 116 | @Predicate(impl = true) 117 | public short getIdx() { 118 | throw new EntityManagerRequiredException(); 119 | } 120 | 121 | @Override 122 | @Predicate(impl = true) 123 | public Resource getResource() { 124 | throw new EntityManagerRequiredException(); 125 | } 126 | 127 | @Override 128 | @Predicate(impl = true) 129 | public boolean isAscending() { 130 | throw new EntityManagerRequiredException(); 131 | } 132 | } 133 | -------------------------------------------------------------------------------- /src/test/java/org/xenei/jdbc4sparql/sparql/items/QueryColumnInfoTest.java: -------------------------------------------------------------------------------- 1 | package org.xenei.jdbc4sparql.sparql.items; 2 | 3 | import static org.junit.Assert.assertEquals; 4 | import static org.junit.Assert.assertFalse; 5 | import static org.junit.Assert.assertNotEquals; 6 | import static org.junit.Assert.assertNotNull; 7 | import static org.junit.Assert.assertTrue; 8 | import static org.mockito.Mockito.mock; 9 | import static org.mockito.Mockito.when; 10 | 11 | import java.sql.SQLDataException; 12 | 13 | import org.junit.Before; 14 | import org.junit.Test; 15 | import org.xenei.jdbc4sparql.iface.Column; 16 | import org.xenei.jdbc4sparql.iface.ColumnDef; 17 | import org.xenei.jdbc4sparql.iface.name.ColumnName; 18 | import org.xenei.jdbc4sparql.iface.name.ItemName; 19 | import org.xenei.jdbc4sparql.iface.name.NameSegments; 20 | import org.xenei.jdbc4sparql.impl.NameUtils; 21 | 22 | import com.hp.hpl.jena.sparql.core.Var; 23 | 24 | public class QueryColumnInfoTest { 25 | 26 | private QueryColumnInfo columnInfo; 27 | private Column column; 28 | private ColumnName columnName; 29 | private ColumnDef colDef; 30 | 31 | @Before 32 | public void setup() { 33 | columnName = new ColumnName("catalog", "schema", "table", "column"); 34 | 35 | colDef = mock(ColumnDef.class); 36 | when(colDef.getType()).thenReturn(java.sql.Types.VARCHAR); 37 | 38 | column = mock(Column.class); 39 | when(column.getName()).thenReturn(columnName); 40 | when(column.getColumnDef()).thenReturn(colDef); 41 | 42 | columnInfo = new QueryColumnInfo(column, false); 43 | } 44 | 45 | // @Test 46 | // public void testGetExpr() { 47 | // assertNull(columnInfo.getExpr()); 48 | // columnInfo.setExpr(new NodeValueString("foo")); 49 | // assertEquals(new NodeValueString("foo"), columnInfo.getExpr()); 50 | // } 51 | 52 | @Test 53 | public void testSegments() { 54 | assertEquals("C:false S:true T:true C:true", columnInfo.getSegments() 55 | .toString()); 56 | assertEquals("schema.table.column", columnInfo.getName().getDBName()); 57 | columnInfo.setSegments(NameSegments.CATALOG); 58 | assertEquals("C:true S:false T:false C:true", columnInfo.getSegments() 59 | .toString()); 60 | assertEquals("column", columnInfo.getName().getDBName()); 61 | columnInfo.setSegments(NameSegments.SCHEMA); 62 | assertEquals("C:false S:true T:true C:true", columnInfo.getSegments() 63 | .toString()); 64 | assertEquals("schema.table.column", columnInfo.getName().getDBName()); 65 | columnInfo.setSegments(NameSegments.TABLE); 66 | assertEquals("C:false S:true T:true C:true", columnInfo.getSegments() 67 | .toString()); 68 | assertEquals("schema.table.column", columnInfo.getName().getDBName()); 69 | columnInfo.setSegments(NameSegments.FFTF); 70 | assertEquals("C:false S:false T:true C:true", columnInfo.getSegments() 71 | .toString()); 72 | assertEquals("table.column", columnInfo.getName().getDBName()); 73 | columnInfo.setSegments(NameSegments.TTTF); 74 | assertEquals("C:true S:true T:true C:true", columnInfo.getSegments() 75 | .toString()); 76 | assertEquals("schema.table.column", columnInfo.getName().getDBName()); 77 | 78 | } 79 | 80 | @Test 81 | public void testGetName() { 82 | final ItemName name = columnInfo.getName(); 83 | assertTrue(name == columnName); 84 | } 85 | 86 | @Test 87 | public void testGetVar() { 88 | final String dbName = "schema" + NameUtils.SPARQL_DOT + "table" 89 | + NameUtils.SPARQL_DOT + "column"; 90 | final Var v = columnInfo.getVar(); 91 | assertEquals(dbName, v.getName()); 92 | } 93 | 94 | @Test 95 | public void testGetGUID() { 96 | final String varName = columnInfo.getName().getGUID(); 97 | assertNotNull(columnInfo.getGUIDVar()); 98 | assertEquals(varName, columnInfo.getGUIDVar().getVarName()); 99 | } 100 | 101 | @Test 102 | public void testIsOptional() { 103 | assertFalse(columnInfo.isOptional()); 104 | columnInfo.setOptional(true); 105 | assertTrue(columnInfo.isOptional()); 106 | } 107 | 108 | @Test 109 | public void testAddAlias() throws SQLDataException { 110 | final ColumnName alias = new ColumnName("", "", "", "alias"); 111 | final QueryColumnInfo aliasInfo = columnInfo.createAlias(alias); 112 | assertEquals(alias, aliasInfo.getName()); 113 | 114 | assertNotEquals(columnInfo.getGUID(), alias.getGUID()); 115 | assertEquals(columnInfo.getGUID(), aliasInfo.getGUID()); 116 | 117 | } 118 | 119 | @Test 120 | public void testGetColumn() { 121 | assertEquals(column, columnInfo.getColumn()); 122 | } 123 | 124 | } 125 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Complete functionality has not been tested. However, most code is functional and testing should 2 | be completed in the near future. 3 | 4 | # JDBC 4 SPARQL 5 | 6 | JDBC 4 SPARQL is a JDBC Driver that uses a SPARQL endpoint (or Jena Model) as the data store. 7 | 8 | ## Licenses 9 | 10 | JDBC 4 SPARQL is licensed under Apache License V2. However, there is one component that is Licensed under the GNU LGPL V3.0 11 | this means that if you want to use this product in an environment that is not permitted under GNU LGPL V3.0 you will need to 12 | find another implementation of the SparqlParser interface. How to do this is covered in the Extensions Points section of this 13 | document. 14 | 15 | ## Maven 16 | 17 | Group ID: org.xenei 18 | 19 | Artifact ID: jdbc4sparql 20 | 21 | ## Usage 22 | 23 | ### URL 24 | The URL for the J4SDriver is 25 | jdbc:j4s:[?arg=value>[&arg2=value2[&arg3=value3...]]]:url 26 | 27 | For current runtime configuration options and defaults execute the J4SDriver class as an application. 28 | 29 | #### Valid arguments 30 | * catalog The name of the catalogue to restrict queries for. 31 | * type The type of the input. 32 | * builder The builder to build the SQL Schema with. Either the name of a registered builder or a class name. See "Registered Schema Builders" below. 33 | * parser The parser class. A fully qualified SparqlParser implementation. Defaults to org.xenei.jdbc4sparql.sparql.parser.jsqlparser.SparqlParserImpl 34 | 35 | #### Valid Types: 36 | * (Default) config - URL is a J4S configuration file (NOT YET IMPLEMENTED) 37 | * sparql - URL is a sparql endpoint 38 | * RDFXML or RDF/XML - URL is a RDF/XML formatted RDF file 39 | * NTRIPLES or N-Triples - URL is a N-Triples formatted RDF file 40 | * N3 or N3 - URL is a N3 formatted RDF file 41 | * TURTLE or Turtle - URL is a Turtle formatted RDF file 42 | * RDFJSON or RDF/JSON - URL is a RDF/JSON formatted RDF file 43 | * NQUADS or N-Quads - URL is a N-Quads formatted RDF file 44 | * TRIG or TriG - URL is a TriG formatted RDF file 45 | 46 | #### Registered Schema Builders 47 | (Default) Simple_Builder: A simple schema builder that builds tables based on RDFS Class names 48 | 49 | #### Notes #### 50 | 51 | Currently the catalogue is built at runtime by the builder, however future improvements should include a mechanism to store an entire configuration of multiple catalogues. 52 | 53 | the Catalogue contains the URL for the SPARQL endpoint or RDF file so it will be possible to configure the driver to access multiple endpoints. 54 | 55 | ## A Conflict Of Nomenclatures 56 | 57 | SQL and SPARQL use nomenclatures that conflict with each other. For the purposes of this documentation, unless otherwise specified, 58 | SQL nomenclatures will be used. 59 | 60 | ## How This Works 61 | 62 | ### Mapping The Graph 63 | In general an RDF Graph (and thus a SPARQL endpoint) is an instance of a navigational database, SQL is generally designed to work 64 | against a relational model so there this application attempts to map a navigational database onto relational tables and keys. It 65 | does this through the use of a "SchemaBuilder" implementation to map the RDF Graph to tables and columns. 66 | The default implementation looks for RDF resources that have a rdf:type of rdfs:Class. It considers 67 | each of these resources as tables and uses the resource name as the table name, we will call these "Table Resources". It then scans the 68 | RDF store looking for distinct properties of objects of the "Table Resource" types. The properties are the columns in the table. All tables generated by the "SchemaBuilder" are 69 | stored in a SQL Schema, so multiple schemas may be created from a single RDF Schema, Vocabulary or datastore. 70 | 71 | It is possible to override the default implementation by implementing a new SchemaBuilder and adding it to the /META-INF/services/org.xenei.jdbc4sparql.sparql.builders.SchemaBuilder file. 72 | The first entry in the file is considered the default builder. 73 | 74 | ### Generating A Query 75 | A SQL query is parsed by a "SparqlParser" implementation the and converted into a SPARQL query. 76 | The default implementation of SparqlParser is LGPL v3 and uses an LGPL v2.1 based package. Other implementations may be used. 77 | To register a different implementation place it as the first entry in the /META-INF/services/org.xenei.jdbc4sparql.sparql.parser.SparqlParser file. 78 | The returned query is then executed against the SPARQL endpoint or the 79 | Jena Model. The SPARQL ResultSet is retrieved and the QuerySolutions stored in a local list. A SQL ResultSet is 80 | created against that list and returned. 81 | 82 | 83 | --------------------------------------------------------------------------------