Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Refactor triple generation to produce aesthetically pleasing graphs
  • Loading branch information
cbeer committed Oct 28, 2014
1 parent feb74ec commit 420a80a
Show file tree
Hide file tree
Showing 8 changed files with 98 additions and 49 deletions.
Expand Up @@ -17,6 +17,7 @@

import com.google.common.base.Function;
import com.google.common.base.Predicate;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Iterators;
import com.hp.hpl.jena.graph.Triple;
import com.hp.hpl.jena.rdf.model.Model;
Expand Down Expand Up @@ -205,48 +206,54 @@ public boolean apply(final Triple input) {
}));
}

rdfStream.concat(filter(getTriples(PropertiesRdfContext.class), tripleFilter));
if (ldpPreferences.prefersServerManaged()) {
rdfStream.concat(getTriples(LdpRdfContext.class));
}

rdfStream.concat(filter(getTriples(TypeRdfContext.class), tripleFilter));


if (httpTripleUtil != null && ldpPreferences.prefersServerManaged()) {
httpTripleUtil.addHttpComponentModelsForResourceToStream(rdfStream, resource(), uriInfo, translator());
}
rdfStream.concat(filter(getTriples(PropertiesRdfContext.class), tripleFilter));

if (!returnPreference.getValue().equals("minimal")) {

// Additional server-managed triples about this resource
if (ldpPreferences.prefersServerManaged()) {
rdfStream.concat(getTriples(AclRdfContext.class));
rdfStream.concat(getTriples(RootRdfContext.class));
rdfStream.concat(getTriples(ContentRdfContext.class));
}

rdfStream.concat(filter(getTriples(HashRdfContext.class), tripleFilter));
rdfStream.concat(filter(getTriples(BlankNodeRdfContext.class), tripleFilter));

if (resource() instanceof Datastream) {
rdfStream.concat(filter(
getTriples(((Datastream) resource()).getBinary(), PropertiesRdfContext.class), tripleFilter));
}

if (ldpPreferences.prefersReferences()) {
rdfStream.concat(getTriples(ReferencesRdfContext.class));
}

if (ldpPreferences.prefersServerManaged()) {
rdfStream.concat(getTriples(ParentRdfContext.class));
}

// containment triples about this resource
if (ldpPreferences.prefersContainment()) {
rdfStream.concat(getTriples(ChildrenRdfContext.class));
}

// LDP container membership triples for this resource
if (ldpPreferences.prefersMembership()) {
rdfStream.concat(getTriples(LdpContainerRdfContext.class));
rdfStream.concat(getTriples(LdpIsMemberOfRdfContext.class));
}

// Include binary properties if this is a binary description
if (resource() instanceof Datastream) {
final FedoraBinary binary = ((Datastream) resource()).getBinary();
rdfStream.concat(filter(binary.getTriples(translator(), ImmutableList.of(
TypeRdfContext.class,
PropertiesRdfContext.class,
ContentRdfContext.class)), tripleFilter));
}

// Embed all hash and blank nodes
rdfStream.concat(filter(getTriples(HashRdfContext.class), tripleFilter));
rdfStream.concat(filter(getTriples(BlankNodeRdfContext.class), tripleFilter));

// Include inbound references to this object
if (ldpPreferences.prefersReferences()) {
rdfStream.concat(getTriples(ReferencesRdfContext.class));
}

// Embed the children of this object
if (ldpPreferences.prefersEmbed()) {

final Iterator<FedoraResource> children = resource().getChildren();
Expand All @@ -256,17 +263,21 @@ public boolean apply(final Triple input) {

@Override
public RdfStream apply(final FedoraResource child) {
return child.getTriples(translator(), PropertiesRdfContext.class);
return child.getTriples(translator(), ImmutableList.of(
TypeRdfContext.class,
PropertiesRdfContext.class,
BlankNodeRdfContext.class));
}
})), tripleFilter));

}
}

