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 static org.fcrepo.kernel.modeshape.identifiers.NodeResourceConverter.nodeConverter; 021import static org.fcrepo.kernel.modeshape.rdf.converters.ValueConverter.nodeForValue; 022import static org.fcrepo.kernel.modeshape.utils.FedoraTypesUtils.getJcrNode; 023import static org.fcrepo.kernel.modeshape.utils.StreamUtils.iteratorToStream; 024import static org.fcrepo.kernel.modeshape.utils.UncheckedFunction.uncheck; 025import static java.util.Arrays.asList; 026import static javax.jcr.PropertyType.PATH; 027import static javax.jcr.PropertyType.REFERENCE; 028import static javax.jcr.PropertyType.WEAKREFERENCE; 029 030import com.hp.hpl.jena.graph.Triple; 031import com.hp.hpl.jena.rdf.model.Resource; 032import org.fcrepo.kernel.api.identifiers.IdentifierConverter; 033import org.fcrepo.kernel.api.models.FedoraResource; 034import org.fcrepo.kernel.modeshape.rdf.impl.mappings.PropertyToTriple; 035import org.fcrepo.kernel.modeshape.rdf.impl.mappings.PropertyValueIterator; 036 037import javax.jcr.Node; 038import javax.jcr.Property; 039import javax.jcr.RepositoryException; 040import javax.jcr.Value; 041 042import java.util.List; 043import java.util.function.Predicate; 044import java.util.stream.Stream; 045 046/** 047 * Accumulate inbound references to a given resource 048 * 049 * @author cabeer 050 * @author escowles 051 */ 052public class ReferencesRdfContext extends NodeRdfContext { 053 054 private final PropertyToTriple property2triple; 055 056 public static final List<Integer> REFERENCE_TYPES = asList(PATH, REFERENCE, WEAKREFERENCE); 057 058 /** 059 * Add the inbound references from other nodes to this resource to the stream 060 * 061 * @param resource the resource 062 * @param idTranslator the id translator 063 * @throws RepositoryException if repository exception occurred 064 */ 065 066 public ReferencesRdfContext(final FedoraResource resource, 067 final IdentifierConverter<Resource, FedoraResource> idTranslator) 068 throws RepositoryException { 069 super(resource, idTranslator); 070 property2triple = new PropertyToTriple(getJcrNode(resource).getSession(), idTranslator); 071 concat(putReferencesIntoContext(getJcrNode(resource))); 072 } 073 074 private final Predicate<Triple> INBOUND = t -> { 075 return t.getObject().getURI().equals(uriFor(resource()).getURI()); 076 }; 077 078 /* References from LDP indirect containers are generated dynamically by LdpContainerRdfContext, so they won't 079 show up in getReferences()/getWeakReferences(). Instead, we should check referencers to see if they are 080 members of an IndirectContainer and generate the appropriate inbound references. */ 081 private Stream<Triple> putReferencesIntoContext(final Node node) throws RepositoryException { 082 return Stream.concat( 083 getAllReferences(node).flatMap(property2triple), 084 getAllReferences(node).flatMap(uncheck((final Property x) -> { 085 @SuppressWarnings("unchecked") 086 final Stream<Value> values = iteratorToStream(new PropertyValueIterator(x.getParent() 087 .getProperties())).filter((final Value y) -> REFERENCE_TYPES.contains(y.getType())); 088 return values; 089 })) 090 .flatMap(uncheck((final Value x) -> { 091 return new LdpContainerRdfContext(nodeConverter.convert(nodeForValue(node.getSession(), x)), 092 translator()); 093 })) 094 .filter(INBOUND)); 095 } 096 097 @SuppressWarnings("unchecked") 098 private static Stream<Property> getAllReferences(final Node node) throws RepositoryException { 099 return Stream.concat(iteratorToStream(node.getReferences()), iteratorToStream(node.getWeakReferences())); 100 } 101}