Skip to content

Commit

Permalink
Add rdf:type for primary and mixin nodetypes and their supertypes
Browse files Browse the repository at this point in the history
  • Loading branch information
yulgit1 authored and Andrew Woods committed Feb 19, 2014
1 parent 8fb508e commit c545379
Show file tree
Hide file tree
Showing 7 changed files with 210 additions and 18 deletions.
Expand Up @@ -37,13 +37,18 @@
import static org.apache.http.impl.client.cache.CacheConfig.DEFAULT;
import static org.fcrepo.http.commons.domain.RDFMediaType.TURTLE;
import static org.fcrepo.jcr.FedoraJcrTypes.ROOT;
import static org.fcrepo.kernel.RdfLexicon.DC_NAMESPACE;
import static org.fcrepo.kernel.RdfLexicon.DC_TITLE;
import static org.fcrepo.kernel.RdfLexicon.HAS_OBJECT_COUNT;
import static org.fcrepo.kernel.RdfLexicon.HAS_OBJECT_SIZE;
import static org.fcrepo.kernel.RdfLexicon.HAS_PRIMARY_IDENTIFIER;
import static org.fcrepo.kernel.RdfLexicon.HAS_PRIMARY_TYPE;
import static org.fcrepo.kernel.RdfLexicon.JCR_NT_NAMESPACE;
import static org.fcrepo.kernel.RdfLexicon.LDP_NAMESPACE;
import static org.fcrepo.kernel.RdfLexicon.MIX_NAMESPACE;
import static org.fcrepo.kernel.RdfLexicon.REPOSITORY_NAMESPACE;
import static org.fcrepo.kernel.RdfLexicon.RESTAPI_NAMESPACE;
import static org.fcrepo.kernel.RdfLexicon.RDF_NAMESPACE;
import static org.fcrepo.kernel.utils.FedoraTypesUtils.map;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
Expand Down Expand Up @@ -92,6 +97,7 @@
import com.hp.hpl.jena.graph.Graph;
import com.hp.hpl.jena.graph.Triple;
import com.hp.hpl.jena.rdf.model.Model;
import com.hp.hpl.jena.rdf.model.Property;
import com.hp.hpl.jena.rdf.model.Resource;
import com.hp.hpl.jena.sparql.core.Quad;
import com.hp.hpl.jena.update.GraphStore;
Expand Down Expand Up @@ -360,6 +366,61 @@ public String apply(final Header h) {

logger.debug("Leaving testGetObjectGraph()...");
}

@Test
public void verifyFullSetOfRdfTypes() throws Exception {
logger.debug("Entering verifyFullSetOfRdfTypes()...");
final String pid = "FedoraGraphWithRdfTypes";
createObject(pid);

final HttpGet getObjMethod =
new HttpGet(serverAddress + pid);
final HttpResponse response = client.execute(getObjMethod);
assertEquals(OK.getStatusCode(), response.getStatusLine()
.getStatusCode());
final GraphStore results = getGraphStore(getObjMethod);
final Model model = createModelForGraph(results.getDefaultGraph());
final Resource nodeUri = createResource(serverAddress + pid);
final Property rdfType = createProperty(RDF_NAMESPACE + "type");

//verifyResource based on the expection of these types on an out of the box fedora object:
/*
http://fedora.info/definitions/v4/rest-api#object
http://fedora.info/definitions/v4/rest-api#relations
http://fedora.info/definitions/v4/rest-api#resource
http://purl.org/dc/elements/1.1/describable
http://www.jcp.org/jcr/mix/1.0created
http://www.jcp.org/jcr/mix/1.0lastModified
http://www.jcp.org/jcr/mix/1.0lockable
http://www.jcp.org/jcr/mix/1.0referenceable
http://www.jcp.org/jcr/mix/1.0simpleVersionable
http://www.jcp.org/jcr/mix/1.0versionable
http://www.jcp.org/jcr/nt/1.0base
http://www.jcp.org/jcr/nt/1.0folder
http://www.jcp.org/jcr/nt/1.0hierarchyNode
http://www.w3.org/ns/ldp#Container
http://www.w3.org/ns/ldp#Page
*/

verifyResource(model, nodeUri, rdfType, RESTAPI_NAMESPACE, "object");
verifyResource(model, nodeUri, rdfType, RESTAPI_NAMESPACE, "relations");
verifyResource(model, nodeUri, rdfType, RESTAPI_NAMESPACE, "resource");
verifyResource(model, nodeUri, rdfType, LDP_NAMESPACE, "Container");
verifyResource(model, nodeUri, rdfType, LDP_NAMESPACE, "Page");
verifyResource(model, nodeUri, rdfType, DC_NAMESPACE, "describable");
verifyResource(model, nodeUri, rdfType, MIX_NAMESPACE, "created");
verifyResource(model, nodeUri, rdfType, MIX_NAMESPACE, "lastModified");
verifyResource(model, nodeUri, rdfType, MIX_NAMESPACE, "lockable");
verifyResource(model, nodeUri, rdfType, MIX_NAMESPACE, "referenceable");
verifyResource(model, nodeUri, rdfType, MIX_NAMESPACE, "simpleVersionable");
verifyResource(model, nodeUri, rdfType, MIX_NAMESPACE, "versionable");
verifyResource(model, nodeUri, rdfType, JCR_NT_NAMESPACE, "base");
verifyResource(model, nodeUri, rdfType, JCR_NT_NAMESPACE, "folder");
verifyResource(model, nodeUri, rdfType, JCR_NT_NAMESPACE, "hierarchyNode");

logger.debug("Leaving verifyFullSetOfRdfTypes()...");
}


