Skip to content

Commit

Permalink
LDP container types
Browse files Browse the repository at this point in the history
  • Loading branch information
cbeer committed Oct 27, 2014
1 parent 33275b9 commit d88f709
Show file tree
Hide file tree
Showing 6 changed files with 143 additions and 68 deletions.
Expand Up @@ -17,29 +17,40 @@
package org.fcrepo.kernel.impl.rdf.impl;

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.NodeFactory;
import com.hp.hpl.jena.graph.Triple;
import com.hp.hpl.jena.rdf.model.RDFNode;
import com.hp.hpl.jena.rdf.model.Resource;
import org.fcrepo.kernel.Datastream;
import org.fcrepo.kernel.FedoraResource;
import org.fcrepo.kernel.exception.RepositoryRuntimeException;
import org.fcrepo.kernel.identifiers.IdentifierConverter;
import org.fcrepo.kernel.impl.rdf.converters.ValueConverter;
import org.fcrepo.kernel.impl.rdf.impl.mappings.PropertyValueIterator;
import org.fcrepo.kernel.utils.iterators.PropertyIterator;
import org.slf4j.Logger;

import javax.jcr.Property;
import javax.jcr.RepositoryException;
import javax.jcr.Value;
import java.util.Collections;
import java.util.Iterator;

import static com.google.common.collect.Iterators.singletonIterator;
import static com.hp.hpl.jena.graph.Triple.create;
import static org.fcrepo.jcr.FedoraJcrTypes.LDP_CONTAINER;
import static com.hp.hpl.jena.rdf.model.ResourceFactory.createResource;
import static org.fcrepo.jcr.FedoraJcrTypes.LDP_DIRECT_CONTAINER;
import static org.fcrepo.jcr.FedoraJcrTypes.LDP_HAS_MEMBER_RELATION;
import static org.fcrepo.jcr.FedoraJcrTypes.LDP_IS_MEMBER_OF_RELATION;
import static org.fcrepo.jcr.FedoraJcrTypes.LDP_INDIRECT_CONTAINER;
import static org.fcrepo.jcr.FedoraJcrTypes.LDP_INSERTED_CONTENT_RELATION;
import static org.fcrepo.jcr.FedoraJcrTypes.LDP_MEMBER_RESOURCE;
import static org.fcrepo.kernel.RdfLexicon.LDP_MEMBER;
import static org.fcrepo.kernel.RdfLexicon.MEMBER_SUBJECT;
import static org.fcrepo.kernel.impl.identifiers.NodeResourceConverter.nodeConverter;
import static org.fcrepo.kernel.impl.rdf.converters.PropertyConverter.getPropertyNameFromPredicate;
import static org.slf4j.LoggerFactory.getLogger;

