Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Lazy-ifacting Version-based RDF generation
  • Loading branch information
ajs6f committed Oct 21, 2013
1 parent d9f152e commit 3767818
Show file tree
Hide file tree
Showing 5 changed files with 186 additions and 27 deletions.
Expand Up @@ -15,7 +15,8 @@
*/
package org.fcrepo.kernel.rdf.impl;

import static com.google.common.collect.ImmutableSet.builder;
import static com.google.common.base.Throwables.propagate;
import static com.google.common.collect.Iterators.transform;
import static com.hp.hpl.jena.graph.NodeFactory.createLiteral;
import static com.hp.hpl.jena.graph.Triple.create;
import static org.fcrepo.kernel.RdfLexicon.HAS_VERSION;
Expand All @@ -27,13 +28,16 @@
import javax.jcr.RepositoryException;
import javax.jcr.version.Version;
import javax.jcr.version.VersionHistory;
import javax.jcr.version.VersionIterator;
import javax.jcr.version.VersionManager;

import org.fcrepo.kernel.rdf.GraphSubjects;
import org.fcrepo.kernel.rdf.NodeRdfContext;
import org.fcrepo.kernel.services.LowLevelStorageService;
import org.fcrepo.kernel.utils.iterators.RdfStream;
import org.fcrepo.kernel.utils.iterators.VersionIterator;

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


Expand All @@ -46,6 +50,10 @@
*/
public class VersionsRdfContext extends NodeRdfContext {

private final VersionManager versionManager;

private final VersionHistory versionHistory;

/**
* Ordinary constructor.
*
Expand All @@ -58,35 +66,46 @@ public VersionsRdfContext(final Node node, final GraphSubjects graphSubjects,
final LowLevelStorageService lowLevelStorageService)
throws RepositoryException {
super(node, graphSubjects, lowLevelStorageService);
versionManager = node().getSession().getWorkspace().getVersionManager();
versionHistory = versionManager.getVersionHistory(node().getPath());
concat(versionTriples());
}

private Iterator<Triple> versionTriples() throws RepositoryException {
final VersionHistory versionHistory =
node().getSession().getWorkspace().getVersionManager()
.getVersionHistory(node().getPath());

final VersionIterator versionIterator = versionHistory.getAllVersions();
final ImmutableSet.Builder<Triple> b = builder();
while (versionIterator.hasNext()) {
final Version version = versionIterator.nextVersion();
final Node frozenNode = version.getFrozenNode();
final com.hp.hpl.jena.graph.Node versionSubject =
graphSubjects().getGraphSubject(frozenNode).asNode();

b.add(create(subject(), HAS_VERSION.asNode(), versionSubject));

final String[] versionLabels =
versionHistory.getVersionLabels(version);
for (final String label : versionLabels) {
b.add(create(versionSubject, HAS_VERSION_LABEL.asNode(), createLiteral(label)));
return Iterators.concat(transform(new VersionIterator(versionHistory
.getAllVersions()), version2triples));
}

private Function<Version, Iterator<Triple>> version2triples =
new Function<Version, Iterator<Triple>>() {

@Override
public Iterator<Triple> apply(final Version version) {

try {
final Node frozenNode = version.getFrozenNode();
final com.hp.hpl.jena.graph.Node versionSubject =
graphSubjects().getGraphSubject(frozenNode).asNode();

final RdfStream results =
new RdfStream(new PropertiesRdfContext(frozenNode,
graphSubjects(), lowLevelStorageService()));

results.concat(create(subject(), HAS_VERSION.asNode(),
versionSubject));

for (final String label : versionHistory
.getVersionLabels(version)) {
results.concat(create(versionSubject, HAS_VERSION_LABEL
.asNode(), createLiteral(label)));
}
return results;
} catch (final RepositoryException e) {
throw propagate(e);
}
}
concat(new PropertiesRdfContext(frozenNode, graphSubjects(),
lowLevelStorageService()));

}
return b.build().iterator();
}
};


}
Expand Up @@ -79,6 +79,17 @@ public RdfStream concat(final Iterator<? extends Triple> newTriples) {
return this;
}

/**
* @param newTriple Triples to add.
* @return This object for continued use.
*/
public RdfStream concat(final Triple newTriple) {
triples =
Iterators.concat(Iterators.forArray(new Triple[] {newTriple}),
triples);
return this;
}

/**
* @param newTriples Triples to add.
* @return This object for continued use.
Expand Down
@@ -0,0 +1,56 @@
/**
* Copyright 2013 DuraSpace, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package org.fcrepo.kernel.utils.iterators;

import java.util.Iterator;

import javax.jcr.version.Version;

import com.google.common.collect.ForwardingIterator;

/**
* Type-aware iterator to wrap the JCR NodeIterator
*
* @author ajs6f
* @date Apr 20, 2013
*/
public class VersionIterator extends ForwardingIterator<Version> implements
Iterable<Version> {

private javax.jcr.version.VersionIterator i;

/**
* Wrap the NodeIterator with our generic version
*
* @param i
*/
public VersionIterator(final javax.jcr.version.VersionIterator i) {
this.i = i;
}

@Override
public Iterator<Version> iterator() {
return this;
}

@SuppressWarnings("unchecked")
@Override
protected Iterator<Version> delegate() {
return i;
}

}
Expand Up @@ -711,7 +711,7 @@ public final void testGetJcrVersionsModel() throws Exception {
"/jcr:system/versions/test/jcr");
when(mockFrozenNode.getPrimaryNodeType()).thenReturn(mockNodeType);
when(mockVersion.getFrozenNode()).thenReturn(mockFrozenNode);
when(mockVersionIterator.nextVersion()).thenReturn(mockVersion);
when(mockVersionIterator.next()).thenReturn(mockVersion);
when(mockVersionHistory.getAllVersions()).thenReturn(
mockVersionIterator);
when(mockWorkspace.getVersionManager()).thenReturn(mockVersionManager);
Expand Down
@@ -0,0 +1,73 @@
/**
* Copyright 2013 DuraSpace, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package org.fcrepo.kernel.utils.iterators;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import static org.mockito.MockitoAnnotations.initMocks;

import javax.jcr.version.Version;

import org.junit.Before;
import org.junit.Test;
import org.mockito.Mock;

public class VersionIteratorTest {

@Mock
javax.jcr.version.VersionIterator i;

@Mock
Version v1, v2;

VersionIterator testIterator;

@Before
public void setUp() {
initMocks(this);
testIterator = new VersionIterator(i);
}

@Test
public void testHasNext() {
when(i.hasNext()).thenReturn(true, false);
assertTrue(testIterator.hasNext());
assertFalse(testIterator.hasNext());
}

@Test
public void testNext() {
when(i.next()).thenReturn(v1, v2);
assertEquals(v1, testIterator.next());
assertEquals(v2, testIterator.next());
}

@Test
public void testRemove() {
testIterator.remove();
verify(i).remove();
}

@Test
public void testIterator() {
assertEquals(testIterator, testIterator.iterator());
}

}

0 comments on commit 3767818

Please sign in to comment.