Skip to content

Commit 6aa1154

Browse files
author
Olaf Hartig
committed
adjusted the data source implementations to i) the introduction of the parser interface and ii) the changes of the request processor interface
1 parent 2b153bb commit 6aa1154

File tree

9 files changed

+406
-318
lines changed

9 files changed

+406
-318
lines changed

src/org/linkeddatafragments/datasource/DataSource.java

Lines changed: 6 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,9 @@
11
package org.linkeddatafragments.datasource;
22

3-
import javax.servlet.http.HttpServletRequest;
4-
5-
import org.linkeddatafragments.config.ConfigReader;
3+
import org.linkeddatafragments.fragments.IFragmentRequestParser;
64
import org.linkeddatafragments.fragments.LinkedDataFragmentRequest;
5+
import org.linkeddatafragments.fragments.tpf.TPFRequestParser;
76
import org.linkeddatafragments.fragments.tpf.TriplePatternFragmentRequest;
8-
import org.linkeddatafragments.fragments.tpf.TriplePatternFragmentRequestImpl;
97

108
/**
119
*
@@ -32,21 +30,16 @@ public String getTitle() {
3230
};
3331

3432
/**
35-
* This implementation assumes that the given request is a
36-
* {@link TriplePatternFragmentRequest}.
33+
* This implementation assumes that requests are
34+
* {@link TriplePatternFragmentRequest}s.
3735
*
3836
* Data sources for other types of {@link LinkedDataFragmentRequest}s must
3937
* override this method accordingly.
4038
*/
4139
@Override
42-
public IFragmentRequestProcessor getRequestProcessor(
43-
final HttpServletRequest request,
44-
final ConfigReader config )
40+
public IFragmentRequestParser getRequestParser()
4541
{
46-
final TriplePatternFragmentRequest r =
47-
new TriplePatternFragmentRequestImpl( request, config );
48-
49-
return getRequestProcessor( r );
42+
return new TPFRequestParser();
5043
}
5144

5245
@Override

src/org/linkeddatafragments/datasource/IDataSource.java

Lines changed: 5 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,7 @@
22

33
import java.io.Closeable;
44

5-
import javax.servlet.http.HttpServletRequest;
6-
7-
import org.linkeddatafragments.config.ConfigReader;
8-
import org.linkeddatafragments.fragments.LinkedDataFragmentRequest;
5+
import org.linkeddatafragments.fragments.IFragmentRequestParser;
96

107
/**
118
* A data source of Linked Data Fragments.
@@ -20,17 +17,12 @@ public interface IDataSource extends Closeable {
2017
public String getDescription();
2118

2219
/**
23-
* Returns a data source specific processor for the given request of a
24-
* Linked Data Fragment.
20+
* Returns a data source specific {@link IFragmentRequestParser}.
2521
*/
26-
IFragmentRequestProcessor getRequestProcessor(
27-
final HttpServletRequest request,
28-
final ConfigReader config );
22+
IFragmentRequestParser getRequestParser();
2923

