Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Support rdf language types
  • Loading branch information
cbeer committed Oct 23, 2014
1 parent 5dd9a1a commit 7e0868e
Show file tree
Hide file tree
Showing 10 changed files with 187 additions and 17 deletions.
Expand Up @@ -22,6 +22,7 @@
import static com.hp.hpl.jena.graph.NodeFactory.createURI;
import static com.hp.hpl.jena.rdf.model.ModelFactory.createDefaultModel;
import static com.hp.hpl.jena.rdf.model.ModelFactory.createModelForGraph;
import static com.hp.hpl.jena.rdf.model.ResourceFactory.createLangLiteral;
import static com.hp.hpl.jena.rdf.model.ResourceFactory.createPlainLiteral;
import static com.hp.hpl.jena.rdf.model.ResourceFactory.createProperty;
import static com.hp.hpl.jena.rdf.model.ResourceFactory.createResource;
Expand Down Expand Up @@ -916,6 +917,38 @@ public void testIngestOnSubtree() throws Exception {

}

@Test
public void testIngestWithRDFLang() throws Exception {
final HttpPost method = postObjMethod("");
method.addHeader("Content-Type", "application/n3");
final BasicHttpEntity entity = new BasicHttpEntity();
final String rdf = "<> <http://purl.org/dc/elements/1.1/title> \"this is a french title\"@fr ." +
"<> <http://purl.org/dc/elements/1.1/title> \"this is an english title\"@en .";
entity.setContent(new ByteArrayInputStream(rdf.getBytes()));
method.setEntity(entity);
final HttpResponse response = client.execute(method);
final String content = EntityUtils.toString(response.getEntity());
final int status = response.getStatusLine().getStatusCode();
assertEquals("Didn't get a CREATED response! Got content:\n" + content,
CREATED.getStatusCode(), status);

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

final HttpGet httpGet = new HttpGet(location);

final GraphStore graphStore = getGraphStore(httpGet);

assertTrue(graphStore.contains(ANY, createResource(location).asNode(),
DC_TITLE.asNode(), createLangLiteral("this is an english title", "en")
.asNode()));

assertTrue(graphStore.contains(ANY, createResource(location).asNode(),
DC_TITLE.asNode(), createLangLiteral("this is a french title", "fr")
.asNode()));

}


