Skip to content

Commit

Permalink
Add streaming RDF to following endpoints
Browse files Browse the repository at this point in the history
- FedoraIdentifiers now streaming RDF
- FedoraRepositoryNodeTypes now streams RDF
- FedoraRepositoryNamespaces now streams RDF
- FedoraWorkspaces now streams RDF

 Better equals and hashCode for RdfStream
 Resolves: https://www.pivotaltracker.com/story/show/61166142
  • Loading branch information
ajs6f authored and Andrew Woods committed Nov 26, 2013
1 parent 49613d5 commit 3ac7aab
Show file tree
Hide file tree
Showing 24 changed files with 270 additions and 176 deletions.
Expand Up @@ -16,13 +16,12 @@

package org.fcrepo.http.api;

import static com.google.common.base.Throwables.propagate;
import static com.google.common.collect.Collections2.transform;
import static com.google.common.collect.ContiguousSet.create;
import static com.google.common.collect.DiscreteDomain.integers;
import static com.google.common.collect.Range.closed;
import static com.hp.hpl.jena.rdf.model.ModelFactory.createDefaultModel;
import static com.hp.hpl.jena.rdf.model.ResourceFactory.createResource;
import static com.hp.hpl.jena.update.GraphStoreFactory.create;
import static com.hp.hpl.jena.graph.NodeFactory.createURI;
import static javax.ws.rs.core.MediaType.TEXT_HTML;
import static org.fcrepo.http.commons.domain.RDFMediaType.N3;
import static org.fcrepo.http.commons.domain.RDFMediaType.N3_ALT1;
Expand Down Expand Up @@ -51,13 +50,15 @@
import org.fcrepo.http.commons.AbstractResource;
import org.fcrepo.http.commons.api.rdf.HttpGraphSubjects;
import org.fcrepo.http.commons.session.InjectedSession;
import org.fcrepo.kernel.rdf.GraphSubjects;
import org.fcrepo.kernel.utils.iterators.RdfStream;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;

import com.codahale.metrics.annotation.Timed;
import com.hp.hpl.jena.query.Dataset;
import com.hp.hpl.jena.rdf.model.Model;
import com.hp.hpl.jena.rdf.model.Resource;
import com.google.common.base.Function;
import com.hp.hpl.jena.graph.Node;
import com.hp.hpl.jena.graph.Triple;