3024
/**
31-
* Returns a data source specific processor for the given request of a
32-
* Linked Data Fragment.
25+
* Returns a data source specific {@link IFragmentRequestProcessor}.
3326
*/
34-
IFragmentRequestProcessor getRequestProcessor(
35-
final LinkedDataFragmentRequest request );
27+
IFragmentRequestProcessor getRequestProcessor();
3628
}
Lines changed: 138 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,138 @@
1+
package org.linkeddatafragments.datasource.hdt;
2+
3+
import java.io.IOException;
4+
5+
import org.linkeddatafragments.datasource.AbstractJenaBasedRequestProcessorForTriplePatterns;
6+
import org.linkeddatafragments.datasource.IFragmentRequestProcessor;
7+
import org.linkeddatafragments.fragments.LinkedDataFragment;
8+
import org.linkeddatafragments.fragments.tpf.TriplePatternFragmentRequest;
9+
import org.rdfhdt.hdt.enums.TripleComponentRole;
10+
import org.rdfhdt.hdt.hdt.HDT;
11+
import org.rdfhdt.hdt.hdt.HDTManager;
12+
import org.rdfhdt.hdt.triples.IteratorTripleID;
13+
import org.rdfhdt.hdt.triples.TripleID;
14+
import org.rdfhdt.hdtjena.NodeDictionary;
15+
16+
import com.hp.hpl.jena.graph.Triple;
17+
import com.hp.hpl.jena.rdf.model.Model;
18+
import com.hp.hpl.jena.rdf.model.ModelFactory;
19+
import com.hp.hpl.jena.rdf.model.Property;
20+
import com.hp.hpl.jena.rdf.model.RDFNode;
21+
import com.hp.hpl.jena.rdf.model.Resource;
22+
23+
/**
24+
* Implementation of {@link IFragmentRequestProcessor} that processes
25+
* {@link TriplePatternFragmentRequest}s over data stored in HDT.
26+
*
27+
* @author Ruben Verborgh
28+
* @author <a href="http://olafhartig.de">Olaf Hartig</a>
29+
*/
30+
public class HdtBasedRequestProcessorForTPFs
31+
extends AbstractJenaBasedRequestProcessorForTriplePatterns
32+
{
33+
protected final HDT datasource;
34+
protected final NodeDictionary dictionary;
35+
36+
/**
37+
* Creates the request processor.
38+
*
39+
* @param hdtFile the HDT datafile
40+
* @throws IOException if the file cannot be loaded
41+
*/
42+
public HdtBasedRequestProcessorForTPFs( String hdtFile ) throws IOException
43+
{
44+
datasource = HDTManager.mapIndexedHDT( hdtFile, null ); // listener=null
45+
dictionary = new NodeDictionary( datasource.getDictionary() );
46+
}
47+
48+
@Override
49+
protected Worker getWorker( final TriplePatternFragmentRequest request )
50+
throws IllegalArgumentException
51+
{
52+
return new Worker( request );
53+
}
54+
55+
56+
protected class Worker
57+
extends AbstractJenaBasedRequestProcessorForTriplePatterns.Worker
58+
{
59+
public Worker( final TriplePatternFragmentRequest request ) {
60+
super( request );
61+
}
62+
63+
@Override
64+
protected LinkedDataFragment createFragment( final Resource subject,
65+
final Property predicate,
66+
final RDFNode object,
67+
final long offset,
68+
final long limit )
69+
{
70+
// look up the result from the HDT datasource)
71+
int subjectId = subject == null ? 0 : dictionary.getIntID(subject.asNode(), TripleComponentRole.SUBJECT);
72+
int predicateId = predicate == null ? 0 : dictionary.getIntID(predicate.asNode(), TripleComponentRole.PREDICATE);
73+
int objectId = object == null ? 0 : dictionary.getIntID(object.asNode(), TripleComponentRole.OBJECT);
74+
75+
if (subjectId < 0 || predicateId < 0 || objectId < 0) {
76+
return createEmptyTriplePatternFragment();
77+
}
78+
79+
final Model triples = ModelFactory.createDefaultModel();
80+
IteratorTripleID matches = datasource.getTriples().search(new TripleID(subjectId, predicateId, objectId));
81+
boolean hasMatches = matches.hasNext();
82+
83+
if (hasMatches) {
84+
// try to jump directly to the offset
85+
boolean atOffset;
86+
if (matches.canGoTo()) {
87+
try {
88+
matches.goTo(offset);
89+
atOffset = true;
90+
} // if the offset is outside the bounds, this page has no matches
91+
catch (IndexOutOfBoundsException exception) {
92+
atOffset = false;
93+
}
94+
} // if not possible, advance to the offset iteratively
95+
else {
96+
matches.goToStart();
97+
for (int i = 0; !(atOffset = i == offset) && matches.hasNext(); i++) {
98+
matches.next();
99+
}
100+
}
101+
// try to add `limit` triples to the result model
102+
if (atOffset) {
103+
for (int i = 0; i < limit && matches.hasNext(); i++) {
104+
triples.add(triples.asStatement(toTriple(matches.next())));
105+
}
106+
}
107+
}
108+
109+
// estimates can be wrong; ensure 0 is returned if there are no results,
110+
// and always more than actual results
111+
final long estimatedTotal = triples.size() > 0 ?
112+
Math.max(offset + triples.size() + 1, matches.estimatedNumResults())
113+
: hasMatches ?
114+
Math.max(matches.estimatedNumResults(), 1)
115+
: 0;
116+
117+
// create the fragment
118+
final boolean isLastPage = ( estimatedTotal < offset + limit );
119+
return createTriplePatternFragment( triples, estimatedTotal, isLastPage );
120+
}
121+
122+
} // end of Worker
123+
124+
/**
125+
* Converts the HDT triple to a Jena Triple.
126+
*
127+
* @param tripleId the HDT triple
128+
* @return the Jena triple
129+
*/
130+
private Triple toTriple(TripleID tripleId) {
131+
return new Triple(
132+
dictionary.getNode(tripleId.getSubject(), TripleComponentRole.SUBJECT),
133+
dictionary.getNode(tripleId.getPredicate(), TripleComponentRole.PREDICATE),
134+
dictionary.getNode(tripleId.getObject(), TripleComponentRole.OBJECT)
135+
);
136+
}
137+
138+
}

