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 org.slf4j.Logger; 031 032import java.util.stream.Stream; 033 034import javax.jcr.Node; 035import javax.jcr.Property; 036import javax.jcr.RepositoryException; 037 038import static java.util.stream.Stream.empty; 039import static java.util.stream.Stream.of; 040import static org.apache.jena.graph.NodeFactory.createURI; 041import static org.apache.jena.graph.Triple.create; 042import static org.apache.jena.rdf.model.ResourceFactory.createResource; 043import static org.fcrepo.kernel.api.FedoraTypes.LDP_BASIC_CONTAINER; 044import static org.fcrepo.kernel.api.FedoraTypes.LDP_DIRECT_CONTAINER; 045import static org.fcrepo.kernel.api.FedoraTypes.LDP_HAS_MEMBER_RELATION; 046import static org.fcrepo.kernel.api.FedoraTypes.LDP_INDIRECT_CONTAINER; 047import static org.fcrepo.kernel.api.FedoraTypes.LDP_INSERTED_CONTENT_RELATION; 048import static org.fcrepo.kernel.api.FedoraTypes.LDP_MEMBER_RESOURCE; 049import static org.fcrepo.kernel.api.RdfLexicon.LDP_MEMBER; 050import static org.fcrepo.kernel.api.RdfLexicon.MEMBER_SUBJECT; 051import static org.fcrepo.kernel.modeshape.identifiers.NodeResourceConverter.nodeConverter; 052import static org.fcrepo.kernel.modeshape.rdf.converters.PropertyConverter.getPropertyNameFromPredicate; 053import static org.fcrepo.kernel.modeshape.utils.FedoraTypesUtils.getJcrNode; 054import static org.fcrepo.kernel.modeshape.utils.FedoraTypesUtils.getReferencePropertyName; 055import static org.fcrepo.kernel.modeshape.utils.StreamUtils.iteratorToStream; 056import static org.fcrepo.kernel.modeshape.utils.UncheckedFunction.uncheck; 057import static org.slf4j.LoggerFactory.getLogger; 058 059/** 060 * @author cabeer 061 * @author ajs6f 062 * @since 9/25/14 063 */ 064public class LdpContainerRdfContext extends NodeRdfContext { 065 private static final Logger LOGGER = getLogger(LdpContainerRdfContext.class); 066 067 /** 068 * Default constructor. 069 * 070 * @param resource the resource 071 * @param idTranslator the id translator 072 * @throws javax.jcr.RepositoryException if repository exception occurred 073 */ 074 public LdpContainerRdfContext(final FedoraResource resource, 075 final IdentifierConverter<Resource, FedoraResource> idTranslator) 076 throws RepositoryException { 077 super(resource, idTranslator); 078 079 concat(getMembershipContext(resource) 080 .flatMap(uncheck(p -> memberRelations(nodeConverter.convert(p.getParent()))))); 081 } 082 083 @SuppressWarnings("unchecked") 084 private static Stream<Property> getMembershipContext(final FedoraResource resource) throws RepositoryException { 085 return iteratorToStream(getJcrNode(resource).getReferences(LDP_MEMBER_RESOURCE)) 086 .filter(UncheckedPredicate.uncheck((final Property p) -> { 087 final Node container = p.getParent(); 088 return container.isNodeType(LDP_DIRECT_CONTAINER) 089 || container.isNodeType(LDP_INDIRECT_CONTAINER); 090 })); 091 } 092 093 /** 094 * Get the member relations assert on the subject by the given node 095 * @param container 096 * @return 097 * @throws RepositoryException 098 */ 099 private Stream<Triple> memberRelations(final FedoraResource container) throws RepositoryException { 100 final org.apache.jena.graph.Node memberRelation; 101 102 if (container.hasProperty(LDP_HAS_MEMBER_RELATION)) { 103 final Property property = getJcrNode(container).getProperty(LDP_HAS_MEMBER_RELATION); 104 memberRelation = createURI(property.getString()); 105 } else if (container.hasType(LDP_BASIC_CONTAINER)) { 106 memberRelation = LDP_MEMBER.asNode(); 107 } else { 108 return empty(); 109 } 110 111 final String insertedContainerProperty; 112 113 if (container.hasType(LDP_INDIRECT_CONTAINER)) { 114 if (container.hasProperty(LDP_INSERTED_CONTENT_RELATION)) { 115 insertedContainerProperty = getJcrNode(container).getProperty(LDP_INSERTED_CONTENT_RELATION) 116 .getString(); 117 } else { 118 return empty(); 119 } 120 } else { 121 insertedContainerProperty = MEMBER_SUBJECT.getURI(); 122 } 123 124 return container.getChildren().flatMap( 125 UncheckedFunction.<FedoraResource, Stream<Triple>>uncheck(child -> { 126 final org.apache.jena.graph.Node childSubject = uriFor(child.getDescribedResource()); 127 128 if (insertedContainerProperty.equals(MEMBER_SUBJECT.getURI())) { 129 return of(create(subject(), memberRelation, childSubject)); 130 } 131 String insertedContentProperty = getPropertyNameFromPredicate(getJcrNode(resource()), 132 createResource(insertedContainerProperty), null); 133 134 if (child.hasProperty(insertedContentProperty)) { 135 // do nothing, insertedContentProperty is good 136 137 } else if (child.hasProperty(getReferencePropertyName(insertedContentProperty))) { 138 // The insertedContentProperty is a pseudo reference property 139 insertedContentProperty = getReferencePropertyName(insertedContentProperty); 140 141 } else { 142 // No property found! 143 return empty(); 144 } 145 146 return iteratorToStream(new PropertyValueIterator( 147 getJcrNode(child).getProperty(insertedContentProperty))) 148 .map(uncheck(v -> create(subject(), memberRelation, 149 new ValueConverter(getJcrNode(container).getSession(), translator()).convert(v).asNode()))); 150 })); 151 } 152}