Skip to content

Commit 91754b7

Browse files
committed
Initial support for jena TDB
1 parent efb5da2 commit 91754b7

5 files changed

Lines changed: 112 additions & 12 deletions

File tree

pom.xml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,11 @@
6868
<version>2.6</version>
6969
<type>jar</type>
7070
</dependency>
71+
<dependency>
72+
<groupId>org.apache.jena</groupId>
73+
<artifactId>jena-tdb</artifactId>
74+
<version>1.1.2</version>
75+
</dependency>
7176
</dependencies>
7277
<build>
7378
<sourceDirectory>src</sourceDirectory>

src/org/linkeddatafragments/datasource/DataSource.java

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,26 @@
33
/**
44
*
55
* @author mielvandersande
6+
* @author Bart Hanssens
67
*/
78
public abstract class DataSource implements IDataSource {
89
protected String title;
910
protected String description;
1011

12+
/**
13+
*
14+
* @param offset
15+
* @param limit
16+
*/
17+
protected void checkBoundaries(long offset, long limit) {
18+
if (offset < 0) {
19+
throw new IndexOutOfBoundsException("offset");
20+
}
21+
if (limit < 1) {
22+
throw new IllegalArgumentException("limit");
23+
}
24+
}
25+
1126
public DataSource(String title, String description) {
1227
this.title = title;
1328
this.description = description;

src/org/linkeddatafragments/datasource/DataSourceFactory.java

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,11 @@
99
/**
1010
*
1111
* @author Miel Vander Sande
12+
* @author Bart Hanssens
1213
*/
1314
public class DataSourceFactory {
15+
public final static String HDT = "HdtDatasource";
16+
public final static String JENA_TDB = "JenaTDBDatasource";
1417

1518
public static IDataSource create(JsonObject config) throws DataSourceException {
1619
String title = config.getAsJsonPrimitive("type").getAsString();
@@ -20,14 +23,18 @@ public static IDataSource create(JsonObject config) throws DataSourceException {
2023
JsonObject settings = config.getAsJsonObject("settings");
2124

2225
switch (type) {
23-
case "HdtDatasource":
24-
File file = new File(settings.getAsJsonPrimitive("file").getAsString());
25-
26+
case HDT:
2627
try {
28+
File file = new File(settings.getAsJsonPrimitive("file").getAsString());
2729
return new HdtDataSource(title, description, file.getAbsolutePath());
2830
} catch (IOException ex) {
2931
throw new DataSourceException(ex);
3032
}
33+
34+
case JENA_TDB:
35+
File file = new File(settings.getAsJsonPrimitive("directory").getAsString());
36+
return new JenaTDBDataSource(title, description, file);
37+
3138
default:
3239
throw new UnknownDataSourceTypeException(type);
3340

src/org/linkeddatafragments/datasource/HdtDataSource.java

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -42,12 +42,7 @@ public HdtDataSource(String title, String description, String hdtFile) throws IO
4242

4343
@Override
4444
public TriplePatternFragment getFragment(Resource subject, Property predicate, RDFNode object, final long offset, final long limit) {
45-
if (offset < 0) {
46-
throw new IndexOutOfBoundsException("offset");
47-
}
48-
if (limit < 1) {
49-
throw new IllegalArgumentException("limit");
50-
}
45+
checkBoundaries(offset, limit);
5146

5247
// look up the result from the HDT datasource)
5348
int subjectId = subject == null ? 0 : dictionary.getIntID(subject.asNode(), TripleComponentRole.SUBJECT);
@@ -88,9 +83,13 @@ public TriplePatternFragment getFragment(Resource subject, Property predicate, R
8883
}
8984
}
9085

91-
// estimates can be wrong; ensure 0 is returned if there are no results, and always more than actual results
92-
final long estimatedTotal = triples.size() > 0 ? Math.max(offset + triples.size() + 1, matches.estimatedNumResults())
93-
: hasMatches ? Math.max(matches.estimatedNumResults(), 1) : 0;
86+
// estimates can be wrong; ensure 0 is returned if there are no results,
87+
// and always more than actual results
88+
final long estimatedTotal = triples.size() > 0
89+
? Math.max(offset + triples.size() + 1, matches.estimatedNumResults())
90+
: hasMatches
91+
? Math.max(matches.estimatedNumResults(), 1)
92+
: 0;
9493

9594
// create the fragment
9695
return new TriplePatternFragment() {
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
package org.linkeddatafragments.datasource;
2+
3+
import com.hp.hpl.jena.query.Dataset;
4+
import com.hp.hpl.jena.query.Query;
5+
import com.hp.hpl.jena.query.QueryExecution;
6+
import com.hp.hpl.jena.query.QueryExecutionFactory;
7+
import com.hp.hpl.jena.query.QueryFactory;
8+
import com.hp.hpl.jena.query.QuerySolutionMap;
9+
import com.hp.hpl.jena.query.ReadWrite;
10+
import com.hp.hpl.jena.query.Syntax;
11+
import com.hp.hpl.jena.rdf.model.Model;
12+
import com.hp.hpl.jena.rdf.model.ModelFactory;
13+
import com.hp.hpl.jena.rdf.model.Property;
14+
import com.hp.hpl.jena.rdf.model.RDFNode;
15+
import com.hp.hpl.jena.rdf.model.Resource;
16+
import com.hp.hpl.jena.tdb.TDBFactory;
17+
import java.io.File;
18+
19+
/**
20+
* Experimental Jena TDB-backed data source of Basic Linked Data Fragments.
21+
*
22+
* @author Bart Hanssens <bart.hanssens@fedict.be>
23+
*/
24+
public class JenaTDBDataSource extends DataSource {
25+
private final Dataset tdb;
26+
private final String sparql = "CONSTRUCT ?s ?p ?o " +
27+
"ORDER BY ?s ?p ?o";
28+
private final Query query = QueryFactory.create(sparql, Syntax.syntaxSPARQL_11);
29+
30+
@Override
31+
public TriplePatternFragment getFragment(Resource subject, Property predicate, RDFNode object, long offset, long limit) {
32+
checkBoundaries(offset, limit);
33+
34+
tdb.begin(ReadWrite.READ);
35+
36+
Model model = tdb.getDefaultModel();
37+
QuerySolutionMap map = new QuerySolutionMap();
38+
map.add("s", subject);
39+
map.add("p", predicate);
40+
map.add("o", object);
41+
42+
query.setOffset(offset);
43+
query.setLimit(limit);
44+
45+
QueryExecution qexec = QueryExecutionFactory.create(query, model);
46+
final Model triples = ModelFactory.createDefaultModel();
47+
qexec.execConstruct(triples);
48+
49+
tdb.end();
50+
51+
if (triples.isEmpty()) {
52+
return new TriplePatternFragmentBase();
53+
} else {
54+
// For now, fake the estimate
55+
long size = triples.size();
56+
long estimate = (size == limit) ? offset + limit + 1 : offset + size;
57+
58+
return new TriplePatternFragmentBase(triples, estimate);
59+
}
60+
}
61+
62+
63+
/**
64+
* Constructor
65+
*
66+
* @param title
67+
* @param description
68+
* @param tdbdir directory used for TDB backing
69+
*/
70+
public JenaTDBDataSource(String title, String description, File tdbdir) {
71+
super(title, description);
72+
this.tdb = TDBFactory.createDataset(tdbdir.getAbsolutePath());
73+
}
74+
}

0 commit comments

Comments
 (0)