Skip to content

Commit

Permalink
Continuing to build iterating persistance machinery
Browse files Browse the repository at this point in the history
  • Loading branch information
ajs6f committed Oct 25, 2013
1 parent 75410ce commit f540613
Show file tree
Hide file tree
Showing 5 changed files with 186 additions and 33 deletions.
Expand Up @@ -17,6 +17,7 @@
package org.fcrepo.kernel.utils.iterators;

import static org.fcrepo.kernel.utils.NodePropertiesTools.appendOrReplaceNodeProperty;
import static org.fcrepo.kernel.utils.NodePropertiesTools.getPropertyType;
import static org.slf4j.LoggerFactory.getLogger;

import javax.jcr.NamespaceException;
Expand All @@ -30,6 +31,7 @@
import org.slf4j.Logger;

import com.hp.hpl.jena.rdf.model.Resource;
import com.hp.hpl.jena.rdf.model.Statement;

/**
* Consumes an {@link RdfStream} by adding its contents to the
Expand Down Expand Up @@ -85,10 +87,14 @@ protected void operateOnMixin(final Resource mixinResource,


@Override
protected void operateOnOneValueOfProperty(final Node n, final String p,
final Value v) throws RepositoryException {
LOGGER.debug("Adding property: {} with value: {} to node: {}.", p, v, n
protected void operateOnProperty(final Statement t, final Node n) throws RepositoryException {
LOGGER.debug("Adding property from triple: {} to node: {}.", t, n
.getPath());
appendOrReplaceNodeProperty(n, p, v);
final String propertyName =
getPropertyNameFromPredicate(n, t.getPredicate());
final Value v =
jcrRdfTools.createValue(n, t.getObject(), getPropertyType(n,
propertyName));
appendOrReplaceNodeProperty(n, propertyName, v);
}
}
Expand Up @@ -16,9 +16,12 @@

package org.fcrepo.kernel.utils.iterators;

import static com.google.common.base.Predicates.and;
import static com.google.common.base.Predicates.not;
import static com.google.common.collect.Iterators.filter;
import static com.hp.hpl.jena.rdf.model.ModelFactory.createDefaultModel;
import static com.hp.hpl.jena.vocabulary.RDF.type;
import static org.fcrepo.kernel.utils.NodePropertiesTools.getPropertyType;
import static org.fcrepo.kernel.utils.iterators.UnmanagedRdfStream.isManagedTriple;
import static org.slf4j.LoggerFactory.getLogger;

import javax.jcr.Node;
Expand All @@ -30,9 +33,13 @@
import org.fcrepo.kernel.utils.JcrRdfTools;
import org.slf4j.Logger;

import com.google.common.base.Predicate;
import com.google.common.util.concurrent.ListenableFuture;
import com.google.common.util.concurrent.SettableFuture;
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.RDFNode;
import com.hp.hpl.jena.rdf.model.Resource;
import com.hp.hpl.jena.rdf.model.Statement;

Expand All @@ -50,6 +57,9 @@ public abstract class RdfPersister implements RdfStreamConsumer {

protected final JcrRdfTools jcrRdfTools;

// if it's not about a Fedora resource, we don't care.
protected final Predicate<Triple> isFedoraSubjectTriple;

private static final Model m = createDefaultModel();

private static final Logger LOGGER = getLogger(RdfPersister.class);
Expand All @@ -63,8 +73,32 @@ public abstract class RdfPersister implements RdfStreamConsumer {
*/
public RdfPersister(final GraphSubjects graphSubjects,
final Session session, final RdfStream stream) {
this.stream = stream;
// this filters out triples with internal or managed predicates
this.idTranslator = graphSubjects;
this.isFedoraSubjectTriple = new Predicate<Triple>() {

@Override
public boolean apply(final Triple t) {

final boolean result =
graphSubjects.isFedoraGraphSubject(m.asStatement(t)
.getSubject());
if (result) {
LOGGER.debug(
"Discovered a Fedora-relevant subject in triple: {}.",
t);
} else {
LOGGER.debug("Ignoring triple: {}.", t);

}
return result;
}

};
// we knock out managed RDF and non-Fedora RDF
this.stream =
new RdfStream(filter(stream, and(not(isManagedTriple),
isFedoraSubjectTriple)));
this.session = session;
this.jcrRdfTools = JcrRdfTools.withContext(graphSubjects, session);
}
Expand All @@ -73,7 +107,7 @@ public RdfPersister(final GraphSubjects graphSubjects,
public void consume() throws Exception {
while (stream.hasNext()) {
final Statement t = m.asStatement(stream.next());
LOGGER.debug("Removing triple {} from repository.", t);
LOGGER.debug("Operating on triple {}.", t);
operateOnTriple(t);
}

Expand All @@ -82,35 +116,35 @@ public void consume() throws Exception {
protected void operateOnTriple(final Statement t)
throws RepositoryException {
final Resource subject = t.getSubject();

// if it's not about a node, we don't care.
if (!idTranslator.isFedoraGraphSubject(subject)) {
return;
}

final Node subjectNode = idTranslator.getNodeFromGraphSubject(subject);

// special logic for handling rdf:type updates.
// if the object is an already-existing mixin, update
// the node's mixins. If it isn't, just treat it normally.
// if this is a RDF type assertion, update the node's mixins. If it
// isn't, treat it as a "data" property.
if (t.getPredicate().equals(type) && t.getObject().isResource()) {
final Resource mixinResource = t.getObject().asResource();
LOGGER.debug("Operating on node: {} with mixin: {}.", subjectNode,
mixinResource);
operateOnMixin(mixinResource, subjectNode);
}
final String propertyName =
jcrRdfTools.getPropertyNameFromPredicate(subjectNode, t
.getPredicate());

if (subjectNode.hasProperty(propertyName)) {
final Value v =
jcrRdfTools.createValue(subjectNode, t.getObject(),
getPropertyType(subjectNode, propertyName));
operateOnOneValueOfProperty(subjectNode, propertyName, v);
} else {
LOGGER.debug("Operating on node: {} from triple: {}.", subjectNode,
t);
operateOnProperty(t, subjectNode);
}
}

protected abstract void operateOnOneValueOfProperty(final Node subjectNode,
final String propertyName, final Value v) throws RepositoryException;
protected String getPropertyNameFromPredicate(final Node subjectNode,
final Property predicate) throws RepositoryException {
return jcrRdfTools.getPropertyNameFromPredicate(subjectNode, predicate,
stream.namespaces());
}

protected Value createValue(final Node subjectNode, final RDFNode object,
final Integer propertyType) throws RepositoryException {
return jcrRdfTools.createValue(subjectNode, object, propertyType);
}

protected abstract void operateOnProperty(final Statement t,
final Node subjectNode) throws RepositoryException;

protected abstract void operateOnMixin(final Resource mixinResource,
final Node subjectNode) throws RepositoryException;
Expand Down
Expand Up @@ -16,6 +16,7 @@

package org.fcrepo.kernel.utils.iterators;

import static org.fcrepo.kernel.utils.NodePropertiesTools.getPropertyType;
import static org.fcrepo.kernel.utils.NodePropertiesTools.removeNodeProperty;
import static org.slf4j.LoggerFactory.getLogger;

Expand All @@ -30,6 +31,7 @@
import org.slf4j.Logger;

import com.hp.hpl.jena.rdf.model.Resource;
import com.hp.hpl.jena.rdf.model.Statement;

/**
* Consumes an {@link RdfStream} by removing its contents from the
Expand Down Expand Up @@ -77,10 +79,17 @@ protected void operateOnMixin(final Resource mixinResource,
}

@Override
protected void operateOnOneValueOfProperty(final Node n, final String p,
final Value v) throws RepositoryException {
LOGGER.debug("Adding property: {} with value: {} to node: {}.", p, v, n
protected void operateOnProperty(final Statement t, final Node n)
throws RepositoryException {
LOGGER.debug("Removing property from triple: {} on node: {}.", t, n
.getPath());
removeNodeProperty(n, p, v);
final String propertyName =
getPropertyNameFromPredicate(n, t.getPredicate());
if (n.hasProperty(propertyName)) {
final Value v =
jcrRdfTools.createValue(n, t.getObject(), getPropertyType(n,
propertyName));
removeNodeProperty(n, propertyName, v);
}
}
}
Expand Up @@ -39,7 +39,7 @@ public class UnmanagedRdfStream extends RdfStream {

private static final Model model = createDefaultModel();

private static final Predicate<Triple> isManagedTriple =
public static final Predicate<Triple> isManagedTriple =
new Predicate<Triple>() {

@Override
Expand Down
@@ -0,0 +1,104 @@

package org.fcrepo.kernel.utils.iterators;

import static com.hp.hpl.jena.graph.NodeFactory.createAnon;
import static com.hp.hpl.jena.graph.Triple.create;
import static com.hp.hpl.jena.rdf.model.ModelFactory.createDefaultModel;
import static com.hp.hpl.jena.vocabulary.RDF.type;
import static org.junit.Assert.assertTrue;
import static org.mockito.Mockito.when;
import static org.mockito.MockitoAnnotations.initMocks;

import javax.jcr.Node;
import javax.jcr.RepositoryException;
import javax.jcr.Session;
import org.fcrepo.kernel.rdf.GraphSubjects;
import org.junit.Before;
import org.junit.Test;
import org.mockito.Mock;
import com.hp.hpl.jena.graph.Triple;
import com.hp.hpl.jena.rdf.model.Model;
import com.hp.hpl.jena.rdf.model.Resource;
import com.hp.hpl.jena.rdf.model.Statement;

public class RdfPersisterTest {

@Mock
private Session mockSession;

@Mock
private Node mockNode;

@Mock
private GraphSubjects mockGraphSubjects;

@Mock
private RdfStream mockStream;

private RdfPersister testPersister;

private boolean successfullyOperatedOnAProperty = false;

private boolean successfullyOperatedOnAMixin = false;

private static final Model m = createDefaultModel();

private static final Triple propertyTriple = create(createAnon(),
createAnon(), createAnon());

private static final Statement propertyStatement = m
.asStatement(propertyTriple);

private static final Triple mixinTriple = create(createAnon(),
type.asNode(), createAnon());

private static final Statement mixinStatement = m.asStatement(mixinTriple);


@Before
public void setUp() throws RepositoryException {
initMocks(this);
when(mockStream.hasNext()).thenReturn(true, true, false);
when(mockStream.next()).thenReturn(propertyTriple, mixinTriple);
when(
mockGraphSubjects.getNodeFromGraphSubject(propertyStatement
.getSubject())).thenReturn(mockNode);
when(
mockGraphSubjects.getNodeFromGraphSubject(mixinStatement
.getSubject())).thenReturn(mockNode);
when(
mockGraphSubjects.isFedoraGraphSubject(propertyStatement
.getSubject())).thenReturn(true);
when(
mockGraphSubjects.isFedoraGraphSubject(mixinStatement
.getSubject())).thenReturn(true);

testPersister =
new RdfPersister(mockGraphSubjects, mockSession, mockStream) {

@Override
protected void operateOnProperty(final Statement s,
final Node subjectNode) throws RepositoryException {
successfullyOperatedOnAProperty = true;
}

@Override
protected void operateOnMixin(final Resource mixinResource,
final Node subjectNode) throws RepositoryException {
successfullyOperatedOnAMixin = true;
}
};

}

@Test
public void testConsumeAsync() throws Exception {
testPersister.consumeAsync();
assertTrue("Didn't successfully operate on a property!",
successfullyOperatedOnAProperty);

assertTrue("Didn't successfully operate on a mixin!",
successfullyOperatedOnAMixin);
}

}

0 comments on commit f540613

Please sign in to comment.