Skip to content

Commit 6228a40

Browse files
committed
Move data sources into an interface.
1 parent 34d22a0 commit 6228a40

File tree

4 files changed

+126
-43
lines changed

4 files changed

+126
-43
lines changed
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
package org.linkeddatafragments.datasource;
2+
3+
import com.hp.hpl.jena.rdf.model.Model;
4+
5+
/**
6+
* A Basic Linked Data Fragment.
7+
* @author Ruben Verborgh
8+
*/
9+
public interface BasicLinkedDataFragment {
10+
/**
11+
* Gets the data of this fragment (possibly only partial).
12+
* @return the data as triples
13+
*/
14+
public Model getTriples();
15+
16+
/**
17+
* Gets the total number of triples in the fragment.
18+
* @return the total number of triples
19+
*/
20+
public int getTotalSize();
21+
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
package org.linkeddatafragments.datasource;
2+
3+
import com.hp.hpl.jena.rdf.model.Property;
4+
import com.hp.hpl.jena.rdf.model.RDFNode;
5+
import com.hp.hpl.jena.rdf.model.Resource;
6+
7+
/**
8+
* A data source of Basic Linked Data Fragments.
9+
* @author Ruben Verborgh
10+
*/
11+
public interface DataSource {
12+
/**
13+
* Gets the Basic Linked Data Fragment matching the specified triple pattern.
14+
* @param subject the subject (null to match any subject)
15+
* @param predicate the predicate (null to match any predicate)
16+
* @param object the object (null to match any object)
17+
* @return the first page of the fragment
18+
*/
19+
public BasicLinkedDataFragment getFragment(Resource subject, Property predicate, RDFNode object);
20+
}
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
package org.linkeddatafragments.datasource;
2+
3+
import java.io.IOException;
4+
5+
import org.rdfhdt.hdt.hdt.HDT;
6+
import org.rdfhdt.hdt.hdt.HDTManager;
7+
import org.rdfhdt.hdtjena.HDTGraph;
8+
9+
import com.hp.hpl.jena.rdf.model.Model;
10+
import com.hp.hpl.jena.rdf.model.ModelFactory;
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.StmtIterator;
15+
16+
/**
17+
* An HDT data source of Basic Linked Data Fragments.
18+
* @author Ruben Verborgh
19+
*/
20+
public class HdtDataSource implements DataSource {
21+
private final static int TRIPLES_LIMIT = 100;
22+
private Model data;
23+
24+
/**
25+
* Creates a new HdtDataSource.
26+
* @param hdtFile the HDT datafile
27+
* @throws IOException if the file cannot be loaded
28+
*/
29+
public HdtDataSource(String hdtFile) throws IOException {
30+
final HDT hdt = HDTManager.mapIndexedHDT(hdtFile, null);
31+
data = ModelFactory.createModelForGraph(new HDTGraph(hdt));
32+
}
33+
34+
@Override
35+
public BasicLinkedDataFragment getFragment(final Resource subject, final Property predicate, final RDFNode object) {
36+
return new BasicLinkedDataFragment() {
37+
@Override
38+
public Model getTriples() {
39+
final Model triples = ModelFactory.createDefaultModel();
40+
final StmtIterator statements = data.listStatements(subject, predicate, object);
41+
for (int i = 0; i < TRIPLES_LIMIT && statements.hasNext(); i++)
42+
triples.add(statements.next());
43+
return triples;
44+
}
45+
46+
@Override
47+
public int getTotalSize() {
48+
return 0;
49+
}
50+
};
51+
}
52+
}

src/org/linkeddatafragments/servlet/BasicLdfServlet.java

Lines changed: 33 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -12,38 +12,35 @@
1212
import javax.servlet.http.HttpServletResponse;
1313

1414
import org.linkeddatafragments.config.ConfigReader;
15-
import org.rdfhdt.hdt.hdt.HDT;
16-
import org.rdfhdt.hdt.hdt.HDTManager;
17-
import org.rdfhdt.hdtjena.HDTGraph;
15+
import org.linkeddatafragments.datasource.BasicLinkedDataFragment;
16+
import org.linkeddatafragments.datasource.DataSource;
17+
import org.linkeddatafragments.datasource.HdtDataSource;
1818

19+
import com.hp.hpl.jena.datatypes.TypeMapper;
1920
import com.hp.hpl.jena.rdf.model.Model;
20-
import com.hp.hpl.jena.rdf.model.ModelFactory;
2121
import com.hp.hpl.jena.rdf.model.Property;
2222
import com.hp.hpl.jena.rdf.model.RDFNode;
2323
import com.hp.hpl.jena.rdf.model.Resource;
24-
import com.hp.hpl.jena.rdf.model.StmtIterator;
24+
import com.hp.hpl.jena.rdf.model.ResourceFactory;
2525

2626
/**
2727
* Servlet that responds with a Basic Linked Data Fragment.
2828
* @author Ruben Verborgh
2929
*/
3030
public class BasicLdfServlet extends HttpServlet {
3131
private final static long serialVersionUID = 1L;
32-
private final static int TRIPLES_PER_PAGE = 100;
33-
private final static Pattern STRINGPATTERN = Pattern.compile("^\"(.*)\"(?:\\^\\^<(.*)>|@(.*))?$");
32+
private final static Pattern STRINGPATTERN = Pattern.compile("^\"(.*)\"(?:@(.*)|\\^\\^<(.*)>)?$");
33+
private final static TypeMapper types = TypeMapper.getInstance();
3434

3535
private ConfigReader config;
36-
private HashMap<String, Model> dataSources = new HashMap<String, Model>();
36+
private HashMap<String, DataSource> dataSources = new HashMap<String, DataSource>();
3737

3838
@Override
3939
public void init(ServletConfig servletConfig) throws ServletException {
4040
try {
4141
config = new ConfigReader(servletConfig.getInitParameter("configFile"));
42-
for (Entry<String, String> dataSource : config.getDataSources().entrySet()) {
43-
final HDT hdt = HDTManager.mapIndexedHDT(dataSource.getValue(), null);
44-
final Model model = ModelFactory.createModelForGraph(new HDTGraph(hdt));
45-
dataSources.put(dataSource.getKey(), model);
46-
}
42+
for (Entry<String, String> dataSource : config.getDataSources().entrySet())
43+
dataSources.put(dataSource.getKey(), new HdtDataSource(dataSource.getValue()));
4744
}
4845
catch (Exception e) {
4946
throw new ServletException(e);
@@ -56,23 +53,19 @@ public void doGet(HttpServletRequest request, HttpServletResponse response) thro
5653
// find the data source
5754
final String path = request.getRequestURI().substring(request.getContextPath().length());
5855
final String dataSourceName = path.substring(1);
59-
final Model dataSource = dataSources.get(dataSourceName);
56+
final DataSource dataSource = dataSources.get(dataSourceName);
6057
if (dataSource == null)
6158
throw new Exception("data source not found");
6259

63-
// create the output model
64-
final Model output = ModelFactory.createDefaultModel();
65-
output.setNsPrefixes(config.getPrefixes());
66-
67-
// parse the subject, predicate, and object parameters
68-
final Resource subject = parseAsResource(request.getParameter("subject"), output);
69-
final Property predicate = parseAsProperty(request.getParameter("predicate"), output);
70-
final RDFNode object = parseAsNode(request.getParameter("object"), output);
60+
// query the fragment
61+
final Resource subject = parseAsResource(request.getParameter("subject"));
62+
final Property predicate = parseAsProperty(request.getParameter("predicate"));
63+
final RDFNode object = parseAsNode(request.getParameter("object"));
64+
final BasicLinkedDataFragment fragment = dataSource.getFragment(subject, predicate, object);
7165

72-
// add all statements with the given parameters to the output model
73-
final StmtIterator statements = dataSource.listStatements(subject, predicate, object);
74-
for (int i = 0; i < TRIPLES_PER_PAGE && statements.hasNext(); i++)
75-
output.add(statements.next());
66+
// fill the output model
67+
final Model output = fragment.getTriples();
68+
output.setNsPrefixes(config.getPrefixes());
7669

7770
// serialize the output as Turtle
7871
response.setHeader("Server", "Linked Data Fragments Server");
@@ -87,32 +80,29 @@ public void doGet(HttpServletRequest request, HttpServletResponse response) thro
8780
/**
8881
* Parses the given value as an RDF resource.
8982
* @param value the value
90-
* @param model the model
9183
* @return the parsed value, or null if unspecified
9284
*/
93-
private Resource parseAsResource(String value, Model model) {
94-
final RDFNode subject = parseAsNode(value, model);
85+
private Resource parseAsResource(String value) {
86+
final RDFNode subject = parseAsNode(value);
9587
return subject instanceof Resource ? (Resource)subject : null;
9688
}
9789

9890
/**
9991
* Parses the given value as an RDF property.
10092
* @param value the value
101-
* @param model the model
10293
* @return the parsed value, or null if unspecified
10394
*/
104-
private Property parseAsProperty(String value, Model model) {
105-
final RDFNode predicate = parseAsNode(value, model);
106-
return predicate instanceof Resource ? model.createProperty(((Resource)predicate).getURI()) : null;
95+
private Property parseAsProperty(String value) {
96+
final RDFNode predicate = parseAsNode(value);
97+
return predicate instanceof Resource ? ResourceFactory.createProperty(((Resource)predicate).getURI()) : null;
10798
}
10899

109100
/**
110101
* Parses the given value as an RDF node.
111102
* @param value the value
112-
* @param model the model
113103
* @return the parsed value, or null if unspecified
114104
*/
115-
private RDFNode parseAsNode(String value, Model model) {
105+
private RDFNode parseAsNode(String value) {
116106
// nothing or empty indicates an unknown
117107
if (value == null || value.length() == 0)
118108
return null;
@@ -125,24 +115,24 @@ private RDFNode parseAsNode(String value, Model model) {
125115
return null;
126116
// angular brackets indicate a URI
127117
case '<':
128-
return model.createResource(value.substring(1, value.length() - 1));
118+
return ResourceFactory.createResource(value.substring(1, value.length() - 1));
129119
// quotes indicate a string
130120
case '"':
131121
final Matcher matcher = STRINGPATTERN.matcher(value);
132122
if (matcher.matches()) {
133123
final String body = matcher.group(1);
134-
final String type = matcher.group(2);
135-
final String lang = matcher.group(3);
136-
if (type != null)
137-
return model.createTypedLiteral(body, type);
124+
final String lang = matcher.group(2);
125+
final String type = matcher.group(3);
138126
if (lang != null)
139-
return model.createLiteral(body, lang);
140-
return model.createLiteral(body);
127+
return ResourceFactory.createLangLiteral(body, lang);
128+
if (type != null)
129+
return ResourceFactory.createTypedLiteral(body, types.getSafeTypeByName(type));
130+
return ResourceFactory.createPlainLiteral(body);
141131
}
142132
return null;
143133
// assume it's a URI without angular brackets
144134
default:
145-
return model.createResource(value);
135+
return ResourceFactory.createResource(value);
146136
}
147137
}
148138
}

0 commit comments

Comments
 (0)