@Test
public void testGetObjectGraphWithChildren() throws Exception {
Expand Down Expand Up @@ -645,8 +706,9 @@ public void testDescribeCount() throws Exception {

assertEquals(CREATED.getStatusCode(),
getStatus(postObjMethod("countNode")));
final String countNode = randomUUID().toString();
assertEquals(CREATED.getStatusCode(), getStatus(postDSMethod(
"countNode", "asdf", "1234")));
countNode, "asdf", "1234")));

graphStore = getGraphStore(new HttpGet(serverAddress + ""));
logger.debug("For testDescribeCount() first count repository graph:\n"
Expand Down Expand Up @@ -825,6 +887,12 @@ private void validateHTML(final String path) throws Exception {
}
logger.info("HTML found to be valid.");
}

private void verifyResource(Model model, Resource nodeUri, Property rdfType, String namespace, String resource) {
assertTrue("Didn't find rdfType " + namespace + resource, model.contains(nodeUri,
rdfType,
createResource(namespace + resource)));
}

public static class HTMLErrorHandler implements ErrorHandler {

Expand Down
12 changes: 12 additions & 0 deletions fcrepo-kernel-api/src/main/java/org/fcrepo/kernel/RdfLexicon.java
Expand Up @@ -90,6 +90,18 @@ public final class RdfLexicon {
public static final String RELATIONS_NAMESPACE =
"http://fedora.info/definitions/v4/rels-ext#";

public static final String RDF_NAMESPACE =
"http://www.w3.org/1999/02/22-rdf-syntax-ns#";

public static final String DC_NAMESPACE =
"http://purl.org/dc/elements/1.1/";

public static final String MIX_NAMESPACE =
"http://www.jcp.org/jcr/mix/1.0";

public static final String JCR_NT_NAMESPACE =
"http://www.jcp.org/jcr/nt/1.0";

// MEMBERSHIP
public static final Property HAS_MEMBER_OF_RESULT =
createProperty(REPOSITORY_NAMESPACE + "hasMember");
Expand Down
Expand Up @@ -17,14 +17,14 @@
package org.fcrepo.kernel.rdf.impl;

import static com.google.common.base.Throwables.propagate;
import static com.google.common.collect.Iterators.forArray;
import static com.hp.hpl.jena.graph.NodeFactory.createURI;
import static com.hp.hpl.jena.graph.Triple.create;
import static com.hp.hpl.jena.vocabulary.RDF.type;
import static org.fcrepo.kernel.rdf.JcrRdfTools.getRDFNamespaceForJcrNamespace;
import static org.slf4j.LoggerFactory.getLogger;

import java.util.Iterator;
import java.util.Set;

import javax.jcr.Node;
import javax.jcr.RepositoryException;
Expand All @@ -36,6 +36,8 @@
import org.slf4j.Logger;

import com.google.common.base.Function;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Iterators;
import com.hp.hpl.jena.graph.Triple;

Expand Down Expand Up @@ -87,9 +89,8 @@ public NodeRdfContext(final Node node, final GraphSubjects graphSubjects,
this.lowLevelStorageService = lowLevelStorageService;
}

// add JCR mixins as rdf:type triples
final Iterator<NodeType> nodeTypes = forArray(node.getMixinNodeTypes());
concat(Iterators.transform(nodeTypes, nodetype2triple()));
//include rdf:type for primaryType, mixins, and their supertypes
concatRdfTypes();
}

/**
Expand Down Expand Up @@ -150,4 +151,24 @@ private String getJcrUri(final String prefix) throws RepositoryException {
.getURI(prefix);
}

private void concatRdfTypes() throws RepositoryException {
final NodeType primaryNodeType = node.getPrimaryNodeType();
final NodeType[] mixinNodeTypesArr = node.getMixinNodeTypes();
final Set<NodeType> primarySupertypes = ImmutableSet.<NodeType>builder()
.add(primaryNodeType.getSupertypes()).build();
final Set<NodeType> mixinNodeTypes = ImmutableSet.<NodeType>builder().add(mixinNodeTypesArr).build();
final ImmutableList.Builder<NodeType> nodeTypesB = ImmutableList.<NodeType>builder()
.add(primaryNodeType)
.addAll(primarySupertypes)
.addAll(mixinNodeTypes);
final ImmutableSet.Builder<NodeType> mixinSupertypes = ImmutableSet.<NodeType>builder();
for (final NodeType mixinNodeType : mixinNodeTypes) {
mixinSupertypes.addAll(ImmutableSet.<NodeType>builder().add(mixinNodeType.getSupertypes()).build());
}
nodeTypesB.addAll(mixinSupertypes.build());
final ImmutableList<NodeType> nodeTypes = nodeTypesB.build();
final Iterator<NodeType> nodeTypesIt = nodeTypes.iterator();
concat(Iterators.transform(nodeTypesIt,nodetype2triple()));
}

}
Expand Up @@ -30,6 +30,7 @@
import static org.fcrepo.kernel.RdfLexicon.MEMBER_SUBJECT;
import static org.fcrepo.kernel.RdfLexicon.PAGE;
import static org.fcrepo.kernel.RdfLexicon.PAGE_OF;
import static org.fcrepo.kernel.RdfLexicon.JCR_NAMESPACE;
import static org.fcrepo.kernel.testutilities.TestNodeIterator.nodeIterator;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
Expand All @@ -48,8 +49,11 @@
import javax.jcr.Node;
import javax.jcr.NodeIterator;
import javax.jcr.Property;
import javax.jcr.NamespaceRegistry;
import javax.jcr.Repository;
import javax.jcr.RepositoryException;
import javax.jcr.Session;
import javax.jcr.Workspace;
import javax.jcr.nodetype.NodeDefinition;
import javax.jcr.nodetype.NodeType;

Expand Down Expand Up @@ -197,6 +201,13 @@ public void setUp() throws RepositoryException {
when(mockGraphSubjects.getGraphSubject(mockChildNode)).thenReturn(
testChildSubject);
when(mockNodeType.isNodeType("mode:system")).thenReturn(false);
when(mockNodeType.getSupertypes()).thenReturn(new NodeType[] {mockNodeType});
when(mockSession.getRepository()).thenReturn(mockRepository);
when(mockSession.getWorkspace()).thenReturn(mockWorkspace);
when(mockWorkspace.getNamespaceRegistry()).thenReturn(mockNamespaceRegistry);
when(mockNamespaceRegistry.getURI("not")).thenReturn(JCR_NAMESPACE);
when(mockParentNode.getSession()).thenReturn(mockSession);

}

private void nodeIsContainer() {
Expand Down Expand Up @@ -254,6 +265,12 @@ private void buildChildNodes() throws RepositoryException {
createResource(RESOURCE_PREFIX + "/4"));
when(mockGraphSubjects.getGraphSubject(mockChildNode5)).thenReturn(
createResource(RESOURCE_PREFIX + "/5"));

when(mockChildNode.getSession()).thenReturn(mockSession);
when(mockChildNode2.getSession()).thenReturn(mockSession);
when(mockChildNode3.getSession()).thenReturn(mockSession);
when(mockChildNode4.getSession()).thenReturn(mockSession);
when(mockChildNode5.getSession()).thenReturn(mockSession);

}

Expand Down Expand Up @@ -325,6 +342,15 @@ private Model getResults() throws RepositoryException {

@Mock
private Session mockSession;

@Mock
private Repository mockRepository;

@Mock
private Workspace mockWorkspace;

@Mock
private NamespaceRegistry mockNamespaceRegistry;

@Mock
private Node mockNode, mockParentNode, mockChildNode, mockChildNode2,
Expand Down
Expand Up @@ -53,7 +53,16 @@ public class NodeRdfContextTest {
private Node mockNode;

@Mock
private NodeType mockNodeType;
private NodeType mockPrimaryNodeType;

@Mock
private NodeType mockMixinNodeType;

@Mock
private NodeType mockPrimarySuperNodeType;

@Mock
private NodeType mockMixinSuperNodeType;

@Mock
private GraphSubjects mockGraphSubjects;
Expand All @@ -77,19 +86,37 @@ public class NodeRdfContextTest {

private static final String mockNodeTypePrefix = "jcr";

private static final String mockNodeTypeName = "someType";
private static final String mockPrimaryNodeTypeName = "somePrimaryType";
private static final String mockMixinNodeTypeName = "someMixinType";
private static final String mockPrimarySuperNodeTypeName = "somePrimarySuperType";
private static final String mockMixinSuperNodeTypeName = "someMixinSuperType";

private static final Resource mockNodeSubject = createResource();

@Before
public void setUp() throws RepositoryException {
initMocks(this);
when(mockNode.getPrimaryNodeType()).thenReturn(mockNodeType);
when(mockNodeType.getName()).thenReturn(
mockNodeTypePrefix + ":" + mockNodeTypeName);
when(mockNode.getPrimaryNodeType()).thenReturn(mockPrimaryNodeType);
when(mockPrimaryNodeType.getName()).thenReturn(
mockNodeTypePrefix + ":" + mockPrimaryNodeTypeName);

when(mockNode.getName()).thenReturn(mockNodeName);

when(mockNode.getMixinNodeTypes()).thenReturn(
new NodeType[] {mockNodeType});
new NodeType[] {mockMixinNodeType});
when(mockMixinNodeType.getName()).thenReturn(
mockNodeTypePrefix + ":" + mockMixinNodeTypeName);

when(mockPrimaryNodeType.getSupertypes()).thenReturn(
new NodeType[] {mockPrimarySuperNodeType});
when(mockPrimarySuperNodeType.getName()).thenReturn(
mockNodeTypePrefix + ":" + mockPrimarySuperNodeTypeName);

when(mockMixinNodeType.getSupertypes()).thenReturn(
new NodeType[] {mockMixinSuperNodeType});
when(mockMixinSuperNodeType.getName()).thenReturn(
mockNodeTypePrefix + ":" + mockMixinSuperNodeTypeName);

when(mockNode.getSession()).thenReturn(mockSession);
when(mockSession.getRepository()).thenReturn(mockRepository);
when(mockSession.getWorkspace()).thenReturn(mockWorkspace);
Expand All @@ -100,15 +127,27 @@ public void setUp() throws RepositoryException {
}

@Test
public void testIncludesMixinTriples() throws RepositoryException,
IOException {
public void testRdfTypesForNodetypes() throws RepositoryException,
IOException {
final Model actual =
new NodeRdfContext(mockNode, mockGraphSubjects, mockLowLevelStorageService).asModel();
final Resource expectedRdfType =
createResource(REPOSITORY_NAMESPACE + mockNodeTypeName);
final Resource expectedRdfTypePrimary =
createResource(REPOSITORY_NAMESPACE + mockPrimaryNodeTypeName);
final Resource expectedRdfTypeMixin =
createResource(REPOSITORY_NAMESPACE + mockMixinNodeTypeName);
final Resource expectedRdfTypePrimarySuper =
createResource(REPOSITORY_NAMESPACE + mockPrimarySuperNodeTypeName);
final Resource expectedRdfTypeMixinSuper =
createResource(REPOSITORY_NAMESPACE + mockMixinSuperNodeTypeName);
logRdf("Constructed RDF: ", actual);
assertTrue("Didn't find RDF type triple for mixin!", actual.contains(
mockNodeSubject, type, expectedRdfType));
assertTrue("Didn't find RDF type triple for primarytype!", actual.contains(
mockNodeSubject, type, expectedRdfTypePrimary));
assertTrue("Didn't find RDF type triple for mixintype!", actual.contains(
mockNodeSubject, type, expectedRdfTypeMixin));
assertTrue("Didn't find RDF type triple for primarysupertype!", actual.contains(
mockNodeSubject, type, expectedRdfTypePrimarySuper));
assertTrue("Didn't find RDF type triple for mixinsupertype!", actual.contains(
mockNodeSubject, type, expectedRdfTypeMixinSuper));
}

@Test(expected = RuntimeException.class)
Expand Down

0 comments on commit c545379

Please sign in to comment.