src/org/linkeddatafragments/datasource/hdt/HdtDataSource.java

Lines changed: 4 additions & 107 deletions
Original file line numberDiff line numberDiff line change
@@ -2,25 +2,8 @@
22

33
import java.io.IOException;
44

5-
import org.linkeddatafragments.datasource.AbstractRequestProcessorForTriplePatterns;
65
import org.linkeddatafragments.datasource.DataSource;
76
import org.linkeddatafragments.datasource.IFragmentRequestProcessor;
8-
import org.linkeddatafragments.fragments.LinkedDataFragment;
9-
import org.linkeddatafragments.fragments.LinkedDataFragmentRequest;
10-
import org.linkeddatafragments.fragments.tpf.TriplePatternFragmentRequest;
11-
import org.rdfhdt.hdt.enums.TripleComponentRole;
12-
import org.rdfhdt.hdt.hdt.HDT;
13-
import org.rdfhdt.hdt.hdt.HDTManager;
14-
import org.rdfhdt.hdt.triples.IteratorTripleID;
15-
import org.rdfhdt.hdt.triples.TripleID;
16-
import org.rdfhdt.hdtjena.NodeDictionary;
17-
18-
import com.hp.hpl.jena.graph.Triple;
19-
import com.hp.hpl.jena.rdf.model.Model;
20-
import com.hp.hpl.jena.rdf.model.ModelFactory;
21-
import com.hp.hpl.jena.rdf.model.Property;
22-
import com.hp.hpl.jena.rdf.model.RDFNode;
23-
import com.hp.hpl.jena.rdf.model.Resource;
247

