package net.fortytwo.sesametools.ldserver; import info.aduna.iteration.CloseableIteration; import org.openrdf.model.Namespace; import org.openrdf.model.Statement; import org.openrdf.model.IRI; import org.openrdf.rio.RDFFormat; import org.openrdf.sail.Sail; import org.openrdf.sail.SailConnection; import org.openrdf.sail.SailException; import org.restlet.data.MediaType; import org.restlet.representation.Representation; import org.restlet.representation.Variant; import org.restlet.resource.Get; import org.restlet.resource.ServerResource; import java.util.Collection; import java.util.LinkedList; import java.util.logging.Level; import java.util.logging.Logger; /** * Graph resources are information resources which (in the present schema) do not use suffixes identifying the RDF * format (e.g. .rdf or .ttl). Instead, they use content negotiation to serve an appropriate representation against * the IRI of the graph, without redirection. * <p> * This conforms to the common expectation that RDF documents and corresponding named graphs have the same IRI. * * @author Joshua Shinavier (http://fortytwo.net) */ public class GraphResource extends ServerResource { private static final Logger logger = Logger.getLogger(GraphResource.class.getName()); protected String selfIRI; protected Sail sail; public GraphResource() { super(); getVariants().addAll(RDFMediaTypes.getRDFVariants()); sail = LinkedDataServer.getInstance().getSail(); } @Override @Get public Representation get(final Variant entity) { MediaType type = entity.getMediaType(); RDFFormat format = RDFMediaTypes.findRdfFormat(type); selfIRI = this.getRequest().getResourceRef().toString(); try { IRI subject = sail.getValueFactory().createIRI(selfIRI); return getRDFRepresentation(subject, format); } catch (Throwable t) { t.printStackTrace(); return null; } } private void addStatementsInGraph(final org.openrdf.model.Resource graph, final Collection<Statement> statements, final SailConnection c) throws SailException { try (CloseableIteration<? extends Statement, SailException> stIter = c.getStatements(null, null, null, false, graph)) { while (stIter.hasNext()) { statements.add(stIter.next()); } } } private Representation getRDFRepresentation(final IRI graph, final RDFFormat format) { try { Collection<Namespace> namespaces = new LinkedList<>(); Collection<Statement> statements = new LinkedList<>(); SailConnection c = sail.getConnection(); try { // Note: do NOT add graph or document metadata, as this document is to contain only those statements // asserted in the graph in question. // Add statements in this graph, preserving the graph component of the statements. addStatementsInGraph(graph, statements, c); // Select namespaces, for human-friendliness try (CloseableIteration<? extends Namespace, SailException> ns = c.getNamespaces()) { while (ns.hasNext()) { namespaces.add(ns.next()); } } } finally { c.close(); } return new RDFRepresentation(statements, namespaces, format); } catch (Throwable t) { logger.log(Level.WARNING, "failed to create RDF representation", t); t.printStackTrace(System.err); return null; } } }