/**
* JAX-RS Resource offering identifier creation.
Expand Down Expand Up @@ -85,20 +86,19 @@ public class FedoraIdentifiers extends AbstractResource {
@Timed
@Produces({TURTLE, N3, N3_ALT1, N3_ALT2, RDF_XML, RDF_JSON, NTRIPLES,
TEXT_HTML})
public Dataset getNextPid(@PathParam("path")
public RdfStream getNextPid(@PathParam("path")
final List<PathSegment> pathList,
@QueryParam("count")
@DefaultValue("1")
final Integer count,
@Context
final UriInfo uriInfo) throws RepositoryException {

final String path = toPath(pathList);

final Model model = createDefaultModel();
final String path = toPath(pathList);

final Resource pidsResult =
createResource(uriInfo.getAbsolutePath().toASCIIString());
final Node pidsResult =
createURI(uriInfo.getAbsolutePath().toASCIIString());

final Collection<String> identifiers =
transform(create(closed(1, count), integers()), pidMinter
Expand All @@ -107,21 +107,39 @@ public Dataset getNextPid(@PathParam("path")
final HttpGraphSubjects subjects =
new HttpGraphSubjects(session, FedoraNodes.class, uriInfo);

for (final String identifier : identifiers) {

final String absPath;
if (path.equals("/")) {
absPath = "/" + identifier;
} else {
absPath = path + "/" + identifier;
}
return new RdfStream(transform(
transform(identifiers, absolutize(path)),
identifier2triple(subjects, pidsResult))).topic(pidsResult);

final Resource s = subjects.getGraphSubject(absPath);
}

model.add(pidsResult, HAS_MEMBER_OF_RESULT, s);
}
private Function<String, String> absolutize(final String path) {
return new Function<String, String>() {

return create(model).toDataset();
@Override
public String apply(final String identifier) {
return path.equals("/") ? "/" + identifier : path + "/"
+ identifier;
}
};
}

private Function<String, Triple> identifier2triple(
final GraphSubjects subjects, final Node pidsResult) {
return new Function<String, Triple>() {

@Override
public Triple apply(final String identifier) {

try {
final Node s =
subjects.getGraphSubject(identifier).asNode();
return Triple.create(pidsResult, HAS_MEMBER_OF_RESULT
.asNode(), s);
} catch (final RepositoryException e) {
throw propagate(e);
}
}
};
}
}
Expand Up @@ -45,6 +45,7 @@
import org.fcrepo.http.commons.AbstractResource;
import org.fcrepo.http.commons.responses.HtmlTemplate;
import org.fcrepo.http.commons.session.InjectedSession;
import org.fcrepo.kernel.utils.iterators.RdfStream;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;

Expand Down Expand Up @@ -82,7 +83,7 @@ public Response updateNamespaces(final InputStream requestBodyStream)

try {
final Dataset dataset =
nodeService.getNamespaceRegistryGraph(session);
nodeService.getNamespaceRegistryDataset(session);
parseExecute(IOUtils.toString(requestBodyStream), dataset);
session.save();
return status(SC_NO_CONTENT).build();
Expand All @@ -101,14 +102,7 @@ public Response updateNamespaces(final InputStream requestBodyStream)
@Produces({TURTLE, N3, N3_ALT1, N3_ALT2, RDF_XML, RDF_JSON, NTRIPLES,
TEXT_HTML})
@HtmlTemplate("jcr:namespaces")
public Dataset getNamespaces() throws RepositoryException, IOException {

try {
final Dataset dataset =
nodeService.getNamespaceRegistryGraph(session);
return dataset;
} finally {
session.logout();
}
public RdfStream getNamespaces() throws RepositoryException, IOException {
return nodeService.getNamespaceRegistryStream(session).session(session);
}
}
Expand Up @@ -17,11 +17,10 @@
package org.fcrepo.http.api.repository;

import com.codahale.metrics.annotation.Timed;
import com.hp.hpl.jena.query.Dataset;
import com.hp.hpl.jena.query.DatasetFactory;
import org.fcrepo.http.commons.AbstractResource;
import org.fcrepo.http.commons.responses.HtmlTemplate;
import org.fcrepo.http.commons.session.InjectedSession;
import org.fcrepo.kernel.utils.iterators.RdfStream;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;

Expand All @@ -32,7 +31,9 @@
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.UriInfo;

import java.io.IOException;
import java.io.InputStream;
Expand All @@ -48,6 +49,8 @@
import static org.fcrepo.http.commons.domain.RDFMediaType.RDF_XML;
import static org.fcrepo.http.commons.domain.RDFMediaType.TURTLE;



/**
* Expose node types at a REST endpoint
* @author cbeer
Expand All @@ -70,13 +73,8 @@ public class FedoraRepositoryNodeTypes extends AbstractResource {
TEXT_HTML})
@Timed
@HtmlTemplate("jcr:nodetypes")
public Dataset getNodeTypes() throws RepositoryException {
try {
return DatasetFactory.create(nodeService.getNodeTypes(session).asModel());
} finally {
session.logout();
}

public RdfStream getNodeTypes(@Context final UriInfo uriInfo) throws RepositoryException {
return nodeService.getNodeTypes(session).session(session);
}

/**
Expand Down
Expand Up @@ -16,8 +16,6 @@

package org.fcrepo.http.api.repository;

import static com.hp.hpl.jena.rdf.model.ResourceFactory.createResource;
import static com.hp.hpl.jena.vocabulary.RDF.type;
import static com.sun.jersey.api.Responses.clientError;
import static javax.ws.rs.core.MediaType.TEXT_HTML;
import static javax.ws.rs.core.Response.created;
Expand All @@ -29,7 +27,6 @@
import static org.fcrepo.http.commons.domain.RDFMediaType.RDF_JSON;
import static org.fcrepo.http.commons.domain.RDFMediaType.RDF_XML;
import static org.fcrepo.http.commons.domain.RDFMediaType.TURTLE;
import static org.fcrepo.kernel.RdfLexicon.NOT_IMPLEMENTED;
import static org.slf4j.LoggerFactory.getLogger;

import java.net.MalformedURLException;
Expand Down Expand Up @@ -58,15 +55,11 @@
import org.fcrepo.http.commons.session.InjectedSession;
import org.fcrepo.kernel.rdf.GraphSubjects;
import org.fcrepo.kernel.rdf.JcrRdfTools;
import org.fcrepo.kernel.utils.iterators.RdfStream;
import org.slf4j.Logger;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;

import com.hp.hpl.jena.query.Dataset;
import com.hp.hpl.jena.query.DatasetFactory;
import com.hp.hpl.jena.rdf.model.Model;
import com.hp.hpl.jena.rdf.model.Resource;

/**
* This class exposes the JCR workspace functionality. It may be
* too JCR-y in the long run, but this lets us exercise the functionality.
Expand All @@ -91,30 +84,11 @@ public class FedoraRepositoryWorkspaces extends AbstractResource {
@Produces({TURTLE, N3, N3_ALT1, N3_ALT2, RDF_XML, RDF_JSON, NTRIPLES,
TEXT_HTML})
@HtmlTemplate("jcr:workspaces")
public Dataset getWorkspaces(@Context final UriInfo uriInfo)
public RdfStream getWorkspaces(@Context final UriInfo uriInfo)
throws RepositoryException {

final Model workspaceModel =
JcrRdfTools.withContext(null, session).getNamespaceTriples().asModel();

final String[] workspaces =
session.getWorkspace().getAccessibleWorkspaceNames();

for (final String workspace : workspaces) {
final Resource resource =
createResource(uriInfo.getBaseUriBuilder()
.path("/workspace:" + workspace)
.build()
.toString());
logger.debug("Discovered workspace: {}", resource);
workspaceModel.add(resource, type, NOT_IMPLEMENTED);
}
return JcrRdfTools.withContext(null, session).getWorkspaceTriples(uriInfo);

try {
return DatasetFactory.create(workspaceModel);
} finally {
session.logout();
}
}

/**
Expand Down
Expand Up @@ -43,7 +43,7 @@
import org.slf4j.Logger;

import com.google.common.base.Function;
import com.hp.hpl.jena.query.Dataset;
import com.hp.hpl.jena.rdf.model.Model;

public class FedoraIdentifiersTest {

Expand Down Expand Up @@ -94,10 +94,9 @@ public String apply(final Object input) {
when(mockNode.getPath()).thenReturn("/asdf:123");
when(mockSession.getNode("/asdf:123")).thenReturn(mockNode);

final Dataset np = testObj.getNextPid(createPathList(""), 2, uriInfo);

LOGGER.debug("Got dataset {}", np.getDefaultModel().toString());
assertTrue(np.getDefaultModel().contains(
final Model np = testObj.getNextPid(createPathList(""), 2, uriInfo).asModel();
LOGGER.debug("Got identifier results:\n{}", np.getGraph());
assertTrue(np.contains(
createResource("http://localhost/fcrepo/fcr:identifier"),
HAS_MEMBER_OF_RESULT,
createResource("http://localhost/fcrepo/asdf:123")));
Expand All @@ -123,11 +122,11 @@ public String apply(final Object input) {
when(mockNode.getPath()).thenReturn("/objects/asdf:123");
when(mockSession.getNode("/objects/asdf:123")).thenReturn(mockNode);

final Dataset np =
testObj.getNextPid(createPathList("objects"), 2, uriInfo);
final Model np =
testObj.getNextPid(createPathList("objects"), 2, uriInfo).asModel();

LOGGER.debug("Got dataset {}", np.getDefaultModel().toString());
assertTrue(np.getDefaultModel().contains(
LOGGER.debug("Got identifier results:\n{}", np.getGraph());
assertTrue(np.contains(
createResource("http://localhost/fcrepo/objects/fcr:identifier"),
HAS_MEMBER_OF_RESULT,
createResource("http://localhost/fcrepo/objects/asdf:123")));
Expand Down
Expand Up @@ -33,6 +33,7 @@

import org.fcrepo.http.api.repository.FedoraRepositoryNamespaces;
import org.fcrepo.kernel.services.NodeService;
import org.fcrepo.kernel.utils.iterators.RdfStream;
import org.junit.Before;
import org.junit.Test;
import org.mockito.Mock;
Expand All @@ -51,6 +52,8 @@ public class FedoraRepositoryNamespacesTest {
@Mock
private Dataset mockDataset;

private RdfStream testRdfStream = new RdfStream();

private Session mockSession;

@Before
Expand All @@ -66,17 +69,17 @@ public void setUp() throws RepositoryException, URISyntaxException,

@Test
public void testGetNamespaces() throws RepositoryException, IOException {
when(mockNodeService.getNamespaceRegistryGraph(mockSession))
.thenReturn(mockDataset);
assertEquals(mockDataset, testObj.getNamespaces());
when(mockNodeService.getNamespaceRegistryStream(mockSession))
.thenReturn(testRdfStream);
assertEquals(testRdfStream, testObj.getNamespaces());
}

@Test
public void testUpdateNamespaces() throws RepositoryException, IOException {

final Model model = createDefaultModel();
final Dataset mockDataset = DatasetFactory.create(model);
when(mockNodeService.getNamespaceRegistryGraph(mockSession))
when(mockNodeService.getNamespaceRegistryDataset(mockSession))
.thenReturn(mockDataset);

testObj.updateNamespaces(new ByteArrayInputStream(
Expand Down

0 comments on commit 3ac7aab

Please sign in to comment.