258
/**
269
* An HDT data source of Basic Linked Data Fragments.
@@ -30,8 +13,7 @@
3013
*/
3114
public class HdtDataSource extends DataSource {
3215

33-
private final HDT datasource;
34-
private final NodeDictionary dictionary;
16+
protected final HdtBasedRequestProcessorForTPFs requestProcessor;
3517

3618
/**
3719
* Creates a new HdtDataSource.
@@ -43,98 +25,13 @@ public class HdtDataSource extends DataSource {
4325
*/
4426
public HdtDataSource(String title, String description, String hdtFile) throws IOException {
4527
super(title, description);
46-
datasource = HDTManager.mapIndexedHDT(hdtFile, null);
47-
dictionary = new NodeDictionary(datasource.getDictionary());
28+
requestProcessor = new HdtBasedRequestProcessorForTPFs( hdtFile );
4829
}
4930

5031
@Override
51-
public IFragmentRequestProcessor getRequestProcessor(
52-
final LinkedDataFragmentRequest request )
32+
public IFragmentRequestProcessor getRequestProcessor()
5333
{
54-
if ( ! (request instanceof TriplePatternFragmentRequest) )
55-
throw new IllegalArgumentException();
56-
57-
return new MyProcessor( (TriplePatternFragmentRequest) request );
58-
}
59-
60-
protected class MyProcessor extends AbstractRequestProcessorForTriplePatterns
61-
{
62-
public MyProcessor( final TriplePatternFragmentRequest request ) {
63-
super( request );
34+
return requestProcessor;
6435
}
6536

66-
@Override
67-
protected LinkedDataFragment createFragment( final Resource subject,
68-
final Property predicate,
69-
final RDFNode object,
70-
final long offset,
71-
final long limit )
72-
{
73-
// look up the result from the HDT datasource)
74-
int subjectId = subject == null ? 0 : dictionary.getIntID(subject.asNode(), TripleComponentRole.SUBJECT);
75-
int predicateId = predicate == null ? 0 : dictionary.getIntID(predicate.asNode(), TripleComponentRole.PREDICATE);
76-
int objectId = object == null ? 0 : dictionary.getIntID(object.asNode(), TripleComponentRole.OBJECT);
77-
78-
if (subjectId < 0 || predicateId < 0 || objectId < 0) {
79-
return createEmptyTriplePatternFragment();
80-
}
81-
82-
final Model triples = ModelFactory.createDefaultModel();
83-
IteratorTripleID matches = datasource.getTriples().search(new TripleID(subjectId, predicateId, objectId));
84-
boolean hasMatches = matches.hasNext();
85-
86-
if (hasMatches) {
87-
// try to jump directly to the offset
88-
boolean atOffset;
89-
if (matches.canGoTo()) {
90-
try {
91-
matches.goTo(offset);
92-
atOffset = true;
93-
} // if the offset is outside the bounds, this page has no matches
94-
catch (IndexOutOfBoundsException exception) {
95-
atOffset = false;
96-
}
97-
} // if not possible, advance to the offset iteratively
98-
else {
99-
matches.goToStart();
100-
for (int i = 0; !(atOffset = i == offset) && matches.hasNext(); i++) {
101-
matches.next();
102-
}
103-
}
104-
// try to add `limit` triples to the result model
105-
if (atOffset) {
106-
for (int i = 0; i < limit && matches.hasNext(); i++) {
107-
triples.add(triples.asStatement(toTriple(matches.next())));
108-
}
109-
}
110-
}
111-
112-
// estimates can be wrong; ensure 0 is returned if there are no results,
113-
// and always more than actual results
114-
final long estimatedTotal = triples.size() > 0
115-
? Math.max(offset + triples.size() + 1, matches.estimatedNumResults())
116-
: hasMatches
117-
? Math.max(matches.estimatedNumResults(), 1)
118-
: 0;
119-
120-
// create the fragment
121-
final boolean isLastPage = ( estimatedTotal < offset + limit );
122-
return createTriplePatternFragment( triples, estimatedTotal, isLastPage );
123-
}
124-
125-
} // end of MyProcessor
126-
127-
/**
128-
* Converts the HDT triple to a Jena Triple.
129-
*
130-
* @param tripleId the HDT triple
131-
* @return the Jena triple
132-
*/
133-
private Triple toTriple(TripleID tripleId) {
134-
return new Triple(
135-
dictionary.getNode(tripleId.getSubject(), TripleComponentRole.SUBJECT),
136-
dictionary.getNode(tripleId.getPredicate(), TripleComponentRole.PREDICATE),
137-
dictionary.getNode(tripleId.getObject(), TripleComponentRole.OBJECT)
138-
);
139-
}
14037
}

0 commit comments

Comments
 (0)