/**
Expand All @@ -60,19 +71,32 @@ public LdpContainerRdfContext(final FedoraResource resource,
final IdentifierConverter<Resource, FedoraResource> idTranslator)
throws RepositoryException {
super(resource, idTranslator);
final PropertyIterator properties = new PropertyIterator(resource.getNode().getReferences(LDP_MEMBER_RESOURCE));
final Iterator<Property> properties = Iterators.filter(new PropertyIterator(resource.getNode().getReferences
(LDP_MEMBER_RESOURCE)), new Predicate<Property>() {


@Override
public boolean apply(final Property input) {
try {
return input.getParent().isNodeType("ldp:DirectContainer") || input.getParent().isNodeType
("ldp:IndirectContainer");
} catch (final RepositoryException e) {
throw new RepositoryRuntimeException(e);
}
}
});

if (properties.hasNext()) {
LOGGER.trace("Found membership containers for {}", resource);
concat(membershipContext(properties));
}

if (!resource.hasProperty(LDP_MEMBER_RESOURCE) && resource.hasType(LDP_CONTAINER)) {
if (resource.hasType("ldp:BasicContainer")) {
concat(memberRelations(resource));
}
}

private Iterator<Triple> membershipContext(final PropertyIterator properties) {
private Iterator<Triple> membershipContext(final Iterator<Property> properties) {
return Iterators.concat(Iterators.transform(properties, nodes2triples()));
}

Expand All @@ -94,37 +118,70 @@ public Iterator<Triple> apply(final Property input) {

/**
* Get the member relations assert on the subject by the given node
* @param resource
* @param container
* @return
* @throws RepositoryException
*/
private Iterator<Triple> memberRelations(final FedoraResource resource) throws RepositoryException {
private Iterator<Triple> memberRelations(final FedoraResource container) throws RepositoryException {
final com.hp.hpl.jena.graph.Node memberRelation;

if (resource.hasProperty(LDP_HAS_MEMBER_RELATION)) {
final Property property = resource.getProperty(LDP_HAS_MEMBER_RELATION);
if (container.hasProperty(LDP_HAS_MEMBER_RELATION)) {
final Property property = container.getProperty(LDP_HAS_MEMBER_RELATION);
memberRelation = NodeFactory.createURI(property.getString());
} else if (resource.hasProperty(LDP_IS_MEMBER_OF_RELATION)) {
return Collections.emptyIterator();
} else {
} else if (container.hasType("ldp:BasicContainer")) {
memberRelation = LDP_MEMBER.asNode();
} else {
return Collections.emptyIterator();
}

final Iterator<FedoraResource> memberNodes = resource.getChildren();
return Iterators.transform(memberNodes, new Function<FedoraResource, Triple>() {
final Iterator<FedoraResource> memberNodes = container.getChildren();

return Iterators.concat(Iterators.transform(memberNodes, new Function<FedoraResource, Iterator<Triple>>() {
@Override
public Triple apply(final FedoraResource child) {
final com.hp.hpl.jena.graph.Node childSubject;
if (child instanceof Datastream) {
childSubject = translator().reverse().convert(((Datastream) child).getBinary()).asNode();
} else {
childSubject = translator().reverse().convert(child).asNode();
}
return create(subject(), memberRelation, childSubject);
public Iterator<Triple> apply(final FedoraResource child) {

try {
final com.hp.hpl.jena.graph.Node childSubject;
if (child instanceof Datastream) {
childSubject = translator().reverse().convert(((Datastream) child).getBinary()).asNode();
} else {
childSubject = translator().reverse().convert(child).asNode();
}

final String insertedContainerProperty;

if (container.hasType(LDP_INDIRECT_CONTAINER) && container.hasProperty
(LDP_INSERTED_CONTENT_RELATION)) {
insertedContainerProperty = container.getProperty(LDP_INSERTED_CONTENT_RELATION).getString();
} else {
insertedContainerProperty = null;
}

if (container.hasType(LDP_DIRECT_CONTAINER)
|| (insertedContainerProperty != null &&
insertedContainerProperty.equals(MEMBER_SUBJECT.getURI()))) {

return singletonIterator(create(subject(), memberRelation, childSubject));
} else {

final PropertyValueIterator values = new PropertyValueIterator(resource().getProperty
(getPropertyNameFromPredicate(resource().getNode(), createResource
(insertedContainerProperty), null)));

return Iterators.transform(values, new Function<Value, Triple>() {
@Override
public Triple apply(final Value input) {
final RDFNode membershipResource = new ValueConverter(session(), translator()).convert
(values.next());
return create(subject(), memberRelation, membershipResource.asNode());
}
});
}
} catch (final RepositoryException e) {
throw new RepositoryRuntimeException(e);
}
}
});
}));
}

}
Expand Up @@ -15,20 +15,29 @@
*/
package org.fcrepo.kernel.impl.rdf.impl;

import com.hp.hpl.jena.rdf.model.RDFNode;
import com.hp.hpl.jena.rdf.model.Resource;
import com.hp.hpl.jena.rdf.model.ResourceFactory;
import org.fcrepo.kernel.FedoraResource;
import org.fcrepo.kernel.RdfLexicon;
import org.fcrepo.kernel.identifiers.IdentifierConverter;
import org.fcrepo.kernel.impl.rdf.converters.ValueConverter;
import org.fcrepo.kernel.impl.rdf.impl.mappings.PropertyValueIterator;

import javax.jcr.Property;
import javax.jcr.RepositoryException;

import static com.hp.hpl.jena.graph.Triple.create;
import static com.hp.hpl.jena.rdf.model.ResourceFactory.createResource;
import static javax.jcr.PropertyType.PATH;
import static javax.jcr.PropertyType.REFERENCE;
import static javax.jcr.PropertyType.WEAKREFERENCE;
import static org.fcrepo.jcr.FedoraJcrTypes.LDP_DIRECT_CONTAINER;
import static org.fcrepo.jcr.FedoraJcrTypes.LDP_INDIRECT_CONTAINER;
import static org.fcrepo.jcr.FedoraJcrTypes.LDP_INSERTED_CONTENT_RELATION;
import static org.fcrepo.jcr.FedoraJcrTypes.LDP_IS_MEMBER_OF_RELATION;
import static org.fcrepo.jcr.FedoraJcrTypes.LDP_MEMBER_RESOURCE;
import static org.fcrepo.kernel.impl.rdf.converters.PropertyConverter.getPropertyNameFromPredicate;

/**
* @author cabeer
Expand All @@ -49,22 +58,43 @@ public LdpIsMemberOfRdfContext(final FedoraResource resource,

final FedoraResource container = resource.getContainer();

if (container != null) {

if (container != null && container.hasProperty(LDP_IS_MEMBER_OF_RELATION)) {
concatIsMemberOfRelation(container);
}
}

private void concatIsMemberOfRelation(final FedoraResource container) throws RepositoryException {
if (container.hasProperty(LDP_IS_MEMBER_OF_RELATION)) {
final Property property = container.getProperty(LDP_IS_MEMBER_OF_RELATION);
final Property property = container.getProperty(LDP_IS_MEMBER_OF_RELATION);

final String insertedContainerProperty;

final Resource memberRelation = ResourceFactory.createResource(property.getString());
if (container.hasType(LDP_INDIRECT_CONTAINER) && container.hasProperty
(LDP_INSERTED_CONTENT_RELATION)) {
insertedContainerProperty = container.getProperty(LDP_INSERTED_CONTENT_RELATION).getString();
} else {
insertedContainerProperty = null;
}

final Resource memberRelation = createResource(property.getString());
final Resource membershipResource = getMemberResource(container);

if (membershipResource == null) {
return;
}

final Resource membershipResource = getMemberResource(container);
if (container.hasType(LDP_DIRECT_CONTAINER)
|| (container.hasType(LDP_INDIRECT_CONTAINER) &&
insertedContainerProperty != null &&
insertedContainerProperty.equals(RdfLexicon.MEMBER_SUBJECT.getURI()))) {
concat(create(subject(), memberRelation.asNode(), membershipResource.asNode()));
} else if (container.hasType(LDP_INDIRECT_CONTAINER) && insertedContainerProperty != null) {
final PropertyValueIterator values = new PropertyValueIterator(resource().getProperty
(getPropertyNameFromPredicate(resource()
.getNode(), createResource(insertedContainerProperty), null)));

if (membershipResource != null) {
concat(create(subject(), memberRelation.asNode(), membershipResource.asNode()));
while (values.hasNext()) {
final RDFNode subject = new ValueConverter(session(), translator()).convert(values.next());
concat(create(subject.asNode(), memberRelation.asNode(), membershipResource.asNode()));
}
}
}
Expand All @@ -85,7 +115,7 @@ private Resource getMemberResource(final FedoraResource parent) throws Repositor
if ( type == REFERENCE || type == WEAKREFERENCE || type == PATH) {
membershipResource = nodeConverter().convert(memberResource.getNode());
} else {
membershipResource = ResourceFactory.createResource(memberResource.getString());
membershipResource = createResource(memberResource.getString());
}
} else {
membershipResource = translator().reverse().convert(parent);
Expand Down
Expand Up @@ -59,42 +59,10 @@ public LdpRdfContext(final FedoraResource resource,

concat(typeContext());

if (isContainer()) {
concat(membershipRelationContext());
}

}

private boolean isContainer() {
return resource() instanceof FedoraObject;
}

private Collection<Triple> membershipRelationContext() {

final Set<Triple> triples1 = new HashSet<>();

if (!resource().hasProperty(LDP_HAS_MEMBER_RELATION)) {
triples1.add(create(subject(), HAS_MEMBER_RELATION.asNode(), LDP_MEMBER.asNode()));
}

if (!resource().hasProperty(LDP_MEMBER_RESOURCE)) {
triples1.add(create(subject(), MEMBERSHIP_RESOURCE.asNode(), subject()));
}

return triples1;
}

private Triple[] typeContext() {
final Triple rdfSource = create(subject(), type.asNode(), RDF_SOURCE.asNode());

if (isContainer()) {
return new Triple[]{
create(subject(), type.asNode(), CONTAINER.asNode()),
create(subject(), type.asNode(), DIRECT_CONTAINER.asNode()),
rdfSource
};
}
return new Triple[] { rdfSource };
private Triple typeContext() {
return create(subject(), type.asNode(), RDF_SOURCE.asNode());
}

}
11 changes: 11 additions & 0 deletions fcrepo-kernel-impl/src/main/resources/fedora-node-types.cnd
Expand Up @@ -71,8 +71,19 @@


[ldp:Container] mixin

[ldp:BasicContainer] > ldp:Container mixin

[ldp:DirectContainer] > ldp:Container mixin
- ldp:membershipResource (REFERENCE)
- ldp:hasMemberRelation (URI)
- ldp:isMemberOfRelation (URI)

[ldp:IndirectContainer] > ldp:Container mixin
- ldp:membershipResource (REFERENCE)
- ldp:hasMemberRelation (URI)
- ldp:isMemberOfRelation (URI)
- ldp:insertedContentRelation (URI)


/*
Expand Down
Expand Up @@ -38,6 +38,10 @@ public interface FedoraJcrTypes {
String FEDORA_BLANKNODE = "fedora:blanknode";

String LDP_CONTAINER = "ldp:Container";
String LDP_BASIC_CONTAINER = "ldp:BasicContainer";
String LDP_DIRECT_CONTAINER = "ldp:DirectContainer";
String LDP_INDIRECT_CONTAINER = "ldp:IndirectContainer";
String LDP_INSERTED_CONTENT_RELATION = "ldp:insertedContentRelation";

String JCR_LASTMODIFIED = "jcr:lastModified";

Expand Down
9 changes: 7 additions & 2 deletions fcrepo-kernel/src/main/java/org/fcrepo/kernel/RdfLexicon.java
Expand Up @@ -94,8 +94,7 @@ public final class RdfLexicon {
*/
public static final Set<String> managedNamespaces = of(RESTAPI_NAMESPACE,
REPOSITORY_NAMESPACE, JCR_NAMESPACE,
MIX_NAMESPACE, JCR_NT_NAMESPACE, MODE_NAMESPACE,
LDP_NAMESPACE);
MIX_NAMESPACE, JCR_NT_NAMESPACE, MODE_NAMESPACE);

/**
* Is this namespace one that the repository manages?
Expand Down Expand Up @@ -168,8 +167,12 @@ public final class RdfLexicon {
createProperty(LDP_NAMESPACE + "nextPage");
public static final Resource CONTAINER =
createResource(LDP_NAMESPACE + "Container");
public static final Resource BASIC_CONTAINER =
createResource(LDP_NAMESPACE + "BasicContainer");
public static final Resource DIRECT_CONTAINER =
createResource(LDP_NAMESPACE + "DirectContainer");
public static final Resource INDIRECT_CONTAINER =
createResource(LDP_NAMESPACE + "IndirectContainer");
public static final Property MEMBERSHIP_RESOURCE =
createProperty(LDP_NAMESPACE + "membershipResource");
public static final Property HAS_MEMBER_RELATION =
Expand All @@ -184,6 +187,8 @@ public final class RdfLexicon {
createProperty(LDP_NAMESPACE + "NonRDFSource");
public static final Property CONSTRAINED_BY =
createProperty(LDP_NAMESPACE + "constrainedBy");
public static final Property MEMBER_SUBJECT =
createProperty(LDP_NAMESPACE + "MemberSubject");

public static final Set<Property> ldpProperties = of(PAGE, PAGE_OF,
FIRST_PAGE, NEXT_PAGE, CONTAINS, LDP_MEMBER);
Expand Down

0 comments on commit d88f709

Please sign in to comment.