package net.fortytwo.sesametools.ldserver;
import net.fortytwo.sesametools.mappingsail.MappingSail;
import net.fortytwo.sesametools.mappingsail.MappingSchema;
import net.fortytwo.sesametools.mappingsail.RewriteRule;
import org.openrdf.model.IRI;
import org.openrdf.model.ValueFactory;
import org.openrdf.sail.Sail;
import org.restlet.Application;
/**
* A RESTful web service which publishes the contents of a Sail data store as Linked Data.
*
* @author Joshua Shinavier (http://fortytwo.net)
*/
public class LinkedDataServer extends Application {
private final Sail sail;
private final IRI datasetURI;
private static LinkedDataServer SINGLETON = null;
/**
* @param baseSail the data store published by this server
* @param internalBaseURI the base URI of resources within the data store
* @param externalBaseURI the base URI of resources as they are to be seen in the Linked Data
*/
public LinkedDataServer(final Sail baseSail,
final String internalBaseURI,
final String externalBaseURI) {
this(baseSail, internalBaseURI, externalBaseURI, null);
}
/**
* @param baseSail the data store published by this server
* @param internalBaseURI the base URI of resources within the data store
* @param externalBaseURI the base URI of resources as they are to be seen in the Linked Data
* @param dataset the URI of the data set to be published.
* This allows resource descriptions to be associated
* with metadata about the data set which contains them.
*/
public LinkedDataServer(final Sail baseSail,
final String internalBaseURI,
final String externalBaseURI,
final String dataset) {
if (null != SINGLETON) {
throw new IllegalStateException("only one LinkedDataServer may be instantiated per JVM");
}
SINGLETON = this;
final ValueFactory vf = baseSail.getValueFactory();
if (!internalBaseURI.equals(externalBaseURI)) {
RewriteRule outboundRewriter = new RewriteRule() {
public IRI rewrite(final IRI original) {
if (null == original) {
return null;
} else {
String s = original.stringValue();
return s.startsWith(internalBaseURI)
? vf.createIRI(s.replace(internalBaseURI, externalBaseURI))
: original;
}
}
};
RewriteRule inboundRewriter = new RewriteRule() {
public IRI rewrite(final IRI original) {
if (null == original) {
return null;
} else {
String s = original.stringValue();
return s.startsWith(externalBaseURI)
? vf.createIRI(s.replace(externalBaseURI, internalBaseURI))
: original;
}
}
};
MappingSchema schema = new MappingSchema();
schema.setRewriter(MappingSchema.Direction.INBOUND, inboundRewriter);
schema.setRewriter(MappingSchema.Direction.OUTBOUND, outboundRewriter);
this.sail = new MappingSail(baseSail, schema);
datasetURI = null == dataset
? null
: outboundRewriter.rewrite(vf.createIRI(dataset));
} else {
this.sail = baseSail;
datasetURI = null == dataset
? null
: vf.createIRI(dataset);
}
}
/**
* @return the data store published by this server
*/
public Sail getSail() {
return sail;
}
/**
* @return the internal URI for the data set published by this server
*/
public IRI getDatasetURI() {
return datasetURI;
}
/**
* @return the single Linked Data server
*/
public static LinkedDataServer getInstance() {
return SINGLETON;
}
}