001/* 002 * Licensed to DuraSpace under one or more contributor license agreements. 003 * See the NOTICE file distributed with this work for additional information 004 * regarding copyright ownership. 005 * 006 * DuraSpace licenses this file to you under the Apache License, 007 * Version 2.0 (the "License"); you may not use this file except in 008 * compliance with the License. You may obtain a copy of the License at 009 * 010 * http://www.apache.org/licenses/LICENSE-2.0 011 * 012 * Unless required by applicable law or agreed to in writing, software 013 * distributed under the License is distributed on an "AS IS" BASIS, 014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 015 * See the License for the specific language governing permissions and 016 * limitations under the License. 017 */ 018package org.fcrepo.kernel.modeshape.rdf.impl; 019 020import org.apache.jena.graph.Triple; 021import org.apache.jena.rdf.model.Resource; 022 023import org.fcrepo.kernel.api.models.FedoraResource; 024import org.fcrepo.kernel.api.identifiers.IdentifierConverter; 025import org.fcrepo.kernel.modeshape.rdf.converters.ValueConverter; 026import org.fcrepo.kernel.modeshape.rdf.impl.mappings.PropertyValueIterator; 027import org.fcrepo.kernel.modeshape.utils.UncheckedFunction; 028import org.fcrepo.kernel.modeshape.utils.UncheckedPredicate; 029 030import java.util.stream.Stream; 031 032import javax.jcr.Node; 033import javax.jcr.Property; 034import javax.jcr.RepositoryException; 035 036import static java.util.stream.Stream.empty; 037import static java.util.stream.Stream.of; 038import static org.apache.jena.graph.NodeFactory.createURI; 039import static org.apache.jena.graph.Triple.create; 040import static org.apache.jena.rdf.model.ResourceFactory.createResource; 041import static org.fcrepo.kernel.api.FedoraTypes.LDP_BASIC_CONTAINER; 042import static org.fcrepo.kernel.api.FedoraTypes.LDP_DIRECT_CONTAINER; 043import static org.fcrepo.kernel.api.FedoraTypes.LDP_HAS_MEMBER_RELATION; 044import static org.fcrepo.kernel.api.FedoraTypes.LDP_INDIRECT_CONTAINER; 045import static org.fcrepo.kernel.api.FedoraTypes.LDP_INSERTED_CONTENT_RELATION; 046import static org.fcrepo.kernel.api.FedoraTypes.LDP_MEMBER_RESOURCE; 047import static org.fcrepo.kernel.api.RdfLexicon.LDP_MEMBER; 048import static org.fcrepo.kernel.api.RdfLexicon.MEMBER_SUBJECT; 049import static org.fcrepo.kernel.modeshape.identifiers.NodeResourceConverter.nodeConverter; 050import static org.fcrepo.kernel.modeshape.rdf.converters.PropertyConverter.getPropertyNameFromPredicate; 051import static org.fcrepo.kernel.modeshape.utils.FedoraTypesUtils.getJcrNode; 052import static org.fcrepo.kernel.modeshape.utils.FedoraTypesUtils.getReferencePropertyName; 053import static org.fcrepo.kernel.modeshape.utils.StreamUtils.iteratorToStream; 054import static org.fcrepo.kernel.modeshape.utils.UncheckedFunction.uncheck; 055 056/** 057 * @author cabeer 058 * @author ajs6f 059 * @since 9/25/14 060 */ 061public class LdpContainerRdfContext extends NodeRdfContext { 062 063 /** 064 * Default constructor. 065 * 066 * @param resource the resource 067 * @param idTranslator the id translator 068 * @throws javax.jcr.RepositoryException if repository exception occurred 069 */ 070 public LdpContainerRdfContext(final FedoraResource resource, 071 final IdentifierConverter<Resource, FedoraResource> idTranslator) 072 throws RepositoryException { 073 super(resource, idTranslator); 074 075 concat(getMembershipContext(resource) 076 .flatMap(uncheck(p -> memberRelations(nodeConverter.convert(p.getParent()))))); 077 } 078 079 @SuppressWarnings("unchecked") 080 private static Stream<Property> getMembershipContext(final FedoraResource resource) throws RepositoryException { 081 return iteratorToStream(getJcrNode(resource).getReferences(LDP_MEMBER_RESOURCE)) 082 .filter(UncheckedPredicate.uncheck((final Property p) -> { 083 final Node container = p.getParent(); 084 return container.isNodeType(LDP_DIRECT_CONTAINER) 085 || container.isNodeType(LDP_INDIRECT_CONTAINER); 086 })); 087 } 088 089 /** 090 * Get the member relations assert on the subject by the given node 091 * @param container with relations 092 * @return Stream of triples 093 * @throws RepositoryException on error 094 */ 095 private Stream<Triple> memberRelations(final FedoraResource container) throws RepositoryException { 096 final org.apache.jena.graph.Node memberRelation; 097 098 if (container.hasProperty(LDP_HAS_MEMBER_RELATION)) { 099 final Property property = getJcrNode(container).getProperty(LDP_HAS_MEMBER_RELATION); 100 memberRelation = createURI(property.getString()); 101 } else if (container.hasType(LDP_BASIC_CONTAINER)) { 102 memberRelation = LDP_MEMBER.asNode(); 103 } else { 104 return empty(); 105 } 106 107 final String insertedContainerProperty; 108 109 if (container.hasType(LDP_INDIRECT_CONTAINER)) { 110 if (container.hasProperty(LDP_INSERTED_CONTENT_RELATION)) { 111 insertedContainerProperty = getJcrNode(container).getProperty(LDP_INSERTED_CONTENT_RELATION) 112 .getString(); 113 } else { 114 return empty(); 115 } 116 } else { 117 insertedContainerProperty = MEMBER_SUBJECT.getURI(); 118 } 119 120 return container.getChildren().flatMap( 121 UncheckedFunction.uncheck(child -> { 122 final org.apache.jena.graph.Node childSubject = uriFor(child.getDescribedResource()); 123 124 if (insertedContainerProperty.equals(MEMBER_SUBJECT.getURI())) { 125 return of(create(subject(), memberRelation, childSubject)); 126 } 127 String insertedContentProperty = getPropertyNameFromPredicate(getJcrNode(resource()), 128 createResource(insertedContainerProperty), null); 129 130 if (child.hasProperty(insertedContentProperty)) { 131 // do nothing, insertedContentProperty is good 132 133 } else if (child.hasProperty(getReferencePropertyName(insertedContentProperty))) { 134 // The insertedContentProperty is a pseudo reference property 135 insertedContentProperty = getReferencePropertyName(insertedContentProperty); 136 137 } else { 138 // No property found! 139 return empty(); 140 } 141 142 return iteratorToStream(new PropertyValueIterator( 143 getJcrNode(child).getProperty(insertedContentProperty))) 144 .map(uncheck(v -> create(subject(), memberRelation, 145 new ValueConverter(getJcrNode(container).getSession(), translator()).convert(v).asNode()))); 146 })); 147 } 148}