@Test
public void testCreateManyObjects() throws Exception {
if (System.getProperty(TEST_ACTIVATION_PROPERTY) == null) {
Expand Down
Expand Up @@ -185,7 +185,9 @@ protected static Value getValueForObject(final Node object) {

final String literalDatatypeURI = object.getLiteralDatatypeURI();

if (literalDatatypeURI != null) {
if (!object.getLiteralLanguage().isEmpty()) {
value = vfactory.createLiteral(object.getLiteralLexicalForm(), object.getLiteralLanguage());
} else if (literalDatatypeURI != null) {
final URI uri = vfactory.createURI(literalDatatypeURI);
value = vfactory.createLiteral(literalValue.toString(), uri);
} else {
Expand Down
Expand Up @@ -203,6 +203,16 @@ public void testWriteWithDatetimeObject() throws IOException {

}


@Test
public void testWriteWithLanguageLiteral() throws IOException {

assertOutputContainsTriple(create(createURI("info:testSubject"),
createURI("info:testPredicate"),
NodeFactory.createLiteral("french string", "fr", XSDDatatype.XSDstring)));

}

@Test(expected = WebApplicationException.class)
public void testWriteWithException() {

Expand Down
Expand Up @@ -262,7 +262,7 @@ public void addProperty(final FedoraResource resource,
}

final String propertyName =
getPropertyNameFromPredicate(node, predicate, namespaces);
getPropertyNameFromPredicate(node, predicate, value, namespaces);
final Value v = createValue(node, value, propertyName);
nodePropertiesTools.appendOrReplaceNodeProperty(idTranslator, node, propertyName, v);
}
Expand Down Expand Up @@ -304,7 +304,7 @@ public void removeProperty(final FedoraResource resource,
final Map<String, String> nsPrefixMap) throws RepositoryException {

final Node node = resource.getNode();
final String propertyName = getPropertyNameFromPredicate(node, predicate, nsPrefixMap);
final String propertyName = getPropertyNameFromPredicate(node, predicate, objectNode, nsPrefixMap);

if (isManagedPredicate.apply(predicate)) {

Expand Down
Expand Up @@ -19,6 +19,7 @@
import com.google.common.base.Converter;
import com.google.common.collect.ImmutableBiMap;
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 org.modeshape.jcr.api.NamespaceRegistry;
import org.modeshape.jcr.api.Namespaced;
Expand Down Expand Up @@ -60,6 +61,8 @@ protected Property doForward(final javax.jcr.Property property) {

if (isReferenceProperty.apply(property)) {
rdfLocalName = getReferencePropertyOriginalName(localName);
} else if (localName.contains("@")) {
rdfLocalName = localName.substring(0, localName.indexOf("@"));
} else {
rdfLocalName = localName;
}
Expand All @@ -79,6 +82,24 @@ protected javax.jcr.Property doBackward(final Property property) {
throw new UnsupportedOperationException();
}

/**
* Given an RDF predicate value (namespace URI + local name), figure out
* what JCR property to use
*
* @param node the JCR node we want a property for
* @param predicate the predicate to map to a property name
* @param namespaceMapping prefix to uri namespace mapping
* @return the JCR property name
* @throws RepositoryException
*/
public static String getPropertyNameFromPredicate(final Node node,
final Resource predicate,
final Map<String,String> namespaceMapping)
throws RepositoryException {
return getPropertyNameFromPredicate(node, predicate, null, namespaceMapping);
}


/**
* Given an RDF predicate value (namespace URI + local name), figure out
* what JCR property to use
Expand All @@ -91,10 +112,12 @@ protected javax.jcr.Property doBackward(final Property property) {
*/
public static String getPropertyNameFromPredicate(final Node node,
final Resource predicate,
final RDFNode object,
final Map<String,String> namespaceMapping) throws RepositoryException {
final NamespaceRegistry namespaceRegistry = getNamespaceRegistry.apply(node);
return getPropertyNameFromPredicate(namespaceRegistry,
predicate,
object,
namespaceMapping);
}

Expand All @@ -109,6 +132,7 @@ public static String getPropertyNameFromPredicate(final Node node,
*/
public static String getPropertyNameFromPredicate(final NamespaceRegistry namespaceRegistry,
final Resource predicate,
final RDFNode object,
final Map<String, String> namespaceMapping)
throws RepositoryException {

Expand Down Expand Up @@ -138,7 +162,19 @@ public static String getPropertyNameFromPredicate(final NamespaceRegistry namesp
}
}

final String propertyName = prefix + ":" + rdfLocalname;
final StringBuilder stringBuilder = new StringBuilder();

stringBuilder.append(prefix);
stringBuilder.append(":");
stringBuilder.append(rdfLocalname);


if (object != null && object.isLiteral() && !object.asLiteral().getLanguage().isEmpty()) {
stringBuilder.append("@");
stringBuilder.append(object.asLiteral().getLanguage());
}

final String propertyName = stringBuilder.toString();

LOGGER.debug("Took RDF predicate {} and translated it to JCR property {}", namespace, propertyName);

Expand Down
Expand Up @@ -16,6 +16,7 @@
package org.fcrepo.kernel.impl.rdf.impl.mappings;

import static com.google.common.base.Throwables.propagate;
import static com.hp.hpl.jena.graph.NodeFactory.createLiteral;
import static com.hp.hpl.jena.graph.Triple.create;
import static org.fcrepo.kernel.impl.identifiers.NodeResourceConverter.nodeToResource;
import static org.slf4j.LoggerFactory.getLogger;
Expand All @@ -30,6 +31,8 @@

import com.google.common.base.Converter;
import com.google.common.collect.Iterators;
import com.hp.hpl.jena.datatypes.xsd.XSDDatatype;
import com.hp.hpl.jena.graph.impl.LiteralLabel;
import com.hp.hpl.jena.rdf.model.Resource;
import org.fcrepo.kernel.FedoraResource;
import org.fcrepo.kernel.impl.rdf.converters.PropertyConverter;
Expand Down Expand Up @@ -106,15 +109,38 @@ public Triple apply(final Value v) {
private Triple propertyvalue2triple(final Property p, final Value v) {
LOGGER.trace("Rendering triple for Property: {} with Value: {}", p, v);
try {
final Triple triple =
create(graphSubjects.convert(p.getParent()).asNode(),
propertyConverter.convert(p).asNode(),
valueConverter.convert(v).asNode());

final Triple triple = create(graphSubjects.convert(p.getParent()).asNode(),
propertyConverter.convert(p).asNode(),
convertObject(p, v));

LOGGER.trace("Created triple: {} ", triple);
return triple;
} catch (final RepositoryException e) {
throw propagate(e);
}
}

private com.hp.hpl.jena.graph.Node convertObject(final Property p, final Value v) throws RepositoryException {
final com.hp.hpl.jena.graph.Node object = valueConverter.convert(v).asNode();

if (object.isLiteral()) {
final String propertyName = p.getName();
final int i = propertyName.indexOf("@");

if (i > 0) {
final LiteralLabel literal = object.getLiteral();
final String datatypeURI = literal.getDatatypeURI();

if (datatypeURI.isEmpty() || datatypeURI.equals(XSDDatatype.XSDstring.getURI())) {

final String lang = propertyName.substring(i + 1);
return createLiteral(literal.getLexicalForm(), lang, literal.getDatatype());
}
}
}

return object;
}

}
Expand Up @@ -30,6 +30,7 @@

import java.util.Map;

import static com.hp.hpl.jena.rdf.model.ResourceFactory.createLangLiteral;
import static com.hp.hpl.jena.rdf.model.ResourceFactory.createProperty;
import static java.util.Collections.emptyMap;
import static javax.jcr.PropertyType.REFERENCE;
Expand Down Expand Up @@ -88,9 +89,19 @@ public final void shouldMapInternalReferencePropertiesToPublicUris() throws Repo

}

@Test
public final void shouldMapLanguageTaggedPropertiesToPublicUris() throws RepositoryException {
when(mockNamespacedProperty.getNamespaceURI()).thenReturn("info:xyz#");
when(mockNamespacedProperty.getLocalName()).thenReturn("some_string@xyz");
final Property property = testObj.convert(mockNamespacedProperty);

assert(property != null);
assertEquals("some_string", property.getLocalName());

}

@Test
public void testGetPredicateForProperty() throws RepositoryException {
testObj.convert(mockNamespacedProperty);
when(mockNamespacedProperty.getNamespaceURI()).thenThrow(new RepositoryException());
try {
testObj.convert(mockNamespacedProperty);
Expand Down Expand Up @@ -123,6 +134,16 @@ public final void shouldRegisterUnknownUris() throws RepositoryException {
assertEquals("ns001:uuid", PropertyConverter.getPropertyNameFromPredicate(mockNode, p, EMPTY_NAMESPACE_MAP));
}

@Test
public final void shouldUseLiteralLanguageAsPartOfPropertyUri() throws RepositoryException {
final Property p = createProperty(REPOSITORY_NAMESPACE, "uuid");
assertEquals("jcr:uuid@de", PropertyConverter.getPropertyNameFromPredicate(mockNode,
p,
createLangLiteral("x", "de"),
EMPTY_NAMESPACE_MAP));
}


private void mockNamespaceRegistry(final NamespaceRegistry mockRegistry) throws RepositoryException {

when(mockRegistry.isRegisteredUri(mockUri)).thenReturn(true);
Expand Down
Expand Up @@ -39,7 +39,6 @@

import javax.jcr.AccessDeniedException;
import javax.jcr.ItemNotFoundException;
import javax.jcr.Property;
import javax.jcr.RepositoryException;
import javax.jcr.Session;
import javax.jcr.Value;
Expand All @@ -48,6 +47,7 @@
import org.fcrepo.kernel.FedoraResource;
import org.fcrepo.kernel.identifiers.IdentifierConverter;
import org.fcrepo.kernel.impl.rdf.impl.DefaultIdentifierTranslator;
import org.fcrepo.kernel.impl.utils.JcrPropertyMock;
import org.junit.Before;
import org.junit.Test;
import org.mockito.Mock;
Expand Down Expand Up @@ -134,6 +134,25 @@ public void testSingleValuedStringLiteralTriple()
.getSubject());
}

@Test
public void testSingleValuedStringLanguageLiteralTriple()
throws RepositoryException {

when(mockProperty.getType()).thenReturn(STRING);
when(mockProperty.getName()).thenReturn(TEST_PROPERTY_NAME + "@en");
when(mockProperty.getLocalName()).thenReturn("predicate@en");
when(mockValue.getType()).thenReturn(STRING);
when(mockValue.getString()).thenReturn(TEST_VALUE);
final Triple t = createSingleValuedLiteralTriple();
assertEquals("Got wrong RDF object!", TEST_VALUE, t.getObject()
.getLiteralValue());
assertEquals("Get wrong RDF object literal language", "en", t.getObject().getLiteralLanguage());
assertEquals("Got wrong RDF predicate!", createProperty(
TEST_PROPERTY_NAME).asNode(), t.getPredicate());
assertEquals("Got wrong RDF subject!", testSubject, t
.getSubject());
}

@Test
public void
testSingleValuedBooleanLiteralTriple() throws RepositoryException {
Expand Down Expand Up @@ -353,6 +372,8 @@ public void setUp() throws ValueFormatException, RepositoryException {
when(mockProperty.getValue()).thenReturn(mockValue);
when(mockProperty.getParent()).thenReturn(mockNode);
when(mockProperty.getName()).thenReturn(TEST_PROPERTY_NAME);
when(mockProperty.getNamespaceURI()).thenReturn("info:");
when(mockProperty.getLocalName()).thenReturn("predicate");
when(mockProperty.getSession()).thenReturn(mockSession);
when(mockSession.getNode(TEST_NODE_PATH)).thenReturn(mockNode);
when(mockNode.getNode(TEST_NODE_PATH)).thenReturn(mockNode);
Expand All @@ -368,7 +389,7 @@ public void setUp() throws ValueFormatException, RepositoryException {
private IdentifierConverter<Resource, FedoraResource> idTranslator;

@Mock
private Property mockProperty;
private JcrPropertyMock mockProperty;

@Mock
private Value mockValue;
Expand Down

0 comments on commit 7e0868e

Please sign in to comment.