if (ldpPreferences.prefersServerManaged()) {
rdfStream.concat(getTriples(LdpRdfContext.class));
}
if (httpTripleUtil != null && ldpPreferences.prefersServerManaged()) {
httpTripleUtil.addHttpComponentModelsForResourceToStream(rdfStream, resource(), uriInfo, translator());
}


return rdfStream;
}

Expand Down
Expand Up @@ -31,7 +31,6 @@
import org.fcrepo.kernel.FedoraObject;
import org.fcrepo.kernel.FedoraResource;
import org.fcrepo.kernel.identifiers.IdentifierConverter;
import org.fcrepo.kernel.impl.rdf.impl.PropertiesRdfContext;
import org.fcrepo.kernel.services.BinaryService;
import org.fcrepo.kernel.services.NodeService;
import org.fcrepo.kernel.services.ObjectService;
Expand Down Expand Up @@ -257,8 +256,8 @@ public void testHeadWithBinary() throws Exception {
when(mockResource.getDescription()).thenReturn(mockDatastream);
final Response actual = testObj.head();
assertEquals(OK.getStatusCode(), actual.getStatus());
assertTrue("Should be an LDP NonRDFSource",
mockResponse.getHeaders("Link").contains("<" + LDP_NAMESPACE + "NonRDFSource>;rel=\"type\""));
assertTrue("Should be an LDP NonRDFSource", mockResponse.getHeaders("Link").contains("<" + LDP_NAMESPACE +
"NonRDFSource>;rel=\"type\""));
assertFalse("Should not advertise Accept-Post flavors", mockResponse.containsHeader("Accept-Post"));
assertFalse("Should not advertise Accept-Patch flavors", mockResponse.containsHeader("Accept-Patch"));
assertTrue("Should contain a link to the binary description",
Expand All @@ -273,8 +272,8 @@ public void testHeadWithBinaryDescription() throws Exception {
when(mockResource.getBinary()).thenReturn(mockBinary);
final Response actual = testObj.head();
assertEquals(OK.getStatusCode(), actual.getStatus());
assertTrue("Should be an LDP RDFSource",
mockResponse.getHeaders("Link").contains("<" + LDP_NAMESPACE + "RDFSource>;rel=\"type\""));
assertTrue("Should be an LDP RDFSource", mockResponse.getHeaders("Link").contains("<" + LDP_NAMESPACE +
"RDFSource>;rel=\"type\""));
assertFalse("Should not advertise Accept-Post flavors", mockResponse.containsHeader("Accept-Post"));
assertTrue("Should advertise Accept-Patch flavors", mockResponse.containsHeader("Accept-Patch"));
assertTrue("Should contain a link to the binary",
Expand Down Expand Up @@ -520,8 +519,8 @@ public String apply(final RDFNode input) {
}
});

assertTrue("Should include references contexts",
rdfNodes.contains("class org.fcrepo.kernel.impl.rdf.impl.ReferencesRdfContext"));
assertTrue("Should include references contexts", rdfNodes.contains("class org.fcrepo.kernel.impl.rdf.impl" +
".ReferencesRdfContext"));

}

Expand All @@ -548,8 +547,8 @@ public void testGetWithBinary() throws Exception {
public void testGetWithBinaryDescription() throws Exception {
final Datastream mockResource = (Datastream)setResource(Datastream.class);
when(mockResource.getBinary()).thenReturn(mockBinary);
when(mockBinary.getTriples(idTranslator, PropertiesRdfContext.class)).thenReturn(
new RdfStream(new Triple(createURI("mockBinary"), createURI("called"), createURI("child:properties"))));
when(mockBinary.getTriples(eq(idTranslator), any(List.class))).thenReturn(new RdfStream(new Triple
(createURI("mockBinary"), createURI("called"), createURI("child:properties"))));
final Response actual = testObj.describe(null);
assertEquals(OK.getStatusCode(), actual.getStatus());
assertTrue("Should be an LDP RDFSource",
Expand Down Expand Up @@ -682,7 +681,7 @@ public void testPatchBinaryDescription() throws Exception {
final Datastream mockObject = (Datastream)setResource(Datastream.class);
when(mockObject.getBinary()).thenReturn(mockBinary);

when(mockBinary.getTriples(idTranslator, PropertiesRdfContext.class)).thenReturn(
when(mockBinary.getTriples(eq(idTranslator), any(List.class))).thenReturn(
new RdfStream(new Triple(createURI("mockBinary"), createURI("called"), createURI("child:properties"))));

doReturn(mockObject).when(testObj).resource();
Expand Down
Expand Up @@ -2163,6 +2163,34 @@ public void testCreateAndReplaceGraphMinimal() throws Exception {

}

@Test
@Ignore("This test needs manual intervention to decide how \"good\" the graph looks")
public void testGraphShouldNotBeTooLumpy() throws Exception {

final String pid = getRandomUniquePid();

final HttpPut httpPut = putObjMethod(pid);
httpPut.addHeader("Content-Type", "text/turtle");
httpPut.setEntity(new StringEntity("<> a <" + DIRECT_CONTAINER.getURI() + ">;" +
" <" + MEMBERSHIP_RESOURCE.getURI() + "> <> ;" +
" <" + HAS_MEMBER_RELATION.getURI() + "> <" + LDP_NAMESPACE + "member> ;" +
" <info:x> <#hash-uri> ;" +
" <info:x> [ <" + DC_11.title + "> \"xyz\" ] . " +
"<#hash-uri> <" + DC_11.title + "> \"some-hash-uri\" ."));

final HttpResponse response = client.execute(httpPut);
final int status = response.getStatusLine().getStatusCode();
assertEquals("Didn't get a CREATED response!", CREATED.getStatusCode(), status);

final String subjectURI = response.getFirstHeader("Location").getValue();

final HttpGet get = new HttpGet(subjectURI);
final HttpResponse getResponse = client.execute(get);

final String s = EntityUtils.toString(getResponse.getEntity());

}

private Date getDateFromModel( final Model model, final Resource subj, final Property pred ) throws Exception {
final StmtIterator stmts = model.listStatements( subj, pred, (String)null );
if ( stmts.hasNext() ) {
Expand Down
Expand Up @@ -63,8 +63,8 @@ public BlankNodeRdfContext(final FedoraResource resource,
public RdfStream apply(final Node node) {
final FedoraResource resource = nodeConverter.convert(node);

return resource.getTriples(idTranslator, ImmutableList.of(PropertiesRdfContext.class,
TypeRdfContext.class,
return resource.getTriples(idTranslator, ImmutableList.of(TypeRdfContext.class,
PropertiesRdfContext.class,
BlankNodeRdfContext.class));
}
})));
Expand Down
Expand Up @@ -20,11 +20,11 @@
import static org.fcrepo.kernel.RdfLexicon.IS_CONTENT_OF;

import org.fcrepo.kernel.Datastream;
import org.fcrepo.kernel.FedoraBinary;
import org.fcrepo.kernel.FedoraResource;
import org.fcrepo.kernel.identifiers.IdentifierConverter;

import com.hp.hpl.jena.graph.Node;
import com.hp.hpl.jena.graph.Triple;
import com.hp.hpl.jena.rdf.model.Resource;

/**
Expand All @@ -44,15 +44,18 @@ public ContentRdfContext(final FedoraResource resource,

// if there's an accessible jcr:content node, include information about
// it
if (resource() instanceof Datastream) {
if (resource instanceof Datastream) {
final FedoraResource contentNode = ((Datastream) resource()).getBinary();
final Node contentSubject = translator().reverse().convert(contentNode).asNode();
final Node subject = translator().reverse().convert(resource()).asNode();
final Node contentSubject = translator().reverse().convert(contentNode).asNode();
// add triples representing parent-to-content-child relationship
concat(new Triple[] {
create(subject, HAS_CONTENT.asNode(), contentSubject),
create(contentSubject, IS_CONTENT_OF.asNode(), subject)});
concat(create(subject, HAS_CONTENT.asNode(), contentSubject));

} else if (resource instanceof FedoraBinary) {
final FedoraResource description = ((FedoraBinary) resource).getDescription();
concat(create(translator().reverse().convert(resource).asNode(),
IS_CONTENT_OF.asNode(),
translator().reverse().convert(description).asNode()));
}
}
}
Expand Up @@ -57,8 +57,8 @@ public HashRdfContext(final FedoraResource resource,
public Iterator<Triple> apply(final Node input) {
final FedoraResource resource = nodeConverter.convert(input);

return resource.getTriples(idTranslator, ImmutableList.of(PropertiesRdfContext.class,
TypeRdfContext.class,
return resource.getTriples(idTranslator, ImmutableList.of(TypeRdfContext.class,
PropertiesRdfContext.class,
BlankNodeRdfContext.class));
}
})));
Expand Down
Expand Up @@ -48,7 +48,7 @@
import com.hp.hpl.jena.rdf.model.Resource;

/**
* <p>PropertiesRdfContextTest class.</p>
* <p>ContentRdfContextTest class.</p>
*
* @author ajs6f
*/
Expand All @@ -61,6 +61,13 @@ public void testForLowLevelStorageTriples() throws IOException {
logRdf("Retrieved RDF for testForLowLevelStorageTriples():", results);
assertTrue("Didn't find triple showing node has content!", results
.contains(mockSubject, HAS_CONTENT, mockContentSubject));
}

@Test
public void testFedoraBinaryTriples() throws IOException {

final Model results =
new ContentRdfContext(mockBinary, idTranslator).asModel();
assertTrue("Didn't find triple showing content has node!", results
.contains(mockContentSubject, IS_CONTENT_OF, mockSubject));
}
Expand All @@ -69,6 +76,7 @@ public void testForLowLevelStorageTriples() throws IOException {
public void setUp() throws RepositoryException {
initMocks(this);
when(mockBinary.getNode()).thenReturn(mockBinaryNode);
when(mockBinary.getDescription()).thenReturn(mockResource);
when(mockBinaryNode.getSession()).thenReturn(mockSession);
when(mockResource.getNode()).thenReturn(mockNode);
when(mockNode.getSession()).thenReturn(mockSession);
Expand Down
Expand Up @@ -147,7 +147,7 @@ public <Tr extends Triple, T extends Iterable<Tr>> RdfStream withThisContext(fin
* @return This object for continued use.
*/
public RdfStream concat(final Iterator<? extends Triple> newTriples) {
triples = Iterators.concat(newTriples, triples);
triples = Iterators.concat(triples, newTriples);
return this;
}

Expand All @@ -156,7 +156,7 @@ public RdfStream concat(final Iterator<? extends Triple> newTriples) {
* @return This object for continued use.
*/
public <T extends Triple> RdfStream concat(final T newTriple) {
triples = Iterators.concat(singletonIterator(newTriple), triples);
triples = Iterators.concat(triples, singletonIterator(newTriple));
return this;
}

Expand All @@ -165,7 +165,7 @@ public <T extends Triple> RdfStream concat(final T newTriple) {
* @return This object for continued use.
*/
public <T extends Triple> RdfStream concat(@SuppressWarnings("unchecked") final T... newTriples) {
triples = Iterators.concat(Iterators.forArray(newTriples), triples);
triples = Iterators.concat(triples, Iterators.forArray(newTriples));
return this;
}

Expand All @@ -174,7 +174,7 @@ public <T extends Triple> RdfStream concat(@SuppressWarnings("unchecked") final
* @return This object for continued use.
*/
public RdfStream concat(final Collection<? extends Triple> newTriples) {
triples = Iterators.concat(newTriples.iterator(), triples);
triples = Iterators.concat(triples, newTriples.iterator());
return this;
}

Expand Down

0 comments on commit 420a80a

Please sign in to comment.